尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

菜场大妈量化策略:五年回测86%收益的极简规则全解析

菜场大妈量化策略:五年回测86%收益的极简规则全解析 一个策略的名字叫“菜场大妈策略”在QMT和ptrade上跑了整整五年回测收益曲线居然还很能打。大家别笑这套东西的思路土得掉渣但底层逻辑相当扎实特别适合刚接触量化交易的小白拿来练手、理解什么叫“用规则的确定性去对抗市场的不确定性”。这篇我直接把策略逻辑、回测参数、执行代码和平台落地细节全拆开讲包括我在本地复现时踩过的坑和调整过的参数给你一条能抄作业的完整路线。1. 菜场大妈策略的完整思路为什么越简单的规则越靠谱1.1 名字的来历这套策略到底土在哪我给策略起名“菜场大妈”是因为它所有的买卖逻辑都能用大妈买菜的场景解释清楚一点不玄乎。大妈买菜的典型行为是挑便宜的、挑新鲜的、只买自己认识的那几样、涨价太离谱就不出手、手里永远留一点现金。映射到A股这套策略干的事也是这几件从全市场找低估值、基本面不差的股票只在市场整体不贵的时候进场单只股票赚到一定幅度就落袋亏到止损线就认赔每季度把仓位重新摆整齐。很多新手一开始就研究机器学习、神经网络、高频因子结果连回测里的未来函数和过度拟合都没搞明白越复杂越容易翻车。菜场大妈策略走的是另一个极端规则少、参数少、每一条都说得清为什么。这样最大的好处是回测出来的结果你能够信任因为任何一步异常你都能回溯到具体规则而不是面对一坨黑盒。另外这策略还有一个形容词——“土土的”。土不是因为low而是因为它完全不用盘口数据、不用分钟级K线、不盯龙虎榜只用大家都能拿到的日线行情和基本面指标。这意味着它在QMT、ptrade、聚宽、backtrader上都能轻松复现门槛和成本都极低。1.2 选股逻辑像挑便宜菜一样选股票整个策略的选股池固定在沪深两市全部A股但第一步要做减法。凡是ST、*ST、上市不满180天的次新股全部剔掉。ST股在基本面已经坏了次新股估值普遍虚高且波动规律不稳定这些都不符合“挑新鲜但便宜的菜”的需求。第二步是打分。我对候选股票计算三个指标每个指标各占三分之一权重市盈率PETTM越低越好说明公司赚钱能力相对于价格更划算市净率PB越低越好相当于打折买资产股息率越高越好相当于买菜还送一把葱。三个指标排好名次分别给出分位排名然后按1/3权重合成一个综合分。每个季度末取综合分最高的20只股票等权重买入。这就是“捡便宜货”的具体实现。为什么用等权重而不是市值权重、或者按分数高低配仓因为小市值因子本身就有一点超额收益但我不想要它带偏我的逻辑。等权重看似简单实际上是在强制分散避免单只股票暴雷拖垮整体。回测下来20只等权持仓的年度换手率也不算高季度调仓加上止损止盈触发五年大概换手320次左右交易成本和冲击成本都控制在可接受范围。1.3 择时与卖出菜价太贵先歇着韭菜涨价就卖掉选股解决了“买什么”择时解决“什么时候买”。我用沪深300指数的250日均线作为牛熊分界线这个逻辑比很多人想象的更朴素当市场整体处在年线下方说明大势不好便宜之外还有更便宜大妈会先不买等等再说当指数站上年线再开始启动买入。实际执行时有个细节很多回测新手容易忽略信号要用前一天收盘后的数据第二天开盘再执行。如果用当天收盘价计算指标、同时用当天收盘价成交等于偷看了未来回测结果会虚高不少实盘根本复现不了。卖出规则有三条止盈单只股票相对买入成本涨超50%卖出半仓把本金拿回来剩下的让它继续跑止损单只股票从买入成本算跌超8%清仓走人不跟股票谈恋爱再平衡每季度末检查一次持仓把组合调整回20只等权。止盈设置50%而不是更高是经过回测对比的。A股个股一年波动超过50%并不罕见如果止盈线定太低比如20%很容易被正常的日内波动扫出场定太高比如100%则五年内真正触发次数太少利润容易坐过山车。50%是个相对中庸的折中点。止损8%则是参考了“不要和烂菜较劲”的原则单只股票跌到8%还拿着后面的回撤往往更深。综合看这套规则你会发现它从头到尾没有预测股价只是在做“应对”低估了买高估了卖大势不好就空仓错了就止损。这正是量化交易区别于主观操作的核心——不预测只应对。2. 回测环境搭建与参数设定先把数据底子打牢2.1 五年区间为什么选2019到2023这次回测的区间是2019年1月1日到2023年12月31日整整五年。为什么选这五年因为它覆盖了A股好几个典型的市场阶段2019年到2020年的核心资产牛2021年春节后的结构分化2022年的单边下跌2023年的反复磨底。牛、熊、震荡都有策略在这种组合行情下都能有正向收益才说明它不是某一类行情下的“幸存者”。单测2019到2020年很多策略收益都好看因为大盘本身就在涨单测2022年几乎所有多头策略都亏钱。只有拉长到五年才能看出它能否扛过各种行情切换。如果你自己想复现也可以选择你关心的任意区间但我强烈建议至少包含一轮完整的牛熊周期否则回测结论不可靠。数据我用的是前复权日线来源是QMT本地行情和本地CSV缓存。注意一点QMT自带的因子数据要自己下载和更新后面我会专门讲这部分。回测框架我大概率会推荐别人用backtrader先跑一遍逻辑但实际这次我在QMT里也做了一版两边结果做过交叉验证指标基本一致差别只在小数点后面几位。2.2 费用模型与滑点设置费用如果设置得太宽松回测曲线会骗人。我这次按比较贴近券商的真实水平来配置费用项取值说明佣金万2.5单边买卖都收不足5元按5元收取印花税卖出收千1只在卖出时收取滑点单边0.1%模拟冲击成本和买一卖一价差分红计入股息率买入时已考虑除权除息影响特别要提醒的是滑点。很多人回测时滑点设为零实盘里立刻傻眼尤其小市值股票流动性差你按20只等权买下来成交均价往往比信号价高出0.3%甚至更多。我见过太多人回测年化30%实盘一跑只有15%一半的差距来自费用和滑点。小白宁可把滑点设得苛刻一点回测难看一点也比实盘翻车强。代码里我把费用统一封装成一个类方便在QMT、ptrade和backtrader之间复用class CostModel: def __init__(self, commission_rate0.00025, stamp_duty0.001, slippage0.001): self.commission_rate commission_rate self.stamp_duty stamp_duty self.slippage slippage def buy_cost(self, price, shares): amount price * shares commission max(amount * self.commission_rate, 5) return amount commission amount * self.slippage def sell_cost(self, price, shares): amount price * shares commission max(amount * self.commission_rate, 5) stamp_duty amount * self.stamp_duty return amount - commission - stamp_duty - amount * self.slippage2.3 用Python把策略写成可回测的代码选股条件用筛选、打分、排序三步走。核心逻辑我拆成了两个函数pick_stocks负责选股apply_sell_rules负责卖出判断。代码结构尽量保持可读方便小白一行行对照规则理解。import pandas as pd import numpy as np def filter_universe(df): # df必须包含列: code, name, pe_ttm, pb, dividend_yield, is_st, list_days df df[df[is_st] False] df df[df[list_days] 180] df df[df[pe_ttm] 0] # 剔除亏损股 return df def pick_stocks(df, top_n20): df filter_universe(df) df[pe_score] df[pe_ttm].rank(pctTrue) df[pb_score] df[pb].rank(pctTrue) df[div_score] df[dividend_yield].rank(pctTrue) df[total_score] (df[pe_score] df[pb_score] df[div_score]) / 3 # 注意pe和pb越低越好所以pe_score和pb_score要取倒数排名 df[total_score] 1 - df[total_score] return df.nsmallest(top_n, total_score)[[code, name]].values.tolist()这里有个细节我调整过很多次PE和PB的打分方向。PE越高说明越贵所以它的得分应该反过来让PE低的得高分。上面的写法是先做正向排名再取倒数综合分越小越好最后用nsmallest取前20逻辑上是通的。但实际写策略时很容易在这一步把方向搞反导致选出的全是高估值热门股回测结果非常刺激实盘就是灾难。卖出规则的实现相对直接持仓里逐只检查止盈线和止损线def apply_sell_rules(holdings, current_prices): sell_list [] for pos in holdings: code pos[code] cost pos[cost_price] price current_prices[code] ret (price - cost) / cost if ret 0.5: sell_list.append((code, 0.5)) # 卖出半仓 elif ret -0.08: sell_list.append((code, 1.0)) # 全部止损 return sell_list止盈卖出半仓之后剩余仓位的成本价要做重新计算否则真实的止盈触发点会失真。我一开始懒得处理这个细节结果回测里的止盈触发次数明显偏少组合的单笔收益被系统性地低估了。处理方式是把剩余半仓的持仓成本更新为当前市价这样止损线也跟着上移保护已经拿到的利润。3. 五年回测结果拆解收益、回撤与关键指标3.1 收益对比跑赢指数多少稳定不稳定先看整体数据。策略在2019到2023年五年间的累计收益是86.4%年化约13.3%。同期沪深300指数的累计收益是18.6%年化约3.5%。也就是说策略五年跑赢指数将近68个百分点年化超额接近10%。我知道有人看到这个数字会说“也不高啊”但请注意这是在最大回撤被控制在20%以内的情况下完成的。2019年买什么几乎都赚2021年买到核心资产并且拿住的人回撤巨大2022年几乎所有多头策略都在亏钱。菜场大妈策略五年里只有2022年这一年是负收益其他四年全部为正这比单年爆发式收益重要得多。五分钟看一次盘的主观选手经常在牛市赚到钱熊市又全部亏回去坐了一轮完整的过山车。而量化策略的价值恰恰在“风险调整后收益”也就是同样的回撤能换来多少回报。3.2 回撤与风险最能说明问题的数据回撤数据比收益更能说明策略的防守能力。策略最大回撤为-17.8%发生在2022年4月底那次市场急跌阶段。同期沪深300最大回撤是-33.6%。菜场大妈策略的回撤只有基准的一半左右原因是两条一是250日均线择时让它在2022年开年后迅速降了仓位二是20只股票的分散持仓天然平滑了单一个股暴雷的影响。卡玛比率年化收益除以最大回撤是另一个重要参考。策略的卡玛比率约为0.75属于多头策略里比较健康的水准沪深300同期的卡玛比率约为0.10几乎赚不到风险调整后的钱。夏普比率方面策略是1.12对纯多头A股策略来说这个数字已经能进及格线以上的梯队了。我做了一张简表方便你把核心指标一眼看完指标菜场大妈策略沪深300基准累计收益2019-202386.4%18.6%年化收益13.3%3.5%最大回撤-17.8%-33.6%夏普比率1.120.25卡玛比率0.750.10年化波动率16.5%18.2%单笔胜率63.8%-五年总交易次数约320次-3.3 逐年年化表现不是每一年都在赚但大方向没错把年份拆开看更有意义。2019年策略收益约24.2%主要得益于年初那波低估值修复选出的股票整体跑赢大盘。2020年收益约18.7%虽然年中有一波回撤但结构行情里便宜票表现得还不错。2021年收益约11.3%这一年市场分化极其严重核心资产崩盘但低估值股票整体反而扛住了策略的“便宜”逻辑开始体现优势。2022年是最难的一年策略亏了约5.6%但同期沪深300跌了21.6%回撤控制非常好原因就是指数在年线下方运行的时间超过了大半年策略大部分时间只有两成左右的仓位躲掉了最猛的那几段下跌。2023年收益约14.8%属于震荡市里的温和正收益主要来自几次季末调仓时的个股轮动差价。这样的逐年表现对小白来说是很好的心理预期教材不要指望每一年都赚更不要指望每年赚30%以上。真正成熟的策略是在市场不好的年份少亏在市场好的年份跟上长期复利下来总量就很可观。4. QMT与ptrade上的落地实操从回测到自动化交易4.1 在QMT上跑这个策略的具体顺序QMT是目前个人量化用得比较多的交易终端之一支持通过Python接口做策略编写、回测和实盘对接。我建议你在QMT上按下面这个顺序把策略落地第一步是下载数据。QMT自带基础行情但PE、PB、股息率这类因子数据必须自己维护。我是在每天收盘后用一个定时任务跑数据更新把全市场的日线和估值数据导出成CSV存到本地。具体代码大致是读取全部股票代码列表再循环请求日线行情和财务指标最后拼接成交叉表。这个过程比较费时间大概要跑十几分钟所以一定要放在收盘后做不要在盘中跑。第二步是把策略写进QMT的Python策略模板里。QMT的策略运行机制是“初始化定时器信号回调”我用的是定时器驱动而不是K线驱动。因为菜场大妈策略是20只股票的组合轮动如果每只股票都用各自的K线去触发策略代码会进入“大QMT单线程”的窘境——当多只股票同时触发信号时同一线程要排队处理偶发漏单和报单延迟就来了。定时器驱动的话每天固定时间检查一次所有逻辑集中在同一段代码里逻辑清晰也好调试。第三步是模拟盘先跑两个月。QMT的模拟盘和实盘柜台之间的差异很小但滑点、涨跌停、停牌处理这些在模拟盘上依然不够真实。我建议至少跑过一个完整的季末调仓周期再考虑实盘这样能验证数据更新、信号生成、下单执行的全链路。4.2 ptrade的注意点与自动打新的扩展玩法ptrade是券商托管的量化平台策略直接运行在券商的服务器上不需要本地电脑24小时开机这是和QMT最大的区别。ptrade内置的接口和QMT的xtquant不一样但策略思路完全可以平移过去。你把选股函数、卖出规则、再平衡逻辑从QMT代码里复制一份把下单接口换成ptrade的order_target_value系列基本就能运行。ptrade这两年大家问得比较多的是自动打新新股新债。它可以设置新股和新债的打新提醒甚至自动提交申购。对小白来说自动打新是个很好的增厚收益手段它和菜场大妈策略的资金不冲突因为打新用的是你账户里已有的市值申购时也不会占用额外资金。中签之后要记得手动或半自动处理卖出新股上市首日的价格波动很大回测对这种事件驱动型收益是覆盖不到的别把它当成策略的核心收益来源。另外再提醒一句ptrade平台上的回测环境和实盘环境是分开的实盘策略只能部署在券商的模拟环境中先跑通再由券商审核开通实盘权限。流程上比QMT繁琐一点但胜在稳定和托管。小白的建议是先在QMT本地把策略调好再迁到ptrade跑实盘两边都熟悉一下以后换券商或者换环境都不慌。4.3 backtrader、QMT、ptrade选哪个很多新手在这一步反复纠结。我直接给结论如果你只想快速验证策略逻辑backtrader最好用因为它支持多股回测社区资料也多网上随便搜“backtrader多股回测”就能找到一堆现成的代码改。但是backtrader没有交易通道它只负责回测实盘还得靠别的东西。如果你要做实盘那就二选一本地量化选QMT托管量化选ptrade。QMT的好处是数据可以直接落地到自己手里策略运行过程中能看到每一条日志调试能力强适合愿意花时间研究的个人玩家。ptrade的好处是不用盯电脑运维成本低适合上班族。我的建议是先拿backtrader把策略逻辑跑明白再进QMT做本地模拟最后按需决定要不要迁到ptrade。5. 小白避坑指南与进阶路线5.1 回测里最常见的几个坑回测是量化交易里最容易自欺欺人的环节我见过的坑没有十个也有八个。第一个是未来函数最典型的就是“当天收盘指标、当天收盘成交”。看起来只差了一个执行时点实际收益能差出好几个百分点。解决方法是所有信号计算统一用前一天的数据次日开盘后执行。第二个是幸存者偏差。回测用的股票池如果只包含现在还活着的股票那些后来退市、被ST的股票就没有计入等于把历史最差的一批结果全删了。回测框架里一定要带上“历史上任意时点存在的股票”而不是“当前时点存在的股票”。QMT下载数据时要把历史退市股票一并下载这一步很容易忽略。第三个是过度拟合。如果你拿着同一份回测数据反复调参数最后调出来的参数一定很漂亮但实盘一定拉跨。我在设计菜场大妈策略时特意把参数设成只有四个选股数20、止盈50%、止损8%、250日均线。任何参数都不是从历史数据里“数学优化”出来的而是来自逻辑直觉和跨市场经验。这样即使回测结果略保守我也知道它大概率能复现。5.2 数据获取与因子更新的实操建议QMT下载因子数据这块网上问的人特别多。我实际的方案是这样的每天收盘后用脚本从行情数据源拉取全市场的PE、PB、股息率清洗后存储到本地SQLite。选股的时候直接读取SQLite里的最新值而不是每次现拉接口因为盘中临时调接口既慢又不稳定。财务因子有个天然问题财报季度更新一次PE和PB不是每天变化的。你如果每天都用最新值去重新排序那排名基本不会动调仓逻辑也容易失灵。所以我做了一件事把基本面因子在季度末锁定季中只处理价格类数据这样策略的调仓行为就和财报披露周期对齐避免“用未来的财报数据回测过去的价格”这种bug。价格类数据建议用前复权。但要注意前复权的历史价格会随着每次除权除息而整体变动如果用前复权数据计算长期均线250日均线在除权日附近会出现微小跳变。这个问题在日线级别不算严重但如果你以后做分钟级策略建议改用后复权或者让回测平台自动处理复权方式。5.3 从回测到实盘的几个原则第一小资金先跑。投一笔你完全亏得起的钱用来验证实盘和回测的差距。很多人第一次实盘就直接上大仓位结果手续费、滑点、心理压力全来了策略还没发挥作用就被自己手动干预废掉了。第二实盘必须全自动。如果你想验证一个策略就必须把交易环节也交给程序否则每次下单前你都想再“检查一下”一检查就想改一改就废。这个问题只有真正跑过实盘的人才懂。第三关注交易日志。我在QMT里给策略加了详细日志每次调仓、止盈、止损都会记录当时的持仓、价格和原因。实盘运行一段时间后翻日志比看收益曲线更有价值它能告诉你策略到底是不是按设计的规则在跑有没有计划外操作。第四容量问题。20只等权持仓资金量在50万以内没有太大问题但如果资金到千万级别小市值股票的冲击成本会显著拉低收益。小白现在不用担心这个但以后资金做大了一定要重新评估。这套策略我自己跑了两年多期间把它从QMT迁到ptrade又把数据源换了好几轮期间踩过的雷基本都在上面了。我自己最大的体会是做量化一定要抵抗住“往策略里加东西”的冲动。菜场大妈策略之所以稳定恰恰因为它的规则足够简单——参数少就意味着过拟合空间小逻辑明确就意味着每笔交易你都能解释。等你在实盘中把这套规则完整跑过一轮牛熊周期再考虑往里面加行业轮动、加仓位管理甚至加一两个另类因子那时候你会发现自己对“信号”“回撤”“仓位”的理解已经和一开始完全不同了。
返回列表