我做交易大概有四五年时间,真正决定把策略从手动搬到程序化,是在某个连续止损的周。那个周我用人为判断反复修改参数,结果越改越差,倒不是行情有多难做,而是执行纪律崩了。后来我开始搭建THS量化交易系统,最初的诉求很单纯:让策略按规则执行,不掺情绪,同时风控能够自动化拦住大回撤。如果你也在纠结要不要上量化、该从哪一步开始,这篇内容大概能给你一个相对完整的路径参考,包括架构拆解、回测陷阱、实盘稳定性和那些没人写在文档里的经验。
1. THS量化系统的整体定位:它解决的实际问题
1.1 手工交易的三个死穴,量化恰好对症
手工交易里最常见的三个问题,第一是执行不一致。明明定好了止损位,价格扫一下又反弹,你想着再扛一扛,结果真跌下去之后心态彻底崩了,止损就在偏离原计划很远的位置成交,单笔亏损直接放大。第二是情绪干扰,连续盈利之后容易自信过头,仓位越下越重;连续亏损之后又容易畏手畏脚,该进场的信号不敢进,白白错过行情。第三是复盘困难,你无法精确知道每一笔决策当时是基于什么逻辑,因为你当时的心理状态是变量,这就导致策略迭代没有数据基础。
量化交易解决的核心不是预测更准,而是把交易过程拆解成确定性可复现的规则,让每一笔入场、出场、仓位大小都可以被代码精确描述,并且可以被回测验证。THS作为一种实践性的量化框架,它强调的事情恰好是这几件事:明确信号定义、明确风控边界、明确执行流程。它不一定比顶尖的私募策略更聪明,但它能做到的是让你不再凭感觉下注,每一笔操作都有据可查。
1.2 THS适合谁,以及它的一套取舍
首先要说清楚,THS量化交易不是某个现成软件,而是一整套我组织策略和程序化执行的思路。它尤其适合那些有一定手工交易经验,想往程序化转型的人,因为这类人通常已经有交易逻辑,只是不知道怎么把逻辑变成代码、变成系统。完全没接触过交易的纯新手,我更建议先拿模拟盘跑三个月,同时按这套体系逐步完成策略的代码化和验证,而不是直接投入真金白银。
THS在设计上有一个区别于其他量化框架的取舍:它不那么追求单笔胜率,而是把精力放在交易的数学期望上。哪怕单笔成功率只有四成,只要盈亏比超过2.5,这套系统长期来看就是正期望的。因此THS的策略侧会刻意做交易过滤和资金管理,而不会去追求什么信号全自动全捕捉。做交易的人应该都有体会,不是每一段行情你都能做,不漏掉机会本身就是一种贪婪,这种贪婪在量化里一样会导致过度拟合和频繁交易。THS的取舍就是允许错过,只做符合策略定义的高确定性行情。
2. 一套完整实盘框架的模块拆解:从行情到风控
2.1 行情数据的获取、清洗与对齐
做回测和实盘的第一个门槛往往不是策略本身,而是数据。很多人下载了历史K线就直接开始写策略逻辑,结果回测结果亮眼,实盘却没跑出那个效果,第一个问题大概率就出在数据对齐上。举例来说,你的数据源可能在不同时段存在复权差异,前复权和后复权算出来的历史趋势不同;又比如分钟线的截面数据如果包含部分延迟行情,你的回测信号会包含未来信息,这个隐患非常致命。
我在THS的数据层里做了这样几件事。第一,统一数据落地格式,全部存成本地列式存储,字段包含时间、开盘价、最高价、最低价、收盘价、成交量、成交额,如果涉及合约展期,额外记录相邻合约的切换时间。第二,做时序对齐校验,检查时间戳是否连续、是否存在跳变,特别是跨交易所的品种,节假日不同会直接让对齐出问题。第三,做前复权处理时保留原始价格,同时建立复权因子,方便策略在需要时切换口径。一个合格的数据层至少要能通过一个简单测试:随机抽取出任意一百根K线,逐根用现价验证复权逻辑是否一致。
2.2 策略层:因子、信号与执行器之间的边界
THS的策略层严格区分三个概念:因子、信号和执行器。
因子是底层的数据特征,比如过去N根K线的收益率波动率、均线偏离度、成交量的相对变化量。回测阶段你可以生成几十上百个因子,但在实盘阶段THS建议只保留相关性低、逻辑解释清晰的少数因子,避免多重共线性对结果稳定性的影响。
信号层负责把因子组合成可执行的交易指令,它会输出目标仓位而非直接下单,这是THS一个值得推荐的设计思路。比如一个顺势策略算出当前应该持有40%仓位,它并不会把40%直接发给执行器,而是先判断当前实际持仓是否超过偏差阈值,如果持仓偏差在允许范围内,就不产生调仓指令。这个机制能显著降低不必要的交易频率,减少手续费磨损。
执行器最核心的任务是保证下单的原子性。一个常见的问题是网络抖动导致下单超时,但单子实际已经发到交易所了,这就会造成重复下单。THS执行器会为每一笔委托生成唯一客户端订单号,并在下单后持续查询订单状态,如果查询不到结果则启动对账流程,而不是盲目重发。这个细节我在早期版本里吃过亏,重复下单一次可能就是几千块的额外损失,处理不好非常影响账户整体表现。
2.3 风控层:整个系统里不能打折扣的部分
没有风控的量化系统等于裸奔。THS的风控层设置了三个层级。
第一层是账户级熔断,当日累计亏损超过总权益的2%,系统自动停止新开仓,已有持仓保留但设一个更紧的止损阈值。这里强调的是绝对回撤,而不是相对于收益率回撤,因为绝对回撤才能直接反映风险偏好。
第二层是策略级的风控,单策略最大持仓比例不能超过设定值,通常是总权益的20%-30%,这样即便策略失效,损失也被控制在一个相对可控的范围内。并且同一个方向的多个策略合计持仓不得超过总权益的50%,防止所有策略实际上在同一个风险因子下持仓,让看似分散的投资组合在真正大跌时同向共振,这种风险在跨策略配置中非常容易被忽视。
第三层是执行级风控,主要处理滑点和流动性问题。下单前执行器会检查当前盘口的挂单量和预估滑点,如果滑点超过单笔止损的某个比率,就拒绝本次下单。这听起来让系统显得有些保守,但这正是THS能活过极端行情的原因。遇到重大行情甚至可以直接触发暂停交易的开关,等人工介入确认后再恢复执行。
2.4 账户与资金管理的数学基础
资金管理的核心公式是凯利公式的改良版本,但实际应用中我会避免直接使用原始凯利,因为它基于单次下注的胜率和赔率,当这两个估计不够准确时,凯利给出的仓位往往过于激进。THS采用的方法是半凯利,也就是把凯利算出的最优仓位减半使用,再叠加一个总仓位上限,最大单策略不超过总权益的20%。
举例来说,某策略的胜率是0.45,盈亏比是2.0,原始凯利算下来f=(bp-q)/b,其中b为赔率2.0,p为胜率0.45,q为失败概率0.55,结果f=(2*0.45-0.55)/2=0.175,也就是17.5%的总资金仓位。如果直接采用这个比例,在胜率出现偏差的连续亏损段很容易爆仓;采用半凯利把仓位压到8.75%,再叠加策略上限20%,实际执行的仓位就是8.75%。这个数字看起来保守,但它在让账户经历过连续十次亏损之后依然有充足的子弹重新入场。
我还会用每日波动率对仓位做一次缩放。如果最近20日年化波动率偏高,即便策略给出较高的目标仓位,执行器也会自动把实际仓位调低,让单日波动不超过总权益的1%。这个波动率缩放机制特别适合股票和数字资产这类波动差异巨大的标的,可以有效避免因为某段时间行情过于剧烈导致账户权益大起大落。
3. 回测与数据对齐中的几个容易让人掉坑的地方
3.1 未来函数和幸存者偏差
回测结果虚高的原因,未来函数和幸存者偏差要排在前两位。未来函数指的是策略在计算当前信号时使用了未来行情数据,比如在选股回测中以当天的收盘价计算信号,却用第二天的收益率来排序,逻辑上听起来像是正常操作,但在实际操作中你当天收盘前根本拿不到全天收盘价,这本质上就是未来数据。
THS在回测引擎中会做一次内存隔离,保证任何特征计算迭代到第T根K线时,只能访问到T及之前的数据。我的一个习惯是在正式回测前跑一遍随机信号测试:把信号全部随机化,如果回测结果仍然是正收益,那说明策略本身没问题,问题出在回测程序对数据的访问上;如果随机信号回测竟然是负收益,那恰好也说明策略的收益来源是真实的,因为负收益意味着策略确实透支了未来信息或承担了某种风险补偿。
幸存者偏差主要出现在股票和多品种回测中。样本池如果只保留了现在还在市场上交易的品种,就会漏掉很多已经退市的劣质标的,历史回测结果自然偏高。THS在构建回测样本池时会做事件回溯,把当时处于可交易状态的品种全部纳入,哪怕它后来已经退市。
3.2 手续费、滑点和涨跌停约束的真实影响
很多人在回测时只按照一个固定手续费率去计算成本,然后看到交易频率高、但整体收益仍然可观就以为策略可行。实际上手续费只是成本的一部分,滑点才是更隐蔽的损耗源,特别是对于成交不活跃的品种,一进场就可能产生几个tick的滑点,高频策略更是会被滑点直接消磨殆尽。
THS在成本模型里默认引入两个与行情相关的滑点估计参数。一个是最小滑点,固定设为一个tick,比如期货品种一个最小变动价位是1个点,那么最小滑点就是1个点;另一个是波动率相关滑点,按照最近20根K线的平均振幅乘以一个系数作为上限。这样处理之后,每一次模拟成交的成本都高于实际平均水平,做出来的回测结果会偏保守,但更接近真实。
涨跌停约束是另一个隐藏问题。当品种涨停时,你无法以涨停价买入,只能等待下一根K线,而且很难保证能成交。THS会让回测引擎在信号触发当天检查是否已经处于一字板状态,如果处于涨停且你试图买入,本次信号直接作废,而不是按涨停价成交,避免回测数据里出现一批实际上买不进的虚假盈利单。
3.3 验证策略稳定性该看的几个指标
看回测报告时,收益率和最大回撤只是第一步账面数据,真正决定你是否敢上实盘的是参数稳定性。THS推荐的检查方法是参数平原分析:固定其他参数不变,把核心参数在合理范围内逐渐增加或减少,观察收益率的曲面是否平滑。如果核心参数从10变动到11时收益大幅增长,从11变动到12又大幅下滑,说明这组参数对被使用数据过度拟合,实盘大概率不稳定。反过来,如果参数在某个区间增减,收益虽然有变化但趋势是平缓的,整体呈平滑的峰型,策略才更值得信赖。
此外还要关注收益曲线的时间稳定性。把回测区间切成两段,前半段和后半段分别回测,如果收益来源高度集中在前半段,后半段基本不赚钱,说明策略已经失效或者只适用特定市场环境,这时候要特别小心,市场和交易标的可能已经悄悄变了运行规律。我通常还会带着策略跑一段成本翻倍测试,把手续费和滑点都翻倍,观察策略是否仍然为正收益,如果翻倍后收益已经转负,那说明该策略对交易成本极度敏感,在真实环境下会很难盈利。
4. 实盘运行中最容易忽视的稳定性问题
4.1 进程守护、断线重连与幂等性
回测环境是理想化的,程序不会崩溃、网络不会中断、交易所不会拒绝请求,但实盘环境什么都会发生,我在THS运行期间遇到过不少次半夜数据中断、早上发现策略完全停止交易的情况。如果遇到极端行情而程序恰好出于停机状态,确实会错过关键的止损时机,这个问题值得认真对待。
进程守护是第一层的保底措施。THS在单独的进程管理器上挂载了交易主进程和风控进程,一旦心跳检测超过30秒没有回应,管理器自动重启对应进程,同时通过告警通道通知我。除了进程守护,数据断线重连也必须有完善的退避重试机制。第一次重连等待3秒,第二次等待8秒,第三次等待20秒,之后每次递增但封顶在5分钟,避免高频重连把交易所的API网关拖垮导致被封IP。我加入这个机制之前遇到过连续重连触发了风控警告,所以算是被现实教育过之后补上的课。
幂等性对于实盘下单模块来说至关重要。每次下单都携带客户端生成的唯一订单号,如果因为网络超时没有收到交易所返回结果,程序不会直接撤销重下,而是先主动查询这笔订单的最终状态。如果查询结果是已成交,就更新本地持仓,不对用户界面发起重复委托;如果查询结果是未成交,才决定是撤销还是重新提交。这个流程能够从根本上杜绝重复下单事件。
4.2 系统时钟、时区与和交易所的同步
交易系统里时钟不同步是一个极其致命的问题。你本机的系统时间慢了两秒,而策略对信号的判断基于本地时间戳,那么在快行情下你觉得信号条件满足了,就立刻发出委托,实际上交易所那边的行情已经越过目标价格。THS在每个交易日开盘前都会同步一次系统时间,而且不仅是和标准时间同步,还要和交易中心的时间窗口对齐。有些交易所会有专门的行情时间戳字段,策略层在判断信号时优先以行情时间戳为准,本地时间只用于日志记录和运维管理,彻底切断本地时钟对信号判断的影响。
还有夏令时和跨时区交易的品种,如果你交易的是跨时区品种,时区切换直接决定K线是否完整。THS在配置里把所有品种的交易时段统一定义为标准UTC时间,由数据层负责做时区换算,策略层永远只处理标准时间,这样能避免因为时区混乱导致K线数据少算一段或多算一段。
4.3 实盘状态下需要关注的关键运行指标
实盘和回测还有一个显著区别是回测系统不会告诉你策略运行状态是否正常,你也不会在回测报告里看到延迟过高、订单丢弃、内存泄漏这些问题。THS运行监控看板会持续采集三个最关键的实时指标:行情延迟、委托成功率和持仓偏差。
行情延迟指的是从交易所发布行情到本地策略取到数据的时间差,当延迟显著高于历史均值,策略的信号质量就会劣化,因为它基于的是陈旧报价,这种时候我会主动降低自动交易的频率或者直接暂停策略。委托成功率则是所有已提交委托中被交易所正常接收的比例,如果这个比例低于99%,说明网络链路或API调用存在问题,需要立刻排查。持仓偏差衡量的是策略理论持仓和实际成交持仓之间的差距,差距产生可能是因为滑点导致的部分成交,也可能是订单丢失,正常情况下这个偏差应该在可接受范围内,一旦明显超出,说明执行环节出了问题,我会把系统切换为只记录不下单的模式,定位清楚原因再恢复。
5. 对“黑嘴”式策略和流动性陷阱的识别
5.1 什么是“黑嘴”式策略及其表现
“黑嘴”这个词原本指那些利用信息优势或粉丝信任进行市场操纵的行为,但我在这里想说的是策略层面的一种设计误区。有些策略在设计时无意识依赖了某些具有自反馈性质的信号,它们看起来逻辑成立,实际上却是在搭便车,依赖市场本身已经出现的单边走势去强化判断,本质上是在追涨杀跌,而没有任何独立于价格走势的核心逻辑。
比如一个策略仅仅基于过去一分钟上涨速度来决定是否追入,在行情好的时候确实能赚钱,一旦行情反转,这种策略的回撤会特别快,因为它的所有因子都在同向推动同一个判断,完全没有风险对冲的概念。THS在构建策略时会做因子逻辑审计,要求每个因子的候选逻辑必须能独立解释一个市场行为,比如布林带收敛之后通常伴随波动率放大,这种解释是市场结构层面的;而“价格上涨所以我买入”这种解释则是循环论证,必须被剔除。
5.2 流动性和盘口深度给策略设的隐形天花板
策略收益的可持续性严重依赖标的的流动性水平。回测中你觉得一个品种每天成交额足够大,可以容纳你的资金体量,但实盘下单时盘口的挂单量可能只有回测假设的十分之一,一个大单砸进去价格直接跳空,滑点远超预期。THS在实盘前会对每个交易品种计算一个资金容量上限,公式简化为日均成交额乘以流动系数,流动系数根据盘中挂单深度取0.05到0.15的低值,结果作为该品种的最大参与资金。如果账户权益超过这个资金容量,要么降低仓位,要么换到流动性更好的品种和合约上。
在挂单深度不足的品种上还容易遇到一个变种陷阱,就是钓鱼单。盘口出现相当厚度的大额挂单,看着让人觉得流动性不错,结果等你的委托进入市场,那层挂单立刻被撤掉,你的单子瞬间穿过多个价位成交,造成远高于常规的滑点。THS执行器默认只使用限价单并且设置可成交的偏离范围,超过偏离范围就撤销等待,不给这类异常盘口留可乘之机。
5.3 从系统设计上规避自我归因和黑箱化
做量化的人很容易陷入把策略赚钱归因于策略本身的能力,而忽略了市场环境、运气和流动性溢价这些客观因素。THS有一个设计习惯,就是每次实盘交易日志里都会同时记录当时的市场状态标签,比如趋势行情、震荡行情、高波动行情、低波动行情。这样过了几个月回看交易记录,你就能清晰看出,哪部分收益来自哪种市场环境,当市场状态标签变化时策略有没有做出适应。这个记录在策略迭代和风格评估中价值很大,很多时候你会发现你以为策略在某个阶段表现不好是自身参数问题,其实只是那个阶段市场本身就不适合该策略的盈利模式。
避免黑箱化的另一个做法是定期人工抽查策略逻辑和实际成交记录是否完全吻合。哪怕系统已经全自动化运行,每周末还是值得把本周的每一笔信号和成交记录摊开审视。很多隐藏问题都是在这种情况下被发现的,比如某个参数因为数据源异常变成了极端值,导致信号数量骤增,订单以不正常频率提交,这些在监控面板上不容易被注意,但逐笔审计一眼就能发现。
6. 我实际运营THS几个月后的操作心得,以及给新手的建议
6.1 初次搭建时应该先完成的三件事
如果你打算照THS的思路搭建自己的量化系统,我建议初期不要奔着复杂的机器学习模型去,而是先把三件事做扎实。第一,跑通一个完整的、简单的、逻辑清晰的策略,从行情订阅、信号计算、模拟下单到日志记录,整个链路至少稳定运行一周无报错。第二,建立一个可靠的回测脚本库,把你想到的策略逻辑都能用同一套代码快速回测,回测结果以HTML或JSON格式自动存档,避免每次回测后人工复制粘贴数据。第三,搭好监控告警,你需要第一时间知道程序停了、网络断了、成交异常了,任何一个环节缺失,都不适合开始放大资金交易。我在走这一步的时候,前两周几乎没有赚钱,但花了大量时间处理基础设施问题,事后看这笔时间花得不冤。
6.2 最小可行性运行:第一目标不是盈利
第一次上实盘,把目标定为“不出大事故”比“赚大钱”重要得多。THS运行的第一周我只投入极小的仓位,甚至相当于模拟盘的资金量,重点观察执行是否符合预期、滑点是否在可接受范围、风控是否按设想触发。前两周如果一切正常,再逐步把仓位调大到目标水平的三分之一,之后每增加一次都要观察至少一周,确认系统没有因为仓位变化而产生新的执行问题。
更实在的建议是实盘初期不要频繁改动策略参数,每改动一次参数,就等于让系统重新进入未知测试状态。你需要让策略在固定参数下运行足够长的时间,积累足够多的样本,判断它在真实市场中的表现是否和回测基本一致。这个积累阶段我走了大约六周,期间只在明确出现逻辑漏洞时才改代码,其余情况不管盈亏都坚持不变,目的就是为了积累干净的可分析数据。
6.3 我踩过的几个具体坑和对应的修补方式
第一个坑是数据源偶尔返回异常K线,导致策略算出一个不合理的信号并触发大额止损。后来我在数据层增加了K线合理性校验,规则很简单:单根K线的最高价必须大于等于开盘价、收盘价和最低价;单根K线涨跌幅超过设定阈值时需要人工复核,软件不会自动信任异常数据。第二个坑是某个工作日忘记给系统进程手动重启导致内存持续堆积,最终让策略信号计算越来越慢,延迟飙升。现在的系统里每天凌晨会自动对交易进程做一次优雅重启,清空累计状态,保证各模块在一个干净状态下开始新的一天。第三个坑是订单部分成交后没有及时更新持仓视图,策略以为仓位没变继续下单,随后发现实际持仓已经超限。现在每次收到交易所的成交回报都会增量更新本地持仓状态机,做到一笔成交同步一次,彻底消除持仓不一致的情况。
6.4 最后再说一点关于策略上限的个人体会
做量化最容易让人沉迷的是不断优化参数、不断叠加新因子、不断尝试更复杂的模型。但实际运营THS之后,我越来越觉得好的策略往往并不复杂,它建立在清晰的市场逻辑之上,并用严格的风控和稳定的执行去兑现逻辑优势。如果哪一天你发现自己的策略模型已经复杂到无法向人解释清楚,那大概率是一个危险信号,你也许正在过拟合,正在做一个连自己都无法控制的黑箱,这样的系统即便短期收益诱人,长期也会成为定时炸弹。
如果你认真看完这些内容,你应该已经清楚THS量化交易不是一个神奇的自动印钞机,它是一套需要你持续投入精心维护的工程系统。把基础设施和风控做扎实,让你的策略在数据和执行层面都无可挑剔,剩下的交给时间去兑现数学期望,这才是量化交易应该有的样子。