news 2026/10/7 7:52:01

【ptrade】MACD金叉 回测实录

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【ptrade】MACD金叉 回测实录

07_MACD金叉 · 回测实录

12只ETF各自判断MACD金叉买入、死叉卖出,最多同时持有3只。

策略类型:趋势跟踪 / 指标
回测批次:2026-10-06(本地 QuantStudio 回测引擎)
数据来源:QuantStudio 本地行情库(etf_daily/stock_daily)


一、策略思路

MACD是最经典的趋势指标:快线 EMA12 上穿慢线 EMA26 叫"金叉",视为趋势转多;反向下穿叫"死叉",视为趋势结束。策略把这套判断分别套在12只ETF上——谁出金叉就买谁,谁出死叉就卖谁。最多同时持有3只;如果同一天有超过3只出现金叉,就按 DIF 值(快线减慢线的差值)排序,优先买趋势更强的那几只,每只占总资产的约1/3。

关键参数

参数取值
FAST12
SLOW26
SIGNAL9
MAX_HOLDINGS3
EXPOSURE0.98

二、回测设置

项目设置
策略文件07_MACD金叉.py
回测区间2022-01-01 ~ 2026-09-01
初始资金100000 元
佣金费率0.00035(最低 5.0 元)
印花税率0.001
过户费率1e-05
滑点0.0
撮合价格close
基准000300
交易日数1130

三、回测结果

净值曲线会非常"趋势策略":2022、2023连续两年小幅磨损,2025年跟着一轮上涨快速拉升(+37.1%),2026年又吐回一部分。请把"累计收益"和"最大回撤"两个数字放在一起看:4年半赚22%,中途却出现过30%的回撤,年化波动率17.9%,风险调整后收益(夏普0.088)几乎为零。这就是趋势策略的真实面目——不是不赚,而是赚得极不稳定。

绩效指标

指标数值
累计收益22.04%
年化收益4.51%
最大回撤30.01%
年化波动率17.85%
夏普比率0.088
索提诺比率0.132
卡玛比率0.150
回合胜率44.06%
日胜率50.18%
盈亏比132.2%
盈利回合数63
亏损回合数80
平均持仓天数80.5
成交笔数315

「盈亏比」= 平均盈利 ÷ 平均亏损 > 100%,表示平均每笔赚的比亏的多。
「回合」指一次完整的买入→卖出(round_trips),「成交笔数」是买卖双方分开计数的原始成交记录条数。

⚠️本窗口基准数据不完整:引擎的基准序列尾部为占位填充值,据此算出的沪深300收益为 0.00%,该数字不可信;净值图中的基准曲线已截断至有效区间(至 2026-07-31)。因此本策略的α、β、超额收益、信息比率等相对指标一律不可引用,只能用绝对收益与回撤来判断。

分年度收益

年份区间收益交易日
2022-11.25%242
2023-3.02%242
202411.50%242
202537.14%243
2026-4.65%161

四、交易明细

  • 完整交易回合数:143个(盈利 63 / 亏损 80)
  • 单笔平均盈亏:+227.73 元;最大单笔盈利+10974.54 元;最大单笔亏损-5382.51 元
  • 持仓天数:平均80.5 天,最长1336 天,最短1 天

盈利最多的 5 个回合

买入日卖出日标的盈亏(元)持仓天数
2022-05-052022-07-04516160.SH+10974.5460
2026-04-022026-05-06515880.SH+10323.3834
2024-09-092024-10-24512880.SH+10002.2545
2025-06-092025-08-08515880.SH+9798.3960
2025-12-012026-01-21512660.SH+9311.1851

亏损最多的 5 个回合

买入日卖出日标的盈亏(元)持仓天数
2022-01-042022-03-16512170.SH-5382.5171
2023-11-222024-01-18512690.SH-4566.5357
2022-01-172022-02-11516160.SH-4026.2825
2026-05-082026-06-09518880.SH-3884.0732
2024-08-012024-09-24512480.SH-3810.2454

五、完整回测代码

文件名:07_MACD金叉.py(共 124 行)
引擎:QuantStudio 本地回测;全部为公开 API,无平台专有调用。

# -*- coding: utf-8 -*-""" 07_MACD金叉策略 (QuantStudio 本地回测版) ======================================== 核心逻辑:MACD金叉(DIF上穿DEA)买入,死叉卖出。 经典趋势指标,多标的独立判断,最多持3只。 参数:EMA12/EMA26/DEA9。 """importnumpyasnp ETF_POOL=['510300.SS','159915.SZ','510500.SS','512880.SS','512800.SS','512690.SS','512170.SS','512480.SS','515880.SS','512660.SS','516160.SS','518880.SS',]FAST=12SLOW=26SIGNAL=9MAX_HOLDINGS=3EXPOSURE=0.98definitialize(context):set_benchmark('000300.SS')run_daily(context,trade,time='09:30')log.info('07_MACD金叉初始化: 池=%d, 参数=%d/%d/%d, 最多持%d只',len(ETF_POOL),FAST,SLOW,SIGNAL,MAX_HOLDINGS)def_ema(arr,period):"""计算EMA序列"""iflen(arr)<period:returnNoneema=np.zeros_like(arr,dtype=float)ema[period-1]=np.mean(arr[:period])k=2.0/(period+1)foriinrange(period,len(arr)):ema[i]=arr[i]*k+ema[i-1]*(1-k)returnemadef_get_macd_cross(code):"""返回 (是否金叉, 是否死叉, DIF, DEA)"""try:n=SLOW+SIGNAL+5h=get_history(n,'1d',field=['close'],security_list=code,fq='pre',include=False,is_dict=True)ifhisNoneorcodenotinh:returnFalse,False,None,Nonecloses=np.asarray(h[code]['close'],dtype=float)closes=closes[np.isfinite(closes)]iflen(closes)<SLOW+SIGNAL+2:returnFalse,False,None,Noneema_fast=_ema(closes,FAST)ema_slow=_ema(closes,SLOW)ifema_fastisNoneorema_slowisNone:returnFalse,False,None,Nonedif=ema_fast-ema_slow# 从有效位置开始计算DEAvalid_start=SLOW-1dif_valid=dif[valid_start:]dea=_ema(dif_valid,SIGNAL)ifdeaisNone:returnFalse,False,None,None# 对齐dif_aligned=dif_valid[-len(dea):]# 判断金叉/死叉(最近两根)iflen(dif_aligned)<2orlen(dea)<2:returnFalse,False,None,Nonegolden=(dif_aligned[-2]<=dea[-2])and(dif_aligned[-1]>dea[-1])death=(dif_aligned[-2]>=dea[-2])and(dif_aligned[-1]<dea[-1])returngolden,death,float(dif_aligned[-1]),float(dea[-1])exceptException:returnFalse,False,None,Nonedeftrade(context):held=list(context.portfolio.positions.keys())# 1. 死叉卖出forcodeinheld:_,death,dif,dea=_get_macd_cross(code)ifdeath:order_target_value(code,0)log.info('MACD死叉卖出 %s (DIF=%.4f, DEA=%.4f)',code,difor0,deaor0)# 2. 金叉买入held=list(context.portfolio.positions.keys())iflen(held)>=MAX_HOLDINGS:returncandidates=[]forcodeinETF_POOL:ifcodeinheld:continuegolden,_,dif,dea=_get_macd_cross(code)ifgolden:candidates.append((code,difor0))ifnotcandidates:return# 按DIF值排序(DIF越大趋势越强)candidates.sort(key=lambdax:x[1],reverse=True)slots=MAX_HOLDINGS-len(held)buy_list=candidates[:slots]total_value=context.portfolio.total_value per_value=total_value*EXPOSURE/MAX_HOLDINGSforcode,difinbuy_list:order_target_value(code,per_value)log.info('MACD金叉买入 %s (DIF=%.4f, 目标市值=%.0f)',code,dif,per_value)defhandle_data(context,data):pass

六、风险提示

MACD是滞后指标:金叉通常出现在一段上涨的中后段、死叉出现在下跌的中后段,趋势策略的固有代价是"吃到鱼身、丢掉鱼头鱼尾"。本策略回合胜率只有44.1%,靠132%的盈亏比(平均盈利是平均亏损的1.32倍)维持正收益,这意味着它必须容忍连续多次止损。更值得注意的是持仓时间:平均80天,最长一笔超过1300天——资金可能被一只长期横盘的ETF占住好几年,期间既没有收益、也失去了其他机会。另外12只标的里有7只是行业主题ETF,同时持有3只时可能出现"同一波行情重复押注"的情况,组合的实际波动高于"分散持3只"给人的印象。


免责声明:本文所有数字来自本地历史回测,回测收益不代表未来表现,也不构成任何投资建议或个股/基金推荐。策略代码仅供研究学习,实盘执行还需额外考虑滑点、冲击成本、流动性、涨跌停与平台差异等因素。投资有风险,决策需谨慎。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/7 7:50:00

VS Code插件离线迁移教程:用TaoToken统一Key打通内网开发环境

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/7 7:49:26

郴州2026年10月想找本地做绗缝加工的厂子靠谱的制造厂家

郴州2026年10月想找本地做绗缝加工的厂子&#xff0c;很多做软体家居和服装的朋友都在问&#xff1a;有靠谱的绗缝加工厂家吗?想找能做绗缝加工的好厂家&#xff0c;推荐一下服装绗缝加工的资源到底去哪里对接。今天就结合行业现状&#xff0c;聊聊绗缝加工这件事该怎么看、怎…

作者头像 李华