本文翻譯自2018年最熱門的Python金融教程 Python For Finance: Algorithmic Trading。
本教程由以下五部分內容構成:
- Python金融入門
- 常見的金融分析方法
- 簡單的動量策略開發
- 回溯測試策略
- 評估交易策略
本文是該教程的最后一部分。
改進交易策略
你已經成功地實現了一個簡單的交易策略,并使用 Pandas、ZipLine 和 Quantopian 進行了回溯測試??梢哉f你已入門了Python交易分析。然而,當你完成交易策略的編碼和回測,并不意味著工作的完成;可能還需要改進策略。有多種算法可以用來持續地改進模型,比如K均值、k最近鄰(KNN)、分類或回歸樹,以及遺傳算法。這將是今后DataCamp教程的內容。
除了可以使用其它算法之外,還可以通過使用多家公司的股票構建投資組合來改進策略。策略中僅有一家公司往往沒有太大意義。在評估移動均線交叉策略時,你還會看到這一點。其他可以做的就是使用風險管理框架或事件驅動的回溯測試來減輕之前提到的前視偏差。
評估移動均線交叉策略
即使改進了交易策略,也不意味著工作到此為止。使用 Pandas 能夠輕松地計算相關指標來進一步評估你的簡單交易策略。首先,使用夏普比率來了解你的投資組合回報,是否是你決定進行明智投資或承擔高風險的事實結果。
當然,最理想的情況是,回報可觀而投資的額外風險盡可能低。夏普比率是收益率和額外風險的比率,因此它的值越高越好。通常,該比率大于1時能被投資者接受,2是非常好的,3就是極好的了。
讓我們來看看該算法是如何實現的!
在開始之前,先獲取 apple 公司的股票數據,參考本教程的第一部分:基礎入門。
# 獲取apple公司股票數據
import pandas_datareader as pdr
import datetime
aapl = pdr.get_data_yahoo('AAPL',
start=datetime.datetime(2006, 10, 1),
end=datetime.datetime(2012, 1, 1))
然后是創建均線交叉策略,參考本教程的第三部分:用Python構建交易策略。
# 導入pandas,numpy
import pandas as pd
import numpy as np
# 初始化短期和長期窗口
short_window = 40
long_window = 100
# 初始化 `signals` 數據框,增加 `signal` 列
signals = pd.DataFrame(index=aapl.index)
signals['signal'] = 0.0
# 創建短期簡單移動均值
signals['short_mavg'] = aapl['Close'] \
.rolling(window=short_window, min_periods=1, center=False) \
.mean()
# 創建長期簡單移動均值
signals['long_mavg'] = aapl['Close'] \
.rolling(window=long_window, min_periods=1, center=False) \
.mean()
# 生成信號
signals['signal'][short_window:] = np.where(signals['short_mavg'][short_window:]
> signals['long_mavg'][short_window:], 1.0, 0.0)
# 生成交易命令
signals['positions'] = signals['signal'].diff()
接下來回測交易策略,參考本教程第四部分:回測交易策略。
# 設置初始資金
initial_capital= float(100000.0)
# 創建數據框 `positions`
positions = pd.DataFrame(index=signals.index).fillna(0.0)
# 當signal為1時,買入100股
positions['AAPL'] = 100*signals['signal']
# 用擁有的價值初始化 portfolio
portfolio = positions.multiply(aapl['Adj Close'], axis=0)
# 存儲股票數目的差值
pos_diff = positions.diff()
# 在 portfolio 中增加 `holdings` 列
portfolio['holdings'] = (positions.multiply(aapl['Adj Close'], axis=0)) \
.sum(axis=1)
# 在 portfolio 中增加`cash`列
portfolio['cash'] = initial_capital \
- (pos_diff.multiply(aapl['Adj Close'], axis=0)) \
.sum(axis=1).cumsum()
# 在 portfolio 中增加`total`列
portfolio['total'] = portfolio['cash'] + portfolio['holdings']
# 在 portfolio 中增加`returns` 列
portfolio['returns'] = portfolio['total'].pct_change()
下面開始對策略進行評估。
# 從策略中提取收益率
returns = portfolio['returns']
# 計算年化的夏普比率
sharpe_ratio = np.sqrt(252) * (returns.mean() / returns.std())
# 輸出夏普比率
print(sharpe_ratio)
0.7244202796907433
注意在本教程中,夏普比率的定義忽略了無風險利率。另外,通常不單獨考慮一只股票的夏普比率,一般將多只股票進行比較。解決該問題最好的方法是使用來自其他公司的更多數據,擴展最初的交易策略。
接下來,還可以計算最大回撤率(Maximum Drawdown),它用于測量在投資組合價值中,在下一次峰值來到之前,最高點和最低點之間的最大單次下降。換言之,該值代表了基于某個策略的投資組合風險。
import matplotlib.pyplot as plt
# 定義交易日的移動窗口
window = 252
# 為每一天計算過去時間窗口中最大回撤率
rolling_max = aapl['Adj Close'].rolling(window, min_periods=1).max()
daily_drawdown = aapl['Adj Close']/rolling_max - 1.0
# 計算最小的(負值)每日回撤率
max_daily_drawdown = daily_drawdown.rolling(window, min_periods=1).min()
# 繪圖
daily_drawdown.plot()
max_daily_drawdown.plot()
# 顯示繪圖
plt.show()
注意設置 min_periods
的值為 1
,這是為了使開始的252天也具有擴展的窗口。
其次是復合年增長率(CAGR),它是一段時間內的恒定回報率。換言之,該比率告訴你在投資期結束時,你真正獲得的收益??梢赃@么來計算,首先將投資最后的價值()除以最初的價值(
)。然后對該比值求
冪次,這里
是投資的期數。最后將上面的結果減去
,就得到了復合年增長率。
也許使用公式來說明會更清楚:
注意,在下方的代碼框中,考慮的是天數,所以將1調整為365天(等價于1年)。
# Get the number of days in `aapl`
days = (aapl.index[-1] - aapl.index[0]).days
# Calculate the CAGR
cagr = ((((aapl['Adj Close'][-1]) / aapl['Adj Close'][1])) ** (365.0/days)) - 1
# Print the CAGR
print(cagr)
0.3823444961078535
除了這兩項指標,還有許多其他指標可以考慮,比如收益分布、交易水平指標,等等。
接下來呢?
干的漂亮,你已經學完了這篇Python金融入門教程!雖然有了一定基礎,但仍有許多知識等待你來發現。從 DataCamp 的 Intro to Python for Finance 課程開始學習更多的基礎知識吧。
Yves Hilpisch 的 《Python For Finance》一書對具備金融背景卻不熟悉Python的讀者是非常好的一本書。 Michael Heydt 的《Mastering Pandas for Data Science》也非常推薦給想學習Python金融的讀者。同時也請查閱 Quantstart文章 中的算法交易入門指南,以及金融Python編程這一完整系列。
如果你對繼續使用R語言進行金融分析更感興趣,可以考慮參加 DataCamp 的 Quantitative Analyst with R 學習路徑。同時,請繼續關注我們關于使用Python進行金融分析的第二篇文章,并查看本教程的 Jupyter notebook。