@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,470 @@
|
|
|
1
|
+
import { PreviousDayHighLowConfig } from '../../../config/chartConfig.types';
|
|
2
|
+
import { Candle } from '../../../models/Candle.types';
|
|
3
|
+
import { ChartViewport } from '../../../models/ChartViewport.types';
|
|
4
|
+
import { Point2D } from '../../../models/Point.types';
|
|
5
|
+
/**
|
|
6
|
+
* Drawing tool names supported by the public chart API.
|
|
7
|
+
*
|
|
8
|
+
* @example `"trendline"`
|
|
9
|
+
*/
|
|
10
|
+
export type ShapeToolType = "trendline" | "rectangle" | "path" | "fibRetracement" | "shortPosition" | "longPosition";
|
|
11
|
+
/**
|
|
12
|
+
* Shape discriminator stored on each shape object.
|
|
13
|
+
*
|
|
14
|
+
* @example `"rectangle"`
|
|
15
|
+
*/
|
|
16
|
+
export type ShapeType = ShapeToolType;
|
|
17
|
+
/**
|
|
18
|
+
* Unique identifier for a chart shape.
|
|
19
|
+
*
|
|
20
|
+
* @example `"shape-1"`
|
|
21
|
+
*/
|
|
22
|
+
export type ShapeId = string;
|
|
23
|
+
/**
|
|
24
|
+
* Shape anchor in chart coordinates.
|
|
25
|
+
*
|
|
26
|
+
* `time` is in milliseconds UTC and `price` is the corresponding price level.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* const vertex: ShapeVertex = {
|
|
31
|
+
* time: 1716883200000,
|
|
32
|
+
* price: 1.085,
|
|
33
|
+
* };
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export type ShapeVertex = {
|
|
37
|
+
time: number;
|
|
38
|
+
price: number;
|
|
39
|
+
};
|
|
40
|
+
export type ShapePoint = Point2D;
|
|
41
|
+
export type ShapeBoundingBox = {
|
|
42
|
+
left: number;
|
|
43
|
+
top: number;
|
|
44
|
+
right: number;
|
|
45
|
+
bottom: number;
|
|
46
|
+
width: number;
|
|
47
|
+
height: number;
|
|
48
|
+
};
|
|
49
|
+
export type ShapeHandleType = "start" | "end" | "topLeft" | "topRight" | "bottomLeft" | "bottomRight" | "leftEdge" | "rightEdge" | "upperHeight" | "lowerHeight" | "move";
|
|
50
|
+
export type ShapeHandleHitbox = {
|
|
51
|
+
shapeId: ShapeId;
|
|
52
|
+
type: ShapeHandleType;
|
|
53
|
+
x: number;
|
|
54
|
+
y: number;
|
|
55
|
+
radius: number;
|
|
56
|
+
cursor?: string;
|
|
57
|
+
index?: number;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Line style used by shape borders and helper lines.
|
|
61
|
+
*
|
|
62
|
+
* @example `"dashed"`
|
|
63
|
+
*/
|
|
64
|
+
export type ShapeLineStyle = "solid" | "dashed" | "dotted";
|
|
65
|
+
/**
|
|
66
|
+
* Shared styling for line-based shapes.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* const config: CommonShapeConfig = {
|
|
71
|
+
* lineWidth: 2,
|
|
72
|
+
* lineColor: "#4ade80",
|
|
73
|
+
* lineOpacity: 1,
|
|
74
|
+
* lineStyle: "solid",
|
|
75
|
+
* handleColor: "#ffffff",
|
|
76
|
+
* handleBorderColor: "#111827",
|
|
77
|
+
* handleBorderThickness: 1,
|
|
78
|
+
* handleRadius: 4,
|
|
79
|
+
* };
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export type CommonShapeConfig = {
|
|
83
|
+
lineWidth: number;
|
|
84
|
+
lineColor: string;
|
|
85
|
+
lineOpacity: number;
|
|
86
|
+
lineStyle: ShapeLineStyle;
|
|
87
|
+
fillColor?: string;
|
|
88
|
+
fillOpacity?: number;
|
|
89
|
+
handleColor: string;
|
|
90
|
+
handleBorderColor: string;
|
|
91
|
+
handleBorderThickness: number;
|
|
92
|
+
handleRadius: number;
|
|
93
|
+
hoverLineWidth?: number;
|
|
94
|
+
selectedLineWidth?: number;
|
|
95
|
+
};
|
|
96
|
+
export type RectangleShapeConfig = CommonShapeConfig & {
|
|
97
|
+
textColor: string;
|
|
98
|
+
textOpacity: number;
|
|
99
|
+
textFontFamily: string;
|
|
100
|
+
textFontSize: number;
|
|
101
|
+
};
|
|
102
|
+
export type FibLevelValue = 1 | 0.72 | 0.618 | 0.5 | 0;
|
|
103
|
+
export type FibLevelConfig = {
|
|
104
|
+
level: FibLevelValue;
|
|
105
|
+
color: string;
|
|
106
|
+
opacity: number;
|
|
107
|
+
lineWidth: number;
|
|
108
|
+
lineStyle: ShapeLineStyle;
|
|
109
|
+
label?: string;
|
|
110
|
+
};
|
|
111
|
+
export type FibRetracementConfig = {
|
|
112
|
+
levels: FibLevelConfig[];
|
|
113
|
+
fillColor?: string;
|
|
114
|
+
fillOpacity?: number;
|
|
115
|
+
handleColor: string;
|
|
116
|
+
handleBorderColor: string;
|
|
117
|
+
handleBorderThickness: number;
|
|
118
|
+
handleRadius: number;
|
|
119
|
+
hoverLineWidth: number;
|
|
120
|
+
selectedLineWidth: number;
|
|
121
|
+
};
|
|
122
|
+
export type PositionShapeConfig = {
|
|
123
|
+
defaultWidthCandles: number;
|
|
124
|
+
defaultStopLossPercent: number;
|
|
125
|
+
defaultRiskRewardRatio: number;
|
|
126
|
+
profitFillColor: string;
|
|
127
|
+
profitFillOpacity: number;
|
|
128
|
+
lossFillColor: string;
|
|
129
|
+
lossFillOpacity: number;
|
|
130
|
+
borderColor: string;
|
|
131
|
+
borderOpacity: number;
|
|
132
|
+
borderWidth: number;
|
|
133
|
+
borderStyle: ShapeLineStyle;
|
|
134
|
+
midLineColor: string;
|
|
135
|
+
midLineOpacity: number;
|
|
136
|
+
midLineWidth: number;
|
|
137
|
+
midLineStyle: ShapeLineStyle;
|
|
138
|
+
handleColor: string;
|
|
139
|
+
handleBorderColor: string;
|
|
140
|
+
handleBorderThickness: number;
|
|
141
|
+
handleRadius: number;
|
|
142
|
+
hoverLineWidth: number;
|
|
143
|
+
selectedLineWidth: number;
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Trendline shape defined by two vertices.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```ts
|
|
150
|
+
* const shape: TrendlineShape = {
|
|
151
|
+
* id: "trend-1",
|
|
152
|
+
* type: "trendline",
|
|
153
|
+
* vertices: [
|
|
154
|
+
* { time: 1716883200000, price: 1.084 },
|
|
155
|
+
* { time: 1716886800000, price: 1.088 },
|
|
156
|
+
* ],
|
|
157
|
+
* };
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
export type TrendlineShape = {
|
|
161
|
+
id: ShapeId;
|
|
162
|
+
type: "trendline";
|
|
163
|
+
vertices: [ShapeVertex, ShapeVertex];
|
|
164
|
+
config?: Partial<ShapeConfig["trendline"]>;
|
|
165
|
+
};
|
|
166
|
+
/**
|
|
167
|
+
* Rectangle annotation with optional text.
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```ts
|
|
171
|
+
* const shape: RectangleShapeData = {
|
|
172
|
+
* id: "zone-1",
|
|
173
|
+
* type: "rectangle",
|
|
174
|
+
* vertices: [
|
|
175
|
+
* { time: 1716883200000, price: 1.084 },
|
|
176
|
+
* { time: 1716888600000, price: 1.0815 },
|
|
177
|
+
* ],
|
|
178
|
+
* text: "Demand",
|
|
179
|
+
* };
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
export type RectangleShapeData = {
|
|
183
|
+
id: ShapeId;
|
|
184
|
+
type: "rectangle";
|
|
185
|
+
vertices: [ShapeVertex, ShapeVertex];
|
|
186
|
+
text?: string;
|
|
187
|
+
config?: Partial<ShapeConfig["rectangle"]>;
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* Freeform path made from one or more vertices.
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* ```ts
|
|
194
|
+
* const shape: PathShapeData = {
|
|
195
|
+
* id: "path-1",
|
|
196
|
+
* type: "path",
|
|
197
|
+
* vertices: [
|
|
198
|
+
* { time: 1716883200000, price: 1.084 },
|
|
199
|
+
* { time: 1716885000000, price: 1.0855 },
|
|
200
|
+
* { time: 1716886800000, price: 1.085 },
|
|
201
|
+
* ],
|
|
202
|
+
* };
|
|
203
|
+
* ```
|
|
204
|
+
*/
|
|
205
|
+
export type PathShapeData = {
|
|
206
|
+
id: ShapeId;
|
|
207
|
+
type: "path";
|
|
208
|
+
vertices: ShapeVertex[];
|
|
209
|
+
config?: Partial<ShapeConfig["path"]>;
|
|
210
|
+
};
|
|
211
|
+
/**
|
|
212
|
+
* Fibonacci retracement defined by start and end vertices.
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* ```ts
|
|
216
|
+
* const shape: FibRetracementShapeData = {
|
|
217
|
+
* id: "fib-1",
|
|
218
|
+
* type: "fibRetracement",
|
|
219
|
+
* vertices: [
|
|
220
|
+
* { time: 1716883200000, price: 1.08 },
|
|
221
|
+
* { time: 1716888600000, price: 1.09 },
|
|
222
|
+
* ],
|
|
223
|
+
* };
|
|
224
|
+
* ```
|
|
225
|
+
*/
|
|
226
|
+
export type FibRetracementShapeData = {
|
|
227
|
+
id: ShapeId;
|
|
228
|
+
type: "fibRetracement";
|
|
229
|
+
vertices: [ShapeVertex, ShapeVertex];
|
|
230
|
+
config?: Partial<ShapeConfig["fibRetracement"]>;
|
|
231
|
+
};
|
|
232
|
+
/**
|
|
233
|
+
* Long or short position planning shape.
|
|
234
|
+
*
|
|
235
|
+
* @example
|
|
236
|
+
* ```ts
|
|
237
|
+
* const shape: PositionShapeData = {
|
|
238
|
+
* id: "position-1",
|
|
239
|
+
* type: "longPosition",
|
|
240
|
+
* entry: { time: 1716883200000, price: 1.085 },
|
|
241
|
+
* endTime: 1716888600000,
|
|
242
|
+
* stopLossPercent: 0.25,
|
|
243
|
+
* takeProfitPercent: 0.5,
|
|
244
|
+
* };
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
247
|
+
export type PositionShapeData = {
|
|
248
|
+
id: ShapeId;
|
|
249
|
+
type: "shortPosition" | "longPosition";
|
|
250
|
+
/**
|
|
251
|
+
* Entry/start candle time and entry price.
|
|
252
|
+
*/
|
|
253
|
+
entry: ShapeVertex;
|
|
254
|
+
/**
|
|
255
|
+
* End candle time. This keeps width stable across timeframe changes.
|
|
256
|
+
*/
|
|
257
|
+
endTime: number;
|
|
258
|
+
/**
|
|
259
|
+
* Loss area as percentage from entry price.
|
|
260
|
+
* Example: 0.25 means 0.25%.
|
|
261
|
+
*/
|
|
262
|
+
stopLossPercent: number;
|
|
263
|
+
/**
|
|
264
|
+
* Profit area as percentage from entry price.
|
|
265
|
+
* Example: 0.375 means 0.375%.
|
|
266
|
+
*/
|
|
267
|
+
takeProfitPercent: number;
|
|
268
|
+
config?: Partial<ShapeConfig["shortPosition"]> | Partial<ShapeConfig["longPosition"]>;
|
|
269
|
+
};
|
|
270
|
+
/**
|
|
271
|
+
* Union of every shape the library can render and edit.
|
|
272
|
+
*
|
|
273
|
+
* @example
|
|
274
|
+
* ```ts
|
|
275
|
+
* const shapes: Shape[] = [
|
|
276
|
+
* {
|
|
277
|
+
* id: "shape-1",
|
|
278
|
+
* type: "trendline",
|
|
279
|
+
* vertices: [
|
|
280
|
+
* { time: 1716883200000, price: 1.084 },
|
|
281
|
+
* { time: 1716886800000, price: 1.088 },
|
|
282
|
+
* ],
|
|
283
|
+
* },
|
|
284
|
+
* ];
|
|
285
|
+
* ```
|
|
286
|
+
*/
|
|
287
|
+
export type Shape = TrendlineShape | RectangleShapeData | PathShapeData | FibRetracementShapeData | PositionShapeData;
|
|
288
|
+
/**
|
|
289
|
+
* Full shape configuration tree used internally by the chart.
|
|
290
|
+
*
|
|
291
|
+
* Consumers usually pass a partial override through `config.shapes`.
|
|
292
|
+
*
|
|
293
|
+
* @example
|
|
294
|
+
* ```ts
|
|
295
|
+
* const config: ShapeConfig = {
|
|
296
|
+
* trendline: { lineWidth: 2, lineColor: "#4ade80", lineOpacity: 1, lineStyle: "solid", handleColor: "#fff", handleBorderColor: "#111827", handleBorderThickness: 1, handleRadius: 4 },
|
|
297
|
+
* rectangle: { lineWidth: 2, lineColor: "#60a5fa", lineOpacity: 1, lineStyle: "solid", handleColor: "#fff", handleBorderColor: "#111827", handleBorderThickness: 1, handleRadius: 4, textColor: "#fff", textOpacity: 1, textFontFamily: "Arial", textFontSize: 12 },
|
|
298
|
+
* path: { lineWidth: 2, lineColor: "#f59e0b", lineOpacity: 1, lineStyle: "solid", handleColor: "#fff", handleBorderColor: "#111827", handleBorderThickness: 1, handleRadius: 4 },
|
|
299
|
+
* fibRetracement: { levels: [], handleColor: "#fff", handleBorderColor: "#111827", handleBorderThickness: 1, handleRadius: 4, hoverLineWidth: 3, selectedLineWidth: 3 },
|
|
300
|
+
* shortPosition: { defaultWidthCandles: 20, defaultStopLossPercent: 0.25, defaultRiskRewardRatio: 2, profitFillColor: "#16a34a", profitFillOpacity: 0.2, lossFillColor: "#dc2626", lossFillOpacity: 0.2, borderColor: "#fff", borderOpacity: 1, borderWidth: 1, borderStyle: "solid", midLineColor: "#fff", midLineOpacity: 0.8, midLineWidth: 1, midLineStyle: "dashed", handleColor: "#fff", handleBorderColor: "#111827", handleBorderThickness: 1, handleRadius: 4, hoverLineWidth: 2, selectedLineWidth: 2 },
|
|
301
|
+
* longPosition: { defaultWidthCandles: 20, defaultStopLossPercent: 0.25, defaultRiskRewardRatio: 2, profitFillColor: "#16a34a", profitFillOpacity: 0.2, lossFillColor: "#dc2626", lossFillOpacity: 0.2, borderColor: "#fff", borderOpacity: 1, borderWidth: 1, borderStyle: "solid", midLineColor: "#fff", midLineOpacity: 0.8, midLineWidth: 1, midLineStyle: "dashed", handleColor: "#fff", handleBorderColor: "#111827", handleBorderThickness: 1, handleRadius: 4, hoverLineWidth: 2, selectedLineWidth: 2 },
|
|
302
|
+
* };
|
|
303
|
+
* ```
|
|
304
|
+
*/
|
|
305
|
+
export type ShapeConfig = {
|
|
306
|
+
trendline: CommonShapeConfig;
|
|
307
|
+
rectangle: RectangleShapeConfig;
|
|
308
|
+
path: CommonShapeConfig;
|
|
309
|
+
fibRetracement: FibRetracementConfig;
|
|
310
|
+
shortPosition: PositionShapeConfig;
|
|
311
|
+
longPosition: PositionShapeConfig;
|
|
312
|
+
};
|
|
313
|
+
/**
|
|
314
|
+
* Partial shape config override accepted through `ChartConfig`.
|
|
315
|
+
*
|
|
316
|
+
* @example
|
|
317
|
+
* ```ts
|
|
318
|
+
* const shapes: PartialShapeConfig = {
|
|
319
|
+
* trendline: { lineColor: "#22c55e" },
|
|
320
|
+
* rectangle: { textColor: "#f8fafc" },
|
|
321
|
+
* };
|
|
322
|
+
* ```
|
|
323
|
+
*/
|
|
324
|
+
export type PartialShapeConfig = Partial<{
|
|
325
|
+
trendline: Partial<CommonShapeConfig>;
|
|
326
|
+
rectangle: Partial<RectangleShapeConfig>;
|
|
327
|
+
path: Partial<CommonShapeConfig>;
|
|
328
|
+
fibRetracement: Partial<FibRetracementConfig>;
|
|
329
|
+
shortPosition: Partial<PositionShapeConfig>;
|
|
330
|
+
longPosition: Partial<PositionShapeConfig>;
|
|
331
|
+
previousDayHighLow: PreviousDayHighLowConfig;
|
|
332
|
+
}>;
|
|
333
|
+
/**
|
|
334
|
+
* Payload emitted after completing a new shape.
|
|
335
|
+
*
|
|
336
|
+
* @example
|
|
337
|
+
* ```ts
|
|
338
|
+
* onShapeAdded: ({ type, shape }) => console.log(type, shape)
|
|
339
|
+
* ```
|
|
340
|
+
*/
|
|
341
|
+
export type ShapeAddedPayload = {
|
|
342
|
+
type: ShapeType;
|
|
343
|
+
id: ShapeId;
|
|
344
|
+
shape: Shape;
|
|
345
|
+
};
|
|
346
|
+
/**
|
|
347
|
+
* Payload emitted after editing an existing shape.
|
|
348
|
+
*
|
|
349
|
+
* @example
|
|
350
|
+
* ```ts
|
|
351
|
+
* onShapeModified: ({ id, shape }) => updateShape(id, shape)
|
|
352
|
+
* ```
|
|
353
|
+
*/
|
|
354
|
+
export type ShapeModifiedPayload = {
|
|
355
|
+
id: ShapeId;
|
|
356
|
+
type: ShapeType;
|
|
357
|
+
shape: Shape;
|
|
358
|
+
};
|
|
359
|
+
/**
|
|
360
|
+
* Payload describing the currently selected shape and its resolved config.
|
|
361
|
+
*
|
|
362
|
+
* @example
|
|
363
|
+
* ```ts
|
|
364
|
+
* onShapeSelected: (payload) => {
|
|
365
|
+
* if (payload?.type === "rectangle") {
|
|
366
|
+
* console.log(payload.config.textColor);
|
|
367
|
+
* }
|
|
368
|
+
* }
|
|
369
|
+
* ```
|
|
370
|
+
*/
|
|
371
|
+
export type ShapeSelectedPayload = {
|
|
372
|
+
shapeId: ShapeId;
|
|
373
|
+
type: "trendline";
|
|
374
|
+
config: ShapeConfig["trendline"];
|
|
375
|
+
} | {
|
|
376
|
+
shapeId: ShapeId;
|
|
377
|
+
type: "rectangle";
|
|
378
|
+
config: ShapeConfig["rectangle"];
|
|
379
|
+
} | {
|
|
380
|
+
shapeId: ShapeId;
|
|
381
|
+
type: "path";
|
|
382
|
+
config: ShapeConfig["path"];
|
|
383
|
+
} | {
|
|
384
|
+
shapeId: ShapeId;
|
|
385
|
+
type: "fibRetracement";
|
|
386
|
+
config: ShapeConfig["fibRetracement"];
|
|
387
|
+
} | {
|
|
388
|
+
shapeId: ShapeId;
|
|
389
|
+
type: "shortPosition";
|
|
390
|
+
config: ShapeConfig["shortPosition"];
|
|
391
|
+
} | {
|
|
392
|
+
shapeId: ShapeId;
|
|
393
|
+
type: "longPosition";
|
|
394
|
+
config: ShapeConfig["longPosition"];
|
|
395
|
+
};
|
|
396
|
+
/**
|
|
397
|
+
* Adapter around ExistingCandlesLayer viewport/candle conversion behavior.
|
|
398
|
+
*
|
|
399
|
+
* Shapes are stored in time + price coordinates, but rendered in canvas
|
|
400
|
+
* coordinates. ShapesLayer receives the real viewport object from
|
|
401
|
+
* ExistingCandlesLayer and uses these callbacks/helpers to convert safely.
|
|
402
|
+
*/
|
|
403
|
+
export type ShapeCoordinateConverter = {
|
|
404
|
+
candles: Candle[];
|
|
405
|
+
viewport: ChartViewport | null;
|
|
406
|
+
getXForTime: (time: number) => number;
|
|
407
|
+
getYForPrice: (price: number) => number;
|
|
408
|
+
getTimeForX: (x: number) => number;
|
|
409
|
+
getPriceForY: (y: number) => number;
|
|
410
|
+
getNearestCandleTimeForX: (x: number) => number;
|
|
411
|
+
getCandleWidth: () => number;
|
|
412
|
+
};
|
|
413
|
+
export type ShapePointerContext = {
|
|
414
|
+
point: ShapePoint;
|
|
415
|
+
vertex: ShapeVertex;
|
|
416
|
+
event: PointerEvent | MouseEvent;
|
|
417
|
+
};
|
|
418
|
+
export type ShapeHitTestResult = {
|
|
419
|
+
shape: Shape;
|
|
420
|
+
handle?: ShapeHandleHitbox;
|
|
421
|
+
isBodyHit: boolean;
|
|
422
|
+
cursor: string;
|
|
423
|
+
};
|
|
424
|
+
export type ActiveShapeDraft = {
|
|
425
|
+
type: "trendline";
|
|
426
|
+
id: ShapeId;
|
|
427
|
+
vertices: [ShapeVertex, ShapeVertex];
|
|
428
|
+
} | {
|
|
429
|
+
type: "rectangle";
|
|
430
|
+
id: ShapeId;
|
|
431
|
+
vertices: [ShapeVertex, ShapeVertex];
|
|
432
|
+
} | {
|
|
433
|
+
type: "path";
|
|
434
|
+
id: ShapeId;
|
|
435
|
+
vertices: ShapeVertex[];
|
|
436
|
+
previewVertex: ShapeVertex | null;
|
|
437
|
+
} | {
|
|
438
|
+
type: "fibRetracement";
|
|
439
|
+
id: ShapeId;
|
|
440
|
+
vertices: [ShapeVertex, ShapeVertex];
|
|
441
|
+
};
|
|
442
|
+
export type ActiveShapeEdit = {
|
|
443
|
+
mode: "move";
|
|
444
|
+
shape: Shape;
|
|
445
|
+
startPoint: ShapePoint;
|
|
446
|
+
startVertex: ShapeVertex;
|
|
447
|
+
} | {
|
|
448
|
+
mode: "resize";
|
|
449
|
+
shape: Shape;
|
|
450
|
+
handleType: ShapeHandleType;
|
|
451
|
+
handleIndex?: number;
|
|
452
|
+
startPoint: ShapePoint;
|
|
453
|
+
startVertex: ShapeVertex;
|
|
454
|
+
};
|
|
455
|
+
export type ShapesLayerOptions = {
|
|
456
|
+
canvas: HTMLCanvasElement;
|
|
457
|
+
candles: Candle[];
|
|
458
|
+
activeSymbol: string;
|
|
459
|
+
shapes: Shape[];
|
|
460
|
+
activeTool?: ShapeToolType | null;
|
|
461
|
+
config?: PartialShapeConfig;
|
|
462
|
+
onShapeAdded?: (payload: ShapeAddedPayload) => void;
|
|
463
|
+
onShapeModified?: (payload: ShapeModifiedPayload) => void;
|
|
464
|
+
onShapeSelected?: (payload: ShapeSelectedPayload | null) => void;
|
|
465
|
+
onToolChange?: (tool: ShapeToolType | null) => void;
|
|
466
|
+
};
|
|
467
|
+
export type InternalDragState = {
|
|
468
|
+
edit: ActiveShapeEdit;
|
|
469
|
+
lastModifiedShape: Shape;
|
|
470
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { PositionShapeConfig, PositionShapeData, ShapeCoordinateConverter, ShapeHandleHitbox, ShapePoint, ShapeVertex } from './ShapesLayer.types';
|
|
2
|
+
import { PositionGeometry } from './ShortLongPosition.types';
|
|
3
|
+
export declare class ShortLongPosition {
|
|
4
|
+
static defaultLongConfig: PositionShapeConfig;
|
|
5
|
+
static defaultShortConfig: PositionShapeConfig;
|
|
6
|
+
static draw({ ctx, activeSymbol, shape, converter, config, selected, hovered, }: {
|
|
7
|
+
ctx: CanvasRenderingContext2D;
|
|
8
|
+
activeSymbol: string;
|
|
9
|
+
shape: PositionShapeData;
|
|
10
|
+
converter: ShapeCoordinateConverter;
|
|
11
|
+
config?: PositionShapeConfig;
|
|
12
|
+
selected?: boolean;
|
|
13
|
+
hovered?: boolean;
|
|
14
|
+
}): void;
|
|
15
|
+
static createFromVertex({ id, type, entry, converter, config, }: {
|
|
16
|
+
id: string;
|
|
17
|
+
type: PositionShapeData["type"];
|
|
18
|
+
entry: ShapeVertex;
|
|
19
|
+
converter: ShapeCoordinateConverter;
|
|
20
|
+
config?: PositionShapeConfig;
|
|
21
|
+
}): PositionShapeData;
|
|
22
|
+
static getGeometry(shape: PositionShapeData, converter: ShapeCoordinateConverter): PositionGeometry;
|
|
23
|
+
static getHandles(shape: PositionShapeData, converter: ShapeCoordinateConverter, config?: PositionShapeConfig): ShapeHandleHitbox[];
|
|
24
|
+
static hitTest({ point, shape, converter, config, }: {
|
|
25
|
+
point: ShapePoint;
|
|
26
|
+
shape: PositionShapeData;
|
|
27
|
+
converter: ShapeCoordinateConverter;
|
|
28
|
+
config?: PositionShapeConfig;
|
|
29
|
+
}): boolean;
|
|
30
|
+
static move(shape: PositionShapeData, delta: ShapeVertex): PositionShapeData;
|
|
31
|
+
static resize({ shape, handleType, vertex, converter, }: {
|
|
32
|
+
shape: PositionShapeData;
|
|
33
|
+
handleType: ShapeHandleHitbox["type"];
|
|
34
|
+
vertex: ShapeVertex;
|
|
35
|
+
converter: ShapeCoordinateConverter;
|
|
36
|
+
}): PositionShapeData;
|
|
37
|
+
private static resizeUpperHeight;
|
|
38
|
+
private static resizeLowerHeight;
|
|
39
|
+
private static drawLabels;
|
|
40
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ShapeBoundingBox, ShapePoint } from './ShapesLayer.types';
|
|
2
|
+
export type PositionGeometry = {
|
|
3
|
+
entryPoint: ShapePoint;
|
|
4
|
+
endX: number;
|
|
5
|
+
entryY: number;
|
|
6
|
+
box: ShapeBoundingBox;
|
|
7
|
+
profitBox: ShapeBoundingBox;
|
|
8
|
+
lossBox: ShapeBoundingBox;
|
|
9
|
+
upperPrice: number;
|
|
10
|
+
lowerPrice: number;
|
|
11
|
+
};
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { TemporaryTradeProtectionHandleRectConfig, TradeHandleRectConfig, TradeHandleStyleConfig } from '../../../config/chartConfig.types';
|
|
2
|
+
import { Candle } from '../../../models/Candle.types';
|
|
3
|
+
import { ChartViewport } from '../../../models/ChartViewport.types';
|
|
4
|
+
import { OpenTrade } from '../../../models/Trade.types';
|
|
5
|
+
import { CreateHitBoxOptions, CreateMissingProtectionHitBoxOptions, DrawConnectorLineOptions, DrawHandleLineOptions, DrawHandleRectOptions, DrawHandleSectionsOptions, DrawTradeHandleOptions, LineBlockedRange, PastTrade, TemporaryTradeProtectionDrag, TradeHandleHitbox, TradeHandleRenderState, TradeHandleType, TradeLayerOptions, TradeProtectionHandleType } from './TradeLayer.types';
|
|
6
|
+
export declare class TradeLayer {
|
|
7
|
+
#private;
|
|
8
|
+
isDragging: boolean;
|
|
9
|
+
trades: OpenTrade[];
|
|
10
|
+
pastTrades: PastTrade[];
|
|
11
|
+
candles: Candle[];
|
|
12
|
+
viewport: ChartViewport | null;
|
|
13
|
+
liveCandle: Candle | null;
|
|
14
|
+
handleHitboxes: TradeHandleHitbox[];
|
|
15
|
+
temporaryProtectionDrag: TemporaryTradeProtectionDrag | null;
|
|
16
|
+
constructor(options: TradeLayerOptions);
|
|
17
|
+
setTrades(trades: OpenTrade[]): void;
|
|
18
|
+
setPastTrades(pastTrades: PastTrade[]): void;
|
|
19
|
+
setCandles(candles: Candle[]): void;
|
|
20
|
+
setViewport(viewport: ChartViewport): void;
|
|
21
|
+
setLiveCandle(candle: Candle): void;
|
|
22
|
+
setIsDragging(isDragging: boolean): void;
|
|
23
|
+
setTemporaryProtectionDrag(temporaryProtectionDrag: TemporaryTradeProtectionDrag | null): void;
|
|
24
|
+
clearTemporaryProtectionDrag(): void;
|
|
25
|
+
renderLiveFeed(): void;
|
|
26
|
+
render(): void;
|
|
27
|
+
createHitBox: ({ price, trade, type, x, y, width, height, viewport }: CreateHitBoxOptions) => {
|
|
28
|
+
kind: "existingHandle";
|
|
29
|
+
price: number;
|
|
30
|
+
trade: OpenTrade;
|
|
31
|
+
type: TradeHandleType;
|
|
32
|
+
x: number;
|
|
33
|
+
y: number;
|
|
34
|
+
width: number;
|
|
35
|
+
height: number;
|
|
36
|
+
viewport: ChartViewport;
|
|
37
|
+
labelArea: {
|
|
38
|
+
x: number;
|
|
39
|
+
y: number;
|
|
40
|
+
width: number;
|
|
41
|
+
height: number;
|
|
42
|
+
};
|
|
43
|
+
closeButtonArea: {
|
|
44
|
+
x: number;
|
|
45
|
+
y: number;
|
|
46
|
+
width: number;
|
|
47
|
+
height: number;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
createMissingProtectionHitBox: ({ price, trade, type, x, y, width, height, viewport, }: CreateMissingProtectionHitBoxOptions) => {
|
|
51
|
+
kind: "missingProtectionHandle";
|
|
52
|
+
price: number;
|
|
53
|
+
trade: OpenTrade;
|
|
54
|
+
type: TradeProtectionHandleType;
|
|
55
|
+
x: number;
|
|
56
|
+
y: number;
|
|
57
|
+
width: number;
|
|
58
|
+
height: number;
|
|
59
|
+
viewport: ChartViewport;
|
|
60
|
+
labelArea: {
|
|
61
|
+
x: number;
|
|
62
|
+
y: number;
|
|
63
|
+
width: number;
|
|
64
|
+
height: number;
|
|
65
|
+
};
|
|
66
|
+
closeButtonArea: {
|
|
67
|
+
x: number;
|
|
68
|
+
y: number;
|
|
69
|
+
width: number;
|
|
70
|
+
height: number;
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
drawTrade({ trade }: {
|
|
74
|
+
trade: OpenTrade;
|
|
75
|
+
}): void;
|
|
76
|
+
drawTradeHandle({ price, type, trade }: DrawTradeHandleOptions): TradeHandleRenderState | null;
|
|
77
|
+
drawTradeHandleFromRenderState({ renderState, blockedRanges, }: {
|
|
78
|
+
renderState: TradeHandleRenderState;
|
|
79
|
+
blockedRanges?: LineBlockedRange[];
|
|
80
|
+
}): void;
|
|
81
|
+
drawHandleLine({ x1, x2, y, config }: DrawHandleLineOptions): void;
|
|
82
|
+
drawConnectorLine({ x1, y1, x2, y2, config }: DrawConnectorLineOptions): void;
|
|
83
|
+
drawHandleRect({ x, y, width, config }: DrawHandleRectOptions): void;
|
|
84
|
+
drawHandleSections({ handleType, handleX, handleY, handleWidth, handleHeight, handleConfig, trade, y, }: DrawHandleSectionsOptions): void;
|
|
85
|
+
getHandlePnLLabel({ handleType, trade }: {
|
|
86
|
+
handleType: TradeHandleType;
|
|
87
|
+
trade: OpenTrade;
|
|
88
|
+
}): string;
|
|
89
|
+
getHandleWidth(config: TradeHandleRectConfig): number;
|
|
90
|
+
getHandleX({ handleWidth, config }: {
|
|
91
|
+
handleWidth: number;
|
|
92
|
+
config: TradeHandleRectConfig;
|
|
93
|
+
}): number;
|
|
94
|
+
getTemporaryProtectionHandleX({ handleWidth, config, }: {
|
|
95
|
+
handleWidth: number;
|
|
96
|
+
config: TemporaryTradeProtectionHandleRectConfig;
|
|
97
|
+
}): number;
|
|
98
|
+
getHandleStyleConfig(type: TradeHandleType): TradeHandleStyleConfig;
|
|
99
|
+
getProtectionDirection({ trade, type }: {
|
|
100
|
+
trade: OpenTrade;
|
|
101
|
+
type: TradeProtectionHandleType;
|
|
102
|
+
}): number;
|
|
103
|
+
constrainProtectionPrice({ price, trade, type, }: {
|
|
104
|
+
price: number;
|
|
105
|
+
trade: OpenTrade;
|
|
106
|
+
type: TradeProtectionHandleType;
|
|
107
|
+
}): number;
|
|
108
|
+
private clearCanvas;
|
|
109
|
+
private resetHitboxes;
|
|
110
|
+
private drawPastTradeIndicators;
|
|
111
|
+
private getPastTradeIndicatorRenderState;
|
|
112
|
+
private drawPastTradeConnector;
|
|
113
|
+
private drawPastTradeArrows;
|
|
114
|
+
private drawPastTradeArrow;
|
|
115
|
+
private getTimeX;
|
|
116
|
+
private normalizeTimestamp;
|
|
117
|
+
private getFirstCandleIndexAtOrAfterTime;
|
|
118
|
+
private getCandleCenterX;
|
|
119
|
+
private getCandleTimeInterval;
|
|
120
|
+
private getTradeHandleRenderState;
|
|
121
|
+
private getPriceY;
|
|
122
|
+
private addHandleHitbox;
|
|
123
|
+
private addMissingProtectionHitbox;
|
|
124
|
+
private drawHandleHorizontalLines;
|
|
125
|
+
private drawTemporaryProtectionHorizontalLines;
|
|
126
|
+
private drawHorizontalLineAroundBlockedRanges;
|
|
127
|
+
private getMergedBlockedRanges;
|
|
128
|
+
private getHandleLineDash;
|
|
129
|
+
private getHandleSections;
|
|
130
|
+
private drawHandleSectionLabel;
|
|
131
|
+
private drawHandleSectionDivider;
|
|
132
|
+
private getMissingProtectionRenderStates;
|
|
133
|
+
private getMissingProtectionHandleTypes;
|
|
134
|
+
private getMissingProtectionHandleRenderState;
|
|
135
|
+
private getMissingProtectionHandleX;
|
|
136
|
+
private getLineBlockedRangesFromMissingProtectionHandles;
|
|
137
|
+
private getMissingProtectionHandleConfig;
|
|
138
|
+
private drawMissingProtectionHandleRect;
|
|
139
|
+
private drawMissingProtectionHandleLabel;
|
|
140
|
+
private drawTemporaryProtectionDrag;
|
|
141
|
+
private getTemporaryProtectionRenderState;
|
|
142
|
+
private getTemporaryProtectionHandleConfig;
|
|
143
|
+
private getTemporaryProtectionLineConfig;
|
|
144
|
+
private drawTemporaryProtectionHandleRect;
|
|
145
|
+
private drawTemporaryProtectionPnLLabel;
|
|
146
|
+
private clearRectArea;
|
|
147
|
+
private getPositionedHandleX;
|
|
148
|
+
private getHandlePnlTextColor;
|
|
149
|
+
private getProtectionPnlTextColor;
|
|
150
|
+
private isBuyTrade;
|
|
151
|
+
private formatPnlLabel;
|
|
152
|
+
}
|