@tradejs/core 2.0.6 → 2.0.7

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.
@@ -1,4 +1,4 @@
1
- import { StrategyFigureLine, StrategyFigurePoints, StrategyFigureZone, OrderLogData, StrategyEntryModelFigures, TrendLine, Signal } from '@tradejs/types';
1
+ import { StrategyFigureAnnotation, StrategyFigureLine, StrategyFigurePoints, StrategyFigureZone, OrderLogData, StrategyEntryModelFigures, TrendLine, Signal } from '@tradejs/types';
2
2
  import { Chart } from 'klinecharts';
3
3
 
4
4
  type MarkerShape = 'RECT' | 'DIAMOND' | 'STAR' | 'CIRCLE' | 'SQUARE' | 'TRIANGLE';
@@ -21,6 +21,46 @@ interface EntryPointsExtendData {
21
21
  interface EntryZoneExtendData {
22
22
  zone: StrategyFigureZone;
23
23
  }
24
+ interface EntryAnnotationExtendData {
25
+ annotation: StrategyFigureAnnotation;
26
+ }
27
+
28
+ type Coordinate$3 = {
29
+ x: number;
30
+ y: number;
31
+ };
32
+ type CreatePointFiguresParams$3 = {
33
+ coordinates: Coordinate$3[];
34
+ overlay: {
35
+ extendData?: EntryAnnotationExtendData;
36
+ };
37
+ };
38
+ declare const createEntryAnnotationPointFigure: ({ coordinates, overlay, }: CreatePointFiguresParams$3) => {
39
+ type: string;
40
+ key: string;
41
+ attrs: {
42
+ x: number;
43
+ y: number;
44
+ text: string;
45
+ align: string;
46
+ baseline: string;
47
+ };
48
+ styles: {
49
+ style: string;
50
+ color: string;
51
+ size: number;
52
+ weight: number;
53
+ backgroundColor: string;
54
+ borderColor: string;
55
+ borderSize: number;
56
+ borderRadius: number;
57
+ paddingLeft: number;
58
+ paddingRight: number;
59
+ paddingTop: number;
60
+ paddingBottom: number;
61
+ };
62
+ ignoreEvent: boolean;
63
+ }[];
24
64
 
25
65
  type Coordinate$2 = {
26
66
  x: number;
@@ -82,7 +122,7 @@ declare const createEntryZonePointFigure: ({ coordinates, overlay, }: CreatePoin
82
122
  }[];
83
123
 
84
124
  type FigureOverlayRef = {
85
- name: 'BacktestEntryLine' | 'BacktestEntryPoints' | 'BacktestEntryZone';
125
+ name: 'BacktestEntryLine' | 'BacktestEntryPoints' | 'BacktestEntryZone' | 'BacktestEntryAnnotation';
86
126
  id: string;
87
127
  };
88
128
  declare const ensureBaseFigureOverlaysRegistered: () => void;
@@ -100,4 +140,4 @@ declare const drawSignalFigures: ({ chart, idPrefix, figures, }: {
100
140
  }) => FigureOverlayRef[];
101
141
  declare const removeSignalFigures: (chart: Chart, overlays: FigureOverlayRef[]) => void;
102
142
 
103
- export { type EntryLineExtendData, type EntryPointsExtendData, type EntryZoneExtendData, type FigureOverlayRef, type MarkerMeta, type MarkerShape, collectSignalFiguresFromOrderLog, convertTrendLineToFigures, createEntryLinePointFigure, createEntryPointsPointFigure, createEntryZonePointFigure, drawSignalFigures, ensureBaseFigureOverlaysRegistered, normalizeSignalFigures, removeSignalFigures };
143
+ export { type EntryAnnotationExtendData, type EntryLineExtendData, type EntryPointsExtendData, type EntryZoneExtendData, type FigureOverlayRef, type MarkerMeta, type MarkerShape, collectSignalFiguresFromOrderLog, convertTrendLineToFigures, createEntryAnnotationPointFigure, createEntryLinePointFigure, createEntryPointsPointFigure, createEntryZonePointFigure, drawSignalFigures, ensureBaseFigureOverlaysRegistered, normalizeSignalFigures, removeSignalFigures };
package/dist/figures.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { StrategyFigureLine, StrategyFigurePoints, StrategyFigureZone, OrderLogData, StrategyEntryModelFigures, TrendLine, Signal } from '@tradejs/types';
1
+ import { StrategyFigureAnnotation, StrategyFigureLine, StrategyFigurePoints, StrategyFigureZone, OrderLogData, StrategyEntryModelFigures, TrendLine, Signal } from '@tradejs/types';
2
2
  import { Chart } from 'klinecharts';
3
3
 
4
4
  type MarkerShape = 'RECT' | 'DIAMOND' | 'STAR' | 'CIRCLE' | 'SQUARE' | 'TRIANGLE';
@@ -21,6 +21,46 @@ interface EntryPointsExtendData {
21
21
  interface EntryZoneExtendData {
22
22
  zone: StrategyFigureZone;
23
23
  }
24
+ interface EntryAnnotationExtendData {
25
+ annotation: StrategyFigureAnnotation;
26
+ }
27
+
28
+ type Coordinate$3 = {
29
+ x: number;
30
+ y: number;
31
+ };
32
+ type CreatePointFiguresParams$3 = {
33
+ coordinates: Coordinate$3[];
34
+ overlay: {
35
+ extendData?: EntryAnnotationExtendData;
36
+ };
37
+ };
38
+ declare const createEntryAnnotationPointFigure: ({ coordinates, overlay, }: CreatePointFiguresParams$3) => {
39
+ type: string;
40
+ key: string;
41
+ attrs: {
42
+ x: number;
43
+ y: number;
44
+ text: string;
45
+ align: string;
46
+ baseline: string;
47
+ };
48
+ styles: {
49
+ style: string;
50
+ color: string;
51
+ size: number;
52
+ weight: number;
53
+ backgroundColor: string;
54
+ borderColor: string;
55
+ borderSize: number;
56
+ borderRadius: number;
57
+ paddingLeft: number;
58
+ paddingRight: number;
59
+ paddingTop: number;
60
+ paddingBottom: number;
61
+ };
62
+ ignoreEvent: boolean;
63
+ }[];
24
64
 
25
65
  type Coordinate$2 = {
26
66
  x: number;
@@ -82,7 +122,7 @@ declare const createEntryZonePointFigure: ({ coordinates, overlay, }: CreatePoin
82
122
  }[];
83
123
 
84
124
  type FigureOverlayRef = {
85
- name: 'BacktestEntryLine' | 'BacktestEntryPoints' | 'BacktestEntryZone';
125
+ name: 'BacktestEntryLine' | 'BacktestEntryPoints' | 'BacktestEntryZone' | 'BacktestEntryAnnotation';
86
126
  id: string;
87
127
  };
88
128
  declare const ensureBaseFigureOverlaysRegistered: () => void;
@@ -100,4 +140,4 @@ declare const drawSignalFigures: ({ chart, idPrefix, figures, }: {
100
140
  }) => FigureOverlayRef[];
101
141
  declare const removeSignalFigures: (chart: Chart, overlays: FigureOverlayRef[]) => void;
102
142
 
103
- export { type EntryLineExtendData, type EntryPointsExtendData, type EntryZoneExtendData, type FigureOverlayRef, type MarkerMeta, type MarkerShape, collectSignalFiguresFromOrderLog, convertTrendLineToFigures, createEntryLinePointFigure, createEntryPointsPointFigure, createEntryZonePointFigure, drawSignalFigures, ensureBaseFigureOverlaysRegistered, normalizeSignalFigures, removeSignalFigures };
143
+ export { type EntryAnnotationExtendData, type EntryLineExtendData, type EntryPointsExtendData, type EntryZoneExtendData, type FigureOverlayRef, type MarkerMeta, type MarkerShape, collectSignalFiguresFromOrderLog, convertTrendLineToFigures, createEntryAnnotationPointFigure, createEntryLinePointFigure, createEntryPointsPointFigure, createEntryZonePointFigure, drawSignalFigures, ensureBaseFigureOverlaysRegistered, normalizeSignalFigures, removeSignalFigures };
package/dist/figures.js CHANGED
@@ -22,6 +22,7 @@ var figures_exports = {};
22
22
  __export(figures_exports, {
23
23
  collectSignalFiguresFromOrderLog: () => collectSignalFiguresFromOrderLog,
24
24
  convertTrendLineToFigures: () => convertTrendLineToFigures,
25
+ createEntryAnnotationPointFigure: () => createEntryAnnotationPointFigure,
25
26
  createEntryLinePointFigure: () => createEntryLinePointFigure,
26
27
  createEntryPointsPointFigure: () => createEntryPointsPointFigure,
27
28
  createEntryZonePointFigure: () => createEntryZonePointFigure,
@@ -32,6 +33,48 @@ __export(figures_exports, {
32
33
  });
33
34
  module.exports = __toCommonJS(figures_exports);
34
35
 
36
+ // src/utils/figures/entryAnnotationPointFigure.ts
37
+ var LINE_HEIGHT = 19;
38
+ var X_OFFSET = 10;
39
+ var Y_OFFSET = 12;
40
+ var createEntryAnnotationPointFigure = ({
41
+ coordinates,
42
+ overlay
43
+ }) => {
44
+ const annotation = overlay.extendData?.annotation;
45
+ const coordinate = coordinates[0];
46
+ if (!annotation || !coordinate) return [];
47
+ const textLines = [annotation.title, ...annotation.items].filter(
48
+ (text) => text.trim().length > 0
49
+ );
50
+ return textLines.map((text, index) => ({
51
+ type: "text",
52
+ key: `entry_annotation_${index}`,
53
+ attrs: {
54
+ x: coordinate.x - X_OFFSET,
55
+ y: coordinate.y + Y_OFFSET + index * LINE_HEIGHT,
56
+ text,
57
+ align: "right",
58
+ baseline: "top"
59
+ },
60
+ styles: {
61
+ style: "fill",
62
+ color: index === 0 ? annotation.color ?? "#facc15" : annotation.textColor ?? "#f8fafc",
63
+ size: index === 0 ? 12 : 11,
64
+ weight: index === 0 ? 600 : 400,
65
+ backgroundColor: annotation.backgroundColor ?? "rgba(15,23,42,0.88)",
66
+ borderColor: "rgba(148,163,184,0.35)",
67
+ borderSize: 1,
68
+ borderRadius: 4,
69
+ paddingLeft: 6,
70
+ paddingRight: 6,
71
+ paddingTop: 3,
72
+ paddingBottom: 3
73
+ },
74
+ ignoreEvent: true
75
+ }));
76
+ };
77
+
35
78
  // src/utils/figures/entryLinePointFigure.ts
36
79
  var createEntryLinePointFigure = ({
37
80
  coordinates,
@@ -48,7 +91,7 @@ var createEntryLinePointFigure = ({
48
91
  {
49
92
  type: "line",
50
93
  attrs: {
51
- coordinates: [coordinates[0], coordinates[coordinates.length - 1]]
94
+ coordinates
52
95
  },
53
96
  styles: { color, size, style }
54
97
  }
@@ -130,6 +173,13 @@ var ensureBaseFigureOverlaysRegistered = () => {
130
173
  needDefaultYAxisFigure: false,
131
174
  createPointFigures: createEntryZonePointFigure
132
175
  });
176
+ (0, import_klinecharts.registerOverlay)({
177
+ name: "BacktestEntryAnnotation",
178
+ needDefaultPointFigure: false,
179
+ needDefaultXAxisFigure: false,
180
+ needDefaultYAxisFigure: false,
181
+ createPointFigures: createEntryAnnotationPointFigure
182
+ });
133
183
  baseFiguresRegistered = true;
134
184
  };
135
185
  var toSortedPoints = (points = []) => [...points].sort((left, right) => left.timestamp - right.timestamp);
@@ -163,26 +213,35 @@ var normalizeSignalFigures = (signal) => {
163
213
  const lines = [...figures.lines ?? []];
164
214
  const points = [...figures.points ?? []];
165
215
  const zones = [...figures.zones ?? []];
216
+ const annotations = [
217
+ ...figures.annotations ?? []
218
+ ];
166
219
  let merged = {
167
220
  lines,
168
221
  points,
169
- zones
222
+ zones,
223
+ annotations
170
224
  };
171
225
  if (figures.trendLine) {
172
226
  const fromTrendLine = convertTrendLineToFigures(figures.trendLine);
173
227
  merged = {
174
228
  lines: [...merged.lines ?? [], ...fromTrendLine.lines ?? []],
175
229
  points: [...merged.points ?? [], ...fromTrendLine.points ?? []],
176
- zones: [...merged.zones ?? [], ...fromTrendLine.zones ?? []]
230
+ zones: [...merged.zones ?? [], ...fromTrendLine.zones ?? []],
231
+ annotations: [
232
+ ...merged.annotations ?? [],
233
+ ...fromTrendLine.annotations ?? []
234
+ ]
177
235
  };
178
236
  }
179
- if (!merged.lines?.length && !merged.points?.length && !merged.zones?.length) {
237
+ if (!merged.lines?.length && !merged.points?.length && !merged.zones?.length && !merged.annotations?.length) {
180
238
  return void 0;
181
239
  }
182
240
  return {
183
241
  ...merged.lines?.length ? { lines: merged.lines } : {},
184
242
  ...merged.points?.length ? { points: merged.points } : {},
185
- ...merged.zones?.length ? { zones: merged.zones } : {}
243
+ ...merged.zones?.length ? { zones: merged.zones } : {},
244
+ ...merged.annotations?.length ? { annotations: merged.annotations } : {}
186
245
  };
187
246
  };
188
247
  var collectSignalFiguresFromOrderLog = (events) => {
@@ -213,6 +272,7 @@ var drawSignalFigures = ({
213
272
  const lines = figures.lines ?? [];
214
273
  const points = figures.points ?? [];
215
274
  const zones = figures.zones ?? [];
275
+ const annotations = figures.annotations ?? [];
216
276
  for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
217
277
  const line = lines[lineIndex];
218
278
  const linePoints = toSortedPoints(line.points ?? []);
@@ -221,7 +281,7 @@ var drawSignalFigures = ({
221
281
  chart.createOverlay({
222
282
  name: "BacktestEntryLine",
223
283
  id,
224
- points: [linePoints[0], linePoints[linePoints.length - 1]],
284
+ points: linePoints,
225
285
  zLevel: 10,
226
286
  extendData: { line }
227
287
  });
@@ -253,6 +313,21 @@ var drawSignalFigures = ({
253
313
  });
254
314
  created.push({ name: "BacktestEntryZone", id });
255
315
  }
316
+ for (let annotationIndex = 0; annotationIndex < annotations.length; annotationIndex++) {
317
+ const annotation = annotations[annotationIndex];
318
+ if (!Number.isFinite(annotation.point?.timestamp) || !Number.isFinite(annotation.point?.value) || !annotation.title.trim()) {
319
+ continue;
320
+ }
321
+ const id = `${idPrefix}-annotation-${annotation.id ?? annotationIndex}`;
322
+ chart.createOverlay({
323
+ name: "BacktestEntryAnnotation",
324
+ id,
325
+ points: [annotation.point],
326
+ zLevel: 14,
327
+ extendData: { annotation }
328
+ });
329
+ created.push({ name: "BacktestEntryAnnotation", id });
330
+ }
256
331
  return created;
257
332
  };
258
333
  var removeSignalFigures = (chart, overlays) => {
@@ -264,6 +339,7 @@ var removeSignalFigures = (chart, overlays) => {
264
339
  0 && (module.exports = {
265
340
  collectSignalFiguresFromOrderLog,
266
341
  convertTrendLineToFigures,
342
+ createEntryAnnotationPointFigure,
267
343
  createEntryLinePointFigure,
268
344
  createEntryPointsPointFigure,
269
345
  createEntryZonePointFigure,
package/dist/figures.mjs CHANGED
@@ -1,3 +1,45 @@
1
+ // src/utils/figures/entryAnnotationPointFigure.ts
2
+ var LINE_HEIGHT = 19;
3
+ var X_OFFSET = 10;
4
+ var Y_OFFSET = 12;
5
+ var createEntryAnnotationPointFigure = ({
6
+ coordinates,
7
+ overlay
8
+ }) => {
9
+ const annotation = overlay.extendData?.annotation;
10
+ const coordinate = coordinates[0];
11
+ if (!annotation || !coordinate) return [];
12
+ const textLines = [annotation.title, ...annotation.items].filter(
13
+ (text) => text.trim().length > 0
14
+ );
15
+ return textLines.map((text, index) => ({
16
+ type: "text",
17
+ key: `entry_annotation_${index}`,
18
+ attrs: {
19
+ x: coordinate.x - X_OFFSET,
20
+ y: coordinate.y + Y_OFFSET + index * LINE_HEIGHT,
21
+ text,
22
+ align: "right",
23
+ baseline: "top"
24
+ },
25
+ styles: {
26
+ style: "fill",
27
+ color: index === 0 ? annotation.color ?? "#facc15" : annotation.textColor ?? "#f8fafc",
28
+ size: index === 0 ? 12 : 11,
29
+ weight: index === 0 ? 600 : 400,
30
+ backgroundColor: annotation.backgroundColor ?? "rgba(15,23,42,0.88)",
31
+ borderColor: "rgba(148,163,184,0.35)",
32
+ borderSize: 1,
33
+ borderRadius: 4,
34
+ paddingLeft: 6,
35
+ paddingRight: 6,
36
+ paddingTop: 3,
37
+ paddingBottom: 3
38
+ },
39
+ ignoreEvent: true
40
+ }));
41
+ };
42
+
1
43
  // src/utils/figures/entryLinePointFigure.ts
2
44
  var createEntryLinePointFigure = ({
3
45
  coordinates,
@@ -14,7 +56,7 @@ var createEntryLinePointFigure = ({
14
56
  {
15
57
  type: "line",
16
58
  attrs: {
17
- coordinates: [coordinates[0], coordinates[coordinates.length - 1]]
59
+ coordinates
18
60
  },
19
61
  styles: { color, size, style }
20
62
  }
@@ -96,6 +138,13 @@ var ensureBaseFigureOverlaysRegistered = () => {
96
138
  needDefaultYAxisFigure: false,
97
139
  createPointFigures: createEntryZonePointFigure
98
140
  });
141
+ registerOverlay({
142
+ name: "BacktestEntryAnnotation",
143
+ needDefaultPointFigure: false,
144
+ needDefaultXAxisFigure: false,
145
+ needDefaultYAxisFigure: false,
146
+ createPointFigures: createEntryAnnotationPointFigure
147
+ });
99
148
  baseFiguresRegistered = true;
100
149
  };
101
150
  var toSortedPoints = (points = []) => [...points].sort((left, right) => left.timestamp - right.timestamp);
@@ -129,26 +178,35 @@ var normalizeSignalFigures = (signal) => {
129
178
  const lines = [...figures.lines ?? []];
130
179
  const points = [...figures.points ?? []];
131
180
  const zones = [...figures.zones ?? []];
181
+ const annotations = [
182
+ ...figures.annotations ?? []
183
+ ];
132
184
  let merged = {
133
185
  lines,
134
186
  points,
135
- zones
187
+ zones,
188
+ annotations
136
189
  };
137
190
  if (figures.trendLine) {
138
191
  const fromTrendLine = convertTrendLineToFigures(figures.trendLine);
139
192
  merged = {
140
193
  lines: [...merged.lines ?? [], ...fromTrendLine.lines ?? []],
141
194
  points: [...merged.points ?? [], ...fromTrendLine.points ?? []],
142
- zones: [...merged.zones ?? [], ...fromTrendLine.zones ?? []]
195
+ zones: [...merged.zones ?? [], ...fromTrendLine.zones ?? []],
196
+ annotations: [
197
+ ...merged.annotations ?? [],
198
+ ...fromTrendLine.annotations ?? []
199
+ ]
143
200
  };
144
201
  }
145
- if (!merged.lines?.length && !merged.points?.length && !merged.zones?.length) {
202
+ if (!merged.lines?.length && !merged.points?.length && !merged.zones?.length && !merged.annotations?.length) {
146
203
  return void 0;
147
204
  }
148
205
  return {
149
206
  ...merged.lines?.length ? { lines: merged.lines } : {},
150
207
  ...merged.points?.length ? { points: merged.points } : {},
151
- ...merged.zones?.length ? { zones: merged.zones } : {}
208
+ ...merged.zones?.length ? { zones: merged.zones } : {},
209
+ ...merged.annotations?.length ? { annotations: merged.annotations } : {}
152
210
  };
153
211
  };
154
212
  var collectSignalFiguresFromOrderLog = (events) => {
@@ -179,6 +237,7 @@ var drawSignalFigures = ({
179
237
  const lines = figures.lines ?? [];
180
238
  const points = figures.points ?? [];
181
239
  const zones = figures.zones ?? [];
240
+ const annotations = figures.annotations ?? [];
182
241
  for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
183
242
  const line = lines[lineIndex];
184
243
  const linePoints = toSortedPoints(line.points ?? []);
@@ -187,7 +246,7 @@ var drawSignalFigures = ({
187
246
  chart.createOverlay({
188
247
  name: "BacktestEntryLine",
189
248
  id,
190
- points: [linePoints[0], linePoints[linePoints.length - 1]],
249
+ points: linePoints,
191
250
  zLevel: 10,
192
251
  extendData: { line }
193
252
  });
@@ -219,6 +278,21 @@ var drawSignalFigures = ({
219
278
  });
220
279
  created.push({ name: "BacktestEntryZone", id });
221
280
  }
281
+ for (let annotationIndex = 0; annotationIndex < annotations.length; annotationIndex++) {
282
+ const annotation = annotations[annotationIndex];
283
+ if (!Number.isFinite(annotation.point?.timestamp) || !Number.isFinite(annotation.point?.value) || !annotation.title.trim()) {
284
+ continue;
285
+ }
286
+ const id = `${idPrefix}-annotation-${annotation.id ?? annotationIndex}`;
287
+ chart.createOverlay({
288
+ name: "BacktestEntryAnnotation",
289
+ id,
290
+ points: [annotation.point],
291
+ zLevel: 14,
292
+ extendData: { annotation }
293
+ });
294
+ created.push({ name: "BacktestEntryAnnotation", id });
295
+ }
222
296
  return created;
223
297
  };
224
298
  var removeSignalFigures = (chart, overlays) => {
@@ -229,6 +303,7 @@ var removeSignalFigures = (chart, overlays) => {
229
303
  export {
230
304
  collectSignalFiguresFromOrderLog,
231
305
  convertTrendLineToFigures,
306
+ createEntryAnnotationPointFigure,
232
307
  createEntryLinePointFigure,
233
308
  createEntryPointsPointFigure,
234
309
  createEntryZonePointFigure,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tradejs/core",
3
- "version": "2.0.6",
3
+ "version": "2.0.7",
4
4
  "description": "MIT-licensed browser-safe API for TradeJS config, strategy authoring, figures, and shared helpers.",
5
5
  "keywords": [
6
6
  "tradejs",
@@ -100,7 +100,7 @@
100
100
  }
101
101
  },
102
102
  "dependencies": {
103
- "@tradejs/types": "^2.0.6",
103
+ "@tradejs/types": "^2.0.7",
104
104
  "date-fns": "^3.6.0",
105
105
  "fast-technical-indicators": "^1.1.4",
106
106
  "klinecharts": "10.0.0-alpha9",