| | |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xcong.excoin.modules.station.dao.StrategyEventLogDao; |
| | | import com.xcong.excoin.modules.station.dao.StrategyStatusDao; |
| | |
| | | persistConfig(apiKeyMd5, params); |
| | | // 2. 发送 MQ 命令,通知 JAR(需手动点击「启动」才生效) |
| | | cmdProducer.sendCommand(apiKeyMd5, "UPDATE_CONFIG", JSON.toJSONString(params)); |
| | | } |
| | | |
| | | // ==================== 手动控制指令 ==================== |
| | | |
| | | @Override |
| | | public void cancelLongTpSl(String apiKeyMd5) { |
| | | cmdProducer.sendCommand(apiKeyMd5, "CANCEL_LONG_TP_SL"); |
| | | } |
| | | |
| | | @Override |
| | | public void cancelShortTpSl(String apiKeyMd5) { |
| | | cmdProducer.sendCommand(apiKeyMd5, "CANCEL_SHORT_TP_SL"); |
| | | } |
| | | |
| | | @Override |
| | | public void rebuildLongTpSl(String apiKeyMd5) { |
| | | cmdProducer.sendCommand(apiKeyMd5, "REBUILD_LONG_TP_SL"); |
| | | } |
| | | |
| | | @Override |
| | | public void rebuildShortTpSl(String apiKeyMd5) { |
| | | cmdProducer.sendCommand(apiKeyMd5, "REBUILD_SHORT_TP_SL"); |
| | | } |
| | | |
| | | @Override |
| | | public void closeLong(String apiKeyMd5) { |
| | | cmdProducer.sendCommand(apiKeyMd5, "CLOSE_LONG"); |
| | | } |
| | | |
| | | @Override |
| | | public void closeShort(String apiKeyMd5) { |
| | | cmdProducer.sendCommand(apiKeyMd5, "CLOSE_SHORT"); |
| | | } |
| | | |
| | | // ==================== 别名 ==================== |
| | | |
| | | @Override |
| | | public void saveAlias(String apiKeyMd5, String alias) { |
| | | String cleaned = alias == null ? "" : alias.trim(); |
| | | String value = cleaned.isEmpty() ? null : cleaned; |
| | | |
| | | StrategyStatus existing = strategyStatusDao.selectByApiKeyMd5(apiKeyMd5); |
| | | if (existing != null) { |
| | | // 用 UpdateWrapper 显式 set,支持把别名更新为 null(清除) |
| | | LambdaUpdateWrapper<StrategyStatus> wrapper = new LambdaUpdateWrapper<>(); |
| | | wrapper.eq(StrategyStatus::getApiKeyMd5, apiKeyMd5) |
| | | .set(StrategyStatus::getAliasName, value); |
| | | strategyStatusDao.update(null, wrapper); |
| | | } else if (value != null) { |
| | | // 实例尚无状态记录(未启动过),仅创建一条只含别名的记录 |
| | | StrategyStatus status = new StrategyStatus(); |
| | | status.setApiKeyMd5(apiKeyMd5); |
| | | status.setAliasName(value); |
| | | status.setCreateTime(new Date()); |
| | | strategyStatusDao.insert(status); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public String getAlias(String apiKeyMd5) { |
| | | StrategyStatus status = strategyStatusDao.selectByApiKeyMd5(apiKeyMd5); |
| | | return status == null ? null : status.getAliasName(); |
| | | } |
| | | |
| | | // ==================== 事件落库 ==================== |
| | |
| | | if (params.containsKey("addPositionQuantity")) status.setAddPositionQuantity(intVal(params.get("addPositionQuantity"))); |
| | | if (params.containsKey("maxPositionPerSide")) status.setMaxPositionPerSide(intVal(params.get("maxPositionPerSide"))); |
| | | if (params.containsKey("addPositionStartThreshold")) status.setAddPositionStartThreshold(intVal(params.get("addPositionStartThreshold"))); |
| | | if (params.containsKey("placeExcessTakeProfit")) status.setPlaceExcessTakeProfit(boolVal(params.get("placeExcessTakeProfit"))); |
| | | if (params.containsKey("placeExcessTakeProfit")) status.setPlaceExcessTakeProfit(str(params.get("placeExcessTakeProfit"))); |
| | | if (params.containsKey("priceDriveEnabled")) status.setPriceDriveEnabled(boolVal(params.get("priceDriveEnabled"))); |
| | | if (params.containsKey("dualStopLossEnabled")) status.setDualStopLossEnabled(boolVal(params.get("dualStopLossEnabled"))); |
| | | if (params.containsKey("longStopLossPrice")) status.setLongStopLossPrice(str(params.get("longStopLossPrice"))); |
| | | if (params.containsKey("shortStopLossPrice")) status.setShortStopLossPrice(str(params.get("shortStopLossPrice"))); |
| | | if (params.containsKey("tpTriggerOppositeAddEnabled")) status.setTpTriggerOppositeAddEnabled(boolVal(params.get("tpTriggerOppositeAddEnabled"))); |
| | | if (params.containsKey("tpTriggerOppositeAddQuantity")) status.setTpTriggerOppositeAddQuantity(intVal(params.get("tpTriggerOppositeAddQuantity"))); |
| | | if (params.containsKey("baseTakeProfitPerGrid")) status.setBaseTakeProfitPerGrid(str(params.get("baseTakeProfitPerGrid"))); |
| | | if (params.containsKey("baseTakeProfitGridCount")) status.setBaseTakeProfitGridCount(intVal(params.get("baseTakeProfitGridCount"))); |
| | | if (params.containsKey("rounds")) status.setTotalRounds(intVal(params.get("rounds"))); |
| | | if (params.containsKey("principal")) status.setPrincipal(str(params.get("principal"))); |
| | | } |