From ec41783155f32f47f0854777e9d753b5a045fe1d Mon Sep 17 00:00:00 2001 From: liaozhaorun <1300336796@qq.com> Date: Tue, 27 Jan 2026 01:06:34 +0800 Subject: [PATCH] =?UTF-8?q?feat(qmt):=20=E6=B7=BB=E5=8A=A0=E7=AD=96?= =?UTF-8?q?=E7=95=A5=E6=9D=83=E9=87=8D=E9=85=8D=E7=BD=AE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 qmt_engine.py 中增加权重计算逻辑 - 下单金额公式改为: target_amt = total_equity * weight / total_weighted_slots - 更新 qmt_config.md 添加 weight 字段配置说明 - 保持向后兼容,不配置 weight 时默认为 1 --- qmt_config.md => qmt/qmt_config.md | 105 ++++++++++++++++++++++++++++- qmt/qmt_engine.py | 20 ++++-- 2 files changed, 119 insertions(+), 6 deletions(-) rename qmt_config.md => qmt/qmt_config.md (77%) diff --git a/qmt_config.md b/qmt/qmt_config.md similarity index 77% rename from qmt_config.md rename to qmt/qmt_config.md index 0121754..194e490 100644 --- a/qmt_config.md +++ b/qmt/qmt_config.md @@ -140,6 +140,7 @@ Redis 用于存储交易状态、缓存策略信号和实时行情数据。 |--------|------|------|--------|------| | `qmt_id` | 字符串 | 是 | - | 策略绑定的 QMT 终端 ID,必须在 `qmt_terminals` 中定义 | | `total_slots` | 整数 | 是 | - | 策略可用的交易仓位总数 | +| `weight` | 整数 | 否 | 1 | 策略权重,用于按权重分配下单金额 | | `execution` | 对象 | 是 | - | 策略执行参数,详见下方说明 | #### execution 执行参数配置 @@ -156,6 +157,7 @@ Redis 用于存储交易状态、缓存策略信号和实时行情数据。 - **`qmt_id`**:策略绑定的 QMT 终端标识符。一个策略只能绑定到一个终端,但多个策略可以绑定到同一个终端。 - **`total_slots`**:策略可用的总仓位数量。例如设为 5 表示策略最多同时持有 5 只股票。此参数用于仓位管理和风险控制。 +- **`weight`**:策略权重,用于按权重分配下单金额。当不配置时,默认为 1,表示等权分配。可用于实现策略间的资金分配比例控制。 - **`execution`**:包含策略的具体执行参数,这些参数控制订单的提交方式。 **执行参数详解** @@ -164,7 +166,100 @@ Redis 用于存储交易状态、缓存策略信号和实时行情数据。 - **`sell_drift_fixed`**:卖出时的固定漂移值。例如设置为 `-0.01`(-1%)表示卖出时允许以低于基准价 1% 的价格成交,用于应对行情快速下跌的情况。计算公式为:卖出价 = 基准价 × (1 + sell_drift_fixed)。 - **`max_adjust_limit`**:单次调仓的最大比例限制。例如设置为 `0.05`(5%)表示每次调仓不超过总仓位的 5%。此参数用于控制换手率和交易成本。 -#### 完整策略配置示例 +#### 权重配置示例 + +通过 `weight` 字段可以控制策略间的资金分配比例。下单金额计算公式为: + +**下单金额 = 可用资金 × 策略权重 / Σ(各策略槽位数 × 权重)** + +##### 基础配置(无权重,等权分配) + +不配置 `weight` 时,所有策略默认为权重 1,实现等权分配: + +```json +"strategies": { + "strategy_a": { + "qmt_id": "gj", + "total_slots": 5, + "execution": { + "buy_drift_pct": 0.005, + "sell_drift_fixed": -0.01, + "max_adjust_limit": 0.05 + } + }, + "strategy_b": { + "qmt_id": "gj", + "total_slots": 5, + "execution": { + "buy_drift_pct": 0.005, + "sell_drift_fixed": -0.01, + "max_adjust_limit": 0.05 + } + } +} +``` + +**计算示例**:A(权重1×5) + B(权重1×5) = 10,可用资金 100 万时,A 和 B 各分配 50 万。 + +##### 加权配置(按权重分配) + +配置 `weight` 字段可以实现差异化的资金分配: + +```json +"strategies": { + "strategy_a": { + "qmt_id": "gj", + "total_slots": 5, + "weight": 1, + "execution": { + "buy_drift_pct": 0.005, + "sell_drift_fixed": -0.01, + "max_adjust_limit": 0.05 + } + }, + "strategy_b": { + "qmt_id": "gj", + "total_slots": 5, + "weight": 2, + "execution": { + "buy_drift_pct": 0.005, + "sell_drift_fixed": -0.01, + "max_adjust_limit": 0.05 + } + } +} +``` + +**计算示例**:A(权重1×5) + B(权重2×5) = 15,可用资金 100 万时,A 分配 100×1/15 ≈ 6.67 万,B 分配 100×2/15 ≈ 13.33 万。 + +##### 不同槽位数的加权配置 + +```json +"strategies": { + "conservative_strategy": { + "qmt_id": "gj", + "total_slots": 3, + "weight": 1, + "execution": { + "buy_drift_pct": 0.003, + "sell_drift_fixed": -0.01, + "max_adjust_limit": 0.03 + } + }, + "aggressive_strategy": { + "qmt_id": "gj", + "total_slots": 8, + "weight": 3, + "execution": { + "buy_drift_pct": 0.008, + "sell_drift_fixed": -0.02, + "max_adjust_limit": 0.1 + } + } +} +``` + +**计算示例**:保守策略(权重1×3) + 激进策略(权重3×8) = 27,可用资金 100 万时,保守策略分配 100×1/27 ≈ 3.7 万,激进策略分配 100×3/27 ≈ 11.1 万。 ```json "strategies": { @@ -254,6 +349,14 @@ A:请检查以下几点: 3. 防火墙是否允许 Redis 端口访问 4. 如果设置了密码,`password` 是否正确 +### Q:如何配置策略的资金分配权重? + +A:通过 `weight` 字段可以配置策略的资金分配权重: +- `weight` 是可选字段,不配置时默认为 1 +- 下单金额计算公式:可用资金 × 策略权重 / Σ(各策略槽位数 × 权重) +- 示例:两个策略,A 的 weight=1、total_slots=5,B 的 weight=2、total_slots=5,则 A 分配 1/(1×5+2×5)=1/15,B 分配 2/(1×5+2×5)=2/15 +- 现有配置无需修改即可兼容,不配置 weight 时按等权分配 + ## 配置文件路径说明 配置文件应放置在以下位置之一: diff --git a/qmt/qmt_engine.py b/qmt/qmt_engine.py index 76338be..e42e4a6 100644 --- a/qmt/qmt_engine.py +++ b/qmt/qmt_engine.py @@ -528,14 +528,24 @@ class MultiEngineManager: asset = unit.xt_trader.query_stock_asset(unit.acc_obj) # 计算该终端的总槽位之和 terminal_strategies = self.get_strategies_by_terminal(unit.qmt_id) - total_slots = sum(self.config['strategies'][s]['total_slots'] for s in terminal_strategies) - if not asset or total_slots <= 0: return + # 计算加权槽位总和(支持策略权重配置) + # 权重默认为 1,支持通过 weight 字段调整资金分配比例 + # 示例:strategies = {"strategy_a": {"total_slots": 5, "weight": 1}, "strategy_b": {"total_slots": 5, "weight": 2}} + total_weighted_slots = sum( + self.config['strategies'][s].get('total_slots', 1) * self.config['strategies'][s].get('weight', 1) + for s in terminal_strategies + ) + + if not asset or total_weighted_slots <= 0: return - # 3. 资金等权分配 (基于该终端总资产) + # 获取当前策略的权重 + weight = strat_cfg.get('weight', 1) + + # 4. 资金加权分配 (基于该终端总资产) total_equity = asset.cash + asset.market_value - target_amt = total_equity / total_slots - actual_amt = min(target_amt, asset.cash * 0.98) # 预留手续费滑点 + target_amt = total_equity * weight / total_weighted_slots + actual_amt = min(target_amt, asset.cash * 0.98) # 预留手续费滑点 if actual_amt < 2000: self.logger.warning(f"[{strategy_name}] 单笔预算 {actual_amt:.2f} 不足 2000 元,取消买入")