【譯】Python 金融:算法交易 (5)評(píng)估交易策略

本文翻譯自2018年最熱門的Python金融教程 Python For Finance: Algorithmic Trading

本教程由以下五部分內(nèi)容構(gòu)成:

本文是該教程的最后一部分。


改進(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à)值(EV)除以最初的價(jià)值(BV)。然后對(duì)該比值求 1/n 冪次,這里 n 是投資的期數(shù)。最后將上面的結(jié)果減去 1,就得到了復(fù)合年增長率。

也許使用公式來說明會(huì)更清楚:

(EV / BV)^{1/n} - 1

注意,在下方的代碼框中,考慮的是天數(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,321評(píng)論 6 543
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,559評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,442評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,835評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,581評(píng)論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,922評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,931評(píng)論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,096評(píng)論 0 290
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,639評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,374評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,591評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,104評(píng)論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,789評(píng)論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,196評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,524評(píng)論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,322評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,554評(píng)論 2 379

推薦閱讀更多精彩內(nèi)容