@backtest-kit/pinets 5.6.2 → 5.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.cjs +49 -4
- package/build/index.mjs +49 -5
- package/package.json +4 -4
- package/types.d.ts +8 -1
package/build/index.cjs
CHANGED
|
@@ -361,10 +361,47 @@ const GET_VALUE_FN = (plots, name, barsBack = 0) => {
|
|
|
361
361
|
const idx = data.length - 1 - barsBack;
|
|
362
362
|
return idx >= 0 ? (data[idx]?.value ?? 0) : 0;
|
|
363
363
|
};
|
|
364
|
+
const GET_VALUE_AT_FN = (plots, name, i, barsBack = 0) => {
|
|
365
|
+
const data = plots[name]?.data;
|
|
366
|
+
if (!data)
|
|
367
|
+
return null;
|
|
368
|
+
const idx = i - barsBack;
|
|
369
|
+
return idx >= 0 ? (data[idx]?.value ?? null) : null;
|
|
370
|
+
};
|
|
364
371
|
class PineDataService {
|
|
365
372
|
constructor() {
|
|
366
373
|
this.loggerService = inject(TYPES.loggerService);
|
|
367
374
|
}
|
|
375
|
+
extractRows(plots, mapping) {
|
|
376
|
+
this.loggerService.log("pineDataService extractRows", {
|
|
377
|
+
plotCount: Object.keys(plots).length,
|
|
378
|
+
mapping,
|
|
379
|
+
});
|
|
380
|
+
const entries = Object.entries(mapping);
|
|
381
|
+
const plotNames = entries.map(([, config]) => typeof config === "string" ? config : config.plot);
|
|
382
|
+
const dataLength = plotNames
|
|
383
|
+
.map((name) => plots[name]?.data?.length ?? 0)
|
|
384
|
+
.reduce((acm, cur) => Math.max(acm, cur), 0);
|
|
385
|
+
const rows = [];
|
|
386
|
+
for (let i = 0; i < dataLength; i++) {
|
|
387
|
+
const row = {};
|
|
388
|
+
for (const [key, config] of entries) {
|
|
389
|
+
if (typeof config === "string") {
|
|
390
|
+
row[key] = GET_VALUE_AT_FN(plots, config, i);
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
const raw = GET_VALUE_AT_FN(plots, config.plot, i, config.barsBack ?? 0);
|
|
394
|
+
row[key] = (raw !== null && config.transform ? config.transform(raw) : raw);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
const firstPlot = plots[plotNames[0]]?.data?.[i];
|
|
398
|
+
row.timestamp = firstPlot?.time
|
|
399
|
+
? new Date(firstPlot.time).toISOString()
|
|
400
|
+
: "";
|
|
401
|
+
rows.push(row);
|
|
402
|
+
}
|
|
403
|
+
return rows;
|
|
404
|
+
}
|
|
368
405
|
extract(plots, mapping) {
|
|
369
406
|
this.loggerService.log("pineDataService extract", {
|
|
370
407
|
plotCount: Object.keys(plots).length,
|
|
@@ -731,7 +768,7 @@ function useIndicator(ctor) {
|
|
|
731
768
|
pine.indicatorConnectionService.useIndicator(ctor);
|
|
732
769
|
}
|
|
733
770
|
|
|
734
|
-
const METHOD_NAME_RUN$
|
|
771
|
+
const METHOD_NAME_RUN$1 = "run.run";
|
|
735
772
|
const GET_SOURCE_FN$2 = async (source) => {
|
|
736
773
|
if (File.isFile(source)) {
|
|
737
774
|
const code = await pine.pineCacheService.readFile(source.path, source.baseDir);
|
|
@@ -770,7 +807,7 @@ const RUN_INFERENCE_FN$1 = async (script, symbol, timeframe, limit, inputs, exch
|
|
|
770
807
|
return await inference();
|
|
771
808
|
};
|
|
772
809
|
async function run(source, { symbol, timeframe, limit, inputs = {} }, exchangeName, when) {
|
|
773
|
-
pine.loggerService.info(METHOD_NAME_RUN$
|
|
810
|
+
pine.loggerService.info(METHOD_NAME_RUN$1, {
|
|
774
811
|
source,
|
|
775
812
|
symbol,
|
|
776
813
|
timeframe,
|
|
@@ -781,9 +818,16 @@ async function run(source, { symbol, timeframe, limit, inputs = {} }, exchangeNa
|
|
|
781
818
|
return plots;
|
|
782
819
|
}
|
|
783
820
|
|
|
784
|
-
const
|
|
821
|
+
const METHOD_NAME_EXTRACT = "extract.extract";
|
|
822
|
+
const METHOD_NAME_EXTRACT_ROWS = "extractRows.extractRows";
|
|
823
|
+
async function extractRows(plots, mapping) {
|
|
824
|
+
pine.loggerService.info(METHOD_NAME_EXTRACT_ROWS, {
|
|
825
|
+
mapping,
|
|
826
|
+
});
|
|
827
|
+
return pine.pineDataService.extractRows(plots, mapping);
|
|
828
|
+
}
|
|
785
829
|
async function extract(plots, mapping) {
|
|
786
|
-
pine.loggerService.info(
|
|
830
|
+
pine.loggerService.info(METHOD_NAME_EXTRACT, {
|
|
787
831
|
mapping,
|
|
788
832
|
});
|
|
789
833
|
return pine.pineDataService.extract(plots, mapping);
|
|
@@ -934,6 +978,7 @@ exports.Code = Code;
|
|
|
934
978
|
exports.File = File;
|
|
935
979
|
exports.dumpPlotData = dumpPlotData;
|
|
936
980
|
exports.extract = extract;
|
|
981
|
+
exports.extractRows = extractRows;
|
|
937
982
|
exports.getSignal = getSignal;
|
|
938
983
|
exports.lib = pine;
|
|
939
984
|
exports.markdown = markdown;
|
package/build/index.mjs
CHANGED
|
@@ -358,10 +358,47 @@ const GET_VALUE_FN = (plots, name, barsBack = 0) => {
|
|
|
358
358
|
const idx = data.length - 1 - barsBack;
|
|
359
359
|
return idx >= 0 ? (data[idx]?.value ?? 0) : 0;
|
|
360
360
|
};
|
|
361
|
+
const GET_VALUE_AT_FN = (plots, name, i, barsBack = 0) => {
|
|
362
|
+
const data = plots[name]?.data;
|
|
363
|
+
if (!data)
|
|
364
|
+
return null;
|
|
365
|
+
const idx = i - barsBack;
|
|
366
|
+
return idx >= 0 ? (data[idx]?.value ?? null) : null;
|
|
367
|
+
};
|
|
361
368
|
class PineDataService {
|
|
362
369
|
constructor() {
|
|
363
370
|
this.loggerService = inject(TYPES.loggerService);
|
|
364
371
|
}
|
|
372
|
+
extractRows(plots, mapping) {
|
|
373
|
+
this.loggerService.log("pineDataService extractRows", {
|
|
374
|
+
plotCount: Object.keys(plots).length,
|
|
375
|
+
mapping,
|
|
376
|
+
});
|
|
377
|
+
const entries = Object.entries(mapping);
|
|
378
|
+
const plotNames = entries.map(([, config]) => typeof config === "string" ? config : config.plot);
|
|
379
|
+
const dataLength = plotNames
|
|
380
|
+
.map((name) => plots[name]?.data?.length ?? 0)
|
|
381
|
+
.reduce((acm, cur) => Math.max(acm, cur), 0);
|
|
382
|
+
const rows = [];
|
|
383
|
+
for (let i = 0; i < dataLength; i++) {
|
|
384
|
+
const row = {};
|
|
385
|
+
for (const [key, config] of entries) {
|
|
386
|
+
if (typeof config === "string") {
|
|
387
|
+
row[key] = GET_VALUE_AT_FN(plots, config, i);
|
|
388
|
+
}
|
|
389
|
+
else {
|
|
390
|
+
const raw = GET_VALUE_AT_FN(plots, config.plot, i, config.barsBack ?? 0);
|
|
391
|
+
row[key] = (raw !== null && config.transform ? config.transform(raw) : raw);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
const firstPlot = plots[plotNames[0]]?.data?.[i];
|
|
395
|
+
row.timestamp = firstPlot?.time
|
|
396
|
+
? new Date(firstPlot.time).toISOString()
|
|
397
|
+
: "";
|
|
398
|
+
rows.push(row);
|
|
399
|
+
}
|
|
400
|
+
return rows;
|
|
401
|
+
}
|
|
365
402
|
extract(plots, mapping) {
|
|
366
403
|
this.loggerService.log("pineDataService extract", {
|
|
367
404
|
plotCount: Object.keys(plots).length,
|
|
@@ -728,7 +765,7 @@ function useIndicator(ctor) {
|
|
|
728
765
|
pine.indicatorConnectionService.useIndicator(ctor);
|
|
729
766
|
}
|
|
730
767
|
|
|
731
|
-
const METHOD_NAME_RUN$
|
|
768
|
+
const METHOD_NAME_RUN$1 = "run.run";
|
|
732
769
|
const GET_SOURCE_FN$2 = async (source) => {
|
|
733
770
|
if (File.isFile(source)) {
|
|
734
771
|
const code = await pine.pineCacheService.readFile(source.path, source.baseDir);
|
|
@@ -767,7 +804,7 @@ const RUN_INFERENCE_FN$1 = async (script, symbol, timeframe, limit, inputs, exch
|
|
|
767
804
|
return await inference();
|
|
768
805
|
};
|
|
769
806
|
async function run(source, { symbol, timeframe, limit, inputs = {} }, exchangeName, when) {
|
|
770
|
-
pine.loggerService.info(METHOD_NAME_RUN$
|
|
807
|
+
pine.loggerService.info(METHOD_NAME_RUN$1, {
|
|
771
808
|
source,
|
|
772
809
|
symbol,
|
|
773
810
|
timeframe,
|
|
@@ -778,9 +815,16 @@ async function run(source, { symbol, timeframe, limit, inputs = {} }, exchangeNa
|
|
|
778
815
|
return plots;
|
|
779
816
|
}
|
|
780
817
|
|
|
781
|
-
const
|
|
818
|
+
const METHOD_NAME_EXTRACT = "extract.extract";
|
|
819
|
+
const METHOD_NAME_EXTRACT_ROWS = "extractRows.extractRows";
|
|
820
|
+
async function extractRows(plots, mapping) {
|
|
821
|
+
pine.loggerService.info(METHOD_NAME_EXTRACT_ROWS, {
|
|
822
|
+
mapping,
|
|
823
|
+
});
|
|
824
|
+
return pine.pineDataService.extractRows(plots, mapping);
|
|
825
|
+
}
|
|
782
826
|
async function extract(plots, mapping) {
|
|
783
|
-
pine.loggerService.info(
|
|
827
|
+
pine.loggerService.info(METHOD_NAME_EXTRACT, {
|
|
784
828
|
mapping,
|
|
785
829
|
});
|
|
786
830
|
return pine.pineDataService.extract(plots, mapping);
|
|
@@ -926,4 +970,4 @@ async function markdown(signalId, source, { symbol, timeframe, limit, inputs = {
|
|
|
926
970
|
return await pine.pineMarkdownService.getReport(signalId, plots, mapping, Number.POSITIVE_INFINITY);
|
|
927
971
|
}
|
|
928
972
|
|
|
929
|
-
export { AXIS_SYMBOL, Code, File, dumpPlotData, extract, getSignal, pine as lib, markdown, run, setLogger, toMarkdown, toSignalDto, useIndicator, usePine };
|
|
973
|
+
export { AXIS_SYMBOL, Code, File, dumpPlotData, extract, extractRows, getSignal, pine as lib, markdown, run, setLogger, toMarkdown, toSignalDto, useIndicator, usePine };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backtest-kit/pinets",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.10.0",
|
|
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",
|
|
@@ -69,12 +69,12 @@
|
|
|
69
69
|
"ts-morph": "27.0.2",
|
|
70
70
|
"tslib": "2.7.0",
|
|
71
71
|
"typedoc": "0.27.9",
|
|
72
|
-
"backtest-kit": "5.
|
|
72
|
+
"backtest-kit": "5.10.0",
|
|
73
73
|
"worker-testbed": "1.0.12"
|
|
74
74
|
},
|
|
75
75
|
"peerDependencies": {
|
|
76
|
-
"backtest-kit": "^5.
|
|
77
|
-
"pinets": "^0.9.
|
|
76
|
+
"backtest-kit": "^5.10.0",
|
|
77
|
+
"pinets": "^0.9.8",
|
|
78
78
|
"typescript": "^5.0.0"
|
|
79
79
|
},
|
|
80
80
|
"dependencies": {
|
package/types.d.ts
CHANGED
|
@@ -74,11 +74,18 @@ type PlotMapping = {
|
|
|
74
74
|
type ExtractedData<M extends PlotMapping> = {
|
|
75
75
|
[K in keyof M]: M[K] extends PlotExtractConfig<infer R> ? R : M[K] extends string ? number : never;
|
|
76
76
|
};
|
|
77
|
+
type ExtractedDataRow<M extends PlotMapping> = {
|
|
78
|
+
[K in keyof M]: M[K] extends PlotExtractConfig<infer R> ? R | null : M[K] extends string ? number | null : never;
|
|
79
|
+
} & {
|
|
80
|
+
timestamp: string;
|
|
81
|
+
};
|
|
77
82
|
declare class PineDataService {
|
|
78
83
|
private readonly loggerService;
|
|
84
|
+
extractRows<M extends PlotMapping>(plots: PlotModel, mapping: M): ExtractedDataRow<M>[];
|
|
79
85
|
extract<M extends PlotMapping>(plots: PlotModel, mapping: M): ExtractedData<M>;
|
|
80
86
|
}
|
|
81
87
|
|
|
88
|
+
declare function extractRows<M extends PlotMapping>(plots: PlotModel, mapping: M): Promise<ExtractedDataRow<M>[]>;
|
|
82
89
|
declare function extract<M extends PlotMapping>(plots: PlotModel, mapping: M): Promise<ExtractedData<M>>;
|
|
83
90
|
|
|
84
91
|
interface ILogger {
|
|
@@ -226,4 +233,4 @@ declare const pine: {
|
|
|
226
233
|
};
|
|
227
234
|
};
|
|
228
235
|
|
|
229
|
-
export { AXIS_SYMBOL, type CandleModel, Code, File, type IIndicator, type ILogger, type IPine, type IProvider, type PlotExtractConfig, type PlotMapping, type PlotModel, type PlotRecord, type SymbolInfoModel, type TIndicatorCtor, type TPineCtor, dumpPlotData, extract, getSignal, pine as lib, markdown, run, setLogger, toMarkdown, toSignalDto, useIndicator, usePine };
|
|
236
|
+
export { AXIS_SYMBOL, type CandleModel, Code, type ExtractedData, type ExtractedDataRow, File, type IIndicator, type ILogger, type IPine, type IProvider, type PlotExtractConfig, type PlotMapping, type PlotModel, type PlotRecord, type SymbolInfoModel, type TIndicatorCtor, type TPineCtor, dumpPlotData, extract, extractRows, getSignal, pine as lib, markdown, run, setLogger, toMarkdown, toSignalDto, useIndicator, usePine };
|