prab-cli 1.2.5 → 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 +134 -2
- package/dist/lib/crypto/data-fetcher.js +86 -0
- package/dist/lib/crypto/ict-strategy.js +955 -0
- package/dist/lib/crypto/index.js +13 -1
- package/dist/lib/crypto/orderblock-strategy.js +445 -0
- package/dist/lib/crypto/signal-generator.js +68 -7
- package/dist/lib/crypto/strategy-engine.js +803 -0
- package/dist/lib/slash-commands.js +18 -0
- package/dist/server/index.js +501 -0
- package/package.json +7 -1
package/dist/index.js
CHANGED
|
@@ -172,6 +172,48 @@ program
|
|
|
172
172
|
.action(async (options) => {
|
|
173
173
|
await (0, crypto_1.runCryptoNews)(options.coin);
|
|
174
174
|
});
|
|
175
|
+
// Smart trading strategy
|
|
176
|
+
program
|
|
177
|
+
.command("strategy <crypto>")
|
|
178
|
+
.description("Generate smart trading strategy with entry, exit, and leverage")
|
|
179
|
+
.option("-s, --style <style>", "Trading style: conservative, moderate, aggressive", "moderate")
|
|
180
|
+
.option("-l, --leverage <number>", "Maximum leverage allowed", "20")
|
|
181
|
+
.option("-d, --direction <direction>", "Trade direction: both, long, short", "both")
|
|
182
|
+
.action(async (crypto, options) => {
|
|
183
|
+
const style = ["conservative", "moderate", "aggressive"].includes(options.style)
|
|
184
|
+
? options.style
|
|
185
|
+
: "moderate";
|
|
186
|
+
const maxLeverage = Math.min(parseInt(options.leverage) || 20, 100);
|
|
187
|
+
const direction = ["both", "long", "short"].includes(options.direction)
|
|
188
|
+
? options.direction
|
|
189
|
+
: "both";
|
|
190
|
+
await (0, crypto_1.runStrategy)(crypto, { style, maxLeverage, direction });
|
|
191
|
+
});
|
|
192
|
+
// Order Block trading strategy
|
|
193
|
+
program
|
|
194
|
+
.command("orderblock <crypto>")
|
|
195
|
+
.alias("ob")
|
|
196
|
+
.description("Order Block trading strategy with BUY/SELL signals based on OB zones")
|
|
197
|
+
.option("-i, --interval <interval>", "Time interval (15m, 1h, 4h, 1d)", "4h")
|
|
198
|
+
.action(async (crypto, options) => {
|
|
199
|
+
const validIntervals = ["15m", "1h", "4h", "1d"];
|
|
200
|
+
const interval = validIntervals.includes(options.interval)
|
|
201
|
+
? options.interval
|
|
202
|
+
: "4h";
|
|
203
|
+
await (0, crypto_1.runOrderBlockStrategy)(crypto, interval);
|
|
204
|
+
});
|
|
205
|
+
// ICT (Inner Circle Trader) Strategy
|
|
206
|
+
program
|
|
207
|
+
.command("ict <crypto>")
|
|
208
|
+
.description("ICT trading strategy - Killzones, OTE, Breakers, Silver Bullet, AMD")
|
|
209
|
+
.option("-i, --interval <interval>", "Time interval (15m, 1h, 4h)", "1h")
|
|
210
|
+
.action(async (crypto, options) => {
|
|
211
|
+
const validIntervals = ["15m", "1h", "4h"];
|
|
212
|
+
const interval = validIntervals.includes(options.interval)
|
|
213
|
+
? options.interval
|
|
214
|
+
: "1h";
|
|
215
|
+
await (0, crypto_1.runICTStrategy)(crypto, interval);
|
|
216
|
+
});
|
|
175
217
|
// Model management commands
|
|
176
218
|
program
|
|
177
219
|
.command("model")
|
|
@@ -336,7 +378,12 @@ program.action(async () => {
|
|
|
336
378
|
default: "btc",
|
|
337
379
|
},
|
|
338
380
|
]);
|
|
339
|
-
|
|
381
|
+
try {
|
|
382
|
+
await (0, crypto_1.comprehensiveAnalysis)(cryptoSymbol);
|
|
383
|
+
}
|
|
384
|
+
catch (err) {
|
|
385
|
+
// Error already handled in comprehensiveAnalysis
|
|
386
|
+
}
|
|
340
387
|
break;
|
|
341
388
|
}
|
|
342
389
|
case "signal": {
|
|
@@ -359,7 +406,12 @@ program.action(async () => {
|
|
|
359
406
|
{ name: "1 Day", value: "1d" },
|
|
360
407
|
],
|
|
361
408
|
});
|
|
362
|
-
|
|
409
|
+
try {
|
|
410
|
+
await (0, crypto_1.fullSignal)(cryptoSymbol, intervalChoice);
|
|
411
|
+
}
|
|
412
|
+
catch (err) {
|
|
413
|
+
// Error already handled in fullSignal
|
|
414
|
+
}
|
|
363
415
|
break;
|
|
364
416
|
}
|
|
365
417
|
case "whale": {
|
|
@@ -418,6 +470,86 @@ program.action(async () => {
|
|
|
418
470
|
await (0, crypto_1.runCryptoNews)(coinFilter);
|
|
419
471
|
break;
|
|
420
472
|
}
|
|
473
|
+
case "strategy": {
|
|
474
|
+
// Prompt for crypto symbol
|
|
475
|
+
const { strategySymbol } = await inquirer_1.default.prompt([
|
|
476
|
+
{
|
|
477
|
+
type: "input",
|
|
478
|
+
name: "strategySymbol",
|
|
479
|
+
message: "Enter cryptocurrency symbol (e.g., btc, eth, sol):",
|
|
480
|
+
default: "btc",
|
|
481
|
+
},
|
|
482
|
+
]);
|
|
483
|
+
// Prompt for trading style
|
|
484
|
+
const styleChoice = await (0, select_1.default)({
|
|
485
|
+
message: "Select your trading style:",
|
|
486
|
+
choices: [
|
|
487
|
+
{ name: "Conservative (5-10x leverage, wider stops)", value: "conservative" },
|
|
488
|
+
{ name: "Moderate (10-20x leverage, balanced) - Recommended", value: "moderate" },
|
|
489
|
+
{ name: "Aggressive (20-50x leverage, tighter stops)", value: "aggressive" },
|
|
490
|
+
],
|
|
491
|
+
});
|
|
492
|
+
// Prompt for direction
|
|
493
|
+
const directionChoice = await (0, select_1.default)({
|
|
494
|
+
message: "Trade direction:",
|
|
495
|
+
choices: [
|
|
496
|
+
{ name: "Both Long & Short", value: "both" },
|
|
497
|
+
{ name: "Long Only", value: "long" },
|
|
498
|
+
{ name: "Short Only", value: "short" },
|
|
499
|
+
],
|
|
500
|
+
});
|
|
501
|
+
await (0, crypto_1.runStrategy)(strategySymbol, {
|
|
502
|
+
style: styleChoice,
|
|
503
|
+
direction: directionChoice,
|
|
504
|
+
maxLeverage: styleChoice === "conservative" ? 10 : styleChoice === "moderate" ? 20 : 50,
|
|
505
|
+
});
|
|
506
|
+
break;
|
|
507
|
+
}
|
|
508
|
+
case "orderblock": {
|
|
509
|
+
// Prompt for crypto symbol
|
|
510
|
+
const { obSymbol } = await inquirer_1.default.prompt([
|
|
511
|
+
{
|
|
512
|
+
type: "input",
|
|
513
|
+
name: "obSymbol",
|
|
514
|
+
message: "Enter cryptocurrency symbol (e.g., btc, eth, sol):",
|
|
515
|
+
default: "btc",
|
|
516
|
+
},
|
|
517
|
+
]);
|
|
518
|
+
// Prompt for timeframe
|
|
519
|
+
const obIntervalChoice = await (0, select_1.default)({
|
|
520
|
+
message: "Select timeframe for Order Block analysis:",
|
|
521
|
+
choices: [
|
|
522
|
+
{ name: "4 Hours (Recommended for swing trades)", value: "4h" },
|
|
523
|
+
{ name: "1 Hour (Intraday trades)", value: "1h" },
|
|
524
|
+
{ name: "15 Minutes (Scalping)", value: "15m" },
|
|
525
|
+
{ name: "1 Day (Position trades)", value: "1d" },
|
|
526
|
+
],
|
|
527
|
+
});
|
|
528
|
+
await (0, crypto_1.runOrderBlockStrategy)(obSymbol, obIntervalChoice);
|
|
529
|
+
break;
|
|
530
|
+
}
|
|
531
|
+
case "ict": {
|
|
532
|
+
// Prompt for crypto symbol
|
|
533
|
+
const { ictSymbol } = await inquirer_1.default.prompt([
|
|
534
|
+
{
|
|
535
|
+
type: "input",
|
|
536
|
+
name: "ictSymbol",
|
|
537
|
+
message: "Enter cryptocurrency symbol (e.g., btc, eth, sol):",
|
|
538
|
+
default: "btc",
|
|
539
|
+
},
|
|
540
|
+
]);
|
|
541
|
+
// Prompt for timeframe
|
|
542
|
+
const ictIntervalChoice = await (0, select_1.default)({
|
|
543
|
+
message: "Select timeframe for ICT analysis:",
|
|
544
|
+
choices: [
|
|
545
|
+
{ name: "1 Hour (Recommended for ICT)", value: "1h" },
|
|
546
|
+
{ name: "15 Minutes (Scalping with Silver Bullet)", value: "15m" },
|
|
547
|
+
{ name: "4 Hours (Higher timeframe bias)", value: "4h" },
|
|
548
|
+
],
|
|
549
|
+
});
|
|
550
|
+
await (0, crypto_1.runICTStrategy)(ictSymbol, ictIntervalChoice);
|
|
551
|
+
break;
|
|
552
|
+
}
|
|
421
553
|
case "model": {
|
|
422
554
|
// Fetch models from Groq API if not cached
|
|
423
555
|
if (cachedModels.length === 0) {
|
|
@@ -5,12 +5,15 @@
|
|
|
5
5
|
* Fetches OHLCV data from Binance public API (no API key required)
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.fetchAllSymbols = fetchAllSymbols;
|
|
9
|
+
exports.findSimilarSymbols = findSimilarSymbols;
|
|
8
10
|
exports.normalizeSymbol = normalizeSymbol;
|
|
9
11
|
exports.fetchOHLCV = fetchOHLCV;
|
|
10
12
|
exports.fetch24hTicker = fetch24hTicker;
|
|
11
13
|
exports.fetchCryptoData = fetchCryptoData;
|
|
12
14
|
exports.getSupportedSymbols = getSupportedSymbols;
|
|
13
15
|
exports.isValidSymbol = isValidSymbol;
|
|
16
|
+
exports.validateSymbol = validateSymbol;
|
|
14
17
|
// Common crypto symbols mapping (user-friendly -> Binance format)
|
|
15
18
|
const SYMBOL_MAP = {
|
|
16
19
|
btc: "BTCUSDT",
|
|
@@ -57,6 +60,63 @@ const SYMBOL_MAP = {
|
|
|
57
60
|
wif: "WIFUSDT",
|
|
58
61
|
};
|
|
59
62
|
const BINANCE_API_BASE = "https://api.binance.com/api/v3";
|
|
63
|
+
// Cache for valid Binance symbols
|
|
64
|
+
let cachedSymbols = null;
|
|
65
|
+
let cacheTimestamp = 0;
|
|
66
|
+
const CACHE_DURATION = 1000 * 60 * 60; // 1 hour cache
|
|
67
|
+
/**
|
|
68
|
+
* Fetch all valid USDT trading pairs from Binance
|
|
69
|
+
*/
|
|
70
|
+
async function fetchAllSymbols() {
|
|
71
|
+
// Return cached symbols if still valid
|
|
72
|
+
if (cachedSymbols && Date.now() - cacheTimestamp < CACHE_DURATION) {
|
|
73
|
+
return cachedSymbols;
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
const response = await fetch(`${BINANCE_API_BASE}/exchangeInfo`);
|
|
77
|
+
if (!response.ok) {
|
|
78
|
+
throw new Error("Failed to fetch exchange info");
|
|
79
|
+
}
|
|
80
|
+
const data = await response.json();
|
|
81
|
+
const symbols = new Set();
|
|
82
|
+
for (const symbol of data.symbols) {
|
|
83
|
+
// Only include USDT pairs that are trading
|
|
84
|
+
if (symbol.status === "TRADING" && symbol.quoteAsset === "USDT") {
|
|
85
|
+
symbols.add(symbol.symbol);
|
|
86
|
+
// Also add the base asset for easy lookup
|
|
87
|
+
symbols.add(symbol.baseAsset.toLowerCase());
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
cachedSymbols = symbols;
|
|
91
|
+
cacheTimestamp = Date.now();
|
|
92
|
+
return symbols;
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
// Return empty set on error, will fall back to direct API check
|
|
96
|
+
return new Set();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get similar symbols for suggestions
|
|
101
|
+
*/
|
|
102
|
+
async function findSimilarSymbols(input, limit = 5) {
|
|
103
|
+
const symbols = await fetchAllSymbols();
|
|
104
|
+
const inputUpper = input.toUpperCase();
|
|
105
|
+
const similar = [];
|
|
106
|
+
for (const symbol of symbols) {
|
|
107
|
+
// Only show USDT pairs, not base assets
|
|
108
|
+
if (!symbol.endsWith("USDT"))
|
|
109
|
+
continue;
|
|
110
|
+
const baseAsset = symbol.replace("USDT", "");
|
|
111
|
+
// Check if base asset starts with or contains the input
|
|
112
|
+
if (baseAsset.startsWith(inputUpper) || baseAsset.includes(inputUpper)) {
|
|
113
|
+
similar.push(baseAsset);
|
|
114
|
+
if (similar.length >= limit)
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return similar;
|
|
119
|
+
}
|
|
60
120
|
/**
|
|
61
121
|
* Normalize symbol to Binance format
|
|
62
122
|
*/
|
|
@@ -156,6 +216,12 @@ function getSupportedSymbols() {
|
|
|
156
216
|
async function isValidSymbol(symbol) {
|
|
157
217
|
try {
|
|
158
218
|
const normalizedSymbol = normalizeSymbol(symbol);
|
|
219
|
+
// First check cache
|
|
220
|
+
const symbols = await fetchAllSymbols();
|
|
221
|
+
if (symbols.has(normalizedSymbol)) {
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
// Fall back to direct API check
|
|
159
225
|
const url = `${BINANCE_API_BASE}/ticker/price?symbol=${normalizedSymbol}`;
|
|
160
226
|
const response = await fetch(url);
|
|
161
227
|
return response.ok;
|
|
@@ -164,3 +230,23 @@ async function isValidSymbol(symbol) {
|
|
|
164
230
|
return false;
|
|
165
231
|
}
|
|
166
232
|
}
|
|
233
|
+
/**
|
|
234
|
+
* Validate symbol and get suggestions if invalid
|
|
235
|
+
*/
|
|
236
|
+
async function validateSymbol(symbol) {
|
|
237
|
+
const normalized = normalizeSymbol(symbol);
|
|
238
|
+
try {
|
|
239
|
+
const url = `${BINANCE_API_BASE}/ticker/price?symbol=${normalized}`;
|
|
240
|
+
const response = await fetch(url);
|
|
241
|
+
if (response.ok) {
|
|
242
|
+
return { valid: true, normalized, suggestions: [] };
|
|
243
|
+
}
|
|
244
|
+
// If invalid, find similar symbols
|
|
245
|
+
const suggestions = await findSimilarSymbols(symbol, 5);
|
|
246
|
+
return { valid: false, normalized, suggestions };
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
const suggestions = await findSimilarSymbols(symbol, 5);
|
|
250
|
+
return { valid: false, normalized, suggestions };
|
|
251
|
+
}
|
|
252
|
+
}
|