react-klinecharts-ui 0.3.0 → 0.5.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 +317 -8
- package/dist/{chunk-U325AHHX.js → chunk-DTBNTO4M.js} +8 -19
- package/dist/chunk-DTBNTO4M.js.map +1 -0
- package/dist/{chunk-PIFLJKYF.cjs → chunk-UJNJH3BS.cjs} +8 -19
- package/dist/chunk-UJNJH3BS.cjs.map +1 -0
- package/dist/extensions.cjs +6 -6
- package/dist/extensions.js +1 -1
- package/dist/index.cjs +476 -273
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +198 -33
- package/dist/index.d.ts +198 -33
- package/dist/index.js +432 -229
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
- package/dist/chunk-PIFLJKYF.cjs.map +0 -1
- package/dist/chunk-U325AHHX.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkUJNJH3BS_cjs = require('./chunk-UJNJH3BS.cjs');
|
|
4
4
|
var react = require('react');
|
|
5
5
|
var reactKlinecharts = require('react-klinecharts');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -58,6 +58,16 @@ function reducer(state, action) {
|
|
|
58
58
|
return { ...state, mainIndicators: action.indicators };
|
|
59
59
|
case "SET_SUB_INDICATORS":
|
|
60
60
|
return { ...state, subIndicators: action.indicators };
|
|
61
|
+
case "SET_INDICATOR_AXES":
|
|
62
|
+
return { ...state, indicatorAxes: action.axes };
|
|
63
|
+
case "SET_INDICATOR_VISIBILITY":
|
|
64
|
+
return { ...state, indicatorVisibility: action.visibility };
|
|
65
|
+
case "SET_ALERTS":
|
|
66
|
+
return { ...state, alerts: action.alerts };
|
|
67
|
+
case "SET_MEASURE":
|
|
68
|
+
return { ...state, measure: { ...state.measure, ...action.measure } };
|
|
69
|
+
case "SET_REPLAY":
|
|
70
|
+
return { ...state, replay: { ...state.replay, ...action.replay } };
|
|
61
71
|
case "SET_STYLES":
|
|
62
72
|
return { ...state, styles: action.styles };
|
|
63
73
|
case "SET_LOCALE":
|
|
@@ -120,12 +130,28 @@ function KlinechartsUIProvider({
|
|
|
120
130
|
(acc, name) => ({ ...acc, [name]: "" }),
|
|
121
131
|
{}
|
|
122
132
|
),
|
|
133
|
+
indicatorAxes: {},
|
|
134
|
+
indicatorVisibility: {},
|
|
135
|
+
alerts: [],
|
|
136
|
+
measure: { isActive: false, fromPoint: null, result: null },
|
|
137
|
+
replay: {
|
|
138
|
+
isReplaying: false,
|
|
139
|
+
isPaused: false,
|
|
140
|
+
speed: 1,
|
|
141
|
+
barIndex: 0,
|
|
142
|
+
totalBars: 0
|
|
143
|
+
},
|
|
123
144
|
styles: opts.styles,
|
|
124
145
|
screenshotUrl: null
|
|
125
146
|
})
|
|
126
147
|
);
|
|
127
148
|
const fullscreenContainerRef = react.useRef(null);
|
|
128
149
|
const undoRedoListenerRef = react.useRef(null);
|
|
150
|
+
const alertTriggeredListenerRef = react.useRef(null);
|
|
151
|
+
const replayIntervalRef = react.useRef(null);
|
|
152
|
+
const replaySavedDataRef = react.useRef([]);
|
|
153
|
+
const replayIndexRef = react.useRef(0);
|
|
154
|
+
const alertPrevCloseRef = react.useRef(null);
|
|
129
155
|
const stateRef = react.useRef(state);
|
|
130
156
|
stateRef.current = state;
|
|
131
157
|
const callbacksRef = react.useRef({
|
|
@@ -177,7 +203,7 @@ function KlinechartsUIProvider({
|
|
|
177
203
|
const extraOverlaysRef = react.useRef(extraOverlays);
|
|
178
204
|
react.useEffect(() => {
|
|
179
205
|
if (shouldRegister) {
|
|
180
|
-
|
|
206
|
+
chunkUJNJH3BS_cjs.registerExtensions();
|
|
181
207
|
}
|
|
182
208
|
extraOverlaysRef.current?.forEach((overlay) => reactKlinecharts.registerOverlay(overlay));
|
|
183
209
|
}, [shouldRegister]);
|
|
@@ -186,13 +212,58 @@ function KlinechartsUIProvider({
|
|
|
186
212
|
state.chart.setStyles(state.styles);
|
|
187
213
|
}
|
|
188
214
|
}, [state.chart, state.styles]);
|
|
215
|
+
const hasAlerts = state.alerts.length > 0;
|
|
216
|
+
react.useEffect(() => {
|
|
217
|
+
const chart = state.chart;
|
|
218
|
+
if (!chart || !hasAlerts) return;
|
|
219
|
+
alertPrevCloseRef.current = null;
|
|
220
|
+
const interval = setInterval(() => {
|
|
221
|
+
const dataList = chart.getDataList();
|
|
222
|
+
if (!dataList || dataList.length === 0) return;
|
|
223
|
+
const currentClose = dataList[dataList.length - 1].close;
|
|
224
|
+
const prevClose = alertPrevCloseRef.current;
|
|
225
|
+
alertPrevCloseRef.current = currentClose;
|
|
226
|
+
if (prevClose === null) return;
|
|
227
|
+
const alerts = stateRef.current.alerts;
|
|
228
|
+
let changed = false;
|
|
229
|
+
const next = alerts.map((alert) => {
|
|
230
|
+
if (alert.triggered) return alert;
|
|
231
|
+
const crossedUp = prevClose < alert.price && currentClose >= alert.price;
|
|
232
|
+
const crossedDown = prevClose > alert.price && currentClose <= alert.price;
|
|
233
|
+
const shouldTrigger = alert.condition === "crossing_up" ? crossedUp : alert.condition === "crossing_down" ? crossedDown : crossedUp || crossedDown;
|
|
234
|
+
if (shouldTrigger) {
|
|
235
|
+
changed = true;
|
|
236
|
+
const triggered = { ...alert, triggered: true };
|
|
237
|
+
alertTriggeredListenerRef.current?.(triggered);
|
|
238
|
+
return triggered;
|
|
239
|
+
}
|
|
240
|
+
return alert;
|
|
241
|
+
});
|
|
242
|
+
if (changed) {
|
|
243
|
+
enhancedDispatch({ type: "SET_ALERTS", alerts: next });
|
|
244
|
+
}
|
|
245
|
+
}, 1e3);
|
|
246
|
+
return () => clearInterval(interval);
|
|
247
|
+
}, [state.chart, hasAlerts, enhancedDispatch]);
|
|
248
|
+
react.useEffect(() => {
|
|
249
|
+
return () => {
|
|
250
|
+
if (replayIntervalRef.current !== null) {
|
|
251
|
+
clearInterval(replayIntervalRef.current);
|
|
252
|
+
replayIntervalRef.current = null;
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
}, []);
|
|
189
256
|
const dispatchValue = react.useMemo(
|
|
190
257
|
() => ({
|
|
191
258
|
dispatch: enhancedDispatch,
|
|
192
259
|
datafeed,
|
|
193
260
|
onSettingsChange,
|
|
194
261
|
fullscreenContainerRef,
|
|
195
|
-
undoRedoListenerRef
|
|
262
|
+
undoRedoListenerRef,
|
|
263
|
+
alertTriggeredListenerRef,
|
|
264
|
+
replayIntervalRef,
|
|
265
|
+
replaySavedDataRef,
|
|
266
|
+
replayIndexRef
|
|
196
267
|
}),
|
|
197
268
|
[enhancedDispatch, datafeed, onSettingsChange]
|
|
198
269
|
);
|
|
@@ -654,75 +725,140 @@ function useIndicators() {
|
|
|
654
725
|
const activeNames = state.mainIndicators;
|
|
655
726
|
const inactive = MAIN_INDICATORS.filter((n) => !activeNames.includes(n));
|
|
656
727
|
return [
|
|
657
|
-
...activeNames.map((name) => ({
|
|
658
|
-
|
|
728
|
+
...activeNames.map((name) => ({
|
|
729
|
+
name,
|
|
730
|
+
isActive: true,
|
|
731
|
+
visible: state.indicatorVisibility[`main_${name}`] ?? true
|
|
732
|
+
})),
|
|
733
|
+
...inactive.map((name) => ({ name, isActive: false, visible: true }))
|
|
659
734
|
];
|
|
660
|
-
}, [state.mainIndicators]);
|
|
735
|
+
}, [state.mainIndicators, state.indicatorVisibility]);
|
|
661
736
|
const subIndicators = react.useMemo(() => {
|
|
662
737
|
const activeNames = Object.keys(state.subIndicators);
|
|
663
738
|
const inactive = SUB_INDICATORS.filter((n) => !activeNames.includes(n));
|
|
664
739
|
return [
|
|
665
|
-
...activeNames.map((name) => ({
|
|
666
|
-
|
|
740
|
+
...activeNames.map((name) => ({
|
|
741
|
+
name,
|
|
742
|
+
isActive: true,
|
|
743
|
+
visible: state.indicatorVisibility[`sub_${name}`] ?? true
|
|
744
|
+
})),
|
|
745
|
+
...inactive.map((name) => ({ name, isActive: false, visible: true }))
|
|
667
746
|
];
|
|
668
|
-
}, [state.subIndicators]);
|
|
747
|
+
}, [state.subIndicators, state.indicatorVisibility]);
|
|
669
748
|
const addMainIndicator = react.useCallback(
|
|
670
|
-
(name) => {
|
|
749
|
+
(name, options) => {
|
|
671
750
|
if (state.mainIndicators.includes(name)) return;
|
|
751
|
+
const yAxis = options?.yAxis;
|
|
672
752
|
state.chart?.createIndicator(
|
|
673
|
-
{ name, id: `main_${name}
|
|
674
|
-
true,
|
|
675
|
-
{ id: "candle_pane" }
|
|
753
|
+
{ name, id: `main_${name}` },
|
|
754
|
+
{ isStack: true, pane: { id: "candle_pane" }, yAxis }
|
|
676
755
|
);
|
|
677
756
|
const newIndicators = [...state.mainIndicators, name];
|
|
678
757
|
dispatch({ type: "SET_MAIN_INDICATORS", indicators: newIndicators });
|
|
758
|
+
if (yAxis?.id) {
|
|
759
|
+
dispatch({
|
|
760
|
+
type: "SET_INDICATOR_AXES",
|
|
761
|
+
axes: { ...state.indicatorAxes, [`main_${name}`]: yAxis.id }
|
|
762
|
+
});
|
|
763
|
+
}
|
|
679
764
|
undoRedoListenerRef.current?.({
|
|
680
765
|
type: "indicator_toggled",
|
|
681
|
-
data: {
|
|
766
|
+
data: {
|
|
767
|
+
name,
|
|
768
|
+
wasActive: false,
|
|
769
|
+
isMain: true,
|
|
770
|
+
paneId: "candle_pane",
|
|
771
|
+
yAxisId: yAxis?.id
|
|
772
|
+
}
|
|
682
773
|
});
|
|
683
774
|
},
|
|
684
|
-
[state.chart, state.mainIndicators, dispatch, undoRedoListenerRef]
|
|
775
|
+
[state.chart, state.mainIndicators, state.indicatorAxes, dispatch, undoRedoListenerRef]
|
|
685
776
|
);
|
|
686
777
|
const removeMainIndicator = react.useCallback(
|
|
687
778
|
(name) => {
|
|
688
|
-
|
|
779
|
+
const id = `main_${name}`;
|
|
780
|
+
const yAxisId = state.indicatorAxes[id];
|
|
781
|
+
state.chart?.removeIndicator({ id });
|
|
689
782
|
const newIndicators = state.mainIndicators.filter((n) => n !== name);
|
|
690
783
|
dispatch({ type: "SET_MAIN_INDICATORS", indicators: newIndicators });
|
|
784
|
+
if (yAxisId) {
|
|
785
|
+
const nextAxes = { ...state.indicatorAxes };
|
|
786
|
+
delete nextAxes[id];
|
|
787
|
+
dispatch({ type: "SET_INDICATOR_AXES", axes: nextAxes });
|
|
788
|
+
}
|
|
789
|
+
if (id in state.indicatorVisibility) {
|
|
790
|
+
const nextVisibility = { ...state.indicatorVisibility };
|
|
791
|
+
delete nextVisibility[id];
|
|
792
|
+
dispatch({ type: "SET_INDICATOR_VISIBILITY", visibility: nextVisibility });
|
|
793
|
+
}
|
|
691
794
|
undoRedoListenerRef.current?.({
|
|
692
795
|
type: "indicator_toggled",
|
|
693
|
-
data: { name, wasActive: true, isMain: true, paneId: "candle_pane" }
|
|
796
|
+
data: { name, wasActive: true, isMain: true, paneId: "candle_pane", yAxisId }
|
|
694
797
|
});
|
|
695
798
|
},
|
|
696
|
-
[
|
|
799
|
+
[
|
|
800
|
+
state.chart,
|
|
801
|
+
state.mainIndicators,
|
|
802
|
+
state.indicatorAxes,
|
|
803
|
+
state.indicatorVisibility,
|
|
804
|
+
dispatch,
|
|
805
|
+
undoRedoListenerRef
|
|
806
|
+
]
|
|
697
807
|
);
|
|
698
808
|
const addSubIndicator = react.useCallback(
|
|
699
|
-
(name) => {
|
|
809
|
+
(name, options) => {
|
|
700
810
|
if (name in state.subIndicators) return;
|
|
701
811
|
const id = `sub_${name}`;
|
|
702
|
-
|
|
812
|
+
const yAxis = options?.yAxis;
|
|
813
|
+
state.chart?.createIndicator({ name, id }, { yAxis });
|
|
703
814
|
const paneId = state.chart?.getIndicators({ id })?.[0]?.paneId ?? "";
|
|
704
815
|
const newIndicators = { ...state.subIndicators, [name]: paneId };
|
|
705
816
|
dispatch({ type: "SET_SUB_INDICATORS", indicators: newIndicators });
|
|
817
|
+
if (yAxis?.id) {
|
|
818
|
+
dispatch({
|
|
819
|
+
type: "SET_INDICATOR_AXES",
|
|
820
|
+
axes: { ...state.indicatorAxes, [id]: yAxis.id }
|
|
821
|
+
});
|
|
822
|
+
}
|
|
706
823
|
undoRedoListenerRef.current?.({
|
|
707
824
|
type: "indicator_toggled",
|
|
708
|
-
data: { name, wasActive: false, isMain: false, paneId }
|
|
825
|
+
data: { name, wasActive: false, isMain: false, paneId, yAxisId: yAxis?.id }
|
|
709
826
|
});
|
|
710
827
|
},
|
|
711
|
-
[state.chart, state.subIndicators, dispatch, undoRedoListenerRef]
|
|
828
|
+
[state.chart, state.subIndicators, state.indicatorAxes, dispatch, undoRedoListenerRef]
|
|
712
829
|
);
|
|
713
830
|
const removeSubIndicator = react.useCallback(
|
|
714
831
|
(name) => {
|
|
832
|
+
const id = `sub_${name}`;
|
|
715
833
|
const paneId = state.subIndicators[name] ?? "";
|
|
716
|
-
state.
|
|
834
|
+
const yAxisId = state.indicatorAxes[id];
|
|
835
|
+
state.chart?.removeIndicator({ id });
|
|
717
836
|
const newIndicators = { ...state.subIndicators };
|
|
718
837
|
delete newIndicators[name];
|
|
719
838
|
dispatch({ type: "SET_SUB_INDICATORS", indicators: newIndicators });
|
|
839
|
+
if (yAxisId) {
|
|
840
|
+
const nextAxes = { ...state.indicatorAxes };
|
|
841
|
+
delete nextAxes[id];
|
|
842
|
+
dispatch({ type: "SET_INDICATOR_AXES", axes: nextAxes });
|
|
843
|
+
}
|
|
844
|
+
if (id in state.indicatorVisibility) {
|
|
845
|
+
const nextVisibility = { ...state.indicatorVisibility };
|
|
846
|
+
delete nextVisibility[id];
|
|
847
|
+
dispatch({ type: "SET_INDICATOR_VISIBILITY", visibility: nextVisibility });
|
|
848
|
+
}
|
|
720
849
|
undoRedoListenerRef.current?.({
|
|
721
850
|
type: "indicator_toggled",
|
|
722
|
-
data: { name, wasActive: true, isMain: false, paneId }
|
|
851
|
+
data: { name, wasActive: true, isMain: false, paneId, yAxisId }
|
|
723
852
|
});
|
|
724
853
|
},
|
|
725
|
-
[
|
|
854
|
+
[
|
|
855
|
+
state.chart,
|
|
856
|
+
state.subIndicators,
|
|
857
|
+
state.indicatorAxes,
|
|
858
|
+
state.indicatorVisibility,
|
|
859
|
+
dispatch,
|
|
860
|
+
undoRedoListenerRef
|
|
861
|
+
]
|
|
726
862
|
);
|
|
727
863
|
const toggleMainIndicator = react.useCallback(
|
|
728
864
|
(name) => {
|
|
@@ -748,12 +884,22 @@ function useIndicators() {
|
|
|
748
884
|
(name, isMain, visible) => {
|
|
749
885
|
const id = isMain ? `main_${name}` : `sub_${name}`;
|
|
750
886
|
state.chart?.overrideIndicator({ name, id, visible });
|
|
887
|
+
const nextVisibility = { ...state.indicatorVisibility };
|
|
888
|
+
if (visible) delete nextVisibility[id];
|
|
889
|
+
else nextVisibility[id] = false;
|
|
890
|
+
dispatch({ type: "SET_INDICATOR_VISIBILITY", visibility: nextVisibility });
|
|
751
891
|
},
|
|
752
|
-
[state.chart]
|
|
892
|
+
[state.chart, state.indicatorVisibility, dispatch]
|
|
893
|
+
);
|
|
894
|
+
const isIndicatorVisible = react.useCallback(
|
|
895
|
+
(name, isMain) => state.indicatorVisibility[isMain ? `main_${name}` : `sub_${name}`] ?? true,
|
|
896
|
+
[state.indicatorVisibility]
|
|
753
897
|
);
|
|
754
898
|
const updateIndicatorParams = react.useCallback(
|
|
755
|
-
|
|
756
|
-
|
|
899
|
+
// `paneId` is kept in the signature for API stability; klinecharts v10
|
|
900
|
+
// `overrideIndicator` no longer accepts it and targets by name/id instead.
|
|
901
|
+
(name, _paneId, params) => {
|
|
902
|
+
state.chart?.overrideIndicator({ name, calcParams: params });
|
|
757
903
|
},
|
|
758
904
|
[state.chart]
|
|
759
905
|
);
|
|
@@ -774,11 +920,9 @@ function useIndicators() {
|
|
|
774
920
|
{
|
|
775
921
|
name,
|
|
776
922
|
id: `main_${name}`,
|
|
777
|
-
paneId: "candle_pane",
|
|
778
923
|
...prevCalcParams ? { calcParams: prevCalcParams } : {}
|
|
779
924
|
},
|
|
780
|
-
true,
|
|
781
|
-
{ id: "candle_pane" }
|
|
925
|
+
{ isStack: true, pane: { id: "candle_pane" } }
|
|
782
926
|
);
|
|
783
927
|
const newSub = { ...state.subIndicators };
|
|
784
928
|
delete newSub[name];
|
|
@@ -832,9 +976,14 @@ function useIndicators() {
|
|
|
832
976
|
id: paneId,
|
|
833
977
|
height: COLLAPSED_HEIGHT
|
|
834
978
|
});
|
|
835
|
-
|
|
979
|
+
const id = `sub_${name}`;
|
|
980
|
+
state.chart.overrideIndicator({ name, id, visible: false });
|
|
981
|
+
dispatch({
|
|
982
|
+
type: "SET_INDICATOR_VISIBILITY",
|
|
983
|
+
visibility: { ...state.indicatorVisibility, [id]: false }
|
|
984
|
+
});
|
|
836
985
|
},
|
|
837
|
-
[state.chart, state.subIndicators]
|
|
986
|
+
[state.chart, state.subIndicators, state.indicatorVisibility, dispatch]
|
|
838
987
|
);
|
|
839
988
|
const expandSubIndicator = react.useCallback(
|
|
840
989
|
(name) => {
|
|
@@ -846,9 +995,13 @@ function useIndicators() {
|
|
|
846
995
|
id: paneId,
|
|
847
996
|
height: savedHeight
|
|
848
997
|
});
|
|
849
|
-
|
|
998
|
+
const id = `sub_${name}`;
|
|
999
|
+
state.chart.overrideIndicator({ name, id, visible: true });
|
|
1000
|
+
const nextVisibility = { ...state.indicatorVisibility };
|
|
1001
|
+
delete nextVisibility[id];
|
|
1002
|
+
dispatch({ type: "SET_INDICATOR_VISIBILITY", visibility: nextVisibility });
|
|
850
1003
|
},
|
|
851
|
-
[state.chart, state.subIndicators]
|
|
1004
|
+
[state.chart, state.subIndicators, state.indicatorVisibility, dispatch]
|
|
852
1005
|
);
|
|
853
1006
|
const isSubIndicatorCollapsed = react.useCallback(
|
|
854
1007
|
(name) => {
|
|
@@ -894,7 +1047,7 @@ function useIndicators() {
|
|
|
894
1047
|
if (sub.styles) {
|
|
895
1048
|
state.chart.overrideIndicator({
|
|
896
1049
|
name: sub.name,
|
|
897
|
-
|
|
1050
|
+
id,
|
|
898
1051
|
styles: sub.styles
|
|
899
1052
|
});
|
|
900
1053
|
}
|
|
@@ -903,6 +1056,44 @@ function useIndicators() {
|
|
|
903
1056
|
},
|
|
904
1057
|
[state.chart, state.subIndicators, dispatch]
|
|
905
1058
|
);
|
|
1059
|
+
const getIndicatorAxis = react.useCallback(
|
|
1060
|
+
(name, isMain) => state.indicatorAxes[isMain ? `main_${name}` : `sub_${name}`],
|
|
1061
|
+
[state.indicatorAxes]
|
|
1062
|
+
);
|
|
1063
|
+
const bindIndicatorToNewAxis = react.useCallback(
|
|
1064
|
+
(name, isMain, yAxis) => {
|
|
1065
|
+
if (!state.chart) return;
|
|
1066
|
+
const id = isMain ? `main_${name}` : `sub_${name}`;
|
|
1067
|
+
const current = state.chart.getIndicators({ id })?.[0];
|
|
1068
|
+
if (!current) return;
|
|
1069
|
+
const calcParams = current.calcParams;
|
|
1070
|
+
const styles = current.styles;
|
|
1071
|
+
const visible = current.visible ?? true;
|
|
1072
|
+
const paneId = isMain ? "candle_pane" : current.paneId ?? state.subIndicators[name] ?? "";
|
|
1073
|
+
state.chart.removeIndicator({ id });
|
|
1074
|
+
state.chart.createIndicator(
|
|
1075
|
+
{
|
|
1076
|
+
name,
|
|
1077
|
+
id,
|
|
1078
|
+
...calcParams ? { calcParams } : {},
|
|
1079
|
+
visible
|
|
1080
|
+
},
|
|
1081
|
+
{
|
|
1082
|
+
isStack: isMain,
|
|
1083
|
+
...paneId ? { pane: { id: paneId } } : {},
|
|
1084
|
+
yAxis
|
|
1085
|
+
}
|
|
1086
|
+
);
|
|
1087
|
+
if (styles) {
|
|
1088
|
+
state.chart.overrideIndicator({ name, id, styles });
|
|
1089
|
+
}
|
|
1090
|
+
const nextAxes = { ...state.indicatorAxes };
|
|
1091
|
+
if (yAxis?.id) nextAxes[id] = yAxis.id;
|
|
1092
|
+
else delete nextAxes[id];
|
|
1093
|
+
dispatch({ type: "SET_INDICATOR_AXES", axes: nextAxes });
|
|
1094
|
+
},
|
|
1095
|
+
[state.chart, state.indicatorAxes, state.subIndicators, dispatch]
|
|
1096
|
+
);
|
|
906
1097
|
return {
|
|
907
1098
|
mainIndicators,
|
|
908
1099
|
subIndicators,
|
|
@@ -919,6 +1110,7 @@ function useIndicators() {
|
|
|
919
1110
|
moveToMain,
|
|
920
1111
|
moveToSub,
|
|
921
1112
|
setIndicatorVisible,
|
|
1113
|
+
isIndicatorVisible,
|
|
922
1114
|
updateIndicatorParams,
|
|
923
1115
|
getIndicatorParams,
|
|
924
1116
|
isMainIndicatorActive,
|
|
@@ -926,7 +1118,11 @@ function useIndicators() {
|
|
|
926
1118
|
collapseSubIndicator,
|
|
927
1119
|
expandSubIndicator,
|
|
928
1120
|
isSubIndicatorCollapsed,
|
|
929
|
-
reorderSubIndicator
|
|
1121
|
+
reorderSubIndicator,
|
|
1122
|
+
indicatorAxes: state.indicatorAxes,
|
|
1123
|
+
getIndicatorAxis,
|
|
1124
|
+
indicatorVisibility: state.indicatorVisibility,
|
|
1125
|
+
bindIndicatorToNewAxis
|
|
930
1126
|
};
|
|
931
1127
|
}
|
|
932
1128
|
|
|
@@ -1236,20 +1432,23 @@ function useKlinechartsUISettings() {
|
|
|
1236
1432
|
() => TOOLTIP_SHOW_RULES.map((r) => ({ key: r, localeKey: r })),
|
|
1237
1433
|
[]
|
|
1238
1434
|
);
|
|
1435
|
+
const applyPaneAxis = react.useCallback(
|
|
1436
|
+
(axis) => {
|
|
1437
|
+
state.chart?.overrideYAxis?.({ paneId: "candle_pane", ...axis });
|
|
1438
|
+
},
|
|
1439
|
+
[state.chart]
|
|
1440
|
+
);
|
|
1239
1441
|
const hasAppliedInitial = react.useRef(false);
|
|
1240
1442
|
react.useEffect(() => {
|
|
1241
1443
|
if (!state.chart || hasAppliedInitial.current) return;
|
|
1242
1444
|
hasAppliedInitial.current = true;
|
|
1243
|
-
const
|
|
1244
|
-
if (
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
...settings.yAxisPosition !== "right" && { position: settings.yAxisPosition },
|
|
1251
|
-
...settings.yAxisInside && { inside: true }
|
|
1252
|
-
}
|
|
1445
|
+
const needsAxisOverride = settings.reverseCoordinate || settings.priceAxisType !== "normal" || settings.yAxisPosition !== "right" || settings.yAxisInside;
|
|
1446
|
+
if (needsAxisOverride) {
|
|
1447
|
+
applyPaneAxis({
|
|
1448
|
+
...settings.priceAxisType !== "normal" && { name: settings.priceAxisType },
|
|
1449
|
+
...settings.reverseCoordinate && { reverse: true },
|
|
1450
|
+
...settings.yAxisPosition !== "right" && { position: settings.yAxisPosition },
|
|
1451
|
+
...settings.yAxisInside && { inside: true }
|
|
1253
1452
|
});
|
|
1254
1453
|
}
|
|
1255
1454
|
if (settings.showIndicatorLastValue) {
|
|
@@ -1272,12 +1471,6 @@ function useKlinechartsUISettings() {
|
|
|
1272
1471
|
},
|
|
1273
1472
|
[state.chart]
|
|
1274
1473
|
);
|
|
1275
|
-
const applyPaneAxis = react.useCallback(
|
|
1276
|
-
(axis) => {
|
|
1277
|
-
state.chart?.setPaneOptions({ id: "candle_pane", axis });
|
|
1278
|
-
},
|
|
1279
|
-
[state.chart]
|
|
1280
|
-
);
|
|
1281
1474
|
const setCandleType = react.useCallback(
|
|
1282
1475
|
(type) => {
|
|
1283
1476
|
applyStyle("candle.type", type);
|
|
@@ -1425,11 +1618,8 @@ function useKlinechartsUISettings() {
|
|
|
1425
1618
|
const resetToDefaults = react.useCallback(() => {
|
|
1426
1619
|
setSettings(defaultSettings);
|
|
1427
1620
|
state.chart?.setStyles(state.theme);
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
axis: { name: "normal", reverse: false, position: "right", inside: false }
|
|
1431
|
-
});
|
|
1432
|
-
}, [state.chart, state.theme]);
|
|
1621
|
+
applyPaneAxis({ name: "normal", reverse: false, position: "right", inside: false });
|
|
1622
|
+
}, [state.chart, state.theme, applyPaneAxis]);
|
|
1433
1623
|
return {
|
|
1434
1624
|
...settings,
|
|
1435
1625
|
candleTypes,
|
|
@@ -1686,21 +1876,28 @@ function useUndoRedo() {
|
|
|
1686
1876
|
break;
|
|
1687
1877
|
}
|
|
1688
1878
|
case "indicator_toggled": {
|
|
1689
|
-
const { name, wasActive, isMain, paneId } = action.data;
|
|
1879
|
+
const { name, wasActive, isMain, paneId, yAxisId } = action.data;
|
|
1880
|
+
const id = isMain ? `main_${name}` : `sub_${name}`;
|
|
1690
1881
|
if (wasActive) {
|
|
1691
1882
|
if (isMain) {
|
|
1692
1883
|
state.chart.createIndicator(
|
|
1693
|
-
{ name, id
|
|
1694
|
-
|
|
1695
|
-
|
|
1884
|
+
{ name, id },
|
|
1885
|
+
{
|
|
1886
|
+
isStack: true,
|
|
1887
|
+
pane: { id: "candle_pane" },
|
|
1888
|
+
...yAxisId ? { yAxis: { id: yAxisId } } : {}
|
|
1889
|
+
}
|
|
1696
1890
|
);
|
|
1697
1891
|
dispatch({
|
|
1698
1892
|
type: "SET_MAIN_INDICATORS",
|
|
1699
1893
|
indicators: [...state.mainIndicators, name]
|
|
1700
1894
|
});
|
|
1701
1895
|
} else {
|
|
1702
|
-
state.chart.createIndicator(
|
|
1703
|
-
|
|
1896
|
+
state.chart.createIndicator(
|
|
1897
|
+
{ name, id },
|
|
1898
|
+
yAxisId ? { yAxis: { id: yAxisId } } : void 0
|
|
1899
|
+
);
|
|
1900
|
+
const newPaneId = state.chart.getIndicators({ id })?.[0]?.paneId ?? "";
|
|
1704
1901
|
dispatch({
|
|
1705
1902
|
type: "SET_SUB_INDICATORS",
|
|
1706
1903
|
indicators: {
|
|
@@ -1709,9 +1906,15 @@ function useUndoRedo() {
|
|
|
1709
1906
|
}
|
|
1710
1907
|
});
|
|
1711
1908
|
}
|
|
1909
|
+
if (yAxisId) {
|
|
1910
|
+
dispatch({
|
|
1911
|
+
type: "SET_INDICATOR_AXES",
|
|
1912
|
+
axes: { ...state.indicatorAxes, [id]: yAxisId }
|
|
1913
|
+
});
|
|
1914
|
+
}
|
|
1712
1915
|
} else {
|
|
1916
|
+
state.chart.removeIndicator({ id });
|
|
1713
1917
|
if (isMain) {
|
|
1714
|
-
state.chart.removeIndicator({ id: `main_${name}` });
|
|
1715
1918
|
dispatch({
|
|
1716
1919
|
type: "SET_MAIN_INDICATORS",
|
|
1717
1920
|
indicators: state.mainIndicators.filter(
|
|
@@ -1719,7 +1922,6 @@ function useUndoRedo() {
|
|
|
1719
1922
|
)
|
|
1720
1923
|
});
|
|
1721
1924
|
} else {
|
|
1722
|
-
state.chart.removeIndicator({ id: `sub_${name}` });
|
|
1723
1925
|
const newSub = { ...state.subIndicators };
|
|
1724
1926
|
delete newSub[name];
|
|
1725
1927
|
dispatch({
|
|
@@ -1727,6 +1929,11 @@ function useUndoRedo() {
|
|
|
1727
1929
|
indicators: newSub
|
|
1728
1930
|
});
|
|
1729
1931
|
}
|
|
1932
|
+
if (state.indicatorAxes[id]) {
|
|
1933
|
+
const nextAxes = { ...state.indicatorAxes };
|
|
1934
|
+
delete nextAxes[id];
|
|
1935
|
+
dispatch({ type: "SET_INDICATOR_AXES", axes: nextAxes });
|
|
1936
|
+
}
|
|
1730
1937
|
}
|
|
1731
1938
|
setRedoStack((prev) => [
|
|
1732
1939
|
...prev,
|
|
@@ -1736,7 +1943,8 @@ function useUndoRedo() {
|
|
|
1736
1943
|
name,
|
|
1737
1944
|
wasActive: !wasActive,
|
|
1738
1945
|
isMain,
|
|
1739
|
-
paneId
|
|
1946
|
+
paneId,
|
|
1947
|
+
yAxisId
|
|
1740
1948
|
}
|
|
1741
1949
|
}
|
|
1742
1950
|
]);
|
|
@@ -1746,7 +1954,7 @@ function useUndoRedo() {
|
|
|
1746
1954
|
} finally {
|
|
1747
1955
|
isProcessingRef.current = false;
|
|
1748
1956
|
}
|
|
1749
|
-
}, [undoStack, state.chart, state.mainIndicators, state.subIndicators, dispatch]);
|
|
1957
|
+
}, [undoStack, state.chart, state.mainIndicators, state.subIndicators, state.indicatorAxes, dispatch]);
|
|
1750
1958
|
const redo = react.useCallback(() => {
|
|
1751
1959
|
if (redoStack.length === 0 || !state.chart || isProcessingRef.current)
|
|
1752
1960
|
return;
|
|
@@ -1798,21 +2006,28 @@ function useUndoRedo() {
|
|
|
1798
2006
|
break;
|
|
1799
2007
|
}
|
|
1800
2008
|
case "indicator_toggled": {
|
|
1801
|
-
const { name, wasActive, isMain } = action.data;
|
|
2009
|
+
const { name, wasActive, isMain, paneId, yAxisId } = action.data;
|
|
2010
|
+
const id = isMain ? `main_${name}` : `sub_${name}`;
|
|
1802
2011
|
if (wasActive) {
|
|
1803
2012
|
if (isMain) {
|
|
1804
2013
|
state.chart.createIndicator(
|
|
1805
|
-
{ name, id
|
|
1806
|
-
|
|
1807
|
-
|
|
2014
|
+
{ name, id },
|
|
2015
|
+
{
|
|
2016
|
+
isStack: true,
|
|
2017
|
+
pane: { id: "candle_pane" },
|
|
2018
|
+
...yAxisId ? { yAxis: { id: yAxisId } } : {}
|
|
2019
|
+
}
|
|
1808
2020
|
);
|
|
1809
2021
|
dispatch({
|
|
1810
2022
|
type: "SET_MAIN_INDICATORS",
|
|
1811
2023
|
indicators: [...state.mainIndicators, name]
|
|
1812
2024
|
});
|
|
1813
2025
|
} else {
|
|
1814
|
-
state.chart.createIndicator(
|
|
1815
|
-
|
|
2026
|
+
state.chart.createIndicator(
|
|
2027
|
+
{ name, id },
|
|
2028
|
+
yAxisId ? { yAxis: { id: yAxisId } } : void 0
|
|
2029
|
+
);
|
|
2030
|
+
const newPaneId = state.chart.getIndicators({ id })?.[0]?.paneId ?? "";
|
|
1816
2031
|
dispatch({
|
|
1817
2032
|
type: "SET_SUB_INDICATORS",
|
|
1818
2033
|
indicators: {
|
|
@@ -1821,9 +2036,15 @@ function useUndoRedo() {
|
|
|
1821
2036
|
}
|
|
1822
2037
|
});
|
|
1823
2038
|
}
|
|
2039
|
+
if (yAxisId) {
|
|
2040
|
+
dispatch({
|
|
2041
|
+
type: "SET_INDICATOR_AXES",
|
|
2042
|
+
axes: { ...state.indicatorAxes, [id]: yAxisId }
|
|
2043
|
+
});
|
|
2044
|
+
}
|
|
1824
2045
|
} else {
|
|
2046
|
+
state.chart.removeIndicator({ id });
|
|
1825
2047
|
if (isMain) {
|
|
1826
|
-
state.chart.removeIndicator({ id: `main_${name}` });
|
|
1827
2048
|
dispatch({
|
|
1828
2049
|
type: "SET_MAIN_INDICATORS",
|
|
1829
2050
|
indicators: state.mainIndicators.filter(
|
|
@@ -1831,7 +2052,6 @@ function useUndoRedo() {
|
|
|
1831
2052
|
)
|
|
1832
2053
|
});
|
|
1833
2054
|
} else {
|
|
1834
|
-
state.chart.removeIndicator({ id: `sub_${name}` });
|
|
1835
2055
|
const newSub = { ...state.subIndicators };
|
|
1836
2056
|
delete newSub[name];
|
|
1837
2057
|
dispatch({
|
|
@@ -1839,6 +2059,11 @@ function useUndoRedo() {
|
|
|
1839
2059
|
indicators: newSub
|
|
1840
2060
|
});
|
|
1841
2061
|
}
|
|
2062
|
+
if (state.indicatorAxes[id]) {
|
|
2063
|
+
const nextAxes = { ...state.indicatorAxes };
|
|
2064
|
+
delete nextAxes[id];
|
|
2065
|
+
dispatch({ type: "SET_INDICATOR_AXES", axes: nextAxes });
|
|
2066
|
+
}
|
|
1842
2067
|
}
|
|
1843
2068
|
setUndoStack((prev) => [
|
|
1844
2069
|
...prev,
|
|
@@ -1847,7 +2072,9 @@ function useUndoRedo() {
|
|
|
1847
2072
|
data: {
|
|
1848
2073
|
name,
|
|
1849
2074
|
wasActive: !wasActive,
|
|
1850
|
-
isMain
|
|
2075
|
+
isMain,
|
|
2076
|
+
paneId,
|
|
2077
|
+
yAxisId
|
|
1851
2078
|
}
|
|
1852
2079
|
}
|
|
1853
2080
|
]);
|
|
@@ -1857,7 +2084,7 @@ function useUndoRedo() {
|
|
|
1857
2084
|
} finally {
|
|
1858
2085
|
isProcessingRef.current = false;
|
|
1859
2086
|
}
|
|
1860
|
-
}, [redoStack, state.chart, state.mainIndicators, state.subIndicators, dispatch]);
|
|
2087
|
+
}, [redoStack, state.chart, state.mainIndicators, state.subIndicators, state.indicatorAxes, dispatch]);
|
|
1861
2088
|
react.useEffect(() => {
|
|
1862
2089
|
const handleKeyDown = (e) => {
|
|
1863
2090
|
const isCtrlOrMeta = e.ctrlKey || e.metaKey;
|
|
@@ -1931,12 +2158,14 @@ function useLayoutManager() {
|
|
|
1931
2158
|
if (indicatorMap) {
|
|
1932
2159
|
indicatorMap.forEach((paneIndicators, paneId) => {
|
|
1933
2160
|
paneIndicators.forEach((indicator) => {
|
|
2161
|
+
const yAxisId = state.indicatorAxes[indicator.id];
|
|
1934
2162
|
indicators2.push({
|
|
1935
2163
|
paneId,
|
|
1936
2164
|
name: indicator.name,
|
|
1937
2165
|
calcParams: indicator.calcParams,
|
|
1938
2166
|
visible: indicator.visible,
|
|
1939
|
-
...indicator.styles ? { styles: indicator.styles } : {}
|
|
2167
|
+
...indicator.styles ? { styles: indicator.styles } : {},
|
|
2168
|
+
...yAxisId ? { yAxisId } : {}
|
|
1940
2169
|
});
|
|
1941
2170
|
});
|
|
1942
2171
|
});
|
|
@@ -1964,7 +2193,7 @@ function useLayoutManager() {
|
|
|
1964
2193
|
indicators: indicators2,
|
|
1965
2194
|
drawings
|
|
1966
2195
|
};
|
|
1967
|
-
}, [state.chart, state.symbol, state.period]);
|
|
2196
|
+
}, [state.chart, state.symbol, state.period, state.indicatorAxes]);
|
|
1968
2197
|
const saveLayout = react.useCallback(
|
|
1969
2198
|
(name) => {
|
|
1970
2199
|
const chartState = serializeState();
|
|
@@ -2012,25 +2241,39 @@ function useLayoutManager() {
|
|
|
2012
2241
|
}
|
|
2013
2242
|
const newMainIndicators = [];
|
|
2014
2243
|
const newSubIndicators = {};
|
|
2244
|
+
const restoredAxes = {};
|
|
2245
|
+
const restoredVisibility = {};
|
|
2015
2246
|
if (chartState.indicators) {
|
|
2016
2247
|
for (const ind of chartState.indicators) {
|
|
2248
|
+
const isMain = ind.paneId === "candle_pane";
|
|
2249
|
+
const id2 = isMain ? `main_${ind.name}` : `sub_${ind.name}`;
|
|
2017
2250
|
chart.createIndicator(
|
|
2018
2251
|
{
|
|
2019
2252
|
name: ind.name,
|
|
2253
|
+
id: id2,
|
|
2020
2254
|
calcParams: ind.calcParams,
|
|
2021
2255
|
visible: ind.visible
|
|
2022
2256
|
},
|
|
2023
|
-
|
|
2024
|
-
|
|
2257
|
+
{
|
|
2258
|
+
isStack: ind.paneId !== "candle_pane",
|
|
2259
|
+
pane: { id: ind.paneId },
|
|
2260
|
+
...ind.yAxisId ? { yAxis: { id: ind.yAxisId } } : {}
|
|
2261
|
+
}
|
|
2025
2262
|
);
|
|
2026
2263
|
if (ind.styles) {
|
|
2027
2264
|
chart.overrideIndicator({
|
|
2028
2265
|
name: ind.name,
|
|
2029
|
-
|
|
2266
|
+
id: id2,
|
|
2030
2267
|
styles: ind.styles
|
|
2031
2268
|
});
|
|
2032
2269
|
}
|
|
2033
|
-
if (ind.
|
|
2270
|
+
if (ind.yAxisId) {
|
|
2271
|
+
restoredAxes[id2] = ind.yAxisId;
|
|
2272
|
+
}
|
|
2273
|
+
if (ind.visible === false) {
|
|
2274
|
+
restoredVisibility[id2] = false;
|
|
2275
|
+
}
|
|
2276
|
+
if (isMain) {
|
|
2034
2277
|
newMainIndicators.push(ind.name);
|
|
2035
2278
|
} else {
|
|
2036
2279
|
newSubIndicators[ind.name] = ind.paneId;
|
|
@@ -2045,6 +2288,14 @@ function useLayoutManager() {
|
|
|
2045
2288
|
type: "SET_SUB_INDICATORS",
|
|
2046
2289
|
indicators: newSubIndicators
|
|
2047
2290
|
});
|
|
2291
|
+
dispatch({
|
|
2292
|
+
type: "SET_INDICATOR_AXES",
|
|
2293
|
+
axes: restoredAxes
|
|
2294
|
+
});
|
|
2295
|
+
dispatch({
|
|
2296
|
+
type: "SET_INDICATOR_VISIBILITY",
|
|
2297
|
+
visibility: restoredVisibility
|
|
2298
|
+
});
|
|
2048
2299
|
if (chartState.drawings) {
|
|
2049
2300
|
for (const drawing of chartState.drawings) {
|
|
2050
2301
|
chart.createOverlay({
|
|
@@ -2228,7 +2479,7 @@ ${code}`
|
|
|
2228
2479
|
];
|
|
2229
2480
|
const fn = new Function(...allArgs);
|
|
2230
2481
|
const shadowValues = SHADOW_KEYS.map(() => void 0);
|
|
2231
|
-
const result = fn(...shadowValues,
|
|
2482
|
+
const result = fn(...shadowValues, chunkUJNJH3BS_cjs.TA_default, dataList, parsedParams);
|
|
2232
2483
|
if (!Array.isArray(result)) {
|
|
2233
2484
|
throw new Error("Script must return an Array.");
|
|
2234
2485
|
}
|
|
@@ -2270,8 +2521,7 @@ ${code}`
|
|
|
2270
2521
|
if (placement === "main") {
|
|
2271
2522
|
paneId = chart.createIndicator(
|
|
2272
2523
|
{ name: indicatorName },
|
|
2273
|
-
true,
|
|
2274
|
-
{ id: "candle_pane" }
|
|
2524
|
+
{ isStack: true, pane: { id: "candle_pane" } }
|
|
2275
2525
|
);
|
|
2276
2526
|
} else {
|
|
2277
2527
|
paneId = chart.createIndicator({ name: indicatorName });
|
|
@@ -2412,10 +2662,9 @@ function useCrosshair() {
|
|
|
2412
2662
|
}
|
|
2413
2663
|
var alertCounter = 0;
|
|
2414
2664
|
function useAlerts() {
|
|
2415
|
-
const { state } = useKlinechartsUI();
|
|
2416
|
-
const
|
|
2417
|
-
const
|
|
2418
|
-
const prevCloseRef = react.useRef(null);
|
|
2665
|
+
const { state, dispatch } = useKlinechartsUI();
|
|
2666
|
+
const { alertTriggeredListenerRef } = useKlinechartsUIDispatch();
|
|
2667
|
+
const alerts = state.alerts;
|
|
2419
2668
|
const addAlert = react.useCallback(
|
|
2420
2669
|
(price, condition, message) => {
|
|
2421
2670
|
const id = `alert_${++alertCounter}`;
|
|
@@ -2426,7 +2675,7 @@ function useAlerts() {
|
|
|
2426
2675
|
message,
|
|
2427
2676
|
triggered: false
|
|
2428
2677
|
};
|
|
2429
|
-
|
|
2678
|
+
dispatch({ type: "SET_ALERTS", alerts: [...state.alerts, alert] });
|
|
2430
2679
|
if (state.chart) {
|
|
2431
2680
|
state.chart.createOverlay({
|
|
2432
2681
|
name: "horizontalStraightLine",
|
|
@@ -2445,67 +2694,30 @@ function useAlerts() {
|
|
|
2445
2694
|
}
|
|
2446
2695
|
return id;
|
|
2447
2696
|
},
|
|
2448
|
-
[state.chart]
|
|
2697
|
+
[state.chart, state.alerts, dispatch]
|
|
2449
2698
|
);
|
|
2450
2699
|
const removeAlert = react.useCallback(
|
|
2451
2700
|
(id) => {
|
|
2452
|
-
|
|
2701
|
+
dispatch({
|
|
2702
|
+
type: "SET_ALERTS",
|
|
2703
|
+
alerts: state.alerts.filter((a) => a.id !== id)
|
|
2704
|
+
});
|
|
2453
2705
|
state.chart?.removeOverlay({ id });
|
|
2454
2706
|
},
|
|
2455
|
-
[state.chart]
|
|
2707
|
+
[state.chart, state.alerts, dispatch]
|
|
2456
2708
|
);
|
|
2457
2709
|
const clearAlerts = react.useCallback(() => {
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
});
|
|
2464
|
-
}, [state.chart]);
|
|
2710
|
+
for (const alert of state.alerts) {
|
|
2711
|
+
state.chart?.removeOverlay({ id: alert.id });
|
|
2712
|
+
}
|
|
2713
|
+
dispatch({ type: "SET_ALERTS", alerts: [] });
|
|
2714
|
+
}, [state.chart, state.alerts, dispatch]);
|
|
2465
2715
|
const onAlertTriggered = react.useCallback(
|
|
2466
2716
|
(callback) => {
|
|
2467
|
-
|
|
2717
|
+
alertTriggeredListenerRef.current = callback;
|
|
2468
2718
|
},
|
|
2469
|
-
[]
|
|
2719
|
+
[alertTriggeredListenerRef]
|
|
2470
2720
|
);
|
|
2471
|
-
react.useEffect(() => {
|
|
2472
|
-
if (!state.chart) return;
|
|
2473
|
-
const interval = setInterval(() => {
|
|
2474
|
-
const dataList = state.chart?.getDataList();
|
|
2475
|
-
if (!dataList || dataList.length === 0) return;
|
|
2476
|
-
const lastBar = dataList[dataList.length - 1];
|
|
2477
|
-
const currentClose = lastBar.close;
|
|
2478
|
-
const prevClose = prevCloseRef.current;
|
|
2479
|
-
if (prevClose === null) {
|
|
2480
|
-
prevCloseRef.current = currentClose;
|
|
2481
|
-
return;
|
|
2482
|
-
}
|
|
2483
|
-
prevCloseRef.current = currentClose;
|
|
2484
|
-
setAlerts((prev) => {
|
|
2485
|
-
let changed = false;
|
|
2486
|
-
const next = prev.map((alert) => {
|
|
2487
|
-
if (alert.triggered) return alert;
|
|
2488
|
-
let shouldTrigger = false;
|
|
2489
|
-
if (alert.condition === "crossing_up") {
|
|
2490
|
-
shouldTrigger = prevClose < alert.price && currentClose >= alert.price;
|
|
2491
|
-
} else if (alert.condition === "crossing_down") {
|
|
2492
|
-
shouldTrigger = prevClose > alert.price && currentClose <= alert.price;
|
|
2493
|
-
} else if (alert.condition === "crossing") {
|
|
2494
|
-
shouldTrigger = prevClose < alert.price && currentClose >= alert.price || prevClose > alert.price && currentClose <= alert.price;
|
|
2495
|
-
}
|
|
2496
|
-
if (shouldTrigger) {
|
|
2497
|
-
changed = true;
|
|
2498
|
-
const triggered = { ...alert, triggered: true };
|
|
2499
|
-
callbackRef.current?.(triggered);
|
|
2500
|
-
return triggered;
|
|
2501
|
-
}
|
|
2502
|
-
return alert;
|
|
2503
|
-
});
|
|
2504
|
-
return changed ? next : prev;
|
|
2505
|
-
});
|
|
2506
|
-
}, 1e3);
|
|
2507
|
-
return () => clearInterval(interval);
|
|
2508
|
-
}, [state.chart]);
|
|
2509
2721
|
return {
|
|
2510
2722
|
alerts,
|
|
2511
2723
|
addAlert,
|
|
@@ -2651,128 +2863,124 @@ function useWatchlist() {
|
|
|
2651
2863
|
};
|
|
2652
2864
|
}
|
|
2653
2865
|
function useReplay() {
|
|
2654
|
-
const { state } = useKlinechartsUI();
|
|
2655
|
-
const
|
|
2656
|
-
const
|
|
2657
|
-
const [speed, setSpeedState] = react.useState(1);
|
|
2658
|
-
const [barIndex, setBarIndex] = react.useState(0);
|
|
2659
|
-
const [totalBars, setTotalBars] = react.useState(0);
|
|
2660
|
-
const intervalRef = react.useRef(null);
|
|
2661
|
-
const savedDataRef = react.useRef([]);
|
|
2662
|
-
const currentIndexRef = react.useRef(0);
|
|
2866
|
+
const { state, dispatch } = useKlinechartsUI();
|
|
2867
|
+
const { replayIntervalRef, replaySavedDataRef, replayIndexRef } = useKlinechartsUIDispatch();
|
|
2868
|
+
const { isReplaying, isPaused, speed, barIndex, totalBars } = state.replay;
|
|
2663
2869
|
const clearInterval_ = react.useCallback(() => {
|
|
2664
|
-
if (
|
|
2665
|
-
clearInterval(
|
|
2666
|
-
|
|
2870
|
+
if (replayIntervalRef.current !== null) {
|
|
2871
|
+
clearInterval(replayIntervalRef.current);
|
|
2872
|
+
replayIntervalRef.current = null;
|
|
2667
2873
|
}
|
|
2668
|
-
}, []);
|
|
2874
|
+
}, [replayIntervalRef]);
|
|
2669
2875
|
const addNextBar = react.useCallback(() => {
|
|
2670
2876
|
if (!state.chart) return;
|
|
2671
|
-
const data =
|
|
2672
|
-
const idx =
|
|
2877
|
+
const data = replaySavedDataRef.current;
|
|
2878
|
+
const idx = replayIndexRef.current;
|
|
2673
2879
|
if (idx >= data.length) {
|
|
2674
2880
|
clearInterval_();
|
|
2675
|
-
|
|
2881
|
+
dispatch({ type: "SET_REPLAY", replay: { isPaused: true } });
|
|
2676
2882
|
return;
|
|
2677
2883
|
}
|
|
2678
2884
|
const bar = data[idx];
|
|
2679
2885
|
state.chart.updateData?.(bar);
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
}, [state.chart, clearInterval_]);
|
|
2886
|
+
replayIndexRef.current = idx + 1;
|
|
2887
|
+
dispatch({ type: "SET_REPLAY", replay: { barIndex: idx + 1 } });
|
|
2888
|
+
}, [state.chart, clearInterval_, replaySavedDataRef, replayIndexRef, dispatch]);
|
|
2683
2889
|
const startInterval = react.useCallback(
|
|
2684
2890
|
(currentSpeed) => {
|
|
2685
2891
|
clearInterval_();
|
|
2686
|
-
|
|
2892
|
+
replayIntervalRef.current = setInterval(addNextBar, 1e3 / currentSpeed);
|
|
2687
2893
|
},
|
|
2688
|
-
[addNextBar, clearInterval_]
|
|
2894
|
+
[addNextBar, clearInterval_, replayIntervalRef]
|
|
2689
2895
|
);
|
|
2690
2896
|
const startReplay = react.useCallback(() => {
|
|
2691
2897
|
if (!state.chart) return;
|
|
2692
2898
|
const dataList = state.chart.getDataList();
|
|
2693
2899
|
if (!dataList || dataList.length === 0) return;
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2900
|
+
replaySavedDataRef.current = [...dataList];
|
|
2901
|
+
replayIndexRef.current = 0;
|
|
2902
|
+
dispatch({
|
|
2903
|
+
type: "SET_REPLAY",
|
|
2904
|
+
replay: {
|
|
2905
|
+
totalBars: dataList.length,
|
|
2906
|
+
barIndex: 0,
|
|
2907
|
+
isReplaying: true,
|
|
2908
|
+
isPaused: false
|
|
2909
|
+
}
|
|
2910
|
+
});
|
|
2700
2911
|
state.chart.clearData?.();
|
|
2701
2912
|
startInterval(speed);
|
|
2702
|
-
}, [state.chart, speed, startInterval]);
|
|
2913
|
+
}, [state.chart, speed, startInterval, replaySavedDataRef, replayIndexRef, dispatch]);
|
|
2703
2914
|
const stopReplay = react.useCallback(() => {
|
|
2704
2915
|
if (!state.chart) return;
|
|
2705
2916
|
clearInterval_();
|
|
2706
|
-
const data =
|
|
2917
|
+
const data = replaySavedDataRef.current;
|
|
2707
2918
|
if (data.length > 0) {
|
|
2708
2919
|
state.chart.clearData?.();
|
|
2709
2920
|
for (const bar of data) {
|
|
2710
2921
|
state.chart.updateData?.(bar);
|
|
2711
2922
|
}
|
|
2712
2923
|
}
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
}, [state.chart, clearInterval_]);
|
|
2924
|
+
replaySavedDataRef.current = [];
|
|
2925
|
+
replayIndexRef.current = 0;
|
|
2926
|
+
dispatch({
|
|
2927
|
+
type: "SET_REPLAY",
|
|
2928
|
+
replay: { isReplaying: false, isPaused: false, barIndex: 0, totalBars: 0 }
|
|
2929
|
+
});
|
|
2930
|
+
}, [state.chart, clearInterval_, replaySavedDataRef, replayIndexRef, dispatch]);
|
|
2720
2931
|
const togglePause = react.useCallback(() => {
|
|
2721
2932
|
if (!isReplaying) return;
|
|
2722
2933
|
if (isPaused) {
|
|
2723
2934
|
startInterval(speed);
|
|
2724
|
-
|
|
2935
|
+
dispatch({ type: "SET_REPLAY", replay: { isPaused: false } });
|
|
2725
2936
|
} else {
|
|
2726
2937
|
clearInterval_();
|
|
2727
|
-
|
|
2938
|
+
dispatch({ type: "SET_REPLAY", replay: { isPaused: true } });
|
|
2728
2939
|
}
|
|
2729
|
-
}, [isReplaying, isPaused, speed, startInterval, clearInterval_]);
|
|
2940
|
+
}, [isReplaying, isPaused, speed, startInterval, clearInterval_, dispatch]);
|
|
2730
2941
|
const stepForward = react.useCallback(() => {
|
|
2731
2942
|
if (!isReplaying || !isPaused) return;
|
|
2732
2943
|
addNextBar();
|
|
2733
2944
|
}, [isReplaying, isPaused, addNextBar]);
|
|
2734
2945
|
const stepBackward = react.useCallback(() => {
|
|
2735
2946
|
if (!isReplaying || !isPaused || !state.chart) return;
|
|
2736
|
-
const idx =
|
|
2947
|
+
const idx = replayIndexRef.current;
|
|
2737
2948
|
if (idx <= 1) return;
|
|
2738
|
-
const data =
|
|
2949
|
+
const data = replaySavedDataRef.current;
|
|
2739
2950
|
state.chart.clearData?.();
|
|
2740
2951
|
for (let i = 0; i < idx - 1; i++) {
|
|
2741
2952
|
state.chart.updateData?.(data[i]);
|
|
2742
2953
|
}
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
}, [isReplaying, isPaused, state.chart]);
|
|
2954
|
+
replayIndexRef.current = idx - 1;
|
|
2955
|
+
dispatch({ type: "SET_REPLAY", replay: { barIndex: idx - 1 } });
|
|
2956
|
+
}, [isReplaying, isPaused, state.chart, replaySavedDataRef, replayIndexRef, dispatch]);
|
|
2746
2957
|
const seekTo = react.useCallback(
|
|
2747
2958
|
(targetIndex) => {
|
|
2748
2959
|
if (!isReplaying || !state.chart) return;
|
|
2749
|
-
const data =
|
|
2960
|
+
const data = replaySavedDataRef.current;
|
|
2750
2961
|
const clamped = Math.max(0, Math.min(targetIndex, data.length));
|
|
2751
2962
|
clearInterval_();
|
|
2752
|
-
setIsPaused(true);
|
|
2753
2963
|
state.chart.clearData?.();
|
|
2754
2964
|
for (let i = 0; i < clamped; i++) {
|
|
2755
2965
|
state.chart.updateData?.(data[i]);
|
|
2756
2966
|
}
|
|
2757
|
-
|
|
2758
|
-
|
|
2967
|
+
replayIndexRef.current = clamped;
|
|
2968
|
+
dispatch({
|
|
2969
|
+
type: "SET_REPLAY",
|
|
2970
|
+
replay: { isPaused: true, barIndex: clamped }
|
|
2971
|
+
});
|
|
2759
2972
|
},
|
|
2760
|
-
[isReplaying, state.chart, clearInterval_]
|
|
2973
|
+
[isReplaying, state.chart, clearInterval_, replaySavedDataRef, replayIndexRef, dispatch]
|
|
2761
2974
|
);
|
|
2762
2975
|
const setSpeed = react.useCallback(
|
|
2763
2976
|
(newSpeed) => {
|
|
2764
|
-
|
|
2977
|
+
dispatch({ type: "SET_REPLAY", replay: { speed: newSpeed } });
|
|
2765
2978
|
if (isReplaying && !isPaused) {
|
|
2766
2979
|
startInterval(newSpeed);
|
|
2767
2980
|
}
|
|
2768
2981
|
},
|
|
2769
|
-
[isReplaying, isPaused, startInterval]
|
|
2982
|
+
[isReplaying, isPaused, startInterval, dispatch]
|
|
2770
2983
|
);
|
|
2771
|
-
react.useEffect(() => {
|
|
2772
|
-
return () => {
|
|
2773
|
-
clearInterval_();
|
|
2774
|
-
};
|
|
2775
|
-
}, [clearInterval_]);
|
|
2776
2984
|
return {
|
|
2777
2985
|
isReplaying,
|
|
2778
2986
|
isPaused,
|
|
@@ -2856,8 +3064,7 @@ function useCompare() {
|
|
|
2856
3064
|
});
|
|
2857
3065
|
const paneId = state.chart.createIndicator(
|
|
2858
3066
|
{ name: indicatorName },
|
|
2859
|
-
true,
|
|
2860
|
-
{ id: "candle_pane" }
|
|
3067
|
+
{ isStack: true, pane: { id: "candle_pane" } }
|
|
2861
3068
|
);
|
|
2862
3069
|
indicatorsRef.current.set(ticker, {
|
|
2863
3070
|
name: indicatorName,
|
|
@@ -2930,31 +3137,25 @@ function useCompare() {
|
|
|
2930
3137
|
return { symbols, addSymbol, removeSymbol, toggleSymbol, clearAll };
|
|
2931
3138
|
}
|
|
2932
3139
|
var MEASURE_OVERLAY_ID = "__measure_line__";
|
|
3140
|
+
function computeResult(from, to) {
|
|
3141
|
+
const priceDiff = to.price - from.price;
|
|
3142
|
+
const pricePercent = from.price !== 0 ? priceDiff / from.price * 100 : 0;
|
|
3143
|
+
const bars = Math.abs(to.barIndex - from.barIndex);
|
|
3144
|
+
const timeDiff = Math.abs(to.timestamp - from.timestamp);
|
|
3145
|
+
return { from, to, priceDiff, pricePercent, bars, timeDiff };
|
|
3146
|
+
}
|
|
2933
3147
|
function useMeasure() {
|
|
2934
|
-
const { state } = useKlinechartsUI();
|
|
2935
|
-
const
|
|
2936
|
-
const [fromPoint, setFromPoint] = react.useState(null);
|
|
2937
|
-
const [result, setResult] = react.useState(null);
|
|
2938
|
-
const clickCountRef = react.useRef(0);
|
|
2939
|
-
const computeResult = react.useCallback(
|
|
2940
|
-
(from, to) => {
|
|
2941
|
-
const priceDiff = to.price - from.price;
|
|
2942
|
-
const pricePercent = from.price !== 0 ? priceDiff / from.price * 100 : 0;
|
|
2943
|
-
const bars = Math.abs(to.barIndex - from.barIndex);
|
|
2944
|
-
const timeDiff = Math.abs(to.timestamp - from.timestamp);
|
|
2945
|
-
return { from, to, priceDiff, pricePercent, bars, timeDiff };
|
|
2946
|
-
},
|
|
2947
|
-
[]
|
|
2948
|
-
);
|
|
3148
|
+
const { state, dispatch } = useKlinechartsUI();
|
|
3149
|
+
const { isActive, fromPoint, result } = state.measure;
|
|
2949
3150
|
const cleanup = react.useCallback(() => {
|
|
2950
3151
|
state.chart?.removeOverlay({ id: MEASURE_OVERLAY_ID });
|
|
2951
3152
|
}, [state.chart]);
|
|
2952
3153
|
const startMeasure = react.useCallback(() => {
|
|
2953
3154
|
cleanup();
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
3155
|
+
dispatch({
|
|
3156
|
+
type: "SET_MEASURE",
|
|
3157
|
+
measure: { isActive: true, fromPoint: null, result: null }
|
|
3158
|
+
});
|
|
2958
3159
|
if (!state.chart) return;
|
|
2959
3160
|
state.chart.createOverlay({
|
|
2960
3161
|
name: "segment",
|
|
@@ -2990,23 +3191,25 @@ function useMeasure() {
|
|
|
2990
3191
|
};
|
|
2991
3192
|
const from = makePoint(points[0]);
|
|
2992
3193
|
const to = makePoint(points[1]);
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
3194
|
+
dispatch({
|
|
3195
|
+
type: "SET_MEASURE",
|
|
3196
|
+
measure: {
|
|
3197
|
+
isActive: false,
|
|
3198
|
+
fromPoint: from,
|
|
3199
|
+
result: computeResult(from, to)
|
|
3200
|
+
}
|
|
3201
|
+
});
|
|
2996
3202
|
}
|
|
2997
3203
|
});
|
|
2998
|
-
}, [state.chart, cleanup,
|
|
3204
|
+
}, [state.chart, cleanup, dispatch]);
|
|
2999
3205
|
const cancelMeasure = react.useCallback(() => {
|
|
3000
3206
|
cleanup();
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
clickCountRef.current = 0;
|
|
3004
|
-
}, [cleanup]);
|
|
3207
|
+
dispatch({ type: "SET_MEASURE", measure: { isActive: false, fromPoint: null } });
|
|
3208
|
+
}, [cleanup, dispatch]);
|
|
3005
3209
|
const clearResult = react.useCallback(() => {
|
|
3006
3210
|
cleanup();
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
}, [cleanup]);
|
|
3211
|
+
dispatch({ type: "SET_MEASURE", measure: { result: null, fromPoint: null } });
|
|
3212
|
+
}, [cleanup, dispatch]);
|
|
3010
3213
|
react.useEffect(() => {
|
|
3011
3214
|
return () => {
|
|
3012
3215
|
state.chart?.removeOverlay({ id: MEASURE_OVERLAY_ID });
|
|
@@ -3172,175 +3375,175 @@ function createDataLoader(datafeed, dispatch) {
|
|
|
3172
3375
|
|
|
3173
3376
|
Object.defineProperty(exports, "TA", {
|
|
3174
3377
|
enumerable: true,
|
|
3175
|
-
get: function () { return
|
|
3378
|
+
get: function () { return chunkUJNJH3BS_cjs.TA_default; }
|
|
3176
3379
|
});
|
|
3177
3380
|
Object.defineProperty(exports, "abcd", {
|
|
3178
3381
|
enumerable: true,
|
|
3179
|
-
get: function () { return
|
|
3382
|
+
get: function () { return chunkUJNJH3BS_cjs.abcd_default; }
|
|
3180
3383
|
});
|
|
3181
3384
|
Object.defineProperty(exports, "anyWaves", {
|
|
3182
3385
|
enumerable: true,
|
|
3183
|
-
get: function () { return
|
|
3386
|
+
get: function () { return chunkUJNJH3BS_cjs.anyWaves_default; }
|
|
3184
3387
|
});
|
|
3185
3388
|
Object.defineProperty(exports, "arrow", {
|
|
3186
3389
|
enumerable: true,
|
|
3187
|
-
get: function () { return
|
|
3390
|
+
get: function () { return chunkUJNJH3BS_cjs.arrow_default; }
|
|
3188
3391
|
});
|
|
3189
3392
|
Object.defineProperty(exports, "bollTv", {
|
|
3190
3393
|
enumerable: true,
|
|
3191
|
-
get: function () { return
|
|
3394
|
+
get: function () { return chunkUJNJH3BS_cjs.bollTv_default; }
|
|
3192
3395
|
});
|
|
3193
3396
|
Object.defineProperty(exports, "brush", {
|
|
3194
3397
|
enumerable: true,
|
|
3195
|
-
get: function () { return
|
|
3398
|
+
get: function () { return chunkUJNJH3BS_cjs.brush_default; }
|
|
3196
3399
|
});
|
|
3197
3400
|
Object.defineProperty(exports, "cci", {
|
|
3198
3401
|
enumerable: true,
|
|
3199
|
-
get: function () { return
|
|
3402
|
+
get: function () { return chunkUJNJH3BS_cjs.cci_default; }
|
|
3200
3403
|
});
|
|
3201
3404
|
Object.defineProperty(exports, "circle", {
|
|
3202
3405
|
enumerable: true,
|
|
3203
|
-
get: function () { return
|
|
3406
|
+
get: function () { return chunkUJNJH3BS_cjs.circle_default; }
|
|
3204
3407
|
});
|
|
3205
3408
|
Object.defineProperty(exports, "depthOverlay", {
|
|
3206
3409
|
enumerable: true,
|
|
3207
|
-
get: function () { return
|
|
3410
|
+
get: function () { return chunkUJNJH3BS_cjs.depthOverlay_default; }
|
|
3208
3411
|
});
|
|
3209
3412
|
Object.defineProperty(exports, "eightWaves", {
|
|
3210
3413
|
enumerable: true,
|
|
3211
|
-
get: function () { return
|
|
3414
|
+
get: function () { return chunkUJNJH3BS_cjs.eightWaves_default; }
|
|
3212
3415
|
});
|
|
3213
3416
|
Object.defineProperty(exports, "elliottWave", {
|
|
3214
3417
|
enumerable: true,
|
|
3215
|
-
get: function () { return
|
|
3418
|
+
get: function () { return chunkUJNJH3BS_cjs.elliottWave_default; }
|
|
3216
3419
|
});
|
|
3217
3420
|
Object.defineProperty(exports, "fibRetracement", {
|
|
3218
3421
|
enumerable: true,
|
|
3219
|
-
get: function () { return
|
|
3422
|
+
get: function () { return chunkUJNJH3BS_cjs.fibRetracement_default; }
|
|
3220
3423
|
});
|
|
3221
3424
|
Object.defineProperty(exports, "fibonacciCircle", {
|
|
3222
3425
|
enumerable: true,
|
|
3223
|
-
get: function () { return
|
|
3426
|
+
get: function () { return chunkUJNJH3BS_cjs.fibonacciCircle_default; }
|
|
3224
3427
|
});
|
|
3225
3428
|
Object.defineProperty(exports, "fibonacciExtension", {
|
|
3226
3429
|
enumerable: true,
|
|
3227
|
-
get: function () { return
|
|
3430
|
+
get: function () { return chunkUJNJH3BS_cjs.fibonacciExtension_default; }
|
|
3228
3431
|
});
|
|
3229
3432
|
Object.defineProperty(exports, "fibonacciSegment", {
|
|
3230
3433
|
enumerable: true,
|
|
3231
|
-
get: function () { return
|
|
3434
|
+
get: function () { return chunkUJNJH3BS_cjs.fibonacciSegment_default; }
|
|
3232
3435
|
});
|
|
3233
3436
|
Object.defineProperty(exports, "fibonacciSpeedResistanceFan", {
|
|
3234
3437
|
enumerable: true,
|
|
3235
|
-
get: function () { return
|
|
3438
|
+
get: function () { return chunkUJNJH3BS_cjs.fibonacciSpeedResistanceFan_default; }
|
|
3236
3439
|
});
|
|
3237
3440
|
Object.defineProperty(exports, "fibonacciSpiral", {
|
|
3238
3441
|
enumerable: true,
|
|
3239
|
-
get: function () { return
|
|
3442
|
+
get: function () { return chunkUJNJH3BS_cjs.fibonacciSpiral_default; }
|
|
3240
3443
|
});
|
|
3241
3444
|
Object.defineProperty(exports, "fiveWaves", {
|
|
3242
3445
|
enumerable: true,
|
|
3243
|
-
get: function () { return
|
|
3446
|
+
get: function () { return chunkUJNJH3BS_cjs.fiveWaves_default; }
|
|
3244
3447
|
});
|
|
3245
3448
|
Object.defineProperty(exports, "gannBox", {
|
|
3246
3449
|
enumerable: true,
|
|
3247
|
-
get: function () { return
|
|
3450
|
+
get: function () { return chunkUJNJH3BS_cjs.gannBox_default; }
|
|
3248
3451
|
});
|
|
3249
3452
|
Object.defineProperty(exports, "gannFan", {
|
|
3250
3453
|
enumerable: true,
|
|
3251
|
-
get: function () { return
|
|
3454
|
+
get: function () { return chunkUJNJH3BS_cjs.gannFan_default; }
|
|
3252
3455
|
});
|
|
3253
3456
|
Object.defineProperty(exports, "hma", {
|
|
3254
3457
|
enumerable: true,
|
|
3255
|
-
get: function () { return
|
|
3458
|
+
get: function () { return chunkUJNJH3BS_cjs.hma_default; }
|
|
3256
3459
|
});
|
|
3257
3460
|
Object.defineProperty(exports, "ichimoku", {
|
|
3258
3461
|
enumerable: true,
|
|
3259
|
-
get: function () { return
|
|
3462
|
+
get: function () { return chunkUJNJH3BS_cjs.ichimoku_default; }
|
|
3260
3463
|
});
|
|
3261
3464
|
Object.defineProperty(exports, "indicators", {
|
|
3262
3465
|
enumerable: true,
|
|
3263
|
-
get: function () { return
|
|
3466
|
+
get: function () { return chunkUJNJH3BS_cjs.indicators; }
|
|
3264
3467
|
});
|
|
3265
3468
|
Object.defineProperty(exports, "longPosition", {
|
|
3266
3469
|
enumerable: true,
|
|
3267
|
-
get: function () { return
|
|
3470
|
+
get: function () { return chunkUJNJH3BS_cjs.longPosition_default; }
|
|
3268
3471
|
});
|
|
3269
3472
|
Object.defineProperty(exports, "maRibbon", {
|
|
3270
3473
|
enumerable: true,
|
|
3271
|
-
get: function () { return
|
|
3474
|
+
get: function () { return chunkUJNJH3BS_cjs.maRibbon_default; }
|
|
3272
3475
|
});
|
|
3273
3476
|
Object.defineProperty(exports, "macdTv", {
|
|
3274
3477
|
enumerable: true,
|
|
3275
|
-
get: function () { return
|
|
3478
|
+
get: function () { return chunkUJNJH3BS_cjs.macdTv_default; }
|
|
3276
3479
|
});
|
|
3277
3480
|
Object.defineProperty(exports, "measure", {
|
|
3278
3481
|
enumerable: true,
|
|
3279
|
-
get: function () { return
|
|
3482
|
+
get: function () { return chunkUJNJH3BS_cjs.measure_default; }
|
|
3280
3483
|
});
|
|
3281
3484
|
Object.defineProperty(exports, "orderLine", {
|
|
3282
3485
|
enumerable: true,
|
|
3283
|
-
get: function () { return
|
|
3486
|
+
get: function () { return chunkUJNJH3BS_cjs.orderLine_default; }
|
|
3284
3487
|
});
|
|
3285
3488
|
Object.defineProperty(exports, "overlays", {
|
|
3286
3489
|
enumerable: true,
|
|
3287
|
-
get: function () { return
|
|
3490
|
+
get: function () { return chunkUJNJH3BS_cjs.overlays; }
|
|
3288
3491
|
});
|
|
3289
3492
|
Object.defineProperty(exports, "parallelChannel", {
|
|
3290
3493
|
enumerable: true,
|
|
3291
|
-
get: function () { return
|
|
3494
|
+
get: function () { return chunkUJNJH3BS_cjs.parallelChannel_default; }
|
|
3292
3495
|
});
|
|
3293
3496
|
Object.defineProperty(exports, "parallelogram", {
|
|
3294
3497
|
enumerable: true,
|
|
3295
|
-
get: function () { return
|
|
3498
|
+
get: function () { return chunkUJNJH3BS_cjs.parallelogram_default; }
|
|
3296
3499
|
});
|
|
3297
3500
|
Object.defineProperty(exports, "pivotPoints", {
|
|
3298
3501
|
enumerable: true,
|
|
3299
|
-
get: function () { return
|
|
3502
|
+
get: function () { return chunkUJNJH3BS_cjs.pivotPoints_default; }
|
|
3300
3503
|
});
|
|
3301
3504
|
Object.defineProperty(exports, "ray", {
|
|
3302
3505
|
enumerable: true,
|
|
3303
|
-
get: function () { return
|
|
3506
|
+
get: function () { return chunkUJNJH3BS_cjs.ray_default; }
|
|
3304
3507
|
});
|
|
3305
3508
|
Object.defineProperty(exports, "rect", {
|
|
3306
3509
|
enumerable: true,
|
|
3307
|
-
get: function () { return
|
|
3510
|
+
get: function () { return chunkUJNJH3BS_cjs.rect_default; }
|
|
3308
3511
|
});
|
|
3309
3512
|
Object.defineProperty(exports, "registerExtensions", {
|
|
3310
3513
|
enumerable: true,
|
|
3311
|
-
get: function () { return
|
|
3514
|
+
get: function () { return chunkUJNJH3BS_cjs.registerExtensions; }
|
|
3312
3515
|
});
|
|
3313
3516
|
Object.defineProperty(exports, "rsiTv", {
|
|
3314
3517
|
enumerable: true,
|
|
3315
|
-
get: function () { return
|
|
3518
|
+
get: function () { return chunkUJNJH3BS_cjs.rsiTv_default; }
|
|
3316
3519
|
});
|
|
3317
3520
|
Object.defineProperty(exports, "shortPosition", {
|
|
3318
3521
|
enumerable: true,
|
|
3319
|
-
get: function () { return
|
|
3522
|
+
get: function () { return chunkUJNJH3BS_cjs.shortPosition_default; }
|
|
3320
3523
|
});
|
|
3321
3524
|
Object.defineProperty(exports, "stochastic", {
|
|
3322
3525
|
enumerable: true,
|
|
3323
|
-
get: function () { return
|
|
3526
|
+
get: function () { return chunkUJNJH3BS_cjs.stochastic_default; }
|
|
3324
3527
|
});
|
|
3325
3528
|
Object.defineProperty(exports, "superTrend", {
|
|
3326
3529
|
enumerable: true,
|
|
3327
|
-
get: function () { return
|
|
3530
|
+
get: function () { return chunkUJNJH3BS_cjs.superTrend_default; }
|
|
3328
3531
|
});
|
|
3329
3532
|
Object.defineProperty(exports, "threeWaves", {
|
|
3330
3533
|
enumerable: true,
|
|
3331
|
-
get: function () { return
|
|
3534
|
+
get: function () { return chunkUJNJH3BS_cjs.threeWaves_default; }
|
|
3332
3535
|
});
|
|
3333
3536
|
Object.defineProperty(exports, "triangle", {
|
|
3334
3537
|
enumerable: true,
|
|
3335
|
-
get: function () { return
|
|
3538
|
+
get: function () { return chunkUJNJH3BS_cjs.triangle_default; }
|
|
3336
3539
|
});
|
|
3337
3540
|
Object.defineProperty(exports, "vwap", {
|
|
3338
3541
|
enumerable: true,
|
|
3339
|
-
get: function () { return
|
|
3542
|
+
get: function () { return chunkUJNJH3BS_cjs.vwap_default; }
|
|
3340
3543
|
});
|
|
3341
3544
|
Object.defineProperty(exports, "xabcd", {
|
|
3342
3545
|
enumerable: true,
|
|
3343
|
-
get: function () { return
|
|
3546
|
+
get: function () { return chunkUJNJH3BS_cjs.xabcd_default; }
|
|
3344
3547
|
});
|
|
3345
3548
|
exports.CANDLE_TYPES = CANDLE_TYPES;
|
|
3346
3549
|
exports.COMPARE_RULES = COMPARE_RULES;
|