feat(stations): 添加止盈触发对向加仓功能
- 在策略状态实体中新增止盈触发对向加仓相关字段
- 在数据库表结构中添加对应的开关和数量列
- 在前端配置界面中增加止盈触发对向加仓设置选项
- 在服务实现中添加参数处理和数据持久化逻辑
- 添加数据库升级脚本支持字段迁移和初始化
| | |
| | | /** 空头止损触发价 */ |
| | | private String shortStopLossPrice; |
| | | |
| | | /** 止盈成交触发对向加仓开关 */ |
| | | private Boolean tpTriggerOppositeAddEnabled; |
| | | |
| | | /** 对向加仓挂单数量 */ |
| | | private Integer tpTriggerOppositeAddQuantity; |
| | | |
| | | /** 当前轮次 */ |
| | | private Integer currentRound; |
| | | |
| | |
| | | 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("rounds")) status.setTotalRounds(intVal(params.get("rounds"))); |
| | | if (params.containsKey("principal")) status.setPrincipal(str(params.get("principal"))); |
| | | } |
| | |
| | | `dual_stop_loss_enabled` TINYINT(1) DEFAULT 0 COMMENT '双开止损触发开关', |
| | | `long_stop_loss_price` VARCHAR(32) DEFAULT NULL COMMENT '多头止损触发价', |
| | | `short_stop_loss_price` VARCHAR(32) DEFAULT NULL COMMENT '空头止损触发价', |
| | | `tp_trigger_opposite_add_enabled` TINYINT(1) DEFAULT 0 COMMENT '止盈成交触发对向加仓开关', |
| | | `tp_trigger_opposite_add_quantity` INT(11) DEFAULT 0 COMMENT '对向加仓挂单数量', |
| | | `current_round` INT(11) DEFAULT 0 COMMENT '当前轮次', |
| | | `total_rounds` INT(11) DEFAULT 0 COMMENT '总轮数上限', |
| | | `accumulated_long_loss` INT(11) DEFAULT 0 COMMENT '多头累计止损次数', |
| | |
| | | -- 旧数据迁移:1(开启)→concentrated,0(关闭)→off |
| | | UPDATE `strategy_status` SET `place_excess_take_profit` = 'concentrated' WHERE `place_excess_take_profit` = '1'; |
| | | UPDATE `strategy_status` SET `place_excess_take_profit` = 'off' WHERE `place_excess_take_profit` = '0'; |
| | | |
| | | -- ============================================================ |
| | | -- 升级脚本:止盈成交触发对向加仓(2026-09 新增) |
| | | -- ============================================================ |
| | | ALTER TABLE `strategy_status` |
| | | ADD COLUMN `tp_trigger_opposite_add_enabled` TINYINT(1) DEFAULT 0 COMMENT '止盈成交触发对向加仓开关' AFTER `short_stop_loss_price`, |
| | | ADD COLUMN `tp_trigger_opposite_add_quantity` INT(11) DEFAULT 0 COMMENT '对向加仓挂单数量' AFTER `tp_trigger_opposite_add_enabled`; |
| | |
| | | dualStopLossEnabled: false, |
| | | longStopLossPrice: '', |
| | | shortStopLossPrice: '', |
| | | tpTriggerOppositeAddEnabled: false, |
| | | tpTriggerOppositeAddQuantity: 0, |
| | | }; |
| | | |
| | | async function loadConfig(md5) { |
| | |
| | | { key: 'addPositionQuantity', label: '加仓数量 (张)', type: 'number', placeholder: '1', jtype: 'int', group: 'addon' }, |
| | | { key: 'maxPositionPerSide', label: '单边最大仓位 (0=不限)', type: 'number', placeholder: '0', jtype: 'int', group: 'addon' }, |
| | | { key: 'addPositionStartThreshold', label: '加仓启动阈值 (次)', type: 'number', placeholder: '1', jtype: 'int', group: 'addon', tip: '前 N 次止损不触发加仓' }, |
| | | { key: 'tpTriggerOppositeAddEnabled', label: '止盈触发对向加仓', type: 'select', options: [{ v: 'false', l: '关闭' }, { v: 'true', l: '开启' }], group: 'addon', tip: '止盈单成交后触发对向加仓' }, |
| | | { key: 'tpTriggerOppositeAddQuantity', label: '对向加仓挂单数量 (张)', type: 'number', placeholder: '0', jtype: 'int', group: 'addon', tip: '止盈成交后在对向挂出的加仓张数' }, |
| | | |
| | | { key: 'rounds', label: '运行轮数 (0=不限)', type: 'number', placeholder: '0', jtype: 'int', group: 'run', tip: '盈利重启达此轮数后停止' }, |
| | | { key: 'placeExcessTakeProfit', label: '止盈模式', type: 'select', options: [{ v: 'off', l: '关闭' }, { v: 'concentrated', l: '集中止盈' }, { v: 'dispersed', l: '分散止盈' }], group: 'run', tip: '超出基础仓位的加仓部分如何挂止盈' }, |