@backtest-kit/cli 0.0.1 → 0.0.2

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/build/index.cjs CHANGED
@@ -134,14 +134,14 @@ class ErrorService {
134
134
  this.handleGlobalError(err);
135
135
  });
136
136
  };
137
- this.init = () => {
137
+ this.init = functoolsKit.singleshot(() => {
138
138
  const global = globalThis;
139
139
  if (global[ERROR_HANDLER_INSTALLED]) {
140
140
  return;
141
141
  }
142
142
  this._listenForError();
143
143
  global[ERROR_HANDLER_INSTALLED] = 1;
144
- };
144
+ });
145
145
  }
146
146
  }
147
147
 
@@ -336,8 +336,8 @@ const ADD_EXCHANGE_FN = (self) => {
336
336
  class ExchangeSchemaService {
337
337
  constructor() {
338
338
  this.loggerService = inject(TYPES.loggerService);
339
- this.init = functoolsKit.singleshot(async () => {
340
- this.loggerService.log("exchangeSchemaService init");
339
+ this.addSchema = functoolsKit.singleshot(async () => {
340
+ this.loggerService.log("exchangeSchemaService addSchema");
341
341
  const { length } = await backtestKit.listExchangeSchema();
342
342
  !length && ADD_EXCHANGE_FN(this);
343
343
  });
@@ -421,8 +421,8 @@ const ADD_FRAME_FN = (self) => {
421
421
  class FrameSchemaService {
422
422
  constructor() {
423
423
  this.loggerService = inject(TYPES.loggerService);
424
- this.init = functoolsKit.singleshot(async () => {
425
- this.loggerService.log("frameSchemaService init");
424
+ this.addSchema = functoolsKit.singleshot(async () => {
425
+ this.loggerService.log("frameSchemaService addSchema");
426
426
  if (!getArgs().values.backtest) {
427
427
  return;
428
428
  }
@@ -435,8 +435,8 @@ class FrameSchemaService {
435
435
  class SymbolSchemaService {
436
436
  constructor() {
437
437
  this.loggerService = inject(TYPES.loggerService);
438
- this.init = functoolsKit.singleshot(async () => {
439
- this.loggerService.log("symbolSchemaService init");
438
+ this.addSchema = functoolsKit.singleshot(async () => {
439
+ this.loggerService.log("symbolSchemaService addSchema");
440
440
  if (!getArgs().values.symbol) {
441
441
  console.warn("Warning: The default symbol is set to BTCUSDT. Please make sure to update it according to your needs using --symbol cli param.");
442
442
  }
@@ -457,56 +457,69 @@ const notifyFinish = functoolsKit.singleshot(() => {
457
457
  disposeRef = functoolsKit.compose(() => unLive(), () => unBacktest());
458
458
  });
459
459
 
460
+ const getEntry = (metaUrl) => {
461
+ return process.argv[1] === new URL(metaUrl).pathname;
462
+ };
463
+
464
+ const DEFAULT_CACHE_LIST = ["1m", "15m", "30m", "1h", "4h"];
465
+ const GET_CACHE_LIST_FN = () => {
466
+ const { values } = getArgs();
467
+ if (!values.cache) {
468
+ console.warn(`Warning: No cache timeframes provided. Using default timeframes: ${DEFAULT_CACHE_LIST.join(", ")}`);
469
+ return DEFAULT_CACHE_LIST;
470
+ }
471
+ return String(values.cache)
472
+ .split(",")
473
+ .map((timeframe) => timeframe.trim());
474
+ };
460
475
  class BacktestMainService {
461
476
  constructor() {
462
477
  this.loggerService = inject(TYPES.loggerService);
478
+ this.resolveService = inject(TYPES.resolveService);
463
479
  this.exchangeSchemaService = inject(TYPES.exchangeSchemaService);
464
480
  this.frameSchemaService = inject(TYPES.frameSchemaService);
481
+ this.symbolSchemaService = inject(TYPES.symbolSchemaService);
465
482
  this.cacheLogicService = inject(TYPES.cacheLogicService);
466
- this.resolveService = inject(TYPES.resolveService);
467
483
  this.frontendProviderService = inject(TYPES.frontendProviderService);
468
484
  this.telegramProviderService = inject(TYPES.telegramProviderService);
469
- this.init = functoolsKit.singleshot(async () => {
470
- this.loggerService.log("backtestMainService init");
485
+ this.run = functoolsKit.singleshot(async (payload) => {
486
+ this.loggerService.log("backtestMainService run", {
487
+ payload,
488
+ });
471
489
  {
472
- this.frontendProviderService.init();
473
- this.telegramProviderService.init();
490
+ this.frontendProviderService.connect();
491
+ this.telegramProviderService.connect();
474
492
  }
475
- const { values, positionals } = getArgs();
476
- if (!values.backtest) {
477
- return;
478
- }
479
- const [entryPoint = null] = positionals;
480
- if (!entryPoint) {
481
- throw new Error("Entry point is required");
482
- }
483
- await this.resolveService.attachEntryPoint(entryPoint);
493
+ await this.resolveService.attachEntryPoint(payload.entryPoint);
484
494
  {
485
- this.exchangeSchemaService.init();
486
- this.frameSchemaService.init();
495
+ this.exchangeSchemaService.addSchema();
496
+ this.symbolSchemaService.addSchema();
497
+ this.frameSchemaService.addSchema();
487
498
  }
488
- const symbol = values.symbol || "BTCUSDT";
499
+ const symbol = payload.symbol || "BTCUSDT";
489
500
  const [defaultStrategyName = null] = await backtestKit.listStrategySchema();
490
501
  const [defaultExchangeName = null] = await backtestKit.listExchangeSchema();
491
502
  const [defaultFrameName = null] = await backtestKit.listFrameSchema();
492
- const strategyName = values.strategy || defaultStrategyName?.strategyName;
503
+ const strategyName = payload.strategy || defaultStrategyName?.strategyName;
493
504
  if (!strategyName) {
494
505
  throw new Error("Strategy name is required");
495
506
  }
496
- const exchangeName = values.exchange || defaultExchangeName?.exchangeName;
507
+ const exchangeName = payload.exchange || defaultExchangeName?.exchangeName;
497
508
  if (!exchangeName) {
498
509
  throw new Error("Exchange name is required");
499
510
  }
500
- const frameName = values.frame || defaultFrameName?.frameName;
511
+ const frameName = payload.frame || defaultFrameName?.frameName;
501
512
  if (!frameName) {
502
513
  throw new Error("Frame name is required");
503
514
  }
504
- await this.cacheLogicService.execute({
505
- exchangeName,
506
- frameName,
507
- symbol,
508
- });
509
- if (values.verbose) {
515
+ {
516
+ await this.cacheLogicService.execute(payload.cacheList, {
517
+ exchangeName,
518
+ frameName,
519
+ symbol,
520
+ });
521
+ }
522
+ if (payload.verbose) {
510
523
  backtestKit.overrideExchangeSchema({
511
524
  exchangeName,
512
525
  callbacks: {
@@ -523,46 +536,68 @@ class BacktestMainService {
523
536
  });
524
537
  notifyFinish();
525
538
  });
539
+ this.init = functoolsKit.singleshot(async () => {
540
+ this.loggerService.log("backtestMainService init");
541
+ if (!getEntry((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))) {
542
+ return;
543
+ }
544
+ const { values, positionals } = getArgs();
545
+ if (!values.backtest) {
546
+ return;
547
+ }
548
+ const [entryPoint = null] = positionals;
549
+ if (!entryPoint) {
550
+ throw new Error("Entry point is required");
551
+ }
552
+ const cacheList = GET_CACHE_LIST_FN();
553
+ return await this.run({
554
+ symbol: values.symbol,
555
+ entryPoint,
556
+ cacheList,
557
+ exchange: values.exchange,
558
+ frame: values.frame,
559
+ strategy: values.strategy,
560
+ verbose: values.verbose,
561
+ });
562
+ });
526
563
  }
527
564
  }
528
565
 
529
566
  class LiveMainService {
530
567
  constructor() {
531
568
  this.loggerService = inject(TYPES.loggerService);
532
- this.exchangeSchemaService = inject(TYPES.exchangeSchemaService);
533
569
  this.resolveService = inject(TYPES.resolveService);
570
+ this.exchangeSchemaService = inject(TYPES.exchangeSchemaService);
571
+ this.symbolSchemaService = inject(TYPES.symbolSchemaService);
534
572
  this.frontendProviderService = inject(TYPES.frontendProviderService);
535
573
  this.telegramProviderService = inject(TYPES.telegramProviderService);
536
- this.init = functoolsKit.singleshot(async () => {
537
- this.loggerService.log("liveMainService init");
574
+ this.liveProviderService = inject(TYPES.liveProviderService);
575
+ this.run = functoolsKit.singleshot(async (payload) => {
576
+ this.loggerService.log("liveMainService run", {
577
+ payload,
578
+ });
538
579
  {
539
- this.frontendProviderService.init();
540
- this.telegramProviderService.init();
541
- }
542
- const { values, positionals } = getArgs();
543
- if (!values.live) {
544
- return;
545
- }
546
- const [entryPoint = null] = positionals;
547
- if (!entryPoint) {
548
- throw new Error("Entry point is required");
580
+ this.frontendProviderService.connect();
581
+ this.telegramProviderService.connect();
582
+ this.liveProviderService.connect();
549
583
  }
550
- await this.resolveService.attachEntryPoint(entryPoint);
584
+ await this.resolveService.attachEntryPoint(payload.entryPoint);
551
585
  {
552
- this.exchangeSchemaService.init();
586
+ this.exchangeSchemaService.addSchema();
587
+ this.symbolSchemaService.addSchema();
553
588
  }
554
- const symbol = values.symbol || "BTCUSDT";
589
+ const symbol = payload.symbol || "BTCUSDT";
555
590
  const [defaultStrategyName = null] = await backtestKit.listStrategySchema();
556
591
  const [defaultExchangeName = null] = await backtestKit.listExchangeSchema();
557
- const strategyName = values.strategy || defaultStrategyName?.strategyName;
592
+ const strategyName = payload.strategy || defaultStrategyName?.strategyName;
558
593
  if (!strategyName) {
559
594
  throw new Error("Strategy name is required");
560
595
  }
561
- const exchangeName = values.exchange || defaultExchangeName?.exchangeName;
596
+ const exchangeName = payload.exchange || defaultExchangeName?.exchangeName;
562
597
  if (!exchangeName) {
563
598
  throw new Error("Exchange name is required");
564
599
  }
565
- if (values.verbose) {
600
+ if (payload.verbose) {
566
601
  backtestKit.overrideExchangeSchema({
567
602
  exchangeName,
568
603
  callbacks: {
@@ -578,46 +613,61 @@ class LiveMainService {
578
613
  });
579
614
  notifyFinish();
580
615
  });
616
+ this.init = functoolsKit.singleshot(async () => {
617
+ this.loggerService.log("liveMainService init");
618
+ if (!getEntry((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))) {
619
+ return;
620
+ }
621
+ const { values, positionals } = getArgs();
622
+ if (!values.live) {
623
+ return;
624
+ }
625
+ const [entryPoint = null] = positionals;
626
+ if (!entryPoint) {
627
+ throw new Error("Entry point is required");
628
+ }
629
+ return await this.run({
630
+ entryPoint,
631
+ exchange: values.exchange,
632
+ strategy: values.strategy,
633
+ symbol: values.symbol,
634
+ verbose: values.verbose,
635
+ });
636
+ });
581
637
  }
582
638
  }
583
639
 
584
640
  class PaperMainService {
585
641
  constructor() {
586
642
  this.loggerService = inject(TYPES.loggerService);
587
- this.exchangeSchemaService = inject(TYPES.exchangeSchemaService);
588
643
  this.resolveService = inject(TYPES.resolveService);
644
+ this.exchangeSchemaService = inject(TYPES.exchangeSchemaService);
645
+ this.symbolSchemaService = inject(TYPES.symbolSchemaService);
589
646
  this.frontendProviderService = inject(TYPES.frontendProviderService);
590
647
  this.telegramProviderService = inject(TYPES.telegramProviderService);
591
- this.init = functoolsKit.singleshot(async () => {
648
+ this.run = functoolsKit.singleshot(async (payload) => {
592
649
  this.loggerService.log("paperMainService init");
593
650
  {
594
- this.frontendProviderService.init();
595
- this.telegramProviderService.init();
596
- }
597
- const { values, positionals } = getArgs();
598
- if (!values.paper) {
599
- return;
651
+ this.frontendProviderService.connect();
652
+ this.telegramProviderService.connect();
600
653
  }
601
- const [entryPoint = null] = positionals;
602
- if (!entryPoint) {
603
- throw new Error("Entry point is required");
604
- }
605
- await this.resolveService.attachEntryPoint(entryPoint);
654
+ await this.resolveService.attachEntryPoint(payload.entryPoint);
606
655
  {
607
- this.exchangeSchemaService.init();
656
+ this.exchangeSchemaService.addSchema();
657
+ this.symbolSchemaService.addSchema();
608
658
  }
609
- const symbol = values.symbol || "BTCUSDT";
659
+ const symbol = payload.symbol || "BTCUSDT";
610
660
  const [defaultStrategyName = null] = await backtestKit.listStrategySchema();
611
661
  const [defaultExchangeName = null] = await backtestKit.listExchangeSchema();
612
- const strategyName = values.strategy || defaultStrategyName?.strategyName;
662
+ const strategyName = payload.strategy || defaultStrategyName?.strategyName;
613
663
  if (!strategyName) {
614
664
  throw new Error("Strategy name is required");
615
665
  }
616
- const exchangeName = values.exchange || defaultExchangeName?.exchangeName;
666
+ const exchangeName = payload.exchange || defaultExchangeName?.exchangeName;
617
667
  if (!exchangeName) {
618
668
  throw new Error("Exchange name is required");
619
669
  }
620
- if (values.verbose) {
670
+ if (payload.verbose) {
621
671
  backtestKit.overrideExchangeSchema({
622
672
  exchangeName,
623
673
  callbacks: {
@@ -633,6 +683,27 @@ class PaperMainService {
633
683
  });
634
684
  notifyFinish();
635
685
  });
686
+ this.init = functoolsKit.singleshot(async () => {
687
+ this.loggerService.log("paperMainService init");
688
+ if (!getEntry((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))) {
689
+ return;
690
+ }
691
+ const { values, positionals } = getArgs();
692
+ if (!values.paper) {
693
+ return;
694
+ }
695
+ const [entryPoint = null] = positionals;
696
+ if (!entryPoint) {
697
+ throw new Error("Entry point is required");
698
+ }
699
+ return await this.run({
700
+ entryPoint,
701
+ exchange: values.exchange,
702
+ strategy: values.strategy,
703
+ symbol: values.symbol,
704
+ verbose: values.verbose,
705
+ });
706
+ });
636
707
  }
637
708
  }
638
709
 
@@ -668,12 +739,12 @@ class FrontendProviderService {
668
739
  lastSubscription();
669
740
  }
670
741
  };
671
- this.init = functoolsKit.singleshot(async () => {
672
- this.loggerService.log("frontendProviderService init");
742
+ this.connect = functoolsKit.singleshot(async () => {
743
+ this.loggerService.log("frontendProviderService connect");
673
744
  if (!getArgs().values.ui) {
674
745
  return;
675
746
  }
676
- entrySubject.subscribe(this.enable);
747
+ return entrySubject.subscribe(this.enable);
677
748
  });
678
749
  }
679
750
  }
@@ -704,12 +775,12 @@ class TelegramProviderService {
704
775
  lastSubscription();
705
776
  }
706
777
  };
707
- this.init = functoolsKit.singleshot(async () => {
708
- this.loggerService.log("telegramProviderService init");
778
+ this.connect = functoolsKit.singleshot(async () => {
779
+ this.loggerService.log("telegramProviderService connect");
709
780
  if (!getArgs().values.telegram) {
710
781
  return;
711
782
  }
712
- entrySubject.subscribe(this.enable);
783
+ return entrySubject.subscribe(this.enable);
713
784
  });
714
785
  }
715
786
  }
@@ -1131,17 +1202,6 @@ class TelegramWebService {
1131
1202
  }
1132
1203
  }
1133
1204
 
1134
- const DEFAULT_TIMEFRAME_LIST = ["1m", "15m", "30m", "1h", "4h"];
1135
- const GET_TIMEFRAME_LIST_FN = async () => {
1136
- const { values } = getArgs();
1137
- if (!values.cache) {
1138
- console.warn(`Warning: No cache timeframes provided. Using default timeframes: ${DEFAULT_TIMEFRAME_LIST.join(", ")}`);
1139
- return DEFAULT_TIMEFRAME_LIST;
1140
- }
1141
- return String(values.cache)
1142
- .split(",")
1143
- .map((timeframe) => timeframe.trim());
1144
- };
1145
1205
  const GET_TIMEFRAME_RANGE_FN = async (frameName) => {
1146
1206
  const frameList = await backtestKit.listFrameSchema();
1147
1207
  const frameSchema = frameList.find((frameSchema) => frameSchema.frameName === frameName);
@@ -1177,12 +1237,11 @@ const CACHE_CANDLES_FN = functoolsKit.retry(async (interval, dto) => {
1177
1237
  class CacheLogicService {
1178
1238
  constructor() {
1179
1239
  this.loggerService = inject(TYPES.loggerService);
1180
- this.execute = async (dto) => {
1240
+ this.execute = async (intervalList, dto) => {
1181
1241
  this.loggerService.log("cacheLogicService execute", {
1182
1242
  dto,
1183
1243
  });
1184
1244
  const { startDate, endDate } = await GET_TIMEFRAME_RANGE_FN(dto.frameName);
1185
- const intervalList = await GET_TIMEFRAME_LIST_FN();
1186
1245
  try {
1187
1246
  for (const interval of intervalList) {
1188
1247
  await CACHE_CANDLES_FN(interval, {
@@ -1355,7 +1414,8 @@ class TelegramLogicService {
1355
1414
  return;
1356
1415
  }
1357
1416
  });
1358
- const unListen = functoolsKit.compose(() => unRisk(), () => unSignal(), () => unCommit());
1417
+ const unConnect = () => this.connect.clear();
1418
+ const unListen = functoolsKit.compose(() => unRisk(), () => unSignal(), () => unCommit(), () => unConnect());
1359
1419
  return () => {
1360
1420
  STOP_BOT_FN();
1361
1421
  unListen();
@@ -1505,10 +1565,10 @@ class ModuleConnectionService {
1505
1565
  }
1506
1566
  }
1507
1567
 
1508
- const LOAD_INSTANCE_FN = functoolsKit.singleshot(async (self) => {
1568
+ const LOAD_INSTANCE_FN = functoolsKit.singleshot(functoolsKit.trycatch(async (self) => {
1509
1569
  const module = (await self.moduleConnectionService.getInstance("./live.module"));
1510
1570
  return module;
1511
- });
1571
+ }, { defaultValue: null }));
1512
1572
  class LiveProviderService {
1513
1573
  constructor() {
1514
1574
  this.loggerService = inject(TYPES.loggerService);
@@ -1518,7 +1578,7 @@ class LiveProviderService {
1518
1578
  event,
1519
1579
  });
1520
1580
  const instance = await LOAD_INSTANCE_FN(this);
1521
- if (instance.onTrailingTake) {
1581
+ if (instance?.onTrailingTake) {
1522
1582
  await instance.onTrailingTake(event);
1523
1583
  }
1524
1584
  };
@@ -1527,7 +1587,7 @@ class LiveProviderService {
1527
1587
  event,
1528
1588
  });
1529
1589
  const instance = await LOAD_INSTANCE_FN(this);
1530
- if (instance.onTrailingStop) {
1590
+ if (instance?.onTrailingStop) {
1531
1591
  await instance.onTrailingStop(event);
1532
1592
  }
1533
1593
  };
@@ -1536,7 +1596,7 @@ class LiveProviderService {
1536
1596
  event,
1537
1597
  });
1538
1598
  const instance = await LOAD_INSTANCE_FN(this);
1539
- if (instance.onBreakeven) {
1599
+ if (instance?.onBreakeven) {
1540
1600
  await instance.onBreakeven(event);
1541
1601
  }
1542
1602
  };
@@ -1545,7 +1605,7 @@ class LiveProviderService {
1545
1605
  event,
1546
1606
  });
1547
1607
  const instance = await LOAD_INSTANCE_FN(this);
1548
- if (instance.onPartialProfit) {
1608
+ if (instance?.onPartialProfit) {
1549
1609
  await instance.onPartialProfit(event);
1550
1610
  }
1551
1611
  };
@@ -1554,7 +1614,7 @@ class LiveProviderService {
1554
1614
  event,
1555
1615
  });
1556
1616
  const instance = await LOAD_INSTANCE_FN(this);
1557
- if (instance.onPartialLoss) {
1617
+ if (instance?.onPartialLoss) {
1558
1618
  await instance.onPartialLoss(event);
1559
1619
  }
1560
1620
  };
@@ -1563,7 +1623,7 @@ class LiveProviderService {
1563
1623
  event,
1564
1624
  });
1565
1625
  const instance = await LOAD_INSTANCE_FN(this);
1566
- if (instance.onScheduled) {
1626
+ if (instance?.onScheduled) {
1567
1627
  await instance.onScheduled(event);
1568
1628
  }
1569
1629
  };
@@ -1572,7 +1632,7 @@ class LiveProviderService {
1572
1632
  event,
1573
1633
  });
1574
1634
  const instance = await LOAD_INSTANCE_FN(this);
1575
- if (instance.onCancelled) {
1635
+ if (instance?.onCancelled) {
1576
1636
  await instance.onCancelled(event);
1577
1637
  }
1578
1638
  };
@@ -1581,7 +1641,7 @@ class LiveProviderService {
1581
1641
  event,
1582
1642
  });
1583
1643
  const instance = await LOAD_INSTANCE_FN(this);
1584
- if (instance.onOpened) {
1644
+ if (instance?.onOpened) {
1585
1645
  await instance.onOpened(event);
1586
1646
  }
1587
1647
  };
@@ -1590,7 +1650,7 @@ class LiveProviderService {
1590
1650
  event,
1591
1651
  });
1592
1652
  const instance = await LOAD_INSTANCE_FN(this);
1593
- if (instance.onClosed) {
1653
+ if (instance?.onClosed) {
1594
1654
  await instance.onClosed(event);
1595
1655
  }
1596
1656
  };
@@ -1599,12 +1659,20 @@ class LiveProviderService {
1599
1659
  event,
1600
1660
  });
1601
1661
  const instance = await LOAD_INSTANCE_FN(this);
1602
- if (instance.onRisk) {
1662
+ if (instance?.onRisk) {
1603
1663
  await instance.onRisk(event);
1604
1664
  }
1605
1665
  };
1606
1666
  this.enable = functoolsKit.singleshot(() => {
1607
1667
  this.loggerService.log("liveProviderService enable");
1668
+ LOAD_INSTANCE_FN(this).then((module) => {
1669
+ if (module) {
1670
+ this.loggerService.log("Live trading initialized successfully with ./modules/live.module.mjs");
1671
+ return;
1672
+ }
1673
+ console.log("No ./modules/live.module.mjs found, live trading failed to initialize");
1674
+ process.exit(-1);
1675
+ });
1608
1676
  const unRisk = backtestKit.listenRisk(async (event) => {
1609
1677
  await this.handleRisk(event);
1610
1678
  });
@@ -1648,7 +1716,8 @@ class LiveProviderService {
1648
1716
  return;
1649
1717
  }
1650
1718
  });
1651
- return functoolsKit.compose(() => unRisk(), () => unSignal(), () => unCommit());
1719
+ const unConnect = () => this.enable.clear();
1720
+ return functoolsKit.compose(() => unRisk(), () => unSignal(), () => unCommit(), () => unConnect());
1652
1721
  });
1653
1722
  this.disable = () => {
1654
1723
  this.loggerService.log("liveProviderService disable");
@@ -1657,12 +1726,12 @@ class LiveProviderService {
1657
1726
  lastSubscription();
1658
1727
  }
1659
1728
  };
1660
- this.init = functoolsKit.singleshot(async () => {
1661
- this.loggerService.log("liveProviderService init");
1729
+ this.connect = functoolsKit.singleshot(async () => {
1730
+ this.loggerService.log("liveProviderService connect");
1662
1731
  if (!getArgs().values.live) {
1663
1732
  return;
1664
1733
  }
1665
- entrySubject.subscribe(this.enable);
1734
+ return entrySubject.subscribe(this.enable);
1666
1735
  });
1667
1736
  }
1668
1737
  }
@@ -1777,6 +1846,9 @@ const BEFORE_EXIT_FN$4 = functoolsKit.singleshot(async () => {
1777
1846
  });
1778
1847
  });
1779
1848
  const main$4 = async () => {
1849
+ if (!getEntry((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))) {
1850
+ return;
1851
+ }
1780
1852
  const { values } = getArgs();
1781
1853
  if (!values.backtest) {
1782
1854
  return;
@@ -1802,6 +1874,9 @@ const BEFORE_EXIT_FN$3 = functoolsKit.singleshot(async () => {
1802
1874
  });
1803
1875
  });
1804
1876
  const main$3 = async () => {
1877
+ if (!getEntry((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))) {
1878
+ return;
1879
+ }
1805
1880
  const { values } = getArgs();
1806
1881
  if (!values.paper) {
1807
1882
  return;
@@ -1828,6 +1903,9 @@ const BEFORE_EXIT_FN$2 = functoolsKit.singleshot(async () => {
1828
1903
  backtestKit.listenDoneLive(cli.liveProviderService.disable);
1829
1904
  });
1830
1905
  const main$2 = async () => {
1906
+ if (!getEntry((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))) {
1907
+ return;
1908
+ }
1831
1909
  const { values } = getArgs();
1832
1910
  if (!values.live) {
1833
1911
  return;
@@ -1842,6 +1920,9 @@ const BEFORE_EXIT_FN$1 = functoolsKit.singleshot(async () => {
1842
1920
  cli.frontendProviderService.disable();
1843
1921
  });
1844
1922
  const main$1 = async () => {
1923
+ if (!getEntry((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))) {
1924
+ return;
1925
+ }
1845
1926
  const { values } = getArgs();
1846
1927
  if (!values.ui) {
1847
1928
  return;
@@ -1856,6 +1937,9 @@ const BEFORE_EXIT_FN = functoolsKit.singleshot(async () => {
1856
1937
  cli.telegramProviderService.disable();
1857
1938
  });
1858
1939
  const main = async () => {
1940
+ if (!getEntry((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))) {
1941
+ return;
1942
+ }
1859
1943
  const { values } = getArgs();
1860
1944
  if (!values.telegram) {
1861
1945
  return;
@@ -1868,5 +1952,26 @@ function setLogger(logger) {
1868
1952
  cli.loggerService.setLogger(logger);
1869
1953
  }
1870
1954
 
1955
+ let _is_started = false;
1956
+ async function run(mode, args) {
1957
+ {
1958
+ if (_is_started) {
1959
+ throw new Error("Should be called only once");
1960
+ }
1961
+ _is_started = true;
1962
+ }
1963
+ if (mode === "backtest") {
1964
+ return await cli.backtestMainService.run(args);
1965
+ }
1966
+ if (mode === "paper") {
1967
+ return await cli.paperMainService.run(args);
1968
+ }
1969
+ if (mode === "live") {
1970
+ return await cli.liveMainService.run(args);
1971
+ }
1972
+ throw new Error(`Invalid mode: ${mode}`);
1973
+ }
1974
+
1871
1975
  exports.cli = cli;
1976
+ exports.run = run;
1872
1977
  exports.setLogger = setLogger;