Rewrite trader service for V4 P0
This commit is contained in:
@@ -1,299 +1,92 @@
|
||||
package com.quantai.trader.config;
|
||||
|
||||
import com.quantai.trader.enums.TraderExecutionMode;
|
||||
import com.quantai.trader.enums.TraderRunMode;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import static com.quantai.trader.util.TraderNumbers.requiredText;
|
||||
|
||||
@ConfigurationProperties(prefix = "trader")
|
||||
public class TraderProperties {
|
||||
|
||||
private String serviceName = "quant-trader-service";
|
||||
private TraderRunMode runMode = TraderRunMode.REPLAY;
|
||||
private String symbol = "BTCUSDT";
|
||||
private String featureVersion = "trader_feature_v0";
|
||||
private String labelVersion = "trader_label_v0";
|
||||
private Playbook playbook = new Playbook();
|
||||
private Replay replay = new Replay();
|
||||
private Integration integration = new Integration();
|
||||
private Risk risk = new Risk();
|
||||
private Sizing sizing = new Sizing();
|
||||
private DataSource dataSource = new DataSource();
|
||||
|
||||
public String getServiceName() {
|
||||
return serviceName;
|
||||
public record TraderProperties(
|
||||
String serviceName,
|
||||
TraderRunMode runMode,
|
||||
String symbol,
|
||||
Artifact artifact,
|
||||
Feedback feedback,
|
||||
Execution execution,
|
||||
Runtime runtime,
|
||||
Outbox outbox,
|
||||
Release release,
|
||||
Risk risk,
|
||||
PositionManager positionManager
|
||||
) {
|
||||
public TraderProperties {
|
||||
serviceName = defaultText(serviceName, "quant-trader-service");
|
||||
runMode = runMode == null ? TraderRunMode.SHADOW : runMode;
|
||||
symbol = defaultText(symbol, "BTC-USDT-PERP");
|
||||
artifact = artifact == null ? new Artifact("trader-v4-btc-p0", "cal-v4-btc-p0", "pm-v4-btc-p0", ".") : artifact;
|
||||
feedback = feedback == null ? new Feedback(false) : feedback;
|
||||
execution = execution == null ? new Execution(TraderExecutionMode.SHADOW, 3, 1500) : execution;
|
||||
runtime = runtime == null ? new Runtime("trader:v4", true, false) : runtime;
|
||||
outbox = outbox == null ? new Outbox(true, 5) : outbox;
|
||||
release = release == null ? new Release(true, true, true) : release;
|
||||
risk = risk == null ? new Risk(new BigDecimal("200"), BigDecimal.ONE, new BigDecimal("500")) : risk;
|
||||
positionManager = positionManager == null ? new PositionManager(BigDecimal.ONE, BigDecimal.ONE) : positionManager;
|
||||
}
|
||||
|
||||
public void setServiceName(String serviceName) {
|
||||
this.serviceName = serviceName;
|
||||
private static String defaultText(String value, String defaultValue) {
|
||||
return value == null || value.isBlank() ? defaultValue : value;
|
||||
}
|
||||
|
||||
public TraderRunMode getRunMode() {
|
||||
return runMode;
|
||||
}
|
||||
|
||||
public void setRunMode(TraderRunMode runMode) {
|
||||
this.runMode = runMode;
|
||||
}
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public String getFeatureVersion() {
|
||||
return featureVersion;
|
||||
}
|
||||
|
||||
public void setFeatureVersion(String featureVersion) {
|
||||
this.featureVersion = featureVersion;
|
||||
}
|
||||
|
||||
public String getLabelVersion() {
|
||||
return labelVersion;
|
||||
}
|
||||
|
||||
public void setLabelVersion(String labelVersion) {
|
||||
this.labelVersion = labelVersion;
|
||||
}
|
||||
|
||||
public Playbook getPlaybook() {
|
||||
return playbook;
|
||||
}
|
||||
|
||||
public void setPlaybook(Playbook playbook) {
|
||||
this.playbook = playbook;
|
||||
}
|
||||
|
||||
public Replay getReplay() {
|
||||
return replay;
|
||||
}
|
||||
|
||||
public void setReplay(Replay replay) {
|
||||
this.replay = replay;
|
||||
}
|
||||
|
||||
public Integration getIntegration() {
|
||||
return integration;
|
||||
}
|
||||
|
||||
public void setIntegration(Integration integration) {
|
||||
this.integration = integration;
|
||||
}
|
||||
|
||||
public Risk getRisk() {
|
||||
return risk;
|
||||
}
|
||||
|
||||
public void setRisk(Risk risk) {
|
||||
this.risk = risk;
|
||||
}
|
||||
|
||||
public Sizing getSizing() {
|
||||
return sizing;
|
||||
}
|
||||
|
||||
public void setSizing(Sizing sizing) {
|
||||
this.sizing = sizing;
|
||||
}
|
||||
|
||||
public DataSource getDataSource() {
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
public static class Playbook {
|
||||
private String locationPattern = "classpath:/playbooks/*.yml";
|
||||
|
||||
public String getLocationPattern() {
|
||||
return locationPattern;
|
||||
}
|
||||
|
||||
public void setLocationPattern(String locationPattern) {
|
||||
this.locationPattern = locationPattern;
|
||||
public record Artifact(
|
||||
String modelBundleVersion,
|
||||
String calibrationBundleVersion,
|
||||
String pmConfigVersion,
|
||||
String artifactRoot
|
||||
) {
|
||||
public Artifact {
|
||||
modelBundleVersion = requiredText(modelBundleVersion, "artifact.modelBundleVersion");
|
||||
calibrationBundleVersion = requiredText(calibrationBundleVersion, "artifact.calibrationBundleVersion");
|
||||
pmConfigVersion = requiredText(pmConfigVersion, "artifact.pmConfigVersion");
|
||||
artifactRoot = requiredText(artifactRoot, "artifact.artifactRoot");
|
||||
}
|
||||
}
|
||||
|
||||
public static class Replay {
|
||||
private String outputDir = "/Users/zach/Desktop/app/trader/replay-output";
|
||||
private boolean failOnDataMissing = true;
|
||||
public record Feedback(boolean httpEnabled) {
|
||||
}
|
||||
|
||||
public String getOutputDir() {
|
||||
return outputDir;
|
||||
}
|
||||
|
||||
public void setOutputDir(String outputDir) {
|
||||
this.outputDir = outputDir;
|
||||
}
|
||||
|
||||
public boolean isFailOnDataMissing() {
|
||||
return failOnDataMissing;
|
||||
}
|
||||
|
||||
public void setFailOnDataMissing(boolean failOnDataMissing) {
|
||||
this.failOnDataMissing = failOnDataMissing;
|
||||
public record Execution(TraderExecutionMode mode, int maxApiErrorCount, long maxExchangeLatencyMs) {
|
||||
public Execution {
|
||||
mode = mode == null ? TraderExecutionMode.SHADOW : mode;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Integration {
|
||||
private String appActionChannel = "JAR_FUTURE";
|
||||
private boolean httpFeedbackEnabled = false;
|
||||
|
||||
public String getAppActionChannel() {
|
||||
return appActionChannel;
|
||||
}
|
||||
|
||||
public void setAppActionChannel(String appActionChannel) {
|
||||
this.appActionChannel = appActionChannel;
|
||||
}
|
||||
|
||||
public boolean isHttpFeedbackEnabled() {
|
||||
return httpFeedbackEnabled;
|
||||
}
|
||||
|
||||
public void setHttpFeedbackEnabled(boolean httpFeedbackEnabled) {
|
||||
this.httpFeedbackEnabled = httpFeedbackEnabled;
|
||||
public record Runtime(String redisKeyPrefix, boolean requireRedisForOpenAdd, boolean tradingEnabled) {
|
||||
public Runtime {
|
||||
redisKeyPrefix = defaultText(redisKeyPrefix, "trader:v4");
|
||||
}
|
||||
}
|
||||
|
||||
public static class Risk {
|
||||
private BigDecimal leverageScreen = BigDecimal.TEN;
|
||||
private boolean requireOneXNotNegative = true;
|
||||
private int maxPlannedEntryLegs = 3;
|
||||
private boolean allowFreeScaleIn = false;
|
||||
private boolean allowReduceThenAdd = false;
|
||||
private boolean requireStop = true;
|
||||
private boolean requireTarget = true;
|
||||
private boolean requireInvalid = true;
|
||||
public record Outbox(boolean enabled, int maxRetryCount) {
|
||||
}
|
||||
|
||||
public BigDecimal getLeverageScreen() {
|
||||
return leverageScreen;
|
||||
}
|
||||
public record Release(boolean requireReviewForPaper, boolean requireReviewForLiveProbe, boolean activePointerCheckEnabled) {
|
||||
}
|
||||
|
||||
public void setLeverageScreen(BigDecimal leverageScreen) {
|
||||
this.leverageScreen = leverageScreen;
|
||||
}
|
||||
|
||||
public boolean isRequireOneXNotNegative() {
|
||||
return requireOneXNotNegative;
|
||||
}
|
||||
|
||||
public void setRequireOneXNotNegative(boolean requireOneXNotNegative) {
|
||||
this.requireOneXNotNegative = requireOneXNotNegative;
|
||||
}
|
||||
|
||||
public int getMaxPlannedEntryLegs() {
|
||||
return maxPlannedEntryLegs;
|
||||
}
|
||||
|
||||
public void setMaxPlannedEntryLegs(int maxPlannedEntryLegs) {
|
||||
this.maxPlannedEntryLegs = maxPlannedEntryLegs;
|
||||
}
|
||||
|
||||
public boolean isAllowFreeScaleIn() {
|
||||
return allowFreeScaleIn;
|
||||
}
|
||||
|
||||
public void setAllowFreeScaleIn(boolean allowFreeScaleIn) {
|
||||
this.allowFreeScaleIn = allowFreeScaleIn;
|
||||
}
|
||||
|
||||
public boolean isAllowReduceThenAdd() {
|
||||
return allowReduceThenAdd;
|
||||
}
|
||||
|
||||
public void setAllowReduceThenAdd(boolean allowReduceThenAdd) {
|
||||
this.allowReduceThenAdd = allowReduceThenAdd;
|
||||
}
|
||||
|
||||
public boolean isRequireStop() {
|
||||
return requireStop;
|
||||
}
|
||||
|
||||
public void setRequireStop(boolean requireStop) {
|
||||
this.requireStop = requireStop;
|
||||
}
|
||||
|
||||
public boolean isRequireTarget() {
|
||||
return requireTarget;
|
||||
}
|
||||
|
||||
public void setRequireTarget(boolean requireTarget) {
|
||||
this.requireTarget = requireTarget;
|
||||
}
|
||||
|
||||
public boolean isRequireInvalid() {
|
||||
return requireInvalid;
|
||||
}
|
||||
|
||||
public void setRequireInvalid(boolean requireInvalid) {
|
||||
this.requireInvalid = requireInvalid;
|
||||
public record Risk(BigDecimal maxDailyLossBps, BigDecimal maxTotalExposureRatio, BigDecimal minLiquidationBufferBps) {
|
||||
public Risk {
|
||||
maxDailyLossBps = maxDailyLossBps == null ? new BigDecimal("200") : maxDailyLossBps;
|
||||
maxTotalExposureRatio = maxTotalExposureRatio == null ? BigDecimal.ONE : maxTotalExposureRatio;
|
||||
minLiquidationBufferBps = minLiquidationBufferBps == null ? new BigDecimal("500") : minLiquidationBufferBps;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Sizing {
|
||||
private String method = "SIGNAL_EXECUTION_RISK_DYNAMIC";
|
||||
private boolean allowFullInitialEntry = true;
|
||||
private int maxPlannedEntryLegs = 3;
|
||||
private BigDecimal maxTotalPositionRatio = BigDecimal.ONE;
|
||||
private BigDecimal maxSingleLegRatio = BigDecimal.ONE;
|
||||
|
||||
public String getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public void setMethod(String method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
public boolean isAllowFullInitialEntry() {
|
||||
return allowFullInitialEntry;
|
||||
}
|
||||
|
||||
public void setAllowFullInitialEntry(boolean allowFullInitialEntry) {
|
||||
this.allowFullInitialEntry = allowFullInitialEntry;
|
||||
}
|
||||
|
||||
public int getMaxPlannedEntryLegs() {
|
||||
return maxPlannedEntryLegs;
|
||||
}
|
||||
|
||||
public void setMaxPlannedEntryLegs(int maxPlannedEntryLegs) {
|
||||
this.maxPlannedEntryLegs = maxPlannedEntryLegs;
|
||||
}
|
||||
|
||||
public BigDecimal getMaxTotalPositionRatio() {
|
||||
return maxTotalPositionRatio;
|
||||
}
|
||||
|
||||
public void setMaxTotalPositionRatio(BigDecimal maxTotalPositionRatio) {
|
||||
this.maxTotalPositionRatio = maxTotalPositionRatio;
|
||||
}
|
||||
|
||||
public BigDecimal getMaxSingleLegRatio() {
|
||||
return maxSingleLegRatio;
|
||||
}
|
||||
|
||||
public void setMaxSingleLegRatio(BigDecimal maxSingleLegRatio) {
|
||||
this.maxSingleLegRatio = maxSingleLegRatio;
|
||||
}
|
||||
}
|
||||
|
||||
public static class DataSource {
|
||||
private String hashMode = "FULL_HASH_OR_SCHEMA_ROW_TIME_MISSING_SUMMARY";
|
||||
|
||||
public String getHashMode() {
|
||||
return hashMode;
|
||||
}
|
||||
|
||||
public void setHashMode(String hashMode) {
|
||||
this.hashMode = hashMode;
|
||||
public record PositionManager(BigDecimal maxSingleLegRatio, BigDecimal maxTotalPositionRatio) {
|
||||
public PositionManager {
|
||||
maxSingleLegRatio = maxSingleLegRatio == null ? BigDecimal.ONE : maxSingleLegRatio;
|
||||
maxTotalPositionRatio = maxTotalPositionRatio == null ? BigDecimal.ONE : maxTotalPositionRatio;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user