この記事では、量化投資におけるバックテストの実現方法の最も簡単な例を共有します。この例は、バックテストの原理の実現方法のみを説明しており、実際の状況ではより複雑なものになる場合があります。
- 買いと売りのシグナルの構築
買いのシグナル signal=1、売りのシグナル signal=0、その他は NaN です。
注意:ここでは、すべての取引がフルポジションで行われると仮定しています。連続したシグナルのうち、最初のシグナルのみが実際の取引意味を持ちます。つまり、最初のシグナルが成立した後は、後続のシグナルが発生しても、フルポジションで買っているため、もうお金を使うことはありません。売りも同様です。
- シグナルを保有状態に変換
保有状態 keep=1、空の状態は 0 とし、すべての取引がフルポジションで行われると仮定すると、keep=signal となります。
# すべての取引がフルポジションであると仮定するため、signal=keep となります。つまり、1 は保有を意味し、0 は空の状態を意味します。
test_kl['keep'] = test_kl['signal']
keep=NaN のデータを前の要素で埋めるために、keep 列に対して下方向に埋める処理を行います。
# keep 列の NaN データを前方向に埋めることで、keep は最終的な取引の保有状態を表すことができます。
test_kl['keep'].fillna(method='ffill', inplace=True)
- ベンチマークの収益計算
ここでのベンチマークの収益とは、最初の日から最後の日までの各日の収益を指します。各日の収益の計算方法は、(当日の終値 - 前日の終値)/ 前日の終値です。
test_kl['benchmark_profit2'] =
test_kl['close'] / test_kl['close'].shift(1) - 1
test_kl['benchmark_profit'] =
np.log(test_kl['close'] / test_kl['close'].shift(1))
- 戦略の収益計算
戦略の収益は、保有状態 * ベンチマークの収益です。ここで、保有状態は 1 と 0 のデータのみで、* ベンチマークの収益後には、フィルターが作成され、0 のデータが自動的にフィルタリングされます。
test_kl['trend_profit'] = test_kl['keep'] * test_kl['benchmark_profit']
- 収益の可視化比較
ベンチマークの収益と戦略の収益を日々累積し、比較します。
test_kl[['benchmark_profit','trend_profit']].cumsum().
plot(grid=True, figsize=14, 7));