@timmeck/trading-brain 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. package/README.md +306 -0
  2. package/dist/api/server.d.ts +21 -0
  3. package/dist/api/server.js +157 -0
  4. package/dist/api/server.js.map +1 -0
  5. package/dist/cli/colors.d.ts +46 -0
  6. package/dist/cli/colors.js +70 -0
  7. package/dist/cli/colors.js.map +1 -0
  8. package/dist/cli/commands/config.d.ts +2 -0
  9. package/dist/cli/commands/config.js +70 -0
  10. package/dist/cli/commands/config.js.map +1 -0
  11. package/dist/cli/commands/doctor.d.ts +2 -0
  12. package/dist/cli/commands/doctor.js +61 -0
  13. package/dist/cli/commands/doctor.js.map +1 -0
  14. package/dist/cli/commands/export.d.ts +2 -0
  15. package/dist/cli/commands/export.js +23 -0
  16. package/dist/cli/commands/export.js.map +1 -0
  17. package/dist/cli/commands/import.d.ts +2 -0
  18. package/dist/cli/commands/import.js +42 -0
  19. package/dist/cli/commands/import.js.map +1 -0
  20. package/dist/cli/commands/insights.d.ts +2 -0
  21. package/dist/cli/commands/insights.js +29 -0
  22. package/dist/cli/commands/insights.js.map +1 -0
  23. package/dist/cli/commands/network.d.ts +2 -0
  24. package/dist/cli/commands/network.js +43 -0
  25. package/dist/cli/commands/network.js.map +1 -0
  26. package/dist/cli/commands/query.d.ts +2 -0
  27. package/dist/cli/commands/query.js +27 -0
  28. package/dist/cli/commands/query.js.map +1 -0
  29. package/dist/cli/commands/rules.d.ts +2 -0
  30. package/dist/cli/commands/rules.js +26 -0
  31. package/dist/cli/commands/rules.js.map +1 -0
  32. package/dist/cli/commands/start.d.ts +2 -0
  33. package/dist/cli/commands/start.js +86 -0
  34. package/dist/cli/commands/start.js.map +1 -0
  35. package/dist/cli/commands/status.d.ts +2 -0
  36. package/dist/cli/commands/status.js +58 -0
  37. package/dist/cli/commands/status.js.map +1 -0
  38. package/dist/cli/commands/stop.d.ts +2 -0
  39. package/dist/cli/commands/stop.js +34 -0
  40. package/dist/cli/commands/stop.js.map +1 -0
  41. package/dist/cli/ipc-helper.d.ts +2 -0
  42. package/dist/cli/ipc-helper.js +26 -0
  43. package/dist/cli/ipc-helper.js.map +1 -0
  44. package/dist/config.d.ts +2 -0
  45. package/dist/config.js +107 -0
  46. package/dist/config.js.map +1 -0
  47. package/dist/db/connection.d.ts +2 -0
  48. package/dist/db/connection.js +19 -0
  49. package/dist/db/connection.js.map +1 -0
  50. package/dist/db/migrations/001_core.d.ts +2 -0
  51. package/dist/db/migrations/001_core.js +42 -0
  52. package/dist/db/migrations/001_core.js.map +1 -0
  53. package/dist/db/migrations/002_synapses.d.ts +2 -0
  54. package/dist/db/migrations/002_synapses.js +43 -0
  55. package/dist/db/migrations/002_synapses.js.map +1 -0
  56. package/dist/db/migrations/003_learning.d.ts +2 -0
  57. package/dist/db/migrations/003_learning.js +48 -0
  58. package/dist/db/migrations/003_learning.js.map +1 -0
  59. package/dist/db/migrations/004_research.d.ts +2 -0
  60. package/dist/db/migrations/004_research.js +29 -0
  61. package/dist/db/migrations/004_research.js.map +1 -0
  62. package/dist/db/migrations/index.d.ts +2 -0
  63. package/dist/db/migrations/index.js +45 -0
  64. package/dist/db/migrations/index.js.map +1 -0
  65. package/dist/db/repositories/calibration.repository.d.ts +25 -0
  66. package/dist/db/repositories/calibration.repository.js +66 -0
  67. package/dist/db/repositories/calibration.repository.js.map +1 -0
  68. package/dist/db/repositories/chain.repository.d.ts +28 -0
  69. package/dist/db/repositories/chain.repository.js +52 -0
  70. package/dist/db/repositories/chain.repository.js.map +1 -0
  71. package/dist/db/repositories/graph.repository.d.ts +33 -0
  72. package/dist/db/repositories/graph.repository.js +73 -0
  73. package/dist/db/repositories/graph.repository.js.map +1 -0
  74. package/dist/db/repositories/insight.repository.d.ts +30 -0
  75. package/dist/db/repositories/insight.repository.js +60 -0
  76. package/dist/db/repositories/insight.repository.js.map +1 -0
  77. package/dist/db/repositories/rule.repository.d.ts +35 -0
  78. package/dist/db/repositories/rule.repository.js +48 -0
  79. package/dist/db/repositories/rule.repository.js.map +1 -0
  80. package/dist/db/repositories/signal.repository.d.ts +17 -0
  81. package/dist/db/repositories/signal.repository.js +35 -0
  82. package/dist/db/repositories/signal.repository.js.map +1 -0
  83. package/dist/db/repositories/synapse.repository.d.ts +25 -0
  84. package/dist/db/repositories/synapse.repository.js +50 -0
  85. package/dist/db/repositories/synapse.repository.js.map +1 -0
  86. package/dist/db/repositories/trade.repository.d.ts +36 -0
  87. package/dist/db/repositories/trade.repository.js +64 -0
  88. package/dist/db/repositories/trade.repository.js.map +1 -0
  89. package/dist/graph/weighted-graph.d.ts +58 -0
  90. package/dist/graph/weighted-graph.js +149 -0
  91. package/dist/graph/weighted-graph.js.map +1 -0
  92. package/dist/index.d.ts +2 -0
  93. package/dist/index.js +49 -0
  94. package/dist/index.js.map +1 -0
  95. package/dist/ipc/client.d.ts +16 -0
  96. package/dist/ipc/client.js +95 -0
  97. package/dist/ipc/client.js.map +1 -0
  98. package/dist/ipc/protocol.d.ts +8 -0
  99. package/dist/ipc/protocol.js +29 -0
  100. package/dist/ipc/protocol.js.map +1 -0
  101. package/dist/ipc/router.d.ts +32 -0
  102. package/dist/ipc/router.js +70 -0
  103. package/dist/ipc/router.js.map +1 -0
  104. package/dist/ipc/server.d.ts +18 -0
  105. package/dist/ipc/server.js +142 -0
  106. package/dist/ipc/server.js.map +1 -0
  107. package/dist/learning/calibrator.d.ts +6 -0
  108. package/dist/learning/calibrator.js +57 -0
  109. package/dist/learning/calibrator.js.map +1 -0
  110. package/dist/learning/chain-detector.d.ts +17 -0
  111. package/dist/learning/chain-detector.js +29 -0
  112. package/dist/learning/chain-detector.js.map +1 -0
  113. package/dist/learning/learning-engine.d.ts +31 -0
  114. package/dist/learning/learning-engine.js +85 -0
  115. package/dist/learning/learning-engine.js.map +1 -0
  116. package/dist/learning/pattern-extractor.d.ts +14 -0
  117. package/dist/learning/pattern-extractor.js +40 -0
  118. package/dist/learning/pattern-extractor.js.map +1 -0
  119. package/dist/mcp/http-server.d.ts +14 -0
  120. package/dist/mcp/http-server.js +117 -0
  121. package/dist/mcp/http-server.js.map +1 -0
  122. package/dist/mcp/server.d.ts +1 -0
  123. package/dist/mcp/server.js +67 -0
  124. package/dist/mcp/server.js.map +1 -0
  125. package/dist/mcp/tools.d.ts +7 -0
  126. package/dist/mcp/tools.js +158 -0
  127. package/dist/mcp/tools.js.map +1 -0
  128. package/dist/research/research-engine.d.ts +21 -0
  129. package/dist/research/research-engine.js +204 -0
  130. package/dist/research/research-engine.js.map +1 -0
  131. package/dist/services/analytics.service.d.ts +16 -0
  132. package/dist/services/analytics.service.js +64 -0
  133. package/dist/services/analytics.service.js.map +1 -0
  134. package/dist/services/insight.service.d.ts +11 -0
  135. package/dist/services/insight.service.js +25 -0
  136. package/dist/services/insight.service.js.map +1 -0
  137. package/dist/services/signal.service.d.ts +22 -0
  138. package/dist/services/signal.service.js +96 -0
  139. package/dist/services/signal.service.js.map +1 -0
  140. package/dist/services/strategy.service.d.ts +29 -0
  141. package/dist/services/strategy.service.js +115 -0
  142. package/dist/services/strategy.service.js.map +1 -0
  143. package/dist/services/synapse.service.d.ts +20 -0
  144. package/dist/services/synapse.service.js +48 -0
  145. package/dist/services/synapse.service.js.map +1 -0
  146. package/dist/services/trade.service.d.ts +37 -0
  147. package/dist/services/trade.service.js +114 -0
  148. package/dist/services/trade.service.js.map +1 -0
  149. package/dist/signals/fingerprint.d.ts +29 -0
  150. package/dist/signals/fingerprint.js +98 -0
  151. package/dist/signals/fingerprint.js.map +1 -0
  152. package/dist/signals/wilson-score.d.ts +10 -0
  153. package/dist/signals/wilson-score.js +19 -0
  154. package/dist/signals/wilson-score.js.map +1 -0
  155. package/dist/synapses/decay.d.ts +6 -0
  156. package/dist/synapses/decay.js +17 -0
  157. package/dist/synapses/decay.js.map +1 -0
  158. package/dist/synapses/hebbian.d.ts +11 -0
  159. package/dist/synapses/hebbian.js +21 -0
  160. package/dist/synapses/hebbian.js.map +1 -0
  161. package/dist/synapses/synapse-manager.d.ts +22 -0
  162. package/dist/synapses/synapse-manager.js +99 -0
  163. package/dist/synapses/synapse-manager.js.map +1 -0
  164. package/dist/trading-core.d.ts +17 -0
  165. package/dist/trading-core.js +235 -0
  166. package/dist/trading-core.js.map +1 -0
  167. package/dist/types/config.types.d.ts +52 -0
  168. package/dist/types/config.types.js +2 -0
  169. package/dist/types/config.types.js.map +1 -0
  170. package/dist/types/ipc.types.d.ts +11 -0
  171. package/dist/types/ipc.types.js +2 -0
  172. package/dist/types/ipc.types.js.map +1 -0
  173. package/dist/utils/events.d.ts +48 -0
  174. package/dist/utils/events.js +23 -0
  175. package/dist/utils/events.js.map +1 -0
  176. package/dist/utils/hash.d.ts +1 -0
  177. package/dist/utils/hash.js +5 -0
  178. package/dist/utils/hash.js.map +1 -0
  179. package/dist/utils/logger.d.ts +8 -0
  180. package/dist/utils/logger.js +39 -0
  181. package/dist/utils/logger.js.map +1 -0
  182. package/dist/utils/paths.d.ts +3 -0
  183. package/dist/utils/paths.js +18 -0
  184. package/dist/utils/paths.js.map +1 -0
  185. package/package.json +47 -0
  186. package/src/api/server.ts +160 -0
  187. package/src/cli/colors.ts +80 -0
  188. package/src/cli/commands/config.ts +76 -0
  189. package/src/cli/commands/doctor.ts +62 -0
  190. package/src/cli/commands/export.ts +24 -0
  191. package/src/cli/commands/import.ts +44 -0
  192. package/src/cli/commands/insights.ts +30 -0
  193. package/src/cli/commands/network.ts +43 -0
  194. package/src/cli/commands/query.ts +28 -0
  195. package/src/cli/commands/rules.ts +27 -0
  196. package/src/cli/commands/start.ts +93 -0
  197. package/src/cli/commands/status.ts +64 -0
  198. package/src/cli/commands/stop.ts +33 -0
  199. package/src/cli/ipc-helper.ts +22 -0
  200. package/src/config.ts +103 -0
  201. package/src/db/connection.ts +22 -0
  202. package/src/db/migrations/001_core.ts +43 -0
  203. package/src/db/migrations/002_synapses.ts +44 -0
  204. package/src/db/migrations/003_learning.ts +49 -0
  205. package/src/db/migrations/004_research.ts +30 -0
  206. package/src/db/migrations/index.ts +60 -0
  207. package/src/db/repositories/calibration.repository.ts +86 -0
  208. package/src/db/repositories/chain.repository.ts +70 -0
  209. package/src/db/repositories/graph.repository.ts +103 -0
  210. package/src/db/repositories/insight.repository.ts +80 -0
  211. package/src/db/repositories/rule.repository.ts +67 -0
  212. package/src/db/repositories/signal.repository.ts +48 -0
  213. package/src/db/repositories/synapse.repository.ts +71 -0
  214. package/src/db/repositories/trade.repository.ts +97 -0
  215. package/src/graph/weighted-graph.ts +194 -0
  216. package/src/index.ts +55 -0
  217. package/src/ipc/client.ts +112 -0
  218. package/src/ipc/protocol.ts +35 -0
  219. package/src/ipc/router.ts +113 -0
  220. package/src/ipc/server.ts +150 -0
  221. package/src/learning/calibrator.ts +57 -0
  222. package/src/learning/chain-detector.ts +43 -0
  223. package/src/learning/learning-engine.ts +94 -0
  224. package/src/learning/pattern-extractor.ts +53 -0
  225. package/src/mcp/http-server.ts +118 -0
  226. package/src/mcp/server.ts +72 -0
  227. package/src/mcp/tools.ts +256 -0
  228. package/src/research/research-engine.ts +223 -0
  229. package/src/services/analytics.service.ts +68 -0
  230. package/src/services/insight.service.ts +29 -0
  231. package/src/services/signal.service.ts +109 -0
  232. package/src/services/strategy.service.ts +130 -0
  233. package/src/services/synapse.service.ts +58 -0
  234. package/src/services/trade.service.ts +139 -0
  235. package/src/signals/fingerprint.ts +93 -0
  236. package/src/signals/wilson-score.ts +17 -0
  237. package/src/synapses/decay.ts +19 -0
  238. package/src/synapses/hebbian.ts +23 -0
  239. package/src/synapses/synapse-manager.ts +112 -0
  240. package/src/trading-core.ts +285 -0
  241. package/src/types/config.types.ts +60 -0
  242. package/src/types/ipc.types.ts +8 -0
  243. package/src/utils/events.ts +42 -0
  244. package/src/utils/hash.ts +5 -0
  245. package/src/utils/logger.ts +48 -0
  246. package/src/utils/paths.ts +19 -0
  247. package/tsconfig.json +18 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.js","sourceRoot":"","sources":["../../../src/cli/commands/stop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAExC,MAAM,UAAU,WAAW;IACzB,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;SACvB,WAAW,CAAC,+BAA+B,CAAC;SAC5C,MAAM,CAAC,GAAG,EAAE;QACX,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,mBAAmB,CAAC,CAAC;QAE7D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,KAAK,CAAC,CAAC,GAAG,CAAC,0DAA0D,CAAC,EAAE,CAAC,CAAC;YACpG,OAAO;QACT,CAAC;QAED,MAAM,GAAG,GAAG,QAAQ,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAElE,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,KAAK,CAAC,CAAC,OAAO,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC;QACxG,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAK,GAA6B,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACpD,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,KAAK,CAAC,CAAC,GAAG,CAAC,yDAAyD,CAAC,EAAE,CAAC,CAAC;YACrG,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,CAAC,0BAA0B,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAC/E,CAAC;QACH,CAAC;QAED,IAAI,CAAC;YAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { IpcClient } from '../ipc/client.js';
2
+ export declare function withIpc<T>(fn: (client: IpcClient) => Promise<T>): Promise<T>;
@@ -0,0 +1,26 @@
1
+ import { IpcClient } from '../ipc/client.js';
2
+ import { getPipeName } from '../utils/paths.js';
3
+ import { c, icons } from './colors.js';
4
+ export async function withIpc(fn) {
5
+ const client = new IpcClient(getPipeName(), 5000);
6
+ try {
7
+ await client.connect();
8
+ return await fn(client);
9
+ }
10
+ catch (err) {
11
+ if (err instanceof Error && err.message.includes('ENOENT')) {
12
+ console.error(`${icons.error} ${c.error('Trading Brain daemon is not running.')} Start it with: ${c.cyan('trading start')}`);
13
+ }
14
+ else if (err instanceof Error && err.message.includes('ECONNREFUSED')) {
15
+ console.error(`${icons.error} ${c.error('Trading Brain daemon is not responding.')} Try: ${c.cyan('trading stop && trading start')}`);
16
+ }
17
+ else {
18
+ console.error(`${icons.error} ${c.error(err instanceof Error ? err.message : String(err))}`);
19
+ }
20
+ process.exit(1);
21
+ }
22
+ finally {
23
+ client.disconnect();
24
+ }
25
+ }
26
+ //# sourceMappingURL=ipc-helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ipc-helper.js","sourceRoot":"","sources":["../../src/cli/ipc-helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEvC,MAAM,CAAC,KAAK,UAAU,OAAO,CAAI,EAAqC;IACpE,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,CAAC;IAClD,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,OAAO,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3D,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,CAAC,sCAAsC,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;QAChI,CAAC;aAAM,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YACxE,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,CAAC,yCAAyC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,+BAA+B,CAAC,EAAE,CAAC,CAAC;QACzI,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;QAChG,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,UAAU,EAAE,CAAC;IACtB,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { TradingBrainConfig } from './types/config.types.js';
2
+ export declare function loadConfig(configPath?: string): TradingBrainConfig;
package/dist/config.js ADDED
@@ -0,0 +1,107 @@
1
+ import path from 'node:path';
2
+ import fs from 'node:fs';
3
+ import { getDataDir, getPipeName } from './utils/paths.js';
4
+ const defaults = {
5
+ dataDir: getDataDir(),
6
+ dbPath: path.join(getDataDir(), 'trading-brain.db'),
7
+ ipc: {
8
+ pipeName: getPipeName(),
9
+ timeout: 5000,
10
+ },
11
+ api: {
12
+ port: 7779,
13
+ enabled: true,
14
+ },
15
+ mcpHttp: {
16
+ port: 7780,
17
+ enabled: true,
18
+ },
19
+ calibration: {
20
+ learningRate: 0.15,
21
+ weakenPenalty: 0.7,
22
+ decayHalfLifeDays: 14,
23
+ patternExtractionInterval: 50,
24
+ patternMinSamples: 10,
25
+ patternWilsonThreshold: 0.5,
26
+ wilsonZ: 1.96,
27
+ spreadingActivationDecay: 0.6,
28
+ spreadingActivationThreshold: 0.05,
29
+ minActivationsForWeight: 3,
30
+ minOutcomesForWeights: 5,
31
+ },
32
+ learning: {
33
+ intervalMs: 900_000, // 15 minutes
34
+ fingerprintSimilarityThreshold: 0.7,
35
+ chainMinLength: 3,
36
+ maxChains: 100,
37
+ },
38
+ research: {
39
+ intervalMs: 3_600_000, // 1 hour
40
+ initialDelayMs: 300_000, // 5 minutes
41
+ trendWindowDays: 7,
42
+ minTrades: 20,
43
+ maxInsights: 50,
44
+ },
45
+ log: {
46
+ level: 'info',
47
+ file: path.join(getDataDir(), 'trading-brain.log'),
48
+ maxSize: 10 * 1024 * 1024,
49
+ maxFiles: 3,
50
+ },
51
+ };
52
+ function applyEnvOverrides(config) {
53
+ if (process.env['TRADING_BRAIN_DATA_DIR']) {
54
+ config.dataDir = process.env['TRADING_BRAIN_DATA_DIR'];
55
+ config.dbPath = path.join(config.dataDir, 'trading-brain.db');
56
+ config.log.file = path.join(config.dataDir, 'trading-brain.log');
57
+ }
58
+ if (process.env['TRADING_BRAIN_DB_PATH'])
59
+ config.dbPath = process.env['TRADING_BRAIN_DB_PATH'];
60
+ if (process.env['TRADING_BRAIN_LOG_LEVEL'])
61
+ config.log.level = process.env['TRADING_BRAIN_LOG_LEVEL'];
62
+ if (process.env['TRADING_BRAIN_PIPE_NAME'])
63
+ config.ipc.pipeName = process.env['TRADING_BRAIN_PIPE_NAME'];
64
+ if (process.env['TRADING_BRAIN_API_PORT'])
65
+ config.api.port = Number(process.env['TRADING_BRAIN_API_PORT']);
66
+ if (process.env['TRADING_BRAIN_API_ENABLED'])
67
+ config.api.enabled = process.env['TRADING_BRAIN_API_ENABLED'] !== 'false';
68
+ if (process.env['TRADING_BRAIN_API_KEY'])
69
+ config.api.apiKey = process.env['TRADING_BRAIN_API_KEY'];
70
+ if (process.env['TRADING_BRAIN_MCP_HTTP_PORT'])
71
+ config.mcpHttp.port = Number(process.env['TRADING_BRAIN_MCP_HTTP_PORT']);
72
+ if (process.env['TRADING_BRAIN_MCP_HTTP_ENABLED'])
73
+ config.mcpHttp.enabled = process.env['TRADING_BRAIN_MCP_HTTP_ENABLED'] !== 'false';
74
+ }
75
+ function deepMerge(target, source) {
76
+ for (const key of Object.keys(source)) {
77
+ const val = source[key];
78
+ if (val && typeof val === 'object' && !Array.isArray(val) && target[key] && typeof target[key] === 'object') {
79
+ deepMerge(target[key], val);
80
+ }
81
+ else if (val !== undefined) {
82
+ target[key] = val;
83
+ }
84
+ }
85
+ }
86
+ export function loadConfig(configPath) {
87
+ const config = structuredClone(defaults);
88
+ if (configPath) {
89
+ const filePath = path.resolve(configPath);
90
+ if (fs.existsSync(filePath)) {
91
+ const raw = fs.readFileSync(filePath, 'utf-8');
92
+ const fileConfig = JSON.parse(raw);
93
+ deepMerge(config, fileConfig);
94
+ }
95
+ }
96
+ else {
97
+ const defaultConfigPath = path.join(getDataDir(), 'config.json');
98
+ if (fs.existsSync(defaultConfigPath)) {
99
+ const raw = fs.readFileSync(defaultConfigPath, 'utf-8');
100
+ const fileConfig = JSON.parse(raw);
101
+ deepMerge(config, fileConfig);
102
+ }
103
+ }
104
+ applyEnvOverrides(config);
105
+ return config;
106
+ }
107
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import Database from 'better-sqlite3';
2
+ export declare function createConnection(dbPath: string): Database.Database;
@@ -0,0 +1,19 @@
1
+ import Database from 'better-sqlite3';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { getLogger } from '../utils/logger.js';
5
+ export function createConnection(dbPath) {
6
+ const logger = getLogger();
7
+ const dir = path.dirname(dbPath);
8
+ if (!fs.existsSync(dir)) {
9
+ fs.mkdirSync(dir, { recursive: true });
10
+ }
11
+ logger.info(`Opening database at ${dbPath}`);
12
+ const db = new Database(dbPath);
13
+ db.pragma('journal_mode = WAL');
14
+ db.pragma('synchronous = NORMAL');
15
+ db.pragma('cache_size = 10000');
16
+ db.pragma('foreign_keys = ON');
17
+ return db;
18
+ }
19
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/db/connection.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,uBAAuB,MAAM,EAAE,CAAC,CAAC;IAC7C,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;IAEhC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;IAClC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAE/B,OAAO,EAAE,CAAC;AACZ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type Database from 'better-sqlite3';
2
+ export declare function up(db: Database.Database): void;
@@ -0,0 +1,42 @@
1
+ export function up(db) {
2
+ db.exec(`
3
+ CREATE TABLE IF NOT EXISTS trades (
4
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
5
+ fingerprint TEXT NOT NULL,
6
+ pair TEXT NOT NULL,
7
+ bot_type TEXT NOT NULL,
8
+ regime TEXT,
9
+ profit_pct REAL NOT NULL,
10
+ win INTEGER NOT NULL DEFAULT 0,
11
+ signals_json TEXT,
12
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
13
+ );
14
+
15
+ CREATE INDEX IF NOT EXISTS idx_trades_fingerprint ON trades(fingerprint);
16
+ CREATE INDEX IF NOT EXISTS idx_trades_pair ON trades(pair);
17
+ CREATE INDEX IF NOT EXISTS idx_trades_bot_type ON trades(bot_type);
18
+ CREATE INDEX IF NOT EXISTS idx_trades_created_at ON trades(created_at);
19
+ CREATE INDEX IF NOT EXISTS idx_trades_win ON trades(win);
20
+
21
+ CREATE TABLE IF NOT EXISTS signal_combos (
22
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
23
+ fingerprint TEXT NOT NULL,
24
+ signals_json TEXT NOT NULL,
25
+ regime TEXT,
26
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
27
+ );
28
+
29
+ CREATE INDEX IF NOT EXISTS idx_combos_fingerprint ON signal_combos(fingerprint);
30
+
31
+ CREATE TABLE IF NOT EXISTS pairs (
32
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
33
+ name TEXT NOT NULL UNIQUE,
34
+ total_trades INTEGER NOT NULL DEFAULT 0,
35
+ total_wins INTEGER NOT NULL DEFAULT 0,
36
+ total_profit REAL NOT NULL DEFAULT 0,
37
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
38
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
39
+ );
40
+ `);
41
+ }
42
+ //# sourceMappingURL=001_core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"001_core.js","sourceRoot":"","sources":["../../../src/db/migrations/001_core.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,EAAE,CAAC,EAAqB;IACtC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCP,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type Database from 'better-sqlite3';
2
+ export declare function up(db: Database.Database): void;
@@ -0,0 +1,43 @@
1
+ export function up(db) {
2
+ db.exec(`
3
+ CREATE TABLE IF NOT EXISTS synapses (
4
+ id TEXT PRIMARY KEY,
5
+ fingerprint TEXT NOT NULL,
6
+ weight REAL NOT NULL DEFAULT 0.5,
7
+ wins INTEGER NOT NULL DEFAULT 0,
8
+ losses INTEGER NOT NULL DEFAULT 0,
9
+ activations INTEGER NOT NULL DEFAULT 0,
10
+ total_profit REAL NOT NULL DEFAULT 0,
11
+ last_activated TEXT NOT NULL DEFAULT (datetime('now')),
12
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
13
+ );
14
+
15
+ CREATE INDEX IF NOT EXISTS idx_synapses_fingerprint ON synapses(fingerprint);
16
+ CREATE INDEX IF NOT EXISTS idx_synapses_weight ON synapses(weight);
17
+
18
+ CREATE TABLE IF NOT EXISTS graph_nodes (
19
+ id TEXT PRIMARY KEY,
20
+ type TEXT NOT NULL,
21
+ label TEXT NOT NULL,
22
+ activation REAL NOT NULL DEFAULT 0,
23
+ total_activations INTEGER NOT NULL DEFAULT 0
24
+ );
25
+
26
+ CREATE INDEX IF NOT EXISTS idx_graph_nodes_type ON graph_nodes(type);
27
+
28
+ CREATE TABLE IF NOT EXISTS graph_edges (
29
+ id TEXT PRIMARY KEY,
30
+ source TEXT NOT NULL,
31
+ target TEXT NOT NULL,
32
+ weight REAL NOT NULL DEFAULT 0.5,
33
+ activations INTEGER NOT NULL DEFAULT 0,
34
+ last_activated TEXT NOT NULL DEFAULT (datetime('now')),
35
+ FOREIGN KEY (source) REFERENCES graph_nodes(id),
36
+ FOREIGN KEY (target) REFERENCES graph_nodes(id)
37
+ );
38
+
39
+ CREATE INDEX IF NOT EXISTS idx_graph_edges_source ON graph_edges(source);
40
+ CREATE INDEX IF NOT EXISTS idx_graph_edges_target ON graph_edges(target);
41
+ `);
42
+ }
43
+ //# sourceMappingURL=002_synapses.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"002_synapses.js","sourceRoot":"","sources":["../../../src/db/migrations/002_synapses.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,EAAE,CAAC,EAAqB;IACtC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCP,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type Database from 'better-sqlite3';
2
+ export declare function up(db: Database.Database): void;
@@ -0,0 +1,48 @@
1
+ export function up(db) {
2
+ db.exec(`
3
+ CREATE TABLE IF NOT EXISTS rules (
4
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
5
+ pattern TEXT NOT NULL,
6
+ confidence REAL NOT NULL,
7
+ sample_count INTEGER NOT NULL,
8
+ win_rate REAL NOT NULL,
9
+ avg_profit REAL NOT NULL DEFAULT 0,
10
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
11
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
12
+ );
13
+
14
+ CREATE INDEX IF NOT EXISTS idx_rules_pattern ON rules(pattern);
15
+ CREATE INDEX IF NOT EXISTS idx_rules_confidence ON rules(confidence);
16
+
17
+ CREATE TABLE IF NOT EXISTS chains (
18
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
19
+ pair TEXT NOT NULL,
20
+ type TEXT NOT NULL,
21
+ length INTEGER NOT NULL,
22
+ fingerprints_json TEXT NOT NULL,
23
+ total_profit REAL NOT NULL DEFAULT 0,
24
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
25
+ );
26
+
27
+ CREATE INDEX IF NOT EXISTS idx_chains_pair ON chains(pair);
28
+ CREATE INDEX IF NOT EXISTS idx_chains_type ON chains(type);
29
+
30
+ CREATE TABLE IF NOT EXISTS calibration (
31
+ id TEXT PRIMARY KEY DEFAULT 'main',
32
+ learning_rate REAL NOT NULL,
33
+ weaken_penalty REAL NOT NULL,
34
+ decay_half_life_days INTEGER NOT NULL,
35
+ pattern_extraction_interval INTEGER NOT NULL,
36
+ pattern_min_samples INTEGER NOT NULL,
37
+ pattern_wilson_threshold REAL NOT NULL,
38
+ wilson_z REAL NOT NULL,
39
+ spreading_activation_decay REAL NOT NULL,
40
+ spreading_activation_threshold REAL NOT NULL,
41
+ min_activations_for_weight INTEGER NOT NULL,
42
+ min_outcomes_for_weights INTEGER NOT NULL,
43
+ last_calibration TEXT NOT NULL DEFAULT (datetime('now')),
44
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
45
+ );
46
+ `);
47
+ }
48
+ //# sourceMappingURL=003_learning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"003_learning.js","sourceRoot":"","sources":["../../../src/db/migrations/003_learning.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,EAAE,CAAC,EAAqB;IACtC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CP,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type Database from 'better-sqlite3';
2
+ export declare function up(db: Database.Database): void;
@@ -0,0 +1,29 @@
1
+ export function up(db) {
2
+ db.exec(`
3
+ CREATE TABLE IF NOT EXISTS insights (
4
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
5
+ type TEXT NOT NULL,
6
+ severity TEXT NOT NULL DEFAULT 'medium',
7
+ title TEXT NOT NULL,
8
+ description TEXT NOT NULL,
9
+ data_json TEXT,
10
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
11
+ );
12
+
13
+ CREATE INDEX IF NOT EXISTS idx_insights_type ON insights(type);
14
+ CREATE INDEX IF NOT EXISTS idx_insights_severity ON insights(severity);
15
+
16
+ CREATE VIRTUAL TABLE IF NOT EXISTS insights_fts USING fts5(
17
+ title, description, content=insights, content_rowid=id
18
+ );
19
+
20
+ CREATE TRIGGER IF NOT EXISTS insights_ai AFTER INSERT ON insights BEGIN
21
+ INSERT INTO insights_fts(rowid, title, description) VALUES (new.id, new.title, new.description);
22
+ END;
23
+
24
+ CREATE TRIGGER IF NOT EXISTS insights_ad AFTER DELETE ON insights BEGIN
25
+ INSERT INTO insights_fts(insights_fts, rowid, title, description) VALUES ('delete', old.id, old.title, old.description);
26
+ END;
27
+ `);
28
+ }
29
+ //# sourceMappingURL=004_research.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"004_research.js","sourceRoot":"","sources":["../../../src/db/migrations/004_research.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,EAAE,CAAC,EAAqB;IACtC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBP,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type Database from 'better-sqlite3';
2
+ export declare function runMigrations(db: Database.Database): void;
@@ -0,0 +1,45 @@
1
+ import { getLogger } from '../../utils/logger.js';
2
+ import { up as coreSchema } from './001_core.js';
3
+ import { up as synapsesSchema } from './002_synapses.js';
4
+ import { up as learningSchema } from './003_learning.js';
5
+ import { up as researchSchema } from './004_research.js';
6
+ const migrations = [
7
+ { version: 1, name: '001_core', up: coreSchema },
8
+ { version: 2, name: '002_synapses', up: synapsesSchema },
9
+ { version: 3, name: '003_learning', up: learningSchema },
10
+ { version: 4, name: '004_research', up: researchSchema },
11
+ ];
12
+ function ensureMigrationsTable(db) {
13
+ db.exec(`
14
+ CREATE TABLE IF NOT EXISTS migrations (
15
+ version INTEGER PRIMARY KEY,
16
+ name TEXT NOT NULL,
17
+ applied_at TEXT NOT NULL DEFAULT (datetime('now'))
18
+ );
19
+ `);
20
+ }
21
+ function getCurrentVersion(db) {
22
+ const row = db.prepare('SELECT MAX(version) as version FROM migrations').get();
23
+ return row?.version ?? 0;
24
+ }
25
+ export function runMigrations(db) {
26
+ const logger = getLogger();
27
+ ensureMigrationsTable(db);
28
+ const currentVersion = getCurrentVersion(db);
29
+ const pending = migrations.filter(m => m.version > currentVersion);
30
+ if (pending.length === 0) {
31
+ logger.info('Database is up to date');
32
+ return;
33
+ }
34
+ logger.info(`Running ${pending.length} migration(s) from version ${currentVersion}`);
35
+ const runAll = db.transaction(() => {
36
+ for (const migration of pending) {
37
+ logger.info(`Applying migration ${migration.name}`);
38
+ migration.up(db);
39
+ db.prepare('INSERT INTO migrations (version, name) VALUES (?, ?)').run(migration.version, migration.name);
40
+ }
41
+ });
42
+ runAll();
43
+ logger.info(`Migrations complete. Now at version ${pending[pending.length - 1].version}`);
44
+ }
45
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/db/migrations/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,EAAE,IAAI,UAAU,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,EAAE,IAAI,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,EAAE,IAAI,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,EAAE,IAAI,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAQzD,MAAM,UAAU,GAAgB;IAC9B,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,UAAU,EAAE;IAChD,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,cAAc,EAAE;IACxD,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,cAAc,EAAE;IACxD,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,cAAc,EAAE;CACzD,CAAC;AAEF,SAAS,qBAAqB,CAAC,EAAqB;IAClD,EAAE,CAAC,IAAI,CAAC;;;;;;GAMP,CAAC,CAAC;AACL,CAAC;AAED,SAAS,iBAAiB,CAAC,EAAqB;IAC9C,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,gDAAgD,CAAC,CAAC,GAAG,EAA4C,CAAC;IACzH,OAAO,GAAG,EAAE,OAAO,IAAI,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,EAAqB;IACjD,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,qBAAqB,CAAC,EAAE,CAAC,CAAC;IAE1B,MAAM,cAAc,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,cAAc,CAAC,CAAC;IAEnE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACtC,OAAO;IACT,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,MAAM,8BAA8B,cAAc,EAAE,CAAC,CAAC;IAErF,MAAM,MAAM,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;QACjC,KAAK,MAAM,SAAS,IAAI,OAAO,EAAE,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC,sBAAsB,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;YACpD,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACjB,EAAE,CAAC,OAAO,CAAC,sDAAsD,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QAC5G,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,EAAE,CAAC;IACT,MAAM,CAAC,IAAI,CAAC,uCAAuC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,OAAO,EAAE,CAAC,CAAC;AAC7F,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type Database from 'better-sqlite3';
2
+ import type { CalibrationConfig } from '../../types/config.types.js';
3
+ export interface CalibrationRecord {
4
+ id: string;
5
+ learning_rate: number;
6
+ weaken_penalty: number;
7
+ decay_half_life_days: number;
8
+ pattern_extraction_interval: number;
9
+ pattern_min_samples: number;
10
+ pattern_wilson_threshold: number;
11
+ wilson_z: number;
12
+ spreading_activation_decay: number;
13
+ spreading_activation_threshold: number;
14
+ min_activations_for_weight: number;
15
+ min_outcomes_for_weights: number;
16
+ last_calibration: string;
17
+ updated_at: string;
18
+ }
19
+ export declare class CalibrationRepository {
20
+ private db;
21
+ private stmts;
22
+ constructor(db: Database.Database);
23
+ save(cal: CalibrationConfig): void;
24
+ get(): CalibrationConfig | null;
25
+ }
@@ -0,0 +1,66 @@
1
+ export class CalibrationRepository {
2
+ db;
3
+ stmts;
4
+ constructor(db) {
5
+ this.db = db;
6
+ this.stmts = {
7
+ upsert: db.prepare(`
8
+ INSERT INTO calibration (id, learning_rate, weaken_penalty, decay_half_life_days,
9
+ pattern_extraction_interval, pattern_min_samples, pattern_wilson_threshold,
10
+ wilson_z, spreading_activation_decay, spreading_activation_threshold,
11
+ min_activations_for_weight, min_outcomes_for_weights, last_calibration, updated_at)
12
+ VALUES ('main', @learning_rate, @weaken_penalty, @decay_half_life_days,
13
+ @pattern_extraction_interval, @pattern_min_samples, @pattern_wilson_threshold,
14
+ @wilson_z, @spreading_activation_decay, @spreading_activation_threshold,
15
+ @min_activations_for_weight, @min_outcomes_for_weights, datetime('now'), datetime('now'))
16
+ ON CONFLICT(id) DO UPDATE SET
17
+ learning_rate = @learning_rate, weaken_penalty = @weaken_penalty,
18
+ decay_half_life_days = @decay_half_life_days,
19
+ pattern_extraction_interval = @pattern_extraction_interval,
20
+ pattern_min_samples = @pattern_min_samples,
21
+ pattern_wilson_threshold = @pattern_wilson_threshold,
22
+ wilson_z = @wilson_z,
23
+ spreading_activation_decay = @spreading_activation_decay,
24
+ spreading_activation_threshold = @spreading_activation_threshold,
25
+ min_activations_for_weight = @min_activations_for_weight,
26
+ min_outcomes_for_weights = @min_outcomes_for_weights,
27
+ last_calibration = datetime('now'), updated_at = datetime('now')
28
+ `),
29
+ get: db.prepare('SELECT * FROM calibration WHERE id = "main"'),
30
+ };
31
+ }
32
+ save(cal) {
33
+ this.stmts['upsert'].run({
34
+ learning_rate: cal.learningRate,
35
+ weaken_penalty: cal.weakenPenalty,
36
+ decay_half_life_days: cal.decayHalfLifeDays,
37
+ pattern_extraction_interval: cal.patternExtractionInterval,
38
+ pattern_min_samples: cal.patternMinSamples,
39
+ pattern_wilson_threshold: cal.patternWilsonThreshold,
40
+ wilson_z: cal.wilsonZ,
41
+ spreading_activation_decay: cal.spreadingActivationDecay,
42
+ spreading_activation_threshold: cal.spreadingActivationThreshold,
43
+ min_activations_for_weight: cal.minActivationsForWeight,
44
+ min_outcomes_for_weights: cal.minOutcomesForWeights,
45
+ });
46
+ }
47
+ get() {
48
+ const row = this.stmts['get'].get();
49
+ if (!row)
50
+ return null;
51
+ return {
52
+ learningRate: row.learning_rate,
53
+ weakenPenalty: row.weaken_penalty,
54
+ decayHalfLifeDays: row.decay_half_life_days,
55
+ patternExtractionInterval: row.pattern_extraction_interval,
56
+ patternMinSamples: row.pattern_min_samples,
57
+ patternWilsonThreshold: row.pattern_wilson_threshold,
58
+ wilsonZ: row.wilson_z,
59
+ spreadingActivationDecay: row.spreading_activation_decay,
60
+ spreadingActivationThreshold: row.spreading_activation_threshold,
61
+ minActivationsForWeight: row.min_activations_for_weight,
62
+ minOutcomesForWeights: row.min_outcomes_for_weights,
63
+ };
64
+ }
65
+ }
66
+ //# sourceMappingURL=calibration.repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calibration.repository.js","sourceRoot":"","sources":["../../../src/db/repositories/calibration.repository.ts"],"names":[],"mappings":"AAqBA,MAAM,OAAO,qBAAqB;IAGZ;IAFZ,KAAK,CAA4B;IAEzC,YAAoB,EAAqB;QAArB,OAAE,GAAF,EAAE,CAAmB;QACvC,IAAI,CAAC,KAAK,GAAG;YACX,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;OAqBlB,CAAC;YACF,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,6CAA6C,CAAC;SAC/D,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,GAAsB;QACzB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAE,CAAC,GAAG,CAAC;YACxB,aAAa,EAAE,GAAG,CAAC,YAAY;YAC/B,cAAc,EAAE,GAAG,CAAC,aAAa;YACjC,oBAAoB,EAAE,GAAG,CAAC,iBAAiB;YAC3C,2BAA2B,EAAE,GAAG,CAAC,yBAAyB;YAC1D,mBAAmB,EAAE,GAAG,CAAC,iBAAiB;YAC1C,wBAAwB,EAAE,GAAG,CAAC,sBAAsB;YACpD,QAAQ,EAAE,GAAG,CAAC,OAAO;YACrB,0BAA0B,EAAE,GAAG,CAAC,wBAAwB;YACxD,8BAA8B,EAAE,GAAG,CAAC,4BAA4B;YAChE,0BAA0B,EAAE,GAAG,CAAC,uBAAuB;YACvD,wBAAwB,EAAE,GAAG,CAAC,qBAAqB;SACpD,CAAC,CAAC;IACL,CAAC;IAED,GAAG;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAE,CAAC,GAAG,EAAmC,CAAC;QACtE,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,OAAO;YACL,YAAY,EAAE,GAAG,CAAC,aAAa;YAC/B,aAAa,EAAE,GAAG,CAAC,cAAc;YACjC,iBAAiB,EAAE,GAAG,CAAC,oBAAoB;YAC3C,yBAAyB,EAAE,GAAG,CAAC,2BAA2B;YAC1D,iBAAiB,EAAE,GAAG,CAAC,mBAAmB;YAC1C,sBAAsB,EAAE,GAAG,CAAC,wBAAwB;YACpD,OAAO,EAAE,GAAG,CAAC,QAAQ;YACrB,wBAAwB,EAAE,GAAG,CAAC,0BAA0B;YACxD,4BAA4B,EAAE,GAAG,CAAC,8BAA8B;YAChE,uBAAuB,EAAE,GAAG,CAAC,0BAA0B;YACvD,qBAAqB,EAAE,GAAG,CAAC,wBAAwB;SACpD,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,28 @@
1
+ import type Database from 'better-sqlite3';
2
+ export interface ChainRecord {
3
+ id: number;
4
+ pair: string;
5
+ type: string;
6
+ length: number;
7
+ fingerprints_json: string;
8
+ total_profit: number;
9
+ created_at: string;
10
+ }
11
+ export declare class ChainRepository {
12
+ private db;
13
+ private stmts;
14
+ constructor(db: Database.Database);
15
+ create(data: {
16
+ pair: string;
17
+ type: string;
18
+ length: number;
19
+ fingerprints: string[];
20
+ total_profit: number;
21
+ }): number;
22
+ getAll(): ChainRecord[];
23
+ getRecent(limit?: number): ChainRecord[];
24
+ getByPair(pair: string): ChainRecord[];
25
+ getByType(type: string): ChainRecord[];
26
+ count(): number;
27
+ pruneOldest(keepCount: number): void;
28
+ }
@@ -0,0 +1,52 @@
1
+ export class ChainRepository {
2
+ db;
3
+ stmts;
4
+ constructor(db) {
5
+ this.db = db;
6
+ this.stmts = {
7
+ create: db.prepare(`
8
+ INSERT INTO chains (pair, type, length, fingerprints_json, total_profit)
9
+ VALUES (@pair, @type, @length, @fingerprints_json, @total_profit)
10
+ `),
11
+ getAll: db.prepare('SELECT * FROM chains ORDER BY created_at DESC'),
12
+ getRecent: db.prepare('SELECT * FROM chains ORDER BY created_at DESC LIMIT ?'),
13
+ getByPair: db.prepare('SELECT * FROM chains WHERE pair = ? ORDER BY created_at DESC'),
14
+ getByType: db.prepare('SELECT * FROM chains WHERE type = ? ORDER BY created_at DESC'),
15
+ count: db.prepare('SELECT COUNT(*) as count FROM chains'),
16
+ deleteOldest: db.prepare('DELETE FROM chains WHERE id IN (SELECT id FROM chains ORDER BY created_at ASC LIMIT ?)'),
17
+ };
18
+ }
19
+ create(data) {
20
+ const result = this.stmts['create'].run({
21
+ pair: data.pair,
22
+ type: data.type,
23
+ length: data.length,
24
+ fingerprints_json: JSON.stringify(data.fingerprints),
25
+ total_profit: data.total_profit,
26
+ });
27
+ return result.lastInsertRowid;
28
+ }
29
+ getAll() {
30
+ return this.stmts['getAll'].all();
31
+ }
32
+ getRecent(limit = 10) {
33
+ return this.stmts['getRecent'].all(limit);
34
+ }
35
+ getByPair(pair) {
36
+ return this.stmts['getByPair'].all(pair);
37
+ }
38
+ getByType(type) {
39
+ return this.stmts['getByType'].all(type);
40
+ }
41
+ count() {
42
+ const row = this.stmts['count'].get();
43
+ return row.count;
44
+ }
45
+ pruneOldest(keepCount) {
46
+ const total = this.count();
47
+ if (total > keepCount) {
48
+ this.stmts['deleteOldest'].run(total - keepCount);
49
+ }
50
+ }
51
+ }
52
+ //# sourceMappingURL=chain.repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain.repository.js","sourceRoot":"","sources":["../../../src/db/repositories/chain.repository.ts"],"names":[],"mappings":"AAaA,MAAM,OAAO,eAAe;IAGN;IAFZ,KAAK,CAA4B;IAEzC,YAAoB,EAAqB;QAArB,OAAE,GAAF,EAAE,CAAmB;QACvC,IAAI,CAAC,KAAK,GAAG;YACX,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC;;;OAGlB,CAAC;YACF,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,+CAA+C,CAAC;YACnE,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,uDAAuD,CAAC;YAC9E,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,8DAA8D,CAAC;YACrF,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,8DAA8D,CAAC;YACrF,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,sCAAsC,CAAC;YACzD,YAAY,EAAE,EAAE,CAAC,OAAO,CAAC,wFAAwF,CAAC;SACnH,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,IAAkG;QACvG,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAE,CAAC,GAAG,CAAC;YACvC,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC;YACpD,YAAY,EAAE,IAAI,CAAC,YAAY;SAChC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,eAAyB,CAAC;IAC1C,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAE,CAAC,GAAG,EAAmB,CAAC;IACtD,CAAC;IAED,SAAS,CAAC,QAAgB,EAAE;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAE,CAAC,GAAG,CAAC,KAAK,CAAkB,CAAC;IAC9D,CAAC;IAED,SAAS,CAAC,IAAY;QACpB,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAE,CAAC,GAAG,CAAC,IAAI,CAAkB,CAAC;IAC7D,CAAC;IAED,SAAS,CAAC,IAAY;QACpB,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAE,CAAC,GAAG,CAAC,IAAI,CAAkB,CAAC;IAC7D,CAAC;IAED,KAAK;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAE,CAAC,GAAG,EAAuB,CAAC;QAC5D,OAAO,GAAG,CAAC,KAAK,CAAC;IACnB,CAAC;IAED,WAAW,CAAC,SAAiB;QAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC3B,IAAI,KAAK,GAAG,SAAS,EAAE,CAAC;YACtB,IAAI,CAAC,KAAK,CAAC,cAAc,CAAE,CAAC,GAAG,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;CACF"}