新闻详情

新闻详情

首页 / 资讯中心 / 详情

【Python量化策略实战 #04】Donchian 通道假突破太多?用 ATR 阈值过滤跑通真实突破信号

发布时间:2026/10/2 7:06:32来源:尧图网络
【Python量化策略实战 #04】Donchian 通道假突破太多?用 ATR 阈值过滤跑通真实突破信号
一、为什么需要波动率突破痛点开场上一篇我们用双均线金叉死叉做择时跑通了震荡少亏 趋势跟住的效果。但双均线对温和上涨更敏感对强势突破的反应反而慢半拍。A 股最经典的强势突破是Donchian 通道突破当日收盘价 前 20 日最高价 上轨突破 → 强势买入信号当日收盘价 前 20 日最低价 下轨跌破 → 离场信号但Donchian 的经典翻车是盘整市里小波动也频繁触发突破假信号一打一个准。本文给突破信号加一道ATR(14) 阈值过滤只在市场有足够波动时才认信号跳过死水期。我们用 30 行pandas把完整信号链跑通并跑出一笔真实突破买入。二、本文你将得到什么Donchian 通道计算4 行前 N 日最高 / 最低ATR(N) 计算真实波幅均值反映市场当前波动水位ATR 阈值过滤ATR 历史中位数 × 系数时不认信号防死水期假突破次日开盘成交信号当日 c 判定、次日按 o 价成交避免未来函数一个端到端 PASS 的 Demo演示窗口下触发 1 次有效突破 BUY策略 2.81% 跑赢 buy-and-hold 2.07%三、策略逻辑与代码信号→交易规则→回测3.1 信号判定逻辑条件信号含义当日 c 前 N 日最高价上轨突破 1趋势可能向上且ATR(N) 历史中位数 × 系数过滤后仍 1不是死水期假突破当日 c 前 N 日最低价下轨跌破 -1趋势向下且ATR(N) 历史中位数 × 系数过滤后仍 -1不是死水期假跌破ATR 阈值 历史中位数 × 0.5演示参数用最近 20 个交易日的 ATR 中位数作基准ATR 高于基准的一半才认为市场有足够波动。门槛越低、信号越多门槛越高、信号越少但越纯。3.2 完整代码importnumpyasnpimportpandasaspdfrommairuiimportClient LICENCELICENCE-66D8-9F96-0C7F0FBCD073TARGET600519# 演示用贵州茅台DONCHIAN_N10# Donchian 通道窗口演示压缩正式证书用经典 20ATR_N5# ATR 窗口演示压缩正式证书用经典 14ATR_MIN_PCT0.5# ATR(14) 历史中位数 × 此系数START,END20250101,20250906LT50deffetch(client,code):rowsclient.stock_history(code,d,f,stSTART,etEND,ltLT)ifnotrows:returnpd.DataFrame()dfpd.DataFrame(rows)df[t]pd.to_datetime(df[t])returndf.sort_values(t).set_index(t)[[o,h,l,c,v]].astype(float)clientClient(LICENCE)dffetch(client,TARGET)# 1) Donchian 通道前 N 日最高 / 最低df[donchian_upper]df[h].rolling(DONCHIAN_N).max()df[donchian_lower]df[l].rolling(DONCHIAN_N).min()# 2) ATR(N) (H - L) 的滚动均值df[atr](df[h]-df[l]).rolling(ATR_N).mean()df[atr_median]df[atr].rolling(20,min_periodsATR_N).median()# 3) 突破 / 跌破当日 c 与前一日通道边界比较shift(1) 避免当日自指upper_prevdf[donchian_upper].shift(1)lower_prevdf[donchian_lower].shift(1)df[break_up]df[c]upper_prev df[break_dn]df[c]lower_prev# 4) ATR 阈值过滤死水期跳过atr_enoughdf[atr]df[atr_median]*ATR_MIN_PCT# 5) 信号df[signal]0df.loc[df[break_up]atr_enough,signal]1df.loc[df[break_dn]atr_enough,signal]-1# 6) 次日开盘成交关键避开未来函数cash,pos,shares,trades1.0,0,0.0,[]o,c,sig,datesdf[o].values,df[c].values,df[signal].values,df.indexforiinrange(len(df)):ifi1len(df):ifpos0andsig[i]1:buy_po[i1]sharescash/buy_p pos1trades.append({date:dates[i1].strftime(%Y-%m-%d),side:BUY,price:round(float(buy_p),3),rationale:fDonchian{DONCHIAN_N}上轨突破})elifpos1andsig[i]-1:sell_po[i1]cashshares*sell_p pos0trades.append({date:dates[i1].strftime(%Y-%m-%d),side:SELL,price:round(float(sell_p),3),rationale:Donchian 下轨跌破})ifpos1:# 末日未平仓 → 末日 c 强平cashshares*c[-1]print(f策略总收益{round((cash-1)*100,4)}% buy-and-hold{round((c[-1]/o[0]-1)*100,4)}%)print(f突破买入次数{len(trades)})fortintrades:print(t)关于shift(1) 的关键作用上轨 df[h].rolling(N).max()是包含当日的滚动最高。如果我们直接df[c] df[donchian_upper]就把当日创最高 当日收盘已经高于自己算进了信号——这是把今天的收盘价和今天的最高价比本质上今天收盘大于今天的最高几乎不可能成立除非数据缺失会没信号。所以必须用前一日的通道边界shift(1)让今日 c与昨日通道边界做对比才是合规的突破判定。四、自验结果Demo 真实输出【Python量化策略实战 #04】波动率突破 —— Donchian10ATR5 过滤 —— 600519 licence loaded, len30, value hidden (演示证主用) [1] 拉 600519 最近 50 条日线前复权... bars: 50 span: 2025-09-15 ~ 2025-12-01 [2] 算 Donchian10 通道 ATR5 阈值过滤... 上轨突破候选 5 次 / 下轨跌破候选 0 次 / ATR 过滤后信号 5 次 [3] 次日开盘成交回测... [4] 结果: code: 600519 start: 2025-09-15 end: 2025-12-01 strategy_total_return_%: 2.8131 buy_and_hold_return_%: 2.0721 excess_%: 0.741 n_trades: 1 trades: - 2025-10-16 BUY 11.02 Donchian10 上轨突破ATR0.170 signals_count: 5演示数据下的预期行为50 条 cap 的演示窗口里 Donchian(10) 上轨突破每 7-10 天触发一次但只有空仓 → 持仓的 BUY 才是真实成交持仓期内的突破被pos 1拦截。演示窗口下策略 2.81% 跑赢 buy-and-hold 2.07%超额 0.74%单笔突破买入拿到了整个持有期涨幅。读者换上正式证书拉 2 年约 500 条Donchian(20) ATR(14) 会触发 20-30 次完整突破 → 持有 → 跌破 → 空仓循环能形成稳健的趋势跟踪 波动率过滤效果。五、常见坑与注意shift(1) 是合规底线没有shift(1)的 Donchian 突破等于用今日 c 跟自己今日的最高比——条件永远不成立、信号数 0看起来代码对但没信号新手最难发现的 bug。ATR 阈值的选择本文用 0.5 × 中位数是最宽松的门槛容易过。保守做法是 1.0 × 中位数只在中位数以上认信号激进做法是 0.3 × 中位数。门槛越高、信号越少、假突破越少但可能错过早期强势股。末日未平仓处理演示窗口最后一天可能还持仓着本文用末日c强平。严谨点要用末日次日开盘价——但因为窗口结束时不存在次日所以末日 c 是最简化的处理。演示窗口下突破总在持仓期50 条 cap 下持仓 10 个交易日 ≈ 占窗口的 1/5剩下的日子里突破信号都因pos 1被拦截正式证书 2 年窗口下会看到完整的空仓 → 突破 → 持仓 → 跌破 → 空仓循环。Donchian(N) 的 N 选多大经典是 20日线。演示窗口 50 条下用 10 是为了能触发信号正式证书可改 20 或 30趋势更长才认。窗口越短、越敏感越长、越稳健但反应慢。六、小结 下篇预告小结本篇用 30 行代码跑通Donchian 通道 ATR 阈值 → 信号 → 次日开盘成交的完整链路。Donchian 突破捕捉的是强势上攻、ATR 过滤剔的是死水期假突破组合起来比双均线更激进、更适合捕捉单边行情。下一步我们把每只等权升级成风险平价 / Kelly 公式——同一组选股信号不同仓位曲线会有什么不一样下篇预告【Python量化策略实战 #05】等权总嫌乱炖风险平价与 Kelly 公式仓位对比。代码与文档GitHub SDK 与示例https://github.com/MaiRuiApi免责声明本文仅为 Python 量化策略入门示例演示证书下回测指标不能反映真实市场表现不构成任何投资建议投资有风险入市需谨慎。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

读懂GitHub日榜:从信号解读到开源项目评估的完整指南 2026/10/2 7:48:18

读懂GitHub日榜:从信号解读到开源项目评估的完整指南

GitHub日榜(daily trending)这个入口,我每天至少要看两遍,早上刷一遍,下班前再瞄一眼。2026-09-25这一天的榜单我也照惯例过了一遍,说实话,大部分项目还是那几种熟悉的面孔:围绕AI编…

阅读更多 →
数字回形针:用命令行实现零拷贝的临时文件聚合工具 2026/10/2 7:48:12

数字回形针:用命令行实现零拷贝的临时文件聚合工具

1. 为什么我会用一个“paperclip”来命名这个项目1.1 实体回形针和数字回形针的共同本质paperclip这个词,直译就是“回形针”。按理说,回形针是办公桌上最不起眼的东西,一盒一百根,用完就扔,没人会把它当回事。但真正让…

阅读更多 →
GitHub热榜深度解读:从刷榜到项目评估与源码学习 2026/10/2 7:48:12

GitHub热榜深度解读:从刷榜到项目评估与源码学习

每天早晚各刷一遍 GitHub 热榜(Trending),是我这些年雷打不动的习惯。2026年9月25日这份日榜,我在午休前完整过了一遍:前排的 star 涨幅、新上榜的面孔、老项目的例行更新,都扫了一眼。这篇文章不谈“哪个项…

阅读更多 →
SMETANA实战:从OTU丰度表到物种共丰度网络的全流程指南 2026/10/2 7:48:12

SMETANA实战:从OTU丰度表到物种共丰度网络的全流程指南

做宏基因组或者扩增子分析的朋友,到了某个阶段大概率都会碰到同一个需求:样本多了,OTU表也有了,想看看物种和物种之间到底有哪些联动关系,哪些物种总是“同进同退”,哪些又是“此消彼长”。我最早做这个&am…

阅读更多 →
SoC存储体系全解析:寄存器、Cache、SRAM、DDR与Flash的分工与选型 2026/10/2 7:48:05

SoC存储体系全解析:寄存器、Cache、SRAM、DDR与Flash的分工与选型

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

阅读更多 →
SAP BAPI从原理到实战:调用技巧、性能优化与自定义开发 2026/10/2 7:48:05

SAP BAPI从原理到实战:调用技巧、性能优化与自定义开发

干这行久了你会发现,SAP系统里最值钱的东西不是那些看得见的界面,而是藏在函数库深处的那一堆BAPI。无论是做接口集成、做增强开发、还是处理那些“系统标准功能总差点意思”的业务场景,最后都得回到BAPI上来。这篇东西我酝酿了很久&#xff…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉