最近一直在折腾量化交易这块,从数据获取到策略回测踩了不少坑。Python凭借其丰富的数据科学生态(pandas、numpy、matplotlib),加上各种现成的量化库,确实是最适合入门量化的语言。这篇文章就系统的整理一下怎么用Python从零开始搭建一套量化交易工具链。从数据获取到策略编写,再到回测验证,一条龙安排明白。
一、环境准备:搭建量化开发环境
做量化交易第一步就是环境搭建。Python的量化生态非常成熟,下面这些库是必备的:
pandas:数据处理的核心,DataFrame是量化分析的基础数据结构
numpy:数值计算,矩阵运算效率极高
matplotlib / mplfinance:数据可视化,画K线图必备
akshare / baostock:A股数据获取,免费且覆盖全面
backtrader:业界最流行的回测框架
直接pip一把梭:
pip install pandas numpy matplotlib mplfinance akshare backtrader tushare
建议在虚拟环境里安装,避免跟其他项目的依赖打架。创建虚拟环境也很简单:
python -m venv quant_env
# Windows激活
quant_envScriptsactivate
# macOS/Linux激活
source quant_env/bin/activate二、数据获取:从哪里拿数据
做量化最头疼的事情之一就是数据源。以前都得花钱买数据,现在好多了,Python生态有几个非常好用的免费数据源。
使用 akshare 获取A股数据
akshare 是我用得比较多的库,接口丰富,覆盖了股票、基金、期货、外汇等各类数据:
import akshare as ak
import pandas as pd
# 获取A股个股历史行情(日K)
stock_zh_a_hist_df = ak.stock_zh_a_hist(
symbol="000001", # 股票代码
period="daily", # 日线
start_date="20240101",
end_date="20240701",
adjust="qfq" # 前复权
)
print(stock_zh_a_hist_df.head())
使用 baostock 获取数据
baostock 是另一个不错的免费数据源,数据质量稳定:
import baostock as bs
import pandas as pd
# 登录
lg = bs.login()
# 获取沪深300日K线数据
rs = bs.query_history_k_data_plus(
"sh.600000",
"date,code,open,high,low,close,volume,amount",
start_date='2024-01-01',
end_date='2024-07-01',
frequency="d",
adjustflag="2" # 前复权
)
data_list = []
while (rs.error_code == '0') and rs.next():
data_list.append(rs.get_row_data())
result = pd.DataFrame(data_list, columns=rs.fields)
bs.logout()
两个库各有优劣,akshare 接口更丰富但偶尔会因网站改版出问题,baostock 更稳定但数据种类少一些。建议两个都装上,哪个好用用哪个。
三、编写第一个策略:双均线策略
数据拿到了,接下来写一个经典的量化策略——双均线策略(Golden Cross)。
核心逻辑很简单:当短期均线上穿长期均线时买入(金叉),当短期均线下穿长期均线时卖出(死叉)。这是趋势跟踪的经典玩法。
import pandas as pd
import numpy as np
def double_ma_strategy(df, short_window=5, long_window=20):
"""
双均线策略
:param df: 包含close列的DataFrame
:param short_window: 短期均线窗口
:param long_window: 长期均线窗口
:return: 带信号的DataFrame
"""
data = df.copy()
# 计算短期和长期移动平均线
data['MA_short'] = data['close'].rolling(window=short_window).mean()
data['MA_long'] = data['close'].rolling(window=long_window).mean()
# 生成信号
data['signal'] = 0
# 当短期均线 > 长期均线时 signal = 1(买入)
data.loc[data['MA_short'] > data['MA_long'], 'signal'] = 1
# 当短期均线 < 长期均线时 signal = -1(卖出)
data.loc[data['MA_short'] < data['MA_long'], 'signal'] = -1
# 计算持仓变化(只有信号变化时才交易)
data['position'] = data['signal'].diff()
return data
# 使用示例
# 假设已经从akshare获取了股票数据
result = double_ma_strategy(stock_zh_a_hist_df)
print(result[['close', 'MA_short', 'MA_long', 'signal', 'position']].tail(10))四、回测验证:策略到底赚不赚钱
策略写出来了,不能直接拿去实盘,得先回测看看历史表现。自己写一个简单的回测引擎也不难:
def backtest(df, initial_capital=100000, trade_size=100):
"""
简单的回测函数
:param df: 包含signal列的DataFrame
:param initial_capital: 初始资金
:param trade_size: 每次交易股数
"""
data = df.copy()
capital = initial_capital
position = 0 # 持仓数量
portfolio_values = []
for i in range(len(data)):
price = data.iloc[i]['close']
signal = data.iloc[i]['position']
# 买入信号(从0变成1)
if signal == 1 and position == 0:
buy_amount = trade_size
cost = buy_amount * price
if capital >= cost:
position = buy_amount
capital -= cost
# 卖出信号(从1变成-1)
elif signal == -1 and position > 0:
capital += position * price
position = 0
# 记录每日总资产
total = capital + position * price
portfolio_values.append(total)
data['portfolio_value'] = portfolio_values
final_value = capital + position * data.iloc[-1]['close']
total_return = (final_value - initial_capital) / initial_capital * 100
print(f"初始资金: {initial_capital}")
print(f"最终资产: {final_value:.2f}")
print(f"总收益率: {total_return:.2f}%")
return data
使用 backtrader 专业回测
自己写回测练手可以,但真要分析策略表现,还是用 backtrader 这种专业框架更靠谱。backtrader 内置了收益率、夏普比率、最大回撤等指标:
import backtrader as bt
class DoubleMAStrategy(bt.Strategy):
params = (('short_period', 5), ('long_period', 20))
def __init__(self):
self.short_ma = bt.indicators.SMA(
self.data.close, period=self.params.short_period)
self.long_ma = bt.indicators.SMA(
self.data.close, period=self.params.long_period)
def next(self):
if not self.position:
# 金叉买入
if self.short_ma[0] > self.long_ma[0]:
self.buy(size=100)
else:
# 死叉卖出
if self.short_ma[0] < self.long_ma[0]:
self.sell(size=100)
# 运行回测
cerebro = bt.Cerebro()
cerebro.addstrategy(DoubleMAStrategy)
# 加载数据(需要先转换成backtrader的格式)
data = bt.feeds.PandasData(dataname=stock_zh_a_hist_df)
cerebro.adddata(data)
cerebro.broker.setcash(100000.0)
print(f'初始资金: {cerebro.broker.getvalue():.2f}')
cerebro.run()
print(f'最终资金: {cerebro.broker.getvalue():.2f}')
cerebro.plot()五、可视化分析:一图胜千言
回测做完了,看看图表更直观。用 mplfinance 画K线和均线:
import mplfinance as mpf
# 准备数据(需要符合mplfinance的格式)
plot_df = stock_zh_a_hist_df.copy()
plot_df.index = pd.to_datetime(plot_df['date'])
plot_df.columns = [c.lower() for c in plot_df.columns]
# 添加均线
ap = [
mpf.make_addplot(result['MA_short'], color='blue', width=0.8),
mpf.make_addplot(result['MA_long'], color='red', width=0.8),
]
# 画K线
mpf.plot(
plot_df[-60:], # 最近60个交易日
type='candle',
style='charles',
title='双均线策略K线图',
ylabel='价格',
addplot=ap,
volume=True
)
六、总结
这篇文章从环境搭建、数据获取、策略编写、回测验证到可视化分析,走完了一个量化交易的完整流程。总结几个关键点:
数据是基础:akshare 和 baostock 对个人开发者来说足够用,免费且稳定
从简单策略开始:双均线虽然经典但已经能跑通整个流程,后续可以尝试更复杂的策略
一定要回测:任何策略在实盘之前都要经过严格的回测验证,backtrader 是好帮手
控制风险:量化交易不是印钞机,回测好看不代表实盘能赚,仓位管理和风控同样重要
量化交易的路很长,这篇文章只是带你入了门。后续可以深入的方向还有很多:多因子模型、机器学习策略、期权定价、高频交易等等。如果对某个方向感兴趣,后面可以单独开文章聊。