先読みバイアス (2017/05/27)

先読みバイアスによってパフォーマンスがどうなるか、そして、バイアスを除いたあとのパフォーマンスがどうなるかを見てみる。

先読みバイアスは不注意から生まれる

先読みバイアスはありえないパフォーマンスを生む。もしタイムマシーンがあって未来の情報を手に入れることができるなら、投資もギャンブルも百戦百勝である。だがもちろん、そのようなことはできない話である。

先読みバイアスはバックテストのときに誤って未来のデータを使ってしまった場合に起きる。MT4では日付をずらしたデータを作成して使ったりしないかぎり、未来のデータを使ってバックテストはできない仕組みになっている。しかし、自分でバックテストシステムを作った場合、先読みバイアスの過ちを犯してしまうリスクがある。

先読みバイアスはプログラミング上の誤りではないので、エラーが発生しない。このため、問題があることに気づきにくいのでやっかいである。

先読みバイアスを避けるにはトレードの時点で存在しないデータを使わないよう注意するしかない。だが、もしありえないようなパフォーマンスが得られたなら、先ず先読みバイアスを疑うべきである。

先読みバイアスが生む異常なパフォーマンス

例えば1本前の足の終値が2本前の足の終値より上であれば買い、下であれば売りという戦略を考えたとする。このような単純な戦略では取引コストを無視すれば勝つということもないが負けることもない。だが取引コストを考慮するなら、右肩下がりの資産曲線となる。

ところが間違えて現在の足の終値が1本前の足の終値より上であれば買い、下であれば売り、とプログラムしたとする。現在の足の終値が上がるか下がるか、始値の時点では分からないのだから、このようなことは現実には実行できない。だがバックテストではできてしまう。

これはつまり終値が上がっていたら始値の時点に戻って買い、終値が下がっていたら始値の時点に戻って売るということである。あたかもタイムマシンで未来に行って結果を見てきてから現在に戻って売買するのと同じである。これでは上がるか下がるの予測は百発百中となるに決まっている。

もし、ある戦略のシャープレシオが3.0くらいあるとしたら、それは優秀な戦略と言っていいと思う。このような戦略を作ることは不可能ではないが、決して簡単なことではない。もし、シャープレシオが3.0を超えるような戦略がふと出来上がってしまったとしたら、先ず先読みバイアスを疑うべきである。

では、上で説明した間違ったコードを2014年1月1日から2017年1月1日までUSDJPYの5分足に適用して検証してみる。

以下のコードを「look_ahead_bias.py」ファイルとして「~/py」フォルダーに保存する。

# coding: utf-8

import forex_system as fs
import pandas as pd

# パラメータの設定
PARAMETER = None

# 最適化の設定
RRANGES = None

get_model = None

def strategy(parameter, symbol, timeframe):
    '''戦略を記述する。
    Args:
        parameter: パラメーター。
        symbol: 通貨ペア。
        timeframe: 期間。
    Returns:
        買いエントリー、買いエグジット、売りエントリー、売りエグジット、ロット数。
    '''
    close1 = fs.i_close(symbol, timeframe, 0)  # 「1」を誤って「0」にしている。
    close2 = fs.i_close(symbol, timeframe, 1)  # 「2」を誤って「1」にしている。
    buy_entry = close2 < close1
    buy_exit = close2 > close1
    sell_entry = close2 > close1
    sell_exit = close2 < close1
    index = close1.index
    lots = pd.Series(1.0, index=index)
    return buy_entry, buy_exit, sell_entry, sell_exit, lots

if __name__ == '__main__':
    fs.platform()

以下のコマンドを実行してバックテストする。

%run -t ~/py/look_ahead_bias.py --mode backtest --symbol USDJPY --timeframe 5 --spread 0.4 --start 2014.01.01 --end 2017.01.01

       start         end  trades          apr   sharpe    kelly drawdowns durations
  2014.01.01  2016.12.31  112760  9.04702e+18  185.484  2307.89     0.009         0

資産曲線は右肩上がりの曲線を描いている。複利で計算しているので、最後は爆発的に利益が増えている。シャープレシオは185.48もあるが、これは明らかに異常なパフォーマンスである。このような結果になったら先ず、先読みバイアスを疑って、コードを確認することである。

バイアスを排除した後の惨めなパフォーマンス

実際にコードを確認すると、やはり間違いがあった。そこで間違いを訂正して実行したところ、以下のようになった。

       start         end  trades    apr  sharpe    kelly drawdowns durations
  2014.01.01  2016.12.31  112759 -0.331 -16.286 -163.036   133.332       782

資産曲線は右肩下がりの曲線を描いている。シャープレシオは-16.29で、実際には全く使い物にならない戦略だということが分かる。