以前投稿した「モンテカルロ法の検証」という記事に「分解モンテカルロ法」も検証してほしいというコメントを頂いていたので、今回は「分解モンテカルロ法」を検証していきます。(コメント頂いた方、遅くなりまして申し訳ございません‥!)
まずはモンテカルロ法と分解モンテカルロ法の違いを明確にします。
モンテカルロ法のFX用アレンジルールは「モンテカルロ法の検証」もご覧ください。分解モンテカルロ法については「分解モンテカルロ法の詳細解説」という記事を参考にさせていただきました。
分解モンテカルロ法のFXアレンジ
カッコ内はモンテカルロ法の場合です。(違いがわかりやすいように併記していきます)
- まずは紙に0,1を書きます。(1,2,3を書く)
- 左右を足した数をロット数とします。(両端の数を足す)
- 勝ったら左右の数字を一つずつ消す。(勝ったら両端の数字を2つずつ消す)
- 負けたらベットした数を右に書き加えます。(同じ)
- 数列が消えた時、終了(数字が1個以下になったら終了)
- 数字が1つ残った場合はその数字を分解して書く(モンテカルロ法には無いルール)
※分解方法 2が残った場合は 1,1。7が残ったら3,4とします。
かなり似ているので以前作った「モンテカルロ法」のプログラムを流用できそうです。
モンテカルロ法のプログラムを変更
void InitLotsArray()
{
for(int i=0;i<50;i++)
{
LotsArray[i] = 0;
}
LotsArray[0] = 0;
LotsArray[1] = 1;
Lots = LotsArray[0] + LotsArray[1];
}
最初の初期値が異なるのでInitLotsArrayを修正しました。
void SetLots(bool isWin)
{
if(isWin)
{
//左端の配列を1つ消す
for(int i=0;i<48;i++)
{
LotsArray[i] = LotsArray[i+1];
}
//右端の配列を1つ消す。
for(int i=1;i<50;i++)
{
if(LotsArray[i] == 0)
{
LotsArray[i-1] = 0;
break;
}
}
//全部ゼロ(1番目の配列が0)だったら終了
if(LotsArray[1] == 0)
{
InitLotsArray();
}
else if(LotsArray[0] > 0 && LotsArray[1] == 0)
{
//数字が1つしか残っていなかったら分解する
LotsArray[0] = (int)MathFloor(LotsArray[0] / 2); //0番目の数字を2で割って切り捨てた数字を0番目の数字する
LotsArray[1] = (int)MathCeil(LotsArray[0] / 2); //0番目の数字を2で割って切り上げた数字を1番目の数字する
}
Lots = LotsArray[0] + LotsArray[1];
}
else
{
//配列の最後に現在Lotsを入れる
for(int i=0;i<50;i++)
{
if(LotsArray[i] == 0)
{
LotsArray[i] = Lots;
break;
}
}
Lots = LotsArray[0] + LotsArray[1];
}
}
ロット計算ロジックをルールに沿って書き換えました。それ以外は変える必要は無さそうです。
なお、売買ルールは「モンテカルロ法の検証」、単純に「買い」を入れて、SLとTPを設定して放置するだけの単純なシステムになっています。
分解モンテカルロ法:バックテスト
USDJPY、2015年1月から2024年2月までの期間でバックテストします。
※Axioryの1分足データを使用。2015年からしか無いため、開始が2015年。ヒストリカルデータを作ったのは先月だったため2024年2月までのデータしかありません。)
スプレッドは5としました。時間軸は無関係です。買ってSLかTPに達するまで放置するだけのシステムです。(TPとSLは同幅です)
ドローダウンがとにかく小さいです。利益も小さいですけど‥。
比較のために同条件でモンテカルロ法を使ってみます。
モンテカルロ法:同条件でバックテスト
利益は通常のモンテカルロ法の方が良いようです。ドローダウンは分解モンテカルロ法に軍配が上がります。とにかくドローダウンを小さくしたい、破産確率を可能な限り減らしたいという場合には使えそうです。
まとめ
というわけで、モンテカルロ法をより「リスクが少ない(ドローダウンが少ない)ベットシステム」に変えたのがict119さんという方が考えた「分解モンテカルロ法」です。
ロットの増え方が非常に緩やかで、連敗時の破産確率が非常に低いシステムになっています。
モンテカルロ法同様、一セット終わるとかならず利益が残るため、より確実性を取りたい場合には採用しやすいのではないでしょうか。
たとえば、キャッシュバックのように「トレード頻度」が重要で「利益はそれほどでなくてもいい」ような場合には使いやすいシステムになりそうです。
作ったソースコードを置いておきます。遊んでみたい方はどうぞご自由に‥。
パラメーター
Magic = マジックナンバー
StopLoss=ストップロス
TakeProfitRate=テイクプロフィット(ストップロスとの割合)
ご注意
そのままリアル口座で動かす人はいないと思いますが、念の為‥
「このプログラムを利用して発生したいかなる損害も当方は責任を負いかねますのでご了承ください」
分解モンテカルロ法をライブラリ化するに続きます。
コメント
コードダウンロードさせていただきました、ありがとうございます。
試しにUSDJPYで流してみたところ、ロットの調整だけで右肩上がりになって驚きでした。
コードはBUYのみだったので、SELLのみに書き換えたらどうかなぁ、ということでやってみたら、今度は右肩下がりでした。同じような勝率なのにここまで差があるのはなぜなのですかね?
もし記事になりそうでしたら検証していただけると嬉しいです。
おそらくスワップの影響が大きいです。
SetLotsの33行目と47行目
Lots = LotsArray[0] + LotsArray[1];
添字1だと右端にならないように思います。なにか解釈が間違っていたらすみません、、。
すみません、回答が遅くなりました。(コメントに気づいていませんでした‥)
分解モンテカルロ法は右端ではなく、左端とその隣を加算します。
(通常のモンテカルロ法では両端を加算します)
※説明の括弧書きの方が通常の「モンテカルロ法」になります。ややこしくてすみません。