一、前言

接著上一篇:【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() 可以在同一子圖建立副座標軸,讓我們資料更好呈現!

image

對畫圖不熟的或想畫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]把有效號的資料拿出來~

image

 

四、策略績效評估

# 策略績效評估 #################################################################
## 策略評估
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,可見不是一隻好策略,

值得一提的是隨著持有時間增加,各個評估指標都有變好的現象!

image

image

 

六、後記

開啟你的量化生涯吧!!寫出更好的交易策略,

因為實務上比較偏向買進訊號進場持有至平倉訊號出場,

當然還有更多更棒的交易方式!

 

arrow
arrow
    創作者介紹
    創作者 恩哥Python 的頭像
    恩哥Python

    恩哥Python量化教室-零基礎也能學會Python

    恩哥Python 發表在 痞客邦 留言(0) 人氣()