NA0TA

PythonとVBAでモンテカルロシミュレーション

OANDA:GBPAUD   Bảng Anh/Đô la Úc
トレードにおいてはリスク管理とマネーマネジメントは最重要項目ですよね。
凄く利益があげられそうな手法でトレードしていてもドローダウンが大きすぎて利益が上がる前に退場してしまっては
しょうがないので、将来的なドローダウンやリスクリワードレシオを把握しておくことは大切で
トレードを開始する前にはモンテカルロシミュレーションを行って、その手法が自分に合っているか事前検証します。

モンテカルロシミュレーションとはヒストリカルデータでシミュレーションした各トレードすべてをランダムに
入れ替えて資産曲線の傾きを調べる方法です。
各トレードの損益はPythonのselenium.webdriverで読み込んでExcelファイルに自動入力していきます。
そして十分な統計データをとるために高速計算が得意なExcelVBAでモンテカルロシミュレーションを3000回行うとします。

今回はポンド/豪ドルでアウトサイドデイを利用したストラテジーの損益データで試しました。
利益も勝率も悪くないしドローダウンも大きくないけど、潜在的なパフォーマンスはいかがなものでしょうか?

開始資金 破産確率 ドローダウン中央値
¥200,000  31%   34.0%
¥250,000  16%   30.6%
¥300,000  7%     28.1%
¥350,000  3%   24.7%
¥400,000  1%    22.2%
¥450,000  0%   20.0%
¥500,000  0%   19.0%
¥550,000  0%   17.9%
¥600,000   0%   16.2%
¥650,000  0%   15.2%
¥700,000   0%    14.5%

開始資金は200,000~700,000の間で、破産の水準を投資資金の50%としたら、400,000以下の資金では破産する確率が
あることがわかりました。これは将来的なドローダウンが大きいのでより多くの資金を投入するかロスカットをきつくする必要があります。
ドローダウンに耐えることが出来れば将来的なパフォーマンスはなかなか良い戦略かもしれません。

このように、モンテカルロシミュレーションを行うと単純な資産曲線やパフォーマンスレポートには表れない
重要な戦略の内面的な部分が浮き彫りになります。

※VBAのモンテカルロシミュレーションコード
Sub MonteC1()
'

Worksheets(1).EnableCalculation = False 'manually calculate to allow faster processing

timex = Time
Randomize (Timer)

fms = MsgBox("シミュレーションを開始しますか?", vbYesNo + vbQuestion)
If fms = vbNo Then
MsgBox "中止します"
End
End If

'最初に削除
Range("E4:L14").Select
Selection.ClearContents


startequity = Range("B1")
equityincrement = startequity / 4#
margin = Range("b3") '破産の水準

lotsize = Range("B5") ' トレードサイズ


trades = Range("B4") '年間トレード数

niters = 3000 'シミュレーション回数

'条件を満たすまで繰り返す式(A列が空白になるまで)
i = 10
Do Until (Range("A" & i) = "")
i = i + 1
Loop
lastrow = i - 1 '空白でない最後のトレード結果


'
upperbound = lastrow - 10 + 1 'total # of trades in group

irow = 4

'シミュレート結果を削除
Range("w1:aa3000").Select
Selection.ClearContents

'スタート資金(4分の1づつ10倍になるまで転記)------------------------------------------------------------------------------
For c1 = startequity To startequity + 10 * equityincrement Step equityincrement

Beginequity = c1


totalriskofruin = 0



For Iteration = 1 To niters '設定したシミュレーション回数

equity = Beginequity
drawdown = 0#

maxequity = equity
ruin = 0


For itrades = 1 To trades '設定した年間トレード


'トレード結果の最上段から最下段まで渡して乱数を返す
tradenumber = Int(((lastrow - 10 + 1) * Rnd) + 10)


tradevalue = Range("A" & tradenumber) 'ランダムなトレード結果


ncontracts = lotsize 'ポジションサイズ


'資金が破産水準より下がったらトレード不可
If equity < margin Then
ncontracts = 0
ruin = 1
End If


equity = equity + ncontracts * tradevalue 'トレード結果=資金×サイズ×ランダムに選んだトレード


If equity > maxequity Then
maxequity = equity
Else
dd = 1 - (equity / maxequity) 'ドローダウンは現在の資金÷スタート資金
If dd > drawdown Then drawdown = dd 'ドローダウンが0より大きかったら値を渡す

End If


Next itrades '設定した年間トレードの数で繰り返し------------------------------------------------------------------------------------------------------------

totalriskofruin = totalriskofruin + ruin


Range("w" & Iteration) = equity '計算後の資金
Range("x" & Iteration) = drawdown 'ドローダウン
Range("y" & Iteration) = ((equity / c1) - 1) 'リターン
If drawdown <> 0 Then Range("z" & Iteration) = ((equity / c1) - 1) / drawdown 'リターン/ドローダウン
Range("AA" & Iteration) = equity - c1 '損益(現在の資金ースタート資金)

Next Iteration 'シミュレート繰り返し

Worksheets(1).EnableCalculation = True

totalriskofruin = totalriskofruin / niters


Range("e" & irow) = c1 'スタート資金
Range("f" & irow) = totalriskofruin '破産確率

Range("G" & irow) = Range("S5") 'mediandrawdown
Range("H" & irow) = Range("S4") - c1 'medianprofit
Range("I" & irow) = Range("S6") 'median IRR
Range("J" & irow) = Range("S7") 'median IRR/DD
Range("K" & irow) = Range("S8") 'probability > 0
Range("L" & irow) = Range("S9")


Worksheets(1).EnableCalculation = False
irow = irow + 1

Next c1

Worksheets(1).EnableCalculation = True

Range("a10").Select

Beep
End Sub
Thông báo miễn trừ trách nhiệm

Thông tin và ấn phẩm không có nghĩa là và không cấu thành, tài chính, đầu tư, kinh doanh, hoặc các loại lời khuyên hoặc khuyến nghị khác được cung cấp hoặc xác nhận bởi TradingView. Đọc thêm trong Điều khoản sử dụng.