ファイナンス機械学習:ラベリング 練習問題 一次モデルと二次モデル 移動平均線

 一次モデルとメタラベルを利用した二次モデルのパフォーマンスを見る。

 E-mini S&P500のドルバーから、一次モデルとして、移動平均線のクロスに基づいたトレンドフォロー戦略を作成する。 
 短期移動平均線と長期移動平均線のクロスによって建てられる戦略は、最もシンプルなもので、短期線が長期線を下から上へ突き抜けた場合に、ゴールドクロスと呼ばれ買いシグナル、逆に短期線が長期線を上から下に抜けたらデッドクロスで売りシグナルとされる。
 このクロスを見つけるコードは以下で実装される。

short=5
long=20
ddfSMA=(pd.DataFrame()
            .assign(price=ddf['Close'])
            .assign(short=ddf['Close'].rolling(short).mean())
            .assign(long=ddf['Close'].rolling(long).mean())).dropna()

def getGCross(df):
    crit1 = df.short > df.long
    crit2 = df.short.shift(1)<df.long.shift(1)
    return df.short[(crit1) & (crit2)]

def getDCross(df):
    crit2 = df.short < df.long
    crit1 = df.short.shift(1) > df.long.shift(1)
    return df.short[(crit1) & (crit2)]

DCross, GCross = getDCross(ddfSMA), getGCross(ddfSMA)

 ここではSMAを使ったが、ddfSMAでEWMAを使ってもクロスを同じ関数で見つけることはできる。
 これを価格と一緒にプロットする。

import matplotlib.pyplot as plt
%matplotlib inline

fig = plt.figure(figsize=(14, 8))

plt.plot(ddfSMA['price'].loc['2018':],ls='-', label='price')
plt.plot(ddfSMA['short'].loc['2018':],ls='-', label='short')
plt.plot(ddfSMA['long'].loc['2018':],ls='-', label='long')
plt.plot(GCross.loc['2018':],ls='',marker='^',label='Gold')
plt.plot(DCross.loc['2018':],ls='',marker='v',label="Dead")
plt.legend()

見やすさのために、2018年以降の2年データでプロットした。

順張りで、買いと売りのサイドを決める。

buy = pd.Series(1, index=GCross.index)
sell = pd.Series(-1, index=DCross.index)
side = pd.concat([sell,buy]).sort_index()

ptSl=[0,2]、日次標準偏差をtgrtにしてnumDay=1の垂直バリアに対するメタラベリングを行う。
ここで、TPEventのsideを入れて実行すると、trgtに設定している日次標準偏差のインデックスがsideのインデックスに含まれない場合のエラーが出るので、以下のように修正する。

def getEventsML(close, tEvents, ptSl, trgt, minRet, t1=False,side=None):
    trgt = trgt.loc[tEvents]
    trgt = trgt[trgt > minRet]
    if t1 is False:
        t1 = pd.Series(pd.NaT, index=tEvents)
        
    if side is None:
        side_, ptSl_ = pd.Series(1., index=trgt.index), [ptSl[0], ptSl[0]]
    else:
        side_, ptSl_ = side.loc[trgt.index.intersection(side.index)], ptSl[:2]
        #side_, ptSl_ = side.loc[trgt.index], ptSl[:2]
        
    events = pd.concat({'t1': t1, 'trgt': trgt, 'side': side_}, axis=1).dropna(subset=['trgt'])
    df0 = applyTPBarrier(close, events, ptSl_)

    events['t1'] = df0.dropna(how='all').min(axis=1)
    if side is None:
        events = events.drop('side', axis=1)
    return events
minRet = .005 
ptsl=[1,2]

span0=20
close=ddf['Close']
daily_vol=getDailyVol(close,span0)
h=daily_vol.mean()
ddf_rtn = close.pct_change().dropna()
events=bars.getTEvents(ddf_rtn, h)  #CUSUM 
t1 = addVerticalBarrier(close, events, numDays=1)

SMATPevents=getEventsML(close,events,ptsl,daily_vol,minRet,t1=t1,side=side)
SMATPevents

 これから、メタラベリングを行うが、このラベリングの目的は、SMAで決めたサイドを実行するかしないかであるから、サイドの入っていない(NaN)の行は消去する。

SMATPevents= SMATPevents.dropna()
SMAlabels=getBinsTUML(SMATPevents,close,t1)
SMAlabels


利益が正となる時のみ、実行フラグの1が立っている。これを次の二次モデルのターゲットとする。

この記事が気に入ったらサポートをしてみませんか?