alpha-cli-toolkit 1.2.0 ā 1.4.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.
- package/bin/alpha.js +163 -5
- package/package.json +1 -1
package/bin/alpha.js
CHANGED
|
@@ -7,7 +7,7 @@ const Table = require('cli-table3');
|
|
|
7
7
|
const { authenticateViaBrowser, getToken, clearToken } = require('../utils/auth');
|
|
8
8
|
|
|
9
9
|
const program = new Command();
|
|
10
|
-
const BACKEND_URL = process.env.ALPHA_BACKEND_URL;
|
|
10
|
+
const BACKEND_URL = process.env.ALPHA_BACKEND_URL || 'https://alpha-cli.onrender.com/api';
|
|
11
11
|
|
|
12
12
|
program
|
|
13
13
|
.name('alpha')
|
|
@@ -71,7 +71,7 @@ program
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
// Backend health
|
|
74
|
-
const healthUrl =
|
|
74
|
+
const healthUrl = `${BACKEND_URL.replace(/\/api$/, '')}/health`;
|
|
75
75
|
try {
|
|
76
76
|
const { data } = await axios.get(healthUrl, { timeout: 3000 });
|
|
77
77
|
console.log(chalk.green(' ā
Backend online') + chalk.grey(` (${data.timestamp})`));
|
|
@@ -111,19 +111,21 @@ program
|
|
|
111
111
|
.option('-n, --nsd', 'Trending NASDAQ assets via Yahoo Finance')
|
|
112
112
|
.option('-f, --nft', 'NFT Market Indexes (Nansen)')
|
|
113
113
|
.option('-m, --macro', 'Smart Money Holdings \u0026 Macro (Nansen)')
|
|
114
|
+
.option('--min-usd <value>', 'Filter Smart Money by minimum USD value', '1000')
|
|
115
|
+
.option('--chains <list>', 'Comma-separated chains (e.g. solana,ethereum)', 'solana')
|
|
114
116
|
.action(async (options) => {
|
|
115
117
|
const token = checkAuth();
|
|
116
118
|
const axios = require('axios');
|
|
117
119
|
|
|
118
|
-
let url = `${BACKEND_URL}/market/crypto/trending`;
|
|
120
|
+
let url = `${BACKEND_URL}/market/crypto/trending?min_usd=${options.minUsd}&chains=${options.chains}`;
|
|
119
121
|
let cType = 'CRYPTO';
|
|
120
122
|
|
|
121
123
|
if (options.sp500) { url = `${BACKEND_URL}/market/tradfi/sp500`; cType = 'S&P 500'; }
|
|
122
124
|
else if (options.nsd) { url = `${BACKEND_URL}/market/tradfi/nsd`; cType = 'NASDAQ'; }
|
|
123
125
|
else if (options.nft || options.macro) {
|
|
124
|
-
console.log(chalk.cyan(`\nš Fetching Nansen Market Macro Insights...`));
|
|
126
|
+
console.log(chalk.cyan(`\nš Fetching Nansen Market Macro Insights (Chains: ${options.chains})...`));
|
|
125
127
|
try {
|
|
126
|
-
const { data } = await axios.get(`${BACKEND_URL}/market/macro`, { headers: authHeaders(token) });
|
|
128
|
+
const { data } = await axios.get(`${BACKEND_URL}/market/macro?chains=${options.chains}`, { headers: authHeaders(token) });
|
|
127
129
|
if (options.nft) {
|
|
128
130
|
console.log(gradient.atlas(`\nāāā Nansen NFT Indexes āāāāāāāāāāāāāāāāāāāāāāāāāā`));
|
|
129
131
|
console.log(JSON.stringify(data.nftIndexes, null, 2));
|
|
@@ -150,6 +152,14 @@ program
|
|
|
150
152
|
}
|
|
151
153
|
|
|
152
154
|
buildMarketTable(items, cType);
|
|
155
|
+
|
|
156
|
+
if (data.netflow?.length) {
|
|
157
|
+
console.log(gradient.atlas(`\nāāā Whale Netflows (Min: $${options.minUsd}) āāāāā`));
|
|
158
|
+
data.netflow.slice(0, 5).forEach((flow) => {
|
|
159
|
+
const direction = flow.net_flow_usd >= 0 ? chalk.green('INFLOW') : chalk.red('OUTFLOW');
|
|
160
|
+
console.log(` ${chalk.bold(flow.token_name || flow.symbol)}: ${direction} $${Math.abs(flow.net_flow_usd).toLocaleString()}`);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
153
163
|
} catch (err) {
|
|
154
164
|
console.error(chalk.red('Failed to fetch market data:'), err.response?.data?.error || err.message);
|
|
155
165
|
}
|
|
@@ -211,6 +221,154 @@ program
|
|
|
211
221
|
}
|
|
212
222
|
});
|
|
213
223
|
|
|
224
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
225
|
+
// FLOW COMMAND (Smart Money Netflow Explorer)
|
|
226
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
227
|
+
program
|
|
228
|
+
.command('flow')
|
|
229
|
+
.description('Deep-dive into capital rotation via Smart Money Netflows')
|
|
230
|
+
.option('--chains <list>', 'Comma-separated chains (e.g. solana,ethereum)', 'solana')
|
|
231
|
+
.option('--sort <period>', 'Sorting timeframe: 1h, 24h, 7d, 30d', '24h')
|
|
232
|
+
.option('--order <dir>', 'Sort direction: DESC, ASC', 'DESC')
|
|
233
|
+
.option('--sector <name>', 'Filter by token sector (e.g. DeFi, AI, Meme)')
|
|
234
|
+
.option('--labels <list>', 'Smart Money labels to include', 'Fund,Smart Trader')
|
|
235
|
+
.option('--stablecoins', 'Include stablecoins in the analysis', false)
|
|
236
|
+
.action(async (options) => {
|
|
237
|
+
const token = checkAuth();
|
|
238
|
+
const axios = require('axios');
|
|
239
|
+
|
|
240
|
+
console.log(chalk.cyan(`\nš Exploring Smart Money rotation...`));
|
|
241
|
+
console.log(chalk.grey(` Timeframe: ${options.sort} | Chains: ${options.chains} | Sort: ${options.order}\n`));
|
|
242
|
+
|
|
243
|
+
try {
|
|
244
|
+
const { data } = await axios.get(`${BACKEND_URL}/market/smart-money/netflow`, {
|
|
245
|
+
params: {
|
|
246
|
+
chains: options.chains,
|
|
247
|
+
sort: options.sort,
|
|
248
|
+
direction: options.order,
|
|
249
|
+
sector: options.sector,
|
|
250
|
+
labels: options.labels,
|
|
251
|
+
include_stablecoins: options.stablecoins
|
|
252
|
+
},
|
|
253
|
+
headers: authHeaders(token)
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
const items = data.data || [];
|
|
257
|
+
|
|
258
|
+
if (!items.length) {
|
|
259
|
+
console.log(chalk.yellow(' No flow data found for these filters.\n'));
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const table = new Table({
|
|
264
|
+
head: [
|
|
265
|
+
chalk.bold.white('Asset'),
|
|
266
|
+
chalk.bold.white('1H Flow'),
|
|
267
|
+
chalk.bold.white('24H Flow'),
|
|
268
|
+
chalk.bold.white('7D Flow'),
|
|
269
|
+
chalk.bold.white('Sector'),
|
|
270
|
+
],
|
|
271
|
+
colWidths: [18, 16, 16, 16, 20],
|
|
272
|
+
style: { border: ['grey'] },
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
items.slice(0, 15).forEach((item) => {
|
|
276
|
+
const formatFlow = (val) => {
|
|
277
|
+
if (!val) return chalk.grey('ā');
|
|
278
|
+
const colorizer = val >= 0 ? chalk.green : chalk.red;
|
|
279
|
+
const prefix = val >= 0 ? '+' : '';
|
|
280
|
+
return colorizer(`${prefix}$${Math.abs(val / 1e3).toFixed(1)}k`);
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
table.push([
|
|
284
|
+
chalk.bold.cyan(item.token_symbol || '???'),
|
|
285
|
+
formatFlow(item.net_flow_1h_usd),
|
|
286
|
+
formatFlow(item.net_flow_24h_usd),
|
|
287
|
+
formatFlow(item.net_flow_7d_usd),
|
|
288
|
+
chalk.grey(item.token_sectors?.[0] || 'ā'),
|
|
289
|
+
]);
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
console.log(gradient.atlas('āāā Smart Money Netflow Explorer āāāāāāāāāāāāāāāā'));
|
|
293
|
+
console.log(table.toString());
|
|
294
|
+
console.log(chalk.grey(`\n * Flows in USD (k = thousands). Positive = Accumulation, Negative = Distribution.`));
|
|
295
|
+
console.log('');
|
|
296
|
+
} catch (err) {
|
|
297
|
+
console.error(chalk.red('Flow exploration failed:'), err.response?.data?.error || err.message);
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
302
|
+
// HISTORY COMMAND (Smart Money Historical Analysis)
|
|
303
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
304
|
+
program
|
|
305
|
+
.command('history <symbol>')
|
|
306
|
+
.description('Analyze historical Smart Money conviction for a token')
|
|
307
|
+
.option('--from <date>', 'Start date (YYYY-MM-DD)', '')
|
|
308
|
+
.option('--to <date>', 'End date (YYYY-MM-DD)', '')
|
|
309
|
+
.option('--chains <list>', 'Comma-separated chains', 'solana')
|
|
310
|
+
.action(async (symbol, options) => {
|
|
311
|
+
const token = checkAuth();
|
|
312
|
+
const axios = require('axios');
|
|
313
|
+
|
|
314
|
+
console.log(chalk.cyan(`\nš Analyzing historical Smart Money conviction for ${chalk.bold(symbol.toUpperCase())}...`));
|
|
315
|
+
|
|
316
|
+
try {
|
|
317
|
+
const { data } = await axios.get(`${BACKEND_URL}/market/smart-money/historical-holdings`, {
|
|
318
|
+
params: {
|
|
319
|
+
symbol,
|
|
320
|
+
from: options.from,
|
|
321
|
+
to: options.to,
|
|
322
|
+
chains: options.chains
|
|
323
|
+
},
|
|
324
|
+
headers: authHeaders(token)
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
const items = data.history || [];
|
|
328
|
+
|
|
329
|
+
if (!items.length) {
|
|
330
|
+
console.log(chalk.yellow(` No historical data found for ${symbol}.\n`));
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Display Conviction Score
|
|
335
|
+
const scoreColor = data.convictionScore === 'HIGH' ? chalk.green : data.convictionScore === 'MEDIUM' ? chalk.yellow : chalk.red;
|
|
336
|
+
console.log(`\n šÆ Conviction Score: ${scoreColor.bold(data.convictionScore)}`);
|
|
337
|
+
console.log(chalk.grey(` (${data.consecutiveDays} consecutive days of accumulation)\n`));
|
|
338
|
+
|
|
339
|
+
const table = new Table({
|
|
340
|
+
head: [
|
|
341
|
+
chalk.bold.white('Date'),
|
|
342
|
+
chalk.bold.white('SM Balance'),
|
|
343
|
+
chalk.bold.white('24H Change'),
|
|
344
|
+
chalk.bold.white('USD Value'),
|
|
345
|
+
],
|
|
346
|
+
colWidths: [14, 18, 16, 18],
|
|
347
|
+
style: { border: ['grey'] },
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
items.slice(0, 15).forEach((day) => {
|
|
351
|
+
const change = day.balance_24h_percent_change;
|
|
352
|
+
const changeColor = change >= 0 ? chalk.green : chalk.red;
|
|
353
|
+
const arrow = change >= 0 ? 'ā²' : 'ā¼';
|
|
354
|
+
|
|
355
|
+
table.push([
|
|
356
|
+
chalk.white(day.date),
|
|
357
|
+
chalk.cyan(day.balance?.toLocaleString()),
|
|
358
|
+
changeColor(`${arrow} ${(change * 100).toFixed(2)}%`),
|
|
359
|
+
chalk.white(`$${(day.value_usd / 1e3).toFixed(1)}k`),
|
|
360
|
+
]);
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
console.log(gradient.atlas(`āāā Historical Trend: ${symbol.toUpperCase()} āāāāāāāāāāāāāā`));
|
|
364
|
+
console.log(table.toString());
|
|
365
|
+
console.log(chalk.grey(`\n * Showing the latest 15 snapshots. Historical data up to 4 years available.`));
|
|
366
|
+
console.log('');
|
|
367
|
+
} catch (err) {
|
|
368
|
+
console.error(chalk.red('Historical analysis failed:'), err.response?.data?.error || err.message);
|
|
369
|
+
}
|
|
370
|
+
});
|
|
371
|
+
|
|
214
372
|
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
215
373
|
// ENTITY COMMAND
|
|
216
374
|
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|