@tradejs/cli 1.0.3 → 1.0.5
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/README.md +1 -1
- package/dist/cli.js +145 -124
- package/dist/scripts/signals.js +144 -123
- package/package.json +18 -10
package/README.md
CHANGED
package/dist/cli.js
CHANGED
|
@@ -10218,7 +10218,7 @@ var init_results = __esm({
|
|
|
10218
10218
|
|
|
10219
10219
|
// src/scripts/signals.ts
|
|
10220
10220
|
var signals_exports = {};
|
|
10221
|
-
var import_config5, import_args12, import_progress5, import_connectors8, import_chalk16, import_connectors9, import_cli8, import_async3, import_constants4, import_strategies3, import_time3, import_logger4, import_redis5, PRELOAD_START, projectRoot6, flags12, minTouches, offset, interval3, resolveStrategyNameByConfigKey, loadRuntimeStrategies, resolveSignalsConnectorName, findSignals, signals;
|
|
10221
|
+
var import_config5, import_args12, import_progress5, import_connectors8, import_chalk16, import_connectors9, import_cli8, import_async3, import_constants4, import_strategies3, import_time3, import_logger4, import_redis5, PRELOAD_START, projectRoot6, flags12, minTouches, offset, interval3, formatElapsed, resolveStrategyNameByConfigKey, loadRuntimeStrategies, resolveSignalsConnectorName, findSignals, signals;
|
|
10222
10222
|
var init_signals = __esm({
|
|
10223
10223
|
"src/scripts/signals.ts"() {
|
|
10224
10224
|
"use strict";
|
|
@@ -10258,6 +10258,7 @@ var init_signals = __esm({
|
|
|
10258
10258
|
minTouches = parseInt(flags12.points);
|
|
10259
10259
|
offset = parseInt(flags12.offset);
|
|
10260
10260
|
interval3 = flags12.timeframe.toString();
|
|
10261
|
+
formatElapsed = (startedAt) => `${((Date.now() - startedAt) / 1e3).toFixed(1)}s`;
|
|
10261
10262
|
resolveStrategyNameByConfigKey = (userName2, key) => {
|
|
10262
10263
|
const parts = key.split(":");
|
|
10263
10264
|
if (parts.length !== 5) {
|
|
@@ -10368,144 +10369,164 @@ var init_signals = __esm({
|
|
|
10368
10369
|
}
|
|
10369
10370
|
};
|
|
10370
10371
|
signals = async () => {
|
|
10372
|
+
const startedAt = Date.now();
|
|
10371
10373
|
const signals2 = new Array();
|
|
10372
|
-
|
|
10373
|
-
|
|
10374
|
-
connectorName
|
|
10375
|
-
|
|
10376
|
-
|
|
10377
|
-
if (!connectorFactory) {
|
|
10378
|
-
throw new Error(`Connector "${connectorName}" is not registered`);
|
|
10379
|
-
}
|
|
10380
|
-
const marketConnector = await connectorFactory({
|
|
10381
|
-
userName: flags12.user
|
|
10382
|
-
});
|
|
10383
|
-
let btcBinanceConnector = marketConnector;
|
|
10384
|
-
let btcCoinbaseConnector = marketConnector;
|
|
10385
|
-
if (connectorName.toLowerCase() === import_connectors9.DEFAULT_CONNECTOR_NAME.toLowerCase()) {
|
|
10386
|
-
const binanceFactory = await (0, import_connectors9.getConnectorCreatorByName)(
|
|
10387
|
-
import_connectors8.ConnectorNames.Binance,
|
|
10374
|
+
let status = "completed";
|
|
10375
|
+
try {
|
|
10376
|
+
const connectorName = await resolveSignalsConnectorName(flags12.connector);
|
|
10377
|
+
const connectorFactory = await (0, import_connectors9.getConnectorCreatorByName)(
|
|
10378
|
+
connectorName,
|
|
10388
10379
|
projectRoot6
|
|
10389
10380
|
);
|
|
10390
|
-
if (
|
|
10391
|
-
|
|
10392
|
-
|
|
10393
|
-
|
|
10394
|
-
|
|
10395
|
-
|
|
10396
|
-
|
|
10397
|
-
|
|
10381
|
+
if (!connectorFactory) {
|
|
10382
|
+
throw new Error(`Connector "${connectorName}" is not registered`);
|
|
10383
|
+
}
|
|
10384
|
+
const marketConnector = await connectorFactory({
|
|
10385
|
+
userName: flags12.user
|
|
10386
|
+
});
|
|
10387
|
+
let btcBinanceConnector = marketConnector;
|
|
10388
|
+
let btcCoinbaseConnector = marketConnector;
|
|
10389
|
+
if (connectorName.toLowerCase() === import_connectors9.DEFAULT_CONNECTOR_NAME.toLowerCase()) {
|
|
10390
|
+
const binanceFactory = await (0, import_connectors9.getConnectorCreatorByName)(
|
|
10391
|
+
import_connectors8.ConnectorNames.Binance,
|
|
10392
|
+
projectRoot6
|
|
10398
10393
|
);
|
|
10394
|
+
if (binanceFactory) {
|
|
10395
|
+
btcBinanceConnector = await binanceFactory({
|
|
10396
|
+
userName: flags12.user
|
|
10397
|
+
});
|
|
10398
|
+
} else {
|
|
10399
|
+
import_logger4.logger.warn(
|
|
10400
|
+
"Binance connector is unavailable. Reusing %s.",
|
|
10401
|
+
connectorName
|
|
10402
|
+
);
|
|
10403
|
+
}
|
|
10404
|
+
const coinbaseFactory = await (0, import_connectors9.getConnectorCreatorByName)(
|
|
10405
|
+
import_connectors8.ConnectorNames.Coinbase,
|
|
10406
|
+
projectRoot6
|
|
10407
|
+
);
|
|
10408
|
+
if (coinbaseFactory) {
|
|
10409
|
+
btcCoinbaseConnector = await coinbaseFactory({
|
|
10410
|
+
userName: flags12.user
|
|
10411
|
+
});
|
|
10412
|
+
} else {
|
|
10413
|
+
import_logger4.logger.warn(
|
|
10414
|
+
"Coinbase connector is unavailable. Reusing %s.",
|
|
10415
|
+
connectorName
|
|
10416
|
+
);
|
|
10417
|
+
}
|
|
10399
10418
|
}
|
|
10400
|
-
const
|
|
10401
|
-
|
|
10402
|
-
|
|
10419
|
+
const tickers = await (0, import_cli8.getTickers)(
|
|
10420
|
+
marketConnector,
|
|
10421
|
+
flags12.tickers,
|
|
10422
|
+
flags12.exclude,
|
|
10423
|
+
flags12.tickersLimit,
|
|
10424
|
+
flags12.chunk
|
|
10403
10425
|
);
|
|
10404
|
-
if (
|
|
10405
|
-
|
|
10406
|
-
|
|
10407
|
-
|
|
10408
|
-
|
|
10426
|
+
if (flags12.showTickersList) {
|
|
10427
|
+
console.log(import_chalk16.default.gray(JSON.stringify(tickers.sort(), null, 2)));
|
|
10428
|
+
return;
|
|
10429
|
+
}
|
|
10430
|
+
if (!flags12.cacheOnly) {
|
|
10431
|
+
await (0, import_cli8.update)(marketConnector, interval3, tickers);
|
|
10432
|
+
if (btcBinanceConnector !== marketConnector) {
|
|
10433
|
+
await (0, import_cli8.update)(btcBinanceConnector, interval3, ["BTCUSDT"]);
|
|
10434
|
+
}
|
|
10435
|
+
if (btcCoinbaseConnector !== marketConnector) {
|
|
10436
|
+
await (0, import_cli8.update)(btcCoinbaseConnector, interval3, ["BTCUSDT"]);
|
|
10437
|
+
}
|
|
10438
|
+
}
|
|
10439
|
+
const currentTimestamp = (0, import_time3.getTimestamp)();
|
|
10440
|
+
const [btcBinanceData, btcCoinbaseData] = await Promise.all([
|
|
10441
|
+
btcBinanceConnector.kline({
|
|
10442
|
+
symbol: "BTCUSDT",
|
|
10443
|
+
start: PRELOAD_START,
|
|
10444
|
+
end: currentTimestamp,
|
|
10445
|
+
cacheOnly: true,
|
|
10446
|
+
interval: interval3
|
|
10447
|
+
}),
|
|
10448
|
+
btcCoinbaseConnector.kline({
|
|
10449
|
+
symbol: "BTCUSDT",
|
|
10450
|
+
start: PRELOAD_START,
|
|
10451
|
+
end: currentTimestamp,
|
|
10452
|
+
cacheOnly: true,
|
|
10453
|
+
interval: interval3
|
|
10454
|
+
})
|
|
10455
|
+
]);
|
|
10456
|
+
if (flags12.updateOnly) {
|
|
10457
|
+
return;
|
|
10458
|
+
}
|
|
10459
|
+
const runtimeStrategies = await loadRuntimeStrategies(flags12.user);
|
|
10460
|
+
if (!runtimeStrategies.length) {
|
|
10409
10461
|
import_logger4.logger.warn(
|
|
10410
|
-
"
|
|
10411
|
-
|
|
10462
|
+
"No strategy configs found by users:%s:strategies:*:config",
|
|
10463
|
+
flags12.user
|
|
10412
10464
|
);
|
|
10465
|
+
return;
|
|
10413
10466
|
}
|
|
10414
|
-
|
|
10415
|
-
|
|
10416
|
-
|
|
10417
|
-
|
|
10418
|
-
|
|
10419
|
-
|
|
10420
|
-
|
|
10421
|
-
|
|
10422
|
-
|
|
10423
|
-
|
|
10424
|
-
|
|
10425
|
-
|
|
10426
|
-
|
|
10427
|
-
await (0,
|
|
10428
|
-
|
|
10429
|
-
|
|
10467
|
+
import_logger4.logger.info(
|
|
10468
|
+
import_chalk16.default.yellow(
|
|
10469
|
+
`loaded strategies: ${runtimeStrategies.map((s) => s.strategyName).join(", ")}`
|
|
10470
|
+
)
|
|
10471
|
+
);
|
|
10472
|
+
const bar = new import_progress5.default(
|
|
10473
|
+
":current/:total [:bar][:percent] :found :eta(s) :symbol",
|
|
10474
|
+
{
|
|
10475
|
+
total: tickers.length,
|
|
10476
|
+
width: 30
|
|
10477
|
+
}
|
|
10478
|
+
);
|
|
10479
|
+
import_logger4.logger.info(import_chalk16.default.yellow(`tickers: ${tickers.length}`));
|
|
10480
|
+
await (0, import_async3.runWithConcurrency)(tickers, 5, async (symbol) => {
|
|
10481
|
+
const signal = await findSignals(
|
|
10482
|
+
symbol,
|
|
10483
|
+
marketConnector,
|
|
10484
|
+
btcBinanceData,
|
|
10485
|
+
btcCoinbaseData,
|
|
10486
|
+
runtimeStrategies
|
|
10487
|
+
);
|
|
10488
|
+
if (signal) {
|
|
10489
|
+
signals2.push(signal);
|
|
10490
|
+
}
|
|
10491
|
+
bar.tick(1, {
|
|
10492
|
+
found: import_chalk16.default.cyan(signals2.length),
|
|
10493
|
+
symbol: import_chalk16.default.gray(symbol)
|
|
10494
|
+
});
|
|
10495
|
+
});
|
|
10496
|
+
if (!flags12.skipScreenshots) {
|
|
10497
|
+
await (0, import_cli8.makeScreenshots)(signals2, "15");
|
|
10498
|
+
await (0, import_cli8.makeScreenshots)(signals2, "60");
|
|
10430
10499
|
}
|
|
10431
|
-
if (
|
|
10432
|
-
await (0, import_cli8.
|
|
10500
|
+
if (flags12.notify) {
|
|
10501
|
+
await (0, import_cli8.sendToTG)(signals2, "15");
|
|
10433
10502
|
}
|
|
10434
|
-
|
|
10435
|
-
|
|
10436
|
-
|
|
10437
|
-
|
|
10438
|
-
|
|
10439
|
-
|
|
10440
|
-
end: currentTimestamp,
|
|
10441
|
-
cacheOnly: true,
|
|
10442
|
-
interval: interval3
|
|
10443
|
-
}),
|
|
10444
|
-
btcCoinbaseConnector.kline({
|
|
10445
|
-
symbol: "BTCUSDT",
|
|
10446
|
-
start: PRELOAD_START,
|
|
10447
|
-
end: currentTimestamp,
|
|
10448
|
-
cacheOnly: true,
|
|
10449
|
-
interval: interval3
|
|
10450
|
-
})
|
|
10451
|
-
]);
|
|
10452
|
-
if (flags12.updateOnly) {
|
|
10453
|
-
return;
|
|
10454
|
-
}
|
|
10455
|
-
const runtimeStrategies = await loadRuntimeStrategies(flags12.user);
|
|
10456
|
-
if (!runtimeStrategies.length) {
|
|
10457
|
-
import_logger4.logger.warn(
|
|
10458
|
-
"No strategy configs found by users:%s:strategies:*:config",
|
|
10459
|
-
flags12.user
|
|
10503
|
+
import_logger4.logger.info(
|
|
10504
|
+
JSON.stringify(
|
|
10505
|
+
signals2.map((s) => s.symbol),
|
|
10506
|
+
null,
|
|
10507
|
+
2
|
|
10508
|
+
)
|
|
10460
10509
|
);
|
|
10461
|
-
|
|
10462
|
-
|
|
10463
|
-
|
|
10464
|
-
|
|
10465
|
-
|
|
10466
|
-
)
|
|
10467
|
-
|
|
10468
|
-
|
|
10469
|
-
|
|
10470
|
-
|
|
10471
|
-
|
|
10472
|
-
|
|
10473
|
-
}
|
|
10474
|
-
);
|
|
10475
|
-
import_logger4.logger.info(import_chalk16.default.yellow(`tickers: ${tickers.length}`));
|
|
10476
|
-
await (0, import_async3.runWithConcurrency)(tickers, 5, async (symbol) => {
|
|
10477
|
-
const signal = await findSignals(
|
|
10478
|
-
symbol,
|
|
10479
|
-
marketConnector,
|
|
10480
|
-
btcBinanceData,
|
|
10481
|
-
btcCoinbaseData,
|
|
10482
|
-
runtimeStrategies
|
|
10510
|
+
} catch (error) {
|
|
10511
|
+
status = "failed";
|
|
10512
|
+
import_logger4.logger.error(
|
|
10513
|
+
"signals failed: %s",
|
|
10514
|
+
error?.message || String(error)
|
|
10515
|
+
);
|
|
10516
|
+
throw error;
|
|
10517
|
+
} finally {
|
|
10518
|
+
import_logger4.logger.info(
|
|
10519
|
+
import_chalk16.default.yellow(
|
|
10520
|
+
`signals ${status} in ${formatElapsed(startedAt)} (found=${signals2.length})`
|
|
10521
|
+
)
|
|
10483
10522
|
);
|
|
10484
|
-
if (signal) {
|
|
10485
|
-
signals2.push(signal);
|
|
10486
|
-
}
|
|
10487
|
-
bar.tick(1, {
|
|
10488
|
-
found: import_chalk16.default.cyan(signals2.length),
|
|
10489
|
-
symbol: import_chalk16.default.gray(symbol)
|
|
10490
|
-
});
|
|
10491
|
-
});
|
|
10492
|
-
if (!flags12.skipScreenshots) {
|
|
10493
|
-
await (0, import_cli8.makeScreenshots)(signals2, "15");
|
|
10494
|
-
await (0, import_cli8.makeScreenshots)(signals2, "60");
|
|
10495
|
-
}
|
|
10496
|
-
if (flags12.notify) {
|
|
10497
|
-
await (0, import_cli8.sendToTG)(signals2, "15");
|
|
10498
10523
|
}
|
|
10499
|
-
import_logger4.logger.info(
|
|
10500
|
-
JSON.stringify(
|
|
10501
|
-
signals2.map((s) => s.symbol),
|
|
10502
|
-
null,
|
|
10503
|
-
2
|
|
10504
|
-
)
|
|
10505
|
-
);
|
|
10506
|
-
process.exit();
|
|
10507
10524
|
};
|
|
10508
|
-
signals()
|
|
10525
|
+
signals().then(() => {
|
|
10526
|
+
process.exit(0);
|
|
10527
|
+
}).catch(() => {
|
|
10528
|
+
process.exit(1);
|
|
10529
|
+
});
|
|
10509
10530
|
}
|
|
10510
10531
|
});
|
|
10511
10532
|
|
package/dist/scripts/signals.js
CHANGED
|
@@ -59,6 +59,7 @@ var flags = import_args.default.parse(process.argv);
|
|
|
59
59
|
var minTouches = parseInt(flags.points);
|
|
60
60
|
var offset = parseInt(flags.offset);
|
|
61
61
|
var interval = flags.timeframe.toString();
|
|
62
|
+
var formatElapsed = (startedAt) => `${((Date.now() - startedAt) / 1e3).toFixed(1)}s`;
|
|
62
63
|
var resolveStrategyNameByConfigKey = (userName, key) => {
|
|
63
64
|
const parts = key.split(":");
|
|
64
65
|
if (parts.length !== 5) {
|
|
@@ -169,141 +170,161 @@ var findSignals = async (symbol, connector, btcBinanceData, btcCoinbaseData, run
|
|
|
169
170
|
}
|
|
170
171
|
};
|
|
171
172
|
var signals = async () => {
|
|
173
|
+
const startedAt = Date.now();
|
|
172
174
|
const signals2 = new Array();
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
connectorName
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
if (!connectorFactory) {
|
|
179
|
-
throw new Error(`Connector "${connectorName}" is not registered`);
|
|
180
|
-
}
|
|
181
|
-
const marketConnector = await connectorFactory({
|
|
182
|
-
userName: flags.user
|
|
183
|
-
});
|
|
184
|
-
let btcBinanceConnector = marketConnector;
|
|
185
|
-
let btcCoinbaseConnector = marketConnector;
|
|
186
|
-
if (connectorName.toLowerCase() === import_connectors2.DEFAULT_CONNECTOR_NAME.toLowerCase()) {
|
|
187
|
-
const binanceFactory = await (0, import_connectors2.getConnectorCreatorByName)(
|
|
188
|
-
import_connectors.ConnectorNames.Binance,
|
|
175
|
+
let status = "completed";
|
|
176
|
+
try {
|
|
177
|
+
const connectorName = await resolveSignalsConnectorName(flags.connector);
|
|
178
|
+
const connectorFactory = await (0, import_connectors2.getConnectorCreatorByName)(
|
|
179
|
+
connectorName,
|
|
189
180
|
projectRoot
|
|
190
181
|
);
|
|
191
|
-
if (
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
182
|
+
if (!connectorFactory) {
|
|
183
|
+
throw new Error(`Connector "${connectorName}" is not registered`);
|
|
184
|
+
}
|
|
185
|
+
const marketConnector = await connectorFactory({
|
|
186
|
+
userName: flags.user
|
|
187
|
+
});
|
|
188
|
+
let btcBinanceConnector = marketConnector;
|
|
189
|
+
let btcCoinbaseConnector = marketConnector;
|
|
190
|
+
if (connectorName.toLowerCase() === import_connectors2.DEFAULT_CONNECTOR_NAME.toLowerCase()) {
|
|
191
|
+
const binanceFactory = await (0, import_connectors2.getConnectorCreatorByName)(
|
|
192
|
+
import_connectors.ConnectorNames.Binance,
|
|
193
|
+
projectRoot
|
|
199
194
|
);
|
|
195
|
+
if (binanceFactory) {
|
|
196
|
+
btcBinanceConnector = await binanceFactory({
|
|
197
|
+
userName: flags.user
|
|
198
|
+
});
|
|
199
|
+
} else {
|
|
200
|
+
import_logger.logger.warn(
|
|
201
|
+
"Binance connector is unavailable. Reusing %s.",
|
|
202
|
+
connectorName
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
const coinbaseFactory = await (0, import_connectors2.getConnectorCreatorByName)(
|
|
206
|
+
import_connectors.ConnectorNames.Coinbase,
|
|
207
|
+
projectRoot
|
|
208
|
+
);
|
|
209
|
+
if (coinbaseFactory) {
|
|
210
|
+
btcCoinbaseConnector = await coinbaseFactory({
|
|
211
|
+
userName: flags.user
|
|
212
|
+
});
|
|
213
|
+
} else {
|
|
214
|
+
import_logger.logger.warn(
|
|
215
|
+
"Coinbase connector is unavailable. Reusing %s.",
|
|
216
|
+
connectorName
|
|
217
|
+
);
|
|
218
|
+
}
|
|
200
219
|
}
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
|
|
220
|
+
const tickers = await (0, import_cli.getTickers)(
|
|
221
|
+
marketConnector,
|
|
222
|
+
flags.tickers,
|
|
223
|
+
flags.exclude,
|
|
224
|
+
flags.tickersLimit,
|
|
225
|
+
flags.chunk
|
|
204
226
|
);
|
|
205
|
-
if (
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
227
|
+
if (flags.showTickersList) {
|
|
228
|
+
console.log(import_chalk.default.gray(JSON.stringify(tickers.sort(), null, 2)));
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
if (!flags.cacheOnly) {
|
|
232
|
+
await (0, import_cli.update)(marketConnector, interval, tickers);
|
|
233
|
+
if (btcBinanceConnector !== marketConnector) {
|
|
234
|
+
await (0, import_cli.update)(btcBinanceConnector, interval, ["BTCUSDT"]);
|
|
235
|
+
}
|
|
236
|
+
if (btcCoinbaseConnector !== marketConnector) {
|
|
237
|
+
await (0, import_cli.update)(btcCoinbaseConnector, interval, ["BTCUSDT"]);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
const currentTimestamp = (0, import_time.getTimestamp)();
|
|
241
|
+
const [btcBinanceData, btcCoinbaseData] = await Promise.all([
|
|
242
|
+
btcBinanceConnector.kline({
|
|
243
|
+
symbol: "BTCUSDT",
|
|
244
|
+
start: PRELOAD_START,
|
|
245
|
+
end: currentTimestamp,
|
|
246
|
+
cacheOnly: true,
|
|
247
|
+
interval
|
|
248
|
+
}),
|
|
249
|
+
btcCoinbaseConnector.kline({
|
|
250
|
+
symbol: "BTCUSDT",
|
|
251
|
+
start: PRELOAD_START,
|
|
252
|
+
end: currentTimestamp,
|
|
253
|
+
cacheOnly: true,
|
|
254
|
+
interval
|
|
255
|
+
})
|
|
256
|
+
]);
|
|
257
|
+
if (flags.updateOnly) {
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
const runtimeStrategies = await loadRuntimeStrategies(flags.user);
|
|
261
|
+
if (!runtimeStrategies.length) {
|
|
210
262
|
import_logger.logger.warn(
|
|
211
|
-
"
|
|
212
|
-
|
|
263
|
+
"No strategy configs found by users:%s:strategies:*:config",
|
|
264
|
+
flags.user
|
|
213
265
|
);
|
|
266
|
+
return;
|
|
214
267
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
await (0,
|
|
229
|
-
|
|
230
|
-
|
|
268
|
+
import_logger.logger.info(
|
|
269
|
+
import_chalk.default.yellow(
|
|
270
|
+
`loaded strategies: ${runtimeStrategies.map((s) => s.strategyName).join(", ")}`
|
|
271
|
+
)
|
|
272
|
+
);
|
|
273
|
+
const bar = new import_progress.default(
|
|
274
|
+
":current/:total [:bar][:percent] :found :eta(s) :symbol",
|
|
275
|
+
{
|
|
276
|
+
total: tickers.length,
|
|
277
|
+
width: 30
|
|
278
|
+
}
|
|
279
|
+
);
|
|
280
|
+
import_logger.logger.info(import_chalk.default.yellow(`tickers: ${tickers.length}`));
|
|
281
|
+
await (0, import_async.runWithConcurrency)(tickers, 5, async (symbol) => {
|
|
282
|
+
const signal = await findSignals(
|
|
283
|
+
symbol,
|
|
284
|
+
marketConnector,
|
|
285
|
+
btcBinanceData,
|
|
286
|
+
btcCoinbaseData,
|
|
287
|
+
runtimeStrategies
|
|
288
|
+
);
|
|
289
|
+
if (signal) {
|
|
290
|
+
signals2.push(signal);
|
|
291
|
+
}
|
|
292
|
+
bar.tick(1, {
|
|
293
|
+
found: import_chalk.default.cyan(signals2.length),
|
|
294
|
+
symbol: import_chalk.default.gray(symbol)
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
if (!flags.skipScreenshots) {
|
|
298
|
+
await (0, import_cli.makeScreenshots)(signals2, "15");
|
|
299
|
+
await (0, import_cli.makeScreenshots)(signals2, "60");
|
|
231
300
|
}
|
|
232
|
-
if (
|
|
233
|
-
await (0, import_cli.
|
|
301
|
+
if (flags.notify) {
|
|
302
|
+
await (0, import_cli.sendToTG)(signals2, "15");
|
|
234
303
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
end: currentTimestamp,
|
|
242
|
-
cacheOnly: true,
|
|
243
|
-
interval
|
|
244
|
-
}),
|
|
245
|
-
btcCoinbaseConnector.kline({
|
|
246
|
-
symbol: "BTCUSDT",
|
|
247
|
-
start: PRELOAD_START,
|
|
248
|
-
end: currentTimestamp,
|
|
249
|
-
cacheOnly: true,
|
|
250
|
-
interval
|
|
251
|
-
})
|
|
252
|
-
]);
|
|
253
|
-
if (flags.updateOnly) {
|
|
254
|
-
return;
|
|
255
|
-
}
|
|
256
|
-
const runtimeStrategies = await loadRuntimeStrategies(flags.user);
|
|
257
|
-
if (!runtimeStrategies.length) {
|
|
258
|
-
import_logger.logger.warn(
|
|
259
|
-
"No strategy configs found by users:%s:strategies:*:config",
|
|
260
|
-
flags.user
|
|
304
|
+
import_logger.logger.info(
|
|
305
|
+
JSON.stringify(
|
|
306
|
+
signals2.map((s) => s.symbol),
|
|
307
|
+
null,
|
|
308
|
+
2
|
|
309
|
+
)
|
|
261
310
|
);
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
)
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
}
|
|
275
|
-
);
|
|
276
|
-
import_logger.logger.info(import_chalk.default.yellow(`tickers: ${tickers.length}`));
|
|
277
|
-
await (0, import_async.runWithConcurrency)(tickers, 5, async (symbol) => {
|
|
278
|
-
const signal = await findSignals(
|
|
279
|
-
symbol,
|
|
280
|
-
marketConnector,
|
|
281
|
-
btcBinanceData,
|
|
282
|
-
btcCoinbaseData,
|
|
283
|
-
runtimeStrategies
|
|
311
|
+
} catch (error) {
|
|
312
|
+
status = "failed";
|
|
313
|
+
import_logger.logger.error(
|
|
314
|
+
"signals failed: %s",
|
|
315
|
+
error?.message || String(error)
|
|
316
|
+
);
|
|
317
|
+
throw error;
|
|
318
|
+
} finally {
|
|
319
|
+
import_logger.logger.info(
|
|
320
|
+
import_chalk.default.yellow(
|
|
321
|
+
`signals ${status} in ${formatElapsed(startedAt)} (found=${signals2.length})`
|
|
322
|
+
)
|
|
284
323
|
);
|
|
285
|
-
if (signal) {
|
|
286
|
-
signals2.push(signal);
|
|
287
|
-
}
|
|
288
|
-
bar.tick(1, {
|
|
289
|
-
found: import_chalk.default.cyan(signals2.length),
|
|
290
|
-
symbol: import_chalk.default.gray(symbol)
|
|
291
|
-
});
|
|
292
|
-
});
|
|
293
|
-
if (!flags.skipScreenshots) {
|
|
294
|
-
await (0, import_cli.makeScreenshots)(signals2, "15");
|
|
295
|
-
await (0, import_cli.makeScreenshots)(signals2, "60");
|
|
296
|
-
}
|
|
297
|
-
if (flags.notify) {
|
|
298
|
-
await (0, import_cli.sendToTG)(signals2, "15");
|
|
299
324
|
}
|
|
300
|
-
import_logger.logger.info(
|
|
301
|
-
JSON.stringify(
|
|
302
|
-
signals2.map((s) => s.symbol),
|
|
303
|
-
null,
|
|
304
|
-
2
|
|
305
|
-
)
|
|
306
|
-
);
|
|
307
|
-
process.exit();
|
|
308
325
|
};
|
|
309
|
-
signals()
|
|
326
|
+
signals().then(() => {
|
|
327
|
+
process.exit(0);
|
|
328
|
+
}).catch(() => {
|
|
329
|
+
process.exit(1);
|
|
330
|
+
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tradejs/cli",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Official
|
|
3
|
+
"version": "1.0.5",
|
|
4
|
+
"description": "Official CLI for the TradeJS open-source framework: infra setup, backtests, signals, bots, and ML workflows.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tradejs",
|
|
7
7
|
"trading",
|
|
@@ -12,6 +12,14 @@
|
|
|
12
12
|
"automation"
|
|
13
13
|
],
|
|
14
14
|
"homepage": "https://tradejs.dev",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/tradejs-dev/tradejs.git",
|
|
18
|
+
"directory": "packages/cli"
|
|
19
|
+
},
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/tradejs-dev/tradejs/issues"
|
|
22
|
+
},
|
|
15
23
|
"main": "dist/cli.js",
|
|
16
24
|
"types": "dist/cli.d.ts",
|
|
17
25
|
"files": [
|
|
@@ -21,14 +29,14 @@
|
|
|
21
29
|
"tradejs": "dist/cli.js"
|
|
22
30
|
},
|
|
23
31
|
"dependencies": {
|
|
24
|
-
"@tradejs/base": "^1.0.
|
|
25
|
-
"@tradejs/connectors": "^1.0.
|
|
26
|
-
"@tradejs/core": "^1.0.
|
|
27
|
-
"@tradejs/indicators": "^1.0.
|
|
28
|
-
"@tradejs/infra": "^1.0.
|
|
29
|
-
"@tradejs/node": "^1.0.
|
|
30
|
-
"@tradejs/strategies": "^1.0.
|
|
31
|
-
"@tradejs/types": "^1.0.
|
|
32
|
+
"@tradejs/base": "^1.0.5",
|
|
33
|
+
"@tradejs/connectors": "^1.0.5",
|
|
34
|
+
"@tradejs/core": "^1.0.5",
|
|
35
|
+
"@tradejs/indicators": "^1.0.5",
|
|
36
|
+
"@tradejs/infra": "^1.0.5",
|
|
37
|
+
"@tradejs/node": "^1.0.5",
|
|
38
|
+
"@tradejs/strategies": "^1.0.5",
|
|
39
|
+
"@tradejs/types": "^1.0.5",
|
|
32
40
|
"args": "^5.0.3",
|
|
33
41
|
"bcryptjs": "^2.4.3",
|
|
34
42
|
"chalk": "4.1.2",
|