程序员量化交易实战 01:为什么程序员适合做量化交易
程序员量化交易实战 01:为什么程序员适合做量化交易
古董级程序员,大厂出来后一直在创业公司,现在仍活跃在一线做 AI 相关的开发。这个专栏会把一个 A 股量化平台从 0 到 1 拆开写:数据、策略、回测、模拟盘、提醒和生产化,尽量用真实代码和真实运行结果说话。更完整的更新也会同步到微信公众号「字与码」。
上一篇是专栏路线图,说明了这个系列会围绕真实项目推进,而不是提前锁死成一份死板目录。从这一篇开始,我们不再只谈方向,而是把项目真正跑起来。
先把边界说清楚:这个系列只做研究、回测、纸面模拟和提醒,不连接券商,不提交真实交易订单,也不构成投资建议。量化交易最容易被讲成“发现一个神奇公式”,但我更愿意从工程角度看它:把一个交易想法拆成数据、规则、验证、风控和复盘,再让它每天以同样的方式运行。
这正是程序员熟悉的工作。

量化交易不是按按钮赚钱
很多人第一次听到“量化交易”,脑子里会出现两个极端画面。
一种是华尔街机房、超低延迟、数学博士和复杂模型。另一种是短视频里随手画两根均线,然后说“金叉买入、死叉卖出”,好像只要照着做就能赚钱。
这两个画面都不适合我们这个系列。
我们要做的是更朴素的事情:用程序把一个交易想法完整表达出来,然后检查它在历史数据里发生了什么,在模拟盘里又发生了什么。这个过程不保证赚钱,但能让“我觉得会涨”变成一套可以被质疑、被验证、被复盘的系统。
用工程语言说,量化交易至少包含这些对象:
- 数据:股票基础信息、行情、财报、交易日历、成交量、停牌状态。
- 规则:什么情况下进入观察池,什么情况下移出,仓位上限是多少。
- 回测:把规则放回历史时间线上,逐日模拟持仓、现金、收益和回撤。
- 风控:限制单票仓位、最大持仓数、交易成本、流动性和异常价格。
- 模拟盘:不下真实订单,只记录纸面订单、净值、复盘和提醒。

只要这样拆开,程序员就会进入熟悉区域。我们不需要先假装自己是基金经理,也不需要先背完一整本金融教材。我们可以先把输入输出定义清楚,把边界条件写进测试,把运行结果保存下来。
程序员的优势在哪里
程序员做量化的优势,不是“会写代码所以一定比别人聪明”。优势主要在四件事上。
第一,程序员习惯把含糊需求拆成明确接口。
“趋势向上”这句话没法运行,但“收盘价高于 20 日均线,且 20 日均线高于 60 日均线”可以运行。“风险太高”这句话没法测试,但“单票仓位不超过总权益 10%,组合最大持仓不超过 10 只”可以测试。
第二,程序员习惯记录证据。
一个策略今天给出 BUY_WATCH,不能只告诉用户“模型认为不错”。它应该能说清楚:最近 20 日动量是多少、财报质量分是多少、成交量是否异常、是否触发风控、数据来源是什么。没有证据的信号,后面无法复盘。
第三,程序员知道系统会坏。
数据源会断,API 会变,数据库迁移会漏,定时任务会重复跑,配置会被误删,时间区间会传错。量化平台不是 notebook 里一段跑完就丢的代码,它需要健康检查、日志、审计、失败重试和权限控制。
第四,程序员天然尊重版本。
策略参数改过没有?回测时用的是哪一版规则?股票池是哪个日期的?财报数据有没有滞后?如果这些都不记录,一个漂亮的收益曲线可能只是一次不可复现的幻觉。
这也是为什么本系列会把项目命名为 ZiQuant,并且从第一天就把它当成一个长期项目,而不是几段零散脚本。
量化交易和主观交易的区别
主观交易并不低级。很多优秀投资者靠行业理解、商业判断、财报阅读和交易经验做决策,这些能力很难被简单代码替代。
量化交易的不同之处在于,它要求决策规则尽量显式化。
例如一个主观判断可以这样说:
这只股票基本面不错,最近走势也还可以,估值不算太贵,可以先观察。
量化系统必须把它拆成更硬的条件:
def generate_signal(stock, factors, risk):
if risk.is_suspended or risk.is_st:
return "RISK_WATCH"
quality_ok = factors.roe_percentile >= 0.70 and factors.margin_percentile >= 0.60
momentum_ok = factors.momentum_60d_percentile >= 0.65
volatility_ok = factors.volatility_20d_percentile <= 0.80
if quality_ok and momentum_ok and volatility_ok:
return "BUY_WATCH"
if quality_ok and not momentum_ok:
return "HOLD_WATCH"
return "OBSERVE"
这段代码本身还很粗糙,但它有一个关键优点:别人可以问它为什么,也可以改它、测它、回滚它。
主观交易更像是专家在复杂环境里的判断;量化交易更像是把一部分判断写成可重复运行的实验。它们不是绝对对立的。真正有用的平台,往往是让程序先把候选、风险和证据整理出来,再由人做最后判断。
所以我们后面会故意把信号命名成 BUY_WATCH、HOLD_WATCH、RISK_WATCH,而不是直接叫 BUY、SELL。系统给的是研究和观察建议,不是自动下单命令。
为什么先做模拟盘
程序员很容易犯一个毛病:系统刚能跑,就想接真实服务。
量化交易里,这个冲动尤其危险。一个没有经历足够回测、样本外验证、模拟盘观察和人工复核的策略,不应该连接真实券商账户。
模拟盘的意义不是假装自己已经赚钱,而是检查三类问题。
第一类是工程问题:信号每天是否稳定生成,数据是否及时刷新,任务是否重复跑,订单数量是否满足规则。
第二类是策略问题:买入后的表现是否符合预期,亏损是不是集中在某类市场环境,换手是否过高,最大回撤是否能接受。
第三类是行为问题:当系统连续亏损时,人是否还能按规则复盘,而不是临时改参数追涨杀跌。
ZiQuant 当前的项目边界也写在 README 里:平台只做量化研究、回测、提醒和模拟盘,不会向真实券商账户提交订单。
这个限制不是保守,而是工程纪律。
A 股规则会改变代码
如果只看教材或海外资料,很容易写出一个“看起来正确、在 A 股完全不现实”的回测。
A 股有几条规则会直接影响程序设计。

这些规则不是最后再补的细节,而应该从项目一开始就进入数据模型和测试。
比如 100 股整数手会影响下单数量:
def normalize_a_share_lot(shares: int) -> int:
"""A 股普通买入按 100 股整数手处理。"""
if shares <= 0:
return 0
return shares // 100 * 100
assert normalize_a_share_lot(99) == 0
assert normalize_a_share_lot(100) == 100
assert normalize_a_share_lot(258) == 200
交易成本也必须尽早进入模型:
def estimate_a_share_fee(amount: float, side: str) -> float:
commission = max(amount * 0.0003, 5.0)
transfer_fee = amount * 0.00001
stamp_tax = amount * 0.0005 if side == "sell" else 0.0
return round(commission + transfer_fee + stamp_tax, 2)
buy_fee = estimate_a_share_fee(20_000, "buy")
sell_fee = estimate_a_share_fee(20_000, "sell")
print(buy_fee, sell_fee)
后面写回测引擎时,我们还会加入涨跌停不可交易、成交量参与率、滑点、T+1 简化处理和纸面订单拒单原因。现在先记住一件事:市场规则会变成代码里的约束,不是文章里的背景知识。
本系列最终要做什么
本系列贯穿项目是 zi-quant-platform。它不是一个只为文章存在的空壳,而是一个可以运行的 FastAPI + PostgreSQL 项目。
当前启动方式如下:
cd /home/alex/work/yswx/zi-quant-platform
uv sync --extra dev
uv run uvicorn app.main:app --host 127.0.0.1 --port 8092
健康检查:
curl http://127.0.0.1:8092/health
运行测试:
uv run pytest
这一章对应的项目 tag:
git clone https://github.com/ax2/zi-quant-platform.git
cd zi-quant-platform
git checkout chapter-01
uv sync --extra dev
uv run pytest
后续文章会沿着这个项目继续加能力:股票池、真实行情、财报、因子、策略、回测、模拟盘、飞书提醒、DeepSeek 策略优化、生产验收。每一篇都应该让项目比上一篇更完整,但也必须保持可运行。
第一篇暂时不要求读者把所有模块写完。我们只做一件事:确认自己不是在写一次性脚本,而是在建立一个长期可演进的工程项目。
实战任务:创建项目 README
如果你从零开始,可以先创建一个最小项目目录:
mkdir -p zi-quant-platform
cd zi-quant-platform
git init
然后写第一版 README.md:
# ZiQuant Platform
面向程序员的 A 股量化交易实战平台。
## 边界
- 只做研究、回测、提醒和模拟盘。
- 不连接券商。
- 不提交真实交易订单。
- 不构成投资建议。
## 第一阶段目标
- 建立 Python 项目骨架。
- 设计股票池和行情数据结构。
- 实现 A 股交易规则检查。
- 跑通第一个可测试的策略实验。
如果你直接跟着我的仓库走,那么第一步是确认项目能安装、能启动、能跑测试。后面的文章会逐步解释每个目录为什么存在,每张表为什么这样设计,每个 API 对应哪一个业务动作。
现在这个 README 看起来很简单,但它先把边界写下来了。量化系统最怕边界模糊:研究系统写着写着变成自动下单,模拟盘写着写着变成真实账户,策略解释写着写着变成投资建议。第一天就把边界写清楚,后面很多风险会少很多。
常见坑
第一个坑,是一上来就找“神奇策略”。
策略当然重要,但没有稳定数据、没有交易约束、没有回测记录、没有风控,策略越复杂越危险。这个系列会先搭地基,再做策略。
第二个坑,是把回测收益当成真实收益。
回测只是验证工具,不是提款机。只要数据有未来函数、交易成本漏算、停牌和涨跌停没处理、股票池有幸存者偏差,收益曲线就可能很好看,也很没用。
第三个坑,是把大模型当交易员。
后面我们会接入 DeepSeek,但它的角色是读报告、解释策略、提出候选参数和生成研究建议。它不能直接决定买卖,更不能绕过回测和人工复核。
第四个坑,是忽略运行状态。
量化平台每天都要和时间、数据源、数据库、任务调度打交道。它不是本地跑一次就结束的脚本。我们会把 /health、/ready、任务运行记录、审计日志和生产验收都写进项目,因为这些东西决定系统能不能长期被信任。
本章更新与代码仓库
本章更新内容:
- 明确 ZiQuant 只做研究、回测、提醒和纸面模拟盘。
- 给出第一版项目 README 边界。
- 建立专栏主线仓库和第 1 章可运行 tag。
代码仓库:
https://github.com/ax2/zi-quant-platform
本章代码:
git clone https://github.com/ax2/zi-quant-platform.git
cd zi-quant-platform
git checkout chapter-01
uv sync --extra dev
uv run pytest
本篇小结
程序员适合做量化交易,不是因为会写代码就能战胜市场,而是因为程序员擅长把复杂问题拆成可运行、可验证、可复盘的系统。
从这一篇开始,我们把量化交易当成工程项目来做。先写边界,再搭骨架;先做模拟,再谈实盘;先保留证据,再讨论结论。
下一篇我们进入项目结构:用 uv、pyproject.toml、.env、测试目录和健康检查,把 ZiQuant 的 Python 工程骨架搭起来。