@aiaiaichain/agent 0.1.6 → 0.1.8

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 (121) hide show
  1. package/dist/api/ExtensionAPI.d.ts +0 -1
  2. package/dist/api/ExtensionAPI.js +3 -7
  3. package/dist/api/Registry.d.ts +0 -1
  4. package/dist/api/Registry.js +54 -57
  5. package/dist/cli.d.ts +0 -1
  6. package/dist/cli.js +364 -768
  7. package/dist/core/AgentDir.d.ts +1 -1
  8. package/dist/core/AgentDir.js +45 -39
  9. package/dist/core/ChainConfig.d.ts +0 -1
  10. package/dist/core/ChainConfig.js +51 -55
  11. package/dist/core/EnvLoader.d.ts +4 -1
  12. package/dist/core/EnvLoader.js +97 -84
  13. package/dist/core/SystemMonitor.d.ts +0 -1
  14. package/dist/core/SystemMonitor.js +70 -85
  15. package/dist/index.d.ts +4 -61
  16. package/dist/index.js +19 -26
  17. package/dist/loader.d.ts +0 -1
  18. package/dist/loader.js +64 -67
  19. package/dist/mcp/entry.d.ts +0 -1
  20. package/dist/mcp/entry.js +3 -6
  21. package/dist/mcp/server.d.ts +0 -1
  22. package/dist/mcp/server.js +152 -156
  23. package/dist/models/CostTracker.d.ts +0 -1
  24. package/dist/models/CostTracker.js +58 -61
  25. package/dist/models/ModelRegistry.d.ts +0 -1
  26. package/dist/models/ModelRegistry.js +195 -155
  27. package/dist/providers/ProviderRegistry.d.ts +0 -1
  28. package/dist/providers/ProviderRegistry.js +33 -36
  29. package/dist/runner/AgentRunner.d.ts +0 -1
  30. package/dist/runner/AgentRunner.js +180 -184
  31. package/dist/runner/ModelClient.d.ts +0 -1
  32. package/dist/runner/ModelClient.js +133 -134
  33. package/dist/runner/SwarmRouter.d.ts +0 -1
  34. package/dist/runner/SwarmRouter.js +17 -22
  35. package/dist/runner/ToolDispatcher.d.ts +0 -1
  36. package/dist/runner/ToolDispatcher.js +30 -33
  37. package/dist/scheduler/AgentScheduler.d.ts +0 -1
  38. package/dist/scheduler/AgentScheduler.js +99 -103
  39. package/dist/session/ContextStore.d.ts +1 -1
  40. package/dist/session/ContextStore.js +76 -78
  41. package/dist/session/GoalManager.d.ts +0 -1
  42. package/dist/session/GoalManager.js +96 -100
  43. package/dist/session/MemoryStore.d.ts +2 -1
  44. package/dist/session/MemoryStore.js +108 -87
  45. package/dist/session/SessionManager.d.ts +5 -4
  46. package/dist/session/SessionManager.js +83 -62
  47. package/dist/session/SessionStore.d.ts +0 -1
  48. package/dist/session/SessionStore.js +112 -116
  49. package/dist/setup/SetupWizard.d.ts +0 -1
  50. package/dist/setup/SetupWizard.js +61 -64
  51. package/dist/tools/CrossTools.d.ts +0 -1
  52. package/dist/tools/CrossTools.js +140 -144
  53. package/dist/tools/GmgnIntegration.d.ts +0 -1
  54. package/dist/tools/GmgnIntegration.js +220 -230
  55. package/dist/tools/MarketSentiment.d.ts +0 -1
  56. package/dist/tools/MarketSentiment.js +213 -195
  57. package/dist/tools/NewsSentiment.d.ts +0 -1
  58. package/dist/tools/NewsSentiment.js +126 -130
  59. package/dist/tools/PriceFeed.d.ts +6 -1
  60. package/dist/tools/PriceFeed.js +201 -133
  61. package/dist/tools/TechnicalAnalysis.d.ts +1 -2
  62. package/dist/tools/TechnicalAnalysis.js +248 -216
  63. package/dist/tools/TechnicalAnalysis.worker.d.ts +25 -0
  64. package/dist/tools/TechnicalAnalysis.worker.js +92 -0
  65. package/dist/tools/TokenCalendar.d.ts +0 -1
  66. package/dist/tools/TokenCalendar.js +63 -68
  67. package/dist/tools/TokenSecurityScanner.d.ts +0 -1
  68. package/dist/tools/TokenSecurityScanner.js +93 -96
  69. package/dist/tools/TransactionSim.d.ts +0 -1
  70. package/dist/tools/TransactionSim.js +65 -71
  71. package/dist/tui/App.d.ts +1 -7
  72. package/dist/tui/App.js +896 -825
  73. package/dist/tui/ModelSelector.d.ts +1 -3
  74. package/dist/tui/ModelSelector.js +47 -50
  75. package/dist/tui/REPL.d.ts +1 -3
  76. package/dist/tui/REPL.js +222 -210
  77. package/dist/tui/Sparkline.d.ts +1 -3
  78. package/dist/tui/Sparkline.js +38 -37
  79. package/dist/tui/StatusBar.d.ts +1 -3
  80. package/dist/tui/StatusBar.js +11 -10
  81. package/dist/tui/ThemePresets.d.ts +0 -1
  82. package/dist/tui/ThemePresets.js +99 -103
  83. package/dist/tui/theme.d.ts +0 -1
  84. package/dist/tui/theme.js +50 -31
  85. package/dist/util/clipboard.d.ts +0 -1
  86. package/dist/util/clipboard.js +16 -20
  87. package/dist/util/commandSuggest.d.ts +0 -1
  88. package/dist/util/commandSuggest.js +34 -38
  89. package/dist/util/confirmation.d.ts +0 -1
  90. package/dist/util/confirmation.js +8 -11
  91. package/dist/util/errorHandler.d.ts +0 -1
  92. package/dist/util/errorHandler.js +20 -23
  93. package/dist/util/errors.d.ts +59 -0
  94. package/dist/util/errors.js +93 -0
  95. package/dist/util/logger.d.ts +0 -1
  96. package/dist/util/logger.js +30 -33
  97. package/dist/util/processManager.d.ts +0 -1
  98. package/dist/util/processManager.js +33 -36
  99. package/dist/util/resilientFetch.d.ts +6 -1
  100. package/dist/util/resilientFetch.js +134 -80
  101. package/dist/util/responseCache.d.ts +0 -1
  102. package/dist/util/responseCache.js +36 -45
  103. package/dist/util/rpc.d.ts +16 -0
  104. package/dist/util/rpc.js +69 -0
  105. package/dist/util/safeLog.d.ts +0 -1
  106. package/dist/util/safeLog.js +52 -53
  107. package/dist/util/scheduler.d.ts +0 -1
  108. package/dist/util/scheduler.js +53 -58
  109. package/dist/util/webhooks.d.ts +0 -1
  110. package/dist/util/webhooks.js +54 -58
  111. package/dist/wallet/ActionFeed.d.ts +0 -1
  112. package/dist/wallet/ActionFeed.js +189 -200
  113. package/dist/wallet/AgentWallet.d.ts +7 -8
  114. package/dist/wallet/AgentWallet.js +117 -144
  115. package/dist/wallet/ProfitTracker.d.ts +0 -1
  116. package/dist/wallet/ProfitTracker.js +71 -74
  117. package/package.json +14 -8
  118. package/scripts/build-esbuild.mjs +40 -0
  119. package/scripts/bundle-dts.mjs +58 -0
  120. package/scripts/minify.mjs +44 -0
  121. package/scripts/postinstall.js +41 -0
@@ -34,7 +34,7 @@ export declare function bollingerBands(data: number[], period?: number, stdDev?:
34
34
  };
35
35
  export declare function bollingerSignal(bb: ReturnType<typeof bollingerBands>, currentPrice: number): AnalysisResult;
36
36
  export declare function atr(candles: OHLCV[], period?: number): number;
37
- export declare function fullAnalysis(candles: OHLCV[]): AnalysisResult[];
37
+ export declare function fullAnalysis(candles: OHLCV[]): Promise<AnalysisResult[]>;
38
38
  export declare const getCandlesParams: import("@sinclair/typebox").TObject<{
39
39
  symbol: import("@sinclair/typebox").TString;
40
40
  interval: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
@@ -47,4 +47,3 @@ export declare const analyzeTAParams: import("@sinclair/typebox").TObject<{
47
47
  volumes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TNumber>>;
48
48
  }>;
49
49
  export declare function getCandlesTool(_id: string, params: Record<string, unknown>): Promise<ToolResult>;
50
- //# sourceMappingURL=TechnicalAnalysis.d.ts.map
@@ -1,235 +1,267 @@
1
- /**
2
- * TechnicalAnalysis — RSI, MACD, Bollinger Bands, EMA, SMA, ATR.
3
- * Works with OHLCV candle data. Tools for the agent to query.
4
- */
1
+
5
2
  import { Type } from "@sinclair/typebox";
6
3
  import { resilientFetch } from "../util/resilientFetch.js";
7
- // ── SMA ──────────────────────────────────────────────────────────────────────
4
+
5
+ function yieldToEventLoop() {
6
+ return new Promise(resolve => setImmediate(resolve));
7
+ }
8
+
9
+ async function rsiAsync(data, period = 14, chunkSize = 50) {
10
+ const result = [];
11
+ const gains = [];
12
+ const losses = [];
13
+ for (let i = 1; i < data.length; i++) {
14
+ const diff = data[i] - data[i - 1];
15
+ gains.push(Math.max(0, diff));
16
+ losses.push(Math.max(0, -diff));
17
+ }
18
+ for (let i = period; i < gains.length; i++) {
19
+ let avgGain = 0, avgLoss = 0;
20
+ for (let j = 0; j < period; j++) {
21
+ avgGain += gains[i - j];
22
+ avgLoss += losses[i - j];
23
+ }
24
+ avgGain /= period;
25
+ avgLoss /= period;
26
+ if (avgLoss === 0) {
27
+ result.push(100);
28
+ continue;
29
+ }
30
+ const rs = avgGain / avgLoss;
31
+ result.push(100 - 100 / (1 + rs));
32
+
33
+ if (data.length > 100 && i % chunkSize === 0)
34
+ await yieldToEventLoop();
35
+ }
36
+ return result;
37
+ }
38
+
8
39
  export function sma(data, period) {
9
- const result = [];
10
- for (let i = period - 1; i < data.length; i++) {
11
- let sum = 0;
12
- for (let j = 0; j < period; j++)
13
- sum += data[i - j];
14
- result.push(sum / period);
15
- }
16
- return result;
17
- }
18
- // ── EMA ──────────────────────────────────────────────────────────────────────
40
+ const result = [];
41
+ for (let i = period - 1; i < data.length; i++) {
42
+ let sum = 0;
43
+ for (let j = 0; j < period; j++)
44
+ sum += data[i - j];
45
+ result.push(sum / period);
46
+ }
47
+ return result;
48
+ }
49
+
19
50
  export function ema(data, period) {
20
- const result = [];
21
- const k = 2 / (period + 1);
22
- const initialSma = data.slice(0, period).reduce((a, b) => a + b, 0) / period;
23
- result.push(initialSma);
24
- for (let i = period; i < data.length; i++) {
25
- result.push(data[i] * k + result[result.length - 1] * (1 - k));
26
- }
27
- return result;
28
- }
29
- // ── RSI ──────────────────────────────────────────────────────────────────────
51
+ const result = [];
52
+ const k = 2 / (period + 1);
53
+ const initialSma = data.slice(0, period).reduce((a, b) => a + b, 0) / period;
54
+ result.push(initialSma);
55
+ for (let i = period; i < data.length; i++) {
56
+ result.push(data[i] * k + result[result.length - 1] * (1 - k));
57
+ }
58
+ return result;
59
+ }
60
+
30
61
  export function rsi(data, period = 14) {
31
- const result = [];
32
- const gains = [];
33
- const losses = [];
34
- for (let i = 1; i < data.length; i++) {
35
- const diff = data[i] - data[i - 1];
36
- gains.push(Math.max(0, diff));
37
- losses.push(Math.max(0, -diff));
38
- }
39
- for (let i = period; i < gains.length; i++) {
40
- let avgGain = 0, avgLoss = 0;
41
- for (let j = 0; j < period; j++) {
42
- avgGain += gains[i - j];
43
- avgLoss += losses[i - j];
44
- }
45
- avgGain /= period;
46
- avgLoss /= period;
47
- if (avgLoss === 0) {
48
- result.push(100);
49
- continue;
50
- }
51
- const rs = avgGain / avgLoss;
52
- result.push(100 - 100 / (1 + rs));
53
- }
54
- return result;
62
+ const result = [];
63
+ const gains = [];
64
+ const losses = [];
65
+ for (let i = 1; i < data.length; i++) {
66
+ const diff = data[i] - data[i - 1];
67
+ gains.push(Math.max(0, diff));
68
+ losses.push(Math.max(0, -diff));
69
+ }
70
+ for (let i = period; i < gains.length; i++) {
71
+ let avgGain = 0, avgLoss = 0;
72
+ for (let j = 0; j < period; j++) {
73
+ avgGain += gains[i - j];
74
+ avgLoss += losses[i - j];
75
+ }
76
+ avgGain /= period;
77
+ avgLoss /= period;
78
+ if (avgLoss === 0) {
79
+ result.push(100);
80
+ continue;
81
+ }
82
+ const rs = avgGain / avgLoss;
83
+ result.push(100 - 100 / (1 + rs));
84
+ }
85
+ return result;
55
86
  }
56
87
  export function rsiSignal(rsiValues, currentPrice, prices) {
57
- const last = rsiValues[rsiValues.length - 1];
58
- let signal = "neutral";
59
- if (last > 70)
60
- signal = "bearish";
61
- else if (last < 30)
62
- signal = "bullish";
63
- return {
64
- indicator: "RSI",
65
- value: parseFloat(last.toFixed(2)),
66
- signal,
67
- details: `RSI(14) = ${last.toFixed(2)}${last > 70 ? " — overbought" : last < 30 ? " — oversold" : " — neutral zone"}`,
68
- };
69
- }
70
- // ── MACD ─────────────────────────────────────────────────────────────────────
88
+ const last = rsiValues[rsiValues.length - 1];
89
+ let signal = "neutral";
90
+ if (last > 70)
91
+ signal = "bearish";
92
+ else if (last < 30)
93
+ signal = "bullish";
94
+ return {
95
+ indicator: "RSI",
96
+ value: parseFloat(last.toFixed(2)),
97
+ signal,
98
+ details: `RSI(14) = ${last.toFixed(2)}${last > 70 ? " — overbought" : last < 30 ? " — oversold" : " — neutral zone"}`,
99
+ };
100
+ }
101
+
71
102
  export function macd(data, fast = 12, slow = 26, signalPeriod = 9) {
72
- const fastEma = ema(data, fast);
73
- const slowEma = ema(data, slow);
74
- const macdLine = [];
75
- // MACD line is fast EMA - slow EMA (aligned)
76
- const offset = slow - fast;
77
- for (let i = 0; i < slowEma.length; i++) {
78
- macdLine.push(fastEma[i + offset] - slowEma[i]);
79
- }
80
- const signal = ema(macdLine, signalPeriod);
81
- // Shift signal to align
82
- const sigShift = signalPeriod - 1;
83
- const histogram = [];
84
- for (let i = 0; i < macdLine.length - sigShift; i++) {
85
- histogram.push(macdLine[i + sigShift] - signal[i]);
86
- }
87
- // Trim macdLine to match histogram length
88
- const trimmed = macdLine.slice(sigShift);
89
- return { macd: trimmed, signal, histogram };
103
+ const fastEma = ema(data, fast);
104
+ const slowEma = ema(data, slow);
105
+ const macdLine = [];
106
+
107
+ const offset = slow - fast;
108
+ for (let i = 0; i < slowEma.length; i++) {
109
+ macdLine.push(fastEma[i + offset] - slowEma[i]);
110
+ }
111
+ const signal = ema(macdLine, signalPeriod);
112
+
113
+ const sigShift = signalPeriod - 1;
114
+ const histogram = [];
115
+ for (let i = 0; i < macdLine.length - sigShift; i++) {
116
+ histogram.push(macdLine[i + sigShift] - signal[i]);
117
+ }
118
+
119
+ const trimmed = macdLine.slice(sigShift);
120
+ return { macd: trimmed, signal, histogram };
90
121
  }
91
122
  export function macdSignal(macdData) {
92
- const hist = macdData.histogram;
93
- const last = hist[hist.length - 1] ?? 0;
94
- const prev = hist[hist.length - 2] ?? 0;
95
- let signal = "neutral";
96
- if (last > 0 && prev <= 0)
97
- signal = "bullish";
98
- else if (last < 0 && prev >= 0)
99
- signal = "bearish";
100
- return {
101
- indicator: "MACD",
102
- value: parseFloat(last.toFixed(6)),
103
- signal,
104
- details: `MACD histogram: ${last.toFixed(6)}${signal !== "neutral" ? ` — ${signal} crossover` : ""}`,
105
- };
106
- }
107
- // ── Bollinger Bands ──────────────────────────────────────────────────────────
123
+ const hist = macdData.histogram;
124
+ const last = hist[hist.length - 1] ?? 0;
125
+ const prev = hist[hist.length - 2] ?? 0;
126
+ let signal = "neutral";
127
+ if (last > 0 && prev <= 0)
128
+ signal = "bullish";
129
+ else if (last < 0 && prev >= 0)
130
+ signal = "bearish";
131
+ return {
132
+ indicator: "MACD",
133
+ value: parseFloat(last.toFixed(6)),
134
+ signal,
135
+ details: `MACD histogram: ${last.toFixed(6)}${signal !== "neutral" ? ` — ${signal} crossover` : ""}`,
136
+ };
137
+ }
138
+
108
139
  export function bollingerBands(data, period = 20, stdDev = 2) {
109
- const middle = sma(data, period);
110
- const upper = [];
111
- const lower = [];
112
- for (let i = 0; i < middle.length; i++) {
113
- const start = i;
114
- let sumSq = 0;
115
- for (let j = 0; j < period; j++) {
116
- const idx = start + j;
117
- if (idx < data.length)
118
- sumSq += (data[idx] - middle[i]) ** 2;
119
- }
120
- const std = Math.sqrt(sumSq / period);
121
- upper.push(middle[i] + stdDev * std);
122
- lower.push(middle[i] - stdDev * std);
123
- }
124
- return { upper, middle, lower };
140
+ const middle = sma(data, period);
141
+ const upper = [];
142
+ const lower = [];
143
+ for (let i = 0; i < middle.length; i++) {
144
+ const start = i;
145
+ let sumSq = 0;
146
+ for (let j = 0; j < period; j++) {
147
+ const idx = start + j;
148
+ if (idx < data.length)
149
+ sumSq += (data[idx] - middle[i]) ** 2;
150
+ }
151
+ const std = Math.sqrt(sumSq / period);
152
+ upper.push(middle[i] + stdDev * std);
153
+ lower.push(middle[i] - stdDev * std);
154
+ }
155
+ return { upper, middle, lower };
125
156
  }
126
157
  export function bollingerSignal(bb, currentPrice) {
127
- const lastUpper = bb.upper[bb.upper.length - 1];
128
- const lastLower = bb.lower[bb.lower.length - 1];
129
- const lastMid = bb.middle[bb.middle.length - 1];
130
- let signal = "neutral";
131
- if (currentPrice >= lastUpper)
132
- signal = "bearish";
133
- else if (currentPrice <= lastLower)
134
- signal = "bullish";
135
- return {
136
- indicator: "Bollinger",
137
- value: [parseFloat(lastUpper.toFixed(6)), parseFloat(lastMid.toFixed(6)), parseFloat(lastLower.toFixed(6))],
138
- signal,
139
- details: signal === "bearish" ? "Price at upper band — overextended" : signal === "bullish" ? "Price at lower band — oversold" : "Within bands",
140
- };
141
- }
142
- // ── ATR ──────────────────────────────────────────────────────────────────────
158
+ const lastUpper = bb.upper[bb.upper.length - 1];
159
+ const lastLower = bb.lower[bb.lower.length - 1];
160
+ const lastMid = bb.middle[bb.middle.length - 1];
161
+ let signal = "neutral";
162
+ if (currentPrice >= lastUpper)
163
+ signal = "bearish";
164
+ else if (currentPrice <= lastLower)
165
+ signal = "bullish";
166
+ return {
167
+ indicator: "Bollinger",
168
+ value: [parseFloat(lastUpper.toFixed(6)), parseFloat(lastMid.toFixed(6)), parseFloat(lastLower.toFixed(6))],
169
+ signal,
170
+ details: signal === "bearish" ? "Price at upper band — overextended" : signal === "bullish" ? "Price at lower band — oversold" : "Within bands",
171
+ };
172
+ }
173
+
143
174
  export function atr(candles, period = 14) {
144
- const trueRanges = [];
145
- for (let i = 1; i < candles.length; i++) {
146
- const high = candles[i].high;
147
- const low = candles[i].low;
148
- const prevClose = candles[i - 1].close;
149
- trueRanges.push(Math.max(high - low, Math.abs(high - prevClose), Math.abs(low - prevClose)));
150
- }
151
- if (trueRanges.length < period)
152
- return trueRanges.reduce((a, b) => a + b, 0) / Math.max(1, trueRanges.length);
153
- return trueRanges.slice(-period).reduce((a, b) => a + b, 0) / period;
154
- }
155
- // ── Full Analysis ────────────────────────────────────────────────────────────
156
- export function fullAnalysis(candles) {
157
- const closes = candles.map(c => c.close);
158
- if (closes.length < 30)
159
- return [];
160
- const results = [];
161
- results.push(rsiSignal(rsi(closes, 14), closes[closes.length - 1], closes));
162
- results.push(macdSignal(macd(closes, 12, 26, 9)));
163
- const bb = bollingerBands(closes, 20, 2);
164
- results.push(bollingerSignal(bb, closes[closes.length - 1]));
165
- const atrValue = atr(candles, 14);
166
- results.push({
167
- indicator: "ATR",
168
- value: parseFloat(atrValue.toFixed(6)),
169
- signal: "neutral",
170
- details: `ATR(14) = ${atrValue.toFixed(6)}`,
171
- });
172
- // Overall signal — weighted
173
- const bullish = results.filter(r => r.signal === "bullish").length;
174
- const bearish = results.filter(r => r.signal === "bearish").length;
175
- const overall = bullish > bearish ? "bullish" : bearish > bullish ? "bearish" : "neutral";
176
- results.push({
177
- indicator: "SUMMARY",
178
- value: results.length,
179
- signal: overall,
180
- details: `${bullish} bullish, ${bearish} bearish, ${results.length - bullish - bearish} neutral — overall ${overall}`,
181
- });
182
- return results;
183
- }
184
- // ── Tools ────────────────────────────────────────────────────────────────────
175
+ const trueRanges = [];
176
+ for (let i = 1; i < candles.length; i++) {
177
+ const high = candles[i].high;
178
+ const low = candles[i].low;
179
+ const prevClose = candles[i - 1].close;
180
+ trueRanges.push(Math.max(high - low, Math.abs(high - prevClose), Math.abs(low - prevClose)));
181
+ }
182
+ if (trueRanges.length < period)
183
+ return trueRanges.reduce((a, b) => a + b, 0) / Math.max(1, trueRanges.length);
184
+ return trueRanges.slice(-period).reduce((a, b) => a + b, 0) / period;
185
+ }
186
+
187
+ export async function fullAnalysis(candles) {
188
+ const closes = candles.map(c => c.close);
189
+ if (closes.length < 30)
190
+ return [];
191
+ const results = [];
192
+
193
+ const rsiValues = await rsiAsync(closes, 14);
194
+ results.push(rsiSignal(rsiValues, closes[closes.length - 1], closes));
195
+ results.push(macdSignal(macd(closes, 12, 26, 9)));
196
+ const bb = bollingerBands(closes, 20, 2);
197
+ results.push(bollingerSignal(bb, closes[closes.length - 1]));
198
+ const atrValue = atr(candles, 14);
199
+ results.push({
200
+ indicator: "ATR",
201
+ value: parseFloat(atrValue.toFixed(6)),
202
+ signal: "neutral",
203
+ details: `ATR(14) = ${atrValue.toFixed(6)}`,
204
+ });
205
+
206
+ const bullish = results.filter(r => r.signal === "bullish").length;
207
+ const bearish = results.filter(r => r.signal === "bearish").length;
208
+ const overall = bullish > bearish ? "bullish" : bearish > bullish ? "bearish" : "neutral";
209
+ results.push({
210
+ indicator: "SUMMARY",
211
+ value: results.length,
212
+ signal: overall,
213
+ details: `${bullish} bullish, ${bearish} bearish, ${results.length - bullish - bearish} neutral — overall ${overall}`,
214
+ });
215
+ return results;
216
+ }
217
+
185
218
  export const getCandlesParams = Type.Object({
186
- symbol: Type.String({ description: "Trading pair symbol (e.g., BTCUSDT, SOLUSDT)" }),
187
- interval: Type.Optional(Type.String({ description: "Candle interval: 1m, 5m, 15m, 1h, 4h, 1d", default: "1d" })),
188
- limit: Type.Optional(Type.Number({ description: "Number of candles", default: 50 })),
219
+ symbol: Type.String({ description: "Trading pair symbol (e.g., BTCUSDT, SOLUSDT)" }),
220
+ interval: Type.Optional(Type.String({ description: "Candle interval: 1m, 5m, 15m, 1h, 4h, 1d", default: "1d" })),
221
+ limit: Type.Optional(Type.Number({ description: "Number of candles", default: 50 })),
189
222
  });
190
223
  export const analyzeTAParams = Type.Object({
191
- prices: Type.Array(Type.Number({ description: "Closing prices" })),
192
- highs: Type.Optional(Type.Array(Type.Number({ description: "High prices" }))),
193
- lows: Type.Optional(Type.Array(Type.Number({ description: "Low prices" }))),
194
- volumes: Type.Optional(Type.Array(Type.Number({ description: "Volumes" }))),
224
+ prices: Type.Array(Type.Number({ description: "Closing prices" })),
225
+ highs: Type.Optional(Type.Array(Type.Number({ description: "High prices" }))),
226
+ lows: Type.Optional(Type.Array(Type.Number({ description: "Low prices" }))),
227
+ volumes: Type.Optional(Type.Array(Type.Number({ description: "Volumes" }))),
195
228
  });
196
229
  export async function getCandlesTool(_id, params) {
197
- const symbol = params.symbol;
198
- const interval = params.interval || "1d";
199
- const limit = params.limit || 50;
200
- try {
201
- const response = await resilientFetch(`https://api.binance.com/api/v3/klines?symbol=${symbol}&interval=${interval}&limit=${limit}`, { timeout: 10_000, retries: 1 });
202
- if (!response.ok) {
203
- return { content: [{ type: "text", text: `Failed to fetch candles for ${symbol}: ${response.status}` }] };
204
- }
205
- const data = await response.json();
206
- const candles = data.map(k => ({
207
- timestamp: k[0],
208
- open: parseFloat(k[1]),
209
- high: parseFloat(k[2]),
210
- low: parseFloat(k[3]),
211
- close: parseFloat(k[4]),
212
- volume: parseFloat(k[5]),
213
- }));
214
- const closes = candles.map(c => c.close);
215
- const results = fullAnalysis(candles);
216
- const lines = [
217
- `--- ${symbol} ${interval} candles (${candles.length}) ---`,
218
- `Last: $${closes[closes.length - 1].toFixed(6)}`,
219
- `Range: $${Math.min(...closes).toFixed(6)} - $${Math.max(...closes).toFixed(6)}`,
220
- ``,
221
- ...results.map(r => {
222
- const icon = r.signal === "bullish" ? "🟢" : r.signal === "bearish" ? "🔴" : "⚪";
223
- return `${icon} ${r.indicator}: ${JSON.stringify(typeof r.value === "number" ? r.value.toFixed(4) : r.value)} — ${r.details ?? ""}`;
224
- }),
225
- ];
226
- return {
227
- content: [{ type: "text", text: lines.join("\n") }],
228
- details: { candles: candles.slice(-5), analysis: results },
229
- };
230
- }
231
- catch (e) {
232
- return { content: [{ type: "text", text: `Error fetching candles: ${e instanceof Error ? e.message : String(e)}` }], isError: true };
233
- }
234
- }
235
- //# sourceMappingURL=TechnicalAnalysis.js.map
230
+ const symbol = params.symbol;
231
+ const interval = params.interval || "1d";
232
+ const limit = params.limit || 50;
233
+ try {
234
+ const response = await resilientFetch(`https://api.binance.com/api/v3/klines?symbol=${symbol}&interval=${interval}&limit=${limit}`, { timeout: 10_000, retries: 1 });
235
+ if (!response.ok) {
236
+ return { content: [{ type: "text", text: `Failed to fetch candles for ${symbol}: ${response.status}` }] };
237
+ }
238
+ const data = await response.json();
239
+ const candles = data.map(k => ({
240
+ timestamp: k[0],
241
+ open: parseFloat(k[1]),
242
+ high: parseFloat(k[2]),
243
+ low: parseFloat(k[3]),
244
+ close: parseFloat(k[4]),
245
+ volume: parseFloat(k[5]),
246
+ }));
247
+ const closes = candles.map(c => c.close);
248
+ const results = await fullAnalysis(candles);
249
+ const lines = [
250
+ `--- ${symbol} ${interval} candles (${candles.length}) ---`,
251
+ `Last: $${closes[closes.length - 1].toFixed(6)}`,
252
+ `Range: $${Math.min(...closes).toFixed(6)} - $${Math.max(...closes).toFixed(6)}`,
253
+ ``,
254
+ ...results.map(r => {
255
+ const icon = r.signal === "bullish" ? "🟢" : r.signal === "bearish" ? "🔴" : "⚪";
256
+ return `${icon} ${r.indicator}: ${JSON.stringify(typeof r.value === "number" ? r.value.toFixed(4) : r.value)} — ${r.details ?? ""}`;
257
+ }),
258
+ ];
259
+ return {
260
+ content: [{ type: "text", text: lines.join("\n") }],
261
+ details: { candles: candles.slice(-5), analysis: results },
262
+ };
263
+ }
264
+ catch (e) {
265
+ return { content: [{ type: "text", text: `Error fetching candles: ${e instanceof Error ? e.message : String(e)}` }], isError: true };
266
+ }
267
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * #21: WebWorker for TechnicalAnalysis — offloads RSI/MACD/Bollinger from main thread.
3
+ * Falls back to synchronous computation if Workers aren't available.
4
+ */
5
+ interface Candle {
6
+ timestamp: number;
7
+ open: number;
8
+ high: number;
9
+ low: number;
10
+ close: number;
11
+ volume: number;
12
+ }
13
+ declare function calcRSI(closes: number[], period?: number): number;
14
+ declare function calcMACD(closes: number[]): {
15
+ macd: number;
16
+ signal: number;
17
+ histogram: number;
18
+ };
19
+ declare function calcBollinger(closes: number[], period?: number): {
20
+ upper: number;
21
+ middle: number;
22
+ lower: number;
23
+ };
24
+ declare function calcATR(candles: Candle[], period?: number): number;
25
+ export { calcRSI, calcMACD, calcBollinger, calcATR };
@@ -0,0 +1,92 @@
1
+
2
+
3
+ function calcRSI(closes, period = 14) {
4
+ if (closes.length < period + 1)
5
+ return 50;
6
+ let gains = 0, losses = 0;
7
+ for (let i = closes.length - period; i < closes.length; i++) {
8
+ const diff = closes[i] - closes[i - 1];
9
+ if (diff > 0)
10
+ gains += diff;
11
+ else
12
+ losses -= diff;
13
+ }
14
+ const avgGain = gains / period;
15
+ const avgLoss = losses / period;
16
+ if (avgLoss === 0)
17
+ return 100;
18
+ const rs = avgGain / avgLoss;
19
+ return 100 - (100 / (1 + rs));
20
+ }
21
+
22
+ function ema(data, period) {
23
+ const result = [];
24
+ const k = 2 / (period + 1);
25
+ result[0] = data[0];
26
+ for (let i = 1; i < data.length; i++) {
27
+ result[i] = data[i] * k + result[i - 1] * (1 - k);
28
+ }
29
+ return result;
30
+ }
31
+
32
+ function calcMACD(closes) {
33
+ if (closes.length < 26)
34
+ return { macd: 0, signal: 0, histogram: 0 };
35
+ const ema12 = ema(closes, 12);
36
+ const ema26 = ema(closes, 26);
37
+ const macdLine = ema12.map((v, i) => v - ema26[i]);
38
+ const signalLine = ema(macdLine, 9);
39
+ const lastIdx = macdLine.length - 1;
40
+ return {
41
+ macd: macdLine[lastIdx],
42
+ signal: signalLine[lastIdx],
43
+ histogram: macdLine[lastIdx] - signalLine[lastIdx],
44
+ };
45
+ }
46
+
47
+ function calcBollinger(closes, period = 20) {
48
+ if (closes.length < period) {
49
+ const avg = closes.reduce((a, b) => a + b, 0) / closes.length;
50
+ return { upper: avg * 1.02, middle: avg, lower: avg * 0.98 };
51
+ }
52
+ const slice = closes.slice(-period);
53
+ const mean = slice.reduce((a, b) => a + b, 0) / period;
54
+ const variance = slice.reduce((sum, v) => sum + (v - mean) ** 2, 0) / period;
55
+ const stdDev = Math.sqrt(variance);
56
+ return { upper: mean + 2 * stdDev, middle: mean, lower: mean - 2 * stdDev };
57
+ }
58
+
59
+ function calcATR(candles, period = 14) {
60
+ if (candles.length < period + 1)
61
+ return 0;
62
+ const trs = [];
63
+ for (let i = 1; i < candles.length; i++) {
64
+ const high = candles[i].high;
65
+ const low = candles[i].low;
66
+ const prevClose = candles[i - 1].close;
67
+ trs.push(Math.max(high - low, Math.abs(high - prevClose), Math.abs(low - prevClose)));
68
+ }
69
+ const recent = trs.slice(-period);
70
+ return recent.reduce((a, b) => a + b, 0) / period;
71
+ }
72
+
73
+ if (typeof self !== 'undefined') {
74
+ self.onmessage = (e) => {
75
+ const { candles, id } = e.data;
76
+ const closes = candles.map((c) => c.close);
77
+ const rsi = calcRSI(closes);
78
+ const macd = calcMACD(closes);
79
+ const bollinger = calcBollinger(closes);
80
+ const atr = calcATR(candles);
81
+ const results = [
82
+ { indicator: 'RSI', value: rsi, signal: rsi > 70 ? 'overbought' : rsi < 30 ? 'oversold' : 'neutral' },
83
+ { indicator: 'MACD', value: [macd.macd, macd.signal, macd.histogram], signal: macd.histogram > 0 ? 'bullish' : 'bearish' },
84
+ { indicator: 'Bollinger', value: [bollinger.upper, bollinger.middle, bollinger.lower], signal: closes[closes.length - 1] > bollinger.upper ? 'overbought' : closes[closes.length - 1] < bollinger.lower ? 'oversold' : 'neutral' },
85
+ { indicator: 'ATR', value: atr, signal: 'neutral' },
86
+ { indicator: 'SUMMARY', value: 0, signal: rsi > 50 && macd.histogram > 0 ? 'bullish' : rsi < 50 && macd.histogram < 0 ? 'bearish' : 'neutral' },
87
+ ];
88
+ self.postMessage({ id, results });
89
+ };
90
+ }
91
+
92
+ export { calcRSI, calcMACD, calcBollinger, calcATR };
@@ -21,4 +21,3 @@ export declare const launchCalendarParams: import("@sinclair/typebox").TObject<{
21
21
  export declare function launchCalendarTool(_id: string, params: Record<string, unknown>): Promise<ToolResult>;
22
22
  /** Get sidebar-ready summary */
23
23
  export declare function getLaunchSummary(): string;
24
- //# sourceMappingURL=TokenCalendar.d.ts.map