@tradejs/core 1.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.
Files changed (68) hide show
  1. package/README.md +60 -0
  2. package/dist/api.d.mts +7 -0
  3. package/dist/api.d.ts +7 -0
  4. package/dist/api.js +64 -0
  5. package/dist/api.mjs +39 -0
  6. package/dist/async.d.mts +4 -0
  7. package/dist/async.d.ts +4 -0
  8. package/dist/async.js +48 -0
  9. package/dist/async.mjs +20 -0
  10. package/dist/backtest.d.mts +45 -0
  11. package/dist/backtest.d.ts +45 -0
  12. package/dist/backtest.js +574 -0
  13. package/dist/backtest.mjs +355 -0
  14. package/dist/chunk-AYC2QVKI.mjs +35 -0
  15. package/dist/chunk-JG2QPVAV.mjs +190 -0
  16. package/dist/chunk-LIGD3WWX.mjs +1545 -0
  17. package/dist/chunk-M7QGVZ3J.mjs +61 -0
  18. package/dist/chunk-NQ7D3T4E.mjs +10 -0
  19. package/dist/chunk-PXLXXXLA.mjs +67 -0
  20. package/dist/config.d.mts +14 -0
  21. package/dist/config.d.ts +14 -0
  22. package/dist/config.js +49 -0
  23. package/dist/config.mjs +21 -0
  24. package/dist/constants.d.mts +41 -0
  25. package/dist/constants.d.ts +41 -0
  26. package/dist/constants.js +238 -0
  27. package/dist/constants.mjs +50 -0
  28. package/dist/data.d.mts +9 -0
  29. package/dist/data.d.ts +9 -0
  30. package/dist/data.js +100 -0
  31. package/dist/data.mjs +12 -0
  32. package/dist/figures.d.mts +103 -0
  33. package/dist/figures.d.ts +103 -0
  34. package/dist/figures.js +274 -0
  35. package/dist/figures.mjs +239 -0
  36. package/dist/indicators-x3xKl3_W.d.mts +90 -0
  37. package/dist/indicators-x3xKl3_W.d.ts +90 -0
  38. package/dist/indicators.d.mts +124 -0
  39. package/dist/indicators.d.ts +124 -0
  40. package/dist/indicators.js +1631 -0
  41. package/dist/indicators.mjs +66 -0
  42. package/dist/json.d.mts +3 -0
  43. package/dist/json.d.ts +3 -0
  44. package/dist/json.js +34 -0
  45. package/dist/json.mjs +7 -0
  46. package/dist/math.d.mts +35 -0
  47. package/dist/math.d.ts +35 -0
  48. package/dist/math.js +98 -0
  49. package/dist/math.mjs +38 -0
  50. package/dist/pine.d.mts +29 -0
  51. package/dist/pine.d.ts +29 -0
  52. package/dist/pine.js +59 -0
  53. package/dist/pine.mjs +29 -0
  54. package/dist/strategies.d.mts +104 -0
  55. package/dist/strategies.d.ts +104 -0
  56. package/dist/strategies.js +1080 -0
  57. package/dist/strategies.mjs +390 -0
  58. package/dist/tickers.d.mts +7 -0
  59. package/dist/tickers.d.ts +7 -0
  60. package/dist/tickers.js +166 -0
  61. package/dist/tickers.mjs +125 -0
  62. package/dist/time-DEyFa2vI.d.mts +11 -0
  63. package/dist/time-DEyFa2vI.d.ts +11 -0
  64. package/dist/time.d.mts +2 -0
  65. package/dist/time.d.ts +2 -0
  66. package/dist/time.js +58 -0
  67. package/dist/time.mjs +15 -0
  68. package/package.json +99 -0
package/dist/data.js ADDED
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/data.ts
31
+ var data_exports = {};
32
+ __export(data_exports, {
33
+ cloneArrayValues: () => cloneArrayValues,
34
+ intervalToMs: () => intervalToMs,
35
+ isWrongData: () => isWrongData,
36
+ mergeData: () => mergeData
37
+ });
38
+ module.exports = __toCommonJS(data_exports);
39
+
40
+ // src/utils/array.ts
41
+ var import_lodash = __toESM(require("lodash"));
42
+ var intervalToMs = (interval) => {
43
+ const minutes = {
44
+ "1": 1,
45
+ "3": 3,
46
+ "5": 5,
47
+ "15": 15,
48
+ "30": 30,
49
+ "60": 60,
50
+ "120": 120,
51
+ "240": 240,
52
+ "360": 360,
53
+ "720": 720
54
+ };
55
+ if (interval in minutes) {
56
+ return minutes[interval] * 60 * 1e3;
57
+ }
58
+ switch (interval) {
59
+ case "D":
60
+ return 24 * 60 * 60 * 1e3;
61
+ case "W":
62
+ return 7 * 24 * 60 * 60 * 1e3;
63
+ case "M":
64
+ return 30 * 24 * 60 * 60 * 1e3;
65
+ default:
66
+ throw new Error(`Unknown interval: ${interval}`);
67
+ }
68
+ };
69
+ var mergeData = (a1, a2) => {
70
+ const res = {
71
+ ...import_lodash.default.keyBy(a1, "timestamp"),
72
+ ...import_lodash.default.keyBy(a2, "timestamp")
73
+ };
74
+ return Object.values(res).sort((b1, b2) => b1.timestamp - b2.timestamp);
75
+ };
76
+ var isWrongData = (interval, data) => {
77
+ if (data.length < 2) return false;
78
+ const step = intervalToMs(interval);
79
+ for (let i = 1; i < data.length; i++) {
80
+ const prev = data[i - 1].timestamp;
81
+ const curr = data[i].timestamp;
82
+ if (curr - prev !== step) {
83
+ return true;
84
+ }
85
+ }
86
+ return false;
87
+ };
88
+ var cloneArrayValues = (record) => Object.fromEntries(
89
+ Object.entries(record).map(([key, value]) => [
90
+ key,
91
+ Array.isArray(value) ? value.slice() : value
92
+ ])
93
+ );
94
+ // Annotate the CommonJS export names for ESM import in node:
95
+ 0 && (module.exports = {
96
+ cloneArrayValues,
97
+ intervalToMs,
98
+ isWrongData,
99
+ mergeData
100
+ });
package/dist/data.mjs ADDED
@@ -0,0 +1,12 @@
1
+ import {
2
+ cloneArrayValues,
3
+ intervalToMs,
4
+ isWrongData,
5
+ mergeData
6
+ } from "./chunk-M7QGVZ3J.mjs";
7
+ export {
8
+ cloneArrayValues,
9
+ intervalToMs,
10
+ isWrongData,
11
+ mergeData
12
+ };
@@ -0,0 +1,103 @@
1
+ import { StrategyFigureLine, StrategyFigurePoints, StrategyFigureZone, OrderLogData, StrategyEntryModelFigures, TrendLine, Signal } from '@tradejs/types';
2
+ import { Chart } from 'klinecharts';
3
+
4
+ type MarkerShape = 'RECT' | 'DIAMOND' | 'STAR' | 'CIRCLE' | 'SQUARE' | 'TRIANGLE';
5
+ interface MarkerMeta {
6
+ shape: MarkerShape;
7
+ color: string;
8
+ timestamp: number;
9
+ value: number;
10
+ type: string;
11
+ profit: number;
12
+ amount: number;
13
+ tradeIndex: number;
14
+ }
15
+ interface EntryLineExtendData {
16
+ line: StrategyFigureLine;
17
+ }
18
+ interface EntryPointsExtendData {
19
+ points: StrategyFigurePoints;
20
+ }
21
+ interface EntryZoneExtendData {
22
+ zone: StrategyFigureZone;
23
+ }
24
+
25
+ type Coordinate$2 = {
26
+ x: number;
27
+ y: number;
28
+ };
29
+ type CreatePointFiguresParams$2 = {
30
+ coordinates: Coordinate$2[];
31
+ overlay: {
32
+ extendData?: EntryLineExtendData;
33
+ };
34
+ };
35
+ declare const createEntryLinePointFigure: ({ coordinates, overlay, }: CreatePointFiguresParams$2) => {
36
+ type: string;
37
+ attrs: {
38
+ coordinates: Coordinate$2[];
39
+ };
40
+ styles: {
41
+ color: string;
42
+ size: number;
43
+ style: "solid" | "dashed";
44
+ };
45
+ }[];
46
+
47
+ type Coordinate$1 = {
48
+ x: number;
49
+ y: number;
50
+ };
51
+ type CreatePointFiguresParams$1 = {
52
+ coordinates: Coordinate$1[];
53
+ overlay: {
54
+ extendData?: EntryPointsExtendData;
55
+ };
56
+ };
57
+ declare const createEntryPointsPointFigure: ({ coordinates, overlay, }: CreatePointFiguresParams$1) => any[];
58
+
59
+ type Coordinate = {
60
+ x: number;
61
+ y: number;
62
+ };
63
+ type CreatePointFiguresParams = {
64
+ coordinates: Coordinate[];
65
+ overlay: {
66
+ extendData?: EntryZoneExtendData;
67
+ };
68
+ };
69
+ declare const createEntryZonePointFigure: ({ coordinates, overlay, }: CreatePointFiguresParams) => {
70
+ type: string;
71
+ attrs: {
72
+ x: number;
73
+ y: number;
74
+ width: number;
75
+ height: number;
76
+ };
77
+ styles: {
78
+ color: string;
79
+ borderColor: string;
80
+ size: number;
81
+ };
82
+ }[];
83
+
84
+ type FigureOverlayRef = {
85
+ name: 'BacktestEntryLine' | 'BacktestEntryPoints' | 'BacktestEntryZone';
86
+ id: string;
87
+ };
88
+ declare const ensureBaseFigureOverlaysRegistered: () => void;
89
+ declare const convertTrendLineToFigures: (trendLine: TrendLine) => StrategyEntryModelFigures;
90
+ declare const normalizeSignalFigures: (signal?: Signal | null) => StrategyEntryModelFigures | undefined;
91
+ declare const collectSignalFiguresFromOrderLog: (events: OrderLogData) => Array<{
92
+ figures: StrategyEntryModelFigures;
93
+ signalId?: string;
94
+ index: number;
95
+ }>;
96
+ declare const drawSignalFigures: ({ chart, idPrefix, figures, }: {
97
+ chart: Chart;
98
+ idPrefix: string;
99
+ figures: StrategyEntryModelFigures;
100
+ }) => FigureOverlayRef[];
101
+ declare const removeSignalFigures: (chart: Chart, overlays: FigureOverlayRef[]) => void;
102
+
103
+ export { type EntryLineExtendData, type EntryPointsExtendData, type EntryZoneExtendData, type FigureOverlayRef, type MarkerMeta, type MarkerShape, collectSignalFiguresFromOrderLog, convertTrendLineToFigures, createEntryLinePointFigure, createEntryPointsPointFigure, createEntryZonePointFigure, drawSignalFigures, ensureBaseFigureOverlaysRegistered, normalizeSignalFigures, removeSignalFigures };
@@ -0,0 +1,103 @@
1
+ import { StrategyFigureLine, StrategyFigurePoints, StrategyFigureZone, OrderLogData, StrategyEntryModelFigures, TrendLine, Signal } from '@tradejs/types';
2
+ import { Chart } from 'klinecharts';
3
+
4
+ type MarkerShape = 'RECT' | 'DIAMOND' | 'STAR' | 'CIRCLE' | 'SQUARE' | 'TRIANGLE';
5
+ interface MarkerMeta {
6
+ shape: MarkerShape;
7
+ color: string;
8
+ timestamp: number;
9
+ value: number;
10
+ type: string;
11
+ profit: number;
12
+ amount: number;
13
+ tradeIndex: number;
14
+ }
15
+ interface EntryLineExtendData {
16
+ line: StrategyFigureLine;
17
+ }
18
+ interface EntryPointsExtendData {
19
+ points: StrategyFigurePoints;
20
+ }
21
+ interface EntryZoneExtendData {
22
+ zone: StrategyFigureZone;
23
+ }
24
+
25
+ type Coordinate$2 = {
26
+ x: number;
27
+ y: number;
28
+ };
29
+ type CreatePointFiguresParams$2 = {
30
+ coordinates: Coordinate$2[];
31
+ overlay: {
32
+ extendData?: EntryLineExtendData;
33
+ };
34
+ };
35
+ declare const createEntryLinePointFigure: ({ coordinates, overlay, }: CreatePointFiguresParams$2) => {
36
+ type: string;
37
+ attrs: {
38
+ coordinates: Coordinate$2[];
39
+ };
40
+ styles: {
41
+ color: string;
42
+ size: number;
43
+ style: "solid" | "dashed";
44
+ };
45
+ }[];
46
+
47
+ type Coordinate$1 = {
48
+ x: number;
49
+ y: number;
50
+ };
51
+ type CreatePointFiguresParams$1 = {
52
+ coordinates: Coordinate$1[];
53
+ overlay: {
54
+ extendData?: EntryPointsExtendData;
55
+ };
56
+ };
57
+ declare const createEntryPointsPointFigure: ({ coordinates, overlay, }: CreatePointFiguresParams$1) => any[];
58
+
59
+ type Coordinate = {
60
+ x: number;
61
+ y: number;
62
+ };
63
+ type CreatePointFiguresParams = {
64
+ coordinates: Coordinate[];
65
+ overlay: {
66
+ extendData?: EntryZoneExtendData;
67
+ };
68
+ };
69
+ declare const createEntryZonePointFigure: ({ coordinates, overlay, }: CreatePointFiguresParams) => {
70
+ type: string;
71
+ attrs: {
72
+ x: number;
73
+ y: number;
74
+ width: number;
75
+ height: number;
76
+ };
77
+ styles: {
78
+ color: string;
79
+ borderColor: string;
80
+ size: number;
81
+ };
82
+ }[];
83
+
84
+ type FigureOverlayRef = {
85
+ name: 'BacktestEntryLine' | 'BacktestEntryPoints' | 'BacktestEntryZone';
86
+ id: string;
87
+ };
88
+ declare const ensureBaseFigureOverlaysRegistered: () => void;
89
+ declare const convertTrendLineToFigures: (trendLine: TrendLine) => StrategyEntryModelFigures;
90
+ declare const normalizeSignalFigures: (signal?: Signal | null) => StrategyEntryModelFigures | undefined;
91
+ declare const collectSignalFiguresFromOrderLog: (events: OrderLogData) => Array<{
92
+ figures: StrategyEntryModelFigures;
93
+ signalId?: string;
94
+ index: number;
95
+ }>;
96
+ declare const drawSignalFigures: ({ chart, idPrefix, figures, }: {
97
+ chart: Chart;
98
+ idPrefix: string;
99
+ figures: StrategyEntryModelFigures;
100
+ }) => FigureOverlayRef[];
101
+ declare const removeSignalFigures: (chart: Chart, overlays: FigureOverlayRef[]) => void;
102
+
103
+ export { type EntryLineExtendData, type EntryPointsExtendData, type EntryZoneExtendData, type FigureOverlayRef, type MarkerMeta, type MarkerShape, collectSignalFiguresFromOrderLog, convertTrendLineToFigures, createEntryLinePointFigure, createEntryPointsPointFigure, createEntryZonePointFigure, drawSignalFigures, ensureBaseFigureOverlaysRegistered, normalizeSignalFigures, removeSignalFigures };
@@ -0,0 +1,274 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/figures.ts
21
+ var figures_exports = {};
22
+ __export(figures_exports, {
23
+ collectSignalFiguresFromOrderLog: () => collectSignalFiguresFromOrderLog,
24
+ convertTrendLineToFigures: () => convertTrendLineToFigures,
25
+ createEntryLinePointFigure: () => createEntryLinePointFigure,
26
+ createEntryPointsPointFigure: () => createEntryPointsPointFigure,
27
+ createEntryZonePointFigure: () => createEntryZonePointFigure,
28
+ drawSignalFigures: () => drawSignalFigures,
29
+ ensureBaseFigureOverlaysRegistered: () => ensureBaseFigureOverlaysRegistered,
30
+ normalizeSignalFigures: () => normalizeSignalFigures,
31
+ removeSignalFigures: () => removeSignalFigures
32
+ });
33
+ module.exports = __toCommonJS(figures_exports);
34
+
35
+ // src/utils/figures/entryLinePointFigure.ts
36
+ var createEntryLinePointFigure = ({
37
+ coordinates,
38
+ overlay
39
+ }) => {
40
+ const line = overlay.extendData?.line;
41
+ const color = line?.color ?? "#facc15";
42
+ const size = Number(line?.width ?? 2);
43
+ const style = line?.style ?? "solid";
44
+ if (coordinates.length < 2) {
45
+ return [];
46
+ }
47
+ return [
48
+ {
49
+ type: "line",
50
+ attrs: {
51
+ coordinates: [coordinates[0], coordinates[coordinates.length - 1]]
52
+ },
53
+ styles: { color, size, style }
54
+ }
55
+ ];
56
+ };
57
+
58
+ // src/utils/figures/entryPointsPointFigure.ts
59
+ var createEntryPointsPointFigure = ({
60
+ coordinates,
61
+ overlay
62
+ }) => {
63
+ const points = overlay.extendData?.points;
64
+ const color = points?.color ?? "#ef4444";
65
+ const r = Number(points?.radius ?? 4);
66
+ const figures = [];
67
+ coordinates.forEach(({ x, y }, index) => {
68
+ figures.push({
69
+ type: "circle",
70
+ key: `entry_pt_${index}`,
71
+ attrs: { x, y, r },
72
+ styles: {
73
+ style: "fill",
74
+ color
75
+ },
76
+ ignoreEvent: true
77
+ });
78
+ });
79
+ return figures;
80
+ };
81
+
82
+ // src/utils/figures/entryZonePointFigure.ts
83
+ var createEntryZonePointFigure = ({
84
+ coordinates,
85
+ overlay
86
+ }) => {
87
+ const zone = overlay.extendData?.zone;
88
+ const color = zone?.color ?? "rgba(147,197,253,0.2)";
89
+ const borderColor = zone?.borderColor ?? "rgba(59,130,246,0.6)";
90
+ if (coordinates.length < 2) return [];
91
+ const [p1, p2] = coordinates;
92
+ const x = Math.min(p1.x, p2.x);
93
+ const y = Math.min(p1.y, p2.y);
94
+ const width = Math.abs(p2.x - p1.x);
95
+ const height = Math.abs(p2.y - p1.y);
96
+ return [
97
+ {
98
+ type: "rect",
99
+ attrs: { x, y, width, height },
100
+ styles: { color, borderColor, size: 1 }
101
+ }
102
+ ];
103
+ };
104
+
105
+ // src/utils/figures/signalFiguresPipeline.ts
106
+ var import_klinecharts = require("klinecharts");
107
+ var baseFiguresRegistered = false;
108
+ var ensureBaseFigureOverlaysRegistered = () => {
109
+ if (baseFiguresRegistered) return;
110
+ (0, import_klinecharts.registerOverlay)({
111
+ name: "BacktestEntryLine",
112
+ totalStep: 2,
113
+ needDefaultPointFigure: false,
114
+ needDefaultXAxisFigure: false,
115
+ needDefaultYAxisFigure: false,
116
+ createPointFigures: createEntryLinePointFigure
117
+ });
118
+ (0, import_klinecharts.registerOverlay)({
119
+ name: "BacktestEntryPoints",
120
+ needDefaultPointFigure: true,
121
+ needDefaultXAxisFigure: false,
122
+ needDefaultYAxisFigure: false,
123
+ createPointFigures: createEntryPointsPointFigure
124
+ });
125
+ (0, import_klinecharts.registerOverlay)({
126
+ name: "BacktestEntryZone",
127
+ totalStep: 2,
128
+ needDefaultPointFigure: false,
129
+ needDefaultXAxisFigure: false,
130
+ needDefaultYAxisFigure: false,
131
+ createPointFigures: createEntryZonePointFigure
132
+ });
133
+ baseFiguresRegistered = true;
134
+ };
135
+ var toSortedPoints = (points = []) => [...points].sort((left, right) => left.timestamp - right.timestamp);
136
+ var convertTrendLineToFigures = (trendLine) => ({
137
+ lines: [
138
+ {
139
+ id: trendLine.id,
140
+ kind: "trendline",
141
+ points: toSortedPoints(trendLine.points ?? []),
142
+ color: trendLine.mode === "lows" ? "#facc15" : "#fb923c",
143
+ width: 2,
144
+ style: "solid"
145
+ }
146
+ ],
147
+ points: [
148
+ {
149
+ id: `${trendLine.id}-points`,
150
+ kind: "trendline_points",
151
+ points: toSortedPoints([
152
+ ...trendLine.points ?? [],
153
+ ...trendLine.touches ?? []
154
+ ]),
155
+ color: "#ef4444",
156
+ radius: 4
157
+ }
158
+ ]
159
+ });
160
+ var normalizeSignalFigures = (signal) => {
161
+ const figures = signal?.figures;
162
+ if (!figures) return void 0;
163
+ const lines = [...figures.lines ?? []];
164
+ const points = [...figures.points ?? []];
165
+ const zones = [...figures.zones ?? []];
166
+ let merged = {
167
+ lines,
168
+ points,
169
+ zones
170
+ };
171
+ if (figures.trendLine) {
172
+ const fromTrendLine = convertTrendLineToFigures(figures.trendLine);
173
+ merged = {
174
+ lines: [...merged.lines ?? [], ...fromTrendLine.lines ?? []],
175
+ points: [...merged.points ?? [], ...fromTrendLine.points ?? []],
176
+ zones: [...merged.zones ?? [], ...fromTrendLine.zones ?? []]
177
+ };
178
+ }
179
+ if (!merged.lines?.length && !merged.points?.length && !merged.zones?.length) {
180
+ return void 0;
181
+ }
182
+ return {
183
+ ...merged.lines?.length ? { lines: merged.lines } : {},
184
+ ...merged.points?.length ? { points: merged.points } : {},
185
+ ...merged.zones?.length ? { zones: merged.zones } : {}
186
+ };
187
+ };
188
+ var collectSignalFiguresFromOrderLog = (events) => {
189
+ const result = [];
190
+ const seenSignalIds = /* @__PURE__ */ new Set();
191
+ for (let index = 0; index < events.length; index++) {
192
+ const event = events[index];
193
+ if (!event.type?.startsWith("OPEN_")) continue;
194
+ const signal = event.signal;
195
+ if (!signal) continue;
196
+ const figures = normalizeSignalFigures(signal);
197
+ if (!figures) continue;
198
+ const signalId = signal.signalId;
199
+ if (signalId) {
200
+ if (seenSignalIds.has(signalId)) continue;
201
+ seenSignalIds.add(signalId);
202
+ }
203
+ result.push({ figures, signalId, index });
204
+ }
205
+ return result;
206
+ };
207
+ var drawSignalFigures = ({
208
+ chart,
209
+ idPrefix,
210
+ figures
211
+ }) => {
212
+ const created = [];
213
+ const lines = figures.lines ?? [];
214
+ const points = figures.points ?? [];
215
+ const zones = figures.zones ?? [];
216
+ for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
217
+ const line = lines[lineIndex];
218
+ const linePoints = toSortedPoints(line.points ?? []);
219
+ if (linePoints.length < 2) continue;
220
+ const id = `${idPrefix}-line-${line.id ?? lineIndex}`;
221
+ chart.createOverlay({
222
+ name: "BacktestEntryLine",
223
+ id,
224
+ points: [linePoints[0], linePoints[linePoints.length - 1]],
225
+ zLevel: 10,
226
+ extendData: { line }
227
+ });
228
+ created.push({ name: "BacktestEntryLine", id });
229
+ }
230
+ for (let pointIndex = 0; pointIndex < points.length; pointIndex++) {
231
+ const pointsData = points[pointIndex];
232
+ const pointValues = toSortedPoints(pointsData.points ?? []);
233
+ if (pointValues.length === 0) continue;
234
+ const id = `${idPrefix}-points-${pointsData.id ?? pointIndex}`;
235
+ chart.createOverlay({
236
+ name: "BacktestEntryPoints",
237
+ id,
238
+ points: pointValues,
239
+ zLevel: 12,
240
+ extendData: { points: pointsData }
241
+ });
242
+ created.push({ name: "BacktestEntryPoints", id });
243
+ }
244
+ for (let zoneIndex = 0; zoneIndex < zones.length; zoneIndex++) {
245
+ const zone = zones[zoneIndex];
246
+ const id = `${idPrefix}-zone-${zone.id ?? zoneIndex}`;
247
+ chart.createOverlay({
248
+ name: "BacktestEntryZone",
249
+ id,
250
+ points: [zone.start, zone.end],
251
+ zLevel: 8,
252
+ extendData: { zone }
253
+ });
254
+ created.push({ name: "BacktestEntryZone", id });
255
+ }
256
+ return created;
257
+ };
258
+ var removeSignalFigures = (chart, overlays) => {
259
+ for (const overlay of overlays) {
260
+ chart.removeOverlay({ name: overlay.name, id: overlay.id });
261
+ }
262
+ };
263
+ // Annotate the CommonJS export names for ESM import in node:
264
+ 0 && (module.exports = {
265
+ collectSignalFiguresFromOrderLog,
266
+ convertTrendLineToFigures,
267
+ createEntryLinePointFigure,
268
+ createEntryPointsPointFigure,
269
+ createEntryZonePointFigure,
270
+ drawSignalFigures,
271
+ ensureBaseFigureOverlaysRegistered,
272
+ normalizeSignalFigures,
273
+ removeSignalFigures
274
+ });