
做币圈量化这几年我见过太多人一上来就写各种高大上的策略结果实盘跑两天就亏得不敢看账户。反而是网格策略这种老掉牙的手法在震荡行情里一直活得挺滋润但我得说能把它用好的人真不多。这篇文章是我自己用VNPY这个开源框架做币圈网格策略实盘的完整记录从策略原理、参数计算到代码实现再到上线后遇到的坑和运维手段全都摊开讲。如果你正打算在币圈搞网格或者已经在用别的工具但想换一套更灵活的框架这篇内容应该能帮你少走很多弯路。1. 为什么在币圈用VNPY做网格策略1.1 网格策略在震荡市里的独特价值先花点时间把网格策略说清楚。它的核心思路特别简单在某个价格区间里按固定间距挂上一系列买单和卖单。价格跌到一个格子就买入一档价格涨到一个格子就卖出一档来回低买高卖。你可以把它想象成一张渔网价格像鱼一样在网里进进出出每次穿过一个网眼你就能赚一笔差价。这种策略最舒服的行情就是震荡市价格在一个箱体里来回跳动没有明显趋势。这种行情里趋势跟踪策略会被反复打脸但网格策略反而如鱼得水因为它的假设就是价格还会回来。而币圈恰恰给了网格策略极佳的生存土壤7x24小时交易、波动率比传统市场高一大截、很多币种长期处于区间震荡状态。更重要的是网格策略不需要人盯盘下单、成交、撤单、再下单这套循环完全交给程序这是它能在币圈流行的根本原因。但我得先说清楚网格策略不是无脑躺着赚钱。价格一旦走出单边行情尤其跌破下沿还继续跌的时候你的每一档买单都会成交然后全部被套住。所以我一直强调网格策略的核心不是那套低买高卖的逻辑而是参数设计和风控这一点后面会详细展开。1.2 VNPY这套框架能解决什么问题很多人觉得自己写个小脚本接上交易所API再写个定时循环也能跑网格为什么要用VNPY我一开始也是这么想的后来被现实教育了。自己写一个最简单的网格爬虫确实不难但做着做着就会发现一堆破事WebSocket断线要重连、API请求要处理限频、订单状态要维护、止损条件要实时判断、策略要跑很久不能崩。把这些都自己撸一遍少说一两个星期而且写完还不一定稳定。VNPY的价值就在于它把这些底层活都给做了提供一个统一的事件驱动引擎把行情推送、交易委托、订单状态变化都封装成事件你只需要把自己的策略逻辑写在一个模块里就行。另一个好处是VNPY自带的回测功能。网格策略最怕的就是拍脑袋定参数回测能让你在实盘之前就用历史数据把策略大概验证一遍虽然不能保证未来赚钱但至少能排除掉那种明显离谱的参数组合。VNPY的CTA模块用起来也顺手策略模板把on_init、on_start、on_bar这些生命周期钩子都定义好了新手照猫画虎也能写出来。当然VNPY不是没有学习成本。它毕竟是一个完整的框架刚上手的时候光是把环境跑通就得折腾一天更别说还要理解事件驱动、引擎启动、策略注册这些概念。我的建议是先跑通它自带的一个示例策略比如双均线把整个链路摸一遍再动手改成网格这样会顺畅很多。1.3 我对这套方案的取舍市面上能跑网格的工具其实不少有些交易所自带网格机器人也有一些商业量化平台提供可视化网格。那为什么我最终选了VNPY自己搭先说交易所自带的那个确实好用但最大的问题是锁死在某个平台上参数灵活性有限而且策略逻辑对你是黑盒。你想加个止损条件对不起没这个按钮。商业量化平台灵活一些但要收管理费还要把策略托管到人家的服务器上很多策略细节就被平台看光了。当然这里不是否定这些工具我只是觉得如果我想把网格当作一个长期策略来研究和优化至少得有一份自己能看懂、能自由改动的代码。VNPY作为开源框架代码在自己手里服务器也自己控制策略逻辑完全透明这是它最大的吸引力。我最终的架构是VNPY自己搭的一套网格策略类跑在一台云服务器上直接连交易所API。整个系统分成行情模块、策略引擎、交易接口三层VNPY负责把底层通信处理好网格策略只处理价格数据和下单信号。这套方案其实没有太多花哨的东西就是实用、稳定、可改。我个人比较享受这种自己掌控的感觉而且出了问题也能快速定位。2. 网格策略的核心参数设计与风险控制2.1 网格间距、上下界、层级数怎么定网格策略有四个关键参数上界、下界、间距、每格下单量。这四个参数直接决定了策略的盈利能力和风险敞口必须仔细算不能拍脑袋。间距有两种常见设计方式固定差价和固定比例。固定差价比如每隔200 USDT挂一单好处是逻辑简单但缺点是在价格很低时200 USDT对应的百分比收益很高在价格很高时又没什么吸引力。固定比例比如每隔2%挂一单则是跟着价格走始终保持固定的相对利润在币圈这种价格变化极大的市场里更常用。我建议新手优先用固定比例。上下界的设定可以先参考币种最近一段时间的支撑位和压力位或者用ATR平均真实波幅来辅助判断。举个例子如果某个币最近一个月在20000到30000之间震荡那上下界就可以初步设为20000和30000跑一段时间后再根据实际行情微调。这里有一个重要的原则上下界不能设得太近否则网格层数太少赚不了几个点就触碰边界也不能设得太远因为边界越远意味着你需要准备的资金越多被深度套牢的概率也越大。层级数由上下界和间距共同决定。如果是固定比例网格价格序列是等比数列。计算公式很简单网格数量 ln(上界 / 下界) / ln(1 间距比例)。用上面的例子20000到30000间距2%算出来大约20层。如果间距放大到3%网格数量降到约14层。网格越多交易次数越密集利润来得多但资金占用也高网格越少交易次数低但每笔利润更厚。我一般会把格子控制在10到30之间这样既不会太频繁也不至于太迟钝。2.2 仓位模型和保证金估算网格的仓位模型直接决定你能扛住多大的行情。每次下单的数量我建议按固定金额来算而不是固定币量。比如你计划每格买入价值200 USDT的币那不管价格是20000还是15000你买入的币量会自动变化这样资金投入是均匀的。还是用20000到30000、20层网格、每格200 USDT来算。如果价格从20000一路跌到下界20层买单全部成交你需要投入20乘以200等于4000 USDT。但这不是全部资金因为你手里买到的币如果继续跌浮亏会越来越大。假如价格从20000跌到15000你做多现货的浮亏比例有多少我们可以简单估算一下。假设所有买单平均成本在18000附近价格跌到15000时你的这4000 USDT仓位浮亏大约损失20%。所以总资金只准备4000 USDT是不够的你得额外留出一部分安全垫用来应对浮亏而不至于爆仓或被强制平仓。我给一个比较稳妥的分配方式总资金里计划用于布单的资金只占50%到60%剩下的作为机动资金。比如你账户里有10000 USDT那网格布单预算最多放到6000 USDT这样即使币价跌穿下界你还有现金可以择机调整或者在不影响生活的前提下选择继续扛单。这里要特别强调网格策略不是全仓梭哈它是用时间换空间资金管理没做好再好的参数也会在极端行情里出局。2.3 最容易被忽略的风险控制我觉得网格策略最容易被新手忽略的不是赚多少而是亏多少的控制。很多人回测里看到年化几十个点就兴奋地直接上实盘结果遇到一次单边下跌就前功尽弃。第一道风控是边界处理。价格一旦跌破下界网格策略就不应该继续加仓了因为这时候已经不是震荡行情而是趋势性下跌。你必须提前设置一个条件比如当最新价低于下界5%时程序强制暂停新买单已成交的仓位要么止损离场要么等待价格回到区间内再继续。注意这个逻辑要在策略里写死不要依赖人工盯盘因为人很容易犹豫。第二道风控是手续费。网格策略是高频率交易每笔利润可能只有2%但如果手续费加滑点吃掉0.2%那实际利润就薄了很多。我建议找一个费率较低、流动性好的交易对最好能把手续费降到一个比较低的级别再跑网格。我见过有人网格参数设得很漂亮结果利润全交了手续费这种事一定要提前算清楚。第三道风控是异常行情。币圈交易所偶尔会出现插针、价格瞬间剧烈波动、甚至断线。VNPY框架里要加一层过滤逻辑比如价格短期内跳动超过阈值就暂停交易等行情稳定后再恢复。这一步看起来简单但没有做的话一次插针就能让你以非常差的价格成交一堆单子。提示网格策略的风控底线是保证自己在最坏的情况下还能活着。参数设计得再漂亮如果风控没做那只是一张好看但一冲就破的纸。3. VNPY环境搭建与网格策略实现3.1 开发环境准备搭建VNPY环境其实没有想象的那么复杂但确实有几个坑。我用的是一台Linux云服务器系统是Ubuntu 20.04配置不需要太高2核4G就够跑了。Python版本建议用3.8到3.10之间太新的版本有时会遇到依赖库还没适配的问题。安装VNPY最省事的方式是直接用pip安装先装一点基础依赖库比如pandas、numpy这些然后安装vnpy再根据你的交易场景安装对应的接口模块。这里要说一句VNPY只是框架真正连接交易所需要安装相应的gateway模块你只需要装上目标交易所对应的模块就行。另外如果你要跑回测还需要把历史数据导入VNPY的数据库它默认支持SQLite数据量大的话也可以换MySQL。跑通环境之后我强烈建议先在模拟盘或者交易所的测试环境里把VNPY自带的一个示例策略跑起来。这一步很多人偷懒跳过直接在实盘上试结果折腾半天发现是行情模块没连上、订单接口权限没开。我的做法是先在测试环境里等VNPY跑出第一笔模拟成交确认行情和交易链路都通了再开始改自己的网格策略。3.2 策略代码实现核心逻辑现在来说网格策略代码怎么写。VNPY的CTA模块提供了一个CtaTemplate基类写网格策略只需要继承它然后实现几个核心方法。下面我给出一个简化但保留关键逻辑的代码框架重点不是让你直接复制就能跑而是理解它的结构。from vnpy_ctastrategy import CtaTemplate, BarData, OrderData, TradeData class GridStrategy(CtaTemplate): author YourName grid_step 0.02 # 网格间距2% upper_price 30000 # 网格上界 lower_price 20000 # 网格下界 volume 0.01 # 每格下单数量根据资金调整 parameters [grid_step, upper_price, lower_price, volume] variables [grid_prices, current_grid_index] def on_init(self): self.grid_prices self.generate_grid_prices() self.write_log(网格策略初始化完成) def generate_grid_prices(self): prices [] price self.lower_price while price self.upper_price: prices.append(round(price, 2)) price * (1 self.grid_step) return prices def on_bar(self, bar: BarData): if not self.grid_prices: return # 处理新K线价格的逻辑判断是否触发买入或卖出 if bar.close_price self.grid_prices[self.current_grid_index] - self.grid_step: self.buy(bar.close_price, self.volume) self.current_grid_index 1 elif bar.close_price self.grid_prices[self.current_grid_index] self.grid_step: self.sell(bar.close_price, self.volume) self.current_grid_index - 1这个骨架看起来简单但实际工程化的时候有好多细节要处理。比如你不能只维护一个current_grid_index因为价格可能在短时间内快速穿越多个格子你需要用一个列表来跟踪哪些格子已经触发了买单哪些触发了卖单。再比如挂单和成交不是一回事VNPY的on_order回调里会告诉你订单状态是已提交、已成交还是已撤销你需要在策略里维护一个活跃委托的映射关系避免重复下单。网格策略在VNPY里实现时还有一个难点就是如何在异常情况下恢复状态。比如程序重启后策略需要知道当前持有哪些币、哪些挂单还活着。我建议在on_init里从交易所查询当前持仓和活跃委托然后重建网格状态。这一步不能省否则重启一次策略就懵一次。3.3 回测与参数优化策略写好后先用VNPY回测引擎跑历史数据。你需要准备一段足够长的历史K线最好包含震荡行情和单边行情这样才能看到策略在不同市场状态下的表现。回测时主要看几个指标总收益率、最大回撤、交易次数、夏普比率。网格策略因为交易频繁交易次数肯定多这不是问题但如果发现最大回撤超过了你的心理承受范围那就要调整参数了。我一般先跑一组默认参数然后做参数扫描把间距、上下界、每格下单量都尝试不同值观察指标变化。比如间距从1%到5%之间收益和回撤的比例关系会有很大变化。有一个特别注意的地方回测结果不能过度优化。你很容易在历史数据上找到一个特别完美的参数组合但它往往只是完美拟合了历史行情对未来行情没有预测力。我习惯把历史数据分成几段一段做参数选择另一段做样本外验证。如果样本外表现也说得过去才敢把参数用于实盘。另外币圈交易手续费和滑点在回测里一定要计进去否则回测出来的收益会虚高实盘一跑就缩水。4. 实盘部署与日常运维实录4.1 从模拟盘到小资金实盘的过渡代码写好、回测也过了接下来就是实盘了。我强烈建议先走一遍模拟盘别直接拿真金白银试错。模拟盘虽然不能完全模拟出真实市场的滑点和深度但至少能验证你的代码在连续行情下能不能稳定运行会不会出现报错、断线、重复下单这些低级问题。模拟盘跑个三到五天确认没有问题之后再用一个小资金账户上实盘。我第一次就跑了个很小的资金量纯粹是为了验证交易所API的连接、订单的成交速度、以及VNPY在实盘环境下的稳定性。这里有个很容易踩的坑模拟盘和实盘的API可能是两套地址你需要确认VNPY连接的是实盘地址别把策略跑在模拟盘上还以为是实盘成交。实盘运行的头几天我建议每天至少看一次持仓和挂单把自己的手工记录和策略记录对比一下。如果发现策略的实际仓位和预期不一致多半是订单部分成交、撤单失败或者状态恢复逻辑有Bug这些问题越早发现代价越小。等小资金跑了两周左右确认各方面都正常再逐步增加资金。4.2 常见问题与排查技巧实盘跑起来之后问题会一件一件跑出来。我把自己踩过的几个高频问题整理成表每个都给了排查思路。问题现象可能原因排查思路策略没有触发任何交易行情数据断流或价格没有越过网格阈值检查VNPY行情模块的连接状态看是否收到最新行情Tick订单一直显示已提交但没成交价格快速穿过挂单价格滑点太大或下单量超过盘口深度查看订单状态必要时撤单后以当前市价重新下单仓位和网格状态错位程序重启后没有正确恢复持仓和活跃委托检查on_init里的恢复逻辑手动校正持仓和挂单策略报错退出数据格式异常、网络超时、API限频查看日志把异常处理加进策略主循环必要时加入自动重启脚本收益远低于回测手续费、滑点、资金费率没有在回测中计入核查实际交易成本重新调整手续费参数并重跑回测还有一个特别值得说的坑网络断线。币圈是7x24小时交易你的服务器网络不可能永远不掉线。网络一断行情收不到订单也不知道成没成交重新连接之后状态很难同步。我的做法是在服务器上部署一个守护进程定期检查VNPY是否还在运行同时VNPY内部还要处理断线重连重连成功后重新拉取一次持仓和挂单。这样能保证策略在断线后还能自动恢复不至于一夜之间乱套。4.3 日常运维清单很多人以为策略跑起来就可以放着不管了事实恰恰相反网格策略最需要定期检查和维护。我给自己定了一个简单的运维清单可以给你参考每天需要做的事包括检查策略进程是否正常、当前挂单数量和持仓是否合理、账户资金是否出现了异常变化。不需要天天看盘但至少确认没有报警信息。每周做一次复盘的维度要多一些本周触发了几次网格交易、收益和回撤是多少、实际收益和回测预期的差距有多大。如果连续一周都没有触发交易那说明当前价格处在网格区间的边缘你需要评估一下设定的上界和下界是不是该调整了。遇到极端行情时要主动干预。比如价格快速跌破下界网格策略还在按部就班地买入这时候我一般会先暂停策略等待行情稳定后重新评估。手动干预的关键是要提前想好规则不要临时起意。比如提前设好一个策略熔断价跌到那个价就自动挂起避免因为犹豫导致亏损扩大。注意网格策略的日常运维核心不是预测行情而是保证策略在约定规则内稳定执行。任何计划之外的手动操作都可能破坏网格的状态一致性这是实盘中最常见的人为风险。5. 实盘中的几个进阶心得5.1 多币种网格与资金分配网格策略不一定只做一个币种做两三个相关性较低的币种可以起到分散风险的效果。比如你选一个主流币和一个平台币它们的节奏往往不太一样当一个币种进入单边行情时另一个可能还在震荡这样可以平滑整体收益曲线。但多币种网格对资金的要求更高因为每个币种都要准备一套独立的下单资金。我的做法是把总资金按比例分配到每个币种不要让一个币种占用过多仓位。比如10000 USDT总资金做两个币种每个币种分5000 USDT而每个币种内部再按我之前说的50%布单比例来操作。这样做的好处是即使一个币种崩了另一个币种还在正常运作整体账户不会因为单一币种的黑天鹅而全军覆没。5.2 网格策略的运行稳定性加固VNPY框架本身是稳的但你自己的代码和服务器的稳定性会决定策略的长期表现。我后来给自己的网格策略加了一个简单的状态监控页面用Flask起一个小服务显示当前策略的持仓、挂单数、最近成交记录和今日盈亏。这样我不用每次登服务器去翻日志直接从网页上看一眼就知道策略是否健康。程序崩溃自动恢复这件事也值得做。我写了一个守护脚本每隔几十秒检查一下VNPY进程是否还活着如果挂了就自动拉起来。但自动拉起来之前必须确保数据库连接正常、策略状态能恢复否则还不如让它停下来等人来处理。这里有个度的问题宁可少交易也不要因为自动重启导致状态混乱和重复下单。5.3 网格策略的扩展方向网格策略本身赚的是波动差价天然适合币圈这种波动大的市场。如果你跑熟了基础网格后面可以试着加一层动态调整逻辑当K线形态进入趋势状态时自动缩小网格间距或者暂停反向加仓当趋势结束时再恢复到正常网格。甚至可以把网格和均线过滤结合只在价格位于某条均线上方时跑多头网格。我自己试过一个比较简单的方式用VNPY自带的定时任务接口每天收盘后重新计算一次网格区间如果发现价格重心明显移动就动态更新上界和下界。这种半动态网格虽然不能抓住所有行情但能有效降低网格一直挂在已经远离价格区间的尴尬。提示网格策略的扩展空间其实很大但方向是让它更贴近行情节奏而不是让它更复杂。加每一条逻辑都要确保自己清楚为什么加并经过回测验证。6. 网格实盘这件事我的体会网格策略在币圈跑了这么久我最大的感受是它不是一个能让你一夜暴富的策略而是一个能在震荡行情里稳定赚钱的策略。它最怕的是趋势行情最怕的是没有风控也最怕的是人乱操作。VNPY这种开源框架给了我们很大的自由度和可维护性但工具始终是工具真正决定策略生死的还是对参数的敬畏和对风控的执行。如果你现在正准备自己写一套网格策略我的建议是先用小资金、长周期、极简参数跑起来把整个链路跑顺了再谈优化。别一上来就想做动态网格或者多品种并行先把基础版本做到一年半载不崩盘那时候你自然知道下一步该怎么改。最后分享一个我自己的小习惯每个月末把策略的完整交易记录导出来筛一遍异常成交和连续亏损的时段看看是不是有某个网格逻辑在特定行情下总是吃亏。这种复盘看着简单但对策略长期迭代的价值比多看几篇技术文章大得多。