package com.quantai.trader.domain; import com.quantai.trader.enums.PositionSide; import com.quantai.trader.enums.TraderActionType; import org.springframework.stereotype.Component; import java.math.BigDecimal; import java.util.Map; @Component public class TraderActionFactory { public TraderAction create(TraderPositionManagerDecision pmDecision, TraderRiskDecision riskDecision, String symbol) { TraderActionType finalAction = riskDecision.finalAction(); PositionSide side = sideFor(finalAction, pmDecision.side()); return new TraderAction( "action_" + pmDecision.cycleId(), pmDecision.runId(), pmDecision.cycleId(), pmDecision.modelOutputId(), pmDecision.pmDecisionId(), riskDecision.riskDecisionId(), finalAction, symbol, side, finalAction.increasesExposure() ? pmDecision.pricePlanId() : null, finalAction.increasesExposure() ? pmDecision.pricePlanConfigHash() : null, ratioFor(finalAction, pmDecision), null, pmDecision.stopPrice(), pmDecision.targetPrice(), finalAction.reducesExposure(), "idem_" + pmDecision.runId() + "_" + pmDecision.cycleId() + "_" + finalAction, riskDecision.allowAction() ? pmDecision.reason() : riskDecision.blocker(), Map.of("riskAllowed", riskDecision.allowAction())); } private BigDecimal ratioFor(TraderActionType action, TraderPositionManagerDecision pmDecision) { return switch (action) { case OPEN_LONG, OPEN_SHORT -> pmDecision.targetPositionRatio(); case ADD_LONG, ADD_SHORT -> pmDecision.addRatio(); case REDUCE_LONG, REDUCE_SHORT -> pmDecision.reduceRatio(); case WAIT, HOLD, CLOSE_LONG, CLOSE_SHORT, MOVE_STOP, CANCEL -> null; }; } private PositionSide sideFor(TraderActionType action, PositionSide pmSide) { return switch (action) { case OPEN_LONG, ADD_LONG, REDUCE_LONG, CLOSE_LONG -> PositionSide.LONG; case OPEN_SHORT, ADD_SHORT, REDUCE_SHORT, CLOSE_SHORT -> PositionSide.SHORT; case WAIT, CANCEL -> PositionSide.NONE; case HOLD, MOVE_STOP -> pmSide; }; } }