iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 9
2
AI & Data

量化交易30天系列 第 9

量化交易30天 Day9 - 撰寫一個均線策略

量化交易30天
本系列文章是紀錄一位量化交易新手的學習過程,除了基礎的Python語法不說明,其他金融相關的東西都會一步步地說明,希望讓更多想學習量化交易但是沒有學過相關金融知識的朋友們,透過這系列的文章,能夠對量化交易略知一二,也歡迎量化交易的高手們多多交流。

上一篇介紹了TA-Lib函數庫,這篇就來寫一下怎麼使用均線寫策略吧,搭配TA-Lib的強大運算,可以很快速地寫出一個策略。

這次要寫的策略就做均線交叉策略,當5日均線向上穿越10日均線的時候買進,當5日均線向下穿越10日均線的時候賣出。(策略僅為個人練習程式使用,實際交易需自行制定買賣策略)

步驟如下(略過前面串接資料的部分):

用talib計算5ma與10ma

# 取開盤價、收盤價
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玩轉金融數據,從個股基本面、技術面、籌碼面相關資料,一直到總體經濟數據,都是平常接觸到的素材;對於投資,除了研究歷史數據,也喜歡瞭解市場上大家在玩些什麼。


上一篇
量化交易30天 Day8 - 好用的技術指標函數庫TA-Lib
下一篇
量化交易30天 Day10 - backtrader回測框架實作(一)均線交叉策略
系列文
量化交易30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言