第二章:1 打造八種趨勢交易策略


Posted by nightqwq on 2021-12-11

練習版程式碼連結:https://colab.research.google.com/drive/1u_uLl79ZHgIxn_IlYTsLNMNorRm3KsXa?usp=sharing

(請參考第一章第一節來啟動該筆記本)

在這一節,我們將利用各種不同的 filters 來研發八種趨勢交易策略。


a. 什麼是趨勢交易

趨勢交易就是買進上漲趨勢的股票。買了以後就一直抱著,直到趨勢結束。

跟上一章的雙均線不同,趨勢交易並不會藉由均線走勢來判斷進出場,而是根據不同的指標來判斷一個趨勢的結束與開始,趨勢開始時買進,趨勢結束時賣出。


b. 單 filters 撰寫

請開啟本節開頭的筆記本來一起練習。

為了測試我們的 filters 對於價格變化有何反應,我們需建立一條簡單的時間序列:

import pandas as pd

s = pd.Series([0] * 200 + [1] * 300 + [0] * 200)

s.plot()

然後開始引入 filters:

from finlab_crypto import indicators

當你輸入「indicators??」時,會跳出這行程式碼的說明:

圖上顯示了八種不同的 filters,有空可以在裡面探索看看,我們先拿出一種 filters 來做策略撰寫:

trend = indicators.trends['sma'](s, 50)

s.plot()

trend.plot()

在上述程式碼中,我們從 indicators 裡叫出了 sma 這個 filters,然後把價格丟進去(時間序列 s),並設定 filters 為每 50 日一個平均,之後傳到 trend 這個變數裡面,最後把價格和預測趨勢都畫出來。

由上圖可以看到,價格趨勢的預測線段(黃色線)由於在一邊確認價格是否從 0 變成 1,一邊進行運算的緣故,並不會百分百貼著價格跑。

那我們來研究其他 filters,是否能夠讓預測價格更加貼近實際價格。


c. 多 filters 撰寫

我們利用 for 迴圈的方式,把 indicators 裡面所有 filters 的名稱和其對應的函式一併列印出來:(因為 indicators 是字典,取出裡面的元素需要加上 items):

for name, func in indicators.trends.items():

  print(name, func)

接下來就要拿實際價格跟上面所有的 filters 做比較,看哪一條最接近實際價格。

其實做法與原本叫出 sma 的方法相似,先把 print 那行去掉,之後會像這樣:

s.plot()

for name, func in indicators.trends.items():

  trend = func(s, 50)

  trend.plot()

雖然很容易看出來,成九十度的藍色線段就是原本的價格,但是卻很難分辨到底哪條 filters 最貼近藍色線段,所以必須要改良這段程式碼。

首先在迴圈上方先建立一個 DataFrame,並把價格存進 DataFrame 裡面,然後再迴圈裡把預測價格存進 DataFrame 裡,並標註為 filters 的名稱。

直接畫出來,先顯示這個 DataFrame,程式碼看起來會像這樣:

filter_results = pd.DataFrame()

filter_results['original_price'] = s

for name, func in indicators.trends.items():

  trend = func(s, 50)

  filter_results[name] = trend

filter_results.plot()

我們可以看到,雖然「detrend」這條 filters 離原本價格最近,但同時突起比較大,導致有時候價格會失真。

所以究竟如何找到最適合的 filters 呢?我們來實際撰寫交易策略試試看。


d. 撰寫交易策略

先下載比特幣的歷史價格:

ohlcv = finlab_crypto.crawler.get_all_binance('BTCUSDT', '4h')

再來直接將第一章的策略複製過來:

close = ohlcv.close

sma20 = close.rolling(20).mean()

sma60 = close.rolling(60).mean()

entries = (sma20 > sma60) & (sma20.shift() < sma60.shift())

exits = (sma20 < sma60) & (sma20.shift() > sma60.shift())

close.plot()

sma20.plot()

sma60.plot()

entries.astype(int).plot(secondary_y=True)

(-exits.astype(int)).plot(secondary_y=True)

最後把雙均線改成趨勢交易,用言語說明有點難懂,請看下面的最終程式碼,會發現我們先是新增了一條filter ,再把兩條均線做修改,總共更動三個地方:

filter_name = 'wma'

close = ohlcv.close

sma20 = indicators.trends[filter_name](close, 20)

sma60 = indicators.trends[filter_name](close, 60)

entries = (sma20 > sma60) & (sma20.shift() < sma60.shift())

exits = (sma20 < sma60) & (sma20.shift() > sma60.shift())

close.plot()

sma20.plot()

sma60.plot()

entries.astype(int).plot(secondary_y=True)

(-exits.astype(int)).plot(secondary_y=True)

上述程式碼採用了 wma 這條 filters,我們可以對每條 filters 都這樣做,並一一打包成 strategy 且進行最佳化,然後各自比較,來看看哪一條的報酬率最高。


至此,我們學到了第二種交易策略。

下一節,我們來實際操作趨勢交易的策略打包及最佳化。


#加密貨幣 #Python







Related Posts

JS註冊組|JavaScript基本語法|JavaScript&jQuery網站互動設計程式進化之道

JS註冊組|JavaScript基本語法|JavaScript&jQuery網站互動設計程式進化之道

AI輔導室|製作相扣的紙花圈

AI輔導室|製作相扣的紙花圈

怎麼檢查 object 是不是空的?

怎麼檢查 object 是不是空的?


Comments