
简介《量化投资以Python为工具》一书的课后习题配套资料包含习题答案、章节Python代码和所用CSV数据适合系统学习量化投资、希望对照习题检验理解并动手实现策略的读者。压缩包共78个文件涵盖37个CSV数据文件、34个Python脚本、5个TXT说明、1个PDF答案及1个Access数据库文件整体约91.84MB覆盖书中各章节练习与数据。已有1649人浏览学习。CSV数据多为模拟或真实行情数据可用于回测与统计分析Python脚本覆盖数据读取、预处理、特征构建到策略回测的完整流程PDF答案便于逐章核对帮助读者将金融理论与Python实现衔接起来提升量化投资实战能力。 整理《量化投资以Python为工具》课后习题这套资料是我最近清理旧硬盘时干的一件事。书买了挺久习题也断断续续做了不少但每次换电脑那些PDF答案、Python代码和CSV数据就散落一地下次想用又得重新翻半天。这次我狠下心把所有东西归档成了一个固定目录从环境搭建到逐题跑通全部重新过了一遍确认能复现才敢放出来。这篇文章就聊聊这套资料到底包含了什么、习题代码里反复出现的核心逻辑是什么、以及你在拿到这些PDF和CSV之后怎么把它们真正变成自己的东西。1. 这套资料解决的是什么问题1.1 这类习题卡住你的不是题目而是环境《量化投资以Python为工具》这本书的定位是给完全能写代码、但还没系统接触过量化的人做入门。它最大的特点是课后题基本没有“纯理论”的题目更不是那种用笔算两步就能出答案的选择题。十道题里有七八道要你下载行情数据、自己写策略函数、算收益曲线最后还要画图。这就带来一个很现实的问题你缺的可能不是解题思路而是那几份格式整齐的CSV数据以及一段能在我本地直接跑起来的参考代码。大多数自学的人卡在这里并不是因为不懂金融而是因为CSV文件给的字段和书里的例子对不上index、close、volume这些列名让人一头雾水代码环境不一致pandas版本、matplotlib中文字体、Python位数不同都会报各种诡异错误明明策略逻辑写对了但算出来的收益曲线和答案差很远因为数据复权方式没对齐。所以这份资料里的PDF答案其实是帮你“对答案”的代码是帮你“看过程”的CSV是帮你“跑起来”的三样缺一不可。1.2 资料包里到底有什么我把目录整理成了下面这个结构目录/文件作用answers/各章课后习题的答案PDF按章节编号命名codes/习题对应的Python源码每章一个.ipynb或.py文件data/习题用到的全部CSV数据包括日线行情、收益率序列等notebooks/我自己复现时写的完整Notebook带输出结果requirements.txt运行代码所需的Python依赖清单CSV文件是这份资料里最容易被忽略、但对新手最致命的部分。很多题目的前提是“用以下数据计算”你如果拿不到原数据就算看懂了答案代码也没法验证自己是不是真的懂了。我把所有CSV按用途重新命名比如stock_daily.csv、factor_data.csv、portfolio_returns.csv并在目录里放了一份字段说明文档标注了每一列的含义和日期范围。2. 习题代码里反复出现的三个核心点2.1 CSV读取与数据清洗所有题目的第一关几乎每一道课后习题的第一步都是读数据。书里用的数据集大多以CSV形式提供打开后你会看到类似这样的结构date,open,high,low,close,volume 2020-01-02,10.5,10.8,10.2,10.65,3456200 2020-01-03,10.7,11.1,10.6,11.0,3891200处理这种文件标准的做法是用pandasimport pandas as pd df pd.read_csv( data/stock_daily.csv, parse_dates[date], index_coldate ) df df.sort_index() print(df.head())这里有几个细节答案代码里经常出现但不会专门解释parse_dates[date]必须写否则日期会变成字符串对象后面做时间序列切片会出问题sort_index()很有必要。有些CSV数据行序是乱的如果不先排序算移动平均时rolling窗口取到的是错误顺序如果CSV文件是中文列名read_csv读进来后列名可能是乱码这时要检查文件编码一般encodinggbk或encodingutf-8二选一。我见过太多人卡在这一步代码往下写了两小时最后报错说“KeyError: close”结果一看列名其实是close前面多了个空格或者列名全部变成了中文乱码。所以拿到数据后第一件事永远是打印df.columns和df.dtypes这两行防御性代码能省下你大量时间。2.2 策略计算双均线、动量、均值回归的出镜率极高这本书的课后习题集中考察三类策略分别对应趋势跟踪、动量效应和均值回归思想。双均线策略在习题里出现频率最高核心逻辑并不复杂df[ma_short] df[close].rolling(window5).mean() df[ma_long] df[close].rolling(window20).mean() df[signal] 0 df.loc[df[ma_short] df[ma_long], signal] 1 df.loc[df[ma_short] df[ma_long], signal] -1动量策略的写法通常是计算过去N日的收益率再根据收益率正负做多或做空df[momentum] df[close] / df[close].shift(10) - 1 df[signal] 0 df.loc[df[momentum] 0, signal] 1 df.loc[df[momentum] 0, signal] -1均值回归策略则是反着来买入那些短期跌幅过大的标的df[zscore] ( df[close] - df[close].rolling(20).mean() ) / df[close].rolling(20).std() df[signal] 0 df.loc[df[zscore] -2, signal] 1 df.loc[df[zscore] 2, signal] -1你可能已经发现了这类题目的难点不在于“策略思想”而在于怎么用pandas把这些逻辑干净地表达出来。我整理习题答案时刻意保留了代码里的注释和中间变量调试过程就是希望你能看到每一步计算长什么样。看那本PDF答案的时候代码逻辑光靠眼睛过是没用的必须在本地逐行跑一遍。2.3 回测与绩效指标算收益是道送分题也是道送命题策略信号生成之后下一步一定是计算策略净值。这里有个非常容易踩坑的细节当天的信号不能当天用必须延迟一天执行。原因很现实你看到收盘价的那一刻已经没法再按这个价格成交了。所以正确的回测写法是这样df[ret] df[close].pct_change() df[strategy_ret] df[signal].shift(1) * df[ret] df[strategy_ret] df[strategy_ret].fillna(0) df[nav] (1 df[strategy_ret]).cumprod() print(df[[signal, ret, strategy_ret, nav]].tail())这里的核心就是shift(1)。如果忘了shift或者shift的位置不对策略净值就会被未来函数污染算出来的收益曲线漂亮得可疑但实盘里根本不可能复制。绩效指标也算固定套路。年化收益率、年化波动率、夏普比率和最大回撤在习题答案里频繁出现我自己整理了配套的函数nav df[nav] daily_ret df[strategy_ret] n_years len(nav) / 252 annual_return nav.iloc[-1] ** (1 / n_years) - 1 annual_vol daily_ret.std() * (252 ** 0.5) sharpe annual_return / annual_vol if annual_vol ! 0 else 0 rolling_max nav.cummax() drawdown nav / rolling_max - 1 max_drawdown drawdown.min()这几行代码几乎能覆盖书里八成以上的绩效类习题。唯一要注意的是pandas里std()默认是样本标准差分母是n-1有的习题答案可能用的是总体标准差导致夏普比率有效数字不同。这种情况不用慌跟PDF答案对一下确认对方用的是哪种定义就行。3. 从环境准备到完整复现一道题3.1 第一步把环境搭到“能跑”的状态如果你是从零开始建议先安装Miniconda然后创建一个专门的虚拟环境conda create -n quant python3.9 conda activate quant pip install pandas numpy matplotlib jupyter如果你需要画中文图不要忘了把matplotlib的中文字体设置好否则图片里全是方框很影响对照答案import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False环境这块我不建议装特别新的Python版本3.9到3.12之间都行但要注意某些老代码用到的pd.append()在新版本里被移除了遇到这种报错把它改成pd.concat()即可。3.2 完整走一遍流程以“双均线策略”例题为例我就拿整理资料时跑的其中一道题作为例子完整复现一遍。这道题要求从CSV读取某只股票的日线数据实现双均线策略并计算策略的年化收益率与最大回撤。流程并不复杂就五步读取CSV数据并打印基本信息计算5日和20日均线生成交易信号上穿做多、下穿做空用shift(1)对齐信号与收益率计算策略净值画净值曲线算出绩效指标与PDF答案做比对。我用的代码如下import pandas as pd import numpy as np import matplotlib.pyplot as plt df pd.read_csv(data/stock_daily.csv, parse_dates[date], index_coldate) df df.sort_index() df[ma_fast] df[close].rolling(5).mean() df[ma_slow] df[close].rolling(20).mean() df[signal] 0 df.loc[df[ma_fast] df[ma_slow], signal] 1 df.loc[df[ma_fast] df[ma_slow], signal] -1 df[ret] df[close].pct_change() df[strategy_ret] df[signal].shift(1) * df[ret] df[strategy_ret] df[strategy_ret].fillna(0) df[nav] (1 df[strategy_ret]).cumprod() plt.figure(figsize(10, 4)) plt.plot(df.index, df[nav], labelStrategy Nav) plt.plot(df.index, df[close] / df[close].iloc[0], labelBuy Hold) plt.legend() plt.title(Dual Moving Average Strategy) plt.show()跑完之后我把nav.iloc[-1]、最大回撤和PDF答案页上的数字做了对比前两位小数基本一致说明数据复权和计算口径没有问题。这一步很重要因为“能运行”和“结果对”是两回事很多代码能跑但结果跟参考答案差得离谱多半是数据版本不一致。3.3 看PDF答案的正确方式很多同学拿到PDF答案的第一反应是直接翻到最后抄代码我的建议恰恰相反。你先自己把题做一遍哪怕做错、跑不通都行然后再打开PDF对着看。重点不是抄那一行代码是怎么写的而是看他为什么要那么写。比如说PDF答案里算收益率的时候有一步把收益率去均值了你就要想他是为了算超额收益还是为了处理系统性波动我整理的答案PDF里不少代码都会多写一两步看起来“多余”的操作这正是作者埋的思路提示碰到这种地方值得停下来多琢磨一下而不是一把梭跳过去。4. 踩坑记录这套CSV和代码里容易翻车的地方4.1 常见问题速查表这段时间复现下来我把自己撞过的墙和后台读者问过的问题整理成了一张表你可以直接当排查手册用问题现象可能原因解决方式KeyError: closeCSV列名含空格或大小写不一致打印df.columns用df.columns.str.strip()清理中文乱码文件编码与读取编码不一致依次尝试encodingutf-8与encodinggbk日期列变成字符串未指定parse_datespd.to_datetime(df[date])后再设为索引信号全为0rolling(20)窗口内数据不足检查数据起始位置取有效段再计算策略净值第一天为NaNpct_change()导致首行无收益率.fillna(0)填充初始位置年化收益异常大忘了shift(1)信号使用了当日收益回测中一律signal.shift(1)延迟执行画图中文显示为方框matplotlib缺少中文字体或未配置设置plt.rcParams[font.sans-serif]4.2 几个容易被忽略的细节第一CSV文件里如果有空行或注释行read_csv默认会当作NaN处理你算均线的时候会发现结果变成了一整条断线。最稳妥的办法是读取后先df.isnull().sum()检查一遍再决定是前向填充还是直接剔除。第二复权数据和不复权数据差异很大。书里有些章节使用的是前复权价格有些则用不复权价格两者算出来的收益曲线完全不同。我在data/目录里特意用文件名做了区分比如stock_daily_qfq.csv代表前复权。如果你用自己下载的数据替换务必先确认复权方式否则结果和PDF答案永远对不上。第三浮点数比较问题。很多习题让你判断“金叉还是死叉”你不能直接写ma_fast ma_slow然后对比两个浮点数因为pandas里的浮点计算会有微小误差。更稳妥的做法是在判断前保留足够多的小数位或者用np.isclose来处理。5. 这套资料怎么用我的经验是把它当成“项目模板”最后聊点我自己的使用习惯。我整理完这份资料后并没有把它当题库去刷而是当成一套“量化项目的脚手架”。每章习题其实就是一个小项目数据读取、策略设计、回测评估这几个环节循环几次基本的量化研究流程就刻在脑子里了。我现在重新用这套资料的方式是先只看题目不看答案PDF自己写代码写完以后跑一遍记录下结果再打开PDF对照重点看差异点在哪里。很多题目的答案代码并不是唯一解比如移动平均的策略有的答案用的周期是5和20你完全可以改成10和30看看结果怎么变。这样折腾几轮你对pandas的熟练度和策略直觉都会明显提升。另外如果你还不太会用Git我强烈建议把这个资料目录初始化成一个仓库每做完一道题就把改动提交一次。这样你回头看时能清清楚楚地看到自己一开始写的笨代码是怎么一步步优化的这个过程本身比题目答案更值钱。我自己回看之前提交的第一版均线策略代码说实话写得挺难看的但正是那次提交记录让我知道了自己是从哪里开始进步的。本文还有配套的精品资源点击获取