如何从开源书籍学习量化交易
开源量化交易书籍梳理从数据、信号、回测到实盘的完整课程路径,说明新手常停在哪一步,以及哪些方法可迁移到美国股票市场。
开源量化交易书籍是一份免费的公开课程大纲:它按照初学者实际接触的顺序,记录从原始数据到实盘下单的完整路径。xingwudao 在 GitHub 发布的《XQuant:人人都能成为量化交易员》手稿,截至 2026 年 8 月获得 686 颗星,是一个结构清晰的范例。全书共九章,沿着几乎所有量化课程都会采用的路径展开。本文将按阶段梳理这条路径,指出每个阶段对应的具体失败风险,并标明哪些部分能够从中国 A 股市场迁移到美国股票市场。
开源量化交易书籍包含哪些内容?
去掉任何入门课程的品牌包装后,通常还剩下五个阶段,而且顺序固定:获取并清洗数据,从数据中构建信号,用历史数据检验信号,决定下注规模,然后发送订单并承担交易成本。截至 016b66e 所示的 2026 年 7 月 14 日提交版本,XQuant 的目录分为九章,覆盖了同样的内容。
- 准备工作,然后是第一章:完整运行一套策略。
- 第二章,买什么:从三只 ETF 开始。
- 第三章,买多少:比较三种资产配置方法。
- 第四章,何时交易:再平衡、止损、止盈。
- 第五章,判断策略是否有效:四个观察角度。
- 第六章,不要过早庆祝:防止过拟合。
- 第七章,从理想到现实:执行交易。
- 第八章,启动之后:监控、诊断、迭代。
- 第九章,寻找新机会:因子研究入门。
章节顺序值得关注。仓位规模在第三章出现,早于两章回测内容;因子研究则放在最后。自学路径通常正好相反:先提出因子思路,再进行回测,却从不制定仓位规则。配套练习仓库(截至同一日期有 333 个 stars)以书面任务规格为组织基础,而不是提供完成的代码,由读者指导 AI 助手实现这些任务。阅读并非自己编写的代码,仍然是决定后续一切的能力,因为每个错误都隐藏在某个实现细节中。
第一阶段:先获取数据,再定义股票池
数据清理是数据工作的显性部分,包括错误成交、缺失交易日,以及拆股和分红调整。选择要研究哪些股票则是隐性部分。幸存者偏差会在策略代码出现之前就从这里进入。逐年提取某个六月周内有成交记录的所有美国股票代码,然后查看其中有多少仍在 2026 年同一周交易。
每个数字背后的完整 SQL
WITH june_week AS (
SELECT toYear(toTimeZone(window_start, 'America/New_York')) AS year,
ticker
FROM global_markets.delayed_stocks_minute_aggs
WHERE toMonth(toTimeZone(window_start, 'America/New_York')) = 6
AND toDayOfMonth(toTimeZone(window_start, 'America/New_York')) BETWEEN 10 AND 16
AND toYear(toTimeZone(window_start, 'America/New_York')) BETWEEN 2016 AND 2026
AND volume > 0
GROUP BY year, ticker
),
survivors AS (
SELECT ticker FROM june_week WHERE year = 2026
)
SELECT year,
uniqExact(ticker) AS tickers_traded,
uniqExactIf(ticker, ticker IN (SELECT ticker FROM survivors)) AS still_trading_2026,
round(100 * uniqExactIf(ticker, ticker IN (SELECT ticker FROM survivors))
/ uniqExact(ticker), 1) AS still_trading_pct
FROM june_week
GROUP BY year
ORDER BY year在 2016 年该周交易的 8224 个股票代码中,50% 个在 2026 年同一周仍在交易。其余股票已被收购、合并、更名或退市。基于当前股票名单构建的回测,只研究最终存续的股票,并让策略持有事后才被选中的公司。初学者使用的数据源会直接提供这份幸存者名单,却不作任何警示:免费股票市场数据 API 指南介绍了这些数据源包含和不包含哪些内容。
第二阶段:将数据转化为信号
信号是在某个时间点为股票评分的规则。因子则是您认为同时适用于许多股票的信号。动量、价值和低波动率是教科书中的典型例子。这个阶段的失败在于不断测试规则,直到找到一个有效的规则。在某一指数的十年数据上测试二十种移动平均线交叉变体,总会产生一个赢家。这个赢家往往只是最贴合噪声的规则。防范方法并不吸引人:在测量规则前先确定规则;留出一段从不查看的历史数据;记录尝试过的每个变体;并优先选择可调参数更少的规则。XQuant 在因子研究之前专门用一整章讨论了这些内容,这一顺序是正确的。
第三阶段:回测,大多数初学者止步于此
这是大多数自学项目终止的阶段。它们往往悄无声息地结束,并留下漂亮的权益曲线。上文提到的生存者偏差是两个错误中的第一个。前视偏差是第二个:策略使用了下单时钟尚未提供的数据。最常见的情况是,根据当日收盘价计算交易规则,并在同一收盘价成交。请衡量这一假设跳过的距离。
每个数字背后的完整 SQL
WITH sessions AS (
SELECT ticker,
toDate(toTimeZone(window_start, 'America/New_York')) AS session,
argMin(open, window_start) AS session_open,
argMax(close, window_start) AS session_close
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('SPY', 'NVDA')
AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2024-08-01')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY ticker, session
),
gaps AS (
SELECT ticker,
session,
toFloat64(session_open) AS open_px,
toFloat64(lagInFrame(session_close) OVER (PARTITION BY ticker ORDER BY session)) AS prev_close
FROM sessions
)
SELECT formatDateTime(toStartOfMonth(session), '%Y-%m') AS month,
formatDateTimeInJodaSyntax(toStartOfMonth(session), 'MMMM yyyy') AS month_label,
round(avgIf(abs(open_px / prev_close - 1) * 10000, ticker = 'SPY'), 1) AS spy_gap_bps,
round(avgIf(abs(open_px / prev_close - 1) * 10000, ticker = 'NVDA'), 1) AS nvda_gap_bps
FROM gaps
WHERE prev_close > 0
GROUP BY month, month_label
HAVING countIf(ticker = 'SPY') > 0 AND countIf(ticker = 'NVDA') > 0
ORDER BY month在 July 2026 中,一次收盘价与下一次开盘成交价之间的平均距离,SPY 为 40.8 个基点,NVDA 为 107.4 个基点。一个基点是一个百分点的百分之一。面板中的全部 24 个月(从 August 2024 开始)均高于零。回测若在收盘时作出决策,并按该收盘价成交,就会在每笔交易中无偿获得这段距离;而实际交易中从来不会有订单做到这一点。回测中的前视偏差详细拆解了这一机制,股票为何隔夜跳空解释了跳空本身。
第四阶段:决定买入多少
这里的问题在于缺少规则。大多数自学交易者从未写下仓位规模规则。因此,他们实际上是偶然采用了一套规则,通常是每个标的投入相同金额,或投入所有可用现金。投入相同金额不等于承担相同风险。
每个数字背后的完整 SQL
WITH daily AS (
SELECT ticker,
toDate(toTimeZone(window_start, 'America/New_York')) AS session,
argMax(close, window_start) AS session_close
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('SPY', 'KO', 'JNJ', 'MSFT', 'AAPL', 'NVDA', 'TSLA', 'COIN')
AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2025-08-01')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY ticker, session
),
rets AS (
SELECT ticker,
toFloat64(session_close) AS close_px,
toFloat64(lagInFrame(session_close) OVER (PARTITION BY ticker ORDER BY session)) AS prev_close
FROM daily
)
SELECT ticker,
round(stddevSamp(close_px / prev_close - 1) * sqrt(252) * 100, 1) AS annualized_vol_pct,
round(abs(min(close_px / prev_close - 1)) * 100, 2) AS worst_day_pct
FROM rets
WHERE prev_close > 0
GROUP BY ticker
ORDER BY annualized_vol_pct DESC截至2026年7月31日的过去十二个月中,COIN的年化波动率为68%;处于该样本平稳端的SPY为12.7%。前者最差的单个交易日收盘价较前一日收盘价低13.34%,而SPY最差的一天为2.69%。对每个标的投入相同金额,会带来幅度截然不同的日内波动。初学者实际承受的是这种波动,而不是交易信号。凯利准则仓位规模介绍了一种正式方法,集中度风险则展示了非正式方法的形态。
第五阶段:执行与回测忽略的成本
两类成本中,只有一类看得见。佣金和监管费会出现在对账单上。滑点不会。滑点是屏幕显示价格与实际成交价格之间的差额。滑点的最低成本是买卖价差,即某一时刻最佳买价与最佳卖价之间的距离。买方支付卖价,卖方按买价成交,因此完成一轮买卖需要跨越价差两次。价差并非固定不变。
每个数字背后的完整 SQL
WITH quotes AS (
SELECT ticker,
toStartOfInterval(toTimeZone(sip_timestamp, 'America/New_York'), INTERVAL 30 MINUTE) AS bucket,
toFloat64(ask_price - bid_price) / toFloat64((ask_price + bid_price) / 2) * 10000 AS spread_bps
FROM global_markets.cache_stocks_quotes
WHERE ticker IN ('AAPL', 'KO')
AND sip_timestamp >= toDateTime('2026-07-17 13:00:00')
AND sip_timestamp < toDateTime('2026-07-17 21:00:00')
AND bid_price > 0
AND ask_price > bid_price
)
SELECT formatDateTime(bucket, '%H:%i') AS et_time,
round(avgIf(spread_bps, ticker = 'AAPL'), 2) AS aapl_spread_bps,
round(avgIf(spread_bps, ticker = 'KO'), 2) AS ko_spread_bps
FROM quotes
WHERE spread_bps > 0 AND spread_bps < 500
GROUP BY et_time
HAVING countIf(ticker = 'AAPL') > 0 AND countIf(ticker = 'KO') > 0
ORDER BY et_time该图涵盖某个周五的 16 个半小时区间,从开盘铃前的第 09:00 个区间到收盘后的第 16:30 个区间。AAPL 在第一个区间的报价价差为 10.53 个基点,在最后一个区间为 3.27 个基点;KO 则分别为 28.87 和 8.04 个基点。当天最窄的报价位于图表中部,介于两端之间。在市场流动性最高的两只股票上进行开盘交易,承担的成本不同于同一策略在午间交易时的成本;而假设零成本的回测无法准确反映这两种情况。买卖价差决定这一数值,价差为何在开盘时扩大解释了这条曲线,交易一只股票的成本则汇总了一轮完整交易的成本。从干净的回测到真实资金之间,还差一步:在投入真实资金前进行模拟交易。
A股课程中哪些部分可以迁移到美股?
XQuant及同类课程面向中国A股和ETF。其方法可以完整迁移:阶段顺序、定义、控制过拟合的纪律、将成本作为单独项目记录而非事后补充的习惯,以及所有仓位计算。价格K线仍然是价格K线。不能直接迁移的是围绕这些内容的规则体系。
- A股实行严格的T+1限制:当天买入的股票要到下一个交易日才能卖出。美国市场的T+1是结算惯例,不限制日内交易。不过,日内交易员规则规定,资产低于25,000美元的保证金账户在五个交易日内最多进行三次日内交易。
- A股主板股票的单日涨跌幅上限为10%,成长板块为20%。美股没有单日涨跌幅上限,暂停交易则主要由波动性熔断机制和新闻停牌触发。
- A股订单以100股为一手交易。许多美国券商支持碎股交易,这会改变仓位规则能够表达的范围。
- 中国对卖出交易收取印花税。美国卖方支付的是金额和计费方式不同的少量监管费用。
- 交易时段也不同,包括上海和深圳市场的午间休市。美股交易时段连续运行,并以收盘集合竞价结束。
从课程中复制到自己代码里的任何成本或时间常数,都可能在第一笔实盘订单执行时暴露为错误。
固定引用版本,而不是 README
截至 2026 年 8 月,该代码仓库没有带标签的发布版本,因此最持久的引用对象是一次提交:016b66e,日期为 2026 年 7 月 14 日。这一点对仍在编写中的书稿很重要。章节编号会调整,README 文件会重写,标题会移动,原本指向第七章的链接也可能悄然指向其他内容。请引用该提交及日期,记录您阅读的章节标题而不是编号。这样,即使一年后,您的笔记仍然可以核查。书稿采用 CC BY-NC-SA 4.0 许可协议发布,构建脚本采用 MIT 许可协议。课程本身的最后一课也是同样的原则:如果一个策略无法基于固定的数据快照重新运行,那它只是一个故事,而不是结果。
常见问题
可以从免费的开源书籍中学习量化交易吗?
可以用它建立知识框架。开放手稿还允许您根据来源核查每项结论。但书籍无法提供您所在市场的数据、交易成本和规则。也正因为如此,为某个交易所编写的课程大纲,往往无法完全适用于您的经纪商。
量化课程的哪个阶段最容易让初学者受挫?
回测阶段。这里有两个错误,都会让结果看起来更好。其一是幸存者偏差,即事后组建股票池。其二是前视偏差,即以时钟尚未记录的价格成交。50% 当周交易的股票代码中,只有 2016 在十年后仍在交易。
幸存者偏差与前视偏差有什么区别?
幸存者偏差是股票池问题。测试对象之所以入选,是因为它们存续了下来。前视偏差是时点问题。策略使用了下单时尚不存在的数据。前者扩大了股票池,后者抬高了成交价格。
中国 A 股量化课程适用于美股吗?
方法可以适用,市场规则则不同。您可以保留阶段顺序、防止过拟合的纪律和成本核算方法。但在投入资金前,必须将数据处理、T+1 卖出限制、每日价格涨跌幅限制和交易单位替换为美国市场对应的规则。
上方每个面板都是一条存储查询,下面附有其 SQL。打开其中一条,替换股票代码或日期,然后在 Strasmore 终端上自行运行。