量化交易30天
本系列文章是紀錄一位量化交易新手的學習過程,除了基礎的Python語法不說明,其他金融相關的東西都會一步步地說明,希望讓更多想學習量化交易但是沒有學過相關金融知識的朋友們,透過這系列的文章,能夠對量化交易略知一二,也歡迎量化交易的高手們多多交流。
上一篇介紹了TA-Lib函數庫,這篇就來寫一下怎麼使用均線寫策略吧,搭配TA-Lib的強大運算,可以很快速地寫出一個策略。
這次要寫的策略就做均線交叉策略,當5日均線向上穿越10日均線的時候買進,當5日均線向下穿越10日均線的時候賣出。(策略僅為個人練習程式使用,實際交易需自行制定買賣策略)
# 取開盤價、收盤價
close = SPY_adj.Close
Open = SPY_adj.Open
Open2019 = Open['2019']
# 計算均線
import talib
ma5 = talib.SMA(close, timeperiod=5)
ma10 = talib.SMA(close, timeperiod=10)
# 繪圖
import matplotlib.pyplot as plt
plt.figure(figsize=(15,10))
plt.plot(ma5['2019'])
plt.plot(ma10['2019'])
plt.legend(['5ma','10ma'])
plt.xticks(rotation='vertical')
取2019年的資料畫圖看看:
從上圖可以看出,5ma與10ma有許多互相穿越的地方,這些就有可能會是買賣點。
# 5ma與10ma差距
MA_dif = ma5 - ma10
MA_dif = MA_dif['2019']
# 參數
stock = 0
sig = []
# 訊號
for i in range(len(MA_dif)):
# 5MA往上穿越10MA
if MA_dif[i-1] < 0 and MA_dif[i] > 0 and stock == 0:
stock += 1
sig.append(1)
# 5MA往下穿越10MA
elif MA_dif[i-1] > 0 and MA_dif[i] < 0 and stock == 1:
stock -= 1
sig.append(-1)
else:
sig.append(0)
# 製作dataframe
import pandas as pd
ma_sig = pd.Series(index = MA_dif.index, data = sig)
ma_sig_2019 = ma_sig['2019']
為了簡化回測的計算,一樣是採取訊號出現後,就採取隔日開盤全部買進或是全部賣出的方式,然後賣出得到的現金在下次買入訊號出現的時候,就全部買入,如果資料日期的最後一天仍然有部位的話,就用最後一天的開盤價全部賣掉。
# 每次買賣的報酬率
rets = []
transaction = []
# 是否仍有庫存
stock = 0
stock_his = []
# 當次交易買入價格
buy_price = 0
# 當次交易賣出價格
sell_price = 0
# 每次買賣的報酬率
for i in range(len(ma_sig_2019)-1):
stock_his.append(stock)
if ma_sig_2019[i] == 1:
# 隔日開盤買入
buy_price = Open2019[ma_sig_2019.index[i+1]]
stock += 1
# 紀錄交易日期
transaction.append([ma_sig_2019.index[i+1],'buy'])
elif ma_sig_2019[i] == -1:
# 隔日開盤賣出
sell_price = Open2019[ma_sig_2019.index[i+1]]
stock -= 1
rets.append((sell_price-buy_price)/buy_price)
# 賣出後就清空資料
buy_price = 0
sell_price = 0
# 紀錄交易日期
transaction.append([ma_sig_2019.index[i+1],'sell'])
# 如果最後手上有庫存,就用回測區間最後一天的開盤價賣掉
if stock == 1 and buy_price != 0 and sell_price == 0:
sell_price = Open2019[-1]
rets.append((sell_price-buy_price)/buy_price)
stock -= 1
transaction.append([Open2019.index[-1],'sell'])
# 總報酬率
total_ret = 1
for ret in rets:
total_ret *= 1 + ret
# print(str(round((total_ret - 1)*100,2)) + '%')
print('總報酬率:' + str(round(100*(total_ret-1),2)) + '%')
transaction
------
總報酬率:12.72%
[[Timestamp('2019-03-15 00:00:00+0000', tz='UTC'), 'buy'],
[Timestamp('2019-03-27 00:00:00+0000', tz='UTC'), 'sell'],
[Timestamp('2019-04-02 00:00:00+0000', tz='UTC'), 'buy'],
[Timestamp('2019-05-07 00:00:00+0000', tz='UTC'), 'sell'],
[Timestamp('2019-05-22 00:00:00+0000', tz='UTC'), 'buy'],
[Timestamp('2019-05-24 00:00:00+0000', tz='UTC'), 'sell'],
[Timestamp('2019-06-10 00:00:00+0000', tz='UTC'), 'buy'],
[Timestamp('2019-07-02 00:00:00+0000', tz='UTC'), 'sell'],
[Timestamp('2019-07-03 00:00:00+0000', tz='UTC'), 'buy'],
[Timestamp('2019-07-23 00:00:00+0000', tz='UTC'), 'sell'],
[Timestamp('2019-07-29 00:00:00+0000', tz='UTC'), 'buy'],
[Timestamp('2019-08-02 00:00:00+0000', tz='UTC'), 'sell'],
[Timestamp('2019-08-15 00:00:00+0000', tz='UTC'), 'buy'],
[Timestamp('2019-08-16 00:00:00+0000', tz='UTC'), 'sell'],
[Timestamp('2019-08-23 00:00:00+0000', tz='UTC'), 'buy'],
[Timestamp('2019-08-29 00:00:00+0000', tz='UTC'), 'sell'],
[Timestamp('2019-09-04 00:00:00+0000', tz='UTC'), 'buy'],
[Timestamp('2019-09-25 00:00:00+0000', tz='UTC'), 'sell'],
[Timestamp('2019-10-15 00:00:00+0000', tz='UTC'), 'buy'],
[Timestamp('2019-12-06 00:00:00+0000', tz='UTC'), 'sell'],
[Timestamp('2019-12-11 00:00:00+0000', tz='UTC'), 'buy'],
[Timestamp('2019-12-31 00:00:00+0000', tz='UTC'), 'sell']]
本篇總結
這篇練習用TA-Lib寫了一個均線交叉的策略,到目前為止,我都是自己寫一個回測函數來算報酬率,不過其實市面上已經有比較完整的回測框架可以使用,而且功能蠻強大的,可以自訂策略,買賣的部位也可以用程式撰寫,下一篇就來講一下開源回測框架,請繼續收看。
P.S.
如果大家對於量化交易有興趣的話,我自己有上過以下這門課,課程內容從串接股市資料API、儲存至資料庫、將自己的策略轉化成程式碼、自動下單,並且可以把整個流程自動化,每天早上執行一次,一整天就不用看盤了,覺得是蠻實戰的,可以參考看看。
筆者 Sean
奈米戶投資人 / Python愛用者
喜歡用Python玩轉金融數據,從個股基本面、技術面、籌碼面相關資料,一直到總體經濟數據,都是平常接觸到的素材;對於投資,除了研究歷史數據,也喜歡瞭解市場上大家在玩些什麼。