MAMS策略:基于3512条信号验证的动量自适应实盘交易系统
过去半年,我的CSI800信号系统累计验证了3677条交易信号。这些信号不是纸面推演——每一条都追踪了T+1的真实涨跌表现。
今天,我用这3677条数据反向工程出一个完整的交易策略:MAMS(Momentum-Adaptive Market Strategy,动量自适应市场策略)。
信号系统告诉我们的5个残酷真相
真相1:均值回归在A股是亏钱策略
| 信号类型 | 样本量 | 胜率 | 平均收益(T+1) |
|---|---|---|---|
| 动量型 | 565 | 51.2% | +0.39% |
| 均值回归型 | 807 | 35.8% | -0.29% |
| 混合型 | 2140 | 37.8% | -0.31% |
均值回归型的胜率只有35.8%——10次做超卖反弹,只有3.6次赚钱。而动量型的胜率超过51%,是均值回归的1.4倍。
真相2:RSI 70-80是最强信号区间
这彻底颠覆了”RSI超买就要卖”的传统认知:
| RSI区间 | 样本量 | 胜率 | 平均收益 |
|---|---|---|---|
| RSI小于20(极度超卖) | 196 | 32.7% | -0.33% |
| RSI 20-30(超卖) | 1088 | 38.3% | -0.32% |
| RSI 40-60(中性) | 256 | 37.9% | -0.60% |
| RSI 60-70(偏强) | 233 | 47.6% | +0.41% |
| RSI 70-80(强势) | 166 | 53.0% | +0.80% |
RSI在70-80的股票,次日上涨概率53%,平均赚0.80%。 而RSI小于20的超卖股,胜率只有32.7%——“抄底”实际上是在接飞刀。
真相3:空头环境反而更适合做动量
| 市场环境 | 动量型胜率 | 动量型均收 | 均值回归胜率 | 均值回归均收 |
|---|---|---|---|---|
| 多头环境 | 53.8% | -0.07% | 13.8% | -0.91% |
| 中性环境 | 44.8% | +0.22% | 31.3% | -0.49% |
| 空头环境 | 50.0% | +0.46% | 40.9% | -0.26% |
在多头环境中做均值回归,胜率只有13.8%——这几乎是送钱。而在空头环境中做动量,胜率50%、均收+0.46%,是最可靠的组合。
真相4:趋势方向决定一切
| 趋势状态 | 样本量 | 胜率 | 平均收益 |
|---|---|---|---|
| 空头排列 | 2640 | 34.4% | -0.49% |
| 震荡 | 530 | 45.7% | -0.24% |
| 多头排列 | 342 | 48.8% | +0.62% |
多头排列(MA5大于MA10大于MA20)的股票,胜率49%、平均收益+0.62%。空头排列的股票则全面亏损。
真相5:最优信号组合
将信号类型、市场环境、RSI和趋势四个维度交叉,得到的最优组合:
| 组合 | 样本量 | 胜率 | 平均收益 |
|---|---|---|---|
| 动量+中性+高RSI+多头排列 | 86 | 52.3% | +0.74% |
| 动量+空头+中等RSI+震荡 | 74 | 51.4% | +0.59% |
| 动量+空头+高RSI+多头排列 | 82 | 51.2% | +0.42% |
最差组合(绝对不能做的):
| 组合 | 样本量 | 胜率 | 平均收益 |
|---|---|---|---|
| 混合+多头+中等RSI+空头排列 | 78 | 12.8% | -1.39% |
| 均值+中性+低RSI+空头排列 | 133 | 23.3% | -0.52% |
MAMS策略设计
基于以上5个发现,策略的核心原则是:
只做动量,不做均值回归。只在强势股上追涨,不抄底。
架构
选股层 → 多因子打分(动量+趋势+RSI+流动性)
信号层 → 市场环境自适应(3种regime × 动态权重)
风控层 → 三级止损(ATR+硬止损+时间止损)
仓位层 → 波动率调整的固定比例
选股因子打分
| 因子 | 加分条件 | 分值 | 数据依据 |
|---|---|---|---|
| 强势动量 | 20日涨幅大于10% 且 多头排列 | +3 | 动量型胜率51% |
| 温和动量 | 5日涨幅大于5% 且 非空头趋势 | +1 | 动量型整体正向 |
| RSI强势 | RSI在60-80区间 | +2 | RSI70-80胜率53% |
| 趋势确认 | MA5大于MA10大于MA20 | +1 | 多头排列胜率49% |
| 布林突破 | 布林带上轨突破 + RSI大于55 | +1 | 动量加速信号 |
| 空头反抽 | 空头环境中趋势反转 | +1 | 空头环境动量50% |
| 超买过滤 | RSI大于85 | -2 | 极端超买风险 |
| 超卖过滤 | 布林下轨 + RSI小于30 | -1 | 均值回归胜率仅36% |
买入阈值:总评分大于等于3分
市场环境自适应
策略会根据当日市场宽度自动调整信号权重:
| 市场环境 | 调整逻辑 | 依据 |
|---|---|---|
| 多头(上涨家数大于55%) | 评分小于等于1的信号全部清零 | 多头环境均值回归胜率仅13.8% |
| 空头(上涨家数小于45%) | 动量+RSI信号额外+1分 | 空头环境动量均收+0.46% |
| 中性 | 不调整 | — |
超短线持仓(T+1到T+3)
信号系统验证的是T+1表现,因此策略采用超短线持仓:
| 平仓条件 | 规则 | 依据 |
|---|---|---|
| ATR止盈 | 收益达4倍ATR | 让利润奔跑 |
| 快速止盈 | 2天内涨超12% | 超买风险 |
| T+3强制平仓 | 持有3天一律卖出 | 信号有效期短 |
| ATR止损 | 亏损达3倍ATR(不低于8%) | 给足波动空间 |
| 硬止损 | 单笔最大亏损10% | 风险底线 |
三级风控体系
| 级别 | 触发条件 | 动作 |
|---|---|---|
| 单笔级 | 亏损超10%或3倍ATR | 止损平仓 |
| 策略级 | 连续亏损10次 | 暂停1轮交易 |
| 账户级 | 回撤超20% | 熔断暂停,14天后恢复 |
Python回测代码
import duckdb, numpy as np, pandas as pd
from collections import defaultdict
DB_PATH = '/mnt/c/Users/Administrator/clawd/data/quant/quant_v2.duckdb'
# 1. 数据加载(只取高流动性股票)
con = duckdb.connect(DB_PATH, read_only=True)
df = con.execute("""
WITH liquid AS (
SELECT code FROM stock_daily
WHERE date >= '2025-01-01' AND amount > 200000000
GROUP BY code HAVING COUNT(*) > 60
)
SELECT s.* FROM stock_daily s
INNER JOIN liquid l ON s.code = l.code
WHERE s.date >= '2025-01-01'
""").fetchdf()
# 2. 因子计算
grouped = df.groupby('code')
df['ret_20d'] = grouped['close'].pct_change(20)
df['ma5'] = grouped['close'].rolling(5).mean().reset_index(0, drop=True)
df['ma20'] = grouped['close'].rolling(20).mean().reset_index(0, drop=True)
df['trend'] = np.where(
(df['close'] > df['ma5']) & (df['ma5'] > df['ma20']), 1,
np.where((df['close'] < df['ma5']) & (df['ma5'] < df['ma20']), -1, 0)
)
# RSI计算(简化版)
delta = grouped['close'].diff()
df['rsi14'] = 100 - 100/(1 + delta.clip(lower=0).rolling(14).mean() /
(-delta).clip(lower=0).rolling(14).mean())
# 3. 信号打分(向量化)
def score_stocks(day_data, market_score):
score = np.zeros(len(day_data))
score[(day_data['ret_20d'] > 0.10) & (day_data['trend'] == 1)] += 3
score[(day_data['rsi14'] >= 60) & (day_data['rsi14'] <= 80)] += 2
score[day_data['trend'] == 1] += 1
score[day_data['rsi14'] > 85] -= 2
if market_score < -1: # 空头环境动量加分
mask = (day_data['ret_20d'] > 0.10) | (day_data['rsi14'] >= 60)
score[mask] += 1
return score
# 4. 回测(含手续费万5+滑点千1)
COMMISSION, SLIPPAGE = 0.0005, 0.001
for date in trading_dates:
# 止损/止盈检查
for pos in positions.values():
loss = (entry - current) / entry
if loss > max(3 * atr / entry, 0.08): # ATR止损
sell()
elif holding_days >= 3: # T+3强制平仓
sell()
# 新信号买入
scores = score_stocks(day_data, market_score)
candidates = day_data[scores >= 3].nlargest(10, 'signal_score')
完整代码见 GitHub仓库,包含回测引擎、风控模块和绩效分析。
回测结果
MAMS策略回测报告
回测周期: 2025-01-01 ~ 2026-06-24 (17个月)
初始资金: ¥100,000
| 指标 | MAMS策略 | 说明 |
|---|---|---|
| 总收益率(17个月) | -5.32% | 手续费侵蚀+6月单月回撤-8.2% |
| 年化收益率 | -3.79% | 扣除手续费+滑点后 |
| 胜率 | 44.0% | 1092笔交易,480盈利 |
| 盈亏比 | 1.24 | 平均盈利6.80% vs 平均亏损5.31% |
| 最大回撤 | 18.21% | 2026年6月算力链回调 |
| Sharpe比率 | -0.112 | 接近0,略低于无风险 |
| 平均持有 | 3.2天 | 超短线轮动 |
| 总交易次数 | 1092次 | 月均64次 |
平仓原因分布
| 平仓类型 | 次数 | 占比 | 说明 |
|---|---|---|---|
| 时间止损(3天未涨) | 571 | 52% | 主要平仓来源 |
| T+3强制平仓 | 335 | 31% | 有盈利但未达止盈 |
| 硬止损(亏损超10%) | 63 | 6% | 极端情况 |
| 快速止盈(2天涨超12%) | 55 | 5% | 最理想情况 |
| ATR止盈 | 34 | 3% | 正常止盈 |
月度收益分析
策略在2026年1月达到最佳(+7.3%),但2026年6月遭遇最大回撤(-8.2%,AI算力链拥挤后的市场全面回调)。
盈利月(7个):2025-02(+5.4%)、2025-08(+1.8%)、2025-09(+2.7%)、2025-12(+3.7%)、2026-01(+7.3%)、2026-03(+4.0%)、2026-05(+4.2%)
亏损月(10个):大部分亏损在-3%以内,属于正常波动。最大亏损月2026-06(-8.2%)是系统性风险。
为什么策略亏钱了?(诚实分析)
- 手续费侵蚀:1092笔交易 × 双边万5 = 约1.1万手续费,占初始资金11%。如果不扣手续费,策略实际正收益
- 滑点成本:1092笔 × 千1滑点 = 约1.1万滑点,再吃掉11%
- 信号衰减:CSI800信号系统的51%胜率是T+1收盘对收盘,实盘中买入价已经反映了信号(开盘跳空)
- 6月极端行情:单月-8.2%回撤拉低了整体表现
怎么改进?
关键在降低交易频率:
| 改进方向 | 预期效果 |
|---|---|
| 信号阈值从3分提高到4分 | 交易次数减半,手续费降50% |
| 持仓周期从T+3延长到T+5 | 减少时间止损触发(目前占52%) |
| 只做评分大于5的高确定性信号 | 月交易从64次降到10-15次 |
| 加入大盘择时(空头环境才交易) | 避免多头环境的低胜率陷阱 |
Ptrade实盘部署
策略已适配国金Ptrade实盘:
def initialize(context):
context.max_positions = 10
context.holding_days_limit = 3
def handle_data(context, data):
# T+3强制平仓
for pos in context.portfolio.positions:
if holding_days(pos) >= 3:
order_target_percent(pos, 0)
# 信号打分+买入
candidates = score_all_stocks(context)
for stock in candidates[:available_slots]:
order_target_percent(stock, position_size)
Ptrade关键配置
| 参数 | 值 | 说明 |
|---|---|---|
| 最大持仓 | 10只 | 分散风险 |
| 单只仓位 | 8-15% | 按信号强度+波动率调整 |
| 止损频率 | 每日检查 | 盘中ATR止损 |
| 资金分配 | 6万/月 | 超短线高频轮动 |
策略的局限性
诚实告知风险:
- 超短线策略手续费侵蚀大:T+1到T+3的持仓意味着每月可能换手5-8次,年手续费成本约2-3%
- 滑点敏感:信号集中在强势股,买入时可能有1-2%冲击成本
- 样本量有限:3677条信号虽然不少,但只覆盖了半年时间,可能存在时间偏差
- 市场环境切换风险:如果市场从震荡转为单边下跌,即使空头环境做动量也可能失效
改进方向
| 方向 | 具体措施 |
|---|---|
| 因子扩展 | 加入成交量突变、北向资金流入、行业轮动信号 |
| 持仓优化 | 测试T+1 vs T+2 vs T+5的最优持仓周期 |
| 机器学习 | 用XGBoost替代线性打分,自动学习因子权重 |
| 组合优化 | 加入股债配置(可转债+股票动态再平衡) |
总结
MAMS策略的核心思想用一句话概括:
在空头或中性环境中,买入RSI在60-80区间、多头排列、20日涨幅超过10%的强势股,持有1-3天。
这不是什么革命性的发现——它只是用3677条真实数据验证了一个常识:在A股,追强势股比抄底更赚钱。
但知道和做到之间,隔着三层风控、仓位管理和纪律执行的距离。
策略代码和回测数据来自CSI800信号系统(3677条验证记录)。回测包含万5手续费和千1滑点。本文不构成投资建议。