@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,22 @@
1
+ import type { SynapseManager } from '../synapses/synapse-manager.js';
2
+ import type { WeightedGraph } from '../graph/weighted-graph.js';
3
+ import type { CalibrationConfig } from '../types/config.types.js';
4
+ import { type SignalInput } from '../signals/fingerprint.js';
5
+ export declare class SignalService {
6
+ private synapseManager;
7
+ private graph;
8
+ private cal;
9
+ private tradeCount;
10
+ constructor(synapseManager: SynapseManager, graph: WeightedGraph, cal: CalibrationConfig, tradeCount: () => number);
11
+ updateCalibration(cal: CalibrationConfig): void;
12
+ /**
13
+ * Get brain-weighted signal strengths based on learned experience.
14
+ * Ported from tradingBrain.js getSignalWeights().
15
+ */
16
+ getSignalWeights(signals: SignalInput, regime?: string): Record<string, number>;
17
+ /**
18
+ * Get Wilson Score confidence for signal pattern.
19
+ * Ported from tradingBrain.js getConfidence().
20
+ */
21
+ getConfidence(signals: SignalInput, regime?: string): number;
22
+ }
@@ -0,0 +1,96 @@
1
+ import { fingerprint } from '../signals/fingerprint.js';
2
+ import { wilsonScore } from '../signals/wilson-score.js';
3
+ import { NODE_TYPES } from '../graph/weighted-graph.js';
4
+ const DEFAULT_WEIGHTS = {
5
+ rsi_oversold: 30,
6
+ rsi_overbought: 30,
7
+ rsi7_oversold: 15,
8
+ rsi7_overbought: 15,
9
+ macd_bullish: 20,
10
+ macd_bearish: 20,
11
+ trend_up: 15,
12
+ trend_down: 15,
13
+ mean_reversion_buy: 10,
14
+ mean_reversion_sell: 10,
15
+ combo_bonus: 0,
16
+ };
17
+ export class SignalService {
18
+ synapseManager;
19
+ graph;
20
+ cal;
21
+ tradeCount;
22
+ constructor(synapseManager, graph, cal, tradeCount) {
23
+ this.synapseManager = synapseManager;
24
+ this.graph = graph;
25
+ this.cal = cal;
26
+ this.tradeCount = tradeCount;
27
+ }
28
+ updateCalibration(cal) {
29
+ this.cal = cal;
30
+ }
31
+ /**
32
+ * Get brain-weighted signal strengths based on learned experience.
33
+ * Ported from tradingBrain.js getSignalWeights().
34
+ */
35
+ getSignalWeights(signals, regime) {
36
+ const weights = { ...DEFAULT_WEIGHTS };
37
+ if (this.tradeCount() < this.cal.minOutcomesForWeights)
38
+ return weights;
39
+ const fp = fingerprint({ ...signals, regime });
40
+ const synapse = this.synapseManager.getByFingerprint(fp);
41
+ // Direct synapse match (fast path)
42
+ if (synapse && synapse.activations >= this.cal.minActivationsForWeight) {
43
+ const factor = synapse.weight / 0.5;
44
+ for (const key of Object.keys(DEFAULT_WEIGHTS)) {
45
+ if (key !== 'combo_bonus') {
46
+ weights[key] = Math.round(DEFAULT_WEIGHTS[key] * factor);
47
+ }
48
+ }
49
+ }
50
+ // Spreading activation for combo bonus
51
+ const comboNodeId = `combo_${fp}`;
52
+ if (this.graph.nodes[comboNodeId]) {
53
+ const activated = this.graph.spreadingActivation(comboNodeId, 1.0, this.cal.spreadingActivationDecay, this.cal.spreadingActivationThreshold, 3);
54
+ let winEnergy = 0;
55
+ let lossEnergy = 0;
56
+ for (const node of activated) {
57
+ if (node.id === 'outcome_win')
58
+ winEnergy = node.activation;
59
+ if (node.id === 'outcome_loss')
60
+ lossEnergy = node.activation;
61
+ }
62
+ const netEnergy = winEnergy - lossEnergy;
63
+ if (Math.abs(netEnergy) > 0.05) {
64
+ const spreadBonus = Math.round(netEnergy * 30);
65
+ weights['combo_bonus'] = Math.max(-20, Math.min(30, spreadBonus));
66
+ }
67
+ // Similar combo nodes boost
68
+ let similarBoost = 0;
69
+ for (const node of activated) {
70
+ if (node.type === NODE_TYPES.COMBO && node.id !== comboNodeId && node.activation > 0.1) {
71
+ const simSyn = this.synapseManager.getByFingerprint(node.label);
72
+ if (simSyn && simSyn.weight > 0.6 && simSyn.activations >= 3) {
73
+ similarBoost += Math.round((simSyn.weight - 0.5) * 10 * node.activation);
74
+ }
75
+ }
76
+ }
77
+ weights['combo_bonus'] = Math.max(-20, Math.min(30, (weights['combo_bonus'] ?? 0) + similarBoost));
78
+ }
79
+ return weights;
80
+ }
81
+ /**
82
+ * Get Wilson Score confidence for signal pattern.
83
+ * Ported from tradingBrain.js getConfidence().
84
+ */
85
+ getConfidence(signals, regime) {
86
+ if (this.tradeCount() < this.cal.minOutcomesForWeights)
87
+ return 0.5;
88
+ const fp = fingerprint({ ...signals, regime });
89
+ const synapse = this.synapseManager.getByFingerprint(fp);
90
+ if (!synapse || synapse.activations < this.cal.minActivationsForWeight)
91
+ return 0.5;
92
+ const total = synapse.wins + synapse.losses;
93
+ return wilsonScore(synapse.wins, total, this.cal.wilsonZ);
94
+ }
95
+ }
96
+ //# sourceMappingURL=signal.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signal.service.js","sourceRoot":"","sources":["../../src/services/signal.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { SynapseManager } from '../synapses/synapse-manager.js';
2
+ import type { WeightedGraph } from '../graph/weighted-graph.js';
3
+ import type { CalibrationConfig } from '../types/config.types.js';
4
+ export interface DCAMultiplierResult {
5
+ multiplier: number;
6
+ reason: string;
7
+ }
8
+ export interface GridParamsResult {
9
+ spacingMultiplier: number;
10
+ reason: string;
11
+ }
12
+ export declare class StrategyService {
13
+ private synapseManager;
14
+ private graph;
15
+ private cal;
16
+ private tradeCount;
17
+ constructor(synapseManager: SynapseManager, graph: WeightedGraph, cal: CalibrationConfig, tradeCount: () => number);
18
+ updateCalibration(cal: CalibrationConfig): void;
19
+ /**
20
+ * Brain-recommended DCA multiplier based on regime success.
21
+ * Ported from tradingBrain.js getDCAMultiplier().
22
+ */
23
+ getDCAMultiplier(regime: string, rsi: number, volatility: number): DCAMultiplierResult;
24
+ /**
25
+ * Brain-recommended grid spacing based on volatility history.
26
+ * Ported from tradingBrain.js getGridParams().
27
+ */
28
+ getGridParams(regime: string, volatility: number, pair: string): GridParamsResult;
29
+ }
@@ -0,0 +1,115 @@
1
+ import { fingerprint, fingerprintSimilarity, classifyVolatility } from '../signals/fingerprint.js';
2
+ export class StrategyService {
3
+ synapseManager;
4
+ graph;
5
+ cal;
6
+ tradeCount;
7
+ constructor(synapseManager, graph, cal, tradeCount) {
8
+ this.synapseManager = synapseManager;
9
+ this.graph = graph;
10
+ this.cal = cal;
11
+ this.tradeCount = tradeCount;
12
+ }
13
+ updateCalibration(cal) {
14
+ this.cal = cal;
15
+ }
16
+ /**
17
+ * Brain-recommended DCA multiplier based on regime success.
18
+ * Ported from tradingBrain.js getDCAMultiplier().
19
+ */
20
+ getDCAMultiplier(regime, rsi, volatility) {
21
+ const result = { multiplier: 1.0, reason: 'Standard' };
22
+ if (this.tradeCount() < 10)
23
+ return result;
24
+ const signals = { rsi14: rsi, macd: 0, trendScore: 0, volatility };
25
+ const fp = fingerprint({ ...signals, regime });
26
+ // Try spreading activation from regime node
27
+ const regimeNodeId = `regime_${regime}`;
28
+ let bestWeight = 0.5;
29
+ let bestActivations = 0;
30
+ if (this.graph.nodes[regimeNodeId]) {
31
+ const activated = this.graph.spreadingActivation(regimeNodeId, 1.0, 0.5, 0.05, 3);
32
+ const winNode = activated.find(n => n.id === 'outcome_win');
33
+ const lossNode = activated.find(n => n.id === 'outcome_loss');
34
+ if (winNode || lossNode) {
35
+ const winE = winNode?.activation || 0;
36
+ const lossE = lossNode?.activation || 0;
37
+ const total = winE + lossE;
38
+ if (total > 0) {
39
+ bestWeight = winE / total;
40
+ bestActivations = 10;
41
+ }
42
+ }
43
+ }
44
+ // Fallback: fingerprint similarity scan
45
+ if (bestActivations < 5) {
46
+ for (const syn of this.synapseManager.getAll()) {
47
+ const sim = fingerprintSimilarity(fp, syn.fingerprint);
48
+ if (sim >= 0.6 && syn.activations > bestActivations) {
49
+ bestWeight = syn.weight;
50
+ bestActivations = syn.activations;
51
+ }
52
+ }
53
+ }
54
+ if (bestActivations >= 5) {
55
+ result.multiplier = Math.max(0.3, Math.min(2.5, bestWeight * 2));
56
+ const winRate = bestWeight > 0.5 ? 'hohe' : 'niedrige';
57
+ result.reason = `Brain: ${winRate} Recovery-Rate (n=${bestActivations})`;
58
+ }
59
+ return result;
60
+ }
61
+ /**
62
+ * Brain-recommended grid spacing based on volatility history.
63
+ * Ported from tradingBrain.js getGridParams().
64
+ */
65
+ getGridParams(regime, volatility, pair) {
66
+ const result = { spacingMultiplier: 1.0, reason: 'Standard' };
67
+ if (this.tradeCount() < 10)
68
+ return result;
69
+ const volClass = classifyVolatility(volatility);
70
+ const volNodeId = `sig_vol_${volClass}`;
71
+ if (this.graph.nodes[volNodeId]) {
72
+ const activated = this.graph.spreadingActivation(volNodeId, 1.0, 0.5, 0.05, 3);
73
+ const winNode = activated.find(n => n.id === 'outcome_win');
74
+ const lossNode = activated.find(n => n.id === 'outcome_loss');
75
+ if (winNode || lossNode) {
76
+ const winE = winNode?.activation || 0;
77
+ const lossE = lossNode?.activation || 0;
78
+ const ratio = (winE - lossE) / Math.max(winE + lossE, 0.01);
79
+ if (ratio < -0.2) {
80
+ result.spacingMultiplier = 1.3 + Math.abs(ratio) * 0.5;
81
+ result.reason = `Brain: ${volClass} Vol historisch schwach → breitere Grids`;
82
+ }
83
+ else if (ratio > 0.2) {
84
+ result.spacingMultiplier = 0.7 + (1 - ratio) * 0.3;
85
+ result.reason = `Brain: ${volClass} Vol historisch stark → engere Grids`;
86
+ }
87
+ return result;
88
+ }
89
+ }
90
+ // Fallback: synapse scan
91
+ const signals = { rsi14: 50, macd: 0, trendScore: 0, volatility };
92
+ const fp = fingerprint({ ...signals, regime });
93
+ let totalWeight = 0, count = 0;
94
+ for (const syn of this.synapseManager.getAll()) {
95
+ const sim = fingerprintSimilarity(fp, syn.fingerprint);
96
+ if (sim >= 0.6 && syn.activations >= 3) {
97
+ totalWeight += syn.weight;
98
+ count++;
99
+ }
100
+ }
101
+ if (count >= 2) {
102
+ const avgWeight = totalWeight / count;
103
+ if (avgWeight < 0.4) {
104
+ result.spacingMultiplier = 1.3 + (0.4 - avgWeight);
105
+ result.reason = `Brain: historisch schwach → breitere Grids`;
106
+ }
107
+ else if (avgWeight > 0.6) {
108
+ result.spacingMultiplier = 0.7 + (1.0 - avgWeight) * 0.5;
109
+ result.reason = `Brain: historisch stark → engere Grids`;
110
+ }
111
+ }
112
+ return result;
113
+ }
114
+ }
115
+ //# sourceMappingURL=strategy.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategy.service.js","sourceRoot":"","sources":["../../src/services/strategy.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { SynapseManager } from '../synapses/synapse-manager.js';
2
+ import type { WeightedGraph, ActivatedNode } from '../graph/weighted-graph.js';
3
+ export declare class SynapseService {
4
+ private synapseManager;
5
+ private graph;
6
+ constructor(synapseManager: SynapseManager, graph: WeightedGraph);
7
+ explore(query: string): ActivatedNode[];
8
+ findPath(fromId: string, toId: string): string[] | null;
9
+ getStats(): {
10
+ totalSynapses: number;
11
+ avgWeight: number;
12
+ graphNodes: number;
13
+ graphEdges: number;
14
+ strongest: Array<{
15
+ id: string;
16
+ weight: number;
17
+ activations: number;
18
+ }>;
19
+ };
20
+ }
@@ -0,0 +1,48 @@
1
+ export class SynapseService {
2
+ synapseManager;
3
+ graph;
4
+ constructor(synapseManager, graph) {
5
+ this.synapseManager = synapseManager;
6
+ this.graph = graph;
7
+ }
8
+ explore(query) {
9
+ // Find matching node (exact or fuzzy)
10
+ let startNode = null;
11
+ for (const node of Object.values(this.graph.nodes)) {
12
+ if (node.id === query || node.label === query) {
13
+ startNode = node.id;
14
+ break;
15
+ }
16
+ }
17
+ if (!startNode) {
18
+ const queryLower = query.toLowerCase();
19
+ for (const node of Object.values(this.graph.nodes)) {
20
+ if (node.label.toLowerCase().includes(queryLower) || node.id.toLowerCase().includes(queryLower)) {
21
+ startNode = node.id;
22
+ break;
23
+ }
24
+ }
25
+ }
26
+ if (!startNode)
27
+ return [];
28
+ return this.graph.spreadingActivation(startNode, 1.0, 0.6, 0.05, 4);
29
+ }
30
+ findPath(fromId, toId) {
31
+ return this.graph.findPath(fromId, toId);
32
+ }
33
+ getStats() {
34
+ const strongest = this.synapseManager.getStrongest(5).map(s => ({
35
+ id: s.id,
36
+ weight: s.weight,
37
+ activations: s.activations,
38
+ }));
39
+ return {
40
+ totalSynapses: this.synapseManager.count(),
41
+ avgWeight: this.synapseManager.getAvgWeight(),
42
+ graphNodes: this.graph.getNodeCount(),
43
+ graphEdges: this.graph.getEdgeCount(),
44
+ strongest,
45
+ };
46
+ }
47
+ }
48
+ //# sourceMappingURL=synapse.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synapse.service.js","sourceRoot":"","sources":["../../src/services/synapse.service.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,cAAc;IAEf;IACA;IAFV,YACU,cAA8B,EAC9B,KAAoB;QADpB,mBAAc,GAAd,cAAc,CAAgB;QAC9B,UAAK,GAAL,KAAK,CAAe;IAC3B,CAAC;IAEJ,OAAO,CAAC,KAAa;QACnB,sCAAsC;QACtC,IAAI,SAAS,GAAkB,IAAI,CAAC;QACpC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACnD,IAAI,IAAI,CAAC,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;gBAC9C,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC;gBACpB,MAAM;YACR,CAAC;QACH,CAAC;QAED,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;YACvC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;gBACnD,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;oBAChG,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC;oBACpB,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,CAAC,SAAS;YAAE,OAAO,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,SAAS,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,QAAQ,CAAC,MAAc,EAAE,IAAY;QACnC,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,QAAQ;QAON,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC9D,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,WAAW,EAAE,CAAC,CAAC,WAAW;SAC3B,CAAC,CAAC,CAAC;QACJ,OAAO;YACL,aAAa,EAAE,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE;YAC1C,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE;YAC7C,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE;YACrC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE;YACrC,SAAS;SACV,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,37 @@
1
+ import type { TradeRepository, TradeRecord } from '../db/repositories/trade.repository.js';
2
+ import type { SignalRepository } from '../db/repositories/signal.repository.js';
3
+ import type { ChainRepository } from '../db/repositories/chain.repository.js';
4
+ import type { SynapseManager } from '../synapses/synapse-manager.js';
5
+ import type { WeightedGraph } from '../graph/weighted-graph.js';
6
+ import type { CalibrationConfig, LearningConfig } from '../types/config.types.js';
7
+ import { type SignalInput } from '../signals/fingerprint.js';
8
+ export interface RecordOutcomeInput {
9
+ signals: SignalInput;
10
+ regime?: string;
11
+ profitPct: number;
12
+ win: boolean;
13
+ botType: string;
14
+ pair: string;
15
+ }
16
+ export declare class TradeService {
17
+ private tradeRepo;
18
+ private signalRepo;
19
+ private chainRepo;
20
+ private synapseManager;
21
+ private graph;
22
+ private cal;
23
+ private learningConfig;
24
+ private recentTrades;
25
+ private logger;
26
+ constructor(tradeRepo: TradeRepository, signalRepo: SignalRepository, chainRepo: ChainRepository, synapseManager: SynapseManager, graph: WeightedGraph, cal: CalibrationConfig, learningConfig: LearningConfig);
27
+ updateCalibration(cal: CalibrationConfig): void;
28
+ recordOutcome(input: RecordOutcomeInput): {
29
+ tradeId: number;
30
+ fingerprint: string;
31
+ synapseWeight: number;
32
+ };
33
+ query(search: string, limit?: number): TradeRecord[];
34
+ getRecent(limit?: number): TradeRecord[];
35
+ getByPair(pair: string): TradeRecord[];
36
+ count(): number;
37
+ }
@@ -0,0 +1,114 @@
1
+ import { fingerprint, decomposeFingerprint } from '../signals/fingerprint.js';
2
+ import { NODE_TYPES } from '../graph/weighted-graph.js';
3
+ import { detectChain } from '../learning/chain-detector.js';
4
+ import { getLogger } from '../utils/logger.js';
5
+ import { getEventBus } from '../utils/events.js';
6
+ export class TradeService {
7
+ tradeRepo;
8
+ signalRepo;
9
+ chainRepo;
10
+ synapseManager;
11
+ graph;
12
+ cal;
13
+ learningConfig;
14
+ recentTrades = [];
15
+ logger = getLogger();
16
+ constructor(tradeRepo, signalRepo, chainRepo, synapseManager, graph, cal, learningConfig) {
17
+ this.tradeRepo = tradeRepo;
18
+ this.signalRepo = signalRepo;
19
+ this.chainRepo = chainRepo;
20
+ this.synapseManager = synapseManager;
21
+ this.graph = graph;
22
+ this.cal = cal;
23
+ this.learningConfig = learningConfig;
24
+ // Seed recent trades for chain detection
25
+ this.recentTrades = this.tradeRepo.getRecent(10);
26
+ }
27
+ updateCalibration(cal) {
28
+ this.cal = cal;
29
+ }
30
+ recordOutcome(input) {
31
+ const bus = getEventBus();
32
+ const fp = fingerprint({ ...input.signals, regime: input.regime });
33
+ // 1. Store signal combo
34
+ this.signalRepo.create(fp, JSON.stringify(input.signals), input.regime);
35
+ // 2. Store trade
36
+ const tradeId = this.tradeRepo.create({
37
+ fingerprint: fp,
38
+ pair: input.pair,
39
+ bot_type: input.botType,
40
+ regime: input.regime,
41
+ profit_pct: input.profitPct,
42
+ win: input.win,
43
+ signals_json: JSON.stringify(input.signals),
44
+ });
45
+ // 3. Hebbian synapse update
46
+ const synapse = input.win
47
+ ? this.synapseManager.recordWin(fp, input.profitPct)
48
+ : this.synapseManager.recordLoss(fp, input.profitPct);
49
+ // 4. Update weighted graph
50
+ const graphNodes = decomposeFingerprint(fp, input.regime, input.pair, input.botType);
51
+ const outcomeNodeId = input.win ? 'outcome_win' : 'outcome_loss';
52
+ for (const gn of graphNodes) {
53
+ this.graph.addNode(gn.id, gn.type, gn.label);
54
+ }
55
+ this.graph.addNode(outcomeNodeId, NODE_TYPES.OUTCOME, input.win ? 'win' : 'loss');
56
+ const comboNodeId = `combo_${fp}`;
57
+ for (const gn of graphNodes) {
58
+ if (gn.id !== comboNodeId) {
59
+ this.graph.addEdge(gn.id, comboNodeId, 0.5);
60
+ if (input.win) {
61
+ this.graph.strengthenEdge(gn.id, comboNodeId, this.cal.learningRate);
62
+ }
63
+ else {
64
+ this.graph.weakenEdge(gn.id, comboNodeId, this.cal.weakenPenalty);
65
+ }
66
+ }
67
+ }
68
+ this.graph.addEdge(comboNodeId, outcomeNodeId, 0.5);
69
+ if (input.win) {
70
+ this.graph.strengthenEdge(comboNodeId, outcomeNodeId, this.cal.learningRate);
71
+ }
72
+ else {
73
+ this.graph.weakenEdge(comboNodeId, outcomeNodeId, this.cal.weakenPenalty);
74
+ }
75
+ // Cross-connect co-occurring signals (Hebbian)
76
+ for (let i = 0; i < graphNodes.length; i++) {
77
+ for (let j = i + 1; j < graphNodes.length; j++) {
78
+ if (graphNodes[i].id !== comboNodeId && graphNodes[j].id !== comboNodeId) {
79
+ this.graph.addEdge(graphNodes[i].id, graphNodes[j].id, 0.3);
80
+ if (input.win) {
81
+ this.graph.strengthenEdge(graphNodes[i].id, graphNodes[j].id, this.cal.learningRate * 0.5);
82
+ }
83
+ }
84
+ }
85
+ }
86
+ // 5. Chain detection
87
+ const trade = this.tradeRepo.getById(tradeId);
88
+ this.recentTrades.push(trade);
89
+ if (this.recentTrades.length > 10)
90
+ this.recentTrades.shift();
91
+ const chain = detectChain(this.recentTrades, trade, this.learningConfig.chainMinLength);
92
+ if (chain) {
93
+ this.chainRepo.create(chain);
94
+ bus.emit('chain:detected', { pair: chain.pair, type: chain.type, length: chain.length });
95
+ this.logger.info(`Chain detected: ${chain.type} (${chain.length}x) on ${chain.pair}`);
96
+ }
97
+ bus.emit('trade:recorded', { tradeId, fingerprint: fp, win: input.win });
98
+ this.logger.info(`Recorded: ${fp} → ${input.win ? 'WIN' : 'LOSS'} (${input.profitPct.toFixed(2)}%) | weight: ${synapse.weight.toFixed(3)} | graph: ${this.graph.getNodeCount()}N/${this.graph.getEdgeCount()}E`);
99
+ return { tradeId, fingerprint: fp, synapseWeight: synapse.weight };
100
+ }
101
+ query(search, limit = 50) {
102
+ return this.tradeRepo.search(search, limit);
103
+ }
104
+ getRecent(limit = 10) {
105
+ return this.tradeRepo.getRecent(limit);
106
+ }
107
+ getByPair(pair) {
108
+ return this.tradeRepo.getByPair(pair);
109
+ }
110
+ count() {
111
+ return this.tradeRepo.count();
112
+ }
113
+ }
114
+ //# sourceMappingURL=trade.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trade.service.js","sourceRoot":"","sources":["../../src/services/trade.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export interface SignalInput {
2
+ rsi14?: number;
3
+ macd?: number;
4
+ trendScore?: number;
5
+ volatility?: number;
6
+ regime?: string;
7
+ }
8
+ export interface DecomposedNode {
9
+ id: string;
10
+ type: string;
11
+ label: string;
12
+ }
13
+ export declare function classifyRSI(rsi: number): string;
14
+ export declare function classifyMACD(macd: number, trendScore: number): string;
15
+ export declare function classifyTrend(trendScore: number): string;
16
+ export declare function classifyVolatility(volatility: number): string;
17
+ /**
18
+ * Create a signal fingerprint string from input signals.
19
+ * Format: rsi_class|macd_class|trend_class|vol_class[|regime]
20
+ */
21
+ export declare function fingerprint(signals: SignalInput): string;
22
+ /**
23
+ * Compare two fingerprints for similarity (0-1).
24
+ */
25
+ export declare function fingerprintSimilarity(fp1: string, fp2: string): number;
26
+ /**
27
+ * Decompose a fingerprint into individual graph node IDs for the weighted graph.
28
+ */
29
+ export declare function decomposeFingerprint(fp: string, regime?: string, pair?: string, botType?: string): DecomposedNode[];
@@ -0,0 +1,98 @@
1
+ import { NODE_TYPES } from '../graph/weighted-graph.js';
2
+ export function classifyRSI(rsi) {
3
+ if (rsi < 25)
4
+ return 'extreme_oversold';
5
+ if (rsi < 30)
6
+ return 'oversold';
7
+ if (rsi < 40)
8
+ return 'low';
9
+ if (rsi > 75)
10
+ return 'extreme_overbought';
11
+ if (rsi > 70)
12
+ return 'overbought';
13
+ if (rsi > 60)
14
+ return 'high';
15
+ return 'neutral';
16
+ }
17
+ export function classifyMACD(macd, trendScore) {
18
+ if (macd > 0 && trendScore > 0)
19
+ return 'bullish';
20
+ if (macd < 0 && trendScore < 0)
21
+ return 'bearish';
22
+ return 'neutral';
23
+ }
24
+ export function classifyTrend(trendScore) {
25
+ if (trendScore > 3)
26
+ return 'strong_up';
27
+ if (trendScore > 1)
28
+ return 'up';
29
+ if (trendScore < -3)
30
+ return 'strong_down';
31
+ if (trendScore < -1)
32
+ return 'down';
33
+ return 'flat';
34
+ }
35
+ export function classifyVolatility(volatility) {
36
+ if (volatility > 80)
37
+ return 'extreme';
38
+ if (volatility > 50)
39
+ return 'high';
40
+ if (volatility > 30)
41
+ return 'medium';
42
+ return 'low';
43
+ }
44
+ /**
45
+ * Create a signal fingerprint string from input signals.
46
+ * Format: rsi_class|macd_class|trend_class|vol_class[|regime]
47
+ */
48
+ export function fingerprint(signals) {
49
+ const parts = [
50
+ classifyRSI(signals.rsi14 ?? 50),
51
+ classifyMACD(signals.macd ?? 0, signals.trendScore ?? 0),
52
+ classifyTrend(signals.trendScore ?? 0),
53
+ classifyVolatility(signals.volatility ?? 30),
54
+ ];
55
+ if (signals.regime)
56
+ parts.push(signals.regime);
57
+ return parts.join('|');
58
+ }
59
+ /**
60
+ * Compare two fingerprints for similarity (0-1).
61
+ */
62
+ export function fingerprintSimilarity(fp1, fp2) {
63
+ const parts1 = fp1.split('|');
64
+ const parts2 = fp2.split('|');
65
+ const maxLen = Math.max(parts1.length, parts2.length);
66
+ if (maxLen === 0)
67
+ return 1;
68
+ let matches = 0;
69
+ for (let i = 0; i < maxLen; i++) {
70
+ if (parts1[i] === parts2[i])
71
+ matches++;
72
+ }
73
+ return matches / maxLen;
74
+ }
75
+ /**
76
+ * Decompose a fingerprint into individual graph node IDs for the weighted graph.
77
+ */
78
+ export function decomposeFingerprint(fp, regime, pair, botType) {
79
+ const parts = fp.split('|');
80
+ const nodes = [];
81
+ if (parts[0])
82
+ nodes.push({ id: `sig_rsi_${parts[0]}`, type: NODE_TYPES.SIGNAL, label: parts[0] });
83
+ if (parts[1])
84
+ nodes.push({ id: `sig_macd_${parts[1]}`, type: NODE_TYPES.SIGNAL, label: parts[1] });
85
+ if (parts[2])
86
+ nodes.push({ id: `sig_trend_${parts[2]}`, type: NODE_TYPES.SIGNAL, label: parts[2] });
87
+ if (parts[3])
88
+ nodes.push({ id: `sig_vol_${parts[3]}`, type: NODE_TYPES.SIGNAL, label: parts[3] });
89
+ if (regime)
90
+ nodes.push({ id: `regime_${regime}`, type: NODE_TYPES.REGIME, label: regime });
91
+ if (pair)
92
+ nodes.push({ id: `pair_${pair}`, type: NODE_TYPES.PAIR, label: pair });
93
+ if (botType)
94
+ nodes.push({ id: `bot_${botType}`, type: NODE_TYPES.BOT_TYPE, label: botType });
95
+ nodes.push({ id: `combo_${fp}`, type: NODE_TYPES.COMBO, label: fp });
96
+ return nodes;
97
+ }
98
+ //# sourceMappingURL=fingerprint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../../src/signals/fingerprint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAgBxD,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,IAAI,GAAG,GAAG,EAAE;QAAE,OAAO,kBAAkB,CAAC;IACxC,IAAI,GAAG,GAAG,EAAE;QAAE,OAAO,UAAU,CAAC;IAChC,IAAI,GAAG,GAAG,EAAE;QAAE,OAAO,KAAK,CAAC;IAC3B,IAAI,GAAG,GAAG,EAAE;QAAE,OAAO,oBAAoB,CAAC;IAC1C,IAAI,GAAG,GAAG,EAAE;QAAE,OAAO,YAAY,CAAC;IAClC,IAAI,GAAG,GAAG,EAAE;QAAE,OAAO,MAAM,CAAC;IAC5B,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,UAAkB;IAC3D,IAAI,IAAI,GAAG,CAAC,IAAI,UAAU,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IACjD,IAAI,IAAI,GAAG,CAAC,IAAI,UAAU,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IACjD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,UAAkB;IAC9C,IAAI,UAAU,GAAG,CAAC;QAAE,OAAO,WAAW,CAAC;IACvC,IAAI,UAAU,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,UAAU,GAAG,CAAC,CAAC;QAAE,OAAO,aAAa,CAAC;IAC1C,IAAI,UAAU,GAAG,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IACnC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,UAAkB;IACnD,IAAI,UAAU,GAAG,EAAE;QAAE,OAAO,SAAS,CAAC;IACtC,IAAI,UAAU,GAAG,EAAE;QAAE,OAAO,MAAM,CAAC;IACnC,IAAI,UAAU,GAAG,EAAE;QAAE,OAAO,QAAQ,CAAC;IACrC,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,OAAoB;IAC9C,MAAM,KAAK,GAAG;QACZ,WAAW,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;QAChC,YAAY,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,EAAE,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC;QACxD,aAAa,CAAC,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC;QACtC,kBAAkB,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC;KAC7C,CAAC;IACF,IAAI,OAAO,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAW,EAAE,GAAW;IAC5D,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACtD,IAAI,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC3B,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC;YAAE,OAAO,EAAE,CAAC;IACzC,CAAC;IACD,OAAO,OAAO,GAAG,MAAM,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,EAAU,EAAE,MAAe,EAAE,IAAa,EAAE,OAAgB;IAC/F,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5B,MAAM,KAAK,GAAqB,EAAE,CAAC;IACnC,IAAI,KAAK,CAAC,CAAC,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,WAAW,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAClG,IAAI,KAAK,CAAC,CAAC,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,YAAY,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACnG,IAAI,KAAK,CAAC,CAAC,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,aAAa,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACpG,IAAI,KAAK,CAAC,CAAC,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,WAAW,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAClG,IAAI,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,UAAU,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3F,IAAI,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,QAAQ,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACjF,IAAI,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,OAAO,OAAO,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAC7F,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;IACrE,OAAO,KAAK,CAAC;AACf,CAAC"}