一、前言
接著上一篇:【Python量化資料】這樣買台積電會賺嗎?手把手教你策略回測與績效分析(上)
我們進到重頭戲,策略的基本回測模型與檢測策略的績效
二、指標及資料視覺化
# 指標及資料視覺化 ##############################################################
## 選定時間區間
dates = pandas.date_range(start,end) # 選定資料期間-----
df_dates = pandas.DataFrame(index=dates)
df = df_dates.join(df).dropna()
## 定義網格
f = plt.subplots(1, 1, sharey=True, figsize=(16,7))
gs = GridSpec(4, 1)
ax = plt.subplot(gs[0:2, :]) # 放股價
ax2 = plt.subplot(gs[2, :]) # 放成交量
ax3 = plt.subplot(gs[3, :]) # 放指標
## 視覺化
xlim = (start, end)
styles = ['-', '--', '.-']
df['Close'].plot(legend=True, color='r', ax=ax, grid=True, xlim=xlim) # 股票
df['Volume'].plot(kind='area', legend=True, ax=ax2, grid=True, xlim=xlim) # 量
df[['dif', 'macd']].plot(legend=True, ax=ax3, style=styles, grid=True, xlim=xlim) # 技術指標 dif macd
ax3_r = ax3.twinx() # 建立附y軸
ax3_r.fill_between(df['osc'].index, df['osc'], color='b', alpha=0.3) # 技術指標 osc
ax3_r.fill_between(df['osc'].index, df['osc'], color='r', alpha=0.2, where = (df['osc'] > 0)) # y < 0 綠色
## 圖表參數
### 圖表線換虛線
ax.grid(linestyle='--', linewidth=0.5, color='gray', alpha=0.4)
ax2.grid(linestyle='--', linewidth=0.5, color='gray', alpha=0.4)
ax3.grid(linestyle='--', linewidth=0.5, color='gray', alpha=0.4)
### 設定抬頭
ax.set_title(ticker, fontsize=30)
我們把我們上一篇所下載的資料及計算的指標話在圖上,方便我們很直觀的使用指標來建構策略。
使用f = plt.subplots(1, 1, sharey=True, figsize=(16,7))來建立一張圖,
用gs = GridSpec(4, 1)分成4個子圖,而後用ax = plt.subplot(gs[0:2, :])來決定子圖要放在大圖的哪裡。
為了使每張圖的x軸對齊xlim = (start, end)來先定義出x軸的範圍,放在plot的xlim參數中。
ax3_r = ax3.twinx() 可以在同一子圖建立副座標軸,讓我們資料更好呈現!
對畫圖不熟的或想畫k線圖的可以參考:【Python量化資料】手把手教你畫出萬用精美股票圖K線圖
三、固定持有時間回測
# 固定持有時間回測 #############################################################
## 產生交易訊號
sig = (df['osc'] > 0) & (df['osc'].shift(1) < 0)
## 計算持有天數報酬
day = 10 # 持有天數
for i in range(1,day):
df['ret'+str(i)] = (df['Close'].shift(-i)-df['Open'].shift(-1)) / df['Open'].shift(-1)
## 計算報酬
df_return = pandas.DataFrame()
fee = 0.01 # 設定手續費
for i in range(1,day):
df_return['sig_ret'+str(i)] = (df['ret'+str(i)]-fee) * sig
df_return = df_return[sig] # 只取有訊號的資料
先定義出交易訊號,這邊是osc今天大於0同時昨天小於0我就買入持有n天。
使用for迴圈算出隔天開盤價到未來n天的報酬,
* 為什麼要用隔天開盤持有到n天收盤,因為訊號是出現在今天收盤,收盤價是無法買的
而後定義df_return為一個dataframe放我們策略執行的結果!
使用for迴圈把sig(訊號) 乘以 return報酬,因為有訊號會是True(1),沒有則為False(0),
1乘上報酬就是我們有訊號買入持有的結果,沒有訊號則為0乘上報酬還是0表示策略沒有執行。
最後使用df_return[sig]把有效號的資料拿出來~
四、策略績效評估
# 策略績效評估 #################################################################
## 策略評估
strategy_perf = df_return.describe() # 策略敘述統計
strategy_perf.loc['ret'] = df_return.sum()# 總報酬
strategy_perf.loc['hit'] = (df_return > 0).sum() / df_return.count() # 勝率
strategy_perf.loc['odds'] = df_return[df_return >= 0].sum() / (-df_return[df_return < 0].sum())# 賺賠比
## 標示買賣點在圖上
ax_r = ax.twinx()
ax_r.fill_between(sig.index, sig*1, color='b', where=sig==1, alpha=0.5) # 訊號顯示在主圖
看來共有37-38次交易,平均每次交易報酬<0,勝率<60%,賺賠比<1,可見不是一隻好策略,
值得一提的是隨著持有時間增加,各個評估指標都有變好的現象!
六、後記
開啟你的量化生涯吧!!寫出更好的交易策略,
因為實務上比較偏向買進訊號進場持有至平倉訊號出場,
當然還有更多更棒的交易方式!
留言列表