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
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Trading Signal API Server
|
|
4
|
+
* REST API for crypto trading strategies
|
|
5
|
+
*
|
|
6
|
+
* Free deployment options:
|
|
7
|
+
* - Railway.app (free tier)
|
|
8
|
+
* - Render.com (free tier)
|
|
9
|
+
* - Vercel (serverless)
|
|
10
|
+
* - Fly.io (free tier)
|
|
11
|
+
* - Local: node dist/server/index.js
|
|
12
|
+
*/
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
// Suppress ora spinners in server mode
|
|
18
|
+
process.env.CI = "true";
|
|
19
|
+
const express_1 = __importDefault(require("express"));
|
|
20
|
+
const cors_1 = __importDefault(require("cors"));
|
|
21
|
+
const crypto_1 = require("../lib/crypto");
|
|
22
|
+
const strategy_engine_1 = require("../lib/crypto/strategy-engine");
|
|
23
|
+
const market_analyzer_1 = require("../lib/crypto/market-analyzer");
|
|
24
|
+
const orderblock_strategy_1 = require("../lib/crypto/orderblock-strategy");
|
|
25
|
+
const ict_strategy_1 = require("../lib/crypto/ict-strategy");
|
|
26
|
+
const app = (0, express_1.default)();
|
|
27
|
+
const PORT = process.env.PORT || 3000;
|
|
28
|
+
// CORS Configuration for Vercel
|
|
29
|
+
const corsOptions = {
|
|
30
|
+
origin: "*",
|
|
31
|
+
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
32
|
+
allowedHeaders: ["Content-Type", "Authorization", "X-Requested-With", "Accept"],
|
|
33
|
+
credentials: false,
|
|
34
|
+
};
|
|
35
|
+
// Middleware
|
|
36
|
+
app.use((0, cors_1.default)(corsOptions));
|
|
37
|
+
app.use(express_1.default.json());
|
|
38
|
+
// Handle preflight OPTIONS requests
|
|
39
|
+
app.options("*", (0, cors_1.default)(corsOptions));
|
|
40
|
+
// Manual CORS headers for all responses (backup for serverless)
|
|
41
|
+
app.use((req, res, next) => {
|
|
42
|
+
res.header("Access-Control-Allow-Origin", "*");
|
|
43
|
+
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
|
|
44
|
+
res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With, Accept");
|
|
45
|
+
if (req.method === "OPTIONS") {
|
|
46
|
+
return res.sendStatus(200);
|
|
47
|
+
}
|
|
48
|
+
next();
|
|
49
|
+
});
|
|
50
|
+
// Request logging
|
|
51
|
+
app.use((req, res, next) => {
|
|
52
|
+
console.log(`[${new Date().toISOString()}] ${req.method} ${req.path}`);
|
|
53
|
+
next();
|
|
54
|
+
});
|
|
55
|
+
// ============================================
|
|
56
|
+
// HEALTH CHECK
|
|
57
|
+
// ============================================
|
|
58
|
+
app.get("/", (req, res) => {
|
|
59
|
+
res.json({
|
|
60
|
+
name: "Crypto Trading Signal API",
|
|
61
|
+
version: "1.0.0",
|
|
62
|
+
status: "running",
|
|
63
|
+
endpoints: {
|
|
64
|
+
signal: "GET /api/signal/:symbol",
|
|
65
|
+
analyze: "GET /api/analyze/:symbol",
|
|
66
|
+
smc: "GET /api/smc/:symbol",
|
|
67
|
+
orderblock: "GET /api/orderblock/:symbol",
|
|
68
|
+
ict: "GET /api/ict/:symbol",
|
|
69
|
+
strategy: "GET /api/strategy/:symbol",
|
|
70
|
+
price: "GET /api/price/:symbol",
|
|
71
|
+
},
|
|
72
|
+
documentation: "https://github.com/your-repo/trading-api",
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
app.get("/health", (req, res) => {
|
|
76
|
+
res.json({ status: "healthy", timestamp: Date.now() });
|
|
77
|
+
});
|
|
78
|
+
// ============================================
|
|
79
|
+
// TRADING SIGNAL ENDPOINTS
|
|
80
|
+
// ============================================
|
|
81
|
+
/**
|
|
82
|
+
* Quick Trading Signal
|
|
83
|
+
* GET /api/signal/:symbol?interval=1h
|
|
84
|
+
*/
|
|
85
|
+
app.get("/api/signal/:symbol", async (req, res) => {
|
|
86
|
+
try {
|
|
87
|
+
const { symbol } = req.params;
|
|
88
|
+
const interval = req.query.interval || "1h";
|
|
89
|
+
// Fetch data and generate signal directly (avoid ora spinner issues)
|
|
90
|
+
const data = await (0, crypto_1.fetchCryptoData)(symbol, interval, 250);
|
|
91
|
+
const signal = (0, crypto_1.generateSignal)(data);
|
|
92
|
+
res.json({
|
|
93
|
+
success: true,
|
|
94
|
+
data: {
|
|
95
|
+
symbol: data.symbol,
|
|
96
|
+
price: data.currentPrice,
|
|
97
|
+
priceChange24h: data.priceChangePercent24h,
|
|
98
|
+
signal: signal.signal,
|
|
99
|
+
confidence: signal.confidence,
|
|
100
|
+
stopLoss: signal.stopLoss,
|
|
101
|
+
takeProfit: signal.takeProfit,
|
|
102
|
+
indicators: signal.indicators,
|
|
103
|
+
reasoning: signal.reasoning,
|
|
104
|
+
},
|
|
105
|
+
timestamp: Date.now(),
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
console.error(`Signal error for ${req.params.symbol}:`, error.message);
|
|
110
|
+
res.status(500).json({
|
|
111
|
+
success: false,
|
|
112
|
+
error: error.message || "Internal server error",
|
|
113
|
+
symbol: req.params.symbol,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
/**
|
|
118
|
+
* Comprehensive Market Analysis
|
|
119
|
+
* GET /api/analyze/:symbol
|
|
120
|
+
*/
|
|
121
|
+
app.get("/api/analyze/:symbol", async (req, res) => {
|
|
122
|
+
try {
|
|
123
|
+
const { symbol } = req.params;
|
|
124
|
+
const analysis = await (0, market_analyzer_1.analyzeMarket)(symbol);
|
|
125
|
+
res.json({
|
|
126
|
+
success: true,
|
|
127
|
+
data: {
|
|
128
|
+
symbol: analysis.symbol,
|
|
129
|
+
currentPrice: analysis.currentPrice,
|
|
130
|
+
priceChange24h: analysis.priceChange24h,
|
|
131
|
+
recommendation: analysis.recommendation,
|
|
132
|
+
confidence: analysis.confidence,
|
|
133
|
+
riskLevel: analysis.riskLevel,
|
|
134
|
+
timeframes: analysis.timeframes,
|
|
135
|
+
timeframeAlignment: analysis.timeframeAlignment,
|
|
136
|
+
indicators: analysis.indicators,
|
|
137
|
+
timing: analysis.timing,
|
|
138
|
+
tradeSetup: analysis.tradeSetup,
|
|
139
|
+
marketCondition: analysis.marketCondition,
|
|
140
|
+
reasoning: analysis.reasoning,
|
|
141
|
+
},
|
|
142
|
+
timestamp: Date.now(),
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
res.status(500).json({
|
|
147
|
+
success: false,
|
|
148
|
+
error: error.message || "Internal server error",
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
/**
|
|
153
|
+
* Smart Money Concepts Analysis
|
|
154
|
+
* GET /api/smc/:symbol?interval=4h
|
|
155
|
+
*/
|
|
156
|
+
app.get("/api/smc/:symbol", async (req, res) => {
|
|
157
|
+
try {
|
|
158
|
+
const { symbol } = req.params;
|
|
159
|
+
const interval = req.query.interval || "4h";
|
|
160
|
+
const data = await (0, crypto_1.fetchCryptoData)(symbol, interval, 200);
|
|
161
|
+
const smc = (0, crypto_1.analyzeSMC)(data.candles);
|
|
162
|
+
res.json({
|
|
163
|
+
success: true,
|
|
164
|
+
data: {
|
|
165
|
+
symbol: data.symbol,
|
|
166
|
+
currentPrice: data.currentPrice,
|
|
167
|
+
priceChange24h: data.priceChangePercent24h,
|
|
168
|
+
marketStructure: smc.marketStructure,
|
|
169
|
+
orderBlocks: {
|
|
170
|
+
bullish: smc.orderBlocks.bullish,
|
|
171
|
+
bearish: smc.orderBlocks.bearish,
|
|
172
|
+
nearest: smc.orderBlocks.nearest,
|
|
173
|
+
},
|
|
174
|
+
fairValueGaps: {
|
|
175
|
+
bullish: smc.fairValueGaps.bullish,
|
|
176
|
+
bearish: smc.fairValueGaps.bearish,
|
|
177
|
+
unfilled: smc.fairValueGaps.unfilled,
|
|
178
|
+
},
|
|
179
|
+
liquidity: smc.liquidity,
|
|
180
|
+
premiumDiscount: smc.premiumDiscount,
|
|
181
|
+
bias: smc.bias,
|
|
182
|
+
},
|
|
183
|
+
timestamp: Date.now(),
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
res.status(500).json({
|
|
188
|
+
success: false,
|
|
189
|
+
error: error.message || "Internal server error",
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
/**
|
|
194
|
+
* Order Block Strategy
|
|
195
|
+
* GET /api/orderblock/:symbol?interval=4h
|
|
196
|
+
*/
|
|
197
|
+
app.get("/api/orderblock/:symbol", async (req, res) => {
|
|
198
|
+
try {
|
|
199
|
+
const { symbol } = req.params;
|
|
200
|
+
const interval = req.query.interval || "4h";
|
|
201
|
+
const result = await (0, orderblock_strategy_1.generateOrderBlockSignal)(symbol, interval);
|
|
202
|
+
res.json({
|
|
203
|
+
success: true,
|
|
204
|
+
data: {
|
|
205
|
+
symbol: result.symbol,
|
|
206
|
+
currentPrice: result.currentPrice,
|
|
207
|
+
signal: result.signal,
|
|
208
|
+
confidence: result.confidence,
|
|
209
|
+
activeOrderBlock: result.activeOB,
|
|
210
|
+
orderBlocks: {
|
|
211
|
+
bullish: result.bullishOBs,
|
|
212
|
+
bearish: result.bearishOBs,
|
|
213
|
+
},
|
|
214
|
+
tradeSetup: {
|
|
215
|
+
entry: result.entry,
|
|
216
|
+
stopLoss: result.stopLoss,
|
|
217
|
+
takeProfit1: result.takeProfit1,
|
|
218
|
+
takeProfit2: result.takeProfit2,
|
|
219
|
+
takeProfit3: result.takeProfit3,
|
|
220
|
+
riskRewardRatio: result.riskRewardRatio,
|
|
221
|
+
},
|
|
222
|
+
context: {
|
|
223
|
+
trend: result.trend,
|
|
224
|
+
premiumDiscount: result.premiumDiscount,
|
|
225
|
+
},
|
|
226
|
+
reasoning: result.reasoning,
|
|
227
|
+
warnings: result.warnings,
|
|
228
|
+
},
|
|
229
|
+
timestamp: result.timestamp,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
res.status(500).json({
|
|
234
|
+
success: false,
|
|
235
|
+
error: error.message || "Internal server error",
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
/**
|
|
240
|
+
* ICT Strategy
|
|
241
|
+
* GET /api/ict/:symbol?interval=1h
|
|
242
|
+
*/
|
|
243
|
+
app.get("/api/ict/:symbol", async (req, res) => {
|
|
244
|
+
try {
|
|
245
|
+
const { symbol } = req.params;
|
|
246
|
+
const interval = req.query.interval || "1h";
|
|
247
|
+
const result = await (0, ict_strategy_1.generateICTSignal)(symbol, interval);
|
|
248
|
+
res.json({
|
|
249
|
+
success: true,
|
|
250
|
+
data: {
|
|
251
|
+
symbol: result.symbol,
|
|
252
|
+
currentPrice: result.currentPrice,
|
|
253
|
+
signal: result.signal,
|
|
254
|
+
confidence: result.confidence,
|
|
255
|
+
modelType: result.modelType,
|
|
256
|
+
killzone: result.killzone,
|
|
257
|
+
inKillzone: result.inKillzone,
|
|
258
|
+
ote: result.ote,
|
|
259
|
+
powerOf3: result.powerOf3,
|
|
260
|
+
marketStructure: result.marketStructure,
|
|
261
|
+
premiumDiscount: result.premiumDiscount,
|
|
262
|
+
displacement: result.displacement,
|
|
263
|
+
breakerBlocks: result.breakerBlocks,
|
|
264
|
+
activeBreaker: result.activeBreaker,
|
|
265
|
+
inducements: result.inducements,
|
|
266
|
+
recentSweep: result.recentSweep,
|
|
267
|
+
tradeSetup: {
|
|
268
|
+
entry: result.entry,
|
|
269
|
+
stopLoss: result.stopLoss,
|
|
270
|
+
takeProfit1: result.takeProfit1,
|
|
271
|
+
takeProfit2: result.takeProfit2,
|
|
272
|
+
takeProfit3: result.takeProfit3,
|
|
273
|
+
riskRewardRatio: result.riskRewardRatio,
|
|
274
|
+
},
|
|
275
|
+
confluenceFactors: result.confluenceFactors,
|
|
276
|
+
reasoning: result.reasoning,
|
|
277
|
+
warnings: result.warnings,
|
|
278
|
+
},
|
|
279
|
+
timestamp: result.timestamp,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
res.status(500).json({
|
|
284
|
+
success: false,
|
|
285
|
+
error: error.message || "Internal server error",
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
/**
|
|
290
|
+
* Full Trading Strategy
|
|
291
|
+
* GET /api/strategy/:symbol?style=moderate&direction=both&leverage=20
|
|
292
|
+
*/
|
|
293
|
+
app.get("/api/strategy/:symbol", async (req, res) => {
|
|
294
|
+
try {
|
|
295
|
+
const { symbol } = req.params;
|
|
296
|
+
const style = req.query.style || "moderate";
|
|
297
|
+
const direction = req.query.direction || "both";
|
|
298
|
+
const maxLeverage = parseInt(req.query.leverage) || 20;
|
|
299
|
+
const result = await (0, strategy_engine_1.generateTradeSetup)(symbol, {
|
|
300
|
+
style,
|
|
301
|
+
direction,
|
|
302
|
+
maxLeverage,
|
|
303
|
+
riskPerTrade: 2,
|
|
304
|
+
});
|
|
305
|
+
res.json({
|
|
306
|
+
success: true,
|
|
307
|
+
data: {
|
|
308
|
+
symbol: result.symbol,
|
|
309
|
+
direction: result.direction,
|
|
310
|
+
confidence: result.confidence,
|
|
311
|
+
entry: {
|
|
312
|
+
price: result.entryPrice,
|
|
313
|
+
stopLoss: result.stopLoss,
|
|
314
|
+
takeProfit1: result.takeProfit1,
|
|
315
|
+
takeProfit2: result.takeProfit2,
|
|
316
|
+
takeProfit3: result.takeProfit3,
|
|
317
|
+
},
|
|
318
|
+
riskManagement: {
|
|
319
|
+
recommendedLeverage: result.recommendedLeverage,
|
|
320
|
+
maxLeverage: result.maxLeverage,
|
|
321
|
+
riskRewardRatio: result.riskRewardRatio,
|
|
322
|
+
positionSizePercent: result.positionSizePercent,
|
|
323
|
+
},
|
|
324
|
+
scores: {
|
|
325
|
+
technical: result.technicalScore,
|
|
326
|
+
smc: result.smcScore,
|
|
327
|
+
volumeWhale: result.volumeWhaleScore,
|
|
328
|
+
news: result.newsScore,
|
|
329
|
+
overall: result.overallScore,
|
|
330
|
+
},
|
|
331
|
+
multiTimeframe: {
|
|
332
|
+
alignment: result.mtfAlignment,
|
|
333
|
+
confirmed: result.mtfConfirmed,
|
|
334
|
+
},
|
|
335
|
+
trailingStops: result.trailingStopLevels,
|
|
336
|
+
alert: {
|
|
337
|
+
status: result.alertStatus,
|
|
338
|
+
reasons: result.alertReasons,
|
|
339
|
+
},
|
|
340
|
+
analysis: result.analysis,
|
|
341
|
+
warnings: result.warnings,
|
|
342
|
+
},
|
|
343
|
+
timestamp: result.timestamp,
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
catch (error) {
|
|
347
|
+
res.status(500).json({
|
|
348
|
+
success: false,
|
|
349
|
+
error: error.message || "Internal server error",
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
/**
|
|
354
|
+
* Price Data
|
|
355
|
+
* GET /api/price/:symbol?interval=1h&limit=100
|
|
356
|
+
*/
|
|
357
|
+
app.get("/api/price/:symbol", async (req, res) => {
|
|
358
|
+
try {
|
|
359
|
+
const { symbol } = req.params;
|
|
360
|
+
const interval = req.query.interval || "1h";
|
|
361
|
+
const limit = parseInt(req.query.limit) || 100;
|
|
362
|
+
const data = await (0, crypto_1.fetchCryptoData)(symbol, interval, limit);
|
|
363
|
+
// Calculate 24h high/low/volume from candles
|
|
364
|
+
const recentCandles = data.candles.slice(-24);
|
|
365
|
+
const high24h = Math.max(...recentCandles.map((c) => c.high));
|
|
366
|
+
const low24h = Math.min(...recentCandles.map((c) => c.low));
|
|
367
|
+
const volume24h = recentCandles.reduce((sum, c) => sum + c.volume, 0);
|
|
368
|
+
res.json({
|
|
369
|
+
success: true,
|
|
370
|
+
data: {
|
|
371
|
+
symbol: data.symbol,
|
|
372
|
+
currentPrice: data.currentPrice,
|
|
373
|
+
priceChange24h: data.priceChangePercent24h,
|
|
374
|
+
high24h,
|
|
375
|
+
low24h,
|
|
376
|
+
volume24h,
|
|
377
|
+
candles: data.candles.map((c) => ({
|
|
378
|
+
timestamp: c.timestamp,
|
|
379
|
+
open: c.open,
|
|
380
|
+
high: c.high,
|
|
381
|
+
low: c.low,
|
|
382
|
+
close: c.close,
|
|
383
|
+
volume: c.volume,
|
|
384
|
+
})),
|
|
385
|
+
},
|
|
386
|
+
timestamp: Date.now(),
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
catch (error) {
|
|
390
|
+
res.status(500).json({
|
|
391
|
+
success: false,
|
|
392
|
+
error: error.message || "Internal server error",
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
/**
|
|
397
|
+
* Batch Analysis - Multiple symbols
|
|
398
|
+
* POST /api/batch/signal
|
|
399
|
+
* Body: { symbols: ["BTC", "ETH", "SOL"], interval: "1h" }
|
|
400
|
+
*/
|
|
401
|
+
app.post("/api/batch/signal", async (req, res) => {
|
|
402
|
+
try {
|
|
403
|
+
const { symbols, interval = "1h" } = req.body;
|
|
404
|
+
if (!symbols || !Array.isArray(symbols)) {
|
|
405
|
+
return res.status(400).json({
|
|
406
|
+
success: false,
|
|
407
|
+
error: "symbols array is required",
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
const results = await Promise.all(symbols.slice(0, 10).map(async (symbol) => {
|
|
411
|
+
try {
|
|
412
|
+
const data = await (0, crypto_1.fetchCryptoData)(symbol, interval, 250);
|
|
413
|
+
const signal = (0, crypto_1.generateSignal)(data);
|
|
414
|
+
return {
|
|
415
|
+
symbol: data.symbol,
|
|
416
|
+
success: true,
|
|
417
|
+
price: data.currentPrice,
|
|
418
|
+
signal: signal.signal,
|
|
419
|
+
confidence: signal.confidence,
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
catch (error) {
|
|
423
|
+
return {
|
|
424
|
+
symbol,
|
|
425
|
+
success: false,
|
|
426
|
+
error: error.message,
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
}));
|
|
430
|
+
res.json({
|
|
431
|
+
success: true,
|
|
432
|
+
data: results,
|
|
433
|
+
timestamp: Date.now(),
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
catch (error) {
|
|
437
|
+
res.status(500).json({
|
|
438
|
+
success: false,
|
|
439
|
+
error: error.message || "Internal server error",
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
// ============================================
|
|
444
|
+
// ERROR HANDLING
|
|
445
|
+
// ============================================
|
|
446
|
+
app.use((req, res) => {
|
|
447
|
+
res.status(404).json({
|
|
448
|
+
success: false,
|
|
449
|
+
error: "Endpoint not found",
|
|
450
|
+
availableEndpoints: [
|
|
451
|
+
"GET /api/signal/:symbol",
|
|
452
|
+
"GET /api/analyze/:symbol",
|
|
453
|
+
"GET /api/smc/:symbol",
|
|
454
|
+
"GET /api/orderblock/:symbol",
|
|
455
|
+
"GET /api/ict/:symbol",
|
|
456
|
+
"GET /api/strategy/:symbol",
|
|
457
|
+
"GET /api/price/:symbol",
|
|
458
|
+
"POST /api/batch/signal",
|
|
459
|
+
],
|
|
460
|
+
});
|
|
461
|
+
});
|
|
462
|
+
app.use((err, req, res, next) => {
|
|
463
|
+
console.error("Server error:", err);
|
|
464
|
+
res.status(500).json({
|
|
465
|
+
success: false,
|
|
466
|
+
error: "Internal server error",
|
|
467
|
+
});
|
|
468
|
+
});
|
|
469
|
+
// ============================================
|
|
470
|
+
// START SERVER (only when not in serverless)
|
|
471
|
+
// ============================================
|
|
472
|
+
// For Vercel serverless, we export the app without calling listen()
|
|
473
|
+
if (!process.env.VERCEL) {
|
|
474
|
+
app.listen(PORT, () => {
|
|
475
|
+
console.log(`
|
|
476
|
+
╔═══════════════════════════════════════════════════════════╗
|
|
477
|
+
║ 🚀 CRYPTO TRADING SIGNAL API SERVER ║
|
|
478
|
+
╠═══════════════════════════════════════════════════════════╣
|
|
479
|
+
║ Server running on: http://localhost:${PORT} ║
|
|
480
|
+
║ ║
|
|
481
|
+
║ Endpoints: ║
|
|
482
|
+
║ GET /api/signal/:symbol Quick signal ║
|
|
483
|
+
║ GET /api/analyze/:symbol Comprehensive analysis ║
|
|
484
|
+
║ GET /api/smc/:symbol Smart Money Concepts ║
|
|
485
|
+
║ GET /api/orderblock/:symbol Order Block strategy ║
|
|
486
|
+
║ GET /api/ict/:symbol ICT strategy ║
|
|
487
|
+
║ GET /api/strategy/:symbol Full trading strategy ║
|
|
488
|
+
║ GET /api/price/:symbol Price & candle data ║
|
|
489
|
+
║ POST /api/batch/signal Batch signals ║
|
|
490
|
+
║ ║
|
|
491
|
+
║ Free Deployment: ║
|
|
492
|
+
║ - Railway.app ║
|
|
493
|
+
║ - Render.com ║
|
|
494
|
+
║ - Fly.io ║
|
|
495
|
+
╚═══════════════════════════════════════════════════════════╝
|
|
496
|
+
`);
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
// Export for Vercel serverless
|
|
500
|
+
exports.default = app;
|
|
501
|
+
module.exports = app;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prab-cli",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.6",
|
|
4
4
|
"description": "AI-powered coding assistant for your terminal. Built with Groq's lightning-fast LLMs, featuring autonomous tool execution, syntax-highlighted output, and git integration.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "tsc",
|
|
12
12
|
"start": "node dist/index.js",
|
|
13
|
+
"server": "node dist/server/index.js",
|
|
14
|
+
"server:dev": "nodemon --exec ts-node src/server/index.ts",
|
|
13
15
|
"dev": "ts-node src/index.ts",
|
|
14
16
|
"dev:watch": "nodemon --exec ts-node src/index.ts",
|
|
15
17
|
"log": "ts-node src/log-viewer.ts",
|
|
@@ -69,8 +71,10 @@
|
|
|
69
71
|
"@langchain/openai": "^1.2.2",
|
|
70
72
|
"chalk": "^5.6.2",
|
|
71
73
|
"commander": "^14.0.2",
|
|
74
|
+
"cors": "^2.8.5",
|
|
72
75
|
"diff": "^8.0.2",
|
|
73
76
|
"dotenv": "^17.2.3",
|
|
77
|
+
"express": "^4.21.0",
|
|
74
78
|
"glob": "^13.0.0",
|
|
75
79
|
"groq-sdk": "^0.37.0",
|
|
76
80
|
"inquirer": "^13.1.0",
|
|
@@ -80,7 +84,9 @@
|
|
|
80
84
|
},
|
|
81
85
|
"devDependencies": {
|
|
82
86
|
"@eslint/js": "^9.39.2",
|
|
87
|
+
"@types/cors": "^2.8.17",
|
|
83
88
|
"@types/diff": "^7.0.2",
|
|
89
|
+
"@types/express": "^4.17.21",
|
|
84
90
|
"@types/glob": "^8.1.0",
|
|
85
91
|
"@types/inquirer": "^9.0.9",
|
|
86
92
|
"@types/node": "^25.0.3",
|