@pradeepjadhav/trading-reload-chart 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +87 -0
- package/README.md +256 -0
- package/dist/canvas/layers/AxisLayerX/AxisLayerX.d.ts +27 -0
- package/dist/canvas/layers/AxisLayerX/AxisLayerX.helpers.d.ts +32 -0
- package/dist/canvas/layers/AxisLayerX/AxisLayerX.types.d.ts +10 -0
- package/dist/canvas/layers/AxisLayerY/AxisLayerY.d.ts +23 -0
- package/dist/canvas/layers/AxisLayerY/AxisLayerY.helpers.d.ts +4 -0
- package/dist/canvas/layers/AxisLayerY/AxisLayerY.types.d.ts +8 -0
- package/dist/canvas/layers/CrosshairLayer.d.ts +23 -0
- package/dist/canvas/layers/CrosshairLayer.types.d.ts +10 -0
- package/dist/canvas/layers/ExistingCandlesLayer.d.ts +107 -0
- package/dist/canvas/layers/ExistingCandlesLayer.types.d.ts +56 -0
- package/dist/canvas/layers/PdhPdlLayer.d.ts +24 -0
- package/dist/canvas/layers/ShapesLayer/FibRetracementShape.d.ts +28 -0
- package/dist/canvas/layers/ShapesLayer/LineShape.d.ts +27 -0
- package/dist/canvas/layers/ShapesLayer/PathShape.d.ts +29 -0
- package/dist/canvas/layers/ShapesLayer/RectangleShape.d.ts +28 -0
- package/dist/canvas/layers/ShapesLayer/ShapesLayer.d.ts +70 -0
- package/dist/canvas/layers/ShapesLayer/ShapesLayer.helpers.d.ts +47 -0
- package/dist/canvas/layers/ShapesLayer/ShapesLayer.types.d.ts +470 -0
- package/dist/canvas/layers/ShapesLayer/ShortLongPosition.d.ts +40 -0
- package/dist/canvas/layers/ShapesLayer/ShortLongPosition.types.d.ts +11 -0
- package/dist/canvas/layers/TradeLayer/TradeLayer.d.ts +152 -0
- package/dist/canvas/layers/TradeLayer/TradeLayer.helpers.d.ts +3 -0
- package/dist/canvas/layers/TradeLayer/TradeLayer.types.d.ts +261 -0
- package/dist/canvas/layers/TradeLayer/TradeLayerEvents.d.ts +68 -0
- package/dist/canvas/layers/TradeLayer/TradeLayerEvents.types.d.ts +12 -0
- package/dist/canvas/layers/VolumeLayer/VolumeLayer.d.ts +28 -0
- package/dist/canvas/layers/VolumeLayer/VolumeLayer.types.d.ts +25 -0
- package/dist/canvas/layers/helpers/LayerHelpers.d.ts +29 -0
- package/dist/chart/ChartController.d.ts +8 -0
- package/dist/chart/ChartController.types.d.ts +224 -0
- package/dist/chart/createChartDom.d.ts +2 -0
- package/dist/chart/createChartDom.types.d.ts +13 -0
- package/dist/chart/utils/deepPartial.types.d.ts +14 -0
- package/dist/chart/utils/getCanvasPoint.d.ts +2 -0
- package/dist/chart/utils/getCanvasPoint.types.d.ts +10 -0
- package/dist/chart/utils/mergeChartConfig.d.ts +3 -0
- package/dist/chart/utils/normalizeCandleTime.d.ts +2 -0
- package/dist/chart/utils/updateTradeTPSL.d.ts +8 -0
- package/dist/config/ChartShapeConfig/chartShapeConfig.d.ts +2 -0
- package/dist/config/chartConfig.d.ts +20 -0
- package/dist/config/chartConfig.types.d.ts +642 -0
- package/dist/config/colors.d.ts +19 -0
- package/dist/config/pairs.d.ts +3 -0
- package/dist/core/CoordinateSystem.d.ts +10 -0
- package/dist/favicon.svg +1 -0
- package/dist/helpers/math.d.ts +1 -0
- package/dist/icons.svg +24 -0
- package/dist/index.d.ts +14 -0
- package/dist/models/Candle.types.d.ts +67 -0
- package/dist/models/ChartViewport.types.d.ts +30 -0
- package/dist/models/Point.types.d.ts +12 -0
- package/dist/models/Trade.types.d.ts +151 -0
- package/dist/models/VisibleRange.types.d.ts +15 -0
- package/dist/react/TradingReload.d.ts +28 -0
- package/dist/react/TradingReload.types.d.ts +74 -0
- package/dist/trading-reload-chart.css +2 -0
- package/dist/trading-reload-chart.js +3503 -0
- package/package.json +74 -0
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { MissingTradeProtectionHandleRectConfig, PastTradeIndicatorArrowConfig, TemporaryTradeProtectionHandleRectConfig, TradeHandleLineConfig, TradeHandleRectConfig, TradeHandleStyleConfig } from '../../../config/chartConfig.types';
|
|
2
|
+
import { ChartViewport } from '../../../models/ChartViewport.types';
|
|
3
|
+
import { OpenTrade, TradeType } from '../../../models/Trade.types';
|
|
4
|
+
/**
|
|
5
|
+
* Type of existing trade handle shown on open positions.
|
|
6
|
+
*
|
|
7
|
+
* @example `"stopLoss"`
|
|
8
|
+
*/
|
|
9
|
+
export type TradeHandleType = "startPrice" | "stopLoss" | "takeProfit";
|
|
10
|
+
/**
|
|
11
|
+
* Type of protection handle used when a trade is missing SL or TP.
|
|
12
|
+
*
|
|
13
|
+
* @example `"takeProfit"`
|
|
14
|
+
*/
|
|
15
|
+
export type TradeProtectionHandleType = "stopLoss" | "takeProfit";
|
|
16
|
+
export type TradeHitboxKind = "existingHandle" | "missingProtectionHandle";
|
|
17
|
+
export type TradeHandleArea = {
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
width: number;
|
|
21
|
+
height: number;
|
|
22
|
+
};
|
|
23
|
+
type BaseTradeHandleHitbox = {
|
|
24
|
+
x: number;
|
|
25
|
+
y: number;
|
|
26
|
+
width: number;
|
|
27
|
+
height: number;
|
|
28
|
+
trade: OpenTrade;
|
|
29
|
+
type: TradeHandleType;
|
|
30
|
+
price: number;
|
|
31
|
+
viewport: ChartViewport;
|
|
32
|
+
kind?: TradeHitboxKind;
|
|
33
|
+
};
|
|
34
|
+
export type ExistingTradeHandleHitbox = BaseTradeHandleHitbox & {
|
|
35
|
+
kind?: "existingHandle";
|
|
36
|
+
labelArea: TradeHandleArea;
|
|
37
|
+
closeButtonArea: TradeHandleArea;
|
|
38
|
+
};
|
|
39
|
+
export type MissingTradeProtectionHandleHitbox = BaseTradeHandleHitbox & {
|
|
40
|
+
kind: "missingProtectionHandle";
|
|
41
|
+
type: TradeProtectionHandleType;
|
|
42
|
+
labelArea: TradeHandleArea;
|
|
43
|
+
closeButtonArea: TradeHandleArea;
|
|
44
|
+
};
|
|
45
|
+
export type TradeHandleHitbox = ExistingTradeHandleHitbox | MissingTradeProtectionHandleHitbox;
|
|
46
|
+
export type TemporaryTradeProtectionDrag = {
|
|
47
|
+
visible: boolean;
|
|
48
|
+
trade: OpenTrade;
|
|
49
|
+
type: TradeProtectionHandleType;
|
|
50
|
+
price: number;
|
|
51
|
+
viewport: ChartViewport;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Historical trade marker rendered on the chart after a position is closed.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* const trade: PastTrade = {
|
|
59
|
+
* symbol: "EURUSD",
|
|
60
|
+
* type: "sell",
|
|
61
|
+
* startTime: 1716796800000,
|
|
62
|
+
* closeTime: 1716800400000,
|
|
63
|
+
* openPrice: 1.089,
|
|
64
|
+
* closePrice: 1.086,
|
|
65
|
+
* volume: 1,
|
|
66
|
+
* sl: 1.091,
|
|
67
|
+
* tp: 1.086,
|
|
68
|
+
* commission: 0,
|
|
69
|
+
* swap: 0,
|
|
70
|
+
* pnl: 30,
|
|
71
|
+
* };
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export type PastTrade = {
|
|
75
|
+
symbol: string;
|
|
76
|
+
type: TradeType;
|
|
77
|
+
startTime: number;
|
|
78
|
+
closeTime: number;
|
|
79
|
+
openPrice: number;
|
|
80
|
+
closePrice: number;
|
|
81
|
+
volume: number;
|
|
82
|
+
sl: number | null;
|
|
83
|
+
tp: number | null;
|
|
84
|
+
commission: number;
|
|
85
|
+
swap: number;
|
|
86
|
+
pnl: number;
|
|
87
|
+
};
|
|
88
|
+
export type TradeLayerEventsOptions = {
|
|
89
|
+
canvas: HTMLCanvasElement;
|
|
90
|
+
getHandleHitboxes: () => TradeHandleHitbox[];
|
|
91
|
+
/**
|
|
92
|
+
* Returns the current market price (latest candle close / live candle close).
|
|
93
|
+
* Used to enforce TP/SL constraints during drag.
|
|
94
|
+
*/
|
|
95
|
+
getCurrentPrice?: () => number;
|
|
96
|
+
onDrag?: (payload: {
|
|
97
|
+
trade: OpenTrade;
|
|
98
|
+
type: TradeHandleType;
|
|
99
|
+
price: number;
|
|
100
|
+
}) => void;
|
|
101
|
+
onMissingProtectionDrag?: (payload: {
|
|
102
|
+
trade: OpenTrade;
|
|
103
|
+
type: TradeProtectionHandleType;
|
|
104
|
+
price: number;
|
|
105
|
+
}) => void;
|
|
106
|
+
onMissingProtectionDragEnd?: (payload: {
|
|
107
|
+
trade: OpenTrade;
|
|
108
|
+
type: TradeProtectionHandleType;
|
|
109
|
+
price: number;
|
|
110
|
+
}) => void;
|
|
111
|
+
onMissingProtectionDragCancel?: () => void;
|
|
112
|
+
onTradeModified?: (payload: {
|
|
113
|
+
ticket: number;
|
|
114
|
+
tp?: number | null;
|
|
115
|
+
sl?: number | null;
|
|
116
|
+
}) => void;
|
|
117
|
+
onTradeCloseClicked?: (payload: {
|
|
118
|
+
ticket: number;
|
|
119
|
+
volume?: number;
|
|
120
|
+
}) => void;
|
|
121
|
+
};
|
|
122
|
+
export type TradeLayerOptions = {
|
|
123
|
+
canvas: HTMLCanvasElement;
|
|
124
|
+
};
|
|
125
|
+
export type TradeHandleRenderState = {
|
|
126
|
+
price: number;
|
|
127
|
+
type: TradeHandleType;
|
|
128
|
+
trade: OpenTrade;
|
|
129
|
+
viewport: ChartViewport;
|
|
130
|
+
y: number;
|
|
131
|
+
handleStyleConfig: TradeHandleStyleConfig;
|
|
132
|
+
handleConfig: TradeHandleRectConfig;
|
|
133
|
+
lineConfig: TradeHandleLineConfig;
|
|
134
|
+
handleX: number;
|
|
135
|
+
handleY: number;
|
|
136
|
+
handleWidth: number;
|
|
137
|
+
handleHeight: number;
|
|
138
|
+
};
|
|
139
|
+
export type MissingProtectionHandleRenderState = {
|
|
140
|
+
price: number;
|
|
141
|
+
type: TradeProtectionHandleType;
|
|
142
|
+
trade: OpenTrade;
|
|
143
|
+
viewport: ChartViewport;
|
|
144
|
+
y: number;
|
|
145
|
+
config: MissingTradeProtectionHandleRectConfig;
|
|
146
|
+
handleX: number;
|
|
147
|
+
handleY: number;
|
|
148
|
+
handleWidth: number;
|
|
149
|
+
handleHeight: number;
|
|
150
|
+
};
|
|
151
|
+
export type TemporaryProtectionRenderState = {
|
|
152
|
+
price: number;
|
|
153
|
+
type: TradeProtectionHandleType;
|
|
154
|
+
trade: OpenTrade;
|
|
155
|
+
viewport: ChartViewport;
|
|
156
|
+
y: number;
|
|
157
|
+
handleConfig: TemporaryTradeProtectionHandleRectConfig;
|
|
158
|
+
lineConfig: TradeHandleLineConfig;
|
|
159
|
+
handleX: number;
|
|
160
|
+
handleY: number;
|
|
161
|
+
handleWidth: number;
|
|
162
|
+
handleHeight: number;
|
|
163
|
+
};
|
|
164
|
+
export type PastTradeIndicatorPoint = {
|
|
165
|
+
x: number;
|
|
166
|
+
y: number;
|
|
167
|
+
price: number;
|
|
168
|
+
time: number;
|
|
169
|
+
};
|
|
170
|
+
export type PastTradeIndicatorRenderState = {
|
|
171
|
+
trade: PastTrade;
|
|
172
|
+
start: PastTradeIndicatorPoint;
|
|
173
|
+
close: PastTradeIndicatorPoint;
|
|
174
|
+
arrowWidth: number;
|
|
175
|
+
arrowHeight: number;
|
|
176
|
+
};
|
|
177
|
+
export type DrawTradeHandleOptions = {
|
|
178
|
+
price: number;
|
|
179
|
+
type: TradeHandleType;
|
|
180
|
+
trade: OpenTrade;
|
|
181
|
+
};
|
|
182
|
+
export type CreateHitBoxOptions = {
|
|
183
|
+
price: number;
|
|
184
|
+
trade: OpenTrade;
|
|
185
|
+
type: TradeHandleType;
|
|
186
|
+
x: number;
|
|
187
|
+
y: number;
|
|
188
|
+
width: number;
|
|
189
|
+
height: number;
|
|
190
|
+
viewport: ChartViewport;
|
|
191
|
+
};
|
|
192
|
+
export type CreateMissingProtectionHitBoxOptions = {
|
|
193
|
+
price: number;
|
|
194
|
+
trade: OpenTrade;
|
|
195
|
+
type: TradeProtectionHandleType;
|
|
196
|
+
x: number;
|
|
197
|
+
y: number;
|
|
198
|
+
width: number;
|
|
199
|
+
height: number;
|
|
200
|
+
viewport: ChartViewport;
|
|
201
|
+
};
|
|
202
|
+
export type DrawHandleLineOptions = {
|
|
203
|
+
x1: number;
|
|
204
|
+
x2: number;
|
|
205
|
+
y: number;
|
|
206
|
+
config: TradeHandleLineConfig;
|
|
207
|
+
};
|
|
208
|
+
export type DrawConnectorLineOptions = {
|
|
209
|
+
x1: number;
|
|
210
|
+
y1: number;
|
|
211
|
+
x2: number;
|
|
212
|
+
y2: number;
|
|
213
|
+
config: TradeHandleLineConfig;
|
|
214
|
+
};
|
|
215
|
+
export type DrawHandleRectOptions = {
|
|
216
|
+
x: number;
|
|
217
|
+
y: number;
|
|
218
|
+
width: number;
|
|
219
|
+
config: TradeHandleRectConfig;
|
|
220
|
+
};
|
|
221
|
+
export type DrawMissingProtectionHandleRectOptions = {
|
|
222
|
+
x: number;
|
|
223
|
+
y: number;
|
|
224
|
+
width: number;
|
|
225
|
+
config: MissingTradeProtectionHandleRectConfig;
|
|
226
|
+
};
|
|
227
|
+
export type DrawTemporaryProtectionHandleRectOptions = {
|
|
228
|
+
x: number;
|
|
229
|
+
y: number;
|
|
230
|
+
width: number;
|
|
231
|
+
config: TemporaryTradeProtectionHandleRectConfig;
|
|
232
|
+
};
|
|
233
|
+
export type DrawHandleSectionsOptions = {
|
|
234
|
+
handleType: TradeHandleType;
|
|
235
|
+
handleX: number;
|
|
236
|
+
handleY: number;
|
|
237
|
+
handleWidth: number;
|
|
238
|
+
handleHeight: number;
|
|
239
|
+
handleConfig: TradeHandleRectConfig;
|
|
240
|
+
trade: OpenTrade;
|
|
241
|
+
y: number;
|
|
242
|
+
};
|
|
243
|
+
export type DrawPastTradeArrowOptions = {
|
|
244
|
+
x: number;
|
|
245
|
+
y: number;
|
|
246
|
+
type: TradeType;
|
|
247
|
+
width: number;
|
|
248
|
+
height: number;
|
|
249
|
+
config: PastTradeIndicatorArrowConfig;
|
|
250
|
+
};
|
|
251
|
+
export type HandleSection = {
|
|
252
|
+
label: string;
|
|
253
|
+
width: number;
|
|
254
|
+
visible: boolean;
|
|
255
|
+
color?: string;
|
|
256
|
+
};
|
|
257
|
+
export type LineBlockedRange = {
|
|
258
|
+
x1: number;
|
|
259
|
+
x2: number;
|
|
260
|
+
};
|
|
261
|
+
export {};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { TradeLayerEventsOptions } from './TradeLayer.types';
|
|
2
|
+
export declare class TradeLayerEvents {
|
|
3
|
+
#private;
|
|
4
|
+
constructor(options: TradeLayerEventsOptions);
|
|
5
|
+
cancelActiveInteraction(): void;
|
|
6
|
+
handlePointerEvent(event: PointerEvent | WheelEvent | MouseEvent): boolean;
|
|
7
|
+
private isSupportedEventType;
|
|
8
|
+
/**
|
|
9
|
+
* Converts a pointer event's client coordinates into canvas-pixel space.
|
|
10
|
+
*
|
|
11
|
+
* The canvas backing-store dimensions (canvas.width / canvas.height) may differ
|
|
12
|
+
* from the CSS-rendered size reported by getBoundingClientRect when the browser
|
|
13
|
+
* zoom level is not 100 %, when the container has sub-pixel fractional dimensions,
|
|
14
|
+
* or when DPR scaling is applied. Without the explicit scale factors the hit-test
|
|
15
|
+
* geometry (built in canvas-pixel space via priceToY) and the mouse position
|
|
16
|
+
* would live in different coordinate spaces, causing the handle to appear to
|
|
17
|
+
* lag or lead the cursor.
|
|
18
|
+
*/
|
|
19
|
+
private getCanvasMousePoint;
|
|
20
|
+
private handleActiveDrag;
|
|
21
|
+
private handleActiveMissingProtectionDrag;
|
|
22
|
+
/**
|
|
23
|
+
* Converts the current absolute canvas-pixel Y position to a price using the
|
|
24
|
+
* viewport captured at drag-start, then applies TP/SL constraints.
|
|
25
|
+
*
|
|
26
|
+
* Using an absolute calculation (startPrice − totalDeltaY × pricePerPixel)
|
|
27
|
+
* instead of an incremental one (price_{n-1} − deltaY_{n} × pricePerPixel)
|
|
28
|
+
* avoids the accumulated normalizePrice quantization errors that cause the
|
|
29
|
+
* handle to lag the cursor when moving slowly or when heavily zoomed in.
|
|
30
|
+
*/
|
|
31
|
+
private getNextDragPrice;
|
|
32
|
+
private getNextMissingProtectionPrice;
|
|
33
|
+
private handleDragEnd;
|
|
34
|
+
private handleMissingProtectionDragEnd;
|
|
35
|
+
private modifyActiveDragTrade;
|
|
36
|
+
private getHoveredHitbox;
|
|
37
|
+
private handleHoveredHitbox;
|
|
38
|
+
private handleMissingProtectionHandleHover;
|
|
39
|
+
private handleCloseButtonHover;
|
|
40
|
+
private handleCloseButtonClick;
|
|
41
|
+
private updateHandleCursor;
|
|
42
|
+
private startDrag;
|
|
43
|
+
private startMissingProtectionDrag;
|
|
44
|
+
private resetCursorIfIdle;
|
|
45
|
+
private isPointInsideArea;
|
|
46
|
+
private isProtectionHandleType;
|
|
47
|
+
/**
|
|
48
|
+
* Constrains a dragged existing TP/SL price to valid levels.
|
|
49
|
+
*
|
|
50
|
+
* TP rules:
|
|
51
|
+
* - Buy: price must be ≥ max(openPrice, currentMarketPrice)
|
|
52
|
+
* - Sell: price must be ≤ min(openPrice, currentMarketPrice)
|
|
53
|
+
*
|
|
54
|
+
* SL rules (trailing SL is permitted — SL may cross the open price):
|
|
55
|
+
* - Buy: price must be ≤ currentMarketPrice (cannot reach the profit side)
|
|
56
|
+
* - Sell: price must be ≥ currentMarketPrice
|
|
57
|
+
*/
|
|
58
|
+
private constrainExistingProtectionPrice;
|
|
59
|
+
/**
|
|
60
|
+
* Constrains a missing-protection handle drag price.
|
|
61
|
+
*
|
|
62
|
+
* TP: same side-of-market rules as constrainExistingProtectionPrice.
|
|
63
|
+
* SL: must not cross currentMarketPrice (trailing SL allowed — no openPrice floor).
|
|
64
|
+
*/
|
|
65
|
+
private constrainProtectionPrice;
|
|
66
|
+
private isBuyTrade;
|
|
67
|
+
private consumeEvent;
|
|
68
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const TRADE_LAYER_EVENT_TYPES_TO_HANDLE: readonly ["pointerdown", "pointermove", "pointerup"];
|
|
2
|
+
export type SupportedPointerEventType = (typeof TRADE_LAYER_EVENT_TYPES_TO_HANDLE)[number];
|
|
3
|
+
export type CanvasMousePoint = {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
};
|
|
7
|
+
export type HitboxArea = {
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Candle } from '../../../models/Candle.types';
|
|
2
|
+
import { ChartViewport } from '../../../models/ChartViewport.types';
|
|
3
|
+
import { VolumeLayerOptions } from './VolumeLayer.types';
|
|
4
|
+
export declare class VolumeLayer {
|
|
5
|
+
#private;
|
|
6
|
+
candles: Candle[];
|
|
7
|
+
viewport: ChartViewport | null;
|
|
8
|
+
bullishColor: string;
|
|
9
|
+
bearishColor: string;
|
|
10
|
+
opacity: number;
|
|
11
|
+
height: number;
|
|
12
|
+
bottomOffset: number;
|
|
13
|
+
minBarHeight: number;
|
|
14
|
+
constructor(options: VolumeLayerOptions);
|
|
15
|
+
setCandles(candles: Candle[]): void;
|
|
16
|
+
setLiveCandle(_candle: Candle | null | undefined): void;
|
|
17
|
+
setViewport(viewport: ChartViewport): void;
|
|
18
|
+
render(): void;
|
|
19
|
+
private drawVolumeBars;
|
|
20
|
+
private drawSingleVolumeBar;
|
|
21
|
+
private getVisibleRange;
|
|
22
|
+
private getCandleX;
|
|
23
|
+
private getMaxVolume;
|
|
24
|
+
private getVolumeAreaHeight;
|
|
25
|
+
private getVolumeBarColor;
|
|
26
|
+
private clampOpacity;
|
|
27
|
+
private clearCanvas;
|
|
28
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Candle } from '../../../models/Candle.types';
|
|
2
|
+
export type VolumeLayerOptions = {
|
|
3
|
+
canvas: HTMLCanvasElement;
|
|
4
|
+
candles: Candle[];
|
|
5
|
+
bullishColor?: string;
|
|
6
|
+
bearishColor?: string;
|
|
7
|
+
opacity?: number;
|
|
8
|
+
height?: number;
|
|
9
|
+
bottomOffset?: number;
|
|
10
|
+
minBarHeight?: number;
|
|
11
|
+
};
|
|
12
|
+
export type DrawVolumeBarsOptions = {
|
|
13
|
+
ctx: CanvasRenderingContext2D;
|
|
14
|
+
candles: Candle[];
|
|
15
|
+
startIndex: number;
|
|
16
|
+
maxVolume: number;
|
|
17
|
+
chartHeight: number;
|
|
18
|
+
};
|
|
19
|
+
export type DrawSingleVolumeBarOptions = {
|
|
20
|
+
ctx: CanvasRenderingContext2D;
|
|
21
|
+
candle: Candle;
|
|
22
|
+
candleX: number;
|
|
23
|
+
maxVolume: number;
|
|
24
|
+
chartHeight: number;
|
|
25
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a market price value
|
|
3
|
+
* into canvas Y coordinate.
|
|
4
|
+
*
|
|
5
|
+
* Shared helper used by multiple layers
|
|
6
|
+
* such as:
|
|
7
|
+
*
|
|
8
|
+
* - ExistingCandlesLayer
|
|
9
|
+
* - TradeLayer
|
|
10
|
+
* - AxisLayerY
|
|
11
|
+
*/
|
|
12
|
+
export declare const priceToY: ({ price, minPrice, priceRange, chartHeight, }: {
|
|
13
|
+
price: number;
|
|
14
|
+
minPrice: number;
|
|
15
|
+
priceRange: number;
|
|
16
|
+
chartHeight: number;
|
|
17
|
+
}) => number;
|
|
18
|
+
/**
|
|
19
|
+
* Converts a canvas Y coordinate
|
|
20
|
+
* into a market price value.
|
|
21
|
+
*
|
|
22
|
+
* Used by the crosshair labels.
|
|
23
|
+
*/
|
|
24
|
+
export declare const yToPrice: ({ y, minPrice, priceRange, chartHeight, }: {
|
|
25
|
+
y: number;
|
|
26
|
+
minPrice: number;
|
|
27
|
+
priceRange: number;
|
|
28
|
+
chartHeight: number;
|
|
29
|
+
}) => number;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ChartControllerProps } from './ChartController.types';
|
|
2
|
+
export declare class ChartController {
|
|
3
|
+
#private;
|
|
4
|
+
constructor(container: HTMLElement, props: ChartControllerProps);
|
|
5
|
+
updateProps(props: ChartControllerProps): void;
|
|
6
|
+
resetChartView(): void;
|
|
7
|
+
destroy(): void;
|
|
8
|
+
}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { Shape, ShapeAddedPayload, ShapeModifiedPayload, ShapeSelectedPayload, ShapeToolType } from '../canvas/layers/ShapesLayer/ShapesLayer.types';
|
|
2
|
+
import { PastTrade } from '../canvas/layers/TradeLayer/TradeLayer.types';
|
|
3
|
+
import { ChartConfig } from '../config/chartConfig.types';
|
|
4
|
+
import { Candle } from '../models/Candle.types';
|
|
5
|
+
import { OpenTrade } from '../models/Trade.types';
|
|
6
|
+
import { DeepPartial } from './utils/deepPartial.types';
|
|
7
|
+
/**
|
|
8
|
+
* Payload emitted when the user commits a stop-loss or take-profit change.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* const payload: TradeModifyPayload = {
|
|
13
|
+
* ticket: 101245,
|
|
14
|
+
* sl: 1.0835,
|
|
15
|
+
* tp: 1.091,
|
|
16
|
+
* };
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export type TradeModifyPayload = {
|
|
20
|
+
/** Trade ticket identifier.
|
|
21
|
+
*
|
|
22
|
+
* @example `101245`
|
|
23
|
+
*/
|
|
24
|
+
ticket: number;
|
|
25
|
+
/** New stop-loss value, or `null` to clear it.
|
|
26
|
+
*
|
|
27
|
+
* @example `1.0835`
|
|
28
|
+
*/
|
|
29
|
+
sl?: number | null;
|
|
30
|
+
/** New take-profit value, or `null` to clear it.
|
|
31
|
+
*
|
|
32
|
+
* @example `1.091`
|
|
33
|
+
*/
|
|
34
|
+
tp?: number | null;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Previous day high and low values used by overlays or external tooling.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* const previousDay: PreviousDay = {
|
|
42
|
+
* high: 1.0924,
|
|
43
|
+
* low: 1.0811,
|
|
44
|
+
* };
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export type PreviousDay = {
|
|
48
|
+
/** Previous day high price.
|
|
49
|
+
*
|
|
50
|
+
* @example `1.0924`
|
|
51
|
+
*/
|
|
52
|
+
high: number;
|
|
53
|
+
/** Previous day low price.
|
|
54
|
+
*
|
|
55
|
+
* @example `1.0811`
|
|
56
|
+
*/
|
|
57
|
+
low: number;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Controlled props consumed by the internal chart controller and by
|
|
61
|
+
* {@link TradingReload}.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* const props: ChartControllerProps = {
|
|
66
|
+
* activeSymbol: "EURUSD",
|
|
67
|
+
* candles,
|
|
68
|
+
* liveCandle,
|
|
69
|
+
* openTrades,
|
|
70
|
+
* pastTrades,
|
|
71
|
+
* shapes,
|
|
72
|
+
* activeShapeTool,
|
|
73
|
+
* onShapeAdded: ({ shape }) => setShapes((prev) => [...prev, shape]),
|
|
74
|
+
* onActiveShapeToolChange: setActiveShapeTool,
|
|
75
|
+
* };
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export type ChartControllerProps = {
|
|
79
|
+
/**
|
|
80
|
+
* Trading symbol for the current chart.
|
|
81
|
+
*
|
|
82
|
+
* @example `"EURUSD"`
|
|
83
|
+
*/
|
|
84
|
+
activeSymbol: string;
|
|
85
|
+
/**
|
|
86
|
+
* Historical candles shown by the chart.
|
|
87
|
+
*
|
|
88
|
+
* `time` values are expected in UTC milliseconds unless you also pass
|
|
89
|
+
* `brokerTimezoneOffsetMs`.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```ts
|
|
93
|
+
* candles: [{ time: 1716883200000, open: 1.084, high: 1.086, low: 1.083, close: 1.085, volume: 1200, ask: 1.0851, isClosed: true }]
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
candles: Candle[];
|
|
97
|
+
/**
|
|
98
|
+
* Forming realtime candle. Pass `null` when there is no live update.
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```ts
|
|
102
|
+
* liveCandle: { time: 1716884100000, open: 1.085, high: 1.0862, low: 1.0848, close: 1.086, volume: 320, ask: 1.0861, isClosed: false }
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
liveCandle: Candle | null;
|
|
106
|
+
/**
|
|
107
|
+
* Parent-owned list of currently open trades rendered on the chart.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```ts
|
|
111
|
+
* openTrades: [{ ticket: 101245, symbol: "EURUSD", volume: 0.5, sl: 1.0835, tp: 1.091, type: "buy", openTime: 1716883200000, openPrice: 1.085, commission: 0, swap: 0, pnl: 12.5, status: "open" }]
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
openTrades: OpenTrade[];
|
|
115
|
+
/**
|
|
116
|
+
* Completed trades rendered as historical markers.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```ts
|
|
120
|
+
* pastTrades: [{ symbol: "EURUSD", type: "sell", startTime: 1716796800000, closeTime: 1716800400000, openPrice: 1.089, closePrice: 1.086, volume: 1, sl: 1.091, tp: 1.086, commission: 0, swap: 0, pnl: 30 }]
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
pastTrades: PastTrade[];
|
|
124
|
+
/**
|
|
125
|
+
* Parent-owned shapes rendered and edited by the chart.
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```ts
|
|
129
|
+
* shapes: [{ id: "shape-1", type: "trendline", vertices: [{ time: 1716883200000, price: 1.084 }, { time: 1716886800000, price: 1.088 }] }]
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
shapes: Shape[];
|
|
133
|
+
/**
|
|
134
|
+
* Currently active drawing tool, or `null` when shape creation is disabled.
|
|
135
|
+
*
|
|
136
|
+
* @example `"rectangle"`
|
|
137
|
+
*/
|
|
138
|
+
activeShapeTool: ShapeToolType | null;
|
|
139
|
+
/**
|
|
140
|
+
* Partial chart config merged on top of the library defaults.
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```ts
|
|
144
|
+
* config: { colors: { background: "#0d1117" }, candles: { defaultWidth: 10 } }
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
config?: DeepPartial<ChartConfig>;
|
|
148
|
+
/**
|
|
149
|
+
* Optional broker timezone offset used to normalize broker-encoded candle
|
|
150
|
+
* timestamps.
|
|
151
|
+
*
|
|
152
|
+
* @example `19800000`
|
|
153
|
+
*/
|
|
154
|
+
brokerTimezoneOffsetMs?: number;
|
|
155
|
+
/**
|
|
156
|
+
* Optional previous day high/low values for related overlays.
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```ts
|
|
160
|
+
* previousDay: { high: 1.0924, low: 1.0811 }
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
previousDay?: PreviousDay | null;
|
|
164
|
+
/**
|
|
165
|
+
* Called after the user completes a brand-new shape.
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```ts
|
|
169
|
+
* onShapeAdded: ({ shape }) => setShapes((prev) => [...prev, shape])
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
onShapeAdded?: (payload: ShapeAddedPayload) => void;
|
|
173
|
+
/**
|
|
174
|
+
* Called after the user edits an existing shape.
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* ```ts
|
|
178
|
+
* onShapeModified: ({ id, shape }) => updateShape(id, shape)
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
onShapeModified?: (payload: ShapeModifiedPayload) => void;
|
|
182
|
+
/**
|
|
183
|
+
* Called when the selected shape changes, or `null` when selection clears.
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```ts
|
|
187
|
+
* onShapeSelected: (payload) => setSelectedShape(payload?.shapeId ?? null)
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
onShapeSelected?: (payload: ShapeSelectedPayload | null) => void;
|
|
191
|
+
/**
|
|
192
|
+
* Called when the chart wants the parent to change the active drawing tool.
|
|
193
|
+
*
|
|
194
|
+
* The chart sends `null` after a completed draw or Escape/cancel path.
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```ts
|
|
198
|
+
* onActiveShapeToolChange: setActiveShapeTool
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
onActiveShapeToolChange?: (tool: ShapeToolType | null) => void;
|
|
202
|
+
/**
|
|
203
|
+
* Called when the user commits an SL/TP modification on pointer release.
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* ```ts
|
|
207
|
+
* onTradeModify: async ({ ticket, sl, tp }) => {
|
|
208
|
+
* await api.modifyTrade({ ticket, sl, tp });
|
|
209
|
+
* }
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
onTradeModify?: (payload: TradeModifyPayload) => void;
|
|
213
|
+
/**
|
|
214
|
+
* Called when the user clicks the close button on a trade handle.
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```ts
|
|
218
|
+
* onTradeClose: ({ ticket }) => api.closeTrade(ticket)
|
|
219
|
+
* ```
|
|
220
|
+
*/
|
|
221
|
+
onTradeClose?: (payload: {
|
|
222
|
+
ticket: number;
|
|
223
|
+
}) => void;
|
|
224
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type ChartDomElements = {
|
|
2
|
+
root: HTMLDivElement;
|
|
3
|
+
layout: HTMLDivElement;
|
|
4
|
+
stack: HTMLDivElement;
|
|
5
|
+
volumeCanvas: HTMLCanvasElement;
|
|
6
|
+
candleCanvas: HTMLCanvasElement;
|
|
7
|
+
shapesCanvas: HTMLCanvasElement;
|
|
8
|
+
tradesCanvas: HTMLCanvasElement;
|
|
9
|
+
overlayCanvas: HTMLCanvasElement;
|
|
10
|
+
axisXCanvas: HTMLCanvasElement;
|
|
11
|
+
axisYCanvas: HTMLCanvasElement;
|
|
12
|
+
interactionTarget: HTMLDivElement;
|
|
13
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recursive partial type used for config overrides.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```ts
|
|
6
|
+
* const config: DeepPartial<ChartConfig> = {
|
|
7
|
+
* colors: { background: "#0d1117" },
|
|
8
|
+
* candles: { defaultWidth: 10 },
|
|
9
|
+
* };
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export type DeepPartial<T> = {
|
|
13
|
+
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
|
|
14
|
+
};
|