目錄
- 1. 概念介紹
- 2.計算動量
- 2.1 作差法求動量
- 2.2 作除法求動量
- 3.定義求動量與作圖函式
- 4. 繪制K線圖與動量圖
- 5. 動量交易策略的制定
1. 概念介紹
動量交易策略,即Momentum Trading Strategy,在經典力學里,動量即物體質量和速度的乘積,動量一方面描述了物體的運動狀態,另一方面也描述了慣性的大小,
在證券市場上,我們也可以把“證券的價格”類比成運動的物體,價格上漲時,可以說價格有著上漲的動量,價格下跌時其具有下跌的動量,這種動量可能會使上漲或下跌繼續維持下去,也可能該動量會越來越小,直到使之運動狀態發生改變,股票資產組合的中期收益存在延續性,即中期價格具有向某一方向連續變動的動量效應,
關于動量產生的原因,有三種說法:
- 反應不足,即利好或利空不能一次完全消化,會持續在股價上體現,
- 正反饋模式,即贏者恒贏,輸者恒輸,
- 過度反應,即投資人對資訊的高估而作出的決策,
2.計算動量
2.1 作差法求動量
即用今天的價格減去一段時間間隔(m期)以前的價格
M
o
m
e
n
t
u
m
t
=
P
t
?
P
t
?
m
\displaystyle Momentum_t = P_t-P_{t-m}
Momentumt?=Pt??Pt?m?
Momentumt為該股票t時期的m期動量
Pt為該股票t時期的價格
Pt-m為該股票在t-m期的價格
以平安銀行(000001.SZ)日線資料為例:
# 匯入相關模塊
import numpy as np
import tushare as ts
import pandas as pd
import mplfinance as mpf
import matplotlib.pyplot as plt
token = 'Your token' # 輸入你的介面密匙,獲取方式及相關權限見Tushare官網,
pro = ts.pro_api(token)
df = pro.daily(ts_code='000001.SZ') # daily為tushare的股票資料介面,
# 將獲取到的DataFrame資料進行標準化處理,轉換為方便自己使用的一種規范格式,
df = df.loc[:, ['trade_date', 'open', 'high', 'low', 'close', 'vol']]
df.rename(
columns={
'trade_date': 'Date', 'open': 'Open',
'high': 'High', 'low': 'Low',
'close': 'Close', 'vol': 'Volume'},
inplace=True) # 重定義列名,方便統一規范操作,
df['Date'] = pd.to_datetime(df['Date']) # 轉換日期列的格式,便于作圖
df.set_index(['Date'], inplace=True) # 將日期列作為行索引
df = df.sort_index() # 倒序,因為Tushare的資料是最近的交易日資料顯示在DataFrame上方,倒序后方能保證作圖時X軸從左到右時間序列遞增,
查看一下df:

好,我們繼續進行,
# 提取2020年日度收盤價
PABank =df.Close['2020']
PABank.describe()

# 假設時間跨度m為5,即求滯后5期的收盤價變數
lag5PABank = PABank.shift(5)
# 求5日動量
momentum5 = PABank - lag5PABank
# 繪制收盤價時序圖與動量曲線圖
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.subplot(211)
plt.plot(PABank,'b*')
plt.xlabel('date')
plt.ylabel('Close')
plt.title('平安銀行2020年收盤價時序圖&5日動量圖')
plt.subplot(212)
plt.plot(momentum5,'r-*')
plt.xlabel('date')
plt.ylabel('momentum5')
plt.show()
效果如圖所示:

2.2 作除法求動量
另一種求動量的方法是作除法,使用t期的價格減去其m期以前的價格Pt-m再除以Pt-m,這種用動量變化率來表示動量的方式,將作差法得到的絕對指標轉化成了一套相對指標,可以將不同的股票的股價放在一起有了一定的可比性,但是考慮到不同股票的狀況不同,也要參考其本身的波動性情況,
用公式表示t時期的ROC(Rate of Change):
R
O
C
t
=
P
t
?
P
t
?
m
P
t
?
m
\displaystyle ROC_t =\frac{P_t-P_{t-m}}{P_{t-m}}
ROCt?=Pt?m?Pt??Pt?m??
其中,ROCt表示股票t時期的m期動量值,
依然以平安銀行2020年收盤價為例
Momen5 = PABank/lag5PABank -1
Momen5 = Momen5.dropna()
# 然后基本同上:
# 繪制收盤價時序圖與動量曲線圖
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.subplot(211)
plt.plot(PABank,'b*')
plt.xlabel('date')
plt.ylabel('Close')
plt.title('平安銀行2020年收盤價時序圖&5日動量圖(作除法)')
plt.subplot(212)
plt.plot(Momen5,'r-*')
plt.xlabel('date')
plt.ylabel('momentum5')
plt.show()
效果如圖:

3.定義求動量與作圖函式
兩個方法求得的動量圖在影像上差別并不大,動量值一般采用作差法求得,可以撰寫一個求動量和作差法繪動量圖的函式,以方便我們使用:
# 定義求動量的函式
def momentum(price, period):
lagPrice = price.shift(period)
momen = price - lagPrice
momen = momen.dropna()
return momen
# 定義求動量且繪時序圖及動量圖的函式
def momentum_plot(price, period):
import matplotlib.pyplot as plt
lagPrice = price.shift(period)
momen = price - lagPrice
momen = momen.dropna()
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.subplot(211)
plt.plot(price,'b*')
plt.xlabel('date')
plt.ylabel('Close')
plt.grid(True)
plt.title('收盤價時序圖(上)&{}日動量圖(下)'.format(period))
plt.subplot(212)
plt.grid(True)
plt.plot(momen,'r-*')
plt.xlabel('date')
plt.ylabel('Momentum')
plt.show()
# 更多影像美化細節待你完善,
# 呼叫,求平安銀行2020年十日動量圖
momentum_plot(PABank,10)
效果如圖:

4. 繪制K線圖與動量圖
這次,我們選擇使用萬能的mplfinance庫,
def candel_momen_plot(df, period):
import matplotlib.pyplot as plt
import mplfinance as mpf
price = df.Close
lagPrice = price.shift(period)
momen = price - lagPrice
momen = momen.dropna()
df1 = df.loc[momen.index[0]:, :] # 使K線圖起始時間與動量圖相同
s = mpf.make_mpf_style(base_mpf_style='nightclouds', rc={'font.family': 'SimHei', 'axes.unicode_minus': 'False'})
add_plot = [mpf.make_addplot(momen)]
mpf.plot(df1, type='candle', style=s, title='K線圖與動量圖', addplot=add_plot, volume=True)
# 呼叫
candel_momen_plot(df['2020'],5)
生成影像如下(nightclouds風格):

5. 動量交易策略的制定
四個步驟:
- 獲取資料
- 確定時間跨度與計算方法
- 選擇關鍵點
- 回測與評價,
最直覺的交易策略是動量大于0,說明股票還有上漲的能量,釋放出買入信號,反之則相反,
在時間跨度m的設定上,仁者見仁智者見智,沒有統一標準,
本次接下來計算將其設定為35日,
# 這次我們提取平安銀行從2019年到昨天(2021-04-26)的收盤資料
Close = df['2019':'2021'].Close
momen35 = momentum(Close,35) # 使用前邊定義過的函式
signal = [] # 交易信號空串列
# 動量值為負表示賣出
# 動量值為正表示買入
for i in momen35:
if i > 0:
signal.append(1)
else:
signal.append(-1)
signal = pd.Series(signal, index=momen35.index)
# 根據買賣點,指定買入和賣出交易,并計算收益率
tradeSig = signal.shift(1) # 滯后一天交易
ret = Close/Close.shift(1)-1 # 計算收益率
Mom35Ret = (ret*tradeSig).dropna() # 去空值
查看一下:

# 策略評價
# 計算勝率
win=Mom35Ret[Mom35Ret>0]
winrate = len(win)/len(Mom35Ret != 0)
查看勝率結果:

還沒完,然后我們可以根據收益率與動量交易策略收益率的時序圖,查看收益率分布情況:
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.subplot(211)
plt.plot(ret[-len(Mom35Ret):],'b')
plt.ylabel('return')
plt.title('收益率時序圖')
plt.subplot(212)
plt.plot(Mom35Ret,'r')
plt.ylabel('Mom35Ret')
plt.title('動量交易策略收益率時序圖')
plt.show()
效果如下:

(這一點需要說明一下:在python console中,只要用mplfinance繪了一次圖,在再次打開python console前,前邊設定的風格會一直沿用下去了,會影響到matplotlib.pyplot,)
再然后,我們可以將預測成功與預測失敗的收益率進行比較分析:
loss = -Mom35Ret[Mom35Ret < 0]
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.subplot(211)
win.hist()
plt.title("盈利直方圖")
plt.subplot(212)
loss.hist()
plt.title("損失直方圖")
如圖所示:

最后,我們計算兩種收益率的平均值與分位數值:
performance = pd.DataFrame({"win":win.describe(),"loss":loss.describe()})
查看結果:

投資有風險,入市需謹慎,量化投資要結合多種策略的結論,而非單一指標,動量交易策略也只是其一,
路過的各路神仙大佬哥哥姐姐叔叔阿姨們,如果覺得我寫得還可以的,就請點一下那個紅色的關注按鈕吧,以及那個灰色的大拇指,讓它變成紅色吧,
更多內容,敬請期待,博主會持續更新,感謝來訪!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/281264.html
標籤:python
