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