Python 金融交易实用指南(四)(4)https://developer.aliyun.com/article/1523805
基于时间序列预测的策略学习
基于时间序列预测的策略取决于在未来某个时间点准确估计股票价格以及其相应置信区间。通常,估计的计算非常耗时。
简单交易规则则包括最后已知价格与未来价格或其下限/上限置信区间值之间的关系。
更复杂的交易规则包括基于趋势分量和季节性分量的决策。
SARIMAX 策略
该策略基于最基本的规则:如果当前价格低于预测的 7 天后价格,则持有股票:
%matplotlib inline from zipline import run_algorithm from zipline.api import order_target_percent, symbol, set_commission from zipline.finance.commission import PerTrade import pandas as pd import pyfolio as pf import pmdarima as pm import warnings warnings.filterwarnings('ignore') def initialize(context): context.stock = symbol('AAPL') context.rolling_window = 90 set_commission(PerTrade(cost=5)) def handle_data(context, data): price_hist = data.history(context.stock, "close", context.rolling_window, "1d") try: model = pm.auto_arima(price_hist, seasonal=True) forecasts = model.predict(7) order_target_percent(context.stock, 1.0 if price_hist[-1] < forecasts[-1] else 0.0) except: pass def analyze(context, perf): returns, positions, transactions = \ pf.utils.extract_rets_pos_txn_from_zipline(perf) pf.create_returns_tear_sheet(returns, benchmark_rets = None) start_date = pd.to_datetime('2017-1-1', utc=True) end_date = pd.to_datetime('2018-1-1', utc=True) results = run_algorithm(start = start_date, end = end_date, initialize = initialize, analyze = analyze, handle_data = handle_data, capital_base = 10000, data_frequency = 'daily', bundle ='quandl')
输出如下:
图 9.97 – SARIMAX 策略;摘要收益和风险统计
在交易期内,该策略表现出很高的尾部比率1.95
,但稳定性很低,为0.25
。最大回撤率为-7.7%
,表现优异。
以下是最差五个回撤期的图表:
图 9.98 – SARIMAX 策略;最差五个回撤期
最差的回撤期显示了净回撤量低于-10%
的幅度。
以下是累积收益图表:
图 9.99 – SARIMAX 策略;投资期内累积收益
累积收益图表证明我们只在交易期的前半段进行了交易。
以下是收益图表:
图 9.100 – SARIMAX 策略;投资期内收益
收益图表显示,收益幅度的波动比其他策略大。
以下是滚动波动率图表:
图 9.101 – SARIMAX 策略;投资期内 6 个月滚动波动率
滚动波动率 图表显示,随着时间的推移,滚动波动率已经减少。
以下是 滚动夏普比率 图表:
图 9.102 - SARIMAX 策略;投资视角下的 6 个月滚动夏普比率
滚动夏普比率 图表显示,交易视角下前半段的夏普比率非常好,然后开始下降。
以下是 前 5 个回撤期间 图表:
图 9.103 - SARIMAX 策略;投资视角下前五个最糟糕的回撤期间
前 5 个回撤期间 图表显示,最糟糕的回撤期是整个交易窗口的后半段。
以下是 月度回报、年度回报 和 月度回报分布 图表:
图 9.104 - 月度回报、年度回报以及投资视角下月度回报的分布
月度回报 表格证实,我们在 2017 年下半年没有进行交易。年度回报 图表显示 2017 年的回报为正,并且 月度回报分布 图表呈现负偏态和大峰度。
在测试的时间范围内,SARIMAX 策略的进入规则并没有经常被触发。但是,它产生了夏普比率为 1.01,最大回撤为 -7.7%。
Prophet 策略
此策略基于预测置信区间,因此比以前的策略更加健壮。此外,Prophet 预测比 SARIMAX 更能应对频繁变化。回测结果完全相同,但是预测算法显著更好。
只有当最后价格低于置信区间的下限值时(我们预计股价将上涨)才购买股票,并且只有当最后价格高于预测置信区间的上限值时才卖出股票(我们预计股价将下跌):
%matplotlib inline from zipline import run_algorithm from zipline.api import order_target_percent, symbol, set_commission from zipline.finance.commission import PerTrade import pandas as pd import pyfolio as pf from fbprophet import Prophet import logging logging.getLogger('fbprophet').setLevel(logging.WARNING) import warnings warnings.filterwarnings('ignore') def initialize(context): context.stock = symbol('AAPL') context.rolling_window = 90 set_commission(PerTrade(cost=5)) def handle_data(context, data): price_hist = data.history(context.stock, "close", context.rolling_window, "1d") price_df = pd.DataFrame({'y' : price_hist}).rename_axis('ds').reset_index() price_df['ds'] = price_df['ds'].dt.tz_convert(None) model = Prophet() model.fit(price_df) df_forecast = model.make_future_dataframe(periods=7, freq='D') df_forecast = model.predict(df_forecast) last_price=price_hist[-1] forecast_lower=df_forecast['yhat_lower'].iloc[-1] forecast_upper=df_forecast['yhat_upper'].iloc[-1] if last_price < forecast_lower: order_target_percent(context.stock, 1.0) elif last_price > forecast_upper: order_target_percent(context.stock, 0.0) def analyze(context, perf): returns, positions, transactions = \ pf.utils.extract_rets_pos_txn_from_zipline(perf) pf.create_returns_tear_sheet(returns, benchmark_rets = None) start_date = pd.to_datetime('2017-1-1', utc=True) end_date = pd.to_datetime('2018-1-1', utc=True) results = run_algorithm(start = start_date, end = end_date, initialize = initialize, analyze = analyze, handle_data = handle_data, capital_base = 10000, data_frequency = 'daily', bundle ='quandl')
输出如下:
图 9.105 - Prophet 策略;摘要回报和风险统计
与 SARIMAX 策略相比,Prophet 策略显示出更好的结果 - 尾部比率为 1.37
,夏普比率为 1.22
,最大回撤为 -8.7%
。
以下是前五个最糟糕的回撤期间图表:
图 9.106 - Prophet 策略;前五个最糟糕的回撤期间
前五个最糟糕的回撤期间证实,最糟糕的净回撤幅度低于 10%。
以下是累积回报图表:
图 9.107 – 先知策略;投资周期内的累积回报
累积回报 图表显示,虽然我们在某些时间段没有进行交易,但入场/出场规则比 SARIMAX 策略更为稳健 – 对比两个累积回报图表。
以下是回报图表:
图 9.108 – 先知策略;投资周期内的回报
回报图表表明正回报超过了负回报。
以下是滚动波动率图表:
图 9.109 – 先知策略;投资周期内的 6 个月滚动波动率
滚动波动率 图表显示几乎恒定的滚动波动率 – 这是先知策略的特点。
以下是滚动夏普比率图表:
图 9.110 – 先知策略;投资周期内的 6 个月滚动夏普比率
-.50
和 1.5
。
以下是前 5 个回撤期图表:
图 9.111 – 先知策略;投资周期内前五个回撤期
前 5 个回撤期图表显示,尽管回撤期相当严重,但算法能够很好地处理它们。
以下是月度回报、年度回报和月度回报分布图表:
图 9.112 – 先知策略;月度回报、年度回报和月度回报分布
月度回报表格确认我们每个月都进行了交易,年度回报良好,如年度回报图表所示。月度回报分布图表呈正偏态,峰度较小。
先知策略是最稳健的策略之一,能够迅速适应市场变化。在给定的时间段内,它产生了 1.22 的夏普比率,最大回撤为 -8.7。
概要
在本章中,我们了解到,算法交易策略由模型、入场/离场规则、头寸限制以及其他关键属性定义。我们展示了在 Zipline 和 PyFolio 中设置完整的回测和风险分析/头寸分析系统是多么容易,这样你就可以专注于策略的开发,而不是浪费时间在基础设施上。
尽管前述策略已广为人知,但通过明智地组合它们,以及智能地选择入场和退出规则,你可以构建高度盈利的策略。
一帆风顺!
附录 A:如何设置 Python 环境
本书的 GitHub 存储库(github.com/PacktPublishing/Hands-On-Financial-Trading-with-Python/
)包含 Jupyter 笔记本,将帮助你复制此处显示的输出。
该环境是通过手动选择所有包含的软件包的兼容版本创建的。
第十章:技术要求
本书中的代码可以在 Windows、Mac 或 Linux 操作系统上运行。
初始设置
要设置 Python 环境,请按照以下步骤进行操作:
- 如果尚未安装 Anaconda Python,请从
www.anaconda.com/products/individual
下载并安装。 git clone
存储库:
git clone XXXXX
- 将当前目录更改为克隆的 GitHub 存储库。
- 运行以下代码:
conda env create -f handson-algorithmic-trading-with-python\environment.yml -n handson-algorithmic-trading-with-python
- 更改活动环境:
conda activate handson-algorithmic-trading-with-python
- 设置市场访问的全局环境变量:
图 1 – 各种变量名及其免费令牌获取位置的表 - 使用 Windows 的控制面板,设置系统环境:
Export QUANDL_API_KEY=xxxx
- 关闭命令提示符,以激活全局环境变量。
- 继续执行
environment.yml
文件,该文件是在修复了一个软件包的元文件中的拼写错误后,使用conda env export > environmenmt.yml
命令生成的。
下载免费的 Quandl 数据包
步骤如下:
- 更改活动环境:
conda activate handson-algorithmic-trading-with-python
- 如果您尚未通过 Window 的控制面板或使用
.bash_profile
或.bashrc
设置过QUANDL_API_KEY
值,请设置它。
对于 Windows,请使用以下命令:
SET QUANDL_API_KEY=XXXXXXXX
- 对于 Mac/Linux,请使用以下命令:
export QUANDL_API_KEY=XXXXXXXX
- 摄取数据:
zipline ingest -b quandl
- 注意
你不需要重复下载这个包。数据已经不再更新。
安装好环境后,请按照以下步骤进行操作:
- 将当前目录更改为克隆的 GitHub 存储库。
- 更改活动环境:
conda activate handson-algorithmic-trading-with-python
- 启动 Jupyter Lab,如下所示:
jupyter lab