backtest-kit 3.0.14 → 3.0.15
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 +47 -0
- package/build/index.cjs +80 -40
- package/build/index.mjs +80 -41
- package/package.json +1 -1
- package/types.d.ts +20 -1
package/README.md
CHANGED
|
@@ -281,6 +281,53 @@ According to this `timestamp` of a candle in backtest-kit is exactly the `openTi
|
|
|
281
281
|
- Adapter must return exactly `limit` candles
|
|
282
282
|
- Sequential timestamps: `since + i * stepMs`
|
|
283
283
|
|
|
284
|
+
|
|
285
|
+
### 🔍 How getOrderBook Works
|
|
286
|
+
|
|
287
|
+
Order book fetching uses the same temporal alignment as candles, but with a configurable time offset window instead of candle intervals.
|
|
288
|
+
|
|
289
|
+
<details>
|
|
290
|
+
<summary>
|
|
291
|
+
The Math
|
|
292
|
+
</summary>
|
|
293
|
+
|
|
294
|
+
**Time range calculation:**
|
|
295
|
+
- `when` = current execution context time (from AsyncLocalStorage)
|
|
296
|
+
- `offsetMinutes` = `CC_ORDER_BOOK_TIME_OFFSET_MINUTES` (configurable)
|
|
297
|
+
- `alignedTo` = `Math.floor(when / (offsetMinutes * 60000)) * (offsetMinutes * 60000)`
|
|
298
|
+
- `to` = `alignedTo` (aligned down to offset boundary)
|
|
299
|
+
- `from` = `alignedTo - offsetMinutes * 60000`
|
|
300
|
+
|
|
301
|
+
**Adapter contract:**
|
|
302
|
+
- `getOrderBook(symbol, depth, from, to, backtest)` is called on the exchange schema
|
|
303
|
+
- `depth` defaults to `CC_ORDER_BOOK_MAX_DEPTH_LEVELS`
|
|
304
|
+
- The `from`/`to` range represents a time window of exactly `offsetMinutes` duration
|
|
305
|
+
- Schema implementation may use the time range (backtest) or ignore it (live trading)
|
|
306
|
+
|
|
307
|
+
**Example with CC_ORDER_BOOK_TIME_OFFSET_MINUTES = 10:**
|
|
308
|
+
```
|
|
309
|
+
when = 1704067920000 // 2024-01-01 00:12:00 UTC
|
|
310
|
+
offsetMinutes = 10
|
|
311
|
+
offsetMs = 10 * 60000 // 600000ms
|
|
312
|
+
|
|
313
|
+
alignedTo = Math.floor(1704067920000 / 600000) * 600000
|
|
314
|
+
= 1704067800000 // 2024-01-01 00:10:00 UTC
|
|
315
|
+
|
|
316
|
+
to = 1704067800000 // 00:10:00 UTC
|
|
317
|
+
from = 1704067200000 // 00:00:00 UTC
|
|
318
|
+
```
|
|
319
|
+
</details>
|
|
320
|
+
|
|
321
|
+
#### Order Book Timestamp Convention:
|
|
322
|
+
|
|
323
|
+
The `from`/`to` range is a **lookback window**. The adapter selects the closest snapshot to `to` in backtest mode, or returns real-time data in live mode. Unlike candles, most exchanges (e.g. Binance `GET /api/v3/depth`) only expose the **current** order book with no historical query support — for backtest you must provide your own snapshot storage.
|
|
324
|
+
|
|
325
|
+
**Key principles:**
|
|
326
|
+
- Time range is aligned down to `CC_ORDER_BOOK_TIME_OFFSET_MINUTES` boundary
|
|
327
|
+
- `to` = aligned timestamp, `from` = `to - offsetMinutes * 60000`
|
|
328
|
+
- `depth` defaults to `CC_ORDER_BOOK_MAX_DEPTH_LEVELS`
|
|
329
|
+
- Adapter receives `(symbol, depth, from, to, backtest)` — may ignore `from`/`to` in live mode
|
|
330
|
+
|
|
284
331
|
### 🔬 Technical Details: Timestamp Alignment
|
|
285
332
|
|
|
286
333
|
**Why align timestamps to interval boundaries?**
|
package/build/index.cjs
CHANGED
|
@@ -715,7 +715,7 @@ async function writeFileAtomic(file, data, options = {}) {
|
|
|
715
715
|
var _a$2;
|
|
716
716
|
const BASE_WAIT_FOR_INIT_SYMBOL = Symbol("wait-for-init");
|
|
717
717
|
// Calculate step in milliseconds for candle close time validation
|
|
718
|
-
const INTERVAL_MINUTES$
|
|
718
|
+
const INTERVAL_MINUTES$7 = {
|
|
719
719
|
"1m": 1,
|
|
720
720
|
"3m": 3,
|
|
721
721
|
"5m": 5,
|
|
@@ -727,7 +727,7 @@ const INTERVAL_MINUTES$6 = {
|
|
|
727
727
|
"6h": 360,
|
|
728
728
|
"8h": 480,
|
|
729
729
|
};
|
|
730
|
-
const MS_PER_MINUTE$
|
|
730
|
+
const MS_PER_MINUTE$5 = 60000;
|
|
731
731
|
const PERSIST_SIGNAL_UTILS_METHOD_NAME_USE_PERSIST_SIGNAL_ADAPTER = "PersistSignalUtils.usePersistSignalAdapter";
|
|
732
732
|
const PERSIST_SIGNAL_UTILS_METHOD_NAME_READ_DATA = "PersistSignalUtils.readSignalData";
|
|
733
733
|
const PERSIST_SIGNAL_UTILS_METHOD_NAME_WRITE_DATA = "PersistSignalUtils.writeSignalData";
|
|
@@ -1627,7 +1627,7 @@ class PersistCandleUtils {
|
|
|
1627
1627
|
const isInitial = !this.getCandlesStorage.has(key);
|
|
1628
1628
|
const stateStorage = this.getCandlesStorage(symbol, interval, exchangeName);
|
|
1629
1629
|
await stateStorage.waitForInit(isInitial);
|
|
1630
|
-
const stepMs = INTERVAL_MINUTES$
|
|
1630
|
+
const stepMs = INTERVAL_MINUTES$7[interval] * MS_PER_MINUTE$5;
|
|
1631
1631
|
// Calculate expected timestamps and fetch each candle directly
|
|
1632
1632
|
const cachedCandles = [];
|
|
1633
1633
|
for (let i = 0; i < limit; i++) {
|
|
@@ -1683,7 +1683,7 @@ class PersistCandleUtils {
|
|
|
1683
1683
|
const stateStorage = this.getCandlesStorage(symbol, interval, exchangeName);
|
|
1684
1684
|
await stateStorage.waitForInit(isInitial);
|
|
1685
1685
|
// Calculate step in milliseconds to determine candle close time
|
|
1686
|
-
const stepMs = INTERVAL_MINUTES$
|
|
1686
|
+
const stepMs = INTERVAL_MINUTES$7[interval] * MS_PER_MINUTE$5;
|
|
1687
1687
|
const now = Date.now();
|
|
1688
1688
|
// Write each candle as a separate file, skipping incomplete candles
|
|
1689
1689
|
for (const candle of candles) {
|
|
@@ -1940,8 +1940,8 @@ class PersistNotificationUtils {
|
|
|
1940
1940
|
*/
|
|
1941
1941
|
const PersistNotificationAdapter = new PersistNotificationUtils();
|
|
1942
1942
|
|
|
1943
|
-
const MS_PER_MINUTE$
|
|
1944
|
-
const INTERVAL_MINUTES$
|
|
1943
|
+
const MS_PER_MINUTE$4 = 60000;
|
|
1944
|
+
const INTERVAL_MINUTES$6 = {
|
|
1945
1945
|
"1m": 1,
|
|
1946
1946
|
"3m": 3,
|
|
1947
1947
|
"5m": 5,
|
|
@@ -1971,7 +1971,7 @@ const INTERVAL_MINUTES$5 = {
|
|
|
1971
1971
|
* @returns Aligned timestamp rounded down to interval boundary
|
|
1972
1972
|
*/
|
|
1973
1973
|
const ALIGN_TO_INTERVAL_FN$2 = (timestamp, intervalMinutes) => {
|
|
1974
|
-
const intervalMs = intervalMinutes * MS_PER_MINUTE$
|
|
1974
|
+
const intervalMs = intervalMinutes * MS_PER_MINUTE$4;
|
|
1975
1975
|
return Math.floor(timestamp / intervalMs) * intervalMs;
|
|
1976
1976
|
};
|
|
1977
1977
|
/**
|
|
@@ -2116,9 +2116,9 @@ const WRITE_CANDLES_CACHE_FN$1 = functoolsKit.trycatch(functoolsKit.queued(async
|
|
|
2116
2116
|
* @returns Promise resolving to array of candle data
|
|
2117
2117
|
*/
|
|
2118
2118
|
const GET_CANDLES_FN = async (dto, since, self) => {
|
|
2119
|
-
const step = INTERVAL_MINUTES$
|
|
2119
|
+
const step = INTERVAL_MINUTES$6[dto.interval];
|
|
2120
2120
|
const sinceTimestamp = since.getTime();
|
|
2121
|
-
const untilTimestamp = sinceTimestamp + dto.limit * step * MS_PER_MINUTE$
|
|
2121
|
+
const untilTimestamp = sinceTimestamp + dto.limit * step * MS_PER_MINUTE$4;
|
|
2122
2122
|
// Try to read from cache first
|
|
2123
2123
|
const cachedCandles = await READ_CANDLES_CACHE_FN$1(dto, sinceTimestamp, untilTimestamp, self);
|
|
2124
2124
|
if (cachedCandles !== null) {
|
|
@@ -2226,11 +2226,11 @@ class ClientExchange {
|
|
|
2226
2226
|
interval,
|
|
2227
2227
|
limit,
|
|
2228
2228
|
});
|
|
2229
|
-
const step = INTERVAL_MINUTES$
|
|
2229
|
+
const step = INTERVAL_MINUTES$6[interval];
|
|
2230
2230
|
if (!step) {
|
|
2231
2231
|
throw new Error(`ClientExchange unknown interval=${interval}`);
|
|
2232
2232
|
}
|
|
2233
|
-
const stepMs = step * MS_PER_MINUTE$
|
|
2233
|
+
const stepMs = step * MS_PER_MINUTE$4;
|
|
2234
2234
|
// Align when down to interval boundary
|
|
2235
2235
|
const whenTimestamp = this.params.execution.context.when.getTime();
|
|
2236
2236
|
const alignedWhen = ALIGN_TO_INTERVAL_FN$2(whenTimestamp, step);
|
|
@@ -2307,11 +2307,11 @@ class ClientExchange {
|
|
|
2307
2307
|
if (!this.params.execution.context.backtest) {
|
|
2308
2308
|
throw new Error(`ClientExchange getNextCandles: cannot fetch future candles in live mode`);
|
|
2309
2309
|
}
|
|
2310
|
-
const step = INTERVAL_MINUTES$
|
|
2310
|
+
const step = INTERVAL_MINUTES$6[interval];
|
|
2311
2311
|
if (!step) {
|
|
2312
2312
|
throw new Error(`ClientExchange getNextCandles: unknown interval=${interval}`);
|
|
2313
2313
|
}
|
|
2314
|
-
const stepMs = step * MS_PER_MINUTE$
|
|
2314
|
+
const stepMs = step * MS_PER_MINUTE$4;
|
|
2315
2315
|
const now = Date.now();
|
|
2316
2316
|
// Align when down to interval boundary
|
|
2317
2317
|
const whenTimestamp = this.params.execution.context.when.getTime();
|
|
@@ -2475,11 +2475,11 @@ class ClientExchange {
|
|
|
2475
2475
|
sDate,
|
|
2476
2476
|
eDate,
|
|
2477
2477
|
});
|
|
2478
|
-
const step = INTERVAL_MINUTES$
|
|
2478
|
+
const step = INTERVAL_MINUTES$6[interval];
|
|
2479
2479
|
if (!step) {
|
|
2480
2480
|
throw new Error(`ClientExchange getRawCandles: unknown interval=${interval}`);
|
|
2481
2481
|
}
|
|
2482
|
-
const stepMs = step * MS_PER_MINUTE$
|
|
2482
|
+
const stepMs = step * MS_PER_MINUTE$4;
|
|
2483
2483
|
const whenTimestamp = this.params.execution.context.when.getTime();
|
|
2484
2484
|
const alignedWhen = ALIGN_TO_INTERVAL_FN$2(whenTimestamp, step);
|
|
2485
2485
|
let sinceTimestamp;
|
|
@@ -2608,7 +2608,7 @@ class ClientExchange {
|
|
|
2608
2608
|
const alignedTo = ALIGN_TO_INTERVAL_FN$2(whenTimestamp, GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES);
|
|
2609
2609
|
const to = new Date(alignedTo);
|
|
2610
2610
|
const from = new Date(alignedTo -
|
|
2611
|
-
GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES * MS_PER_MINUTE$
|
|
2611
|
+
GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES * MS_PER_MINUTE$4);
|
|
2612
2612
|
return await this.params.getOrderBook(symbol, depth, from, to, this.params.execution.context.backtest);
|
|
2613
2613
|
}
|
|
2614
2614
|
}
|
|
@@ -3073,7 +3073,7 @@ const beginTime = (run) => (...args) => {
|
|
|
3073
3073
|
return fn();
|
|
3074
3074
|
};
|
|
3075
3075
|
|
|
3076
|
-
const INTERVAL_MINUTES$
|
|
3076
|
+
const INTERVAL_MINUTES$5 = {
|
|
3077
3077
|
"1m": 1,
|
|
3078
3078
|
"3m": 3,
|
|
3079
3079
|
"5m": 5,
|
|
@@ -3586,7 +3586,7 @@ const GET_SIGNAL_FN = functoolsKit.trycatch(async (self) => {
|
|
|
3586
3586
|
}
|
|
3587
3587
|
const currentTime = self.params.execution.context.when.getTime();
|
|
3588
3588
|
{
|
|
3589
|
-
const intervalMinutes = INTERVAL_MINUTES$
|
|
3589
|
+
const intervalMinutes = INTERVAL_MINUTES$5[self.params.interval];
|
|
3590
3590
|
const intervalMs = intervalMinutes * 60 * 1000;
|
|
3591
3591
|
// Проверяем что прошел нужный интервал с последнего getSignal
|
|
3592
3592
|
if (self._lastSignalTimestamp !== null &&
|
|
@@ -8197,7 +8197,7 @@ class StrategyConnectionService {
|
|
|
8197
8197
|
* Maps FrameInterval to minutes for timestamp calculation.
|
|
8198
8198
|
* Used to generate timeframe arrays with proper spacing.
|
|
8199
8199
|
*/
|
|
8200
|
-
const INTERVAL_MINUTES$
|
|
8200
|
+
const INTERVAL_MINUTES$4 = {
|
|
8201
8201
|
"1m": 1,
|
|
8202
8202
|
"3m": 3,
|
|
8203
8203
|
"5m": 5,
|
|
@@ -8252,7 +8252,7 @@ const GET_TIMEFRAME_FN = async (symbol, self) => {
|
|
|
8252
8252
|
symbol,
|
|
8253
8253
|
});
|
|
8254
8254
|
const { interval, startDate, endDate } = self.params;
|
|
8255
|
-
const intervalMinutes = INTERVAL_MINUTES$
|
|
8255
|
+
const intervalMinutes = INTERVAL_MINUTES$4[interval];
|
|
8256
8256
|
if (!intervalMinutes) {
|
|
8257
8257
|
throw new Error(`ClientFrame unknown interval: ${interval}`);
|
|
8258
8258
|
}
|
|
@@ -26048,7 +26048,7 @@ const EXCHANGE_METHOD_NAME_FORMAT_QUANTITY = "ExchangeUtils.formatQuantity";
|
|
|
26048
26048
|
const EXCHANGE_METHOD_NAME_FORMAT_PRICE = "ExchangeUtils.formatPrice";
|
|
26049
26049
|
const EXCHANGE_METHOD_NAME_GET_ORDER_BOOK = "ExchangeUtils.getOrderBook";
|
|
26050
26050
|
const EXCHANGE_METHOD_NAME_GET_RAW_CANDLES = "ExchangeUtils.getRawCandles";
|
|
26051
|
-
const MS_PER_MINUTE$
|
|
26051
|
+
const MS_PER_MINUTE$3 = 60000;
|
|
26052
26052
|
/**
|
|
26053
26053
|
* Gets current timestamp from execution context if available.
|
|
26054
26054
|
* Returns current Date() if no execution context exists (non-trading GUI).
|
|
@@ -26103,7 +26103,7 @@ const DEFAULT_FORMAT_PRICE_FN = async (_symbol, price, _backtest) => {
|
|
|
26103
26103
|
const DEFAULT_GET_ORDER_BOOK_FN = async (_symbol, _depth, _from, _to, _backtest) => {
|
|
26104
26104
|
throw new Error(`getOrderBook is not implemented for this exchange`);
|
|
26105
26105
|
};
|
|
26106
|
-
const INTERVAL_MINUTES$
|
|
26106
|
+
const INTERVAL_MINUTES$3 = {
|
|
26107
26107
|
"1m": 1,
|
|
26108
26108
|
"3m": 3,
|
|
26109
26109
|
"5m": 5,
|
|
@@ -26133,7 +26133,7 @@ const INTERVAL_MINUTES$2 = {
|
|
|
26133
26133
|
* @returns Aligned timestamp rounded down to interval boundary
|
|
26134
26134
|
*/
|
|
26135
26135
|
const ALIGN_TO_INTERVAL_FN$1 = (timestamp, intervalMinutes) => {
|
|
26136
|
-
const intervalMs = intervalMinutes * MS_PER_MINUTE$
|
|
26136
|
+
const intervalMs = intervalMinutes * MS_PER_MINUTE$3;
|
|
26137
26137
|
return Math.floor(timestamp / intervalMs) * intervalMs;
|
|
26138
26138
|
};
|
|
26139
26139
|
/**
|
|
@@ -26271,11 +26271,11 @@ class ExchangeInstance {
|
|
|
26271
26271
|
limit,
|
|
26272
26272
|
});
|
|
26273
26273
|
const getCandles = this._methods.getCandles;
|
|
26274
|
-
const step = INTERVAL_MINUTES$
|
|
26274
|
+
const step = INTERVAL_MINUTES$3[interval];
|
|
26275
26275
|
if (!step) {
|
|
26276
26276
|
throw new Error(`ExchangeInstance unknown interval=${interval}`);
|
|
26277
26277
|
}
|
|
26278
|
-
const stepMs = step * MS_PER_MINUTE$
|
|
26278
|
+
const stepMs = step * MS_PER_MINUTE$3;
|
|
26279
26279
|
// Align when down to interval boundary
|
|
26280
26280
|
const when = await GET_TIMESTAMP_FN();
|
|
26281
26281
|
const whenTimestamp = when.getTime();
|
|
@@ -26454,7 +26454,7 @@ class ExchangeInstance {
|
|
|
26454
26454
|
const when = await GET_TIMESTAMP_FN();
|
|
26455
26455
|
const alignedTo = ALIGN_TO_INTERVAL_FN$1(when.getTime(), GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES);
|
|
26456
26456
|
const to = new Date(alignedTo);
|
|
26457
|
-
const from = new Date(alignedTo - GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES * MS_PER_MINUTE$
|
|
26457
|
+
const from = new Date(alignedTo - GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES * MS_PER_MINUTE$3);
|
|
26458
26458
|
const isBacktest = await GET_BACKTEST_FN();
|
|
26459
26459
|
return await this._methods.getOrderBook(symbol, depth, from, to, isBacktest);
|
|
26460
26460
|
};
|
|
@@ -26497,11 +26497,11 @@ class ExchangeInstance {
|
|
|
26497
26497
|
sDate,
|
|
26498
26498
|
eDate,
|
|
26499
26499
|
});
|
|
26500
|
-
const step = INTERVAL_MINUTES$
|
|
26500
|
+
const step = INTERVAL_MINUTES$3[interval];
|
|
26501
26501
|
if (!step) {
|
|
26502
26502
|
throw new Error(`ExchangeInstance getRawCandles: unknown interval=${interval}`);
|
|
26503
26503
|
}
|
|
26504
|
-
const stepMs = step * MS_PER_MINUTE$
|
|
26504
|
+
const stepMs = step * MS_PER_MINUTE$3;
|
|
26505
26505
|
const when = await GET_TIMESTAMP_FN();
|
|
26506
26506
|
const nowTimestamp = when.getTime();
|
|
26507
26507
|
const alignedNow = ALIGN_TO_INTERVAL_FN$1(nowTimestamp, step);
|
|
@@ -26772,8 +26772,8 @@ const Exchange = new ExchangeUtils();
|
|
|
26772
26772
|
|
|
26773
26773
|
const WARM_CANDLES_METHOD_NAME = "cache.warmCandles";
|
|
26774
26774
|
const CHECK_CANDLES_METHOD_NAME = "cache.checkCandles";
|
|
26775
|
-
const MS_PER_MINUTE$
|
|
26776
|
-
const INTERVAL_MINUTES$
|
|
26775
|
+
const MS_PER_MINUTE$2 = 60000;
|
|
26776
|
+
const INTERVAL_MINUTES$2 = {
|
|
26777
26777
|
"1m": 1,
|
|
26778
26778
|
"3m": 3,
|
|
26779
26779
|
"5m": 5,
|
|
@@ -26786,7 +26786,7 @@ const INTERVAL_MINUTES$1 = {
|
|
|
26786
26786
|
"8h": 480,
|
|
26787
26787
|
};
|
|
26788
26788
|
const ALIGN_TO_INTERVAL_FN = (timestamp, intervalMinutes) => {
|
|
26789
|
-
const intervalMs = intervalMinutes * MS_PER_MINUTE$
|
|
26789
|
+
const intervalMs = intervalMinutes * MS_PER_MINUTE$2;
|
|
26790
26790
|
return Math.floor(timestamp / intervalMs) * intervalMs;
|
|
26791
26791
|
};
|
|
26792
26792
|
const BAR_LENGTH = 30;
|
|
@@ -26811,11 +26811,11 @@ const PRINT_PROGRESS_FN = (fetched, total, symbol, interval) => {
|
|
|
26811
26811
|
async function checkCandles(params) {
|
|
26812
26812
|
const { symbol, exchangeName, interval, from, to, baseDir = "./dump/data/candle" } = params;
|
|
26813
26813
|
bt.loggerService.info(CHECK_CANDLES_METHOD_NAME, params);
|
|
26814
|
-
const step = INTERVAL_MINUTES$
|
|
26814
|
+
const step = INTERVAL_MINUTES$2[interval];
|
|
26815
26815
|
if (!step) {
|
|
26816
26816
|
throw new Error(`checkCandles: unsupported interval=${interval}`);
|
|
26817
26817
|
}
|
|
26818
|
-
const stepMs = step * MS_PER_MINUTE$
|
|
26818
|
+
const stepMs = step * MS_PER_MINUTE$2;
|
|
26819
26819
|
const dir = path.join(baseDir, exchangeName, symbol, interval);
|
|
26820
26820
|
const fromTs = ALIGN_TO_INTERVAL_FN(from.getTime(), step);
|
|
26821
26821
|
const toTs = ALIGN_TO_INTERVAL_FN(to.getTime(), step);
|
|
@@ -26885,11 +26885,11 @@ async function warmCandles(params) {
|
|
|
26885
26885
|
from,
|
|
26886
26886
|
to,
|
|
26887
26887
|
});
|
|
26888
|
-
const step = INTERVAL_MINUTES$
|
|
26888
|
+
const step = INTERVAL_MINUTES$2[interval];
|
|
26889
26889
|
if (!step) {
|
|
26890
26890
|
throw new Error(`warmCandles: unsupported interval=${interval}`);
|
|
26891
26891
|
}
|
|
26892
|
-
const stepMs = step * MS_PER_MINUTE$
|
|
26892
|
+
const stepMs = step * MS_PER_MINUTE$2;
|
|
26893
26893
|
const instance = new ExchangeInstance(exchangeName);
|
|
26894
26894
|
const sinceTimestamp = ALIGN_TO_INTERVAL_FN(from.getTime(), step);
|
|
26895
26895
|
const untilTimestamp = ALIGN_TO_INTERVAL_FN(to.getTime(), step);
|
|
@@ -36397,8 +36397,8 @@ const CACHE_METHOD_NAME_CLEAR = "CacheInstance.clear";
|
|
|
36397
36397
|
const CACHE_METHOD_NAME_RUN = "CacheInstance.run";
|
|
36398
36398
|
const CACHE_METHOD_NAME_GC = "CacheInstance.gc";
|
|
36399
36399
|
const CACHE_METHOD_NAME_FN = "CacheUtils.fn";
|
|
36400
|
-
const MS_PER_MINUTE = 60000;
|
|
36401
|
-
const INTERVAL_MINUTES = {
|
|
36400
|
+
const MS_PER_MINUTE$1 = 60000;
|
|
36401
|
+
const INTERVAL_MINUTES$1 = {
|
|
36402
36402
|
"1m": 1,
|
|
36403
36403
|
"3m": 3,
|
|
36404
36404
|
"5m": 5,
|
|
@@ -36431,11 +36431,11 @@ const INTERVAL_MINUTES = {
|
|
|
36431
36431
|
* ```
|
|
36432
36432
|
*/
|
|
36433
36433
|
const align = (timestamp, interval) => {
|
|
36434
|
-
const intervalMinutes = INTERVAL_MINUTES[interval];
|
|
36434
|
+
const intervalMinutes = INTERVAL_MINUTES$1[interval];
|
|
36435
36435
|
if (!intervalMinutes) {
|
|
36436
36436
|
throw new Error(`align: unknown interval=${interval}`);
|
|
36437
36437
|
}
|
|
36438
|
-
const intervalMs = intervalMinutes * MS_PER_MINUTE;
|
|
36438
|
+
const intervalMs = intervalMinutes * MS_PER_MINUTE$1;
|
|
36439
36439
|
return Math.floor(timestamp / intervalMs) * intervalMs;
|
|
36440
36440
|
};
|
|
36441
36441
|
/**
|
|
@@ -36524,7 +36524,7 @@ class CacheInstance {
|
|
|
36524
36524
|
*/
|
|
36525
36525
|
this.run = (...args) => {
|
|
36526
36526
|
bt.loggerService.debug(CACHE_METHOD_NAME_RUN, { args });
|
|
36527
|
-
const step = INTERVAL_MINUTES[this.interval];
|
|
36527
|
+
const step = INTERVAL_MINUTES$1[this.interval];
|
|
36528
36528
|
{
|
|
36529
36529
|
if (!MethodContextService.hasContext()) {
|
|
36530
36530
|
throw new Error("CacheInstance run requires method context");
|
|
@@ -37190,6 +37190,45 @@ class StrategyUtils {
|
|
|
37190
37190
|
*/
|
|
37191
37191
|
const Strategy = new StrategyUtils();
|
|
37192
37192
|
|
|
37193
|
+
const MS_PER_MINUTE = 60000;
|
|
37194
|
+
const INTERVAL_MINUTES = {
|
|
37195
|
+
"1m": 1,
|
|
37196
|
+
"3m": 3,
|
|
37197
|
+
"5m": 5,
|
|
37198
|
+
"15m": 15,
|
|
37199
|
+
"30m": 30,
|
|
37200
|
+
"1h": 60,
|
|
37201
|
+
"2h": 120,
|
|
37202
|
+
"4h": 240,
|
|
37203
|
+
"6h": 360,
|
|
37204
|
+
"8h": 480,
|
|
37205
|
+
};
|
|
37206
|
+
/**
|
|
37207
|
+
* Aligns timestamp down to the nearest interval boundary.
|
|
37208
|
+
* For example, for 15m interval: 00:17 -> 00:15, 00:44 -> 00:30
|
|
37209
|
+
*
|
|
37210
|
+
* Candle timestamp convention:
|
|
37211
|
+
* - Candle timestamp = openTime (when candle opens)
|
|
37212
|
+
* - Candle with timestamp 00:00 covers period [00:00, 00:15) for 15m interval
|
|
37213
|
+
*
|
|
37214
|
+
* Adapter contract:
|
|
37215
|
+
* - Adapter must return candles with timestamp = openTime
|
|
37216
|
+
* - First returned candle.timestamp must equal aligned since
|
|
37217
|
+
* - Adapter must return exactly `limit` candles
|
|
37218
|
+
*
|
|
37219
|
+
* @param date - Date to align
|
|
37220
|
+
* @param interval - Candle interval (e.g., "1m", "15m", "1h")
|
|
37221
|
+
* @returns New Date aligned down to interval boundary
|
|
37222
|
+
*/
|
|
37223
|
+
const alignToInterval = (date, interval) => {
|
|
37224
|
+
const minutes = INTERVAL_MINUTES[interval];
|
|
37225
|
+
if (minutes === undefined) {
|
|
37226
|
+
throw new Error(`alignToInterval: unknown interval=${interval}`);
|
|
37227
|
+
}
|
|
37228
|
+
const intervalMs = minutes * MS_PER_MINUTE;
|
|
37229
|
+
return new Date(Math.floor(date.getTime() / intervalMs) * intervalMs);
|
|
37230
|
+
};
|
|
37231
|
+
|
|
37193
37232
|
/**
|
|
37194
37233
|
* Rounds a price to the appropriate precision based on the tick size.
|
|
37195
37234
|
*
|
|
@@ -37366,6 +37405,7 @@ exports.addRiskSchema = addRiskSchema;
|
|
|
37366
37405
|
exports.addSizingSchema = addSizingSchema;
|
|
37367
37406
|
exports.addStrategySchema = addStrategySchema;
|
|
37368
37407
|
exports.addWalkerSchema = addWalkerSchema;
|
|
37408
|
+
exports.alignToInterval = alignToInterval;
|
|
37369
37409
|
exports.checkCandles = checkCandles;
|
|
37370
37410
|
exports.commitActivateScheduled = commitActivateScheduled;
|
|
37371
37411
|
exports.commitBreakeven = commitBreakeven;
|
package/build/index.mjs
CHANGED
|
@@ -695,7 +695,7 @@ async function writeFileAtomic(file, data, options = {}) {
|
|
|
695
695
|
var _a$2;
|
|
696
696
|
const BASE_WAIT_FOR_INIT_SYMBOL = Symbol("wait-for-init");
|
|
697
697
|
// Calculate step in milliseconds for candle close time validation
|
|
698
|
-
const INTERVAL_MINUTES$
|
|
698
|
+
const INTERVAL_MINUTES$7 = {
|
|
699
699
|
"1m": 1,
|
|
700
700
|
"3m": 3,
|
|
701
701
|
"5m": 5,
|
|
@@ -707,7 +707,7 @@ const INTERVAL_MINUTES$6 = {
|
|
|
707
707
|
"6h": 360,
|
|
708
708
|
"8h": 480,
|
|
709
709
|
};
|
|
710
|
-
const MS_PER_MINUTE$
|
|
710
|
+
const MS_PER_MINUTE$5 = 60000;
|
|
711
711
|
const PERSIST_SIGNAL_UTILS_METHOD_NAME_USE_PERSIST_SIGNAL_ADAPTER = "PersistSignalUtils.usePersistSignalAdapter";
|
|
712
712
|
const PERSIST_SIGNAL_UTILS_METHOD_NAME_READ_DATA = "PersistSignalUtils.readSignalData";
|
|
713
713
|
const PERSIST_SIGNAL_UTILS_METHOD_NAME_WRITE_DATA = "PersistSignalUtils.writeSignalData";
|
|
@@ -1607,7 +1607,7 @@ class PersistCandleUtils {
|
|
|
1607
1607
|
const isInitial = !this.getCandlesStorage.has(key);
|
|
1608
1608
|
const stateStorage = this.getCandlesStorage(symbol, interval, exchangeName);
|
|
1609
1609
|
await stateStorage.waitForInit(isInitial);
|
|
1610
|
-
const stepMs = INTERVAL_MINUTES$
|
|
1610
|
+
const stepMs = INTERVAL_MINUTES$7[interval] * MS_PER_MINUTE$5;
|
|
1611
1611
|
// Calculate expected timestamps and fetch each candle directly
|
|
1612
1612
|
const cachedCandles = [];
|
|
1613
1613
|
for (let i = 0; i < limit; i++) {
|
|
@@ -1663,7 +1663,7 @@ class PersistCandleUtils {
|
|
|
1663
1663
|
const stateStorage = this.getCandlesStorage(symbol, interval, exchangeName);
|
|
1664
1664
|
await stateStorage.waitForInit(isInitial);
|
|
1665
1665
|
// Calculate step in milliseconds to determine candle close time
|
|
1666
|
-
const stepMs = INTERVAL_MINUTES$
|
|
1666
|
+
const stepMs = INTERVAL_MINUTES$7[interval] * MS_PER_MINUTE$5;
|
|
1667
1667
|
const now = Date.now();
|
|
1668
1668
|
// Write each candle as a separate file, skipping incomplete candles
|
|
1669
1669
|
for (const candle of candles) {
|
|
@@ -1920,8 +1920,8 @@ class PersistNotificationUtils {
|
|
|
1920
1920
|
*/
|
|
1921
1921
|
const PersistNotificationAdapter = new PersistNotificationUtils();
|
|
1922
1922
|
|
|
1923
|
-
const MS_PER_MINUTE$
|
|
1924
|
-
const INTERVAL_MINUTES$
|
|
1923
|
+
const MS_PER_MINUTE$4 = 60000;
|
|
1924
|
+
const INTERVAL_MINUTES$6 = {
|
|
1925
1925
|
"1m": 1,
|
|
1926
1926
|
"3m": 3,
|
|
1927
1927
|
"5m": 5,
|
|
@@ -1951,7 +1951,7 @@ const INTERVAL_MINUTES$5 = {
|
|
|
1951
1951
|
* @returns Aligned timestamp rounded down to interval boundary
|
|
1952
1952
|
*/
|
|
1953
1953
|
const ALIGN_TO_INTERVAL_FN$2 = (timestamp, intervalMinutes) => {
|
|
1954
|
-
const intervalMs = intervalMinutes * MS_PER_MINUTE$
|
|
1954
|
+
const intervalMs = intervalMinutes * MS_PER_MINUTE$4;
|
|
1955
1955
|
return Math.floor(timestamp / intervalMs) * intervalMs;
|
|
1956
1956
|
};
|
|
1957
1957
|
/**
|
|
@@ -2096,9 +2096,9 @@ const WRITE_CANDLES_CACHE_FN$1 = trycatch(queued(async (candles, dto, self) => {
|
|
|
2096
2096
|
* @returns Promise resolving to array of candle data
|
|
2097
2097
|
*/
|
|
2098
2098
|
const GET_CANDLES_FN = async (dto, since, self) => {
|
|
2099
|
-
const step = INTERVAL_MINUTES$
|
|
2099
|
+
const step = INTERVAL_MINUTES$6[dto.interval];
|
|
2100
2100
|
const sinceTimestamp = since.getTime();
|
|
2101
|
-
const untilTimestamp = sinceTimestamp + dto.limit * step * MS_PER_MINUTE$
|
|
2101
|
+
const untilTimestamp = sinceTimestamp + dto.limit * step * MS_PER_MINUTE$4;
|
|
2102
2102
|
// Try to read from cache first
|
|
2103
2103
|
const cachedCandles = await READ_CANDLES_CACHE_FN$1(dto, sinceTimestamp, untilTimestamp, self);
|
|
2104
2104
|
if (cachedCandles !== null) {
|
|
@@ -2206,11 +2206,11 @@ class ClientExchange {
|
|
|
2206
2206
|
interval,
|
|
2207
2207
|
limit,
|
|
2208
2208
|
});
|
|
2209
|
-
const step = INTERVAL_MINUTES$
|
|
2209
|
+
const step = INTERVAL_MINUTES$6[interval];
|
|
2210
2210
|
if (!step) {
|
|
2211
2211
|
throw new Error(`ClientExchange unknown interval=${interval}`);
|
|
2212
2212
|
}
|
|
2213
|
-
const stepMs = step * MS_PER_MINUTE$
|
|
2213
|
+
const stepMs = step * MS_PER_MINUTE$4;
|
|
2214
2214
|
// Align when down to interval boundary
|
|
2215
2215
|
const whenTimestamp = this.params.execution.context.when.getTime();
|
|
2216
2216
|
const alignedWhen = ALIGN_TO_INTERVAL_FN$2(whenTimestamp, step);
|
|
@@ -2287,11 +2287,11 @@ class ClientExchange {
|
|
|
2287
2287
|
if (!this.params.execution.context.backtest) {
|
|
2288
2288
|
throw new Error(`ClientExchange getNextCandles: cannot fetch future candles in live mode`);
|
|
2289
2289
|
}
|
|
2290
|
-
const step = INTERVAL_MINUTES$
|
|
2290
|
+
const step = INTERVAL_MINUTES$6[interval];
|
|
2291
2291
|
if (!step) {
|
|
2292
2292
|
throw new Error(`ClientExchange getNextCandles: unknown interval=${interval}`);
|
|
2293
2293
|
}
|
|
2294
|
-
const stepMs = step * MS_PER_MINUTE$
|
|
2294
|
+
const stepMs = step * MS_PER_MINUTE$4;
|
|
2295
2295
|
const now = Date.now();
|
|
2296
2296
|
// Align when down to interval boundary
|
|
2297
2297
|
const whenTimestamp = this.params.execution.context.when.getTime();
|
|
@@ -2455,11 +2455,11 @@ class ClientExchange {
|
|
|
2455
2455
|
sDate,
|
|
2456
2456
|
eDate,
|
|
2457
2457
|
});
|
|
2458
|
-
const step = INTERVAL_MINUTES$
|
|
2458
|
+
const step = INTERVAL_MINUTES$6[interval];
|
|
2459
2459
|
if (!step) {
|
|
2460
2460
|
throw new Error(`ClientExchange getRawCandles: unknown interval=${interval}`);
|
|
2461
2461
|
}
|
|
2462
|
-
const stepMs = step * MS_PER_MINUTE$
|
|
2462
|
+
const stepMs = step * MS_PER_MINUTE$4;
|
|
2463
2463
|
const whenTimestamp = this.params.execution.context.when.getTime();
|
|
2464
2464
|
const alignedWhen = ALIGN_TO_INTERVAL_FN$2(whenTimestamp, step);
|
|
2465
2465
|
let sinceTimestamp;
|
|
@@ -2588,7 +2588,7 @@ class ClientExchange {
|
|
|
2588
2588
|
const alignedTo = ALIGN_TO_INTERVAL_FN$2(whenTimestamp, GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES);
|
|
2589
2589
|
const to = new Date(alignedTo);
|
|
2590
2590
|
const from = new Date(alignedTo -
|
|
2591
|
-
GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES * MS_PER_MINUTE$
|
|
2591
|
+
GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES * MS_PER_MINUTE$4);
|
|
2592
2592
|
return await this.params.getOrderBook(symbol, depth, from, to, this.params.execution.context.backtest);
|
|
2593
2593
|
}
|
|
2594
2594
|
}
|
|
@@ -3053,7 +3053,7 @@ const beginTime = (run) => (...args) => {
|
|
|
3053
3053
|
return fn();
|
|
3054
3054
|
};
|
|
3055
3055
|
|
|
3056
|
-
const INTERVAL_MINUTES$
|
|
3056
|
+
const INTERVAL_MINUTES$5 = {
|
|
3057
3057
|
"1m": 1,
|
|
3058
3058
|
"3m": 3,
|
|
3059
3059
|
"5m": 5,
|
|
@@ -3566,7 +3566,7 @@ const GET_SIGNAL_FN = trycatch(async (self) => {
|
|
|
3566
3566
|
}
|
|
3567
3567
|
const currentTime = self.params.execution.context.when.getTime();
|
|
3568
3568
|
{
|
|
3569
|
-
const intervalMinutes = INTERVAL_MINUTES$
|
|
3569
|
+
const intervalMinutes = INTERVAL_MINUTES$5[self.params.interval];
|
|
3570
3570
|
const intervalMs = intervalMinutes * 60 * 1000;
|
|
3571
3571
|
// Проверяем что прошел нужный интервал с последнего getSignal
|
|
3572
3572
|
if (self._lastSignalTimestamp !== null &&
|
|
@@ -8177,7 +8177,7 @@ class StrategyConnectionService {
|
|
|
8177
8177
|
* Maps FrameInterval to minutes for timestamp calculation.
|
|
8178
8178
|
* Used to generate timeframe arrays with proper spacing.
|
|
8179
8179
|
*/
|
|
8180
|
-
const INTERVAL_MINUTES$
|
|
8180
|
+
const INTERVAL_MINUTES$4 = {
|
|
8181
8181
|
"1m": 1,
|
|
8182
8182
|
"3m": 3,
|
|
8183
8183
|
"5m": 5,
|
|
@@ -8232,7 +8232,7 @@ const GET_TIMEFRAME_FN = async (symbol, self) => {
|
|
|
8232
8232
|
symbol,
|
|
8233
8233
|
});
|
|
8234
8234
|
const { interval, startDate, endDate } = self.params;
|
|
8235
|
-
const intervalMinutes = INTERVAL_MINUTES$
|
|
8235
|
+
const intervalMinutes = INTERVAL_MINUTES$4[interval];
|
|
8236
8236
|
if (!intervalMinutes) {
|
|
8237
8237
|
throw new Error(`ClientFrame unknown interval: ${interval}`);
|
|
8238
8238
|
}
|
|
@@ -26028,7 +26028,7 @@ const EXCHANGE_METHOD_NAME_FORMAT_QUANTITY = "ExchangeUtils.formatQuantity";
|
|
|
26028
26028
|
const EXCHANGE_METHOD_NAME_FORMAT_PRICE = "ExchangeUtils.formatPrice";
|
|
26029
26029
|
const EXCHANGE_METHOD_NAME_GET_ORDER_BOOK = "ExchangeUtils.getOrderBook";
|
|
26030
26030
|
const EXCHANGE_METHOD_NAME_GET_RAW_CANDLES = "ExchangeUtils.getRawCandles";
|
|
26031
|
-
const MS_PER_MINUTE$
|
|
26031
|
+
const MS_PER_MINUTE$3 = 60000;
|
|
26032
26032
|
/**
|
|
26033
26033
|
* Gets current timestamp from execution context if available.
|
|
26034
26034
|
* Returns current Date() if no execution context exists (non-trading GUI).
|
|
@@ -26083,7 +26083,7 @@ const DEFAULT_FORMAT_PRICE_FN = async (_symbol, price, _backtest) => {
|
|
|
26083
26083
|
const DEFAULT_GET_ORDER_BOOK_FN = async (_symbol, _depth, _from, _to, _backtest) => {
|
|
26084
26084
|
throw new Error(`getOrderBook is not implemented for this exchange`);
|
|
26085
26085
|
};
|
|
26086
|
-
const INTERVAL_MINUTES$
|
|
26086
|
+
const INTERVAL_MINUTES$3 = {
|
|
26087
26087
|
"1m": 1,
|
|
26088
26088
|
"3m": 3,
|
|
26089
26089
|
"5m": 5,
|
|
@@ -26113,7 +26113,7 @@ const INTERVAL_MINUTES$2 = {
|
|
|
26113
26113
|
* @returns Aligned timestamp rounded down to interval boundary
|
|
26114
26114
|
*/
|
|
26115
26115
|
const ALIGN_TO_INTERVAL_FN$1 = (timestamp, intervalMinutes) => {
|
|
26116
|
-
const intervalMs = intervalMinutes * MS_PER_MINUTE$
|
|
26116
|
+
const intervalMs = intervalMinutes * MS_PER_MINUTE$3;
|
|
26117
26117
|
return Math.floor(timestamp / intervalMs) * intervalMs;
|
|
26118
26118
|
};
|
|
26119
26119
|
/**
|
|
@@ -26251,11 +26251,11 @@ class ExchangeInstance {
|
|
|
26251
26251
|
limit,
|
|
26252
26252
|
});
|
|
26253
26253
|
const getCandles = this._methods.getCandles;
|
|
26254
|
-
const step = INTERVAL_MINUTES$
|
|
26254
|
+
const step = INTERVAL_MINUTES$3[interval];
|
|
26255
26255
|
if (!step) {
|
|
26256
26256
|
throw new Error(`ExchangeInstance unknown interval=${interval}`);
|
|
26257
26257
|
}
|
|
26258
|
-
const stepMs = step * MS_PER_MINUTE$
|
|
26258
|
+
const stepMs = step * MS_PER_MINUTE$3;
|
|
26259
26259
|
// Align when down to interval boundary
|
|
26260
26260
|
const when = await GET_TIMESTAMP_FN();
|
|
26261
26261
|
const whenTimestamp = when.getTime();
|
|
@@ -26434,7 +26434,7 @@ class ExchangeInstance {
|
|
|
26434
26434
|
const when = await GET_TIMESTAMP_FN();
|
|
26435
26435
|
const alignedTo = ALIGN_TO_INTERVAL_FN$1(when.getTime(), GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES);
|
|
26436
26436
|
const to = new Date(alignedTo);
|
|
26437
|
-
const from = new Date(alignedTo - GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES * MS_PER_MINUTE$
|
|
26437
|
+
const from = new Date(alignedTo - GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES * MS_PER_MINUTE$3);
|
|
26438
26438
|
const isBacktest = await GET_BACKTEST_FN();
|
|
26439
26439
|
return await this._methods.getOrderBook(symbol, depth, from, to, isBacktest);
|
|
26440
26440
|
};
|
|
@@ -26477,11 +26477,11 @@ class ExchangeInstance {
|
|
|
26477
26477
|
sDate,
|
|
26478
26478
|
eDate,
|
|
26479
26479
|
});
|
|
26480
|
-
const step = INTERVAL_MINUTES$
|
|
26480
|
+
const step = INTERVAL_MINUTES$3[interval];
|
|
26481
26481
|
if (!step) {
|
|
26482
26482
|
throw new Error(`ExchangeInstance getRawCandles: unknown interval=${interval}`);
|
|
26483
26483
|
}
|
|
26484
|
-
const stepMs = step * MS_PER_MINUTE$
|
|
26484
|
+
const stepMs = step * MS_PER_MINUTE$3;
|
|
26485
26485
|
const when = await GET_TIMESTAMP_FN();
|
|
26486
26486
|
const nowTimestamp = when.getTime();
|
|
26487
26487
|
const alignedNow = ALIGN_TO_INTERVAL_FN$1(nowTimestamp, step);
|
|
@@ -26752,8 +26752,8 @@ const Exchange = new ExchangeUtils();
|
|
|
26752
26752
|
|
|
26753
26753
|
const WARM_CANDLES_METHOD_NAME = "cache.warmCandles";
|
|
26754
26754
|
const CHECK_CANDLES_METHOD_NAME = "cache.checkCandles";
|
|
26755
|
-
const MS_PER_MINUTE$
|
|
26756
|
-
const INTERVAL_MINUTES$
|
|
26755
|
+
const MS_PER_MINUTE$2 = 60000;
|
|
26756
|
+
const INTERVAL_MINUTES$2 = {
|
|
26757
26757
|
"1m": 1,
|
|
26758
26758
|
"3m": 3,
|
|
26759
26759
|
"5m": 5,
|
|
@@ -26766,7 +26766,7 @@ const INTERVAL_MINUTES$1 = {
|
|
|
26766
26766
|
"8h": 480,
|
|
26767
26767
|
};
|
|
26768
26768
|
const ALIGN_TO_INTERVAL_FN = (timestamp, intervalMinutes) => {
|
|
26769
|
-
const intervalMs = intervalMinutes * MS_PER_MINUTE$
|
|
26769
|
+
const intervalMs = intervalMinutes * MS_PER_MINUTE$2;
|
|
26770
26770
|
return Math.floor(timestamp / intervalMs) * intervalMs;
|
|
26771
26771
|
};
|
|
26772
26772
|
const BAR_LENGTH = 30;
|
|
@@ -26791,11 +26791,11 @@ const PRINT_PROGRESS_FN = (fetched, total, symbol, interval) => {
|
|
|
26791
26791
|
async function checkCandles(params) {
|
|
26792
26792
|
const { symbol, exchangeName, interval, from, to, baseDir = "./dump/data/candle" } = params;
|
|
26793
26793
|
bt.loggerService.info(CHECK_CANDLES_METHOD_NAME, params);
|
|
26794
|
-
const step = INTERVAL_MINUTES$
|
|
26794
|
+
const step = INTERVAL_MINUTES$2[interval];
|
|
26795
26795
|
if (!step) {
|
|
26796
26796
|
throw new Error(`checkCandles: unsupported interval=${interval}`);
|
|
26797
26797
|
}
|
|
26798
|
-
const stepMs = step * MS_PER_MINUTE$
|
|
26798
|
+
const stepMs = step * MS_PER_MINUTE$2;
|
|
26799
26799
|
const dir = join(baseDir, exchangeName, symbol, interval);
|
|
26800
26800
|
const fromTs = ALIGN_TO_INTERVAL_FN(from.getTime(), step);
|
|
26801
26801
|
const toTs = ALIGN_TO_INTERVAL_FN(to.getTime(), step);
|
|
@@ -26865,11 +26865,11 @@ async function warmCandles(params) {
|
|
|
26865
26865
|
from,
|
|
26866
26866
|
to,
|
|
26867
26867
|
});
|
|
26868
|
-
const step = INTERVAL_MINUTES$
|
|
26868
|
+
const step = INTERVAL_MINUTES$2[interval];
|
|
26869
26869
|
if (!step) {
|
|
26870
26870
|
throw new Error(`warmCandles: unsupported interval=${interval}`);
|
|
26871
26871
|
}
|
|
26872
|
-
const stepMs = step * MS_PER_MINUTE$
|
|
26872
|
+
const stepMs = step * MS_PER_MINUTE$2;
|
|
26873
26873
|
const instance = new ExchangeInstance(exchangeName);
|
|
26874
26874
|
const sinceTimestamp = ALIGN_TO_INTERVAL_FN(from.getTime(), step);
|
|
26875
26875
|
const untilTimestamp = ALIGN_TO_INTERVAL_FN(to.getTime(), step);
|
|
@@ -36377,8 +36377,8 @@ const CACHE_METHOD_NAME_CLEAR = "CacheInstance.clear";
|
|
|
36377
36377
|
const CACHE_METHOD_NAME_RUN = "CacheInstance.run";
|
|
36378
36378
|
const CACHE_METHOD_NAME_GC = "CacheInstance.gc";
|
|
36379
36379
|
const CACHE_METHOD_NAME_FN = "CacheUtils.fn";
|
|
36380
|
-
const MS_PER_MINUTE = 60000;
|
|
36381
|
-
const INTERVAL_MINUTES = {
|
|
36380
|
+
const MS_PER_MINUTE$1 = 60000;
|
|
36381
|
+
const INTERVAL_MINUTES$1 = {
|
|
36382
36382
|
"1m": 1,
|
|
36383
36383
|
"3m": 3,
|
|
36384
36384
|
"5m": 5,
|
|
@@ -36411,11 +36411,11 @@ const INTERVAL_MINUTES = {
|
|
|
36411
36411
|
* ```
|
|
36412
36412
|
*/
|
|
36413
36413
|
const align = (timestamp, interval) => {
|
|
36414
|
-
const intervalMinutes = INTERVAL_MINUTES[interval];
|
|
36414
|
+
const intervalMinutes = INTERVAL_MINUTES$1[interval];
|
|
36415
36415
|
if (!intervalMinutes) {
|
|
36416
36416
|
throw new Error(`align: unknown interval=${interval}`);
|
|
36417
36417
|
}
|
|
36418
|
-
const intervalMs = intervalMinutes * MS_PER_MINUTE;
|
|
36418
|
+
const intervalMs = intervalMinutes * MS_PER_MINUTE$1;
|
|
36419
36419
|
return Math.floor(timestamp / intervalMs) * intervalMs;
|
|
36420
36420
|
};
|
|
36421
36421
|
/**
|
|
@@ -36504,7 +36504,7 @@ class CacheInstance {
|
|
|
36504
36504
|
*/
|
|
36505
36505
|
this.run = (...args) => {
|
|
36506
36506
|
bt.loggerService.debug(CACHE_METHOD_NAME_RUN, { args });
|
|
36507
|
-
const step = INTERVAL_MINUTES[this.interval];
|
|
36507
|
+
const step = INTERVAL_MINUTES$1[this.interval];
|
|
36508
36508
|
{
|
|
36509
36509
|
if (!MethodContextService.hasContext()) {
|
|
36510
36510
|
throw new Error("CacheInstance run requires method context");
|
|
@@ -37170,6 +37170,45 @@ class StrategyUtils {
|
|
|
37170
37170
|
*/
|
|
37171
37171
|
const Strategy = new StrategyUtils();
|
|
37172
37172
|
|
|
37173
|
+
const MS_PER_MINUTE = 60000;
|
|
37174
|
+
const INTERVAL_MINUTES = {
|
|
37175
|
+
"1m": 1,
|
|
37176
|
+
"3m": 3,
|
|
37177
|
+
"5m": 5,
|
|
37178
|
+
"15m": 15,
|
|
37179
|
+
"30m": 30,
|
|
37180
|
+
"1h": 60,
|
|
37181
|
+
"2h": 120,
|
|
37182
|
+
"4h": 240,
|
|
37183
|
+
"6h": 360,
|
|
37184
|
+
"8h": 480,
|
|
37185
|
+
};
|
|
37186
|
+
/**
|
|
37187
|
+
* Aligns timestamp down to the nearest interval boundary.
|
|
37188
|
+
* For example, for 15m interval: 00:17 -> 00:15, 00:44 -> 00:30
|
|
37189
|
+
*
|
|
37190
|
+
* Candle timestamp convention:
|
|
37191
|
+
* - Candle timestamp = openTime (when candle opens)
|
|
37192
|
+
* - Candle with timestamp 00:00 covers period [00:00, 00:15) for 15m interval
|
|
37193
|
+
*
|
|
37194
|
+
* Adapter contract:
|
|
37195
|
+
* - Adapter must return candles with timestamp = openTime
|
|
37196
|
+
* - First returned candle.timestamp must equal aligned since
|
|
37197
|
+
* - Adapter must return exactly `limit` candles
|
|
37198
|
+
*
|
|
37199
|
+
* @param date - Date to align
|
|
37200
|
+
* @param interval - Candle interval (e.g., "1m", "15m", "1h")
|
|
37201
|
+
* @returns New Date aligned down to interval boundary
|
|
37202
|
+
*/
|
|
37203
|
+
const alignToInterval = (date, interval) => {
|
|
37204
|
+
const minutes = INTERVAL_MINUTES[interval];
|
|
37205
|
+
if (minutes === undefined) {
|
|
37206
|
+
throw new Error(`alignToInterval: unknown interval=${interval}`);
|
|
37207
|
+
}
|
|
37208
|
+
const intervalMs = minutes * MS_PER_MINUTE;
|
|
37209
|
+
return new Date(Math.floor(date.getTime() / intervalMs) * intervalMs);
|
|
37210
|
+
};
|
|
37211
|
+
|
|
37173
37212
|
/**
|
|
37174
37213
|
* Rounds a price to the appropriate precision based on the tick size.
|
|
37175
37214
|
*
|
|
@@ -37302,4 +37341,4 @@ const set = (object, path, value) => {
|
|
|
37302
37341
|
}
|
|
37303
37342
|
};
|
|
37304
37343
|
|
|
37305
|
-
export { ActionBase, Backtest, Breakeven, Cache, Constant, Exchange, ExecutionContextService, Heat, Live, Markdown, MarkdownFileBase, MarkdownFolderBase, MethodContextService, Notification, NotificationBacktest, NotificationLive, Partial, Performance, PersistBase, PersistBreakevenAdapter, PersistCandleAdapter, PersistNotificationAdapter, PersistPartialAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, PersistStorageAdapter, PositionSize, Report, ReportBase, Risk, Schedule, Storage, StorageBacktest, StorageLive, Strategy, Walker, addActionSchema, addExchangeSchema, addFrameSchema, addRiskSchema, addSizingSchema, addStrategySchema, addWalkerSchema, checkCandles, commitActivateScheduled, commitBreakeven, commitCancelScheduled, commitClosePending, commitPartialLoss, commitPartialProfit, commitTrailingStop, commitTrailingTake, emitters, formatPrice, formatQuantity, get, getActionSchema, getAveragePrice, getBacktestTimeframe, getCandles, getColumns, getConfig, getContext, getDate, getDefaultColumns, getDefaultConfig, getExchangeSchema, getFrameSchema, getMode, getNextCandles, getOrderBook, getRawCandles, getRiskSchema, getSizingSchema, getStrategySchema, getSymbol, getWalkerSchema, hasTradeContext, backtest as lib, listExchangeSchema, listFrameSchema, listRiskSchema, listSizingSchema, listStrategySchema, listWalkerSchema, listenActivePing, listenActivePingOnce, listenBacktestProgress, listenBreakevenAvailable, listenBreakevenAvailableOnce, listenDoneBacktest, listenDoneBacktestOnce, listenDoneLive, listenDoneLiveOnce, listenDoneWalker, listenDoneWalkerOnce, listenError, listenExit, listenPartialLossAvailable, listenPartialLossAvailableOnce, listenPartialProfitAvailable, listenPartialProfitAvailableOnce, listenPerformance, listenRisk, listenRiskOnce, listenSchedulePing, listenSchedulePingOnce, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalOnce, listenStrategyCommit, listenStrategyCommitOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, overrideActionSchema, overrideExchangeSchema, overrideFrameSchema, overrideRiskSchema, overrideSizingSchema, overrideStrategySchema, overrideWalkerSchema, parseArgs, roundTicks, set, setColumns, setConfig, setLogger, stopStrategy, validate, warmCandles };
|
|
37344
|
+
export { ActionBase, Backtest, Breakeven, Cache, Constant, Exchange, ExecutionContextService, Heat, Live, Markdown, MarkdownFileBase, MarkdownFolderBase, MethodContextService, Notification, NotificationBacktest, NotificationLive, Partial, Performance, PersistBase, PersistBreakevenAdapter, PersistCandleAdapter, PersistNotificationAdapter, PersistPartialAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, PersistStorageAdapter, PositionSize, Report, ReportBase, Risk, Schedule, Storage, StorageBacktest, StorageLive, Strategy, Walker, addActionSchema, addExchangeSchema, addFrameSchema, addRiskSchema, addSizingSchema, addStrategySchema, addWalkerSchema, alignToInterval, checkCandles, commitActivateScheduled, commitBreakeven, commitCancelScheduled, commitClosePending, commitPartialLoss, commitPartialProfit, commitTrailingStop, commitTrailingTake, emitters, formatPrice, formatQuantity, get, getActionSchema, getAveragePrice, getBacktestTimeframe, getCandles, getColumns, getConfig, getContext, getDate, getDefaultColumns, getDefaultConfig, getExchangeSchema, getFrameSchema, getMode, getNextCandles, getOrderBook, getRawCandles, getRiskSchema, getSizingSchema, getStrategySchema, getSymbol, getWalkerSchema, hasTradeContext, backtest as lib, listExchangeSchema, listFrameSchema, listRiskSchema, listSizingSchema, listStrategySchema, listWalkerSchema, listenActivePing, listenActivePingOnce, listenBacktestProgress, listenBreakevenAvailable, listenBreakevenAvailableOnce, listenDoneBacktest, listenDoneBacktestOnce, listenDoneLive, listenDoneLiveOnce, listenDoneWalker, listenDoneWalkerOnce, listenError, listenExit, listenPartialLossAvailable, listenPartialLossAvailableOnce, listenPartialProfitAvailable, listenPartialProfitAvailableOnce, listenPerformance, listenRisk, listenRiskOnce, listenSchedulePing, listenSchedulePingOnce, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalOnce, listenStrategyCommit, listenStrategyCommitOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, overrideActionSchema, overrideExchangeSchema, overrideFrameSchema, overrideRiskSchema, overrideSizingSchema, overrideStrategySchema, overrideWalkerSchema, parseArgs, roundTicks, set, setColumns, setConfig, setLogger, stopStrategy, validate, warmCandles };
|
package/package.json
CHANGED
package/types.d.ts
CHANGED
|
@@ -16182,6 +16182,25 @@ declare namespace emitters {
|
|
|
16182
16182
|
export { emitters_activePingSubject as activePingSubject, emitters_backtestScheduleOpenSubject as backtestScheduleOpenSubject, emitters_breakevenSubject as breakevenSubject, emitters_doneBacktestSubject as doneBacktestSubject, emitters_doneLiveSubject as doneLiveSubject, emitters_doneWalkerSubject as doneWalkerSubject, emitters_errorEmitter as errorEmitter, emitters_exitEmitter as exitEmitter, emitters_partialLossSubject as partialLossSubject, emitters_partialProfitSubject as partialProfitSubject, emitters_performanceEmitter as performanceEmitter, emitters_progressBacktestEmitter as progressBacktestEmitter, emitters_progressWalkerEmitter as progressWalkerEmitter, emitters_riskSubject as riskSubject, emitters_schedulePingSubject as schedulePingSubject, emitters_signalBacktestEmitter as signalBacktestEmitter, emitters_signalEmitter as signalEmitter, emitters_signalLiveEmitter as signalLiveEmitter, emitters_strategyCommitSubject as strategyCommitSubject, emitters_validationSubject as validationSubject, emitters_walkerCompleteSubject as walkerCompleteSubject, emitters_walkerEmitter as walkerEmitter, emitters_walkerStopSubject as walkerStopSubject };
|
|
16183
16183
|
}
|
|
16184
16184
|
|
|
16185
|
+
/**
|
|
16186
|
+
* Aligns timestamp down to the nearest interval boundary.
|
|
16187
|
+
* For example, for 15m interval: 00:17 -> 00:15, 00:44 -> 00:30
|
|
16188
|
+
*
|
|
16189
|
+
* Candle timestamp convention:
|
|
16190
|
+
* - Candle timestamp = openTime (when candle opens)
|
|
16191
|
+
* - Candle with timestamp 00:00 covers period [00:00, 00:15) for 15m interval
|
|
16192
|
+
*
|
|
16193
|
+
* Adapter contract:
|
|
16194
|
+
* - Adapter must return candles with timestamp = openTime
|
|
16195
|
+
* - First returned candle.timestamp must equal aligned since
|
|
16196
|
+
* - Adapter must return exactly `limit` candles
|
|
16197
|
+
*
|
|
16198
|
+
* @param date - Date to align
|
|
16199
|
+
* @param interval - Candle interval (e.g., "1m", "15m", "1h")
|
|
16200
|
+
* @returns New Date aligned down to interval boundary
|
|
16201
|
+
*/
|
|
16202
|
+
declare const alignToInterval: (date: Date, interval: CandleInterval) => Date;
|
|
16203
|
+
|
|
16185
16204
|
/**
|
|
16186
16205
|
* Rounds a price to the appropriate precision based on the tick size.
|
|
16187
16206
|
*
|
|
@@ -20823,4 +20842,4 @@ declare const backtest: {
|
|
|
20823
20842
|
loggerService: LoggerService;
|
|
20824
20843
|
};
|
|
20825
20844
|
|
|
20826
|
-
export { ActionBase, type ActivateScheduledCommit, type ActivateScheduledCommitNotification, type ActivePingContract, Backtest, type BacktestStatisticsModel, Breakeven, type BreakevenAvailableNotification, type BreakevenCommit, type BreakevenCommitNotification, type BreakevenContract, type BreakevenData, Cache, type CancelScheduledCommit, type CandleData, type CandleInterval, type ClosePendingCommit, type ColumnConfig, type ColumnModel, Constant, type CriticalErrorNotification, type DoneContract, type EntityId, Exchange, ExecutionContextService, type FrameInterval, type GlobalConfig, Heat, type HeatmapStatisticsModel, type IActivateScheduledCommitRow, type IBidData, type IBreakevenCommitRow, type ICandleData, type ICommitRow, type IExchangeSchema, type IFrameSchema, type IHeatmapRow, type IMarkdownDumpOptions, type INotificationUtils, type IOrderBookData, type IPartialLossCommitRow, type IPartialProfitCommitRow, type IPersistBase, type IPositionSizeATRParams, type IPositionSizeFixedPercentageParams, type IPositionSizeKellyParams, type IPublicSignalRow, type IReportDumpOptions, type IRiskActivePosition, type IRiskCheckArgs, type IRiskSchema, type IRiskSignalRow, type IRiskValidation, type IRiskValidationFn, type IRiskValidationPayload, type IScheduledSignalCancelRow, type IScheduledSignalRow, type ISignalDto, type ISignalRow, type ISizingCalculateParams, type ISizingCalculateParamsATR, type ISizingCalculateParamsFixedPercentage, type ISizingCalculateParamsKelly, type ISizingParams, type ISizingParamsATR, type ISizingParamsFixedPercentage, type ISizingParamsKelly, type ISizingSchema, type ISizingSchemaATR, type ISizingSchemaFixedPercentage, type ISizingSchemaKelly, type IStorageSignalRow, type IStorageUtils, type IStrategyPnL, type IStrategyResult, type IStrategySchema, type IStrategyTickResult, type IStrategyTickResultActive, type IStrategyTickResultCancelled, type IStrategyTickResultClosed, type IStrategyTickResultIdle, type IStrategyTickResultOpened, type IStrategyTickResultScheduled, type IStrategyTickResultWaiting, type ITrailingStopCommitRow, type ITrailingTakeCommitRow, type IWalkerResults, type IWalkerSchema, type IWalkerStrategyResult, type InfoErrorNotification, Live, type LiveStatisticsModel, Markdown, MarkdownFileBase, MarkdownFolderBase, type MarkdownName, MethodContextService, type MetricStats, Notification, NotificationBacktest, type NotificationData, NotificationLive, type NotificationModel, Partial$1 as Partial, type PartialData, type PartialEvent, type PartialLossAvailableNotification, type PartialLossCommit, type PartialLossCommitNotification, type PartialLossContract, type PartialProfitAvailableNotification, type PartialProfitCommit, type PartialProfitCommitNotification, type PartialProfitContract, type PartialStatisticsModel, Performance, type PerformanceContract, type PerformanceMetricType, type PerformanceStatisticsModel, PersistBase, PersistBreakevenAdapter, PersistCandleAdapter, PersistNotificationAdapter, PersistPartialAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, PersistStorageAdapter, PositionSize, type ProgressBacktestContract, type ProgressWalkerContract, Report, ReportBase, type ReportName, Risk, type RiskContract, type RiskData, type RiskEvent, type RiskRejectionNotification, type RiskStatisticsModel, Schedule, type ScheduleData, type SchedulePingContract, type ScheduleStatisticsModel, type ScheduledEvent, type SignalCancelledNotification, type SignalClosedNotification, type SignalData, type SignalInterval, type SignalOpenedNotification, type SignalScheduledNotification, Storage, StorageBacktest, type StorageData, StorageLive, Strategy, type StrategyActionType, type StrategyCancelReason, type StrategyCloseReason, type StrategyCommitContract, type StrategyEvent, type StrategyStatisticsModel, type TMarkdownBase, type TNotificationUtilsCtor, type TPersistBase, type TPersistBaseCtor, type TReportBase, type TStorageUtilsCtor, type TickEvent, type TrailingStopCommit, type TrailingStopCommitNotification, type TrailingTakeCommit, type TrailingTakeCommitNotification, type ValidationErrorNotification, Walker, type WalkerCompleteContract, type WalkerContract, type WalkerMetric, type SignalData$1 as WalkerSignalData, type WalkerStatisticsModel, addActionSchema, addExchangeSchema, addFrameSchema, addRiskSchema, addSizingSchema, addStrategySchema, addWalkerSchema, checkCandles, commitActivateScheduled, commitBreakeven, commitCancelScheduled, commitClosePending, commitPartialLoss, commitPartialProfit, commitTrailingStop, commitTrailingTake, emitters, formatPrice, formatQuantity, get, getActionSchema, getAveragePrice, getBacktestTimeframe, getCandles, getColumns, getConfig, getContext, getDate, getDefaultColumns, getDefaultConfig, getExchangeSchema, getFrameSchema, getMode, getNextCandles, getOrderBook, getRawCandles, getRiskSchema, getSizingSchema, getStrategySchema, getSymbol, getWalkerSchema, hasTradeContext, backtest as lib, listExchangeSchema, listFrameSchema, listRiskSchema, listSizingSchema, listStrategySchema, listWalkerSchema, listenActivePing, listenActivePingOnce, listenBacktestProgress, listenBreakevenAvailable, listenBreakevenAvailableOnce, listenDoneBacktest, listenDoneBacktestOnce, listenDoneLive, listenDoneLiveOnce, listenDoneWalker, listenDoneWalkerOnce, listenError, listenExit, listenPartialLossAvailable, listenPartialLossAvailableOnce, listenPartialProfitAvailable, listenPartialProfitAvailableOnce, listenPerformance, listenRisk, listenRiskOnce, listenSchedulePing, listenSchedulePingOnce, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalOnce, listenStrategyCommit, listenStrategyCommitOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, overrideActionSchema, overrideExchangeSchema, overrideFrameSchema, overrideRiskSchema, overrideSizingSchema, overrideStrategySchema, overrideWalkerSchema, parseArgs, roundTicks, set, setColumns, setConfig, setLogger, stopStrategy, validate, warmCandles };
|
|
20845
|
+
export { ActionBase, type ActivateScheduledCommit, type ActivateScheduledCommitNotification, type ActivePingContract, Backtest, type BacktestStatisticsModel, Breakeven, type BreakevenAvailableNotification, type BreakevenCommit, type BreakevenCommitNotification, type BreakevenContract, type BreakevenData, Cache, type CancelScheduledCommit, type CandleData, type CandleInterval, type ClosePendingCommit, type ColumnConfig, type ColumnModel, Constant, type CriticalErrorNotification, type DoneContract, type EntityId, Exchange, ExecutionContextService, type FrameInterval, type GlobalConfig, Heat, type HeatmapStatisticsModel, type IActivateScheduledCommitRow, type IBidData, type IBreakevenCommitRow, type ICandleData, type ICommitRow, type IExchangeSchema, type IFrameSchema, type IHeatmapRow, type IMarkdownDumpOptions, type INotificationUtils, type IOrderBookData, type IPartialLossCommitRow, type IPartialProfitCommitRow, type IPersistBase, type IPositionSizeATRParams, type IPositionSizeFixedPercentageParams, type IPositionSizeKellyParams, type IPublicSignalRow, type IReportDumpOptions, type IRiskActivePosition, type IRiskCheckArgs, type IRiskSchema, type IRiskSignalRow, type IRiskValidation, type IRiskValidationFn, type IRiskValidationPayload, type IScheduledSignalCancelRow, type IScheduledSignalRow, type ISignalDto, type ISignalRow, type ISizingCalculateParams, type ISizingCalculateParamsATR, type ISizingCalculateParamsFixedPercentage, type ISizingCalculateParamsKelly, type ISizingParams, type ISizingParamsATR, type ISizingParamsFixedPercentage, type ISizingParamsKelly, type ISizingSchema, type ISizingSchemaATR, type ISizingSchemaFixedPercentage, type ISizingSchemaKelly, type IStorageSignalRow, type IStorageUtils, type IStrategyPnL, type IStrategyResult, type IStrategySchema, type IStrategyTickResult, type IStrategyTickResultActive, type IStrategyTickResultCancelled, type IStrategyTickResultClosed, type IStrategyTickResultIdle, type IStrategyTickResultOpened, type IStrategyTickResultScheduled, type IStrategyTickResultWaiting, type ITrailingStopCommitRow, type ITrailingTakeCommitRow, type IWalkerResults, type IWalkerSchema, type IWalkerStrategyResult, type InfoErrorNotification, Live, type LiveStatisticsModel, Markdown, MarkdownFileBase, MarkdownFolderBase, type MarkdownName, MethodContextService, type MetricStats, Notification, NotificationBacktest, type NotificationData, NotificationLive, type NotificationModel, Partial$1 as Partial, type PartialData, type PartialEvent, type PartialLossAvailableNotification, type PartialLossCommit, type PartialLossCommitNotification, type PartialLossContract, type PartialProfitAvailableNotification, type PartialProfitCommit, type PartialProfitCommitNotification, type PartialProfitContract, type PartialStatisticsModel, Performance, type PerformanceContract, type PerformanceMetricType, type PerformanceStatisticsModel, PersistBase, PersistBreakevenAdapter, PersistCandleAdapter, PersistNotificationAdapter, PersistPartialAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, PersistStorageAdapter, PositionSize, type ProgressBacktestContract, type ProgressWalkerContract, Report, ReportBase, type ReportName, Risk, type RiskContract, type RiskData, type RiskEvent, type RiskRejectionNotification, type RiskStatisticsModel, Schedule, type ScheduleData, type SchedulePingContract, type ScheduleStatisticsModel, type ScheduledEvent, type SignalCancelledNotification, type SignalClosedNotification, type SignalData, type SignalInterval, type SignalOpenedNotification, type SignalScheduledNotification, Storage, StorageBacktest, type StorageData, StorageLive, Strategy, type StrategyActionType, type StrategyCancelReason, type StrategyCloseReason, type StrategyCommitContract, type StrategyEvent, type StrategyStatisticsModel, type TMarkdownBase, type TNotificationUtilsCtor, type TPersistBase, type TPersistBaseCtor, type TReportBase, type TStorageUtilsCtor, type TickEvent, type TrailingStopCommit, type TrailingStopCommitNotification, type TrailingTakeCommit, type TrailingTakeCommitNotification, type ValidationErrorNotification, Walker, type WalkerCompleteContract, type WalkerContract, type WalkerMetric, type SignalData$1 as WalkerSignalData, type WalkerStatisticsModel, addActionSchema, addExchangeSchema, addFrameSchema, addRiskSchema, addSizingSchema, addStrategySchema, addWalkerSchema, alignToInterval, checkCandles, commitActivateScheduled, commitBreakeven, commitCancelScheduled, commitClosePending, commitPartialLoss, commitPartialProfit, commitTrailingStop, commitTrailingTake, emitters, formatPrice, formatQuantity, get, getActionSchema, getAveragePrice, getBacktestTimeframe, getCandles, getColumns, getConfig, getContext, getDate, getDefaultColumns, getDefaultConfig, getExchangeSchema, getFrameSchema, getMode, getNextCandles, getOrderBook, getRawCandles, getRiskSchema, getSizingSchema, getStrategySchema, getSymbol, getWalkerSchema, hasTradeContext, backtest as lib, listExchangeSchema, listFrameSchema, listRiskSchema, listSizingSchema, listStrategySchema, listWalkerSchema, listenActivePing, listenActivePingOnce, listenBacktestProgress, listenBreakevenAvailable, listenBreakevenAvailableOnce, listenDoneBacktest, listenDoneBacktestOnce, listenDoneLive, listenDoneLiveOnce, listenDoneWalker, listenDoneWalkerOnce, listenError, listenExit, listenPartialLossAvailable, listenPartialLossAvailableOnce, listenPartialProfitAvailable, listenPartialProfitAvailableOnce, listenPerformance, listenRisk, listenRiskOnce, listenSchedulePing, listenSchedulePingOnce, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalOnce, listenStrategyCommit, listenStrategyCommitOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, overrideActionSchema, overrideExchangeSchema, overrideFrameSchema, overrideRiskSchema, overrideSizingSchema, overrideStrategySchema, overrideWalkerSchema, parseArgs, roundTicks, set, setColumns, setConfig, setLogger, stopStrategy, validate, warmCandles };
|