tradelab 0.1.1 → 0.2.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 +39 -15
- package/dist/cjs/data.cjs +1718 -0
- package/dist/cjs/index.cjs +2294 -0
- package/package.json +28 -6
- package/src/data/yahoo.js +40 -17
- package/src/engine/backtest.js +46 -4
- package/src/index.js +1 -0
- package/src/metrics/buildMetrics.js +32 -16
- package/src/reporting/exportBacktestArtifacts.js +13 -0
- package/src/reporting/exportMetricsJson.js +24 -0
- package/src/reporting/renderHtmlReport.js +26 -9
- package/types/data.d.ts +13 -0
- package/types/index.d.ts +512 -0
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
export type Side = "long" | "short";
|
|
2
|
+
|
|
3
|
+
export interface Candle {
|
|
4
|
+
time: number;
|
|
5
|
+
open: number;
|
|
6
|
+
high: number;
|
|
7
|
+
low: number;
|
|
8
|
+
close: number;
|
|
9
|
+
volume?: number;
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Realized equity snapshot captured during a backtest. */
|
|
14
|
+
export interface EquityPoint {
|
|
15
|
+
/** Bar timestamp in Unix milliseconds. */
|
|
16
|
+
time: number;
|
|
17
|
+
/** Alias of `time` kept for charting/export compatibility. */
|
|
18
|
+
timestamp: number;
|
|
19
|
+
/** Realized account equity at this point in the run. */
|
|
20
|
+
equity: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Lightweight chart frame for replay/export consumers. */
|
|
24
|
+
export interface ReplayFrame {
|
|
25
|
+
/** ISO timestamp string. */
|
|
26
|
+
t: string;
|
|
27
|
+
/** Close or mark price for the frame. */
|
|
28
|
+
price: number;
|
|
29
|
+
/** Realized equity at the frame time. */
|
|
30
|
+
equity: number;
|
|
31
|
+
/** Active position side, or `null` when flat. */
|
|
32
|
+
posSide: Side | null;
|
|
33
|
+
/** Active position size at the frame time. */
|
|
34
|
+
posSize: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Replay event emitted for entries, exits, adds, and scale-outs. */
|
|
38
|
+
export interface ReplayEvent {
|
|
39
|
+
/** ISO timestamp string. */
|
|
40
|
+
t: string;
|
|
41
|
+
/** Event price. */
|
|
42
|
+
price: number;
|
|
43
|
+
/** Event label such as `ENTRY`, `EXIT`, `SCALE`, or `ADD`. */
|
|
44
|
+
type: string;
|
|
45
|
+
side?: Side;
|
|
46
|
+
size?: number;
|
|
47
|
+
tradeId?: number;
|
|
48
|
+
reason?: string;
|
|
49
|
+
pnl?: number;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Chart-friendly replay payload returned by `backtest()`. */
|
|
53
|
+
export interface ReplayPayload {
|
|
54
|
+
/** Sequential per-bar frames. */
|
|
55
|
+
frames: ReplayFrame[];
|
|
56
|
+
/** Sparse trade/execution events. */
|
|
57
|
+
events: ReplayEvent[];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface TradeExit {
|
|
61
|
+
price: number;
|
|
62
|
+
time: number;
|
|
63
|
+
reason: string;
|
|
64
|
+
pnl: number;
|
|
65
|
+
exitATR?: number;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface BacktestTrade {
|
|
69
|
+
symbol?: string;
|
|
70
|
+
id?: number;
|
|
71
|
+
side: Side;
|
|
72
|
+
entry: number;
|
|
73
|
+
stop: number;
|
|
74
|
+
takeProfit: number;
|
|
75
|
+
size: number;
|
|
76
|
+
openTime: number;
|
|
77
|
+
entryFill?: number;
|
|
78
|
+
entryFeeTotal?: number;
|
|
79
|
+
initSize?: number;
|
|
80
|
+
baseSize?: number;
|
|
81
|
+
entryATR?: number;
|
|
82
|
+
mfeR?: number;
|
|
83
|
+
maeR?: number;
|
|
84
|
+
adds?: number;
|
|
85
|
+
_initRisk?: number;
|
|
86
|
+
_rr?: number;
|
|
87
|
+
exit: TradeExit;
|
|
88
|
+
[key: string]: unknown;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface SideBreakdownEntry {
|
|
92
|
+
trades: number;
|
|
93
|
+
winRate: number;
|
|
94
|
+
avgPnL: number;
|
|
95
|
+
avgR: number;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Aggregate performance metrics returned by `backtest()`. */
|
|
99
|
+
export interface BacktestMetrics {
|
|
100
|
+
/** Count of completed positions included in the aggregate metrics. */
|
|
101
|
+
trades: number;
|
|
102
|
+
/** Percent of completed positions with positive PnL. */
|
|
103
|
+
winRate: number;
|
|
104
|
+
/** Gross profit divided by gross loss. */
|
|
105
|
+
profitFactor: number;
|
|
106
|
+
/** Average PnL per completed position. */
|
|
107
|
+
expectancy: number;
|
|
108
|
+
totalR: number;
|
|
109
|
+
avgR: number;
|
|
110
|
+
/** Daily Sharpe ratio alias for quick access. */
|
|
111
|
+
sharpe: number;
|
|
112
|
+
sharpePerTrade: number;
|
|
113
|
+
sortinoPerTrade: number;
|
|
114
|
+
/** Maximum drawdown percent alias. */
|
|
115
|
+
maxDrawdown: number;
|
|
116
|
+
maxDrawdownPct: number;
|
|
117
|
+
calmar: number;
|
|
118
|
+
maxConsecWins: number;
|
|
119
|
+
maxConsecLosses: number;
|
|
120
|
+
/** Average hold time in minutes alias. */
|
|
121
|
+
avgHold: number;
|
|
122
|
+
avgHoldMin: number;
|
|
123
|
+
exposurePct: number;
|
|
124
|
+
totalPnL: number;
|
|
125
|
+
returnPct: number;
|
|
126
|
+
finalEquity: number;
|
|
127
|
+
startEquity: number;
|
|
128
|
+
profitFactor_pos: number;
|
|
129
|
+
profitFactor_leg: number;
|
|
130
|
+
winRate_pos: number;
|
|
131
|
+
winRate_leg: number;
|
|
132
|
+
/** Daily Sharpe ratio computed from realized equity changes. */
|
|
133
|
+
sharpeDaily: number;
|
|
134
|
+
sortinoDaily: number;
|
|
135
|
+
/** Long/short breakdown grouped by completed position side. */
|
|
136
|
+
sideBreakdown: {
|
|
137
|
+
long: SideBreakdownEntry;
|
|
138
|
+
short: SideBreakdownEntry;
|
|
139
|
+
};
|
|
140
|
+
/** Long-side breakdown alias. */
|
|
141
|
+
long: SideBreakdownEntry;
|
|
142
|
+
/** Short-side breakdown alias. */
|
|
143
|
+
short: SideBreakdownEntry;
|
|
144
|
+
rDist: {
|
|
145
|
+
p10: number;
|
|
146
|
+
p25: number;
|
|
147
|
+
p50: number;
|
|
148
|
+
p75: number;
|
|
149
|
+
p90: number;
|
|
150
|
+
};
|
|
151
|
+
holdDistMin: {
|
|
152
|
+
p10: number;
|
|
153
|
+
p25: number;
|
|
154
|
+
p50: number;
|
|
155
|
+
p75: number;
|
|
156
|
+
p90: number;
|
|
157
|
+
};
|
|
158
|
+
daily: {
|
|
159
|
+
count: number;
|
|
160
|
+
winRate: number;
|
|
161
|
+
avgReturn: number;
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export interface SignalContext {
|
|
166
|
+
candles: Candle[];
|
|
167
|
+
index: number;
|
|
168
|
+
bar: Candle;
|
|
169
|
+
equity: number;
|
|
170
|
+
openPosition: BacktestTrade | null;
|
|
171
|
+
pendingOrder: PendingOrder | null;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export interface SignalResult {
|
|
175
|
+
side?: Side | "buy" | "sell";
|
|
176
|
+
direction?: Side | "buy" | "sell";
|
|
177
|
+
action?: Side | "buy" | "sell";
|
|
178
|
+
entry?: number;
|
|
179
|
+
limit?: number;
|
|
180
|
+
price?: number;
|
|
181
|
+
stop?: number;
|
|
182
|
+
stopLoss?: number;
|
|
183
|
+
sl?: number;
|
|
184
|
+
takeProfit?: number;
|
|
185
|
+
target?: number;
|
|
186
|
+
tp?: number;
|
|
187
|
+
qty?: number;
|
|
188
|
+
size?: number;
|
|
189
|
+
riskPct?: number;
|
|
190
|
+
riskFraction?: number;
|
|
191
|
+
rr?: number;
|
|
192
|
+
_rr?: number;
|
|
193
|
+
_entryExpiryBars?: number;
|
|
194
|
+
_cooldownBars?: number;
|
|
195
|
+
_breakevenAtR?: number;
|
|
196
|
+
_trailAfterR?: number;
|
|
197
|
+
_maxBarsInTrade?: number;
|
|
198
|
+
_maxHoldMin?: number;
|
|
199
|
+
_initRisk?: number;
|
|
200
|
+
_imb?: { mid?: number; [key: string]: unknown };
|
|
201
|
+
[key: string]: unknown;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export type SignalFunction = (context: SignalContext) => SignalResult | null;
|
|
205
|
+
|
|
206
|
+
export interface PendingOrder {
|
|
207
|
+
side: Side;
|
|
208
|
+
entry: number;
|
|
209
|
+
stop: number;
|
|
210
|
+
tp: number;
|
|
211
|
+
riskFrac: number;
|
|
212
|
+
fixedQty?: number | null;
|
|
213
|
+
expiresAt: number;
|
|
214
|
+
startedAtIndex: number;
|
|
215
|
+
meta: SignalResult;
|
|
216
|
+
plannedRiskAbs: number;
|
|
217
|
+
[key: string]: unknown;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export interface OCOOptions {
|
|
221
|
+
mode?: "intrabar" | "close";
|
|
222
|
+
tieBreak?: "pessimistic" | "optimistic";
|
|
223
|
+
clampStops?: boolean;
|
|
224
|
+
clampEpsBps?: number;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export interface MfeTrailOptions {
|
|
228
|
+
enabled?: boolean;
|
|
229
|
+
armR?: number;
|
|
230
|
+
givebackR?: number;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export interface PyramidingOptions {
|
|
234
|
+
enabled?: boolean;
|
|
235
|
+
addAtR?: number;
|
|
236
|
+
addFrac?: number;
|
|
237
|
+
maxAdds?: number;
|
|
238
|
+
onlyAfterBreakEven?: boolean;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export interface VolScaleOptions {
|
|
242
|
+
enabled?: boolean;
|
|
243
|
+
atrPeriod?: number;
|
|
244
|
+
cutIfAtrX?: number;
|
|
245
|
+
cutFrac?: number;
|
|
246
|
+
noCutAboveR?: number;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export interface EntryChaseOptions {
|
|
250
|
+
enabled?: boolean;
|
|
251
|
+
afterBars?: number;
|
|
252
|
+
maxSlipR?: number;
|
|
253
|
+
convertOnExpiry?: boolean;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export interface BacktestOptions {
|
|
257
|
+
candles: Candle[];
|
|
258
|
+
symbol?: string;
|
|
259
|
+
equity?: number;
|
|
260
|
+
riskPct?: number;
|
|
261
|
+
riskFraction?: number;
|
|
262
|
+
signal: SignalFunction;
|
|
263
|
+
interval?: string;
|
|
264
|
+
range?: string;
|
|
265
|
+
warmupBars?: number;
|
|
266
|
+
slippageBps?: number;
|
|
267
|
+
feeBps?: number;
|
|
268
|
+
scaleOutAtR?: number;
|
|
269
|
+
scaleOutFrac?: number;
|
|
270
|
+
finalTP_R?: number;
|
|
271
|
+
maxDailyLossPct?: number;
|
|
272
|
+
atrTrailMult?: number;
|
|
273
|
+
atrTrailPeriod?: number;
|
|
274
|
+
oco?: OCOOptions;
|
|
275
|
+
triggerMode?: "intrabar" | "close";
|
|
276
|
+
flattenAtClose?: boolean;
|
|
277
|
+
dailyMaxTrades?: number;
|
|
278
|
+
postLossCooldownBars?: number;
|
|
279
|
+
mfeTrail?: MfeTrailOptions;
|
|
280
|
+
pyramiding?: PyramidingOptions;
|
|
281
|
+
volScale?: VolScaleOptions;
|
|
282
|
+
qtyStep?: number;
|
|
283
|
+
minQty?: number;
|
|
284
|
+
maxLeverage?: number;
|
|
285
|
+
entryChase?: EntryChaseOptions;
|
|
286
|
+
reanchorStopOnFill?: boolean;
|
|
287
|
+
maxSlipROnFill?: number;
|
|
288
|
+
collectEqSeries?: boolean;
|
|
289
|
+
collectReplay?: boolean;
|
|
290
|
+
strict?: boolean;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/** Full result payload returned by `backtest()`. */
|
|
294
|
+
export interface BacktestResult {
|
|
295
|
+
symbol?: string;
|
|
296
|
+
interval?: string;
|
|
297
|
+
range?: string;
|
|
298
|
+
/** Realized legs, including scale-outs and partial exits. */
|
|
299
|
+
trades: BacktestTrade[];
|
|
300
|
+
/** Completed positions only, without intermediate realized legs. */
|
|
301
|
+
positions: BacktestTrade[];
|
|
302
|
+
/** Aggregate performance statistics. */
|
|
303
|
+
metrics: BacktestMetrics;
|
|
304
|
+
/** Realized equity points suitable for charts and exports. */
|
|
305
|
+
eqSeries: EquityPoint[];
|
|
306
|
+
/** Lightweight frames/events payload for report and chart consumers. */
|
|
307
|
+
replay: ReplayPayload;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export interface CsvLoadOptions {
|
|
311
|
+
delimiter?: string;
|
|
312
|
+
skipRows?: number;
|
|
313
|
+
hasHeader?: boolean;
|
|
314
|
+
timeCol?: string | number;
|
|
315
|
+
openCol?: string | number;
|
|
316
|
+
highCol?: string | number;
|
|
317
|
+
lowCol?: string | number;
|
|
318
|
+
closeCol?: string | number;
|
|
319
|
+
volumeCol?: string | number;
|
|
320
|
+
startDate?: string | Date;
|
|
321
|
+
endDate?: string | Date;
|
|
322
|
+
customDateParser?: (value: unknown) => number | Date;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
export interface HistoricalDataOptions {
|
|
326
|
+
source?: "auto" | "yahoo" | "csv";
|
|
327
|
+
symbol?: string;
|
|
328
|
+
interval?: string;
|
|
329
|
+
period?: string | number;
|
|
330
|
+
cache?: boolean;
|
|
331
|
+
refresh?: boolean;
|
|
332
|
+
cacheDir?: string;
|
|
333
|
+
csvPath?: string;
|
|
334
|
+
csv?: CsvLoadOptions & { filePath?: string; path?: string };
|
|
335
|
+
includePrePost?: boolean;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
export interface BacktestHistoricalOptions {
|
|
339
|
+
data?: HistoricalDataOptions;
|
|
340
|
+
backtestOptions?: Omit<BacktestOptions, "candles" | "symbol" | "interval" | "range"> & {
|
|
341
|
+
symbol?: string;
|
|
342
|
+
interval?: string;
|
|
343
|
+
range?: string;
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export interface CandleStats {
|
|
348
|
+
count: number;
|
|
349
|
+
firstTime: string;
|
|
350
|
+
lastTime: string;
|
|
351
|
+
durationDays: number;
|
|
352
|
+
estimatedIntervalMin: number;
|
|
353
|
+
priceRange: {
|
|
354
|
+
low: number;
|
|
355
|
+
high: number;
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export interface CacheMeta {
|
|
360
|
+
symbol?: string;
|
|
361
|
+
interval?: string;
|
|
362
|
+
period?: string | number;
|
|
363
|
+
outDir?: string;
|
|
364
|
+
source?: string;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
export interface ExportHtmlReportOptions {
|
|
368
|
+
symbol: string;
|
|
369
|
+
interval: string;
|
|
370
|
+
range: string;
|
|
371
|
+
metrics: BacktestMetrics;
|
|
372
|
+
eqSeries: EquityPoint[];
|
|
373
|
+
replay?: ReplayPayload;
|
|
374
|
+
positions?: BacktestTrade[];
|
|
375
|
+
outDir?: string;
|
|
376
|
+
plotlyCdnUrl?: string;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
export interface ExportTradesCsvOptions {
|
|
380
|
+
symbol?: string;
|
|
381
|
+
interval?: string;
|
|
382
|
+
range?: string;
|
|
383
|
+
outDir?: string;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
export interface ExportMetricsJsonOptions {
|
|
387
|
+
result: BacktestResult;
|
|
388
|
+
symbol?: string;
|
|
389
|
+
interval?: string;
|
|
390
|
+
range?: string;
|
|
391
|
+
outDir?: string;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
export interface ExportArtifactsOptions {
|
|
395
|
+
result: BacktestResult;
|
|
396
|
+
symbol?: string;
|
|
397
|
+
interval?: string;
|
|
398
|
+
range?: string;
|
|
399
|
+
outDir?: string;
|
|
400
|
+
exportCsv?: boolean;
|
|
401
|
+
exportHtml?: boolean;
|
|
402
|
+
exportMetrics?: boolean;
|
|
403
|
+
csvSource?: "trades" | "positions";
|
|
404
|
+
plotlyCdnUrl?: string;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
export interface ArtifactPaths {
|
|
408
|
+
csv: string | null;
|
|
409
|
+
html: string | null;
|
|
410
|
+
metrics: string | null;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Run a candle-based backtest.
|
|
415
|
+
*
|
|
416
|
+
* Returns realized trade legs in `trades`, completed positions in `positions`,
|
|
417
|
+
* aggregate statistics in `metrics`, realized equity points in `eqSeries`, and
|
|
418
|
+
* chart-friendly replay frames/events in `replay`.
|
|
419
|
+
*/
|
|
420
|
+
export function backtest(options: BacktestOptions): BacktestResult;
|
|
421
|
+
export function buildMetrics(input: {
|
|
422
|
+
closed: BacktestTrade[];
|
|
423
|
+
equityStart: number;
|
|
424
|
+
equityFinal: number;
|
|
425
|
+
candles: Candle[];
|
|
426
|
+
estBarMs: number;
|
|
427
|
+
eqSeries?: EquityPoint[];
|
|
428
|
+
}): BacktestMetrics;
|
|
429
|
+
|
|
430
|
+
export function getHistoricalCandles(options?: HistoricalDataOptions): Promise<Candle[]>;
|
|
431
|
+
export function backtestHistorical(options: BacktestHistoricalOptions): Promise<BacktestResult>;
|
|
432
|
+
export function fetchHistorical(
|
|
433
|
+
symbol: string,
|
|
434
|
+
interval?: string,
|
|
435
|
+
period?: string | number,
|
|
436
|
+
options?: { includePrePost?: boolean }
|
|
437
|
+
): Promise<Candle[]>;
|
|
438
|
+
export function fetchLatestCandle(
|
|
439
|
+
symbol: string,
|
|
440
|
+
interval?: string,
|
|
441
|
+
options?: { includePrePost?: boolean }
|
|
442
|
+
): Promise<Candle | null>;
|
|
443
|
+
export function loadCandlesFromCSV(filePath: string, options?: CsvLoadOptions): Candle[];
|
|
444
|
+
export function normalizeCandles(candles: Candle[]): Candle[];
|
|
445
|
+
export function mergeCandles(...arrays: Candle[][]): Candle[];
|
|
446
|
+
export function candleStats(candles: Candle[]): CandleStats | null;
|
|
447
|
+
export function saveCandlesToCache(candles: Candle[], meta?: CacheMeta): string;
|
|
448
|
+
export function cachedCandlesPath(
|
|
449
|
+
symbol: string,
|
|
450
|
+
interval: string,
|
|
451
|
+
period: string | number,
|
|
452
|
+
outDir?: string
|
|
453
|
+
): string;
|
|
454
|
+
export function loadCandlesFromCache(
|
|
455
|
+
symbol: string,
|
|
456
|
+
interval: string,
|
|
457
|
+
period: string | number,
|
|
458
|
+
outDir?: string
|
|
459
|
+
): Candle[] | null;
|
|
460
|
+
|
|
461
|
+
export function renderHtmlReport(options: ExportHtmlReportOptions): string;
|
|
462
|
+
export function exportHtmlReport(options: ExportHtmlReportOptions): string | null;
|
|
463
|
+
export function exportTradesCsv(
|
|
464
|
+
trades: BacktestTrade[],
|
|
465
|
+
options?: ExportTradesCsvOptions
|
|
466
|
+
): string | null;
|
|
467
|
+
export function exportMetricsJSON(options: ExportMetricsJsonOptions): string;
|
|
468
|
+
export function exportBacktestArtifacts(options: ExportArtifactsOptions): ArtifactPaths;
|
|
469
|
+
|
|
470
|
+
export function ema(values: number[], period?: number): number[];
|
|
471
|
+
export function atr(bars: Candle[], period?: number): Array<number | undefined>;
|
|
472
|
+
export function swingHigh(bars: Candle[], index: number, left?: number, right?: number): boolean;
|
|
473
|
+
export function swingLow(bars: Candle[], index: number, left?: number, right?: number): boolean;
|
|
474
|
+
export function detectFVG(
|
|
475
|
+
bars: Candle[],
|
|
476
|
+
index: number
|
|
477
|
+
): { type: "bull" | "bear"; top: number; bottom: number; mid: number } | null;
|
|
478
|
+
export function lastSwing(
|
|
479
|
+
bars: Candle[],
|
|
480
|
+
index: number,
|
|
481
|
+
direction: "up" | "down"
|
|
482
|
+
): { idx: number; price: number } | null;
|
|
483
|
+
export function structureState(
|
|
484
|
+
bars: Candle[],
|
|
485
|
+
index: number
|
|
486
|
+
): {
|
|
487
|
+
lastLow: { idx: number; price: number } | null;
|
|
488
|
+
lastHigh: { idx: number; price: number } | null;
|
|
489
|
+
};
|
|
490
|
+
export function bpsOf(price: number, bps: number): number;
|
|
491
|
+
export function pct(a: number, b: number): number;
|
|
492
|
+
|
|
493
|
+
export function calculatePositionSize(input: {
|
|
494
|
+
equity: number;
|
|
495
|
+
entry: number;
|
|
496
|
+
stop: number;
|
|
497
|
+
riskFraction?: number;
|
|
498
|
+
qtyStep?: number;
|
|
499
|
+
minQty?: number;
|
|
500
|
+
maxLeverage?: number;
|
|
501
|
+
}): number;
|
|
502
|
+
|
|
503
|
+
export function offsetET(timeMs: number): number;
|
|
504
|
+
export function minutesET(timeMs: number): number;
|
|
505
|
+
export function isSession(timeMs: number, session?: "NYSE" | "FUT" | "AUTO"): boolean;
|
|
506
|
+
export function parseWindowsCSV(
|
|
507
|
+
csv: string
|
|
508
|
+
): Array<{ aMin: number; bMin: number }> | null;
|
|
509
|
+
export function inWindowsET(
|
|
510
|
+
timeMs: number,
|
|
511
|
+
windows: Array<{ aMin: number; bMin: number }>
|
|
512
|
+
): boolean;
|