prab-cli 1.2.4 → 1.2.6
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.
- package/dist/index.js +218 -2
- package/dist/lib/chat-handler.js +39 -5
- package/dist/lib/crypto/data-fetcher.js +86 -0
- package/dist/lib/crypto/ict-strategy.js +955 -0
- package/dist/lib/crypto/index.js +23 -1
- package/dist/lib/crypto/market-scanner.js +569 -0
- package/dist/lib/crypto/news-fetcher.js +394 -0
- package/dist/lib/crypto/orderblock-strategy.js +445 -0
- package/dist/lib/crypto/signal-generator.js +144 -17
- package/dist/lib/crypto/smc-analyzer.js +39 -7
- package/dist/lib/crypto/strategy-engine.js +803 -0
- package/dist/lib/crypto/whale-tracker.js +508 -0
- package/dist/lib/slash-commands.js +36 -0
- package/dist/lib/ui.js +45 -1
- package/dist/server/index.js +501 -0
- package/package.json +7 -1
|
@@ -20,13 +20,17 @@ const analyzer_1 = require("./analyzer");
|
|
|
20
20
|
const market_analyzer_1 = require("./market-analyzer");
|
|
21
21
|
const config_1 = require("../config");
|
|
22
22
|
const groq_provider_1 = require("../models/groq-provider");
|
|
23
|
+
const ui_1 = require("../ui");
|
|
23
24
|
/**
|
|
24
25
|
* Generate AI reasoning for the trading signal
|
|
25
26
|
*/
|
|
26
27
|
async function generateAIReasoning(symbol, signal, price, priceChange24h) {
|
|
27
28
|
const apiKey = (0, config_1.getApiKey)();
|
|
28
29
|
if (!apiKey) {
|
|
29
|
-
return
|
|
30
|
+
return {
|
|
31
|
+
text: "AI reasoning unavailable (no API key configured)",
|
|
32
|
+
tokens: { promptTokens: 0, completionTokens: 0, totalTokens: 0 },
|
|
33
|
+
};
|
|
30
34
|
}
|
|
31
35
|
const modelConfig = (0, config_1.getModelConfig)();
|
|
32
36
|
const provider = new groq_provider_1.GroqProvider(modelConfig.modelId, 0.7);
|
|
@@ -50,6 +54,7 @@ Key Observations:
|
|
|
50
54
|
${signal.reasoning.map((r) => `- ${r}`).join("\n")}
|
|
51
55
|
|
|
52
56
|
Provide a concise trading insight (2-3 sentences) explaining the signal and any cautions. Be direct and actionable.`;
|
|
57
|
+
const tokens = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
|
|
53
58
|
try {
|
|
54
59
|
const stream = provider.streamChat([{ role: "user", content: prompt }], [] // No tools needed
|
|
55
60
|
);
|
|
@@ -58,11 +63,35 @@ Provide a concise trading insight (2-3 sentences) explaining the signal and any
|
|
|
58
63
|
if (chunk.content && typeof chunk.content === "string") {
|
|
59
64
|
response += chunk.content;
|
|
60
65
|
}
|
|
66
|
+
// Capture token usage (check multiple formats)
|
|
67
|
+
if (chunk.usage_metadata) {
|
|
68
|
+
tokens.promptTokens =
|
|
69
|
+
chunk.usage_metadata.input_tokens || chunk.usage_metadata.prompt_tokens || 0;
|
|
70
|
+
tokens.completionTokens =
|
|
71
|
+
chunk.usage_metadata.output_tokens || chunk.usage_metadata.completion_tokens || 0;
|
|
72
|
+
tokens.totalTokens =
|
|
73
|
+
chunk.usage_metadata.total_tokens || tokens.promptTokens + tokens.completionTokens;
|
|
74
|
+
}
|
|
75
|
+
if (chunk.response_metadata?.usage) {
|
|
76
|
+
const usage = chunk.response_metadata.usage;
|
|
77
|
+
tokens.promptTokens = usage.prompt_tokens || usage.input_tokens || 0;
|
|
78
|
+
tokens.completionTokens = usage.completion_tokens || usage.output_tokens || 0;
|
|
79
|
+
tokens.totalTokens = usage.total_tokens || tokens.promptTokens + tokens.completionTokens;
|
|
80
|
+
}
|
|
61
81
|
}
|
|
62
|
-
|
|
82
|
+
// Estimate tokens if not provided by API (rough estimate: ~4 chars per token)
|
|
83
|
+
if (tokens.totalTokens === 0 && response.length > 0) {
|
|
84
|
+
tokens.promptTokens = Math.ceil(prompt.length / 4);
|
|
85
|
+
tokens.completionTokens = Math.ceil(response.length / 4);
|
|
86
|
+
tokens.totalTokens = tokens.promptTokens + tokens.completionTokens;
|
|
87
|
+
}
|
|
88
|
+
return { text: response.trim(), tokens };
|
|
63
89
|
}
|
|
64
90
|
catch (error) {
|
|
65
|
-
return
|
|
91
|
+
return {
|
|
92
|
+
text: `AI reasoning unavailable: ${error.message}`,
|
|
93
|
+
tokens,
|
|
94
|
+
};
|
|
66
95
|
}
|
|
67
96
|
}
|
|
68
97
|
/**
|
|
@@ -78,10 +107,13 @@ async function generateTradingSignal(symbol, interval = "1h", includeAI = true)
|
|
|
78
107
|
const signal = (0, analyzer_1.generateSignal)(data);
|
|
79
108
|
spinner.text = "Generating trading signal...";
|
|
80
109
|
let aiReasoning;
|
|
110
|
+
let tokenUsage;
|
|
81
111
|
// Generate AI reasoning if requested
|
|
82
112
|
if (includeAI) {
|
|
83
113
|
spinner.text = "Getting AI insights...";
|
|
84
|
-
|
|
114
|
+
const aiResult = await generateAIReasoning(data.symbol, signal, data.currentPrice, data.priceChangePercent24h);
|
|
115
|
+
aiReasoning = aiResult.text;
|
|
116
|
+
tokenUsage = aiResult.tokens;
|
|
85
117
|
}
|
|
86
118
|
spinner.succeed(`Analysis complete for ${data.symbol}`);
|
|
87
119
|
return {
|
|
@@ -91,6 +123,7 @@ async function generateTradingSignal(symbol, interval = "1h", includeAI = true)
|
|
|
91
123
|
aiReasoning,
|
|
92
124
|
price: data.currentPrice,
|
|
93
125
|
priceChange24h: data.priceChangePercent24h,
|
|
126
|
+
tokenUsage,
|
|
94
127
|
};
|
|
95
128
|
}
|
|
96
129
|
catch (error) {
|
|
@@ -105,9 +138,35 @@ async function generateTradingSignal(symbol, interval = "1h", includeAI = true)
|
|
|
105
138
|
/**
|
|
106
139
|
* Display trading signal in terminal
|
|
107
140
|
*/
|
|
108
|
-
function displaySignal(result) {
|
|
141
|
+
async function displaySignal(result) {
|
|
109
142
|
if (!result.success || !result.signal) {
|
|
110
|
-
console.log(
|
|
143
|
+
console.log("");
|
|
144
|
+
console.log(chalk_1.default.red(" ╔═══════════════════════════════════════════════════════════════════════╗"));
|
|
145
|
+
console.log(chalk_1.default.red(" ║ ❌ SIGNAL ERROR ║"));
|
|
146
|
+
console.log(chalk_1.default.red(" ╚═══════════════════════════════════════════════════════════════════════╝"));
|
|
147
|
+
console.log("");
|
|
148
|
+
if (result.error?.includes("Invalid symbol") || result.error?.includes("Failed to fetch")) {
|
|
149
|
+
// Extract the base symbol from the normalized symbol
|
|
150
|
+
const baseSymbol = result.symbol.replace("USDT", "");
|
|
151
|
+
console.log(chalk_1.default.yellow(` ⚠️ Symbol not found: "${baseSymbol}"`));
|
|
152
|
+
console.log("");
|
|
153
|
+
// Get similar symbols from Binance
|
|
154
|
+
const suggestions = await (0, data_fetcher_1.findSimilarSymbols)(baseSymbol, 8);
|
|
155
|
+
if (suggestions.length > 0) {
|
|
156
|
+
console.log(chalk_1.default.gray(" Did you mean one of these?"));
|
|
157
|
+
console.log("");
|
|
158
|
+
console.log(chalk_1.default.cyan(` ${suggestions.join(", ")}`));
|
|
159
|
+
console.log("");
|
|
160
|
+
}
|
|
161
|
+
console.log(chalk_1.default.gray(" This symbol is not available on Binance exchange."));
|
|
162
|
+
console.log(chalk_1.default.gray(" Note: This tool only supports Binance USDT trading pairs."));
|
|
163
|
+
console.log(chalk_1.default.gray(" The token might exist on other exchanges (KuCoin, Bybit, etc.)"));
|
|
164
|
+
console.log("");
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
console.log(chalk_1.default.yellow(` ⚠️ ${result.error || "An unexpected error occurred"}`));
|
|
168
|
+
}
|
|
169
|
+
console.log("");
|
|
111
170
|
return;
|
|
112
171
|
}
|
|
113
172
|
const { signal, symbol, price, priceChange24h, aiReasoning } = result;
|
|
@@ -212,6 +271,10 @@ function displaySignal(result) {
|
|
|
212
271
|
}
|
|
213
272
|
// Footer
|
|
214
273
|
console.log(chalk_1.default.cyan("\u{2514}" + "\u{2500}".repeat(45) + "\u{2518}"));
|
|
274
|
+
// Token usage
|
|
275
|
+
if (result.tokenUsage && result.tokenUsage.totalTokens > 0) {
|
|
276
|
+
(0, ui_1.showTokenUsageCompact)(result.tokenUsage.promptTokens, result.tokenUsage.completionTokens, result.tokenUsage.totalTokens);
|
|
277
|
+
}
|
|
215
278
|
// Disclaimer
|
|
216
279
|
console.log("");
|
|
217
280
|
console.log(chalk_1.default.gray.italic(" \u{26A0}\u{FE0F} This is not financial advice. Always do your own research."));
|
|
@@ -221,15 +284,27 @@ function displaySignal(result) {
|
|
|
221
284
|
* Quick signal check (no AI)
|
|
222
285
|
*/
|
|
223
286
|
async function quickSignal(symbol) {
|
|
224
|
-
|
|
225
|
-
|
|
287
|
+
try {
|
|
288
|
+
const result = await generateTradingSignal(symbol, "1h", false);
|
|
289
|
+
await displaySignal(result);
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
// Fallback error handling
|
|
293
|
+
console.log(chalk_1.default.red(`\n Error: ${error.message || "Failed to generate signal"}\n`));
|
|
294
|
+
}
|
|
226
295
|
}
|
|
227
296
|
/**
|
|
228
297
|
* Full signal with AI reasoning
|
|
229
298
|
*/
|
|
230
299
|
async function fullSignal(symbol, interval = "1h") {
|
|
231
|
-
|
|
232
|
-
|
|
300
|
+
try {
|
|
301
|
+
const result = await generateTradingSignal(symbol, interval, true);
|
|
302
|
+
await displaySignal(result);
|
|
303
|
+
}
|
|
304
|
+
catch (error) {
|
|
305
|
+
// Fallback error handling
|
|
306
|
+
console.log(chalk_1.default.red(`\n Error: ${error.message || "Failed to generate signal"}\n`));
|
|
307
|
+
}
|
|
233
308
|
}
|
|
234
309
|
// ============================================
|
|
235
310
|
// COMPREHENSIVE ANALYSIS
|
|
@@ -240,7 +315,10 @@ async function fullSignal(symbol, interval = "1h") {
|
|
|
240
315
|
async function generateComprehensiveAIAnalysis(analysis) {
|
|
241
316
|
const apiKey = (0, config_1.getApiKey)();
|
|
242
317
|
if (!apiKey) {
|
|
243
|
-
return
|
|
318
|
+
return {
|
|
319
|
+
text: "AI analysis unavailable (no API key configured)",
|
|
320
|
+
tokens: { promptTokens: 0, completionTokens: 0, totalTokens: 0 },
|
|
321
|
+
};
|
|
244
322
|
}
|
|
245
323
|
const modelConfig = (0, config_1.getModelConfig)();
|
|
246
324
|
const provider = new groq_provider_1.GroqProvider(modelConfig.modelId, 0.7);
|
|
@@ -307,6 +385,7 @@ Provide a detailed trading analysis (4-6 sentences) that:
|
|
|
307
385
|
3. Mentions specific price levels to watch
|
|
308
386
|
4. Highlights any risks or cautions
|
|
309
387
|
Be specific with prices and actionable advice.`;
|
|
388
|
+
const tokens = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
|
|
310
389
|
try {
|
|
311
390
|
const stream = provider.streamChat([{ role: "user", content: prompt }], []);
|
|
312
391
|
let response = "";
|
|
@@ -314,11 +393,32 @@ Be specific with prices and actionable advice.`;
|
|
|
314
393
|
if (chunk.content && typeof chunk.content === "string") {
|
|
315
394
|
response += chunk.content;
|
|
316
395
|
}
|
|
396
|
+
// Capture token usage (check multiple formats)
|
|
397
|
+
if (chunk.usage_metadata) {
|
|
398
|
+
tokens.promptTokens =
|
|
399
|
+
chunk.usage_metadata.input_tokens || chunk.usage_metadata.prompt_tokens || 0;
|
|
400
|
+
tokens.completionTokens =
|
|
401
|
+
chunk.usage_metadata.output_tokens || chunk.usage_metadata.completion_tokens || 0;
|
|
402
|
+
tokens.totalTokens =
|
|
403
|
+
chunk.usage_metadata.total_tokens || tokens.promptTokens + tokens.completionTokens;
|
|
404
|
+
}
|
|
405
|
+
if (chunk.response_metadata?.usage) {
|
|
406
|
+
const usage = chunk.response_metadata.usage;
|
|
407
|
+
tokens.promptTokens = usage.prompt_tokens || usage.input_tokens || 0;
|
|
408
|
+
tokens.completionTokens = usage.completion_tokens || usage.output_tokens || 0;
|
|
409
|
+
tokens.totalTokens = usage.total_tokens || tokens.promptTokens + tokens.completionTokens;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
// Estimate tokens if not provided by API (rough estimate: ~4 chars per token)
|
|
413
|
+
if (tokens.totalTokens === 0 && response.length > 0) {
|
|
414
|
+
tokens.promptTokens = Math.ceil(prompt.length / 4);
|
|
415
|
+
tokens.completionTokens = Math.ceil(response.length / 4);
|
|
416
|
+
tokens.totalTokens = tokens.promptTokens + tokens.completionTokens;
|
|
317
417
|
}
|
|
318
|
-
return response.trim();
|
|
418
|
+
return { text: response.trim(), tokens };
|
|
319
419
|
}
|
|
320
420
|
catch (error) {
|
|
321
|
-
return `AI analysis unavailable: ${error.message}
|
|
421
|
+
return { text: `AI analysis unavailable: ${error.message}`, tokens };
|
|
322
422
|
}
|
|
323
423
|
}
|
|
324
424
|
/**
|
|
@@ -357,7 +457,7 @@ function wordWrap(text, maxWidth) {
|
|
|
357
457
|
/**
|
|
358
458
|
* Display comprehensive analysis in terminal
|
|
359
459
|
*/
|
|
360
|
-
function displayComprehensiveAnalysis(analysis, aiAnalysis) {
|
|
460
|
+
function displayComprehensiveAnalysis(analysis, aiAnalysis, tokenUsage) {
|
|
361
461
|
const boxWidth = 55;
|
|
362
462
|
const contentWidth = boxWidth - 4;
|
|
363
463
|
const border = {
|
|
@@ -535,6 +635,10 @@ function displayComprehensiveAnalysis(analysis, aiAnalysis) {
|
|
|
535
635
|
}
|
|
536
636
|
// Footer
|
|
537
637
|
console.log(border.bot);
|
|
638
|
+
// Token usage
|
|
639
|
+
if (tokenUsage && tokenUsage.totalTokens > 0) {
|
|
640
|
+
(0, ui_1.showTokenUsageCompact)(tokenUsage.promptTokens, tokenUsage.completionTokens, tokenUsage.totalTokens);
|
|
641
|
+
}
|
|
538
642
|
console.log("");
|
|
539
643
|
console.log(chalk_1.default.gray.italic(" \u{26A0}\u{FE0F} This is not financial advice. Always do your own research."));
|
|
540
644
|
console.log("");
|
|
@@ -548,12 +652,35 @@ async function comprehensiveAnalysis(symbol) {
|
|
|
548
652
|
spinner.text = "Fetching 1H, 4H, and 1D data...";
|
|
549
653
|
const analysis = await (0, market_analyzer_1.analyzeMarket)(symbol);
|
|
550
654
|
spinner.text = "Generating AI insights...";
|
|
551
|
-
const
|
|
655
|
+
const aiResult = await generateComprehensiveAIAnalysis(analysis);
|
|
552
656
|
spinner.succeed(`Comprehensive analysis complete for ${analysis.symbol}`);
|
|
553
|
-
displayComprehensiveAnalysis(analysis,
|
|
657
|
+
displayComprehensiveAnalysis(analysis, aiResult.text, aiResult.tokens);
|
|
554
658
|
}
|
|
555
659
|
catch (error) {
|
|
556
660
|
spinner.fail(`Failed to analyze ${symbol}`);
|
|
557
|
-
console.log(
|
|
661
|
+
console.log("");
|
|
662
|
+
console.log(chalk_1.default.red(" ╔═══════════════════════════════════════════════════════════════════════╗"));
|
|
663
|
+
console.log(chalk_1.default.red(" ║ ❌ ANALYSIS ERROR ║"));
|
|
664
|
+
console.log(chalk_1.default.red(" ╚═══════════════════════════════════════════════════════════════════════╝"));
|
|
665
|
+
console.log("");
|
|
666
|
+
if (error.message?.includes("Invalid symbol") || error.message?.includes("Failed to fetch")) {
|
|
667
|
+
console.log(chalk_1.default.yellow(` ⚠️ Symbol not found: "${symbol.toUpperCase()}"`));
|
|
668
|
+
console.log("");
|
|
669
|
+
// Get similar symbols from Binance
|
|
670
|
+
const suggestions = await (0, data_fetcher_1.findSimilarSymbols)(symbol, 8);
|
|
671
|
+
if (suggestions.length > 0) {
|
|
672
|
+
console.log(chalk_1.default.gray(" Did you mean one of these?"));
|
|
673
|
+
console.log("");
|
|
674
|
+
console.log(chalk_1.default.cyan(` ${suggestions.join(", ")}`));
|
|
675
|
+
console.log("");
|
|
676
|
+
}
|
|
677
|
+
console.log(chalk_1.default.gray(" This symbol is not available on Binance exchange."));
|
|
678
|
+
console.log(chalk_1.default.gray(" Note: This tool only supports Binance USDT trading pairs."));
|
|
679
|
+
console.log(chalk_1.default.gray(" The token might exist on other exchanges (KuCoin, Bybit, etc.)"));
|
|
680
|
+
}
|
|
681
|
+
else {
|
|
682
|
+
console.log(chalk_1.default.yellow(` ⚠️ ${error.message || "An unexpected error occurred"}`));
|
|
683
|
+
}
|
|
684
|
+
console.log("");
|
|
558
685
|
}
|
|
559
686
|
}
|
|
@@ -15,6 +15,7 @@ const data_fetcher_1 = require("./data-fetcher");
|
|
|
15
15
|
const smc_indicators_1 = require("./smc-indicators");
|
|
16
16
|
const config_1 = require("../config");
|
|
17
17
|
const groq_provider_1 = require("../models/groq-provider");
|
|
18
|
+
const ui_1 = require("../ui");
|
|
18
19
|
const chart_visual_1 = require("./chart-visual");
|
|
19
20
|
// ============================================
|
|
20
21
|
// TRADE SETUP GENERATION
|
|
@@ -121,8 +122,12 @@ function generateSMCTradeSetup(smc, currentPrice) {
|
|
|
121
122
|
// ============================================
|
|
122
123
|
async function generateSMCAIAnalysis(analysis) {
|
|
123
124
|
const apiKey = (0, config_1.getApiKey)();
|
|
124
|
-
if (!apiKey)
|
|
125
|
-
return
|
|
125
|
+
if (!apiKey) {
|
|
126
|
+
return {
|
|
127
|
+
text: "AI analysis unavailable (no API key configured)",
|
|
128
|
+
tokens: { promptTokens: 0, completionTokens: 0, totalTokens: 0 },
|
|
129
|
+
};
|
|
130
|
+
}
|
|
126
131
|
const modelConfig = (0, config_1.getModelConfig)();
|
|
127
132
|
const provider = new groq_provider_1.GroqProvider(modelConfig.modelId, 0.7);
|
|
128
133
|
provider.initialize(apiKey, modelConfig.modelId);
|
|
@@ -173,6 +178,7 @@ Provide SMC-focused analysis explaining:
|
|
|
173
178
|
3. Best entry strategy (order block, FVG, or liquidity sweep)
|
|
174
179
|
4. Key levels to watch and when to enter
|
|
175
180
|
Be specific with prices and SMC terminology.`;
|
|
181
|
+
const tokens = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
|
|
176
182
|
try {
|
|
177
183
|
const stream = provider.streamChat([{ role: "user", content: prompt }], []);
|
|
178
184
|
let response = "";
|
|
@@ -180,11 +186,32 @@ Be specific with prices and SMC terminology.`;
|
|
|
180
186
|
if (chunk.content && typeof chunk.content === "string") {
|
|
181
187
|
response += chunk.content;
|
|
182
188
|
}
|
|
189
|
+
// Capture token usage (check multiple formats)
|
|
190
|
+
if (chunk.usage_metadata) {
|
|
191
|
+
tokens.promptTokens =
|
|
192
|
+
chunk.usage_metadata.input_tokens || chunk.usage_metadata.prompt_tokens || 0;
|
|
193
|
+
tokens.completionTokens =
|
|
194
|
+
chunk.usage_metadata.output_tokens || chunk.usage_metadata.completion_tokens || 0;
|
|
195
|
+
tokens.totalTokens =
|
|
196
|
+
chunk.usage_metadata.total_tokens || tokens.promptTokens + tokens.completionTokens;
|
|
197
|
+
}
|
|
198
|
+
if (chunk.response_metadata?.usage) {
|
|
199
|
+
const usage = chunk.response_metadata.usage;
|
|
200
|
+
tokens.promptTokens = usage.prompt_tokens || usage.input_tokens || 0;
|
|
201
|
+
tokens.completionTokens = usage.completion_tokens || usage.output_tokens || 0;
|
|
202
|
+
tokens.totalTokens = usage.total_tokens || tokens.promptTokens + tokens.completionTokens;
|
|
203
|
+
}
|
|
183
204
|
}
|
|
184
|
-
|
|
205
|
+
// Estimate tokens if not provided by API (rough estimate: ~4 chars per token)
|
|
206
|
+
if (tokens.totalTokens === 0 && response.length > 0) {
|
|
207
|
+
tokens.promptTokens = Math.ceil(prompt.length / 4);
|
|
208
|
+
tokens.completionTokens = Math.ceil(response.length / 4);
|
|
209
|
+
tokens.totalTokens = tokens.promptTokens + tokens.completionTokens;
|
|
210
|
+
}
|
|
211
|
+
return { text: response.trim(), tokens };
|
|
185
212
|
}
|
|
186
213
|
catch (error) {
|
|
187
|
-
return `AI analysis unavailable: ${error.message}
|
|
214
|
+
return { text: `AI analysis unavailable: ${error.message}`, tokens };
|
|
188
215
|
}
|
|
189
216
|
}
|
|
190
217
|
// ============================================
|
|
@@ -216,7 +243,7 @@ function wordWrap(text, maxWidth) {
|
|
|
216
243
|
lines.push(currentLine.trim());
|
|
217
244
|
return lines;
|
|
218
245
|
}
|
|
219
|
-
function displaySMCAnalysis(analysis, aiAnalysis) {
|
|
246
|
+
function displaySMCAnalysis(analysis, aiAnalysis, tokenUsage) {
|
|
220
247
|
const boxWidth = 58;
|
|
221
248
|
const contentWidth = boxWidth - 4;
|
|
222
249
|
const border = {
|
|
@@ -380,6 +407,11 @@ function displaySMCAnalysis(analysis, aiAnalysis) {
|
|
|
380
407
|
console.log("");
|
|
381
408
|
const smcChart = (0, chart_visual_1.createSMCVisualChart)(currentPrice, smc, tradeSetup);
|
|
382
409
|
smcChart.forEach((l) => console.log(l));
|
|
410
|
+
// Token usage
|
|
411
|
+
if (tokenUsage && tokenUsage.totalTokens > 0) {
|
|
412
|
+
console.log("");
|
|
413
|
+
(0, ui_1.showTokenUsageCompact)(tokenUsage.promptTokens, tokenUsage.completionTokens, tokenUsage.totalTokens);
|
|
414
|
+
}
|
|
383
415
|
console.log("");
|
|
384
416
|
console.log(chalk_1.default.gray.italic(" \u{26A0}\u{FE0F} This is not financial advice. Always do your own research."));
|
|
385
417
|
console.log("");
|
|
@@ -407,9 +439,9 @@ async function runSMCAnalysis(symbol) {
|
|
|
407
439
|
candles: data.candles,
|
|
408
440
|
};
|
|
409
441
|
spinner.text = "Getting AI insights...";
|
|
410
|
-
const
|
|
442
|
+
const aiResult = await generateSMCAIAnalysis(analysis);
|
|
411
443
|
spinner.succeed(`SMC analysis complete for ${data.symbol}`);
|
|
412
|
-
displaySMCAnalysis(analysis,
|
|
444
|
+
displaySMCAnalysis(analysis, aiResult.text, aiResult.tokens);
|
|
413
445
|
}
|
|
414
446
|
catch (error) {
|
|
415
447
|
spinner.fail(`Failed to analyze ${symbol}`);
|