velo-plot 2.0.0 → 2.20.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/dist/{ChartCore-BhQ4j7f5.js → ChartCore-ivzLqxVb.js} +419 -393
- package/dist/ChartCore-ivzLqxVb.js.map +1 -0
- package/dist/{SciPlot-GJvw7GJo.js → SciPlot-CEU4ApgD.js} +2 -2
- package/dist/{SciPlot-GJvw7GJo.js.map → SciPlot-CEU4ApgD.js.map} +1 -1
- package/dist/{axisFormat-SPX-CD5s.js → axisFormat-CzumxpCL.js} +3 -3
- package/dist/axisFormat-CzumxpCL.js.map +1 -0
- package/dist/core/chart/ChartAxisManager.d.ts +2 -0
- package/dist/core/chart/ChartCore.d.ts +15 -0
- package/dist/core/chart/ChartPluginBridge.d.ts +1 -0
- package/dist/core/chart/ChartRenderLoop.d.ts +2 -0
- package/dist/core/chart/ChartStateManager.d.ts +2 -0
- package/dist/core/chart/types.d.ts +5 -0
- package/dist/core/sync/index.d.ts +0 -1
- package/dist/{createStackedChart-DJSmqerD.js → createStackedChart-DxNW0VkF.js} +178 -179
- package/dist/createStackedChart-DxNW0VkF.js.map +1 -0
- package/dist/{index-D7dTq6VB.js → index-BBpJwOct.js} +17 -19
- package/dist/index-BBpJwOct.js.map +1 -0
- package/dist/{index-CUGS98p4.js → index-CaXWSOTk.js} +3 -6
- package/dist/index-CaXWSOTk.js.map +1 -0
- package/dist/{index-CWipqOLP.js → index-qunX30Xu.js} +2 -2
- package/dist/{index-CWipqOLP.js.map → index-qunX30Xu.js.map} +1 -1
- package/dist/{index.core-fpZ1dYN0.js → index.core-COREBDNq.js} +25 -24
- package/dist/{index.core-fpZ1dYN0.js.map → index.core-COREBDNq.js.map} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/{mockDatafeed-Cdg5hKEo.js → mockDatafeed-927foCM4.js} +2 -2
- package/dist/mockDatafeed-927foCM4.js.map +1 -0
- package/dist/plugins/analysis/contours.d.ts +31 -0
- package/dist/plugins/analysis.js +494 -407
- package/dist/plugins/analysis.js.map +1 -1
- package/dist/plugins/broken-axis.js +170 -181
- package/dist/plugins/broken-axis.js.map +1 -1
- package/dist/plugins/forecasting/algorithms.d.ts +7 -2
- package/dist/plugins/forecasting/types.d.ts +13 -3
- package/dist/plugins/forecasting.js +355 -175
- package/dist/plugins/forecasting.js.map +1 -1
- package/dist/plugins/latex/symbols.d.ts +50 -0
- package/dist/plugins/latex/types.d.ts +13 -1
- package/dist/plugins/latex.js +351 -331
- package/dist/plugins/latex.js.map +1 -1
- package/dist/plugins/ml-integration/native-algorithms.d.ts +24 -4
- package/dist/plugins/ml-integration/types.d.ts +19 -0
- package/dist/plugins/ml-integration.js +191 -140
- package/dist/plugins/ml-integration.js.map +1 -1
- package/dist/plugins/pattern-recognition/types.d.ts +28 -1
- package/dist/plugins/pattern-recognition.js +416 -343
- package/dist/plugins/pattern-recognition.js.map +1 -1
- package/dist/plugins/snapshot.js +36 -36
- package/dist/plugins/snapshot.js.map +1 -1
- package/dist/plugins/sync.js +1 -1
- package/dist/plugins/tools.js +1 -1
- package/dist/plugins/virtualization.js +1 -1
- package/dist/react.js +2 -2
- package/dist/symbols-DT0eLlpW.js +568 -0
- package/dist/symbols-DT0eLlpW.js.map +1 -0
- package/dist/trading.js +5 -5
- package/dist/velo-plot.full.js +184 -182
- package/dist/velo-plot.js +3 -3
- package/dist/workers/indicatorsAsync.d.ts +24 -0
- package/package.json +1 -1
- package/dist/ChartCore-BhQ4j7f5.js.map +0 -1
- package/dist/axisFormat-SPX-CD5s.js.map +0 -1
- package/dist/createStackedChart-DJSmqerD.js.map +0 -1
- package/dist/index-CUGS98p4.js.map +0 -1
- package/dist/index-D7dTq6VB.js.map +0 -1
- package/dist/mockDatafeed-Cdg5hKEo.js.map +0 -1
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
function
|
|
2
|
-
const
|
|
3
|
-
for (let
|
|
4
|
-
const
|
|
5
|
-
|
|
1
|
+
function R(o) {
|
|
2
|
+
const n = [], e = [];
|
|
3
|
+
for (let s = 1; s < o.length - 1; s++) {
|
|
4
|
+
const l = o[s - 1], a = o[s], f = o[s + 1];
|
|
5
|
+
a.y > l.y && a.y > f.y ? n.push({ ...a, type: "peak" }) : a.y < l.y && a.y < f.y && e.push({ ...a, type: "valley" });
|
|
6
6
|
}
|
|
7
|
-
return { peaks:
|
|
7
|
+
return { peaks: n, valleys: e };
|
|
8
8
|
}
|
|
9
|
-
function
|
|
10
|
-
return (
|
|
9
|
+
function C(o, n) {
|
|
10
|
+
return (n.y - o.y) / (n.x - o.x);
|
|
11
11
|
}
|
|
12
|
-
function T(
|
|
13
|
-
const
|
|
12
|
+
function T(o) {
|
|
13
|
+
const n = o.map((f) => f.y), e = o.map((f) => f.x), s = Math.max(...n) - Math.min(...n), l = Math.max(...e) - Math.min(...e), a = C(o[0], o[o.length - 1]);
|
|
14
14
|
return {
|
|
15
|
-
height:
|
|
16
|
-
width:
|
|
17
|
-
slope:
|
|
15
|
+
height: s,
|
|
16
|
+
width: l,
|
|
17
|
+
slope: a,
|
|
18
18
|
volumeProfile: {
|
|
19
19
|
increasing: 0.4,
|
|
20
20
|
// Mock values
|
|
21
21
|
decreasing: 0.3,
|
|
22
22
|
neutral: 0.3
|
|
23
23
|
},
|
|
24
|
-
breakoutTarget: Math.max(...
|
|
25
|
-
stopLoss: Math.min(...
|
|
24
|
+
breakoutTarget: Math.max(...n) + s * 0.8,
|
|
25
|
+
stopLoss: Math.min(...n) - s * 0.2
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
-
function
|
|
29
|
-
if (
|
|
28
|
+
function _(o) {
|
|
29
|
+
if (o.length < 5)
|
|
30
30
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Insufficient points for head-shoulders pattern"] };
|
|
31
|
-
const { peaks:
|
|
32
|
-
if (
|
|
31
|
+
const { peaks: n, valleys: e } = R(o);
|
|
32
|
+
if (n.length < 3 || e.length < 2)
|
|
33
33
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Insufficient peaks/valleys"] };
|
|
34
|
-
const
|
|
35
|
-
if (!
|
|
34
|
+
const s = n[0], l = n[1], a = n[2], f = e[0], m = e[1], v = l.y > s.y && l.y > a.y, y = Math.abs(s.y - a.y) / s.y < 0.1, S = f.y < s.y && m.y < a.y;
|
|
35
|
+
if (!v || !y || !S)
|
|
36
36
|
return {
|
|
37
37
|
valid: !1,
|
|
38
38
|
confidence: 0,
|
|
@@ -40,89 +40,89 @@ function D(s) {
|
|
|
40
40
|
keyPoints: [],
|
|
41
41
|
errors: ["Invalid head-shoulders structure"]
|
|
42
42
|
};
|
|
43
|
-
const
|
|
44
|
-
{ start:
|
|
45
|
-
{ start:
|
|
46
|
-
{ start:
|
|
47
|
-
{ start:
|
|
48
|
-
],
|
|
43
|
+
const w = [
|
|
44
|
+
{ start: s, end: f, type: "resistance", strength: 0.8 },
|
|
45
|
+
{ start: f, end: l, type: "support", strength: 0.7 },
|
|
46
|
+
{ start: l, end: m, type: "resistance", strength: 0.8 },
|
|
47
|
+
{ start: m, end: a, type: "support", strength: 0.7 }
|
|
48
|
+
], x = [s, f, l, m, a], M = T(o), k = 1 - Math.abs(s.y - a.y) / l.y, z = 1 - Math.abs(f.y - m.y) / l.y;
|
|
49
49
|
return {
|
|
50
50
|
valid: !0,
|
|
51
|
-
confidence: (
|
|
52
|
-
segments:
|
|
53
|
-
keyPoints:
|
|
51
|
+
confidence: (k + z) / 2,
|
|
52
|
+
segments: w,
|
|
53
|
+
keyPoints: x,
|
|
54
54
|
measurements: M
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
|
-
function
|
|
58
|
-
if (
|
|
57
|
+
function N(o) {
|
|
58
|
+
if (o.length < 4)
|
|
59
59
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Insufficient points for double top"] };
|
|
60
|
-
const { peaks:
|
|
61
|
-
if (
|
|
60
|
+
const { peaks: n, valleys: e } = R(o);
|
|
61
|
+
if (n.length < 2 || e.length < 1)
|
|
62
62
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Insufficient peaks/valleys"] };
|
|
63
|
-
const
|
|
64
|
-
if (!
|
|
63
|
+
const s = n[0], l = n[1], a = e[0], f = Math.abs(s.y - l.y) / s.y < 0.05, m = a.y < s.y && a.y < l.y, v = (s.y - a.y) / s.y > 0.1;
|
|
64
|
+
if (!f || !m || !v)
|
|
65
65
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Invalid double top structure"] };
|
|
66
66
|
const y = [
|
|
67
|
-
{ start:
|
|
68
|
-
{ start:
|
|
69
|
-
{ start:
|
|
70
|
-
],
|
|
67
|
+
{ start: s, end: a, type: "resistance", strength: 0.9 },
|
|
68
|
+
{ start: a, end: l, type: "support", strength: 0.8 },
|
|
69
|
+
{ start: s, end: l, type: "resistance", strength: 0.9 }
|
|
70
|
+
], S = [s, a, l], w = T(o), x = 1 - Math.abs(s.y - l.y) / s.y, M = (s.y - a.y) / s.y;
|
|
71
71
|
return {
|
|
72
72
|
valid: !0,
|
|
73
|
-
confidence: (
|
|
73
|
+
confidence: (x + Math.min(M * 2, 1)) / 2,
|
|
74
74
|
segments: y,
|
|
75
|
-
keyPoints:
|
|
76
|
-
measurements:
|
|
75
|
+
keyPoints: S,
|
|
76
|
+
measurements: w
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
|
-
function
|
|
80
|
-
if (
|
|
79
|
+
function V(o) {
|
|
80
|
+
if (o.length < 4)
|
|
81
81
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Insufficient points for double bottom"] };
|
|
82
|
-
const { peaks:
|
|
83
|
-
if (
|
|
82
|
+
const { peaks: n, valleys: e } = R(o);
|
|
83
|
+
if (e.length < 2 || n.length < 1)
|
|
84
84
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Insufficient peaks/valleys"] };
|
|
85
|
-
const
|
|
86
|
-
if (!
|
|
85
|
+
const s = e[0], l = e[1], a = n[0], f = Math.abs(s.y - l.y) / s.y < 0.05, m = a.y > s.y && a.y > l.y, v = (a.y - s.y) / s.y > 0.1;
|
|
86
|
+
if (!f || !m || !v)
|
|
87
87
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Invalid double bottom structure"] };
|
|
88
88
|
const y = [
|
|
89
|
-
{ start:
|
|
90
|
-
{ start:
|
|
91
|
-
{ start:
|
|
92
|
-
],
|
|
89
|
+
{ start: s, end: a, type: "support", strength: 0.9 },
|
|
90
|
+
{ start: a, end: l, type: "resistance", strength: 0.8 },
|
|
91
|
+
{ start: s, end: l, type: "support", strength: 0.9 }
|
|
92
|
+
], S = [s, a, l], w = T(o), x = 1 - Math.abs(s.y - l.y) / s.y, M = (a.y - s.y) / s.y;
|
|
93
93
|
return {
|
|
94
94
|
valid: !0,
|
|
95
|
-
confidence: (
|
|
95
|
+
confidence: (x + Math.min(M * 2, 1)) / 2,
|
|
96
96
|
segments: y,
|
|
97
|
-
keyPoints:
|
|
98
|
-
measurements:
|
|
97
|
+
keyPoints: S,
|
|
98
|
+
measurements: w
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
|
-
function
|
|
102
|
-
if (
|
|
101
|
+
function q(o) {
|
|
102
|
+
if (o.length < 4)
|
|
103
103
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Insufficient points for ascending triangle"] };
|
|
104
|
-
const
|
|
105
|
-
if (
|
|
104
|
+
const n = o.map((k) => k.y), e = Math.max(...n), s = o.filter((k) => Math.abs(k.y - e) / e < 0.02);
|
|
105
|
+
if (s.length < 2)
|
|
106
106
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Insufficient resistance points"] };
|
|
107
|
-
const
|
|
108
|
-
if (
|
|
107
|
+
const l = o.filter((k, z) => z === 0 || k.y < o[z - 1].y);
|
|
108
|
+
if (l.length < 2)
|
|
109
109
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Insufficient low points"] };
|
|
110
|
-
const
|
|
111
|
-
if (
|
|
110
|
+
const a = l[0], f = l[l.length - 1], m = C(a, f);
|
|
111
|
+
if (m <= 0)
|
|
112
112
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Support not ascending"] };
|
|
113
|
-
const
|
|
114
|
-
{ start:
|
|
115
|
-
{ start:
|
|
116
|
-
], y = [...
|
|
113
|
+
const v = [
|
|
114
|
+
{ start: s[0], end: s[s.length - 1], type: "resistance", strength: 0.8 },
|
|
115
|
+
{ start: a, end: f, type: "support", strength: 0.7 }
|
|
116
|
+
], y = [...s.slice(0, 2), a, f], S = T(o), w = 1 - Math.abs(s[0].y - s[s.length - 1].y) / e, x = Math.min(m / 0.01, 1);
|
|
117
117
|
return {
|
|
118
118
|
valid: !0,
|
|
119
|
-
confidence: (
|
|
120
|
-
segments:
|
|
119
|
+
confidence: (w + x) / 2,
|
|
120
|
+
segments: v,
|
|
121
121
|
keyPoints: y,
|
|
122
|
-
measurements:
|
|
122
|
+
measurements: S
|
|
123
123
|
};
|
|
124
124
|
}
|
|
125
|
-
const
|
|
125
|
+
const A = {
|
|
126
126
|
"head-shoulders": {
|
|
127
127
|
id: "head-shoulders",
|
|
128
128
|
type: "head-shoulders",
|
|
@@ -130,7 +130,7 @@ const B = {
|
|
|
130
130
|
description: "Bearish reversal pattern with three peaks",
|
|
131
131
|
minPoints: 5,
|
|
132
132
|
maxPoints: 7,
|
|
133
|
-
validator:
|
|
133
|
+
validator: _
|
|
134
134
|
},
|
|
135
135
|
"inverse-head-shoulders": {
|
|
136
136
|
id: "inverse-head-shoulders",
|
|
@@ -139,9 +139,9 @@ const B = {
|
|
|
139
139
|
description: "Bullish reversal pattern with three valleys",
|
|
140
140
|
minPoints: 5,
|
|
141
141
|
maxPoints: 7,
|
|
142
|
-
validator: (
|
|
143
|
-
const
|
|
144
|
-
return
|
|
142
|
+
validator: (o) => {
|
|
143
|
+
const n = o.map((s) => ({ ...s, y: -s.y }));
|
|
144
|
+
return _(n);
|
|
145
145
|
}
|
|
146
146
|
},
|
|
147
147
|
"double-top": {
|
|
@@ -151,7 +151,7 @@ const B = {
|
|
|
151
151
|
description: "Bearish reversal pattern with two equal peaks",
|
|
152
152
|
minPoints: 4,
|
|
153
153
|
maxPoints: 6,
|
|
154
|
-
validator:
|
|
154
|
+
validator: N
|
|
155
155
|
},
|
|
156
156
|
"double-bottom": {
|
|
157
157
|
id: "double-bottom",
|
|
@@ -160,7 +160,7 @@ const B = {
|
|
|
160
160
|
description: "Bullish reversal pattern with two equal valleys",
|
|
161
161
|
minPoints: 4,
|
|
162
162
|
maxPoints: 6,
|
|
163
|
-
validator:
|
|
163
|
+
validator: V
|
|
164
164
|
},
|
|
165
165
|
"triple-top": {
|
|
166
166
|
id: "triple-top",
|
|
@@ -169,24 +169,24 @@ const B = {
|
|
|
169
169
|
description: "Bearish reversal pattern with three equal peaks",
|
|
170
170
|
minPoints: 5,
|
|
171
171
|
maxPoints: 7,
|
|
172
|
-
validator: (
|
|
173
|
-
if (
|
|
172
|
+
validator: (o) => {
|
|
173
|
+
if (o.length < 5)
|
|
174
174
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Insufficient points"] };
|
|
175
|
-
const { peaks:
|
|
176
|
-
if (
|
|
175
|
+
const { peaks: n } = R(o);
|
|
176
|
+
if (n.length < 3)
|
|
177
177
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Need at least 3 peaks"] };
|
|
178
|
-
const
|
|
179
|
-
if (!(Math.abs(
|
|
178
|
+
const e = n[0].y, s = n[1].y, l = n[2].y, a = 0.05;
|
|
179
|
+
if (!(Math.abs(e - s) / e < a && Math.abs(s - l) / s < a))
|
|
180
180
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Peaks not equal"] };
|
|
181
|
-
const
|
|
182
|
-
{ start:
|
|
183
|
-
{ start:
|
|
184
|
-
],
|
|
181
|
+
const m = [
|
|
182
|
+
{ start: n[0], end: n[1], type: "resistance", strength: 0.8 },
|
|
183
|
+
{ start: n[1], end: n[2], type: "resistance", strength: 0.8 }
|
|
184
|
+
], v = [n[0], n[1], n[2]], y = T(o);
|
|
185
185
|
return {
|
|
186
186
|
valid: !0,
|
|
187
187
|
confidence: 0.8,
|
|
188
|
-
segments:
|
|
189
|
-
keyPoints:
|
|
188
|
+
segments: m,
|
|
189
|
+
keyPoints: v,
|
|
190
190
|
measurements: y
|
|
191
191
|
};
|
|
192
192
|
}
|
|
@@ -198,9 +198,9 @@ const B = {
|
|
|
198
198
|
description: "Bullish reversal pattern with three equal valleys",
|
|
199
199
|
minPoints: 5,
|
|
200
200
|
maxPoints: 7,
|
|
201
|
-
validator: (
|
|
202
|
-
const
|
|
203
|
-
return
|
|
201
|
+
validator: (o) => {
|
|
202
|
+
const n = o.map((e) => ({ ...e, y: -e.y }));
|
|
203
|
+
return A["triple-top"].validator(n);
|
|
204
204
|
}
|
|
205
205
|
},
|
|
206
206
|
"ascending-triangle": {
|
|
@@ -210,7 +210,7 @@ const B = {
|
|
|
210
210
|
description: "Continuation pattern with horizontal resistance and ascending support",
|
|
211
211
|
minPoints: 4,
|
|
212
212
|
maxPoints: 8,
|
|
213
|
-
validator:
|
|
213
|
+
validator: q
|
|
214
214
|
},
|
|
215
215
|
"descending-triangle": {
|
|
216
216
|
id: "descending-triangle",
|
|
@@ -219,9 +219,9 @@ const B = {
|
|
|
219
219
|
description: "Continuation pattern with horizontal support and descending resistance",
|
|
220
220
|
minPoints: 4,
|
|
221
221
|
maxPoints: 8,
|
|
222
|
-
validator: (
|
|
223
|
-
const
|
|
224
|
-
return
|
|
222
|
+
validator: (o) => {
|
|
223
|
+
const n = o.map((s) => ({ ...s, y: -s.y }));
|
|
224
|
+
return q(n);
|
|
225
225
|
}
|
|
226
226
|
},
|
|
227
227
|
"symmetrical-triangle": {
|
|
@@ -231,22 +231,22 @@ const B = {
|
|
|
231
231
|
description: "Continuation pattern with converging support and resistance",
|
|
232
232
|
minPoints: 4,
|
|
233
233
|
maxPoints: 8,
|
|
234
|
-
validator: (
|
|
235
|
-
if (
|
|
234
|
+
validator: (o) => {
|
|
235
|
+
if (o.length < 4)
|
|
236
236
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Insufficient points"] };
|
|
237
|
-
const
|
|
238
|
-
if (!(
|
|
237
|
+
const n = o.slice(0, Math.floor(o.length / 2)), e = o.slice(Math.floor(o.length / 2)), s = C(n[0], n[n.length - 1]), l = C(e[0], e[e.length - 1]);
|
|
238
|
+
if (!(s > 0 && l < 0 || s < 0 && l > 0))
|
|
239
239
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Lines not converging"] };
|
|
240
|
-
const
|
|
241
|
-
{ start:
|
|
242
|
-
{ start:
|
|
243
|
-
],
|
|
240
|
+
const f = [
|
|
241
|
+
{ start: n[0], end: n[n.length - 1], type: "trendline", strength: 0.7 },
|
|
242
|
+
{ start: e[0], end: e[e.length - 1], type: "trendline", strength: 0.7 }
|
|
243
|
+
], m = [n[0], n[n.length - 1], e[0], e[e.length - 1]], v = T(o);
|
|
244
244
|
return {
|
|
245
245
|
valid: !0,
|
|
246
246
|
confidence: 0.7,
|
|
247
|
-
segments:
|
|
248
|
-
keyPoints:
|
|
249
|
-
measurements:
|
|
247
|
+
segments: f,
|
|
248
|
+
keyPoints: m,
|
|
249
|
+
measurements: v
|
|
250
250
|
};
|
|
251
251
|
}
|
|
252
252
|
},
|
|
@@ -257,25 +257,25 @@ const B = {
|
|
|
257
257
|
description: "Bearish reversal pattern with two converging upward lines",
|
|
258
258
|
minPoints: 4,
|
|
259
259
|
maxPoints: 8,
|
|
260
|
-
validator: (
|
|
261
|
-
if (
|
|
260
|
+
validator: (o) => {
|
|
261
|
+
if (o.length < 4)
|
|
262
262
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Insufficient points"] };
|
|
263
|
-
const { peaks:
|
|
264
|
-
if (
|
|
263
|
+
const { peaks: n, valleys: e } = R(o);
|
|
264
|
+
if (n.length < 2 || e.length < 2)
|
|
265
265
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Insufficient peaks/valleys"] };
|
|
266
|
-
const
|
|
267
|
-
if (!(
|
|
266
|
+
const s = C(n[0], n[n.length - 1]), l = C(e[0], e[e.length - 1]);
|
|
267
|
+
if (!(s > 0 && l > 0 && l > s))
|
|
268
268
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Not a rising wedge pattern"] };
|
|
269
|
-
const
|
|
270
|
-
{ start:
|
|
271
|
-
{ start:
|
|
272
|
-
],
|
|
269
|
+
const f = [
|
|
270
|
+
{ start: n[0], end: n[n.length - 1], type: "resistance", strength: 0.8 },
|
|
271
|
+
{ start: e[0], end: e[e.length - 1], type: "support", strength: 0.8 }
|
|
272
|
+
], m = [n[0], n[n.length - 1], e[0], e[e.length - 1]], v = T(o);
|
|
273
273
|
return {
|
|
274
274
|
valid: !0,
|
|
275
275
|
confidence: 0.75,
|
|
276
|
-
segments:
|
|
277
|
-
keyPoints:
|
|
278
|
-
measurements:
|
|
276
|
+
segments: f,
|
|
277
|
+
keyPoints: m,
|
|
278
|
+
measurements: v
|
|
279
279
|
};
|
|
280
280
|
}
|
|
281
281
|
},
|
|
@@ -286,9 +286,9 @@ const B = {
|
|
|
286
286
|
description: "Bullish reversal pattern with two converging downward lines",
|
|
287
287
|
minPoints: 4,
|
|
288
288
|
maxPoints: 8,
|
|
289
|
-
validator: (
|
|
290
|
-
const
|
|
291
|
-
return
|
|
289
|
+
validator: (o) => {
|
|
290
|
+
const n = o.map((s) => ({ ...s, y: -s.y }));
|
|
291
|
+
return A["rising-wedge"].validator(n);
|
|
292
292
|
}
|
|
293
293
|
},
|
|
294
294
|
rectangle: {
|
|
@@ -298,22 +298,22 @@ const B = {
|
|
|
298
298
|
description: "Continuation pattern with horizontal support and resistance",
|
|
299
299
|
minPoints: 4,
|
|
300
300
|
maxPoints: 10,
|
|
301
|
-
validator: (
|
|
302
|
-
if (
|
|
301
|
+
validator: (o) => {
|
|
302
|
+
if (o.length < 4)
|
|
303
303
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Insufficient points"] };
|
|
304
|
-
const
|
|
305
|
-
if (
|
|
304
|
+
const n = o.map((y) => y.y), e = Math.max(...n), s = Math.min(...n), l = o.filter((y) => Math.abs(y.y - e) / e < 0.05), a = o.filter((y) => Math.abs(y.y - s) / s < 0.05);
|
|
305
|
+
if (l.length < 2 || a.length < 2)
|
|
306
306
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Insufficient horizontal lines"] };
|
|
307
|
-
const
|
|
308
|
-
{ start:
|
|
309
|
-
{ start:
|
|
310
|
-
],
|
|
307
|
+
const f = [
|
|
308
|
+
{ start: l[0], end: l[l.length - 1], type: "resistance", strength: 0.9 },
|
|
309
|
+
{ start: a[0], end: a[a.length - 1], type: "support", strength: 0.9 }
|
|
310
|
+
], m = [l[0], l[l.length - 1], a[0], a[a.length - 1]], v = T(o);
|
|
311
311
|
return {
|
|
312
312
|
valid: !0,
|
|
313
313
|
confidence: 0.8,
|
|
314
|
-
segments:
|
|
315
|
-
keyPoints:
|
|
316
|
-
measurements:
|
|
314
|
+
segments: f,
|
|
315
|
+
keyPoints: m,
|
|
316
|
+
measurements: v
|
|
317
317
|
};
|
|
318
318
|
}
|
|
319
319
|
},
|
|
@@ -324,21 +324,21 @@ const B = {
|
|
|
324
324
|
description: "Short-term continuation pattern after strong move",
|
|
325
325
|
minPoints: 3,
|
|
326
326
|
maxPoints: 6,
|
|
327
|
-
validator: (
|
|
328
|
-
if (
|
|
327
|
+
validator: (o) => {
|
|
328
|
+
if (o.length < 3)
|
|
329
329
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Insufficient points"] };
|
|
330
|
-
const
|
|
331
|
-
if (!(Math.abs(
|
|
330
|
+
const n = C(o[0], o[o.length - 1]);
|
|
331
|
+
if (!(Math.abs(n) < 0.01))
|
|
332
332
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Not horizontal enough"] };
|
|
333
|
-
const
|
|
334
|
-
{ start:
|
|
335
|
-
],
|
|
333
|
+
const s = [
|
|
334
|
+
{ start: o[0], end: o[o.length - 1], type: "trendline", strength: 0.6 }
|
|
335
|
+
], l = [o[0], o[o.length - 1]], a = T(o);
|
|
336
336
|
return {
|
|
337
337
|
valid: !0,
|
|
338
338
|
confidence: 0.6,
|
|
339
|
-
segments:
|
|
340
|
-
keyPoints:
|
|
341
|
-
measurements:
|
|
339
|
+
segments: s,
|
|
340
|
+
keyPoints: l,
|
|
341
|
+
measurements: a
|
|
342
342
|
};
|
|
343
343
|
}
|
|
344
344
|
},
|
|
@@ -349,7 +349,7 @@ const B = {
|
|
|
349
349
|
description: "Short-term continuation pattern with converging lines",
|
|
350
350
|
minPoints: 3,
|
|
351
351
|
maxPoints: 5,
|
|
352
|
-
validator: (
|
|
352
|
+
validator: (o) => A["symmetrical-triangle"].validator(o)
|
|
353
353
|
},
|
|
354
354
|
custom: {
|
|
355
355
|
id: "custom",
|
|
@@ -357,15 +357,15 @@ const B = {
|
|
|
357
357
|
name: "Custom Pattern",
|
|
358
358
|
description: "User-defined pattern",
|
|
359
359
|
minPoints: 3,
|
|
360
|
-
validator: (
|
|
360
|
+
validator: (o) => ({ valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Custom pattern not implemented"] })
|
|
361
361
|
}
|
|
362
|
-
},
|
|
362
|
+
}, F = {
|
|
363
363
|
name: "pattern-recognition",
|
|
364
364
|
version: "1.0.0",
|
|
365
365
|
description: "Technical pattern recognition for financial and scientific data",
|
|
366
366
|
author: "Sci Plot Team",
|
|
367
367
|
provides: ["patterns", "technical-analysis", "chart-patterns"]
|
|
368
|
-
},
|
|
368
|
+
}, H = {
|
|
369
369
|
defaultParameters: {
|
|
370
370
|
minConfidence: 0.7,
|
|
371
371
|
maxPatterns: 10,
|
|
@@ -411,211 +411,284 @@ const B = {
|
|
|
411
411
|
alertTypes: ["head-shoulders", "double-top", "double-bottom"]
|
|
412
412
|
}
|
|
413
413
|
};
|
|
414
|
-
function
|
|
415
|
-
const
|
|
416
|
-
let
|
|
417
|
-
const
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
414
|
+
function O(o = {}) {
|
|
415
|
+
const n = { ...H, ...o };
|
|
416
|
+
let e = null;
|
|
417
|
+
const s = /* @__PURE__ */ new Map(), l = new Map(Object.entries(A)), a = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Set(), m = /* @__PURE__ */ new Map(), v = {
|
|
418
|
+
"head-shoulders": "bearish",
|
|
419
|
+
"inverse-head-shoulders": "bullish",
|
|
420
|
+
"double-top": "bearish",
|
|
421
|
+
"double-bottom": "bullish",
|
|
422
|
+
"triple-top": "bearish",
|
|
423
|
+
"triple-bottom": "bullish",
|
|
424
|
+
"ascending-triangle": "bullish",
|
|
425
|
+
"descending-triangle": "bearish",
|
|
426
|
+
"symmetrical-triangle": "neutral",
|
|
427
|
+
"rising-wedge": "bearish",
|
|
428
|
+
"falling-wedge": "bullish",
|
|
429
|
+
rectangle: "neutral",
|
|
430
|
+
flag: "neutral",
|
|
431
|
+
pennant: "neutral",
|
|
432
|
+
custom: "neutral"
|
|
433
|
+
};
|
|
434
|
+
function y(t, r, c, i, u, d, h) {
|
|
435
|
+
for (let g = i.minPatternSize; g <= Math.min(c.length, i.maxPatternSize); g++) {
|
|
436
|
+
const p = c.slice(Math.max(0, g - i.maxPatternSize), g);
|
|
437
|
+
if (p.length < t.minPoints || t.maxPoints && p.length > t.maxPoints) continue;
|
|
438
|
+
const P = t.validator(p);
|
|
439
|
+
if (P.valid && P.confidence >= i.minConfidence) {
|
|
440
|
+
const $ = {
|
|
441
|
+
pattern: t,
|
|
442
|
+
confidence: P.confidence,
|
|
443
|
+
location: {
|
|
444
|
+
startIndex: Math.max(0, g - i.maxPatternSize),
|
|
445
|
+
endIndex: g,
|
|
446
|
+
startPoint: p[0],
|
|
447
|
+
endPoint: p[p.length - 1]
|
|
448
|
+
},
|
|
449
|
+
validation: P,
|
|
450
|
+
timestamp: Date.now(),
|
|
451
|
+
seriesId: u
|
|
452
|
+
};
|
|
453
|
+
if (!M($, d, i.overlapTolerance) && (d.push($), h[r] = (h[r] || 0) + 1, d.length >= i.maxPatterns))
|
|
454
|
+
return !0;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
return !1;
|
|
458
|
+
}
|
|
459
|
+
function S(t) {
|
|
460
|
+
var c, i;
|
|
461
|
+
const r = v[t.pattern.type] ?? "neutral";
|
|
462
|
+
e == null || e.events.emit("pattern:signal", {
|
|
463
|
+
seriesId: t.seriesId,
|
|
464
|
+
patternType: t.pattern.type,
|
|
465
|
+
patternName: t.pattern.name,
|
|
466
|
+
direction: r,
|
|
467
|
+
confidence: t.confidence,
|
|
468
|
+
price: t.location.endPoint.y,
|
|
469
|
+
x: t.location.endPoint.x,
|
|
470
|
+
target: (c = t.validation.measurements) == null ? void 0 : c.breakoutTarget,
|
|
471
|
+
stopLoss: (i = t.validation.measurements) == null ? void 0 : i.stopLoss,
|
|
472
|
+
timestamp: t.timestamp
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
async function w(t, r, c) {
|
|
476
|
+
const i = { ...n.defaultParameters, ...c }, u = performance.now(), d = [], h = {}, g = x(r, i.sensitivity);
|
|
477
|
+
let p = !1;
|
|
478
|
+
for (const b of i.patternTypes) {
|
|
479
|
+
const I = l.get(b);
|
|
480
|
+
if (I && y(I, b, g, i, t, d, h)) {
|
|
481
|
+
p = !0;
|
|
482
|
+
break;
|
|
447
483
|
}
|
|
448
484
|
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
485
|
+
if (!p && a.size > 0 && i.patternTypes.includes("custom")) {
|
|
486
|
+
for (const [b, I] of a)
|
|
487
|
+
if (y(I, b, g, i, t, d, h))
|
|
488
|
+
break;
|
|
489
|
+
}
|
|
490
|
+
d.sort((b, I) => I.confidence - b.confidence), s.set(t, d);
|
|
491
|
+
const P = performance.now() - u;
|
|
492
|
+
for (const b of d)
|
|
493
|
+
b.confidence >= n.notifications.minAlertConfidence && S(b), b.confidence >= n.notifications.minAlertConfidence && n.notifications.alertTypes.includes(b.pattern.type) && (e == null || e.events.emit("pattern:detected", {
|
|
494
|
+
match: b,
|
|
495
|
+
seriesId: t,
|
|
455
496
|
timestamp: Date.now()
|
|
456
497
|
}));
|
|
457
|
-
const
|
|
458
|
-
matches:
|
|
498
|
+
const $ = {
|
|
499
|
+
matches: d,
|
|
459
500
|
summary: {
|
|
460
|
-
totalPatterns:
|
|
461
|
-
patternsByType:
|
|
462
|
-
averageConfidence:
|
|
501
|
+
totalPatterns: d.length,
|
|
502
|
+
patternsByType: h,
|
|
503
|
+
averageConfidence: d.length > 0 ? d.reduce((b, I) => b + I.confidence, 0) / d.length : 0,
|
|
463
504
|
detectionTime: P
|
|
464
505
|
},
|
|
465
|
-
processedPoints:
|
|
466
|
-
parameters:
|
|
506
|
+
processedPoints: g.length,
|
|
507
|
+
parameters: i
|
|
467
508
|
};
|
|
468
|
-
return
|
|
509
|
+
return e == null || e.log.info(`Pattern detection completed for ${t}: ${d.length} patterns found`), $;
|
|
469
510
|
}
|
|
470
|
-
function
|
|
471
|
-
return
|
|
472
|
-
if (
|
|
473
|
-
const
|
|
474
|
-
return Math.abs(
|
|
511
|
+
function x(t, r) {
|
|
512
|
+
return t.filter((c, i) => {
|
|
513
|
+
if (i === 0 || i === t.length - 1) return !0;
|
|
514
|
+
const u = t[i - 1];
|
|
515
|
+
return Math.abs(c.y - u.y) / u.y >= r * 0.01;
|
|
475
516
|
});
|
|
476
517
|
}
|
|
477
|
-
function
|
|
478
|
-
for (const
|
|
479
|
-
const
|
|
480
|
-
if (
|
|
518
|
+
function M(t, r, c) {
|
|
519
|
+
for (const i of r) {
|
|
520
|
+
const u = Math.max(t.location.startIndex, i.location.startIndex), h = Math.min(t.location.endIndex, i.location.endIndex) - u, g = t.location.endIndex - t.location.startIndex, p = i.location.endIndex - i.location.startIndex;
|
|
521
|
+
if (h / Math.min(g, p) > c)
|
|
481
522
|
return !0;
|
|
482
523
|
}
|
|
483
524
|
return !1;
|
|
484
525
|
}
|
|
485
|
-
function k(
|
|
486
|
-
const
|
|
487
|
-
id:
|
|
526
|
+
function k(t) {
|
|
527
|
+
const r = {
|
|
528
|
+
id: t.id,
|
|
488
529
|
type: "custom",
|
|
489
|
-
name:
|
|
490
|
-
minPoints:
|
|
491
|
-
maxPoints:
|
|
492
|
-
validator: (
|
|
530
|
+
name: t.name,
|
|
531
|
+
minPoints: t.pointSequence.length,
|
|
532
|
+
maxPoints: t.pointSequence.length,
|
|
533
|
+
validator: (c) => L(c, t)
|
|
493
534
|
};
|
|
494
|
-
|
|
535
|
+
a.set(t.id, r), e == null || e.log.info(`Custom pattern registered: ${t.id}`);
|
|
495
536
|
}
|
|
496
|
-
function
|
|
497
|
-
if (
|
|
537
|
+
function z(t, r) {
|
|
538
|
+
if ("pointSequence" in r) {
|
|
539
|
+
k({ ...r, id: t });
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
const c = r;
|
|
543
|
+
if (typeof c.validator != "function") {
|
|
544
|
+
e == null || e.log.error(`Cannot register pattern '${t}': a validator function is required`);
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
const i = {
|
|
548
|
+
id: t,
|
|
549
|
+
type: "custom",
|
|
550
|
+
name: c.name ?? t,
|
|
551
|
+
description: c.description,
|
|
552
|
+
minPoints: c.minPoints ?? 3,
|
|
553
|
+
maxPoints: c.maxPoints,
|
|
554
|
+
validator: c.validator,
|
|
555
|
+
confidenceCalculator: c.confidenceCalculator
|
|
556
|
+
};
|
|
557
|
+
a.set(t, i), e == null || e.log.info(`Custom pattern registered: ${t}`);
|
|
558
|
+
}
|
|
559
|
+
function D(t) {
|
|
560
|
+
const r = a.delete(t);
|
|
561
|
+
return r && (e == null || e.log.info(`Custom pattern removed: ${t}`)), r;
|
|
562
|
+
}
|
|
563
|
+
function L(t, r) {
|
|
564
|
+
if (t.length < r.pointSequence.length)
|
|
498
565
|
return { valid: !1, confidence: 0, segments: [], keyPoints: [], errors: ["Insufficient points"] };
|
|
499
|
-
let
|
|
500
|
-
const
|
|
501
|
-
for (let
|
|
502
|
-
const
|
|
503
|
-
if (
|
|
504
|
-
const
|
|
505
|
-
if (
|
|
506
|
-
const [
|
|
507
|
-
(
|
|
566
|
+
let c = 1;
|
|
567
|
+
const i = [];
|
|
568
|
+
for (let u = 0; u < r.pointSequence.length; u++) {
|
|
569
|
+
const d = r.pointSequence[u], h = t[u];
|
|
570
|
+
if (d.constraints) {
|
|
571
|
+
const g = d.constraints;
|
|
572
|
+
if (g.higherThanPrevious && u > 0 && h.y <= t[u - 1].y && (c *= 0.8, i.push(`Point ${u} not higher than previous`)), g.lowerThanPrevious && u > 0 && h.y >= t[u - 1].y && (c *= 0.8, i.push(`Point ${u} not lower than previous`)), g.withinRange) {
|
|
573
|
+
const [p, P] = g.withinRange;
|
|
574
|
+
(h.y < p || h.y > P) && (c *= 0.7, i.push(`Point ${u} not within range [${p}, ${P}]`));
|
|
508
575
|
}
|
|
509
576
|
}
|
|
510
577
|
}
|
|
511
578
|
return {
|
|
512
|
-
valid:
|
|
513
|
-
confidence:
|
|
579
|
+
valid: c >= 0.5,
|
|
580
|
+
confidence: c,
|
|
514
581
|
segments: [],
|
|
515
|
-
keyPoints:
|
|
516
|
-
errors:
|
|
582
|
+
keyPoints: t,
|
|
583
|
+
errors: i.length > 0 ? i : void 0
|
|
517
584
|
};
|
|
518
585
|
}
|
|
519
|
-
const
|
|
520
|
-
detectPatterns:
|
|
586
|
+
const B = {
|
|
587
|
+
detectPatterns: w,
|
|
521
588
|
registerCustomPattern: k,
|
|
589
|
+
register: z,
|
|
590
|
+
unregister: D,
|
|
591
|
+
onSignal(t) {
|
|
592
|
+
return (e == null ? void 0 : e.events.onPlugin("pattern:signal", (r) => t(r))) ?? (() => {
|
|
593
|
+
});
|
|
594
|
+
},
|
|
522
595
|
getRegisteredPatterns() {
|
|
523
|
-
return
|
|
596
|
+
return [...l.values(), ...a.values()];
|
|
524
597
|
},
|
|
525
|
-
getPatternMatches(
|
|
526
|
-
return
|
|
598
|
+
getPatternMatches(t) {
|
|
599
|
+
return s.get(t) || [];
|
|
527
600
|
},
|
|
528
|
-
clearPatternMatches(
|
|
529
|
-
|
|
601
|
+
clearPatternMatches(t) {
|
|
602
|
+
s.delete(t), e == null || e.log.info(`Pattern matches cleared for series: ${t}`);
|
|
530
603
|
},
|
|
531
|
-
enableRealtimeDetection(
|
|
532
|
-
|
|
533
|
-
const
|
|
534
|
-
if (
|
|
535
|
-
const
|
|
536
|
-
if (
|
|
537
|
-
const
|
|
538
|
-
if (
|
|
539
|
-
const
|
|
540
|
-
x:
|
|
541
|
-
y:
|
|
604
|
+
enableRealtimeDetection(t, r) {
|
|
605
|
+
f.add(t);
|
|
606
|
+
const c = e == null ? void 0 : e.chart;
|
|
607
|
+
if (c) {
|
|
608
|
+
const i = c.getSeries(t);
|
|
609
|
+
if (i) {
|
|
610
|
+
const u = i.getData();
|
|
611
|
+
if (u && u.x.length > 0) {
|
|
612
|
+
const d = Array.from(u.x).map((h, g) => ({
|
|
613
|
+
x: h,
|
|
614
|
+
y: u.y[g]
|
|
542
615
|
}));
|
|
543
|
-
|
|
616
|
+
w(t, d, r);
|
|
544
617
|
}
|
|
545
618
|
}
|
|
546
619
|
}
|
|
547
|
-
|
|
620
|
+
e == null || e.log.info(`Real-time pattern detection enabled for series: ${t}`);
|
|
548
621
|
},
|
|
549
|
-
disableRealtimeDetection(
|
|
550
|
-
|
|
551
|
-
const
|
|
552
|
-
|
|
622
|
+
disableRealtimeDetection(t) {
|
|
623
|
+
f.delete(t);
|
|
624
|
+
const r = m.get(t);
|
|
625
|
+
r && (clearTimeout(r), m.delete(t)), e == null || e.log.info(`Real-time pattern detection disabled for series: ${t}`);
|
|
553
626
|
},
|
|
554
|
-
getStatistics(
|
|
555
|
-
if (
|
|
556
|
-
const
|
|
557
|
-
for (const
|
|
558
|
-
|
|
627
|
+
getStatistics(t) {
|
|
628
|
+
if (t) {
|
|
629
|
+
const r = s.get(t) || [], c = {};
|
|
630
|
+
for (const i of r)
|
|
631
|
+
c[i.pattern.type] = (c[i.pattern.type] || 0) + 1;
|
|
559
632
|
return {
|
|
560
|
-
totalDetections:
|
|
561
|
-
patternsByType:
|
|
562
|
-
averageConfidence:
|
|
563
|
-
detectionRate:
|
|
633
|
+
totalDetections: r.length,
|
|
634
|
+
patternsByType: c,
|
|
635
|
+
averageConfidence: r.length > 0 ? r.reduce((i, u) => i + u.confidence, 0) / r.length : 0,
|
|
636
|
+
detectionRate: r.length / 100
|
|
564
637
|
};
|
|
565
638
|
} else {
|
|
566
|
-
let
|
|
567
|
-
const
|
|
568
|
-
for (const
|
|
569
|
-
|
|
570
|
-
for (const
|
|
571
|
-
d
|
|
639
|
+
let r = 0;
|
|
640
|
+
const c = {}, i = [];
|
|
641
|
+
for (const u of s.values()) {
|
|
642
|
+
r += u.length, i.push(...u.map((d) => d.confidence));
|
|
643
|
+
for (const d of u)
|
|
644
|
+
c[d.pattern.type] = (c[d.pattern.type] || 0) + 1;
|
|
572
645
|
}
|
|
573
646
|
return {
|
|
574
|
-
totalDetections:
|
|
575
|
-
patternsByType:
|
|
576
|
-
averageConfidence:
|
|
577
|
-
detectionRate:
|
|
647
|
+
totalDetections: r,
|
|
648
|
+
patternsByType: c,
|
|
649
|
+
averageConfidence: i.length > 0 ? i.reduce((u, d) => u + d, 0) / i.length : 0,
|
|
650
|
+
detectionRate: r / 100
|
|
578
651
|
};
|
|
579
652
|
}
|
|
580
653
|
},
|
|
581
|
-
updateConfig: (
|
|
582
|
-
Object.assign(
|
|
654
|
+
updateConfig: (t) => {
|
|
655
|
+
Object.assign(n, t);
|
|
583
656
|
},
|
|
584
|
-
getConfig: () => ({ ...
|
|
585
|
-
visualizePatterns(
|
|
586
|
-
const
|
|
587
|
-
if (!
|
|
588
|
-
const
|
|
589
|
-
|
|
590
|
-
for (const
|
|
591
|
-
const
|
|
592
|
-
for (const
|
|
593
|
-
const
|
|
594
|
-
|
|
595
|
-
id:
|
|
657
|
+
getConfig: () => ({ ...n }),
|
|
658
|
+
visualizePatterns(t, r) {
|
|
659
|
+
const c = e == null ? void 0 : e.chart;
|
|
660
|
+
if (!c) return;
|
|
661
|
+
const i = s.get(t) || [], u = r ? i.filter((d) => r.includes(d.pattern.type)) : i;
|
|
662
|
+
B.hidePatterns(t);
|
|
663
|
+
for (const d of u) {
|
|
664
|
+
const h = n.visualization.colorScheme[d.pattern.type] || "#666666";
|
|
665
|
+
for (const g of d.validation.segments) {
|
|
666
|
+
const p = `${t}_pattern_${d.pattern.id}_${d.location.startIndex}`;
|
|
667
|
+
c.addSeries({
|
|
668
|
+
id: p,
|
|
596
669
|
type: "line",
|
|
597
670
|
data: {
|
|
598
|
-
x: new Float32Array([
|
|
599
|
-
y: new Float32Array([
|
|
671
|
+
x: new Float32Array([g.start.x, g.end.x]),
|
|
672
|
+
y: new Float32Array([g.start.y, g.end.y])
|
|
600
673
|
},
|
|
601
674
|
style: {
|
|
602
|
-
color:
|
|
603
|
-
width:
|
|
604
|
-
opacity:
|
|
675
|
+
color: h,
|
|
676
|
+
width: n.visualization.lineWidth,
|
|
677
|
+
opacity: n.visualization.opacity,
|
|
605
678
|
lineDash: [5, 5]
|
|
606
679
|
}
|
|
607
680
|
});
|
|
608
681
|
}
|
|
609
|
-
if (
|
|
610
|
-
const
|
|
611
|
-
|
|
612
|
-
id:
|
|
682
|
+
if (n.visualization.showLabels) {
|
|
683
|
+
const g = `${t}_label_${d.pattern.id}_${d.location.startIndex}`, p = (d.location.startPoint.x + d.location.endPoint.x) / 2, P = (d.location.startPoint.y + d.location.endPoint.y) / 2;
|
|
684
|
+
c.addAnnotation({
|
|
685
|
+
id: g,
|
|
613
686
|
type: "text",
|
|
614
|
-
text:
|
|
615
|
-
x:
|
|
616
|
-
y:
|
|
687
|
+
text: d.pattern.name,
|
|
688
|
+
x: p,
|
|
689
|
+
y: P,
|
|
617
690
|
style: {
|
|
618
|
-
color:
|
|
691
|
+
color: h,
|
|
619
692
|
fontSize: 12,
|
|
620
693
|
backgroundColor: "rgba(255, 255, 255, 0.8)"
|
|
621
694
|
}
|
|
@@ -623,68 +696,68 @@ function F(s = {}) {
|
|
|
623
696
|
}
|
|
624
697
|
}
|
|
625
698
|
},
|
|
626
|
-
hidePatterns(
|
|
627
|
-
const
|
|
628
|
-
if (!
|
|
629
|
-
const
|
|
630
|
-
for (const
|
|
631
|
-
for (let
|
|
632
|
-
const
|
|
633
|
-
|
|
699
|
+
hidePatterns(t) {
|
|
700
|
+
const r = e == null ? void 0 : e.chart;
|
|
701
|
+
if (!r) return;
|
|
702
|
+
const c = s.get(t) || [];
|
|
703
|
+
for (const i of c) {
|
|
704
|
+
for (let d = 0; d < i.validation.segments.length; d++) {
|
|
705
|
+
const h = `${t}_pattern_${i.pattern.id}_${i.location.startIndex}`;
|
|
706
|
+
r.getSeries(h) && r.removeSeries(h);
|
|
634
707
|
}
|
|
635
|
-
const
|
|
636
|
-
|
|
708
|
+
const u = `${t}_label_${i.pattern.id}_${i.location.startIndex}`;
|
|
709
|
+
r.getAnnotation(u) && r.removeAnnotation(u);
|
|
637
710
|
}
|
|
638
711
|
}
|
|
639
712
|
};
|
|
640
|
-
function
|
|
641
|
-
if (!
|
|
642
|
-
const { seriesId:
|
|
643
|
-
if (
|
|
644
|
-
const
|
|
645
|
-
|
|
646
|
-
const
|
|
647
|
-
const
|
|
648
|
-
if (
|
|
649
|
-
const
|
|
650
|
-
if (
|
|
651
|
-
const
|
|
652
|
-
if (
|
|
653
|
-
const
|
|
654
|
-
x:
|
|
655
|
-
y:
|
|
713
|
+
function E(t, r) {
|
|
714
|
+
if (!n.enableRealtime) return;
|
|
715
|
+
const { seriesId: c } = r;
|
|
716
|
+
if (f.has(c)) {
|
|
717
|
+
const i = m.get(c);
|
|
718
|
+
i && clearTimeout(i);
|
|
719
|
+
const u = setTimeout(() => {
|
|
720
|
+
const d = t.chart;
|
|
721
|
+
if (d) {
|
|
722
|
+
const h = d.getSeries(c);
|
|
723
|
+
if (h) {
|
|
724
|
+
const g = h.getData();
|
|
725
|
+
if (g && g.x.length > 0) {
|
|
726
|
+
const p = Array.from(g.x).map((P, $) => ({
|
|
727
|
+
x: P,
|
|
728
|
+
y: g.y[$]
|
|
656
729
|
}));
|
|
657
|
-
|
|
730
|
+
w(c, p), n.visualization.showPatterns && B.visualizePatterns(c);
|
|
658
731
|
}
|
|
659
732
|
}
|
|
660
733
|
}
|
|
661
|
-
},
|
|
662
|
-
|
|
734
|
+
}, n.debounceTime);
|
|
735
|
+
m.set(c, u);
|
|
663
736
|
}
|
|
664
737
|
}
|
|
665
738
|
return {
|
|
666
|
-
manifest:
|
|
667
|
-
onInit(
|
|
668
|
-
if (
|
|
669
|
-
for (const
|
|
670
|
-
k(
|
|
671
|
-
|
|
739
|
+
manifest: F,
|
|
740
|
+
onInit(t) {
|
|
741
|
+
if (e = t, n.customPatterns)
|
|
742
|
+
for (const r of n.customPatterns)
|
|
743
|
+
k(r);
|
|
744
|
+
e.log.info(`Pattern Recognition plugin initialized with ${l.size} patterns`);
|
|
672
745
|
},
|
|
673
|
-
onConfigChange(
|
|
746
|
+
onConfigChange(t, r) {
|
|
674
747
|
},
|
|
675
|
-
onBeforeRender(
|
|
748
|
+
onBeforeRender(t, r) {
|
|
676
749
|
},
|
|
677
|
-
onDataUpdate:
|
|
678
|
-
onDestroy(
|
|
679
|
-
for (const
|
|
680
|
-
clearTimeout(
|
|
681
|
-
|
|
750
|
+
onDataUpdate: E,
|
|
751
|
+
onDestroy(t) {
|
|
752
|
+
for (const r of m.values())
|
|
753
|
+
clearTimeout(r);
|
|
754
|
+
m.clear(), s.clear(), f.clear(), l.clear(), a.clear();
|
|
682
755
|
},
|
|
683
|
-
api:
|
|
756
|
+
api: B
|
|
684
757
|
};
|
|
685
758
|
}
|
|
686
759
|
export {
|
|
687
|
-
|
|
688
|
-
|
|
760
|
+
O as PluginPatternRecognition,
|
|
761
|
+
O as default
|
|
689
762
|
};
|
|
690
763
|
//# sourceMappingURL=pattern-recognition.js.map
|