131 lines
6.5 KiB
Java
131 lines
6.5 KiB
Java
package com.quantai.trader.domain;
|
|
|
|
import static com.quantai.trader.util.TraderNumbers.*;
|
|
|
|
import java.math.BigDecimal;
|
|
|
|
public record TraderPmConfig(
|
|
String pmConfigVersion,
|
|
OpenRuleConfig open,
|
|
AddRuleConfig add,
|
|
ExitRuleConfig exit,
|
|
SizingConfig sizing
|
|
) {
|
|
public TraderPmConfig {
|
|
pmConfigVersion = requiredText(pmConfigVersion, "pmConfigVersion");
|
|
open = java.util.Objects.requireNonNull(open, "open config is required");
|
|
add = java.util.Objects.requireNonNull(add, "add config is required");
|
|
exit = java.util.Objects.requireNonNull(exit, "exit config is required");
|
|
sizing = java.util.Objects.requireNonNull(sizing, "sizing config is required");
|
|
}
|
|
|
|
public record OpenRuleConfig(
|
|
BigDecimal longOpenProb,
|
|
BigDecimal shortOpenProb,
|
|
BigDecimal minLongEntryProb,
|
|
BigDecimal minShortEntryProb,
|
|
BigDecimal maxMarketRiskProb,
|
|
BigDecimal minExpectedEdgeBps,
|
|
BigDecimal minDirectionMargin,
|
|
BigDecimal minLiquidityCapacityRatio,
|
|
BigDecimal maxOodScore
|
|
) {
|
|
public OpenRuleConfig {
|
|
longOpenProb = probability(longOpenProb, "open.longOpenProb");
|
|
shortOpenProb = probability(shortOpenProb, "open.shortOpenProb");
|
|
minLongEntryProb = probability(minLongEntryProb, "open.minLongEntryProb");
|
|
minShortEntryProb = probability(minShortEntryProb, "open.minShortEntryProb");
|
|
maxMarketRiskProb = probability(maxMarketRiskProb, "open.maxMarketRiskProb");
|
|
minExpectedEdgeBps = required(minExpectedEdgeBps, "open.minExpectedEdgeBps");
|
|
minDirectionMargin = nonNegative(minDirectionMargin, "open.minDirectionMargin");
|
|
minLiquidityCapacityRatio = nonNegative(minLiquidityCapacityRatio, "open.minLiquidityCapacityRatio");
|
|
maxOodScore = probability(maxOodScore, "open.maxOodScore");
|
|
}
|
|
}
|
|
|
|
public record AddRuleConfig(
|
|
BigDecimal minLongProb,
|
|
BigDecimal minShortProb,
|
|
BigDecimal minContinueProb,
|
|
BigDecimal minEntryProb,
|
|
BigDecimal maxExitProb,
|
|
BigDecimal maxMarketRiskProb,
|
|
BigDecimal maxPositionRiskProb,
|
|
BigDecimal minExpectedEdgeBps,
|
|
BigDecimal minContinueVsExitEdgeBps,
|
|
BigDecimal minLiquidityCapacityRatio,
|
|
BigDecimal minPostTradeLiquidationBufferBps,
|
|
int maxAddCount,
|
|
long cooldownMinutes
|
|
) {
|
|
public AddRuleConfig {
|
|
minLongProb = probability(minLongProb, "add.minLongProb");
|
|
minShortProb = probability(minShortProb, "add.minShortProb");
|
|
minContinueProb = probability(minContinueProb, "add.minContinueProb");
|
|
minEntryProb = probability(minEntryProb, "add.minEntryProb");
|
|
maxExitProb = probability(maxExitProb, "add.maxExitProb");
|
|
maxMarketRiskProb = probability(maxMarketRiskProb, "add.maxMarketRiskProb");
|
|
maxPositionRiskProb = probability(maxPositionRiskProb, "add.maxPositionRiskProb");
|
|
minExpectedEdgeBps = required(minExpectedEdgeBps, "add.minExpectedEdgeBps");
|
|
minContinueVsExitEdgeBps = required(minContinueVsExitEdgeBps, "add.minContinueVsExitEdgeBps");
|
|
minLiquidityCapacityRatio = nonNegative(minLiquidityCapacityRatio, "add.minLiquidityCapacityRatio");
|
|
minPostTradeLiquidationBufferBps = nonNegative(minPostTradeLiquidationBufferBps, "add.minPostTradeLiquidationBufferBps");
|
|
if (maxAddCount < 0 || cooldownMinutes < 0) {
|
|
throw new IllegalArgumentException("add count and cooldown must be >= 0");
|
|
}
|
|
}
|
|
}
|
|
|
|
public record ExitRuleConfig(
|
|
BigDecimal closeExitProb,
|
|
BigDecimal closePositionRiskProb,
|
|
BigDecimal closeMarketRiskProb,
|
|
BigDecimal closeContinueMax,
|
|
BigDecimal reduceAdverseMoveProb,
|
|
BigDecimal reduceContinueMin,
|
|
BigDecimal reduceContinueMax,
|
|
BigDecimal minProfitForReduceBps,
|
|
BigDecimal maxPositionPathRiskBps
|
|
) {
|
|
public ExitRuleConfig {
|
|
closeExitProb = probability(closeExitProb, "exit.closeExitProb");
|
|
closePositionRiskProb = probability(closePositionRiskProb, "exit.closePositionRiskProb");
|
|
closeMarketRiskProb = probability(closeMarketRiskProb, "exit.closeMarketRiskProb");
|
|
closeContinueMax = probability(closeContinueMax, "exit.closeContinueMax");
|
|
reduceAdverseMoveProb = probability(reduceAdverseMoveProb, "exit.reduceAdverseMoveProb");
|
|
reduceContinueMin = probability(reduceContinueMin, "exit.reduceContinueMin");
|
|
reduceContinueMax = probability(reduceContinueMax, "exit.reduceContinueMax");
|
|
minProfitForReduceBps = nonNegative(minProfitForReduceBps, "exit.minProfitForReduceBps");
|
|
maxPositionPathRiskBps = nonNegative(maxPositionPathRiskBps, "exit.maxPositionPathRiskBps");
|
|
}
|
|
}
|
|
|
|
public record SizingConfig(
|
|
BigDecimal baseRatio,
|
|
BigDecimal minInitialRatio,
|
|
BigDecimal maxSingleLegRatio,
|
|
BigDecimal minAddRatio,
|
|
BigDecimal maxAddRatio,
|
|
BigDecimal maxTotalPositionRatio,
|
|
BigDecimal minEdgeBps,
|
|
BigDecimal maxLossPerTradeBps,
|
|
BigDecimal maxLiquidityUsageRatio,
|
|
BigDecimal uncertaintyPenaltyMultiplier,
|
|
BigDecimal minPostTradeLiquidationBufferBps
|
|
) {
|
|
public SizingConfig {
|
|
baseRatio = positive(baseRatio, "sizing.baseRatio");
|
|
minInitialRatio = nonNegative(minInitialRatio, "sizing.minInitialRatio");
|
|
maxSingleLegRatio = positive(maxSingleLegRatio, "sizing.maxSingleLegRatio");
|
|
minAddRatio = nonNegative(minAddRatio, "sizing.minAddRatio");
|
|
maxAddRatio = nonNegative(maxAddRatio, "sizing.maxAddRatio");
|
|
maxTotalPositionRatio = positive(maxTotalPositionRatio, "sizing.maxTotalPositionRatio");
|
|
minEdgeBps = required(minEdgeBps, "sizing.minEdgeBps");
|
|
maxLossPerTradeBps = positive(maxLossPerTradeBps, "sizing.maxLossPerTradeBps");
|
|
maxLiquidityUsageRatio = positive(maxLiquidityUsageRatio, "sizing.maxLiquidityUsageRatio");
|
|
uncertaintyPenaltyMultiplier = nonNegative(uncertaintyPenaltyMultiplier, "sizing.uncertaintyPenaltyMultiplier");
|
|
minPostTradeLiquidationBufferBps = nonNegative(minPostTradeLiquidationBufferBps, "sizing.minPostTradeLiquidationBufferBps");
|
|
}
|
|
}
|
|
}
|