backtest-kit 6.9.0 → 6.10.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/build/index.cjs +639 -24
- package/build/index.mjs +636 -25
- package/package.json +3 -3
- package/types.d.ts +378 -21
package/build/index.mjs
CHANGED
|
@@ -7970,6 +7970,90 @@ class ClientStrategy {
|
|
|
7970
7970
|
}
|
|
7971
7971
|
return this._pendingSignal._fall.pnlCost;
|
|
7972
7972
|
}
|
|
7973
|
+
/**
|
|
7974
|
+
* Returns the distance in PnL percentage between the current price and the highest profit peak.
|
|
7975
|
+
*
|
|
7976
|
+
* Measures how much PnL% the position has given back from its best point.
|
|
7977
|
+
* Computed as: max(0, peakPnlPercentage - currentPnlPercentage).
|
|
7978
|
+
* Zero when called at the exact moment the peak was set, or when current PnL >= peak PnL.
|
|
7979
|
+
*
|
|
7980
|
+
* Returns null if no pending signal exists.
|
|
7981
|
+
*
|
|
7982
|
+
* @param symbol - Trading pair symbol
|
|
7983
|
+
* @param currentPrice - Current market price
|
|
7984
|
+
* @returns Promise resolving to drawdown distance in PnL% (≥ 0) or null
|
|
7985
|
+
*/
|
|
7986
|
+
async getPositionHighestProfitDistancePnlPercentage(symbol, currentPrice) {
|
|
7987
|
+
this.params.logger.debug("ClientStrategy getPositionHighestProfitDistancePnlPercentage", { symbol, currentPrice });
|
|
7988
|
+
if (!this._pendingSignal) {
|
|
7989
|
+
return null;
|
|
7990
|
+
}
|
|
7991
|
+
const currentPnl = toProfitLossDto(this._pendingSignal, currentPrice);
|
|
7992
|
+
return Math.max(0, this._pendingSignal._peak.pnlPercentage - currentPnl.pnlPercentage);
|
|
7993
|
+
}
|
|
7994
|
+
/**
|
|
7995
|
+
* Returns the distance in PnL cost between the current price and the highest profit peak.
|
|
7996
|
+
*
|
|
7997
|
+
* Measures how much PnL cost the position has given back from its best point.
|
|
7998
|
+
* Computed as: max(0, peakPnlCost - currentPnlCost).
|
|
7999
|
+
* Zero when called at the exact moment the peak was set, or when current PnL >= peak PnL.
|
|
8000
|
+
*
|
|
8001
|
+
* Returns null if no pending signal exists.
|
|
8002
|
+
*
|
|
8003
|
+
* @param symbol - Trading pair symbol
|
|
8004
|
+
* @param currentPrice - Current market price
|
|
8005
|
+
* @returns Promise resolving to drawdown distance in PnL cost (≥ 0) or null
|
|
8006
|
+
*/
|
|
8007
|
+
async getPositionHighestProfitDistancePnlCost(symbol, currentPrice) {
|
|
8008
|
+
this.params.logger.debug("ClientStrategy getPositionHighestProfitDistancePnlCost", { symbol, currentPrice });
|
|
8009
|
+
if (!this._pendingSignal) {
|
|
8010
|
+
return null;
|
|
8011
|
+
}
|
|
8012
|
+
const currentPnl = toProfitLossDto(this._pendingSignal, currentPrice);
|
|
8013
|
+
return Math.max(0, this._pendingSignal._peak.pnlCost - currentPnl.pnlCost);
|
|
8014
|
+
}
|
|
8015
|
+
/**
|
|
8016
|
+
* Returns the distance in PnL percentage between the current price and the worst drawdown trough.
|
|
8017
|
+
*
|
|
8018
|
+
* Measures how much the position has recovered from its deepest loss point.
|
|
8019
|
+
* Computed as: max(0, currentPnlPercentage - fallPnlPercentage).
|
|
8020
|
+
* Zero when called at the exact moment the trough was set, or when current PnL <= trough PnL.
|
|
8021
|
+
*
|
|
8022
|
+
* Returns null if no pending signal exists.
|
|
8023
|
+
*
|
|
8024
|
+
* @param symbol - Trading pair symbol
|
|
8025
|
+
* @param currentPrice - Current market price
|
|
8026
|
+
* @returns Promise resolving to recovery distance in PnL% (≥ 0) or null
|
|
8027
|
+
*/
|
|
8028
|
+
async getPositionHighestMaxDrawdownPnlPercentage(symbol, currentPrice) {
|
|
8029
|
+
this.params.logger.debug("ClientStrategy getPositionHighestMaxDrawdownPnlPercentage", { symbol, currentPrice });
|
|
8030
|
+
if (!this._pendingSignal) {
|
|
8031
|
+
return null;
|
|
8032
|
+
}
|
|
8033
|
+
const currentPnl = toProfitLossDto(this._pendingSignal, currentPrice);
|
|
8034
|
+
return Math.max(0, currentPnl.pnlPercentage - this._pendingSignal._fall.pnlPercentage);
|
|
8035
|
+
}
|
|
8036
|
+
/**
|
|
8037
|
+
* Returns the distance in PnL cost between the current price and the worst drawdown trough.
|
|
8038
|
+
*
|
|
8039
|
+
* Measures how much the position has recovered from its deepest loss point.
|
|
8040
|
+
* Computed as: max(0, currentPnlCost - fallPnlCost).
|
|
8041
|
+
* Zero when called at the exact moment the trough was set, or when current PnL <= trough PnL.
|
|
8042
|
+
*
|
|
8043
|
+
* Returns null if no pending signal exists.
|
|
8044
|
+
*
|
|
8045
|
+
* @param symbol - Trading pair symbol
|
|
8046
|
+
* @param currentPrice - Current market price
|
|
8047
|
+
* @returns Promise resolving to recovery distance in PnL cost (≥ 0) or null
|
|
8048
|
+
*/
|
|
8049
|
+
async getPositionHighestMaxDrawdownPnlCost(symbol, currentPrice) {
|
|
8050
|
+
this.params.logger.debug("ClientStrategy getPositionHighestMaxDrawdownPnlCost", { symbol, currentPrice });
|
|
8051
|
+
if (!this._pendingSignal) {
|
|
8052
|
+
return null;
|
|
8053
|
+
}
|
|
8054
|
+
const currentPnl = toProfitLossDto(this._pendingSignal, currentPrice);
|
|
8055
|
+
return Math.max(0, currentPnl.pnlCost - this._pendingSignal._fall.pnlCost);
|
|
8056
|
+
}
|
|
7973
8057
|
/**
|
|
7974
8058
|
* Performs a single tick of strategy execution.
|
|
7975
8059
|
*
|
|
@@ -11077,6 +11161,90 @@ class StrategyConnectionService {
|
|
|
11077
11161
|
const strategy = this.getStrategy(symbol, context.strategyName, context.exchangeName, context.frameName, backtest);
|
|
11078
11162
|
return await strategy.getPositionMaxDrawdownPnlCost(symbol);
|
|
11079
11163
|
};
|
|
11164
|
+
/**
|
|
11165
|
+
* Returns the distance in PnL percentage between the current price and the highest profit peak.
|
|
11166
|
+
*
|
|
11167
|
+
* Resolves current price via priceMetaService and delegates to
|
|
11168
|
+
* ClientStrategy.getPositionHighestProfitDistancePnlPercentage().
|
|
11169
|
+
* Returns null if no pending signal exists.
|
|
11170
|
+
*
|
|
11171
|
+
* @param backtest - Whether running in backtest mode
|
|
11172
|
+
* @param symbol - Trading pair symbol
|
|
11173
|
+
* @param context - Execution context with strategyName, exchangeName, frameName
|
|
11174
|
+
* @returns Promise resolving to drawdown distance in PnL% (≥ 0) or null
|
|
11175
|
+
*/
|
|
11176
|
+
this.getPositionHighestProfitDistancePnlPercentage = async (backtest, symbol, context) => {
|
|
11177
|
+
this.loggerService.log("strategyConnectionService getPositionHighestProfitDistancePnlPercentage", {
|
|
11178
|
+
symbol,
|
|
11179
|
+
context,
|
|
11180
|
+
});
|
|
11181
|
+
const strategy = this.getStrategy(symbol, context.strategyName, context.exchangeName, context.frameName, backtest);
|
|
11182
|
+
const currentPrice = await this.priceMetaService.getCurrentPrice(symbol, context, backtest);
|
|
11183
|
+
return await strategy.getPositionHighestProfitDistancePnlPercentage(symbol, currentPrice);
|
|
11184
|
+
};
|
|
11185
|
+
/**
|
|
11186
|
+
* Returns the distance in PnL cost between the current price and the highest profit peak.
|
|
11187
|
+
*
|
|
11188
|
+
* Resolves current price via priceMetaService and delegates to
|
|
11189
|
+
* ClientStrategy.getPositionHighestProfitDistancePnlCost().
|
|
11190
|
+
* Returns null if no pending signal exists.
|
|
11191
|
+
*
|
|
11192
|
+
* @param backtest - Whether running in backtest mode
|
|
11193
|
+
* @param symbol - Trading pair symbol
|
|
11194
|
+
* @param context - Execution context with strategyName, exchangeName, frameName
|
|
11195
|
+
* @returns Promise resolving to drawdown distance in PnL cost (≥ 0) or null
|
|
11196
|
+
*/
|
|
11197
|
+
this.getPositionHighestProfitDistancePnlCost = async (backtest, symbol, context) => {
|
|
11198
|
+
this.loggerService.log("strategyConnectionService getPositionHighestProfitDistancePnlCost", {
|
|
11199
|
+
symbol,
|
|
11200
|
+
context,
|
|
11201
|
+
});
|
|
11202
|
+
const strategy = this.getStrategy(symbol, context.strategyName, context.exchangeName, context.frameName, backtest);
|
|
11203
|
+
const currentPrice = await this.priceMetaService.getCurrentPrice(symbol, context, backtest);
|
|
11204
|
+
return await strategy.getPositionHighestProfitDistancePnlCost(symbol, currentPrice);
|
|
11205
|
+
};
|
|
11206
|
+
/**
|
|
11207
|
+
* Returns the distance in PnL percentage between the current price and the worst drawdown trough.
|
|
11208
|
+
*
|
|
11209
|
+
* Resolves current price via priceMetaService and delegates to
|
|
11210
|
+
* ClientStrategy.getPositionHighestMaxDrawdownPnlPercentage().
|
|
11211
|
+
* Returns null if no pending signal exists.
|
|
11212
|
+
*
|
|
11213
|
+
* @param backtest - Whether running in backtest mode
|
|
11214
|
+
* @param symbol - Trading pair symbol
|
|
11215
|
+
* @param context - Execution context with strategyName, exchangeName, frameName
|
|
11216
|
+
* @returns Promise resolving to recovery distance in PnL% (≥ 0) or null
|
|
11217
|
+
*/
|
|
11218
|
+
this.getPositionHighestMaxDrawdownPnlPercentage = async (backtest, symbol, context) => {
|
|
11219
|
+
this.loggerService.log("strategyConnectionService getPositionHighestMaxDrawdownPnlPercentage", {
|
|
11220
|
+
symbol,
|
|
11221
|
+
context,
|
|
11222
|
+
});
|
|
11223
|
+
const strategy = this.getStrategy(symbol, context.strategyName, context.exchangeName, context.frameName, backtest);
|
|
11224
|
+
const currentPrice = await this.priceMetaService.getCurrentPrice(symbol, context, backtest);
|
|
11225
|
+
return await strategy.getPositionHighestMaxDrawdownPnlPercentage(symbol, currentPrice);
|
|
11226
|
+
};
|
|
11227
|
+
/**
|
|
11228
|
+
* Returns the distance in PnL cost between the current price and the worst drawdown trough.
|
|
11229
|
+
*
|
|
11230
|
+
* Resolves current price via priceMetaService and delegates to
|
|
11231
|
+
* ClientStrategy.getPositionHighestMaxDrawdownPnlCost().
|
|
11232
|
+
* Returns null if no pending signal exists.
|
|
11233
|
+
*
|
|
11234
|
+
* @param backtest - Whether running in backtest mode
|
|
11235
|
+
* @param symbol - Trading pair symbol
|
|
11236
|
+
* @param context - Execution context with strategyName, exchangeName, frameName
|
|
11237
|
+
* @returns Promise resolving to recovery distance in PnL cost (≥ 0) or null
|
|
11238
|
+
*/
|
|
11239
|
+
this.getPositionHighestMaxDrawdownPnlCost = async (backtest, symbol, context) => {
|
|
11240
|
+
this.loggerService.log("strategyConnectionService getPositionHighestMaxDrawdownPnlCost", {
|
|
11241
|
+
symbol,
|
|
11242
|
+
context,
|
|
11243
|
+
});
|
|
11244
|
+
const strategy = this.getStrategy(symbol, context.strategyName, context.exchangeName, context.frameName, backtest);
|
|
11245
|
+
const currentPrice = await this.priceMetaService.getCurrentPrice(symbol, context, backtest);
|
|
11246
|
+
return await strategy.getPositionHighestMaxDrawdownPnlCost(symbol, currentPrice);
|
|
11247
|
+
};
|
|
11080
11248
|
/**
|
|
11081
11249
|
* Disposes the ClientStrategy instance for the given context.
|
|
11082
11250
|
*
|
|
@@ -15238,6 +15406,82 @@ class StrategyCoreService {
|
|
|
15238
15406
|
await this.validate(context);
|
|
15239
15407
|
return await this.strategyConnectionService.getPositionMaxDrawdownPnlCost(backtest, symbol, context);
|
|
15240
15408
|
};
|
|
15409
|
+
/**
|
|
15410
|
+
* Returns the distance in PnL percentage between the current price and the highest profit peak.
|
|
15411
|
+
*
|
|
15412
|
+
* Delegates to StrategyConnectionService.getPositionHighestProfitDistancePnlPercentage().
|
|
15413
|
+
* Returns null if no pending signal exists.
|
|
15414
|
+
*
|
|
15415
|
+
* @param backtest - Whether running in backtest mode
|
|
15416
|
+
* @param symbol - Trading pair symbol
|
|
15417
|
+
* @param context - Execution context with strategyName, exchangeName, frameName
|
|
15418
|
+
* @returns Promise resolving to drawdown distance in PnL% (≥ 0) or null
|
|
15419
|
+
*/
|
|
15420
|
+
this.getPositionHighestProfitDistancePnlPercentage = async (backtest, symbol, context) => {
|
|
15421
|
+
this.loggerService.log("strategyCoreService getPositionHighestProfitDistancePnlPercentage", {
|
|
15422
|
+
symbol,
|
|
15423
|
+
context,
|
|
15424
|
+
});
|
|
15425
|
+
await this.validate(context);
|
|
15426
|
+
return await this.strategyConnectionService.getPositionHighestProfitDistancePnlPercentage(backtest, symbol, context);
|
|
15427
|
+
};
|
|
15428
|
+
/**
|
|
15429
|
+
* Returns the distance in PnL cost between the current price and the highest profit peak.
|
|
15430
|
+
*
|
|
15431
|
+
* Delegates to StrategyConnectionService.getPositionHighestProfitDistancePnlCost().
|
|
15432
|
+
* Returns null if no pending signal exists.
|
|
15433
|
+
*
|
|
15434
|
+
* @param backtest - Whether running in backtest mode
|
|
15435
|
+
* @param symbol - Trading pair symbol
|
|
15436
|
+
* @param context - Execution context with strategyName, exchangeName, frameName
|
|
15437
|
+
* @returns Promise resolving to drawdown distance in PnL cost (≥ 0) or null
|
|
15438
|
+
*/
|
|
15439
|
+
this.getPositionHighestProfitDistancePnlCost = async (backtest, symbol, context) => {
|
|
15440
|
+
this.loggerService.log("strategyCoreService getPositionHighestProfitDistancePnlCost", {
|
|
15441
|
+
symbol,
|
|
15442
|
+
context,
|
|
15443
|
+
});
|
|
15444
|
+
await this.validate(context);
|
|
15445
|
+
return await this.strategyConnectionService.getPositionHighestProfitDistancePnlCost(backtest, symbol, context);
|
|
15446
|
+
};
|
|
15447
|
+
/**
|
|
15448
|
+
* Returns the distance in PnL percentage between the current price and the worst drawdown trough.
|
|
15449
|
+
*
|
|
15450
|
+
* Delegates to StrategyConnectionService.getPositionHighestMaxDrawdownPnlPercentage().
|
|
15451
|
+
* Returns null if no pending signal exists.
|
|
15452
|
+
*
|
|
15453
|
+
* @param backtest - Whether running in backtest mode
|
|
15454
|
+
* @param symbol - Trading pair symbol
|
|
15455
|
+
* @param context - Execution context with strategyName, exchangeName, frameName
|
|
15456
|
+
* @returns Promise resolving to recovery distance in PnL% (≥ 0) or null
|
|
15457
|
+
*/
|
|
15458
|
+
this.getPositionHighestMaxDrawdownPnlPercentage = async (backtest, symbol, context) => {
|
|
15459
|
+
this.loggerService.log("strategyCoreService getPositionHighestMaxDrawdownPnlPercentage", {
|
|
15460
|
+
symbol,
|
|
15461
|
+
context,
|
|
15462
|
+
});
|
|
15463
|
+
await this.validate(context);
|
|
15464
|
+
return await this.strategyConnectionService.getPositionHighestMaxDrawdownPnlPercentage(backtest, symbol, context);
|
|
15465
|
+
};
|
|
15466
|
+
/**
|
|
15467
|
+
* Returns the distance in PnL cost between the current price and the worst drawdown trough.
|
|
15468
|
+
*
|
|
15469
|
+
* Delegates to StrategyConnectionService.getPositionHighestMaxDrawdownPnlCost().
|
|
15470
|
+
* Returns null if no pending signal exists.
|
|
15471
|
+
*
|
|
15472
|
+
* @param backtest - Whether running in backtest mode
|
|
15473
|
+
* @param symbol - Trading pair symbol
|
|
15474
|
+
* @param context - Execution context with strategyName, exchangeName, frameName
|
|
15475
|
+
* @returns Promise resolving to recovery distance in PnL cost (≥ 0) or null
|
|
15476
|
+
*/
|
|
15477
|
+
this.getPositionHighestMaxDrawdownPnlCost = async (backtest, symbol, context) => {
|
|
15478
|
+
this.loggerService.log("strategyCoreService getPositionHighestMaxDrawdownPnlCost", {
|
|
15479
|
+
symbol,
|
|
15480
|
+
context,
|
|
15481
|
+
});
|
|
15482
|
+
await this.validate(context);
|
|
15483
|
+
return await this.strategyConnectionService.getPositionHighestMaxDrawdownPnlCost(backtest, symbol, context);
|
|
15484
|
+
};
|
|
15241
15485
|
}
|
|
15242
15486
|
}
|
|
15243
15487
|
|
|
@@ -34893,6 +35137,10 @@ const GET_POSITION_MAX_DRAWDOWN_PRICE_METHOD_NAME = "strategy.getPositionMaxDraw
|
|
|
34893
35137
|
const GET_POSITION_MAX_DRAWDOWN_TIMESTAMP_METHOD_NAME = "strategy.getPositionMaxDrawdownTimestamp";
|
|
34894
35138
|
const GET_POSITION_MAX_DRAWDOWN_PNL_PERCENTAGE_METHOD_NAME = "strategy.getPositionMaxDrawdownPnlPercentage";
|
|
34895
35139
|
const GET_POSITION_MAX_DRAWDOWN_PNL_COST_METHOD_NAME = "strategy.getPositionMaxDrawdownPnlCost";
|
|
35140
|
+
const GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_PERCENTAGE_METHOD_NAME = "strategy.getPositionHighestProfitDistancePnlPercentage";
|
|
35141
|
+
const GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_COST_METHOD_NAME = "strategy.getPositionHighestProfitDistancePnlCost";
|
|
35142
|
+
const GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_PERCENTAGE_METHOD_NAME = "strategy.getPositionHighestMaxDrawdownPnlPercentage";
|
|
35143
|
+
const GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_COST_METHOD_NAME = "strategy.getPositionHighestMaxDrawdownPnlCost";
|
|
34896
35144
|
const GET_POSITION_ENTRY_OVERLAP_METHOD_NAME = "strategy.getPositionEntryOverlap";
|
|
34897
35145
|
const GET_POSITION_PARTIAL_OVERLAP_METHOD_NAME = "strategy.getPositionPartialOverlap";
|
|
34898
35146
|
const HAS_NO_PENDING_SIGNAL_METHOD_NAME = "strategy.hasNoPendingSignal";
|
|
@@ -36527,6 +36775,122 @@ async function getPositionMaxDrawdownPnlCost(symbol) {
|
|
|
36527
36775
|
const { exchangeName, frameName, strategyName } = backtest.methodContextService.context;
|
|
36528
36776
|
return await backtest.strategyCoreService.getPositionMaxDrawdownPnlCost(isBacktest, symbol, { exchangeName, frameName, strategyName });
|
|
36529
36777
|
}
|
|
36778
|
+
/**
|
|
36779
|
+
* Returns the distance in PnL percentage between the current price and the highest profit peak.
|
|
36780
|
+
*
|
|
36781
|
+
* Computed as: max(0, peakPnlPercentage - currentPnlPercentage).
|
|
36782
|
+
* Returns null if no pending signal exists.
|
|
36783
|
+
*
|
|
36784
|
+
* @param symbol - Trading pair symbol
|
|
36785
|
+
* @returns Promise resolving to drawdown distance in PnL% (≥ 0) or null
|
|
36786
|
+
*
|
|
36787
|
+
* @example
|
|
36788
|
+
* ```typescript
|
|
36789
|
+
* import { getPositionHighestProfitDistancePnlPercentage } from "backtest-kit";
|
|
36790
|
+
*
|
|
36791
|
+
* const dist = await getPositionHighestProfitDistancePnlPercentage("BTCUSDT");
|
|
36792
|
+
* // e.g. 1.5 (gave back 1.5% from peak)
|
|
36793
|
+
* ```
|
|
36794
|
+
*/
|
|
36795
|
+
async function getPositionHighestProfitDistancePnlPercentage(symbol) {
|
|
36796
|
+
backtest.loggerService.info(GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_PERCENTAGE_METHOD_NAME, { symbol });
|
|
36797
|
+
if (!ExecutionContextService.hasContext()) {
|
|
36798
|
+
throw new Error("getPositionHighestProfitDistancePnlPercentage requires an execution context");
|
|
36799
|
+
}
|
|
36800
|
+
if (!MethodContextService.hasContext()) {
|
|
36801
|
+
throw new Error("getPositionHighestProfitDistancePnlPercentage requires a method context");
|
|
36802
|
+
}
|
|
36803
|
+
const { backtest: isBacktest } = backtest.executionContextService.context;
|
|
36804
|
+
const { exchangeName, frameName, strategyName } = backtest.methodContextService.context;
|
|
36805
|
+
return await backtest.strategyCoreService.getPositionHighestProfitDistancePnlPercentage(isBacktest, symbol, { exchangeName, frameName, strategyName });
|
|
36806
|
+
}
|
|
36807
|
+
/**
|
|
36808
|
+
* Returns the distance in PnL cost between the current price and the highest profit peak.
|
|
36809
|
+
*
|
|
36810
|
+
* Computed as: max(0, peakPnlCost - currentPnlCost).
|
|
36811
|
+
* Returns null if no pending signal exists.
|
|
36812
|
+
*
|
|
36813
|
+
* @param symbol - Trading pair symbol
|
|
36814
|
+
* @returns Promise resolving to drawdown distance in PnL cost (≥ 0) or null
|
|
36815
|
+
*
|
|
36816
|
+
* @example
|
|
36817
|
+
* ```typescript
|
|
36818
|
+
* import { getPositionHighestProfitDistancePnlCost } from "backtest-kit";
|
|
36819
|
+
*
|
|
36820
|
+
* const dist = await getPositionHighestProfitDistancePnlCost("BTCUSDT");
|
|
36821
|
+
* // e.g. 3.2 (gave back $3.2 from peak)
|
|
36822
|
+
* ```
|
|
36823
|
+
*/
|
|
36824
|
+
async function getPositionHighestProfitDistancePnlCost(symbol) {
|
|
36825
|
+
backtest.loggerService.info(GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_COST_METHOD_NAME, { symbol });
|
|
36826
|
+
if (!ExecutionContextService.hasContext()) {
|
|
36827
|
+
throw new Error("getPositionHighestProfitDistancePnlCost requires an execution context");
|
|
36828
|
+
}
|
|
36829
|
+
if (!MethodContextService.hasContext()) {
|
|
36830
|
+
throw new Error("getPositionHighestProfitDistancePnlCost requires a method context");
|
|
36831
|
+
}
|
|
36832
|
+
const { backtest: isBacktest } = backtest.executionContextService.context;
|
|
36833
|
+
const { exchangeName, frameName, strategyName } = backtest.methodContextService.context;
|
|
36834
|
+
return await backtest.strategyCoreService.getPositionHighestProfitDistancePnlCost(isBacktest, symbol, { exchangeName, frameName, strategyName });
|
|
36835
|
+
}
|
|
36836
|
+
/**
|
|
36837
|
+
* Returns the distance in PnL percentage between the current price and the worst drawdown trough.
|
|
36838
|
+
*
|
|
36839
|
+
* Computed as: max(0, currentPnlPercentage - fallPnlPercentage).
|
|
36840
|
+
* Returns null if no pending signal exists.
|
|
36841
|
+
*
|
|
36842
|
+
* @param symbol - Trading pair symbol
|
|
36843
|
+
* @returns Promise resolving to recovery distance in PnL% (≥ 0) or null
|
|
36844
|
+
*
|
|
36845
|
+
* @example
|
|
36846
|
+
* ```typescript
|
|
36847
|
+
* import { getPositionHighestMaxDrawdownPnlPercentage } from "backtest-kit";
|
|
36848
|
+
*
|
|
36849
|
+
* const dist = await getPositionHighestMaxDrawdownPnlPercentage("BTCUSDT");
|
|
36850
|
+
* // e.g. 2.1 (recovered 2.1% from trough)
|
|
36851
|
+
* ```
|
|
36852
|
+
*/
|
|
36853
|
+
async function getPositionHighestMaxDrawdownPnlPercentage(symbol) {
|
|
36854
|
+
backtest.loggerService.info(GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_PERCENTAGE_METHOD_NAME, { symbol });
|
|
36855
|
+
if (!ExecutionContextService.hasContext()) {
|
|
36856
|
+
throw new Error("getPositionHighestMaxDrawdownPnlPercentage requires an execution context");
|
|
36857
|
+
}
|
|
36858
|
+
if (!MethodContextService.hasContext()) {
|
|
36859
|
+
throw new Error("getPositionHighestMaxDrawdownPnlPercentage requires a method context");
|
|
36860
|
+
}
|
|
36861
|
+
const { backtest: isBacktest } = backtest.executionContextService.context;
|
|
36862
|
+
const { exchangeName, frameName, strategyName } = backtest.methodContextService.context;
|
|
36863
|
+
return await backtest.strategyCoreService.getPositionHighestMaxDrawdownPnlPercentage(isBacktest, symbol, { exchangeName, frameName, strategyName });
|
|
36864
|
+
}
|
|
36865
|
+
/**
|
|
36866
|
+
* Returns the distance in PnL cost between the current price and the worst drawdown trough.
|
|
36867
|
+
*
|
|
36868
|
+
* Computed as: max(0, currentPnlCost - fallPnlCost).
|
|
36869
|
+
* Returns null if no pending signal exists.
|
|
36870
|
+
*
|
|
36871
|
+
* @param symbol - Trading pair symbol
|
|
36872
|
+
* @returns Promise resolving to recovery distance in PnL cost (≥ 0) or null
|
|
36873
|
+
*
|
|
36874
|
+
* @example
|
|
36875
|
+
* ```typescript
|
|
36876
|
+
* import { getPositionHighestMaxDrawdownPnlCost } from "backtest-kit";
|
|
36877
|
+
*
|
|
36878
|
+
* const dist = await getPositionHighestMaxDrawdownPnlCost("BTCUSDT");
|
|
36879
|
+
* // e.g. 4.8 (recovered $4.8 from trough)
|
|
36880
|
+
* ```
|
|
36881
|
+
*/
|
|
36882
|
+
async function getPositionHighestMaxDrawdownPnlCost(symbol) {
|
|
36883
|
+
backtest.loggerService.info(GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_COST_METHOD_NAME, { symbol });
|
|
36884
|
+
if (!ExecutionContextService.hasContext()) {
|
|
36885
|
+
throw new Error("getPositionHighestMaxDrawdownPnlCost requires an execution context");
|
|
36886
|
+
}
|
|
36887
|
+
if (!MethodContextService.hasContext()) {
|
|
36888
|
+
throw new Error("getPositionHighestMaxDrawdownPnlCost requires a method context");
|
|
36889
|
+
}
|
|
36890
|
+
const { backtest: isBacktest } = backtest.executionContextService.context;
|
|
36891
|
+
const { exchangeName, frameName, strategyName } = backtest.methodContextService.context;
|
|
36892
|
+
return await backtest.strategyCoreService.getPositionHighestMaxDrawdownPnlCost(isBacktest, symbol, { exchangeName, frameName, strategyName });
|
|
36893
|
+
}
|
|
36530
36894
|
/**
|
|
36531
36895
|
* Checks whether the current price falls within the tolerance zone of any existing DCA entry level.
|
|
36532
36896
|
* Use this to prevent duplicate DCA entries at the same price area.
|
|
@@ -38196,6 +38560,10 @@ const BACKTEST_METHOD_NAME_GET_POSITION_MAX_DRAWDOWN_PRICE = "BacktestUtils.getP
|
|
|
38196
38560
|
const BACKTEST_METHOD_NAME_GET_POSITION_MAX_DRAWDOWN_TIMESTAMP = "BacktestUtils.getPositionMaxDrawdownTimestamp";
|
|
38197
38561
|
const BACKTEST_METHOD_NAME_GET_POSITION_MAX_DRAWDOWN_PNL_PERCENTAGE = "BacktestUtils.getPositionMaxDrawdownPnlPercentage";
|
|
38198
38562
|
const BACKTEST_METHOD_NAME_GET_POSITION_MAX_DRAWDOWN_PNL_COST = "BacktestUtils.getPositionMaxDrawdownPnlCost";
|
|
38563
|
+
const BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_PERCENTAGE = "BacktestUtils.getPositionHighestProfitDistancePnlPercentage";
|
|
38564
|
+
const BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_COST = "BacktestUtils.getPositionHighestProfitDistancePnlCost";
|
|
38565
|
+
const BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_PERCENTAGE = "BacktestUtils.getPositionHighestMaxDrawdownPnlPercentage";
|
|
38566
|
+
const BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_COST = "BacktestUtils.getPositionHighestMaxDrawdownPnlCost";
|
|
38199
38567
|
const BACKTEST_METHOD_NAME_GET_POSITION_ENTRY_OVERLAP = "BacktestUtils.getPositionEntryOverlap";
|
|
38200
38568
|
const BACKTEST_METHOD_NAME_GET_POSITION_PARTIAL_OVERLAP = "BacktestUtils.getPositionPartialOverlap";
|
|
38201
38569
|
const BACKTEST_METHOD_NAME_BREAKEVEN = "Backtest.commitBreakeven";
|
|
@@ -39465,6 +39833,118 @@ class BacktestUtils {
|
|
|
39465
39833
|
}
|
|
39466
39834
|
return await backtest.strategyCoreService.getPositionMaxDrawdownPnlCost(true, symbol, context);
|
|
39467
39835
|
};
|
|
39836
|
+
/**
|
|
39837
|
+
* Returns the distance in PnL percentage between the current price and the highest profit peak.
|
|
39838
|
+
*
|
|
39839
|
+
* Computed as: max(0, peakPnlPercentage - currentPnlPercentage).
|
|
39840
|
+
* Returns null if no pending signal exists.
|
|
39841
|
+
*
|
|
39842
|
+
* @param symbol - Trading pair symbol
|
|
39843
|
+
* @param context - Execution context with strategyName, exchangeName, and frameName
|
|
39844
|
+
* @returns drawdown distance in PnL% (≥ 0) or null if no active position
|
|
39845
|
+
*/
|
|
39846
|
+
this.getPositionHighestProfitDistancePnlPercentage = async (symbol, context) => {
|
|
39847
|
+
backtest.loggerService.info(BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_PERCENTAGE, {
|
|
39848
|
+
symbol,
|
|
39849
|
+
context,
|
|
39850
|
+
});
|
|
39851
|
+
backtest.strategyValidationService.validate(context.strategyName, BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_PERCENTAGE);
|
|
39852
|
+
backtest.exchangeValidationService.validate(context.exchangeName, BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_PERCENTAGE);
|
|
39853
|
+
{
|
|
39854
|
+
const { riskName, riskList, actions } = backtest.strategySchemaService.get(context.strategyName);
|
|
39855
|
+
riskName &&
|
|
39856
|
+
backtest.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_PERCENTAGE);
|
|
39857
|
+
riskList &&
|
|
39858
|
+
riskList.forEach((riskName) => backtest.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_PERCENTAGE));
|
|
39859
|
+
actions &&
|
|
39860
|
+
actions.forEach((actionName) => backtest.actionValidationService.validate(actionName, BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_PERCENTAGE));
|
|
39861
|
+
}
|
|
39862
|
+
return await backtest.strategyCoreService.getPositionHighestProfitDistancePnlPercentage(true, symbol, context);
|
|
39863
|
+
};
|
|
39864
|
+
/**
|
|
39865
|
+
* Returns the distance in PnL cost between the current price and the highest profit peak.
|
|
39866
|
+
*
|
|
39867
|
+
* Computed as: max(0, peakPnlCost - currentPnlCost).
|
|
39868
|
+
* Returns null if no pending signal exists.
|
|
39869
|
+
*
|
|
39870
|
+
* @param symbol - Trading pair symbol
|
|
39871
|
+
* @param context - Execution context with strategyName, exchangeName, and frameName
|
|
39872
|
+
* @returns drawdown distance in PnL cost (≥ 0) or null if no active position
|
|
39873
|
+
*/
|
|
39874
|
+
this.getPositionHighestProfitDistancePnlCost = async (symbol, context) => {
|
|
39875
|
+
backtest.loggerService.info(BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_COST, {
|
|
39876
|
+
symbol,
|
|
39877
|
+
context,
|
|
39878
|
+
});
|
|
39879
|
+
backtest.strategyValidationService.validate(context.strategyName, BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_COST);
|
|
39880
|
+
backtest.exchangeValidationService.validate(context.exchangeName, BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_COST);
|
|
39881
|
+
{
|
|
39882
|
+
const { riskName, riskList, actions } = backtest.strategySchemaService.get(context.strategyName);
|
|
39883
|
+
riskName &&
|
|
39884
|
+
backtest.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_COST);
|
|
39885
|
+
riskList &&
|
|
39886
|
+
riskList.forEach((riskName) => backtest.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_COST));
|
|
39887
|
+
actions &&
|
|
39888
|
+
actions.forEach((actionName) => backtest.actionValidationService.validate(actionName, BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_COST));
|
|
39889
|
+
}
|
|
39890
|
+
return await backtest.strategyCoreService.getPositionHighestProfitDistancePnlCost(true, symbol, context);
|
|
39891
|
+
};
|
|
39892
|
+
/**
|
|
39893
|
+
* Returns the distance in PnL percentage between the current price and the worst drawdown trough.
|
|
39894
|
+
*
|
|
39895
|
+
* Computed as: max(0, currentPnlPercentage - fallPnlPercentage).
|
|
39896
|
+
* Returns null if no pending signal exists.
|
|
39897
|
+
*
|
|
39898
|
+
* @param symbol - Trading pair symbol
|
|
39899
|
+
* @param context - Execution context with strategyName, exchangeName, and frameName
|
|
39900
|
+
* @returns recovery distance in PnL% (≥ 0) or null if no active position
|
|
39901
|
+
*/
|
|
39902
|
+
this.getPositionHighestMaxDrawdownPnlPercentage = async (symbol, context) => {
|
|
39903
|
+
backtest.loggerService.info(BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_PERCENTAGE, {
|
|
39904
|
+
symbol,
|
|
39905
|
+
context,
|
|
39906
|
+
});
|
|
39907
|
+
backtest.strategyValidationService.validate(context.strategyName, BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_PERCENTAGE);
|
|
39908
|
+
backtest.exchangeValidationService.validate(context.exchangeName, BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_PERCENTAGE);
|
|
39909
|
+
{
|
|
39910
|
+
const { riskName, riskList, actions } = backtest.strategySchemaService.get(context.strategyName);
|
|
39911
|
+
riskName &&
|
|
39912
|
+
backtest.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_PERCENTAGE);
|
|
39913
|
+
riskList &&
|
|
39914
|
+
riskList.forEach((riskName) => backtest.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_PERCENTAGE));
|
|
39915
|
+
actions &&
|
|
39916
|
+
actions.forEach((actionName) => backtest.actionValidationService.validate(actionName, BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_PERCENTAGE));
|
|
39917
|
+
}
|
|
39918
|
+
return await backtest.strategyCoreService.getPositionHighestMaxDrawdownPnlPercentage(true, symbol, context);
|
|
39919
|
+
};
|
|
39920
|
+
/**
|
|
39921
|
+
* Returns the distance in PnL cost between the current price and the worst drawdown trough.
|
|
39922
|
+
*
|
|
39923
|
+
* Computed as: max(0, currentPnlCost - fallPnlCost).
|
|
39924
|
+
* Returns null if no pending signal exists.
|
|
39925
|
+
*
|
|
39926
|
+
* @param symbol - Trading pair symbol
|
|
39927
|
+
* @param context - Execution context with strategyName, exchangeName, and frameName
|
|
39928
|
+
* @returns recovery distance in PnL cost (≥ 0) or null if no active position
|
|
39929
|
+
*/
|
|
39930
|
+
this.getPositionHighestMaxDrawdownPnlCost = async (symbol, context) => {
|
|
39931
|
+
backtest.loggerService.info(BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_COST, {
|
|
39932
|
+
symbol,
|
|
39933
|
+
context,
|
|
39934
|
+
});
|
|
39935
|
+
backtest.strategyValidationService.validate(context.strategyName, BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_COST);
|
|
39936
|
+
backtest.exchangeValidationService.validate(context.exchangeName, BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_COST);
|
|
39937
|
+
{
|
|
39938
|
+
const { riskName, riskList, actions } = backtest.strategySchemaService.get(context.strategyName);
|
|
39939
|
+
riskName &&
|
|
39940
|
+
backtest.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_COST);
|
|
39941
|
+
riskList &&
|
|
39942
|
+
riskList.forEach((riskName) => backtest.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_COST));
|
|
39943
|
+
actions &&
|
|
39944
|
+
actions.forEach((actionName) => backtest.actionValidationService.validate(actionName, BACKTEST_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_COST));
|
|
39945
|
+
}
|
|
39946
|
+
return await backtest.strategyCoreService.getPositionHighestMaxDrawdownPnlCost(true, symbol, context);
|
|
39947
|
+
};
|
|
39468
39948
|
/**
|
|
39469
39949
|
* Checks whether the current price falls within the tolerance zone of any existing DCA entry level.
|
|
39470
39950
|
* Use this to prevent duplicate DCA entries at the same price area.
|
|
@@ -40590,6 +41070,10 @@ const LIVE_METHOD_NAME_GET_POSITION_MAX_DRAWDOWN_PRICE = "LiveUtils.getPositionM
|
|
|
40590
41070
|
const LIVE_METHOD_NAME_GET_POSITION_MAX_DRAWDOWN_TIMESTAMP = "LiveUtils.getPositionMaxDrawdownTimestamp";
|
|
40591
41071
|
const LIVE_METHOD_NAME_GET_POSITION_MAX_DRAWDOWN_PNL_PERCENTAGE = "LiveUtils.getPositionMaxDrawdownPnlPercentage";
|
|
40592
41072
|
const LIVE_METHOD_NAME_GET_POSITION_MAX_DRAWDOWN_PNL_COST = "LiveUtils.getPositionMaxDrawdownPnlCost";
|
|
41073
|
+
const LIVE_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_PERCENTAGE = "LiveUtils.getPositionHighestProfitDistancePnlPercentage";
|
|
41074
|
+
const LIVE_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_COST = "LiveUtils.getPositionHighestProfitDistancePnlCost";
|
|
41075
|
+
const LIVE_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_PERCENTAGE = "LiveUtils.getPositionHighestMaxDrawdownPnlPercentage";
|
|
41076
|
+
const LIVE_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_COST = "LiveUtils.getPositionHighestMaxDrawdownPnlCost";
|
|
40593
41077
|
const LIVE_METHOD_NAME_GET_POSITION_ENTRY_OVERLAP = "LiveUtils.getPositionEntryOverlap";
|
|
40594
41078
|
const LIVE_METHOD_NAME_GET_POSITION_PARTIAL_OVERLAP = "LiveUtils.getPositionPartialOverlap";
|
|
40595
41079
|
const LIVE_METHOD_NAME_BREAKEVEN = "Live.commitBreakeven";
|
|
@@ -41986,6 +42470,134 @@ class LiveUtils {
|
|
|
41986
42470
|
frameName: "",
|
|
41987
42471
|
});
|
|
41988
42472
|
};
|
|
42473
|
+
/**
|
|
42474
|
+
* Returns the distance in PnL percentage between the current price and the highest profit peak.
|
|
42475
|
+
*
|
|
42476
|
+
* Computed as: max(0, peakPnlPercentage - currentPnlPercentage).
|
|
42477
|
+
* Returns null if no pending signal exists.
|
|
42478
|
+
*
|
|
42479
|
+
* @param symbol - Trading pair symbol
|
|
42480
|
+
* @param context - Execution context with strategyName and exchangeName
|
|
42481
|
+
* @returns drawdown distance in PnL% (≥ 0) or null if no active position
|
|
42482
|
+
*/
|
|
42483
|
+
this.getPositionHighestProfitDistancePnlPercentage = async (symbol, context) => {
|
|
42484
|
+
backtest.loggerService.info(LIVE_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_PERCENTAGE, {
|
|
42485
|
+
symbol,
|
|
42486
|
+
context,
|
|
42487
|
+
});
|
|
42488
|
+
backtest.strategyValidationService.validate(context.strategyName, LIVE_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_PERCENTAGE);
|
|
42489
|
+
backtest.exchangeValidationService.validate(context.exchangeName, LIVE_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_PERCENTAGE);
|
|
42490
|
+
{
|
|
42491
|
+
const { riskName, riskList, actions } = backtest.strategySchemaService.get(context.strategyName);
|
|
42492
|
+
riskName &&
|
|
42493
|
+
backtest.riskValidationService.validate(riskName, LIVE_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_PERCENTAGE);
|
|
42494
|
+
riskList &&
|
|
42495
|
+
riskList.forEach((riskName) => backtest.riskValidationService.validate(riskName, LIVE_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_PERCENTAGE));
|
|
42496
|
+
actions &&
|
|
42497
|
+
actions.forEach((actionName) => backtest.actionValidationService.validate(actionName, LIVE_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_PERCENTAGE));
|
|
42498
|
+
}
|
|
42499
|
+
return await backtest.strategyCoreService.getPositionHighestProfitDistancePnlPercentage(false, symbol, {
|
|
42500
|
+
strategyName: context.strategyName,
|
|
42501
|
+
exchangeName: context.exchangeName,
|
|
42502
|
+
frameName: "",
|
|
42503
|
+
});
|
|
42504
|
+
};
|
|
42505
|
+
/**
|
|
42506
|
+
* Returns the distance in PnL cost between the current price and the highest profit peak.
|
|
42507
|
+
*
|
|
42508
|
+
* Computed as: max(0, peakPnlCost - currentPnlCost).
|
|
42509
|
+
* Returns null if no pending signal exists.
|
|
42510
|
+
*
|
|
42511
|
+
* @param symbol - Trading pair symbol
|
|
42512
|
+
* @param context - Execution context with strategyName and exchangeName
|
|
42513
|
+
* @returns drawdown distance in PnL cost (≥ 0) or null if no active position
|
|
42514
|
+
*/
|
|
42515
|
+
this.getPositionHighestProfitDistancePnlCost = async (symbol, context) => {
|
|
42516
|
+
backtest.loggerService.info(LIVE_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_COST, {
|
|
42517
|
+
symbol,
|
|
42518
|
+
context,
|
|
42519
|
+
});
|
|
42520
|
+
backtest.strategyValidationService.validate(context.strategyName, LIVE_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_COST);
|
|
42521
|
+
backtest.exchangeValidationService.validate(context.exchangeName, LIVE_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_COST);
|
|
42522
|
+
{
|
|
42523
|
+
const { riskName, riskList, actions } = backtest.strategySchemaService.get(context.strategyName);
|
|
42524
|
+
riskName &&
|
|
42525
|
+
backtest.riskValidationService.validate(riskName, LIVE_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_COST);
|
|
42526
|
+
riskList &&
|
|
42527
|
+
riskList.forEach((riskName) => backtest.riskValidationService.validate(riskName, LIVE_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_COST));
|
|
42528
|
+
actions &&
|
|
42529
|
+
actions.forEach((actionName) => backtest.actionValidationService.validate(actionName, LIVE_METHOD_NAME_GET_POSITION_HIGHEST_PROFIT_DISTANCE_PNL_COST));
|
|
42530
|
+
}
|
|
42531
|
+
return await backtest.strategyCoreService.getPositionHighestProfitDistancePnlCost(false, symbol, {
|
|
42532
|
+
strategyName: context.strategyName,
|
|
42533
|
+
exchangeName: context.exchangeName,
|
|
42534
|
+
frameName: "",
|
|
42535
|
+
});
|
|
42536
|
+
};
|
|
42537
|
+
/**
|
|
42538
|
+
* Returns the distance in PnL percentage between the current price and the worst drawdown trough.
|
|
42539
|
+
*
|
|
42540
|
+
* Computed as: max(0, currentPnlPercentage - fallPnlPercentage).
|
|
42541
|
+
* Returns null if no pending signal exists.
|
|
42542
|
+
*
|
|
42543
|
+
* @param symbol - Trading pair symbol
|
|
42544
|
+
* @param context - Execution context with strategyName and exchangeName
|
|
42545
|
+
* @returns recovery distance in PnL% (≥ 0) or null if no active position
|
|
42546
|
+
*/
|
|
42547
|
+
this.getPositionHighestMaxDrawdownPnlPercentage = async (symbol, context) => {
|
|
42548
|
+
backtest.loggerService.info(LIVE_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_PERCENTAGE, {
|
|
42549
|
+
symbol,
|
|
42550
|
+
context,
|
|
42551
|
+
});
|
|
42552
|
+
backtest.strategyValidationService.validate(context.strategyName, LIVE_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_PERCENTAGE);
|
|
42553
|
+
backtest.exchangeValidationService.validate(context.exchangeName, LIVE_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_PERCENTAGE);
|
|
42554
|
+
{
|
|
42555
|
+
const { riskName, riskList, actions } = backtest.strategySchemaService.get(context.strategyName);
|
|
42556
|
+
riskName &&
|
|
42557
|
+
backtest.riskValidationService.validate(riskName, LIVE_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_PERCENTAGE);
|
|
42558
|
+
riskList &&
|
|
42559
|
+
riskList.forEach((riskName) => backtest.riskValidationService.validate(riskName, LIVE_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_PERCENTAGE));
|
|
42560
|
+
actions &&
|
|
42561
|
+
actions.forEach((actionName) => backtest.actionValidationService.validate(actionName, LIVE_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_PERCENTAGE));
|
|
42562
|
+
}
|
|
42563
|
+
return await backtest.strategyCoreService.getPositionHighestMaxDrawdownPnlPercentage(false, symbol, {
|
|
42564
|
+
strategyName: context.strategyName,
|
|
42565
|
+
exchangeName: context.exchangeName,
|
|
42566
|
+
frameName: "",
|
|
42567
|
+
});
|
|
42568
|
+
};
|
|
42569
|
+
/**
|
|
42570
|
+
* Returns the distance in PnL cost between the current price and the worst drawdown trough.
|
|
42571
|
+
*
|
|
42572
|
+
* Computed as: max(0, currentPnlCost - fallPnlCost).
|
|
42573
|
+
* Returns null if no pending signal exists.
|
|
42574
|
+
*
|
|
42575
|
+
* @param symbol - Trading pair symbol
|
|
42576
|
+
* @param context - Execution context with strategyName and exchangeName
|
|
42577
|
+
* @returns recovery distance in PnL cost (≥ 0) or null if no active position
|
|
42578
|
+
*/
|
|
42579
|
+
this.getPositionHighestMaxDrawdownPnlCost = async (symbol, context) => {
|
|
42580
|
+
backtest.loggerService.info(LIVE_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_COST, {
|
|
42581
|
+
symbol,
|
|
42582
|
+
context,
|
|
42583
|
+
});
|
|
42584
|
+
backtest.strategyValidationService.validate(context.strategyName, LIVE_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_COST);
|
|
42585
|
+
backtest.exchangeValidationService.validate(context.exchangeName, LIVE_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_COST);
|
|
42586
|
+
{
|
|
42587
|
+
const { riskName, riskList, actions } = backtest.strategySchemaService.get(context.strategyName);
|
|
42588
|
+
riskName &&
|
|
42589
|
+
backtest.riskValidationService.validate(riskName, LIVE_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_COST);
|
|
42590
|
+
riskList &&
|
|
42591
|
+
riskList.forEach((riskName) => backtest.riskValidationService.validate(riskName, LIVE_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_COST));
|
|
42592
|
+
actions &&
|
|
42593
|
+
actions.forEach((actionName) => backtest.actionValidationService.validate(actionName, LIVE_METHOD_NAME_GET_POSITION_HIGHEST_MAX_DRAWDOWN_PNL_COST));
|
|
42594
|
+
}
|
|
42595
|
+
return await backtest.strategyCoreService.getPositionHighestMaxDrawdownPnlCost(false, symbol, {
|
|
42596
|
+
strategyName: context.strategyName,
|
|
42597
|
+
exchangeName: context.exchangeName,
|
|
42598
|
+
frameName: "",
|
|
42599
|
+
});
|
|
42600
|
+
};
|
|
41989
42601
|
/**
|
|
41990
42602
|
* Checks whether the current price falls within the tolerance zone of any existing DCA entry level.
|
|
41991
42603
|
* Use this to prevent duplicate DCA entries at the same price area.
|
|
@@ -53625,17 +54237,17 @@ const CREATE_KEY_FN = (strategyName, exchangeName, frameName, isBacktest) => {
|
|
|
53625
54237
|
* @example
|
|
53626
54238
|
* ```typescript
|
|
53627
54239
|
* const instance = new IntervalFnInstance(mySignalFn, "1h");
|
|
53628
|
-
* await instance.run("BTCUSDT"); // →
|
|
53629
|
-
* await instance.run("BTCUSDT"); // → null
|
|
54240
|
+
* await instance.run("BTCUSDT"); // → T | null (fn called)
|
|
54241
|
+
* await instance.run("BTCUSDT"); // → null (skipped, same interval)
|
|
53630
54242
|
* // After 1 hour passes:
|
|
53631
|
-
* await instance.run("BTCUSDT"); // →
|
|
54243
|
+
* await instance.run("BTCUSDT"); // → T | null (fn called again)
|
|
53632
54244
|
* ```
|
|
53633
54245
|
*/
|
|
53634
54246
|
class IntervalFnInstance {
|
|
53635
54247
|
/**
|
|
53636
54248
|
* Creates a new IntervalFnInstance.
|
|
53637
54249
|
*
|
|
53638
|
-
* @param fn -
|
|
54250
|
+
* @param fn - Function to fire once per interval
|
|
53639
54251
|
* @param interval - Candle interval that controls the firing boundary
|
|
53640
54252
|
*/
|
|
53641
54253
|
constructor(fn, interval) {
|
|
@@ -53655,7 +54267,7 @@ class IntervalFnInstance {
|
|
|
53655
54267
|
* Requires active method context and execution context.
|
|
53656
54268
|
*
|
|
53657
54269
|
* @param symbol - Trading pair symbol (e.g. "BTCUSDT")
|
|
53658
|
-
* @returns The
|
|
54270
|
+
* @returns The value returned by `fn` on the first non-null fire, `null` on all subsequent calls
|
|
53659
54271
|
* within the same interval or when `fn` itself returned `null`
|
|
53660
54272
|
* @throws Error if method context, execution context, or interval is missing
|
|
53661
54273
|
*/
|
|
@@ -53716,13 +54328,13 @@ class IntervalFnInstance {
|
|
|
53716
54328
|
*
|
|
53717
54329
|
* Fired state survives process restarts — unlike `IntervalFnInstance` which is in-memory only.
|
|
53718
54330
|
*
|
|
53719
|
-
* @template T - Async function type: `(symbol: string, ...args) => Promise<
|
|
54331
|
+
* @template T - Async function type: `(symbol: string, ...args) => Promise<R | null>`
|
|
53720
54332
|
*
|
|
53721
54333
|
* @example
|
|
53722
54334
|
* ```typescript
|
|
53723
54335
|
* const instance = new IntervalFileInstance(fetchSignal, "1h", "mySignal");
|
|
53724
|
-
* await instance.run("BTCUSDT"); // →
|
|
53725
|
-
* await instance.run("BTCUSDT"); // → null
|
|
54336
|
+
* await instance.run("BTCUSDT"); // → R | null (fn called, result written to disk)
|
|
54337
|
+
* await instance.run("BTCUSDT"); // → null (record exists, already fired)
|
|
53726
54338
|
* ```
|
|
53727
54339
|
*/
|
|
53728
54340
|
class IntervalFileInstance {
|
|
@@ -53752,7 +54364,7 @@ class IntervalFileInstance {
|
|
|
53752
54364
|
this.interval = interval;
|
|
53753
54365
|
this.name = name;
|
|
53754
54366
|
/**
|
|
53755
|
-
* Execute the async
|
|
54367
|
+
* Execute the async function with persistent once-per-interval enforcement.
|
|
53756
54368
|
*
|
|
53757
54369
|
* Algorithm:
|
|
53758
54370
|
* 1. Build bucket = `${name}_${interval}_${index}` — fixed per instance, used as directory name.
|
|
@@ -53764,13 +54376,13 @@ class IntervalFileInstance {
|
|
|
53764
54376
|
*
|
|
53765
54377
|
* Requires active method context and execution context.
|
|
53766
54378
|
*
|
|
53767
|
-
* @param
|
|
53768
|
-
* @returns The
|
|
54379
|
+
* @param symbol - Trading pair symbol (e.g. "BTCUSDT")
|
|
54380
|
+
* @returns The value on the first non-null fire, `null` if already fired this interval
|
|
53769
54381
|
* or if `fn` itself returned `null`
|
|
53770
54382
|
* @throws Error if method context, execution context, or interval is missing
|
|
53771
54383
|
*/
|
|
53772
|
-
this.run = async (
|
|
53773
|
-
backtest.loggerService.debug(INTERVAL_FILE_INSTANCE_METHOD_NAME_RUN, {
|
|
54384
|
+
this.run = async (symbol) => {
|
|
54385
|
+
backtest.loggerService.debug(INTERVAL_FILE_INSTANCE_METHOD_NAME_RUN, { symbol });
|
|
53774
54386
|
const step = INTERVAL_MINUTES[this.interval];
|
|
53775
54387
|
{
|
|
53776
54388
|
if (!MethodContextService.hasContext()) {
|
|
@@ -53783,7 +54395,6 @@ class IntervalFileInstance {
|
|
|
53783
54395
|
throw new Error(`IntervalFileInstance unknown interval=${this.interval}`);
|
|
53784
54396
|
}
|
|
53785
54397
|
}
|
|
53786
|
-
const [symbol] = args;
|
|
53787
54398
|
const { when } = backtest.executionContextService.context;
|
|
53788
54399
|
const alignedTs = align(when.getTime(), this.interval);
|
|
53789
54400
|
const bucket = `${this.name}_${this.interval}_${this.index}`;
|
|
@@ -53792,7 +54403,7 @@ class IntervalFileInstance {
|
|
|
53792
54403
|
if (cached !== null) {
|
|
53793
54404
|
return null;
|
|
53794
54405
|
}
|
|
53795
|
-
const result = await this.fn
|
|
54406
|
+
const result = await this.fn(symbol, when);
|
|
53796
54407
|
if (result !== null) {
|
|
53797
54408
|
await PersistIntervalAdapter.writeIntervalData({ id: entityKey, data: result, removed: false }, bucket, entityKey);
|
|
53798
54409
|
}
|
|
@@ -53823,8 +54434,8 @@ IntervalFileInstance._indexCounter = 0;
|
|
|
53823
54434
|
* import { Interval } from "./classes/Interval";
|
|
53824
54435
|
*
|
|
53825
54436
|
* const fireOncePerHour = Interval.fn(mySignalFn, { interval: "1h" });
|
|
53826
|
-
* await fireOncePerHour("BTCUSDT"
|
|
53827
|
-
* await fireOncePerHour("BTCUSDT"
|
|
54437
|
+
* await fireOncePerHour("BTCUSDT"); // fn called — returns its result
|
|
54438
|
+
* await fireOncePerHour("BTCUSDT"); // returns null (same interval)
|
|
53828
54439
|
* ```
|
|
53829
54440
|
*/
|
|
53830
54441
|
class IntervalUtils {
|
|
@@ -53850,19 +54461,19 @@ class IntervalUtils {
|
|
|
53850
54461
|
*
|
|
53851
54462
|
* @param run - Signal function to wrap
|
|
53852
54463
|
* @param context.interval - Candle interval that controls the firing boundary
|
|
53853
|
-
* @returns Wrapped function with the same signature as `TIntervalFn
|
|
54464
|
+
* @returns Wrapped function with the same signature as `TIntervalFn<T>`, plus a `clear()` method
|
|
53854
54465
|
*
|
|
53855
54466
|
* @example
|
|
53856
54467
|
* ```typescript
|
|
53857
54468
|
* const fireOnce = Interval.fn(mySignalFn, { interval: "15m" });
|
|
53858
54469
|
*
|
|
53859
|
-
* await fireOnce("BTCUSDT"
|
|
53860
|
-
* await fireOnce("BTCUSDT"
|
|
54470
|
+
* await fireOnce("BTCUSDT"); // → T or null (fn called)
|
|
54471
|
+
* await fireOnce("BTCUSDT"); // → null (same interval, skipped)
|
|
53861
54472
|
* ```
|
|
53862
54473
|
*/
|
|
53863
54474
|
this.fn = (run, context) => {
|
|
53864
54475
|
backtest.loggerService.info(INTERVAL_METHOD_NAME_FN, { context });
|
|
53865
|
-
const wrappedFn = (symbol
|
|
54476
|
+
const wrappedFn = (symbol) => {
|
|
53866
54477
|
const instance = this._getInstance(run, context.interval);
|
|
53867
54478
|
return instance.run(symbol);
|
|
53868
54479
|
};
|
|
@@ -53899,7 +54510,7 @@ class IntervalUtils {
|
|
|
53899
54510
|
*
|
|
53900
54511
|
* @example
|
|
53901
54512
|
* ```typescript
|
|
53902
|
-
* const fetchSignal = async (symbol: string,
|
|
54513
|
+
* const fetchSignal = async (symbol: string, when: Date) => { ... };
|
|
53903
54514
|
* const fireOnce = Interval.file(fetchSignal, { interval: "1h", name: "fetchSignal" });
|
|
53904
54515
|
* await fireOnce.clear(); // delete disk records so the function fires again next call
|
|
53905
54516
|
* ```
|
|
@@ -53909,9 +54520,9 @@ class IntervalUtils {
|
|
|
53909
54520
|
{
|
|
53910
54521
|
this._getFileInstance(run, context.interval, context.name);
|
|
53911
54522
|
}
|
|
53912
|
-
const wrappedFn = (
|
|
54523
|
+
const wrappedFn = (symbol) => {
|
|
53913
54524
|
const instance = this._getFileInstance(run, context.interval, context.name);
|
|
53914
|
-
return instance.run(
|
|
54525
|
+
return instance.run(symbol);
|
|
53915
54526
|
};
|
|
53916
54527
|
wrappedFn.clear = async () => {
|
|
53917
54528
|
backtest.loggerService.info(INTERVAL_METHOD_NAME_FILE_CLEAR);
|
|
@@ -55082,4 +55693,4 @@ const validateSignal = (signal, currentPrice) => {
|
|
|
55082
55693
|
return !errors.length;
|
|
55083
55694
|
};
|
|
55084
55695
|
|
|
55085
|
-
export { ActionBase, Backtest, Breakeven, Broker, BrokerBase, Cache, Constant, Dump, Exchange, ExecutionContextService, Heat, HighestProfit, Interval, Live, Log, Markdown, MarkdownFileBase, MarkdownFolderBase, MarkdownWriter, MaxDrawdown, Memory, MethodContextService, Notification, NotificationBacktest, NotificationLive, Partial, Performance, PersistBase, PersistBreakevenAdapter, PersistCandleAdapter, PersistIntervalAdapter, PersistLogAdapter, PersistMeasureAdapter, PersistMemoryAdapter, PersistNotificationAdapter, PersistPartialAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, PersistStorageAdapter, Position, PositionSize, Report, ReportBase, ReportWriter, Risk, Schedule, Storage, StorageBacktest, StorageLive, Strategy, Sync, Walker, addActionSchema, addExchangeSchema, addFrameSchema, addRiskSchema, addSizingSchema, addStrategySchema, addWalkerSchema, alignToInterval, checkCandles, commitActivateScheduled, commitAverageBuy, commitBreakeven, commitCancelScheduled, commitClosePending, commitPartialLoss, commitPartialLossCost, commitPartialProfit, commitPartialProfitCost, commitTrailingStop, commitTrailingStopCost, commitTrailingTake, commitTrailingTakeCost, dumpAgentAnswer, dumpError, dumpJson, dumpRecord, dumpTable, dumpText, emitters, formatPrice, formatQuantity, get, getActionSchema, getAggregatedTrades, getAveragePrice, getBacktestTimeframe, getBreakeven, getCandles, getColumns, getConfig, getContext, getDate, getDefaultColumns, getDefaultConfig, getEffectivePriceOpen, getExchangeSchema, getFrameSchema, getMode, getNextCandles, getOrderBook, getPendingSignal, getPositionCountdownMinutes, getPositionDrawdownMinutes, getPositionEffectivePrice, getPositionEntries, getPositionEntryOverlap, getPositionEstimateMinutes, getPositionHighestPnlCost, getPositionHighestPnlPercentage, getPositionHighestProfitBreakeven, getPositionHighestProfitMinutes, getPositionHighestProfitPrice, getPositionHighestProfitTimestamp, getPositionInvestedCost, getPositionInvestedCount, getPositionLevels, getPositionMaxDrawdownMinutes, getPositionMaxDrawdownPnlCost, getPositionMaxDrawdownPnlPercentage, getPositionMaxDrawdownPrice, getPositionMaxDrawdownTimestamp, getPositionPartialOverlap, getPositionPartials, getPositionPnlCost, getPositionPnlPercent, getRawCandles, getRiskSchema, getScheduledSignal, getSizingSchema, getStrategySchema, getSymbol, getTimestamp, getTotalClosed, getTotalCostClosed, getTotalPercentClosed, getWalkerSchema, hasNoPendingSignal, hasNoScheduledSignal, hasTradeContext, investedCostToPercent, backtest as lib, listExchangeSchema, listFrameSchema, listMemory, listRiskSchema, listSizingSchema, listStrategySchema, listWalkerSchema, listenActivePing, listenActivePingOnce, listenBacktestProgress, listenBreakevenAvailable, listenBreakevenAvailableOnce, listenDoneBacktest, listenDoneBacktestOnce, listenDoneLive, listenDoneLiveOnce, listenDoneWalker, listenDoneWalkerOnce, listenError, listenExit, listenHighestProfit, listenHighestProfitOnce, listenMaxDrawdown, listenMaxDrawdownOnce, listenPartialLossAvailable, listenPartialLossAvailableOnce, listenPartialProfitAvailable, listenPartialProfitAvailableOnce, listenPerformance, listenRisk, listenRiskOnce, listenSchedulePing, listenSchedulePingOnce, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalOnce, listenStrategyCommit, listenStrategyCommitOnce, listenSync, listenSyncOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, overrideActionSchema, overrideExchangeSchema, overrideFrameSchema, overrideRiskSchema, overrideSizingSchema, overrideStrategySchema, overrideWalkerSchema, parseArgs, percentDiff, percentToCloseCost, percentValue, readMemory, removeMemory, roundTicks, runInMockContext, searchMemory, set, setColumns, setConfig, setLogger, shutdown, slPercentShiftToPrice, slPriceToPercentShift, stopStrategy, toProfitLossDto, tpPercentShiftToPrice, tpPriceToPercentShift, validate, validateCommonSignal, validatePendingSignal, validateScheduledSignal, validateSignal, waitForCandle, warmCandles, writeMemory };
|
|
55696
|
+
export { ActionBase, Backtest, Breakeven, Broker, BrokerBase, Cache, Constant, Dump, Exchange, ExecutionContextService, Heat, HighestProfit, Interval, Live, Log, Markdown, MarkdownFileBase, MarkdownFolderBase, MarkdownWriter, MaxDrawdown, Memory, MethodContextService, Notification, NotificationBacktest, NotificationLive, Partial, Performance, PersistBase, PersistBreakevenAdapter, PersistCandleAdapter, PersistIntervalAdapter, PersistLogAdapter, PersistMeasureAdapter, PersistMemoryAdapter, PersistNotificationAdapter, PersistPartialAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, PersistStorageAdapter, Position, PositionSize, Report, ReportBase, ReportWriter, Risk, Schedule, Storage, StorageBacktest, StorageLive, Strategy, Sync, Walker, addActionSchema, addExchangeSchema, addFrameSchema, addRiskSchema, addSizingSchema, addStrategySchema, addWalkerSchema, alignToInterval, checkCandles, commitActivateScheduled, commitAverageBuy, commitBreakeven, commitCancelScheduled, commitClosePending, commitPartialLoss, commitPartialLossCost, commitPartialProfit, commitPartialProfitCost, commitTrailingStop, commitTrailingStopCost, commitTrailingTake, commitTrailingTakeCost, dumpAgentAnswer, dumpError, dumpJson, dumpRecord, dumpTable, dumpText, emitters, formatPrice, formatQuantity, get, getActionSchema, getAggregatedTrades, getAveragePrice, getBacktestTimeframe, getBreakeven, getCandles, getColumns, getConfig, getContext, getDate, getDefaultColumns, getDefaultConfig, getEffectivePriceOpen, getExchangeSchema, getFrameSchema, getMode, getNextCandles, getOrderBook, getPendingSignal, getPositionCountdownMinutes, getPositionDrawdownMinutes, getPositionEffectivePrice, getPositionEntries, getPositionEntryOverlap, getPositionEstimateMinutes, getPositionHighestMaxDrawdownPnlCost, getPositionHighestMaxDrawdownPnlPercentage, getPositionHighestPnlCost, getPositionHighestPnlPercentage, getPositionHighestProfitBreakeven, getPositionHighestProfitDistancePnlCost, getPositionHighestProfitDistancePnlPercentage, getPositionHighestProfitMinutes, getPositionHighestProfitPrice, getPositionHighestProfitTimestamp, getPositionInvestedCost, getPositionInvestedCount, getPositionLevels, getPositionMaxDrawdownMinutes, getPositionMaxDrawdownPnlCost, getPositionMaxDrawdownPnlPercentage, getPositionMaxDrawdownPrice, getPositionMaxDrawdownTimestamp, getPositionPartialOverlap, getPositionPartials, getPositionPnlCost, getPositionPnlPercent, getRawCandles, getRiskSchema, getScheduledSignal, getSizingSchema, getStrategySchema, getSymbol, getTimestamp, getTotalClosed, getTotalCostClosed, getTotalPercentClosed, getWalkerSchema, hasNoPendingSignal, hasNoScheduledSignal, hasTradeContext, investedCostToPercent, backtest as lib, listExchangeSchema, listFrameSchema, listMemory, listRiskSchema, listSizingSchema, listStrategySchema, listWalkerSchema, listenActivePing, listenActivePingOnce, listenBacktestProgress, listenBreakevenAvailable, listenBreakevenAvailableOnce, listenDoneBacktest, listenDoneBacktestOnce, listenDoneLive, listenDoneLiveOnce, listenDoneWalker, listenDoneWalkerOnce, listenError, listenExit, listenHighestProfit, listenHighestProfitOnce, listenMaxDrawdown, listenMaxDrawdownOnce, listenPartialLossAvailable, listenPartialLossAvailableOnce, listenPartialProfitAvailable, listenPartialProfitAvailableOnce, listenPerformance, listenRisk, listenRiskOnce, listenSchedulePing, listenSchedulePingOnce, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalOnce, listenStrategyCommit, listenStrategyCommitOnce, listenSync, listenSyncOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, overrideActionSchema, overrideExchangeSchema, overrideFrameSchema, overrideRiskSchema, overrideSizingSchema, overrideStrategySchema, overrideWalkerSchema, parseArgs, percentDiff, percentToCloseCost, percentValue, readMemory, removeMemory, roundTicks, runInMockContext, searchMemory, set, setColumns, setConfig, setLogger, shutdown, slPercentShiftToPrice, slPriceToPercentShift, stopStrategy, toProfitLossDto, tpPercentShiftToPrice, tpPriceToPercentShift, validate, validateCommonSignal, validatePendingSignal, validateScheduledSignal, validateSignal, waitForCandle, warmCandles, writeMemory };
|