量化交易圈子里THS是一个绕不开的名字。很多人是从手工看盘开始接触它的后来慢慢发现与其每天盯盘手动下单不如让程序替我们完成数据读取、策略计算、信号生成和交易执行这一整套闭环。这篇文章我不打算讲那些悬在空中的理论直接把我这几年用THS终端做量化交易的完整链路拆开——从数据怎么拿、怎么清洗到策略怎么写、回测怎么做再到模拟盘怎么验证、实盘怎么接最后附上我踩过的坑和排查思路。不管你是刚接触量化不久还是已经写了几百行策略代码这篇文章都值得花十分钟看完。先说清楚这套方案能解决什么问题日常看盘的效率问题、数据获取的标准化问题、策略验证的可靠性问题以及实盘执行中容易忽视的风控细节。全文以THS终端作为数据源和交易执行中枢技术栈以Python为主适合那些已经在用THS看盘、想往程序化方向走一步的投资者也适合已经写了策略但还没想清楚数据管线怎么搭的人。1. 整体架构与方案选型思考1.1 为什么把THS终端作为数据与执行中枢很多人在量化入门时第一个问题就是行情数据从哪来市面上有免费接口、有付费数据商、有爬虫方案但我最终还是选择围绕THS终端来搭。原因很朴实它本身就覆盖了行情、财务、公告、板块、资金流这些量化常用的数据维度而且我日常盯盘本来就在这个软件上数据的一致性能直接对齐。终端方案相比纯爬虫的优势在于稳定性。行情网站的反爬策略经常变今天能抓的字段明天可能就换了字段名维护成本极高。THS终端至少在数据完整度和更新频率上有保障分时、日线、财务数据都能按固定节奏获取。再加上它自带的模拟交易功能可以在不投入真金白银的前提下验证策略执行链路。不过这里也有一个要提前想清楚的点THS终端本质上是给“人”看盘用的工具程序化读取数据时要在终端和后端脚本之间做一层桥接。这层桥接做得好不好直接决定整个策略系统的稳定性。后面我会专门讲这部分的实现细节。1.2 量化系统的四层架构我习惯把这套量化系统拆成四个层次每一层职责单一互不纠缠数据层负责从THS终端读取行情、财务、板块等原始数据做清洗、复权、对齐最终落成可供策略直接调用的标准数据表。策略层接收标准数据运行交易信号逻辑输出目标持仓或买卖指令。这是整个系统的大脑也是迭代最频繁的一层。执行层把策略信号翻译成真实或模拟的交易动作包括下单、撤单、成交回报处理。风控层把止损、仓位上限、单票持仓比例、黑名单等规则硬编码在系统中任何交易动作必须过风控才能放行。这样分层之后每一层的替换成本都很低。数据源坏了不影响策略回测策略迭代了不影响执行链路风控规则加严了也不用去动策略代码。很多人一开始写着写着就变成一锅粥所有逻辑揉在一个脚本里后面想加一个风控条件都小心翼翼这就是没做好分层的代价。1.3 技术栈的选择与理由我的技术栈很简单Python写策略和脚本SQLite存历史数据CSV做轻量数据交换计划任务做定时轮询。选Python没有悬念量化生态里它最成熟pandas处理表格数据、numpy算指标、回测框架随手就能找到。存储用SQLite是够用原则——普通个人级别的量化场景每天更新几千只股票的日线数据SQLite完全扛得住没必要上重型数据库。当然数据量如果到了上亿行级别我会考虑换Parquet列式存储但那不是大多数人的现状。还有一点容易被忽略系统和脚本的编码格式。THS导出的数据在Windows上通常是GBK编码而Python 3默认UTF-8读进来直接乱码。这个我在初学时踩过坑后面会提到。技术选型时就要先确认好自己的运行环境尽量把脚本和终端的字符集问题在源头解掉。2. 数据管线的搭建从行情读取到标准数据表2.1 行情数据获取的三种方式对比我从THS终端取数据主要试过三种方式各有优劣。第一种是手动导出。在终端里选好股票列表和时间范围导出Excel或CSV再写脚本读入。这种方式的优点是零开发成本缺点是没法自动化只适合一次性研究比如我刚开始研究某个策略时用这种方式拿几天数据练手。第二种是本地数据文件读取。THS终端会在本地目录缓存一些行情数据找到对应路径后可以用脚本直接解析文件。这种方式速度很快但问题在于文件格式不是公开文档化的一旦终端升级字段布局可能变化脚本就得跟着改。第三种是模拟键盘鼠标操作终端界面自动点击菜单完成数据查询和导出。这个思路虽然在自动化程度上最高但对界面变动非常敏感稳定性一般。我现在的方案是结合第二种和第三种常规日线数据走本地文件解析特殊场景用界面自动操作补充。无论哪种方式有一个原则是共通的获取数据只是第一步数据的校验和清洗才是真正花时间的部分。2.2 数据清洗的必做流程复权、停牌与ST行情数据拿到手之后麻烦事才开始。你要是直接用原始价算收益和信号结果会偏得离谱。这里说三个必做的清洗步骤。复权处理是重中之重。股票分红送股之后价格会出现跳空但这是“假跳空”并不是真实的市场波动。如果你拿不复权的数据算均线信号可能在除权日当天被严重误导。我的习惯是统一用前复权数据做策略计算也就是以当前价格为基准把历史价格做相应调整。这样信号计算用的是同一价格基准不会出现除权那天的“幽灵信号”。停牌过滤也很容易漏。长时间停牌的股票在K线上表现为连续相同价格或者没有数据如果不加处理策略可能在里面“空转”甚至产生虚假成交。我的处理方式是在股票池筛选阶段就把停牌超过一定天数的票剔除在实盘信号生成阶段再次确认标的当天有正常交易状态。ST股票过滤则是风险偏好的问题。很多策略并不希望买入ST股因为涨跌幅限制不同流动性也差。我在生成股票池的时候会拉取ST标记列表统一做一个黑名单过滤。虽然这会在某些行情下损失一点收益但换来的确定性和合规性值这个代价。2.3 数据存储模型与每日更新节奏清洗完的数据需要一个清晰的存储模型。我用的表结构大致如下stock_basic证券代码、名称、行业、上市日期、是否ST等静态信息。daily_price代码、日期、开高低收、成交量、成交额、复权因子、前复权价。daily_indicator由价格数据算出的技术指标比如均线值、RSI、MACD等。trade_status每日停复牌状态、涨跌停状态。每日更新的节奏是收盘后定时任务触发从THS拉取当天数据追加写入daily_price增量更新trade_status再对最新数据全量计算技术指标。整个过程大概十几分钟跑完留到晚上复盘用足够了。一个实用的技巧入库之前先做一次去重和主键检查以“代码日期”作为唯一键重复的要么覆盖要么跳过。不要小看这一步终端偶尔会重复导出同一段区间不查重的话指标计算会因为重复行悄悄出错。3. 策略研究与回测把想法变成可验证的信号3.1 以双均线策略为例讲清楚回测的完整流程很多人写策略上来就追求复杂模型其实经典的简单策略更能验证你的系统是否可靠。这里我用双均线策略来演示当短期均线上穿长期均线时买入下穿时卖出。回测流程大体是从本地数据库读取股票池过去三年的前复权日线数据。计算短均线比如5日和长均线比如20日。定义信号金叉记1死叉记-1中间保持原来持仓状态。按信号模拟每日调仓同时扣除手续费。统计最终收益、年化收益率、最大回撤、夏普比率、胜率等指标。这里最需要解释清楚的是第三步的做法。信号的持仓状态是连续的而不是只有当天瞬间的买卖动作。金叉当天买入后在没有出现死叉之前你是持续持有的。这个状态转换逻辑写不对回测结果会和实盘完全两样。我见过不少初学代码回测收益很好、实盘一塌糊涂的案例细查之下都是状态保持逻辑写错了。3.2 回测指标的镜像解释别只看收益率评估一个策略靠不靠谱不能只看最终收益率。我每次回测必看的四个指标是年化收益率、最大回撤、夏普比率和胜率。年化收益代表赚钱能力但必须配合最大回撤一起看。一个策略一年赚了80%中间却回撤了40%说实话这种策略一般人拿不住心态早在回撤途中就崩了。我更关心的是收益回撤比低回撤的稳健策略比高波动高收益的策略更适合个人投资者。夏普比率衡量的是“每承担一单位风险能换来多少超额收益”通常大于1算合格大于2就算不错。这个指标的计算公式是(策略年化收益率-无风险利率)/策略收益波动率。无风险利率我一般取一年期国债收益率或者定期存款利率国内个人量化场景下通常用2%左右的近似值。胜率这个东西要辩证看。有的策略胜率只有40%但盈亏比很高整体照样赚钱。回测报告里胜率和盈亏比要放在一起看单独看任何一项都很容易误判。3.3 参数优化的陷阱如何防止过拟合做回测不可避免会遇到参数优化。双均线的短周期、长周期参数都可以通过遍历找出一组历史表现最好的数值。比如短周期从3到15长周期从15到60两两组合都跑一遍选出夏普最高的那组参数。这个思路本身没问题但大多数人在这里栽跟头是因为过拟合你找出的参数可能只是把历史噪声都拟合进去了换到未来行情立刻失效。我有几个应对手段数据分段验证不要把整段历史数据都用来选参数留下一段最近的数据做样本外验证。比如用前80%的数据选参数后20%的数据验证效果。参数平原原则不要选那种“唯一最优”的参数而是看参数周围是否有一片区域表现都还可以。如果最优参数旁边都是断崖式下跌说明策略对参数极其敏感实盘中必死。减少参数个数策略参数越多过拟合空间越大。能用两个参数表达清楚的就别上五个。我还会特意给回测脚本加入随机扰动测试比如在价格序列上加一点随机噪声再跑一遍。如果策略绩效因为微小扰动就大幅变差说明它捕捉的是噪声而非规律。4. 模拟盘与实盘执行从回测到真金白银的最后一公里4.1 模拟盘的真正价值不是验证收益而是检验流程模拟盘最容易被误解的地方在于很多人用它来验证策略的收益能力但模拟盘的撮合逻辑和实盘有本质区别。模拟盘往往按当前价直接成交不产生滑点也不考虑盘口深度。策略在模拟盘上跑出来的收益曲线大概率比实盘漂亮。我认为模拟盘的真正价值在流程验证。策略模块能不能按时产出信号执行模块能不能准确下单风控模块能不能在触发条件时果断拦截有没有漏单、重复下单、订单状态不同步之类的致命bug这些问题在模拟盘阶段暴露出来的成本比实盘低太多。我当时在模拟盘上刻意做了一件事人为制造异常场景。比如临时拔掉网线再恢复看看系统会怎么处理未确认的订单比如在策略里故意放一个超过风控限额的指令看风控模块到底拦不拦得住。这种故障注入测试常规跑流程根本碰不到但对实盘的稳健性至关重要。4.2 实盘下单链路的落地要点当模拟盘连续稳定运行一段时间后可以开始考虑实盘。我接的下单链路大致是这样策略模块在收盘后或盘中按固定频率生成目标持仓。执行模块对比当前持仓和目标持仓计算差异。风控模块对每一笔差异交易逐一检查是否在股票池内、是否超仓位限制、是否触发止损。通过风控的订单按优先级排序逐笔下达到THS终端的交易接口。成交回报返回后更新实时持仓记录。这里有一个容易被忽略的细节下单频率要与行情更新频率匹配。如果你用的是日线级别信号盘中每五分钟就跑一次策略就没意义反而徒增计算量和重复下单风险。正确的做法是在日线数据更新后计算一次仓位目标然后在当日交易时段内按固定节奏执行调仓。另一个要点是订单的幂等性。系统重试下单时要保证同一指令不会下两次。我的做法是给每一笔订单生成唯一ID终端返回订单号后立即记录重复执行时先查这个订单号是否已存在。4.3 风控规则硬编码宁可错过不可出错风控是实盘和模拟盘最大的区别。模拟盘下单错了顶多心态难受实盘一次风控失效可能就是大额亏损。我的风控规则全部硬编码进系统不依赖任何人工判断单票仓位上限任何一只票不超过总资金的20%。行业集中度控制同一行业不超过总资金的40%防止单一行业系统性风险。止损硬线单票浮亏达到8%无条件止损不回滚、不商量。黑名单机制ST、停牌、重大利空公告的标的直接从股票池剔除。异动熔断策略单日调仓次数超过预设阈值自动停用策略并人工介入。这些规则写起来都不复杂难的是坚决执行。我见过太多人在盘中止损线到了却手动操作“再等等”等来的往往是更深的亏损。把规则交给代码执行反而是对自己情绪的最大保护。5. 常见问题与排查技巧实录5.1 数据对不上先查数据源再查自己的代码跑策略时经常遇到一种诡异情况某个标的的行情明显波动很大但策略完全没反应。第一步基本是怀疑策略代码有bug但排查到最后往往发现是数据层的问题。我遇到的一个典型场景是THS终端里看到的日线数据和本地库里的数据对不上。后来发现是导出时日期没有按从早到晚排序而我的策略脚本默认数据是有序的导致计算出来的均线值错位。从那之后我在数据入库时强制按“代码日期”排序并在读取时加了一层校验发现乱序直接报警。另一个常见问题是复权状态不统一。不同时间导出的数据可能一次是前复权、一次是不复权混在一起用的话策略信号会出现莫名其妙的跳变。我的对策很简单在数据表里加一个字段记录复权状态入库时校验坚决禁止混合状态。5.2 信号延迟先确认计算时点再怪网络盘中跑策略出现信号延迟时很多人的第一反应是网络慢、接口慢。但我的排查经验是大概率是策略脚本的计算时点错了。盘中实时行情每秒钟都在更新如果你的策略用了当日未收盘的最新价去算日线指标结果必然处于漂移状态。正确的做法是盘中信号用盘中快照计算收盘信号等当日数据完全落地后再计算两套信号分别处理。我一开始偷懒一套代码两个场景通吃结果盘中信号和收盘信号经常互相矛盾。另外本地脚本从THS读数据时要留意终端是否正处于数据刷新中。我碰到过终端正在下载历史数据时本地脚本读到的文件是半截状态解析直接报错。现在的处理方式是读文件前先检查文件大小是否稳定两次读取间隔一秒大小一致才认为写完了。5.3 常见问题速查表问题现象可能原因排查方法中文乱码编码格式不匹配指定GBK读取导出文件回测收益虚高未扣除手续费和滑点回测中增加交易成本模型实盘信号与回测不符复权状态不一致统一使用前复权数据重复下单订单状态未持久化为订单生成唯一ID并入库某日数据缺失停牌或数据未刷新校准trade_status表策略触发频率异常信号状态保持逻辑错误检查金叉死叉状态转换实盘持仓与目标偏离部分成交未处理成交回报逐笔对齐这张表是我平时排查问题的粗线条框架。真遇到问题的时候我会从数据层开始逐层向上排查先确认输入数据没问题再看信号计算接着看风控拦截最后才怀疑下单环节。这个顺序基本能覆盖90%的异常场景。5.4 日志记录复盘和排障的底牌最后必须强调日志的重要性。我的系统从一开始就在每个关键环节打日志数据入库时间、信号生成时间、风控检查结果、下单指令、成交回报全部记录。一开始觉得麻烦但几次排查线上问题全靠日志快速定位。日志记录有几个注意点日志要带时间戳精确到秒级甚至毫秒级。策略信号要记录当时的计算输入快照方便事后复现。风控拦截要明确记录拦截原因否则你根本不知道哪个规则在起作用。日志文件要按日期切割方便回看某一天的全部轨迹。我在实盘运营中发现很多看似奇怪的问题翻出当天日志一看原因立刻清晰。比如某个标的没买入不是策略没信号而是风控因为当天有重大公告把它拉黑了。这种事情在盘面上完全看不出来只有日志能还原完整因果链。我个人在实际操作中最深的体会是量化交易的成败多半不在策略代码本身而在于你愿不愿意把数据、回测、执行、风控这些“细碎环节”一项项做扎实。很多人把精力全放在策略模型上最后却因为一个复权处理不当导致实盘亏损这太可惜了。如果你想尝试把THS终端变成自己的量化基础设施建议从数据管线开始搭建然后跑熟回测流程再逐步接上模拟盘和实盘执行一步一步来别急着全链路打通。最后再分享一个小技巧系统的每个关键脚本都不要只写一个默认版本留一个带详细调试输出的开关平时关掉排查问题时打开你会省下大量猜来猜去的时间。