@backtest-kit/pinets 0.0.5 → 3.0.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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Run TradingView Pine Script strategies in Node.js self hosted enviroment. Execute your existing Pine Script indicators and generate trading signals - pure technical analysis with 1:1 syntax compatibility.
4
4
 
5
- ![bots](https://raw.githubusercontent.com/tripolskypetr/backtest-kit/HEAD/assets/bots.png)
5
+ ![screenshot](https://raw.githubusercontent.com/tripolskypetr/backtest-kit/HEAD/assets/screenshots/screenshot8.png)
6
6
 
7
7
  [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/tripolskypetr/backtest-kit)
8
8
  [![npm](https://img.shields.io/npm/v/@backtest-kit/pinets.svg?style=flat-square)](https://npmjs.org/package/@backtest-kit/pinets)
@@ -29,7 +29,11 @@ Port your TradingView strategies to backtest-kit with zero rewrite. Powered by [
29
29
  | Function | Description |
30
30
  |----------|-------------|
31
31
  | **`getSignal()`** | Run Pine Script and get structured `ISignalDto` (position, TP/SL, estimated time) |
32
- | **`run()`** | Run Pine Script with custom plot mapping for advanced extraction |
32
+ | **`run()`** | Run Pine Script and return raw plot data |
33
+ | **`extract()`** | Extract values from plots with custom mapping |
34
+ | **`dumpPlotData()`** | Dump plot data to markdown files for debugging |
35
+ | **`usePine()`** | Register custom Pine constructor |
36
+ | **`setLogger()`** | Configure custom logger |
33
37
  | **`File.fromPath()`** | Load Pine Script from `.pine` file |
34
38
  | **`Code.fromString()`** | Use inline Pine Script code |
35
39
 
@@ -141,7 +145,7 @@ const plots = await run(source, {
141
145
  limit: 200,
142
146
  });
143
147
 
144
- const data = extract(plots, {
148
+ const data = await extract(plots, {
145
149
  // Simple: plot name -> number
146
150
  rsi: 'RSI',
147
151
  macd: 'MACD',
@@ -160,6 +164,51 @@ const data = extract(plots, {
160
164
  // data = { rsi: 55.2, macd: 12.5, prevRsi: 52.1, trendStrength: 'strong' }
161
165
  ```
162
166
 
167
+ ### Debug with Plot Dump
168
+
169
+ Dump plot data to markdown files for analysis and debugging:
170
+
171
+ ```typescript
172
+ import { File, run, dumpPlotData } from '@backtest-kit/pinets';
173
+
174
+ const source = File.fromPath('strategy.pine');
175
+
176
+ const plots = await run(source, {
177
+ symbol: 'BTCUSDT',
178
+ timeframe: '1h',
179
+ limit: 100,
180
+ });
181
+
182
+ // Dump plots to ./dump/ta directory
183
+ await dumpPlotData('signal-001', plots, 'ema-cross', './dump/ta');
184
+ ```
185
+
186
+ ### Custom Pine Constructor
187
+
188
+ Register a custom Pine constructor for advanced configurations:
189
+
190
+ ```typescript
191
+ import { usePine } from '@backtest-kit/pinets';
192
+ import { Pine } from 'pinets';
193
+
194
+ // Use custom Pine instance
195
+ usePine(Pine);
196
+ ```
197
+
198
+ ### Custom Logger
199
+
200
+ Configure logging for debugging:
201
+
202
+ ```typescript
203
+ import { setLogger } from '@backtest-kit/pinets';
204
+
205
+ setLogger({
206
+ log: (method, data) => console.log(`[${method}]`, data),
207
+ info: (method, data) => console.info(`[${method}]`, data),
208
+ error: (method, data) => console.error(`[${method}]`, data),
209
+ });
210
+ ```
211
+
163
212
  ## 📜 Pine Script Conventions
164
213
 
165
214
  For `getSignal()` to work, your Pine Script must include these plots:
package/build/index.cjs CHANGED
@@ -690,26 +690,32 @@ function setLogger(logger) {
690
690
  pine.loggerService.setLogger(logger);
691
691
  }
692
692
 
693
- function toSignalDto(data) {
693
+ function toSignalDto(id, data, priceOpen = data.priceOpen) {
694
694
  if (data.position === 1) {
695
- return {
696
- id: functoolsKit.randomString(),
695
+ const result = {
696
+ id: String(id),
697
697
  position: "long",
698
- priceOpen: data.priceOpen,
699
698
  priceTakeProfit: data.priceTakeProfit,
700
699
  priceStopLoss: data.priceStopLoss,
701
700
  minuteEstimatedTime: data.minuteEstimatedTime,
702
701
  };
702
+ if (priceOpen) {
703
+ Object.assign(result, { priceOpen });
704
+ }
705
+ return result;
703
706
  }
704
707
  if (data.position === -1) {
705
- return {
706
- id: functoolsKit.randomString(),
708
+ const result = {
709
+ id: String(id),
707
710
  position: "short",
708
- priceOpen: data.priceOpen,
709
711
  priceTakeProfit: data.priceTakeProfit,
710
712
  priceStopLoss: data.priceStopLoss,
711
713
  minuteEstimatedTime: data.minuteEstimatedTime,
712
714
  };
715
+ if (priceOpen) {
716
+ Object.assign(result, { priceOpen });
717
+ }
718
+ return result;
713
719
  }
714
720
  return null;
715
721
  }
@@ -744,8 +750,9 @@ async function getSignal(source, { symbol, timeframe, limit }) {
744
750
  limit,
745
751
  });
746
752
  const { plots } = await pine.pineJobService.run(await GET_SOURCE_FN(source), symbol, timeframe, limit);
753
+ const resultId = functoolsKit.randomString();
747
754
  const data = pine.pineDataService.extract(plots, SIGNAL_SCHEMA);
748
- return toSignalDto(data);
755
+ return toSignalDto(resultId, data);
749
756
  }
750
757
 
751
758
  const DUMP_SIGNAL_METHOD_NAME = "dump.dumpSignal";
package/build/index.mjs CHANGED
@@ -687,26 +687,32 @@ function setLogger(logger) {
687
687
  pine.loggerService.setLogger(logger);
688
688
  }
689
689
 
690
- function toSignalDto(data) {
690
+ function toSignalDto(id, data, priceOpen = data.priceOpen) {
691
691
  if (data.position === 1) {
692
- return {
693
- id: randomString(),
692
+ const result = {
693
+ id: String(id),
694
694
  position: "long",
695
- priceOpen: data.priceOpen,
696
695
  priceTakeProfit: data.priceTakeProfit,
697
696
  priceStopLoss: data.priceStopLoss,
698
697
  minuteEstimatedTime: data.minuteEstimatedTime,
699
698
  };
699
+ if (priceOpen) {
700
+ Object.assign(result, { priceOpen });
701
+ }
702
+ return result;
700
703
  }
701
704
  if (data.position === -1) {
702
- return {
703
- id: randomString(),
705
+ const result = {
706
+ id: String(id),
704
707
  position: "short",
705
- priceOpen: data.priceOpen,
706
708
  priceTakeProfit: data.priceTakeProfit,
707
709
  priceStopLoss: data.priceStopLoss,
708
710
  minuteEstimatedTime: data.minuteEstimatedTime,
709
711
  };
712
+ if (priceOpen) {
713
+ Object.assign(result, { priceOpen });
714
+ }
715
+ return result;
710
716
  }
711
717
  return null;
712
718
  }
@@ -741,8 +747,9 @@ async function getSignal(source, { symbol, timeframe, limit }) {
741
747
  limit,
742
748
  });
743
749
  const { plots } = await pine.pineJobService.run(await GET_SOURCE_FN(source), symbol, timeframe, limit);
750
+ const resultId = randomString();
744
751
  const data = pine.pineDataService.extract(plots, SIGNAL_SCHEMA);
745
- return toSignalDto(data);
752
+ return toSignalDto(resultId, data);
746
753
  }
747
754
 
748
755
  const DUMP_SIGNAL_METHOD_NAME = "dump.dumpSignal";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backtest-kit/pinets",
3
- "version": "0.0.5",
3
+ "version": "3.0.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",
@@ -72,8 +72,8 @@
72
72
  "worker-testbed": "1.0.12"
73
73
  },
74
74
  "peerDependencies": {
75
- "backtest-kit": "^2.2.1",
76
- "pinets": "^0.8.3",
75
+ "backtest-kit": "^3.0.5",
76
+ "pinets": "^0.8.6",
77
77
  "typescript": "^5.0.0"
78
78
  },
79
79
  "dependencies": {
package/types.d.ts CHANGED
@@ -83,12 +83,13 @@ interface IParams {
83
83
  }
84
84
  declare function getSignal(source: File | Code, { symbol, timeframe, limit }: IParams): Promise<ISignalDto | null>;
85
85
 
86
- type ResultId$1 = string | number;
87
- declare function dumpPlotData(signalId: ResultId$1, plots: PlotModel, taName: string, outputDir?: string): Promise<void>;
86
+ type ResultId$2 = string | number;
87
+ declare function dumpPlotData(signalId: ResultId$2, plots: PlotModel, taName: string, outputDir?: string): Promise<void>;
88
88
 
89
+ type ResultId$1 = string | number;
89
90
  interface SignalData {
90
91
  position: number;
91
- priceOpen: number;
92
+ priceOpen?: number;
92
93
  priceTakeProfit: number;
93
94
  priceStopLoss: number;
94
95
  minuteEstimatedTime: number;
@@ -96,7 +97,7 @@ interface SignalData {
96
97
  interface Signal extends ISignalDto {
97
98
  id: string;
98
99
  }
99
- declare function toSignalDto(data: SignalData): Signal | null;
100
+ declare function toSignalDto(id: ResultId$1, data: SignalData, priceOpen?: number | null | undefined): Signal | null;
100
101
 
101
102
  interface CandleModel {
102
103
  openTime: number;