@backtest-kit/pinets 3.0.3 → 3.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/build/index.cjs CHANGED
@@ -81,9 +81,11 @@ class LoggerService {
81
81
 
82
82
  const { provide, inject, init, override } = diKit.createActivator("pine");
83
83
 
84
- const baseServices = {
84
+ const baseServices$1 = {
85
85
  loggerService: Symbol("loggerService"),
86
- contextService: Symbol("contextService"),
86
+ };
87
+ const contextServices$1 = {
88
+ exchangeContextService: Symbol("exchangeContextService"),
87
89
  };
88
90
  const providerServices$1 = {
89
91
  axisProviderService: Symbol("axisProviderService"),
@@ -105,7 +107,8 @@ const markdownServices$1 = {
105
107
  pineMarkdownService: Symbol("pineMarkdownService"),
106
108
  };
107
109
  const TYPES = {
108
- ...baseServices,
110
+ ...baseServices$1,
111
+ ...contextServices$1,
109
112
  ...providerServices$1,
110
113
  ...jobServices$1,
111
114
  ...dataServices$1,
@@ -232,15 +235,15 @@ class AxisProviderService {
232
235
  }
233
236
  }
234
237
 
235
- const ContextService = diScoped.scoped(class {
238
+ const ExchangeContextService = diScoped.scoped(class {
236
239
  constructor(context) {
237
240
  this.context = context;
238
241
  }
239
242
  });
240
243
 
241
244
  const GET_RAW_CANDLES_FN = async (self, symbol, interval, limit, sDate, eDate) => {
242
- if (ContextService.hasContext()) {
243
- return await backtestKit.Exchange.getRawCandles(symbol, interval, self.contextService.context, limit, sDate, eDate);
245
+ if (ExchangeContextService.hasContext()) {
246
+ return await backtestKit.Exchange.getRawCandles(symbol, interval, self.exchangeContextService.context, limit, sDate, eDate);
244
247
  }
245
248
  if (!backtestKit.MethodContextService.hasContext()) {
246
249
  throw new Error("MethodContextService context is required to get market data for pinets if exchangeName?: string is not specified");
@@ -253,7 +256,7 @@ const GET_RAW_CANDLES_FN = async (self, symbol, interval, limit, sDate, eDate) =
253
256
  class CandleProviderService {
254
257
  constructor() {
255
258
  this.loggerService = inject(TYPES.loggerService);
256
- this.contextService = inject(TYPES.contextService);
259
+ this.exchangeContextService = inject(TYPES.exchangeContextService);
257
260
  }
258
261
  async getMarketData(tickerId, timeframe, limit, sDate, eDate) {
259
262
  this.loggerService.log("candleProviderService getMarketData", {
@@ -574,7 +577,9 @@ class PineMarkdownService {
574
577
 
575
578
  {
576
579
  provide(TYPES.loggerService, () => new LoggerService());
577
- provide(TYPES.contextService, () => new ContextService());
580
+ }
581
+ {
582
+ provide(TYPES.exchangeContextService, () => new ExchangeContextService());
578
583
  }
579
584
  {
580
585
  provide(TYPES.axisProviderService, () => new AxisProviderService());
@@ -596,9 +601,11 @@ class PineMarkdownService {
596
601
  provide(TYPES.pineMarkdownService, () => new PineMarkdownService());
597
602
  }
598
603
 
599
- const commonServices = {
604
+ const baseServices = {
600
605
  loggerService: inject(TYPES.loggerService),
601
- contextService: inject(TYPES.contextService),
606
+ };
607
+ const contextServices = {
608
+ exchangeContextService: inject(TYPES.exchangeContextService),
602
609
  };
603
610
  const providerServices = {
604
611
  axisProviderService: inject(TYPES.axisProviderService),
@@ -620,7 +627,8 @@ const markdownServices = {
620
627
  pineMarkdownService: inject(TYPES.pineMarkdownService),
621
628
  };
622
629
  const pine = {
623
- ...commonServices,
630
+ ...contextServices,
631
+ ...baseServices,
624
632
  ...providerServices,
625
633
  ...jobServices,
626
634
  ...dataServices,
@@ -649,13 +657,26 @@ const GET_SOURCE_FN$1 = async (source) => {
649
657
  }
650
658
  throw new Error("Source must be a File or Code instance");
651
659
  };
652
- const RUN_INFERENCE_FN = async (script, symbol, timeframe, limit, exchangeName) => {
660
+ const BASE_RUNNER_FN = async (script, symbol, timeframe, limit) => await pine.pineJobService.run(script, symbol, timeframe, limit);
661
+ const CREATE_INFERENCE_FN = (script, symbol, timeframe, limit, exchangeName, when) => {
662
+ let fn = () => BASE_RUNNER_FN(script, symbol, timeframe, limit);
653
663
  if (exchangeName) {
654
- return await ContextService.runInContext(async () => await pine.pineJobService.run(script, symbol, timeframe, limit), { exchangeName });
664
+ fn = ExchangeContextService.runWithContext(fn, { exchangeName });
655
665
  }
656
- return await pine.pineJobService.run(script, symbol, timeframe, limit);
666
+ if (when) {
667
+ fn = backtestKit.ExecutionContextService.runWithContext(fn, {
668
+ when,
669
+ symbol,
670
+ backtest: true,
671
+ });
672
+ }
673
+ return fn;
674
+ };
675
+ const RUN_INFERENCE_FN = async (script, symbol, timeframe, limit, exchangeName, when) => {
676
+ const inference = CREATE_INFERENCE_FN(script, symbol, timeframe, limit, exchangeName, when);
677
+ return await inference();
657
678
  };
658
- async function run(source, { symbol, timeframe, limit }, exchangeName) {
679
+ async function run(source, { symbol, timeframe, limit }, exchangeName, when) {
659
680
  pine.loggerService.info(METHOD_NAME_RUN$2, {
660
681
  source,
661
682
  symbol,
@@ -663,7 +684,7 @@ async function run(source, { symbol, timeframe, limit }, exchangeName) {
663
684
  limit,
664
685
  });
665
686
  const script = await GET_SOURCE_FN$1(source);
666
- const { plots } = await RUN_INFERENCE_FN(script, symbol, timeframe, limit, exchangeName);
687
+ const { plots } = await RUN_INFERENCE_FN(script, symbol, timeframe, limit, exchangeName, when);
667
688
  return plots;
668
689
  }
669
690
 
package/build/index.mjs CHANGED
@@ -78,9 +78,11 @@ class LoggerService {
78
78
 
79
79
  const { provide, inject, init, override } = createActivator("pine");
80
80
 
81
- const baseServices = {
81
+ const baseServices$1 = {
82
82
  loggerService: Symbol("loggerService"),
83
- contextService: Symbol("contextService"),
83
+ };
84
+ const contextServices$1 = {
85
+ exchangeContextService: Symbol("exchangeContextService"),
84
86
  };
85
87
  const providerServices$1 = {
86
88
  axisProviderService: Symbol("axisProviderService"),
@@ -102,7 +104,8 @@ const markdownServices$1 = {
102
104
  pineMarkdownService: Symbol("pineMarkdownService"),
103
105
  };
104
106
  const TYPES = {
105
- ...baseServices,
107
+ ...baseServices$1,
108
+ ...contextServices$1,
106
109
  ...providerServices$1,
107
110
  ...jobServices$1,
108
111
  ...dataServices$1,
@@ -229,15 +232,15 @@ class AxisProviderService {
229
232
  }
230
233
  }
231
234
 
232
- const ContextService = scoped(class {
235
+ const ExchangeContextService = scoped(class {
233
236
  constructor(context) {
234
237
  this.context = context;
235
238
  }
236
239
  });
237
240
 
238
241
  const GET_RAW_CANDLES_FN = async (self, symbol, interval, limit, sDate, eDate) => {
239
- if (ContextService.hasContext()) {
240
- return await Exchange.getRawCandles(symbol, interval, self.contextService.context, limit, sDate, eDate);
242
+ if (ExchangeContextService.hasContext()) {
243
+ return await Exchange.getRawCandles(symbol, interval, self.exchangeContextService.context, limit, sDate, eDate);
241
244
  }
242
245
  if (!MethodContextService.hasContext()) {
243
246
  throw new Error("MethodContextService context is required to get market data for pinets if exchangeName?: string is not specified");
@@ -250,7 +253,7 @@ const GET_RAW_CANDLES_FN = async (self, symbol, interval, limit, sDate, eDate) =
250
253
  class CandleProviderService {
251
254
  constructor() {
252
255
  this.loggerService = inject(TYPES.loggerService);
253
- this.contextService = inject(TYPES.contextService);
256
+ this.exchangeContextService = inject(TYPES.exchangeContextService);
254
257
  }
255
258
  async getMarketData(tickerId, timeframe, limit, sDate, eDate) {
256
259
  this.loggerService.log("candleProviderService getMarketData", {
@@ -571,7 +574,9 @@ class PineMarkdownService {
571
574
 
572
575
  {
573
576
  provide(TYPES.loggerService, () => new LoggerService());
574
- provide(TYPES.contextService, () => new ContextService());
577
+ }
578
+ {
579
+ provide(TYPES.exchangeContextService, () => new ExchangeContextService());
575
580
  }
576
581
  {
577
582
  provide(TYPES.axisProviderService, () => new AxisProviderService());
@@ -593,9 +598,11 @@ class PineMarkdownService {
593
598
  provide(TYPES.pineMarkdownService, () => new PineMarkdownService());
594
599
  }
595
600
 
596
- const commonServices = {
601
+ const baseServices = {
597
602
  loggerService: inject(TYPES.loggerService),
598
- contextService: inject(TYPES.contextService),
603
+ };
604
+ const contextServices = {
605
+ exchangeContextService: inject(TYPES.exchangeContextService),
599
606
  };
600
607
  const providerServices = {
601
608
  axisProviderService: inject(TYPES.axisProviderService),
@@ -617,7 +624,8 @@ const markdownServices = {
617
624
  pineMarkdownService: inject(TYPES.pineMarkdownService),
618
625
  };
619
626
  const pine = {
620
- ...commonServices,
627
+ ...contextServices,
628
+ ...baseServices,
621
629
  ...providerServices,
622
630
  ...jobServices,
623
631
  ...dataServices,
@@ -646,13 +654,26 @@ const GET_SOURCE_FN$1 = async (source) => {
646
654
  }
647
655
  throw new Error("Source must be a File or Code instance");
648
656
  };
649
- const RUN_INFERENCE_FN = async (script, symbol, timeframe, limit, exchangeName) => {
657
+ const BASE_RUNNER_FN = async (script, symbol, timeframe, limit) => await pine.pineJobService.run(script, symbol, timeframe, limit);
658
+ const CREATE_INFERENCE_FN = (script, symbol, timeframe, limit, exchangeName, when) => {
659
+ let fn = () => BASE_RUNNER_FN(script, symbol, timeframe, limit);
650
660
  if (exchangeName) {
651
- return await ContextService.runInContext(async () => await pine.pineJobService.run(script, symbol, timeframe, limit), { exchangeName });
661
+ fn = ExchangeContextService.runWithContext(fn, { exchangeName });
652
662
  }
653
- return await pine.pineJobService.run(script, symbol, timeframe, limit);
663
+ if (when) {
664
+ fn = ExecutionContextService.runWithContext(fn, {
665
+ when,
666
+ symbol,
667
+ backtest: true,
668
+ });
669
+ }
670
+ return fn;
671
+ };
672
+ const RUN_INFERENCE_FN = async (script, symbol, timeframe, limit, exchangeName, when) => {
673
+ const inference = CREATE_INFERENCE_FN(script, symbol, timeframe, limit, exchangeName, when);
674
+ return await inference();
654
675
  };
655
- async function run(source, { symbol, timeframe, limit }, exchangeName) {
676
+ async function run(source, { symbol, timeframe, limit }, exchangeName, when) {
656
677
  pine.loggerService.info(METHOD_NAME_RUN$2, {
657
678
  source,
658
679
  symbol,
@@ -660,7 +681,7 @@ async function run(source, { symbol, timeframe, limit }, exchangeName) {
660
681
  limit,
661
682
  });
662
683
  const script = await GET_SOURCE_FN$1(source);
663
- const { plots } = await RUN_INFERENCE_FN(script, symbol, timeframe, limit, exchangeName);
684
+ const { plots } = await RUN_INFERENCE_FN(script, symbol, timeframe, limit, exchangeName, when);
664
685
  return plots;
665
686
  }
666
687
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backtest-kit/pinets",
3
- "version": "3.0.3",
3
+ "version": "3.0.5",
4
4
  "description": "Run TradingView Pine Script strategies in Node.js self hosted environment. Execute existing Pine Script indicators and generate trading signals with 1:1 syntax compatibility via PineTS runtime.",
5
5
  "author": {
6
6
  "name": "Petr Tripolsky",
@@ -72,13 +72,13 @@
72
72
  "worker-testbed": "1.0.12"
73
73
  },
74
74
  "peerDependencies": {
75
- "backtest-kit": "^3.0.5",
75
+ "backtest-kit": "^3.0.9",
76
76
  "pinets": "^0.8.6",
77
77
  "typescript": "^5.0.0"
78
78
  },
79
79
  "dependencies": {
80
80
  "di-kit": "^1.0.18",
81
- "di-scoped": "^1.0.20",
81
+ "di-scoped": "^1.0.21",
82
82
  "functools-kit": "^1.0.95",
83
83
  "get-moment-stamp": "^1.1.1"
84
84
  },
package/types.d.ts CHANGED
@@ -43,7 +43,7 @@ interface IPine {
43
43
  declare function usePine<T = TPineCtor>(ctor: T): void;
44
44
 
45
45
  type ExchangeName = string;
46
- interface IContext {
46
+ interface IExchangeContext {
47
47
  exchangeName: ExchangeName;
48
48
  }
49
49
 
@@ -52,7 +52,7 @@ interface IRunParams {
52
52
  timeframe: CandleInterval;
53
53
  limit: number;
54
54
  }
55
- declare function run(source: File | Code, { symbol, timeframe, limit }: IRunParams, exchangeName?: ExchangeName): Promise<PlotModel>;
55
+ declare function run(source: File | Code, { symbol, timeframe, limit }: IRunParams, exchangeName?: ExchangeName, when?: Date): Promise<PlotModel>;
56
56
 
57
57
  type PlotExtractConfig<T = number> = {
58
58
  plot: string;
@@ -144,8 +144,8 @@ declare class LoggerService implements ILogger {
144
144
 
145
145
  declare class CandleProviderService implements IProvider {
146
146
  readonly loggerService: LoggerService;
147
- readonly contextService: {
148
- readonly context: IContext;
147
+ readonly exchangeContextService: {
148
+ readonly context: IExchangeContext;
149
149
  };
150
150
  getMarketData(tickerId: string, timeframe: string, limit?: number, sDate?: number, eDate?: number): Promise<any[]>;
151
151
  getSymbolInfo(tickerId: string): Promise<any>;
@@ -194,8 +194,8 @@ declare const pine: {
194
194
  axisProviderService: AxisProviderService;
195
195
  candleProviderService: CandleProviderService;
196
196
  loggerService: LoggerService;
197
- contextService: {
198
- readonly context: IContext;
197
+ exchangeContextService: {
198
+ readonly context: IExchangeContext;
199
199
  };
200
200
  };
201
201