ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

不靠QMT,聚宽策略小资金自动下单的完整方案

不靠QMT,聚宽策略小资金自动下单的完整方案 做量化的人应该都有过这种体验策略在聚宽上回测曲线漂亮得很年化、回撤、胜率怎么看怎么顺眼可真到了准备实盘那一关整个人就卡住了——券商那边要你开通QMT一问资金门槛心凉半截再一看终端环境配置又是一堆破事。我当初就为这事纠结了很久后来干脆换了一条路不碰QMT照样用聚宽跑策略小资金自动下单。这套方案我跑了快一年稳定性和省心程度都超出预期今天把它完整拆开讲。先说清楚这套方案适合谁主要面向已经在聚宽上写好策略、资金量在几十万以内、不想去凑券商资产门槛的散户朋友。你不一定需要多高深的编程能力但至少能用Python写简单脚本。整条链路的核心思路就一句话聚宽只负责算信号本地跑一个执行器负责下单二者之间用最普通的HTTP请求或者消息推送对接绕开券商对QMT的种种限制。1. 先想清楚为什么非要从QMT这条路绕开1.1 QMT不是不好是门槛实在不友好QMT的全称是迅投极速策略交易系统功能确实强支持Python策略、实盘交易、Level-2行情这些硬需求很多机构和个人大户都在用。但对小资金用户来说它最大的问题就是开通条件。我接触过几家券商的客户经理口径大同小异有的要求账户资产连续20个交易日不低于50万有的要求30万外加一定的交易经验有的虽然资金门槛能谈但会要求你不定期保持一定的交易频率。你算一笔账就明白假如你账户里只有5万块连门槛的零头都不够这条路基本走不通。还有些券商的QMT通道要单独申请、单独审核审核周期短则两三天长则一两周。等你把流程跑完策略也许早就不想做了。这种挫败感经历过的人都懂——明明技术方案已经闭环了最后卡在开户审核和资金门槛上太不值。1.2 QMT本身也有让人头疼的毛病就算资金量达标QMT也未必省心。它不是一个开箱即用的东西对运行环境有要求需要Windows系统、需要安装特定版本的Python环境、需要处理一堆依赖库的兼容问题。网上搜QMT相关内容十个帖子里面有八个是在问“环境依赖怎么装”“客户端client is null怎么办”“终端连不上”。这里面的坑我帮你们踩过一部分QMT带了Python但版本往往偏老装第三方库容易遇到编译问题客户端要登录、要更新数据有些券商的版本还时不时抽风登录态失效、连接断掉你根本不敢把自动交易的生死完全交给这样一套环境。这些现实问题叠加起来让我下决心小资金就没必要硬往QMT上挤换一条轻量路径可能更舒服。2. 整体信号链路聚宽只做大脑本地做手脚2.1 三层架构信号生成、传输、执行不依赖QMT的自动化交易本质上就是一个更直白的三层结构第一层聚宽平台。你的策略在这里运行负责计算每日目标持仓、输出交易信号。它不需要直接下单所以不涉及任何券商接口。第二层信号传输通道。聚宽把信号推送到本地最常见的方式是HTTP回调、消息推送机器人或者邮件轮询。第三层本地执行器。一台常年开机的电脑或者云服务器定时接收信号和当前真实持仓对比计算出要买什么、卖什么、各多少股然后调起下单接口。整个架构里最复杂的是第三层但它的复杂度和QMT那套相比已经小太多了你要面对的题目不是庞大厚重的交易终端而是你自己完全可控的几百行Python代码。2.2 聚宽侧信号推送的具体做法聚宽这边最简单的做法是利用它的模拟交易功能或者定时运行的研究任务把策略的目标持仓通过一个HTTP请求推到本地。比如你的策略持仓里有三只股票每天收盘后模拟盘会刷新持仓。这时候在聚宽的代码里加一段推送逻辑把目标持仓、日期、信号ID这些信息打包成JSON发到本地服务端口。# 聚宽模拟盘/定时任务中示意代码具体接口以聚宽官方文档为准 import requests import json def after_trading_end(context): targets get_target_position(context) signal { signal_id: str(context.current_dt.date()), date: str(context.current_dt.date()), targets: targets } try: requests.post( http://你的本地地址:8000/signal, jsonsignal, timeout10 ) except Exception as e: log.warn(信号推送失败: %s, e)推送通道具体用什么我建议按稳定性和开发成本排序推送方式稳定性实现成本说明HTTP回调到本地/云服务器高低需要本地暴露端口或使用云服务器中转企业微信/钉钉群机器人高极低免费、有重试机制本地轮询机器人消息即可邮件轮询中极低有延迟但最简单适合盘后低频策略聚宽本身的邮件/微信通知中最低只适合人工提醒不适合自动触发下单我个人实际跑下来最喜欢的是HTTP回调因为它能让本地执行器立刻感知新信号还方便调试。如果你不想暴露家里IP也可以在一台便宜的云服务器上部署一个只有几十行的消息中转服务聚宽推给云服务器本地再从云服务器拉取中间不会暴露内网端口更安全。3. 本地执行器的核心代码从目标信号到真实订单3.1 主循环与状态处理流程本地执行器是整个方案里唯一真正碰钱的程序所以它的设计核心不是“能下单”而是“不瞎下单、不乱重复下单”。我的主循环写得很朴素但每一步都在防问题import time import requests import sqlite3 def main_loop(): while True: signal fetch_latest_signal() if signal and not is_duplicate(signal[signal_id]): targets signal[targets] positions get_current_positions() orders build_orders(targets, positions) for order in orders: submit_order(order) mark_processed(signal[signal_id]) time.sleep(60)这段代码看着简单实际背后有几个值得注意的设计点。第一点是signal_id。这个字段必须能唯一标识一条信号我用的是日期加策略编号的组合。收到信号后先查数据库如果这个信号ID已经处理过直接忽略——这是防止重复下单最重要的一道防线。第二点是build_orders。它把“目标持仓”变成“具体交易动作”。比如你的目标持仓是“某某股票占比20%”就需要结合当前真实持仓和账户可用资金算出来到底要买多少股、卖多少股。这个函数不能出错否则要么资金不够要么买成超仓。第三点是所有委托记录都落库。我用的是SQLite轻量还不用装服务。每次收到信号、每次下单、每次委托失败都写一条日志出问题的时候回查非常方便。3.2 下单通道怎么选不通过QMT下单通道主要有这么几个选择券商自带的普通交易客户端配套自动化库比如通过pywinauto、pyautogui模拟界面操作稳健性一般但胜在门槛低。开源项目如easytrader通过对同花顺、券商客户端做底层操作实现自动交易社区用的人多。部分券商提供的简版API直接HTTP请求下单但需要你逐一确认自己开户的券商是否有这类通道。你可能会问我用哪种。我的建议是先用模拟交易或自己写一个模拟盘接口验证整个执行器逻辑再考虑接真实券商通道。真实通道不管选哪种都存在一个共性风险——券商客户端升级可能导致脚本失效所以放量实盘前一定要留出观察期。3.3 仓位和股数计算逻辑计算下单数量是整个执行器里最容易出错的地方因为股票交易有每手100股的约束而目标持仓比例往往是百分比不是一个整数。每次都要算清楚def calc_order_quantity(share, target_value, price, cash_available): desired_quantity int(target_value / price / 100) * 100 current_quantity share if share else 0 diff desired_quantity - current_quantity if diff 0: need_cash diff * price if need_cash cash_available: # 资金不足时只买能买得起的整手数 diff int(cash_available / price / 100) * 100 return diff这里有几个细节不能漏A股买入必须整手卖出时可以卖出零股但最好也整手处理计算买入量的价格要用现价估实际成交价可能更高所以最好留出2%到3%的资金缓冲否则容易下单后可用资金不足被券商拒单。我刚开始跑的时候吃过这个亏按市价刚好够买100股结果下一瞬间价格跳了一分钱委托就失败了。4. 聚宽与本地的一致性处理成败都在细节4.1 历史数据与复权方式必须对齐如果聚宽模拟盘负责生成信号本地只做执行那么信号本身的可信度就锚定在聚宽的数据上。聚宽默认用的前复权价格、真实价格和你本地下单所看到的行情价格可能不完全一致。这并不是平台的问题而是复权因子、数据供应商的差异造成的。这个问题在日频策略上影响相对有限但如果你做的是突破类、价格敏感类策略就要额外小心。我的建议是让聚宽计算信号时优先使用“不复权”价格或者模型里避开对绝对价位的依赖否则你很容易发现策略在模拟盘信号正常到了实盘却因为价位对不上而错过买入点。4.2 执行时点的选择很多聚宽策略是收盘后或者第二天开盘前才刷新信号。如果你等信号推送完再开始下单往往已经过了最佳时间窗口。这里有个经典矛盾信号越早拿到执行越接近预期但前提是你的策略不依赖盘中实时数据。我目前的方案分两种策略处理日频策略当天收盘后用当天的日线数据和收盘指标计算次日目标持仓。盘后信号推送完毕本地在第二天集合竞价阶段或开盘前几分钟按计划下单。分钟级策略不建议完全走这套轻量链路因为延迟太大。如果你确实做分钟级至少要保证本地服务器位于离券商通道近的机房并且信号推送链路使用云服务器中转否则一个轮询周期就是几十秒策略早就失效了。4.3 模拟盘成交与实盘成交的偏差容错聚宽模拟盘成交假设比较理想比如按收盘价、开盘价成交不考虑滑点。但真实实盘里流动性不足的股票、大盘开盘瞬间的波动都会让成交价和信号计算价差出不少。小资金尤其明显你总共买个几千块滑点可能吃掉小半个点。我的做法是在执行器里设置一个成交价容忍度如果预计成交价和信号价格偏离超过1.5%暂时不追单记录到告警日志等下一次信号刷新再处理。宁可错过一次交易也不要在情绪化价格下成交。这个参数我后来调宽到2%因为A股振幅本身不小卡太死会导致很多委托白白废掉。5. 小资金实盘最常踩的五个坑5.1 最小交易单位与资金碎片的矛盾这是小资金实盘最现实的问题。比如账户里总资产5万一个信号告诉你“买20%仓位”算出来是一万块按理能买几百股某只价格20多的股票但当你持仓里有十只股票时每一只都可能因为整手限制剩下几十股的零头这些零头既卖不掉又不值钱逐渐拖累资金利用率。解决办法有两个一是坚持“目标持仓数量不要贪多”小资金控制在3到5只以内二是在执行器里加资金碎片整理逻辑定期把持仓市值不足一手的股票一次性清掉把资金集中到核心标的上。5.2 停牌和涨跌停的委托失败处理策略信号是静态的但市场是动态的。目标持仓里有股票停牌或者正好一字涨停买不进、一字跌停卖不出这种情况非常常见。执行器如果不知道停牌状态就会反复提交委托下单然后反复被拒。我现在维护了一份“可交易状态表”每日开盘前用行情接口拉取所有持仓和候选股票的停牌状态停牌日在执行器里直接跳过对于涨跌停设定“只尝试失败一次即放弃”的规则不做无意义重试。这样虽然可能错过某些回归的机会但至少程序不会陷入死循环里浪费资源。5.3 重复执行、重试风暴与幂等防护自动化程序最怕一个场景行情接口临时超时信号拉取请求被打回然后本地程序误以为没收到信号下一次循环又重新下单一遍。这种重复下单在半自动场景下还不致命但在全自动模式下就可能造成超额买入、严重超仓。幂等设计我前面提过一次这里再强调一层所有涉及钱的接口调用都必须有唯一请求号并且执行器要能够通过查询状态决定自己是否已经处理过该信号。我在SQLite里建了一张signal_record表记录每个signal_id对应的订单编号哪怕程序重启、网络抖动都不会重复执行。5.4 环境故障死机、断网、掉线你可能觉得程序写对了就万事大吉但实际上跑自动化交易最不停歇的敌人是环境问题。我有一次出差云服务器上的执行器因为内存不足崩了第二天早上才发现它已经停了好几个小时那天的信号完全没执行。后来我做了三层保障第一用systemd或者supervisor管理执行器进程崩了自动拉起第二加一个看门狗脚本每隔20分钟检查一次最新信号的处理时间如果超时没有新信号或没有新委托记录就给自己推送一条告警第三凡是涉及跨天运行的任务每天凌晨定时重启一次进程清掉无效连接。这些保障看起来笨但真的能救命。5.5 费用与滑点对小资金的实际影响做回测时很多人不会太在意手续费和滑点但小资金实盘会被这些成本咬得很疼。以万2.5佣金加卖出万10印花税来算一个来回大约千分之1.5到2的成本加上买卖各几毛钱的滑点你的策略年化如果只有10%扣完成本可能只剩六七个点再遇上几次失败委托、追价单收益会更薄。我的建议是实盘前先在回测里强行加上双边千分之2的成本模型看策略还能不能活。如果一个策略在这么苛刻的成本假设下依然能赚钱才值得拿出来跑实盘。6. 我的分阶段落地节奏与维护清单6.1 第一阶段聚宽模拟盘加本地影子执行我推荐你第一周不要碰真钱。先把聚宽模拟盘信号推送写好本地执行器全部接一个“模拟交易接口”也就是只在SQLite里记录“假如我下单了会买什么、买多少、成本多少”不实际发送任何委托。这一阶段主要验证信号链路通不通、执行器算得对不对、日志全不全。你可以人为制造一些极端情况来测试比如把信号故意设成重复推送两次观察执行器是否只处理一次比如故意断网一次重启后再看数据库里的状态是否正确。所有反馈正常再进入第二阶段。6.2 第二阶段最小资金试跑与滑点统计第二阶段我放了一万块钱进去只执行一到两只股票的策略。这时候你要特别关注三组数据理想成交价与实际成交价的差、实际执行耗时、以及执行器在开盘高峰期的稳定性。这一阶段不再写新功能只看它的表现。持续运行两三周把每天的滑点记录下来如果平均滑点超过预期就要回头检查下单时点或者下单通道的延迟。当初我跑出来的数据给自己提了个醒开盘前几分钟委托会被券商排得很久原本预期开盘价附近成交实际滑点常常到了1%以上。后来我调整成开盘15分钟后才开始下单虽然信号时效性略降但执行质量明显提升。6.3 第三阶段放量后的日常维护清单第二阶段跑顺之后你就可以根据自己实际情况逐步放大资金量。不过放量不代表放任不管我给自己列了个简单的维护清单每天收盘后看一眼信号推送是否成功、委托记录是否完整。每周做一次SQLite备份日志定期清理防止磁盘占满。每月对比一次聚宽模拟盘净值与真实账户净值的偏差如果偏差持续放大说明执行环节出了问题。每次券商客户端升级后先跑一天模拟交易再恢复实盘。这套方案跑下来我的感受是它不一定适合所有人但对“资金量小、策略逻辑不复杂、想要自动化却不想被QMT绑死”的人而言它提供了另外一条完全可行的路。你不需要为了开通一个工具去凑资金门槛也不用忍受复杂客户端的各种环境问题只要把聚宽和本地执行器之间这条链路做稳了小资金一样可以做到自动化交易。最后再分享一个小技巧本地执行器除了处理信号之外我还会把它接到一个简单的Web页面上每天显示“当前目标持仓、实际持仓、最近一轮交易记录”。哪怕你在外面用手机看一眼心里也踏实得多。自动化交易最重要的不是每天紧张盯盘而是当它出问题的时候你能第一时间知道。
返回列表