株価 - バックテスト(DMI/ADX版)!
Updated:
Ruby + MySQL で自作した株価取得のシステム。 全市場(東京・大阪・名古屋・札幌・福岡)の全銘柄の1983年からの全取引データを取得しています。
以前は、売買サイン発生後の株価の挙動を集計しました。
今回は、「DMI」・「ADX」での計算で発生した売買サインデータを基に、仮に取引をしていた場合にどのような結果(損益)になるのかを検証していました。 (DMI、ADXについては上記の過去記事をご参照ください。) 通常、このようなテストのことをバックテストと言います。
全体的にどんな傾向があるのかを把握するのと、Ruby (+ MySQL) の学習が目的です。 ※興味が無ければスルーしてください。
以下に、前提条件・検証結果を掲載します。
1.前提条件等
1.売買サインの定義
-
定義1 買いサイン : +DI が -DI を下から上抜けた時 売りサイン : +DI が -DI を上から下抜けた時
-
定義2 買いサイン : ADX が ADXR を下から上抜けた時に、+DI が -DI より上にある場合 売りサイン : ADX が ADXR を下から上抜けた時に、+DI が -DI より下にある場合
-
定義3 買いサイン : ADX が ADXR を上から下抜けた時に、+DI が -DI より下にある場合 売りサイン : ADX が ADXR を上から下抜けた時に、+DI が -DI より上にある場合
-
定義4 買いサイン : +DI - -DI が 10 を下から上抜けた時 売りサイン : +DI - -DI が -10 を上から下抜けた時
-
定義5 買いサイン : ADX が ADXR を下から上抜けた時 売りサイン : ADX が ADXR を上から下抜けた時
-
定義6 買いサイン : +DI が -DI を上抜け、ADX が -DI を下から上抜けた時 売りサイン : +DI が -DI を下抜け、ADX が +DI を下から上抜けた時
-
定義7 買いサイン : +DI が -DI を下から上抜け、ADX が ADXR より上の時 売りサイン : +DI が -DI を上から下抜け、ADX が ADXR より下の時
-
定義8 買いサイン : +DI が -DI を下から上抜けた後、ADXが -DI を下から上抜けた時 売りサイン : +DI が -DI を上から下抜けた後、ADXが +DI を下から上抜けた時
としました。 ※計算に使用した日数は、DI、ADX、ADXR ともに14日です。 また、調整後終値(株式分割があった場合の調整値)を考慮していません。
2.検証銘柄と検証期間
2012年3月31日現在上場している全市場の 3,579 銘柄を対象に、2000年1月1日から2011年12月31日の株価データを使用して検証しました。 また、複数の市場に上場している銘柄については、優先市場のみで検証しました。 ※全取引件数は 7,901,550 件
3.注文条件
- 資金は 5,000,000 円に設定
- 無ポジション中に買いサイン発生で、買いエントリ
- 買いポジション中にストップロス発生で、エグジット
- 買いポジション中に売りサイン発生で、エグジット
- 無ポジション中に売りサイン発生で、売りエントリ
- 売りポジション中にストップロス発生で、エグジット
- 売りポジション中に売りサイン発生で、エグジット
- エントリ・エグジットは翌営業日の始値で行う
- 手数料は、SBI証券の手数料(スタンダードプラン)を使用する。
- リスク率は 0.05 に設定
- ストップロス率は 0.4 に設定
- スリッページは 1 に設定
- 呼び値も考慮
- エントリ時は、毎回資金残高中で投資可能な最高額を投資
- エントリ時に資金残高が不足する場合はエントリしない。
各種用語については、各自でお調べください。 検証アルゴリズムは以下の書籍(エクセルでの検証)も参考にしています。
4.検証方法
- 各銘柄について、対象の期間内のデータで売買サインの発生を検証する。
- 各銘柄について、上記3の「注文条件」にしたがって、バックテストを行う。 算出項目:売買単位、手数料、損益、総損益、資金残高、最大ドローダウン
- 全銘柄のバックテスト結果を集計する。 検証項目:総損益、利益、損益、プロフィットファクター、トレード回数、 勝率、勝ちトレード数、負けトレード数、最大利益額、最大損失額、 総手数料額、最大ドローダウン、 平均損益額、平均利益額、平均損失額
2.検証結果
以下は、一番総損益が良かった DEF-6 で計算した結果です。
1.バックテスト結果
買い・売り両方のエントリを想定して検証しています。 全銘柄のトータルなので、莫大な数値となっています。 やはり、総損益もマイナスとなってしまいます。 また、買いエントリだけ、売りエントリだけを想定して検証した結果は、金額に差が出るものの比率は同じような結果になりました。
−−−−−−−−−−− [ TRADE(ALL) ][ TRADE(LONG) ][ TRADE(SHORT) ]
総損益 -1,302,233,314 -937,974,705 -364,258,609
利益 3,381,779,446 1,603,649,117 1,778,130,329
損益 -4,684,012,760 -2,541,623,822 -2,142,388,938
プロフィットファクター 72.19 63.09 82.99
トレード回数 76,695 37,893 38,802
勝率 5.01% 4.04% 5.96%
勝ちトレード数 3,847 1,534 2,313
負けトレード数 72,848 36,359 36,489
最大利益額 757,791 411,922 429,288
最大損失額 -161,230 -140,400 -122,565
総手数料額 185,049,723 91,515,421 93,534,302
最大ドローダウン -163,328 -141,050 -123,851
2.平均損益・利益・損失額集計
各銘柄でバックテスト(算出)した平均損益額・平均利益額・平均損失額の平均値・最大値・最小値を算出。 通常、各銘柄で算出した場合、平均損益額=平均利益額+平均損失額となりますが、全銘柄を集計した場合には数値の性質上イコールにはなりません。 イメージをつかむために全銘柄の平均値・最大値・最小値を算出してみました。
[ 全トレード ]
AVG ( MAX MIN )
[P/L ] -8,387 ( 5,074,461 -315,118 )
[PROFIT] 568,177 ( 96,853,663 0 )
[LOST ] -65,682 ( 0 -1,044,152 )
[ 買いトレード ]
AVG ( MAX MIN )
[P/L ] -20,883 ( 9,777,225 -415,068 )
[PROFIT] 359,422 ( 96,853,663 0 )
[LOST ] -70,900 ( 0 -1,107,330 )
[ 売りトレード ]
AVG ( MAX MIN )
[P/L ] -113 ( 3,795,432 -971,949 )
[PROFIT] 353,044 ( 9,213,351 0 )
[LOST ] -58,869 ( 0 -971,949 )
3.平均損益件数集計
こちらも、イメージをつかむため、平均損益がプラスの銘柄・マイナスの銘柄の件数を集計。 やはり、トータル的に観るとマイナスになる銘柄が多いようですが、今までのバックテストに比べるとプラスとなる銘柄が格段に多いです。
[TRADE] [+ COUNT] [- COUNT]
[ALL ] 809 2,701
[LONG ] 529 2,935
[SHORT] 857 2,608
今回の検証でも損失が出る結果となりました。
また、バックテストと称していながら、手数料・リスク率・ストップロス・スリッページ・呼び値等を考慮していないものが多数あります。 今回はこれらも考慮しているのでより実際に近いシミュレーションが出来ているのではないでしょうか。 計算間違いしていなければの話ですが・・・ ※計算間違いが発覚すれば、その都度再検証してみるつもりです。
もちろん、実際は場合によってエントリ方法を調整する必要があることは言うまでもありませんが。。。 特にエグジットの条件を変更する(利益のあるうちにエグジットするようにする)ともっと利益に繋がるでしょう。
Ruby 学習の延長で検証作業を行ってみましたが、こうして実際に実用的な何かを作成してみることで知識も深まっていきます。
以上。
Comments