@tradejs/cli 1.0.2 → 1.0.4

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/cli.js CHANGED
@@ -1619,7 +1619,7 @@ var require_list_it = __commonJS({
1619
1619
 
1620
1620
  // src/scripts/backtest.ts
1621
1621
  var backtest_exports = {};
1622
- var import_args, import_progress, import_child_process, import_fs, import_path, import_os, import_chalk, import_lodash, import_date_fns, import_uuid, import_connectors, import_connectors2, import_cli, import_backtest, import_data, import_constants, import_redis, ListIt, MAX_PARALLEL, flags, interval, progressStep, uuid, testerWorkerPathCandidates, testerWorkerPath, testerNeedsTsRuntime, HEADERS_RESULTS, HEADERS_RESULTS_BY_TICKERS, successTests, errorTests, errorMessages, results, resultsByTickers, userName, runStartedAt, createListIt, createTable, createTimestamp, filterGoodTests, recordError, isStrategyConfigGrid, resolveBacktestConnectorName, getLogsById, setTestData, backtest, saveAndPrintResults, saveAndPrintResultsByTickers, finish;
1622
+ var import_args, import_progress, import_child_process, import_fs, import_path, import_os, import_chalk, import_lodash, import_date_fns, import_uuid, import_connectors, import_connectors2, import_cli, import_backtest, import_data, import_constants, import_redis, ListIt, MAX_PARALLEL, flags, interval, progressStep, uuid, projectRoot, testerWorkerPathCandidates, testerWorkerPath, testerNeedsTsRuntime, HEADERS_RESULTS, HEADERS_RESULTS_BY_TICKERS, successTests, errorTests, errorMessages, results, resultsByTickers, userName, runStartedAt, createListIt, createTable, createTimestamp, filterGoodTests, recordError, isStrategyConfigGrid, resolveBacktestConnectorName, getLogsById, setTestData, backtest, saveAndPrintResults, saveAndPrintResultsByTickers, finish;
1623
1623
  var init_backtest = __esm({
1624
1624
  "src/scripts/backtest.ts"() {
1625
1625
  "use strict";
@@ -1673,6 +1673,7 @@ var init_backtest = __esm({
1673
1673
  interval = flags.timeframe.toString();
1674
1674
  progressStep = flags.progressStep;
1675
1675
  uuid = (len = 12) => (0, import_uuid.v4)().slice(-len);
1676
+ projectRoot = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
1676
1677
  testerWorkerPathCandidates = [
1677
1678
  // `tradejs` bin runs from dist/cli.js, so bundled commands resolve from `dist`.
1678
1679
  import_path.default.resolve(__dirname, "./workers/testerWorker.js"),
@@ -1734,7 +1735,7 @@ var init_backtest = __esm({
1734
1735
  );
1735
1736
  };
1736
1737
  resolveBacktestConnectorName = async (value) => {
1737
- const connectorName = await (0, import_connectors2.resolveConnectorName)(value);
1738
+ const connectorName = await (0, import_connectors2.resolveConnectorName)(value, projectRoot);
1738
1739
  if (connectorName) {
1739
1740
  return connectorName;
1740
1741
  }
@@ -1799,7 +1800,10 @@ var init_backtest = __esm({
1799
1800
  );
1800
1801
  }
1801
1802
  const connectorName = await resolveBacktestConnectorName(flags.connector);
1802
- const connectorFactory = await (0, import_connectors2.getConnectorCreatorByName)(connectorName);
1803
+ const connectorFactory = await (0, import_connectors2.getConnectorCreatorByName)(
1804
+ connectorName,
1805
+ projectRoot
1806
+ );
1803
1807
  if (!connectorFactory) {
1804
1808
  throw new Error(`Connector "${connectorName}" is not registered`);
1805
1809
  }
@@ -1819,10 +1823,12 @@ var init_backtest = __esm({
1819
1823
  if (!flags.cacheOnly) {
1820
1824
  await (0, import_cli.update)(marketConnector, interval, tickers);
1821
1825
  const binanceConnectorCreator = await (0, import_connectors2.getConnectorCreatorByName)(
1822
- import_connectors.ConnectorNames.Binance
1826
+ import_connectors.ConnectorNames.Binance,
1827
+ projectRoot
1823
1828
  );
1824
1829
  const coinbaseConnectorCreator = await (0, import_connectors2.getConnectorCreatorByName)(
1825
- import_connectors.ConnectorNames.Coinbase
1830
+ import_connectors.ConnectorNames.Coinbase,
1831
+ projectRoot
1826
1832
  );
1827
1833
  if (!binanceConnectorCreator || !coinbaseConnectorCreator) {
1828
1834
  throw new Error("Binance/Coinbase connectors are required");
@@ -2063,7 +2069,7 @@ var init_backtest = __esm({
2063
2069
  });
2064
2070
 
2065
2071
  // src/lib/runBot.ts
2066
- var import_lodash2, import_connectors3, import_data2, import_strategies, import_async, import_constants2, import_time, import_logger, import_redis2, runBot;
2072
+ var import_lodash2, import_connectors3, import_data2, import_strategies, import_async, import_constants2, import_time, import_logger, import_redis2, projectRoot2, runBot;
2067
2073
  var init_runBot = __esm({
2068
2074
  "src/lib/runBot.ts"() {
2069
2075
  "use strict";
@@ -2076,6 +2082,7 @@ var init_runBot = __esm({
2076
2082
  import_time = require("@tradejs/core/time");
2077
2083
  import_logger = require("@tradejs/infra/logger");
2078
2084
  import_redis2 = require("@tradejs/infra/redis");
2085
+ projectRoot2 = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
2079
2086
  runBot = async () => {
2080
2087
  const botResults = [];
2081
2088
  const preloadStart = (0, import_time.getTimestamp)(import_constants2.BOT_PRELOAD_DAYS);
@@ -2101,11 +2108,17 @@ var init_runBot = __esm({
2101
2108
  continue;
2102
2109
  }
2103
2110
  try {
2104
- const strategyCreator = await (0, import_strategies.getStrategyCreator)(strategyName);
2111
+ const strategyCreator = await (0, import_strategies.getStrategyCreator)(
2112
+ strategyName,
2113
+ projectRoot2
2114
+ );
2105
2115
  if (!strategyCreator) {
2106
2116
  throw new Error(`Unknown strategy: ${strategyName}`);
2107
2117
  }
2108
- const connectorCreator = await (0, import_connectors3.getConnectorCreatorByName)(connectorName);
2118
+ const connectorCreator = await (0, import_connectors3.getConnectorCreatorByName)(
2119
+ connectorName,
2120
+ projectRoot2
2121
+ );
2109
2122
  if (!connectorCreator) {
2110
2123
  throw new Error(`Unknown connector: ${connectorName}`);
2111
2124
  }
@@ -2113,10 +2126,12 @@ var init_runBot = __esm({
2113
2126
  userName: userName2
2114
2127
  });
2115
2128
  const binanceConnectorCreator = await (0, import_connectors3.getConnectorCreatorByName)(
2116
- import_connectors3.BUILTIN_CONNECTOR_NAMES.Binance
2129
+ import_connectors3.BUILTIN_CONNECTOR_NAMES.Binance,
2130
+ projectRoot2
2117
2131
  );
2118
2132
  const coinbaseConnectorCreator = await (0, import_connectors3.getConnectorCreatorByName)(
2119
- import_connectors3.BUILTIN_CONNECTOR_NAMES.Coinbase
2133
+ import_connectors3.BUILTIN_CONNECTOR_NAMES.Coinbase,
2134
+ projectRoot2
2120
2135
  );
2121
2136
  if (!binanceConnectorCreator || !coinbaseConnectorCreator) {
2122
2137
  throw new Error("Binance/Coinbase connectors are required");
@@ -2319,7 +2334,7 @@ var init_cleanTests = __esm({
2319
2334
 
2320
2335
  // src/scripts/continuity.ts
2321
2336
  var continuity_exports = {};
2322
- var import_args5, import_progress2, import_chalk3, import_connectors4, import_cli5, import_constants3, import_time2, import_logger2, import_timescale, flags5, interval2, intervalKey, parseProviders, findGapInData, continuity;
2337
+ var import_args5, import_progress2, import_chalk3, import_connectors4, import_cli5, import_constants3, import_time2, import_logger2, import_timescale, flags5, interval2, intervalKey, projectRoot3, parseProviders, findGapInData, continuity;
2323
2338
  var init_continuity = __esm({
2324
2339
  "src/scripts/continuity.ts"() {
2325
2340
  "use strict";
@@ -2343,8 +2358,9 @@ var init_continuity = __esm({
2343
2358
  flags5 = import_args5.default.parse(process.argv);
2344
2359
  interval2 = Number(flags5.timeframe);
2345
2360
  intervalKey = flags5.timeframe.toString();
2361
+ projectRoot3 = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
2346
2362
  parseProviders = async (value) => {
2347
- const allProviders = await (0, import_connectors4.getAvailableConnectorProviders)();
2363
+ const allProviders = await (0, import_connectors4.getAvailableConnectorProviders)(projectRoot3);
2348
2364
  const raw = String(value || "").trim().toLowerCase();
2349
2365
  if (!raw || raw === "all") {
2350
2366
  return allProviders;
@@ -2388,7 +2404,10 @@ var init_continuity = __esm({
2388
2404
  const providerIds = await parseProviders(flags5.provider);
2389
2405
  const providers = await Promise.all(
2390
2406
  providerIds.map(async (providerId) => {
2391
- const connectorName = await (0, import_connectors4.getConnectorNameByProvider)(providerId);
2407
+ const connectorName = await (0, import_connectors4.getConnectorNameByProvider)(
2408
+ providerId,
2409
+ projectRoot3
2410
+ );
2392
2411
  if (!connectorName) {
2393
2412
  import_logger2.logger.warn(
2394
2413
  'Skip provider "%s": connector mapping is missing',
@@ -2396,7 +2415,10 @@ var init_continuity = __esm({
2396
2415
  );
2397
2416
  return null;
2398
2417
  }
2399
- const creator = await (0, import_connectors4.getConnectorCreatorByName)(connectorName);
2418
+ const creator = await (0, import_connectors4.getConnectorCreatorByName)(
2419
+ connectorName,
2420
+ projectRoot3
2421
+ );
2400
2422
  if (!creator) {
2401
2423
  import_logger2.logger.warn(
2402
2424
  'Skip provider "%s": connector "%s" is not registered',
@@ -8240,7 +8262,7 @@ var init_infraUp = __esm({
8240
8262
 
8241
8263
  // src/scripts/migration.ts
8242
8264
  var migration_exports = {};
8243
- var import_progress4, import_chalk11, import_logger3, import_files, import_timescale4, DIR, re, BATCH, migrateFile, migration;
8265
+ var import_progress4, import_chalk11, import_logger3, import_files, import_timescale4, DIR, re, BATCH, projectRoot4, migrateFile, migration;
8244
8266
  var init_migration = __esm({
8245
8267
  "src/scripts/migration.ts"() {
8246
8268
  "use strict";
@@ -8252,19 +8274,25 @@ var init_migration = __esm({
8252
8274
  DIR = "data/history";
8253
8275
  re = /^(.+?)_(\d+)\.json$/;
8254
8276
  BATCH = 2e3;
8277
+ projectRoot4 = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
8255
8278
  migrateFile = async (file) => {
8256
8279
  const m = re.exec(file);
8257
8280
  if (!m) return;
8258
8281
  const symbol = m[1];
8259
8282
  const interval4 = Number(m[2]);
8260
- const data = await (0, import_files.getFile)(DIR, `${symbol}_${interval4}`);
8283
+ const data = await (0, import_files.getFile)(
8284
+ DIR,
8285
+ `${symbol}_${interval4}`,
8286
+ [],
8287
+ projectRoot4
8288
+ );
8261
8289
  const rows = (0, import_timescale4.toRows)(symbol, interval4, data);
8262
8290
  for (let i = 0; i < rows.length; i += BATCH) {
8263
8291
  await (0, import_timescale4.upsertCandles)(rows.slice(i, i + BATCH));
8264
8292
  }
8265
8293
  };
8266
8294
  migration = async () => {
8267
- const files = await (0, import_files.getFiles)(DIR);
8295
+ const files = await (0, import_files.getFiles)(DIR, projectRoot4);
8268
8296
  const bar = new import_progress4.default(
8269
8297
  ":current/:total [:bar][:percent] :eta(s) :file",
8270
8298
  {
@@ -8290,7 +8318,7 @@ var init_migration = __esm({
8290
8318
  });
8291
8319
 
8292
8320
  // src/scripts/selectStrategy.ts
8293
- var import_readline, import_chalk12, import_strategies2, defaultStrategy, getStrategyChoices, selectStrategy;
8321
+ var import_readline, import_chalk12, import_strategies2, defaultStrategy, projectRoot5, getStrategyChoices, selectStrategy;
8294
8322
  var init_selectStrategy = __esm({
8295
8323
  "src/scripts/selectStrategy.ts"() {
8296
8324
  "use strict";
@@ -8298,9 +8326,10 @@ var init_selectStrategy = __esm({
8298
8326
  import_chalk12 = __toESM(require("chalk"));
8299
8327
  import_strategies2 = require("@tradejs/node/strategies");
8300
8328
  defaultStrategy = "TrendLine";
8329
+ projectRoot5 = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
8301
8330
  getStrategyChoices = async () => {
8302
8331
  try {
8303
- const loaded = await (0, import_strategies2.getAvailableStrategyNames)();
8332
+ const loaded = await (0, import_strategies2.getAvailableStrategyNames)(projectRoot5);
8304
8333
  if (loaded.length) {
8305
8334
  return loaded;
8306
8335
  }
@@ -10189,7 +10218,7 @@ var init_results = __esm({
10189
10218
 
10190
10219
  // src/scripts/signals.ts
10191
10220
  var signals_exports = {};
10192
- 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, 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, resolveStrategyNameByConfigKey, loadRuntimeStrategies, resolveSignalsConnectorName, findSignals, signals;
10193
10222
  var init_signals = __esm({
10194
10223
  "src/scripts/signals.ts"() {
10195
10224
  "use strict";
@@ -10224,6 +10253,7 @@ var init_signals = __esm({
10224
10253
  "bybit"
10225
10254
  );
10226
10255
  PRELOAD_START = (0, import_time3.getTimestamp)(import_constants4.SIGNALS_PRELOAD_DAYS);
10256
+ projectRoot6 = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
10227
10257
  flags12 = import_args12.default.parse(process.argv);
10228
10258
  minTouches = parseInt(flags12.points);
10229
10259
  offset = parseInt(flags12.offset);
@@ -10248,7 +10278,10 @@ var init_signals = __esm({
10248
10278
  if (!strategyName) {
10249
10279
  return null;
10250
10280
  }
10251
- const strategyCreator = await (0, import_strategies3.getStrategyCreator)(strategyName);
10281
+ const strategyCreator = await (0, import_strategies3.getStrategyCreator)(
10282
+ strategyName,
10283
+ projectRoot6
10284
+ );
10252
10285
  if (!strategyCreator) {
10253
10286
  import_logger4.logger.warn("Skip unknown strategy config key: %s", key);
10254
10287
  return null;
@@ -10264,7 +10297,7 @@ var init_signals = __esm({
10264
10297
  return strategyConfigs.filter(Boolean);
10265
10298
  };
10266
10299
  resolveSignalsConnectorName = async (value) => {
10267
- const connectorName = await (0, import_connectors9.resolveConnectorName)(value);
10300
+ const connectorName = await (0, import_connectors9.resolveConnectorName)(value, projectRoot6);
10268
10301
  if (connectorName) {
10269
10302
  return connectorName;
10270
10303
  }
@@ -10337,7 +10370,10 @@ var init_signals = __esm({
10337
10370
  signals = async () => {
10338
10371
  const signals2 = new Array();
10339
10372
  const connectorName = await resolveSignalsConnectorName(flags12.connector);
10340
- const connectorFactory = await (0, import_connectors9.getConnectorCreatorByName)(connectorName);
10373
+ const connectorFactory = await (0, import_connectors9.getConnectorCreatorByName)(
10374
+ connectorName,
10375
+ projectRoot6
10376
+ );
10341
10377
  if (!connectorFactory) {
10342
10378
  throw new Error(`Connector "${connectorName}" is not registered`);
10343
10379
  }
@@ -10348,7 +10384,8 @@ var init_signals = __esm({
10348
10384
  let btcCoinbaseConnector = marketConnector;
10349
10385
  if (connectorName.toLowerCase() === import_connectors9.DEFAULT_CONNECTOR_NAME.toLowerCase()) {
10350
10386
  const binanceFactory = await (0, import_connectors9.getConnectorCreatorByName)(
10351
- import_connectors8.ConnectorNames.Binance
10387
+ import_connectors8.ConnectorNames.Binance,
10388
+ projectRoot6
10352
10389
  );
10353
10390
  if (binanceFactory) {
10354
10391
  btcBinanceConnector = await binanceFactory({
@@ -10361,7 +10398,8 @@ var init_signals = __esm({
10361
10398
  );
10362
10399
  }
10363
10400
  const coinbaseFactory = await (0, import_connectors9.getConnectorCreatorByName)(
10364
- import_connectors8.ConnectorNames.Coinbase
10401
+ import_connectors8.ConnectorNames.Coinbase,
10402
+ projectRoot6
10365
10403
  );
10366
10404
  if (coinbaseFactory) {
10367
10405
  btcCoinbaseConnector = await coinbaseFactory({
@@ -10595,7 +10633,8 @@ var init_test_ml = __esm({
10595
10633
  const mlResult = await (0, import_ml2.fetchMlThreshold)({
10596
10634
  strategy: "TrendLine",
10597
10635
  features,
10598
- threshold: ML_THRESHOLD
10636
+ threshold: ML_THRESHOLD,
10637
+ projectRoot: process.cwd()
10599
10638
  });
10600
10639
  if (!mlResult) {
10601
10640
  console.log("ML result is null (check ml-infer or ML_GRPC_ADDRESS).");
@@ -42,6 +42,7 @@ var import_constants = require("@tradejs/core/constants");
42
42
  var import_time = require("@tradejs/core/time");
43
43
  var import_logger = require("@tradejs/infra/logger");
44
44
  var import_redis = require("@tradejs/infra/redis");
45
+ var projectRoot = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
45
46
  var runBot = async () => {
46
47
  const botResults = [];
47
48
  const preloadStart = (0, import_time.getTimestamp)(import_constants.BOT_PRELOAD_DAYS);
@@ -67,11 +68,17 @@ var runBot = async () => {
67
68
  continue;
68
69
  }
69
70
  try {
70
- const strategyCreator = await (0, import_strategies.getStrategyCreator)(strategyName);
71
+ const strategyCreator = await (0, import_strategies.getStrategyCreator)(
72
+ strategyName,
73
+ projectRoot
74
+ );
71
75
  if (!strategyCreator) {
72
76
  throw new Error(`Unknown strategy: ${strategyName}`);
73
77
  }
74
- const connectorCreator = await (0, import_connectors.getConnectorCreatorByName)(connectorName);
78
+ const connectorCreator = await (0, import_connectors.getConnectorCreatorByName)(
79
+ connectorName,
80
+ projectRoot
81
+ );
75
82
  if (!connectorCreator) {
76
83
  throw new Error(`Unknown connector: ${connectorName}`);
77
84
  }
@@ -79,10 +86,12 @@ var runBot = async () => {
79
86
  userName
80
87
  });
81
88
  const binanceConnectorCreator = await (0, import_connectors.getConnectorCreatorByName)(
82
- import_connectors.BUILTIN_CONNECTOR_NAMES.Binance
89
+ import_connectors.BUILTIN_CONNECTOR_NAMES.Binance,
90
+ projectRoot
83
91
  );
84
92
  const coinbaseConnectorCreator = await (0, import_connectors.getConnectorCreatorByName)(
85
- import_connectors.BUILTIN_CONNECTOR_NAMES.Coinbase
93
+ import_connectors.BUILTIN_CONNECTOR_NAMES.Coinbase,
94
+ projectRoot
86
95
  );
87
96
  if (!binanceConnectorCreator || !coinbaseConnectorCreator) {
88
97
  throw new Error("Binance/Coinbase connectors are required");
@@ -1660,6 +1660,7 @@ var flags = import_args.default.parse(process.argv);
1660
1660
  var interval = flags.timeframe.toString();
1661
1661
  var progressStep = flags.progressStep;
1662
1662
  var uuid = (len = 12) => (0, import_uuid.v4)().slice(-len);
1663
+ var projectRoot = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
1663
1664
  var testerWorkerPathCandidates = [
1664
1665
  // `tradejs` bin runs from dist/cli.js, so bundled commands resolve from `dist`.
1665
1666
  import_path.default.resolve(__dirname, "./workers/testerWorker.js"),
@@ -1721,7 +1722,7 @@ var isStrategyConfigGrid = (value) => {
1721
1722
  );
1722
1723
  };
1723
1724
  var resolveBacktestConnectorName = async (value) => {
1724
- const connectorName = await (0, import_connectors2.resolveConnectorName)(value);
1725
+ const connectorName = await (0, import_connectors2.resolveConnectorName)(value, projectRoot);
1725
1726
  if (connectorName) {
1726
1727
  return connectorName;
1727
1728
  }
@@ -1786,7 +1787,10 @@ var backtest = async () => {
1786
1787
  );
1787
1788
  }
1788
1789
  const connectorName = await resolveBacktestConnectorName(flags.connector);
1789
- const connectorFactory = await (0, import_connectors2.getConnectorCreatorByName)(connectorName);
1790
+ const connectorFactory = await (0, import_connectors2.getConnectorCreatorByName)(
1791
+ connectorName,
1792
+ projectRoot
1793
+ );
1790
1794
  if (!connectorFactory) {
1791
1795
  throw new Error(`Connector "${connectorName}" is not registered`);
1792
1796
  }
@@ -1806,10 +1810,12 @@ var backtest = async () => {
1806
1810
  if (!flags.cacheOnly) {
1807
1811
  await (0, import_cli.update)(marketConnector, interval, tickers);
1808
1812
  const binanceConnectorCreator = await (0, import_connectors2.getConnectorCreatorByName)(
1809
- import_connectors.ConnectorNames.Binance
1813
+ import_connectors.ConnectorNames.Binance,
1814
+ projectRoot
1810
1815
  );
1811
1816
  const coinbaseConnectorCreator = await (0, import_connectors2.getConnectorCreatorByName)(
1812
- import_connectors.ConnectorNames.Coinbase
1817
+ import_connectors.ConnectorNames.Coinbase,
1818
+ projectRoot
1813
1819
  );
1814
1820
  if (!binanceConnectorCreator || !coinbaseConnectorCreator) {
1815
1821
  throw new Error("Binance/Coinbase connectors are required");
@@ -35,6 +35,7 @@ var import_constants = require("@tradejs/core/constants");
35
35
  var import_time = require("@tradejs/core/time");
36
36
  var import_logger = require("@tradejs/infra/logger");
37
37
  var import_redis = require("@tradejs/infra/redis");
38
+ var projectRoot = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
38
39
  var runBot = async () => {
39
40
  const botResults = [];
40
41
  const preloadStart = (0, import_time.getTimestamp)(import_constants.BOT_PRELOAD_DAYS);
@@ -60,11 +61,17 @@ var runBot = async () => {
60
61
  continue;
61
62
  }
62
63
  try {
63
- const strategyCreator = await (0, import_strategies.getStrategyCreator)(strategyName);
64
+ const strategyCreator = await (0, import_strategies.getStrategyCreator)(
65
+ strategyName,
66
+ projectRoot
67
+ );
64
68
  if (!strategyCreator) {
65
69
  throw new Error(`Unknown strategy: ${strategyName}`);
66
70
  }
67
- const connectorCreator = await (0, import_connectors.getConnectorCreatorByName)(connectorName);
71
+ const connectorCreator = await (0, import_connectors.getConnectorCreatorByName)(
72
+ connectorName,
73
+ projectRoot
74
+ );
68
75
  if (!connectorCreator) {
69
76
  throw new Error(`Unknown connector: ${connectorName}`);
70
77
  }
@@ -72,10 +79,12 @@ var runBot = async () => {
72
79
  userName
73
80
  });
74
81
  const binanceConnectorCreator = await (0, import_connectors.getConnectorCreatorByName)(
75
- import_connectors.BUILTIN_CONNECTOR_NAMES.Binance
82
+ import_connectors.BUILTIN_CONNECTOR_NAMES.Binance,
83
+ projectRoot
76
84
  );
77
85
  const coinbaseConnectorCreator = await (0, import_connectors.getConnectorCreatorByName)(
78
- import_connectors.BUILTIN_CONNECTOR_NAMES.Coinbase
86
+ import_connectors.BUILTIN_CONNECTOR_NAMES.Coinbase,
87
+ projectRoot
79
88
  );
80
89
  if (!binanceConnectorCreator || !coinbaseConnectorCreator) {
81
90
  throw new Error("Binance/Coinbase connectors are required");
@@ -43,8 +43,9 @@ import_args.default.option(["U", "user"], "Use user confg", "root");
43
43
  var flags = import_args.default.parse(process.argv);
44
44
  var interval = Number(flags.timeframe);
45
45
  var intervalKey = flags.timeframe.toString();
46
+ var projectRoot = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
46
47
  var parseProviders = async (value) => {
47
- const allProviders = await (0, import_connectors.getAvailableConnectorProviders)();
48
+ const allProviders = await (0, import_connectors.getAvailableConnectorProviders)(projectRoot);
48
49
  const raw = String(value || "").trim().toLowerCase();
49
50
  if (!raw || raw === "all") {
50
51
  return allProviders;
@@ -88,7 +89,10 @@ var continuity = async () => {
88
89
  const providerIds = await parseProviders(flags.provider);
89
90
  const providers = await Promise.all(
90
91
  providerIds.map(async (providerId) => {
91
- const connectorName = await (0, import_connectors.getConnectorNameByProvider)(providerId);
92
+ const connectorName = await (0, import_connectors.getConnectorNameByProvider)(
93
+ providerId,
94
+ projectRoot
95
+ );
92
96
  if (!connectorName) {
93
97
  import_logger.logger.warn(
94
98
  'Skip provider "%s": connector mapping is missing',
@@ -96,7 +100,10 @@ var continuity = async () => {
96
100
  );
97
101
  return null;
98
102
  }
99
- const creator = await (0, import_connectors.getConnectorCreatorByName)(connectorName);
103
+ const creator = await (0, import_connectors.getConnectorCreatorByName)(
104
+ connectorName,
105
+ projectRoot
106
+ );
100
107
  if (!creator) {
101
108
  import_logger.logger.warn(
102
109
  'Skip provider "%s": connector "%s" is not registered',
@@ -31,19 +31,25 @@ var import_timescale = require("@tradejs/infra/timescale");
31
31
  var DIR = "data/history";
32
32
  var re = /^(.+?)_(\d+)\.json$/;
33
33
  var BATCH = 2e3;
34
+ var projectRoot = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
34
35
  var migrateFile = async (file) => {
35
36
  const m = re.exec(file);
36
37
  if (!m) return;
37
38
  const symbol = m[1];
38
39
  const interval = Number(m[2]);
39
- const data = await (0, import_files.getFile)(DIR, `${symbol}_${interval}`);
40
+ const data = await (0, import_files.getFile)(
41
+ DIR,
42
+ `${symbol}_${interval}`,
43
+ [],
44
+ projectRoot
45
+ );
40
46
  const rows = (0, import_timescale.toRows)(symbol, interval, data);
41
47
  for (let i = 0; i < rows.length; i += BATCH) {
42
48
  await (0, import_timescale.upsertCandles)(rows.slice(i, i + BATCH));
43
49
  }
44
50
  };
45
51
  var migration = async () => {
46
- const files = await (0, import_files.getFiles)(DIR);
52
+ const files = await (0, import_files.getFiles)(DIR, projectRoot);
47
53
  const bar = new import_progress.default(
48
54
  ":current/:total [:bar][:percent] :eta(s) :file",
49
55
  {
@@ -30,9 +30,10 @@ var import_readline = __toESM(require("readline"));
30
30
  var import_chalk = __toESM(require("chalk"));
31
31
  var import_strategies = require("@tradejs/node/strategies");
32
32
  var defaultStrategy = "TrendLine";
33
+ var projectRoot = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
33
34
  var getStrategyChoices = async () => {
34
35
  try {
35
- const loaded = await (0, import_strategies.getAvailableStrategyNames)();
36
+ const loaded = await (0, import_strategies.getAvailableStrategyNames)(projectRoot);
36
37
  if (loaded.length) {
37
38
  return loaded;
38
39
  }
@@ -38,9 +38,10 @@ var import_readline = __toESM(require("readline"));
38
38
  var import_chalk = __toESM(require("chalk"));
39
39
  var import_strategies = require("@tradejs/node/strategies");
40
40
  var defaultStrategy = "TrendLine";
41
+ var projectRoot = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
41
42
  var getStrategyChoices = async () => {
42
43
  try {
43
- const loaded = await (0, import_strategies.getAvailableStrategyNames)();
44
+ const loaded = await (0, import_strategies.getAvailableStrategyNames)(projectRoot);
44
45
  if (loaded.length) {
45
46
  return loaded;
46
47
  }
@@ -37,9 +37,10 @@ var import_readline = __toESM(require("readline"));
37
37
  var import_chalk = __toESM(require("chalk"));
38
38
  var import_strategies = require("@tradejs/node/strategies");
39
39
  var defaultStrategy = "TrendLine";
40
+ var projectRoot = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
40
41
  var getStrategyChoices = async () => {
41
42
  try {
42
- const loaded = await (0, import_strategies.getAvailableStrategyNames)();
43
+ const loaded = await (0, import_strategies.getAvailableStrategyNames)(projectRoot);
43
44
  if (loaded.length) {
44
45
  return loaded;
45
46
  }
@@ -54,6 +54,7 @@ import_args.default.option(
54
54
  "bybit"
55
55
  );
56
56
  var PRELOAD_START = (0, import_time.getTimestamp)(import_constants.SIGNALS_PRELOAD_DAYS);
57
+ var projectRoot = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
57
58
  var flags = import_args.default.parse(process.argv);
58
59
  var minTouches = parseInt(flags.points);
59
60
  var offset = parseInt(flags.offset);
@@ -78,7 +79,10 @@ var loadRuntimeStrategies = async (userName) => {
78
79
  if (!strategyName) {
79
80
  return null;
80
81
  }
81
- const strategyCreator = await (0, import_strategies.getStrategyCreator)(strategyName);
82
+ const strategyCreator = await (0, import_strategies.getStrategyCreator)(
83
+ strategyName,
84
+ projectRoot
85
+ );
82
86
  if (!strategyCreator) {
83
87
  import_logger.logger.warn("Skip unknown strategy config key: %s", key);
84
88
  return null;
@@ -94,7 +98,7 @@ var loadRuntimeStrategies = async (userName) => {
94
98
  return strategyConfigs.filter(Boolean);
95
99
  };
96
100
  var resolveSignalsConnectorName = async (value) => {
97
- const connectorName = await (0, import_connectors2.resolveConnectorName)(value);
101
+ const connectorName = await (0, import_connectors2.resolveConnectorName)(value, projectRoot);
98
102
  if (connectorName) {
99
103
  return connectorName;
100
104
  }
@@ -167,7 +171,10 @@ var findSignals = async (symbol, connector, btcBinanceData, btcCoinbaseData, run
167
171
  var signals = async () => {
168
172
  const signals2 = new Array();
169
173
  const connectorName = await resolveSignalsConnectorName(flags.connector);
170
- const connectorFactory = await (0, import_connectors2.getConnectorCreatorByName)(connectorName);
174
+ const connectorFactory = await (0, import_connectors2.getConnectorCreatorByName)(
175
+ connectorName,
176
+ projectRoot
177
+ );
171
178
  if (!connectorFactory) {
172
179
  throw new Error(`Connector "${connectorName}" is not registered`);
173
180
  }
@@ -178,7 +185,8 @@ var signals = async () => {
178
185
  let btcCoinbaseConnector = marketConnector;
179
186
  if (connectorName.toLowerCase() === import_connectors2.DEFAULT_CONNECTOR_NAME.toLowerCase()) {
180
187
  const binanceFactory = await (0, import_connectors2.getConnectorCreatorByName)(
181
- import_connectors.ConnectorNames.Binance
188
+ import_connectors.ConnectorNames.Binance,
189
+ projectRoot
182
190
  );
183
191
  if (binanceFactory) {
184
192
  btcBinanceConnector = await binanceFactory({
@@ -191,7 +199,8 @@ var signals = async () => {
191
199
  );
192
200
  }
193
201
  const coinbaseFactory = await (0, import_connectors2.getConnectorCreatorByName)(
194
- import_connectors.ConnectorNames.Coinbase
202
+ import_connectors.ConnectorNames.Coinbase,
203
+ projectRoot
195
204
  );
196
205
  if (coinbaseFactory) {
197
206
  btcCoinbaseConnector = await coinbaseFactory({
@@ -119,7 +119,8 @@ var main = async () => {
119
119
  const mlResult = await (0, import_ml.fetchMlThreshold)({
120
120
  strategy: "TrendLine",
121
121
  features,
122
- threshold: ML_THRESHOLD
122
+ threshold: ML_THRESHOLD,
123
+ projectRoot: process.cwd()
123
124
  });
124
125
  if (!mlResult) {
125
126
  console.log("ML result is null (check ml-infer or ML_GRPC_ADDRESS).");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tradejs/cli",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Official TradeJS CLI for infra setup, backtests, signals, bots, and ML workflows.",
5
5
  "keywords": [
6
6
  "tradejs",
@@ -21,14 +21,14 @@
21
21
  "tradejs": "dist/cli.js"
22
22
  },
23
23
  "dependencies": {
24
- "@tradejs/base": "^1.0.2",
25
- "@tradejs/connectors": "^1.0.2",
26
- "@tradejs/core": "^1.0.2",
27
- "@tradejs/indicators": "^1.0.2",
28
- "@tradejs/infra": "^1.0.2",
29
- "@tradejs/node": "^1.0.2",
30
- "@tradejs/strategies": "^1.0.2",
31
- "@tradejs/types": "^1.0.2",
24
+ "@tradejs/base": "^1.0.4",
25
+ "@tradejs/connectors": "^1.0.4",
26
+ "@tradejs/core": "^1.0.4",
27
+ "@tradejs/indicators": "^1.0.4",
28
+ "@tradejs/infra": "^1.0.4",
29
+ "@tradejs/node": "^1.0.4",
30
+ "@tradejs/strategies": "^1.0.4",
31
+ "@tradejs/types": "^1.0.4",
32
32
  "args": "^5.0.3",
33
33
  "bcryptjs": "^2.4.3",
34
34
  "chalk": "4.1.2",
@@ -49,35 +49,36 @@
49
49
  "scripts": {
50
50
  "build": "tsup",
51
51
  "typecheck": "tsc -p ./tsconfig.json --noEmit",
52
- "run:ts": "dotenv -e \"${DOTENV_CONFIG_PATH:-${PROJECT_CWD:-$PWD}/.env}\" -- ts-node -r tsconfig-paths/register",
53
- "clean-dir": "yarn run run:ts ./src/scripts/cleanDir",
54
- "clean-redis": "yarn run run:ts ./src/scripts/cleanRedis",
55
- "clean-tests": "yarn run run:ts ./src/scripts/cleanTests",
56
- "doctor": "yarn run run:ts ./src/scripts/doctor",
57
- "backtest": "yarn run run:ts ./src/scripts/backtest",
58
- "bot": "yarn run run:ts ./src/scripts/bot",
59
- "signals": "yarn run run:ts ./src/scripts/signals",
60
- "results": "yarn run run:ts ./src/scripts/results",
61
- "continuity": "yarn run run:ts ./src/scripts/continuity",
62
- "derivatives:ingest": "yarn run run:ts ./src/scripts/derivativesIngest",
63
- "derivatives:ingest:coinalyze:all": "yarn run run:ts ./src/scripts/derivativesIngestCoinalyzeAll",
64
- "infra-init": "yarn run run:ts ./src/scripts/infraInit",
65
- "infra-up": "yarn run run:ts ./src/scripts/infraUp",
66
- "infra-down": "yarn run run:ts ./src/scripts/infraDown",
67
- "spread:ingest": "yarn run run:ts ./src/scripts/derivativesIngest --provider binance_coinbase_spread",
68
- "migration": "yarn run run:ts ./src/scripts/migration",
69
- "ml-export": "yarn run run:ts ./src/scripts/mlExportSelect",
70
- "ml-inspect": "yarn run run:ts ./src/scripts/mlInspect",
71
- "ml-train:latest": "yarn run run:ts ./src/scripts/mlTrainLatestSelect",
72
- "ml-train:trendline:catboost": "yarn run run:ts ./src/scripts/mlTrainLatestSelect --model catboost --latestOnly",
73
- "ml-train:trendline:extra-trees": "yarn run run:ts ./src/scripts/mlTrainLatestSelect --model extra_trees --latestOnly",
74
- "ml-train:trendline:lightgbm": "yarn run run:ts ./src/scripts/mlTrainLatestSelect --model lightgbm --latestOnly",
75
- "ml-train:trendline:rf": "yarn run run:ts ./src/scripts/mlTrainLatestSelect --model random_forest --latestOnly",
76
- "ml-train:trendline:xgboost": "yarn run run:ts ./src/scripts/mlTrainLatestSelect --model xgboost --latestOnly",
77
- "ml-train:unified:catboost": "yarn run run:ts ./src/scripts/mlTrainLatestSelect --strategy any --model catboost --latestOnly",
78
- "test-script": "yarn run run:ts ./src/scripts/test",
79
- "test-ml": "yarn run run:ts ./src/scripts/test-ml",
80
- "user-add": "yarn run run:ts ./src/scripts/user-add"
52
+ "run:src": "dotenv -e \"${DOTENV_CONFIG_PATH:-${PROJECT_CWD:-$PWD}/.env}\" -- ts-node -r tsconfig-paths/register",
53
+ "run:dist": "dotenv -e \"${DOTENV_CONFIG_PATH:-${PROJECT_CWD:-$PWD}/.env}\" -- node ./dist/cli.js",
54
+ "clean-dir": "yarn run run:dist clean-dir",
55
+ "clean-redis": "yarn run run:dist clean-redis",
56
+ "clean-tests": "yarn run run:dist clean-tests",
57
+ "doctor": "yarn run run:dist doctor",
58
+ "backtest": "yarn run run:dist backtest",
59
+ "bot": "yarn run run:dist bot",
60
+ "signals": "yarn run run:dist signals",
61
+ "results": "yarn run run:dist results",
62
+ "continuity": "yarn run run:dist continuity",
63
+ "derivatives:ingest": "yarn run run:dist derivatives:ingest",
64
+ "derivatives:ingest:coinalyze:all": "yarn run run:dist derivatives:ingest:coinalyze:all",
65
+ "infra-init": "yarn run run:dist infra-init",
66
+ "infra-up": "yarn run run:dist infra-up",
67
+ "infra-down": "yarn run run:dist infra-down",
68
+ "spread:ingest": "yarn run run:dist spread:ingest",
69
+ "migration": "yarn run run:dist migration",
70
+ "ml-export": "yarn run run:dist ml-export",
71
+ "ml-inspect": "yarn run run:dist ml-inspect",
72
+ "ml-train:latest": "yarn run run:dist ml-train:latest",
73
+ "ml-train:trendline:catboost": "yarn run run:dist ml-train:trendline:catboost",
74
+ "ml-train:trendline:extra-trees": "yarn run run:dist ml-train:trendline:extra-trees",
75
+ "ml-train:trendline:lightgbm": "yarn run run:dist ml-train:trendline:lightgbm",
76
+ "ml-train:trendline:rf": "yarn run run:dist ml-train:trendline:rf",
77
+ "ml-train:trendline:xgboost": "yarn run run:dist ml-train:trendline:xgboost",
78
+ "ml-train:unified:catboost": "yarn run run:dist ml-train:unified:catboost",
79
+ "test-script": "yarn run run:dist test-script",
80
+ "test-ml": "yarn run run:dist test-ml",
81
+ "user-add": "yarn run run:dist user-add"
81
82
  },
82
83
  "license": "MIT",
83
84
  "author": "aleksnick (https://github.com/aleksnick)"