Fxを代表とするハイリスクでキャピタルゲインを狙うタイプの投資では、資金管理が何よりも大事です。資金管理の重要性を示す例として”ヴァルサラの破産確率”があり、どの程度のリスク・勝率・損益比率が確保されていれば負けないか?を示す数式があります。
今回はその、”1トレードあたりの資金に対するリスク”、”1トレードあたりの勝率”、”1トレードあたりの損益比率”を設定し、実際にちゃんと利益が積み重ねられていくのかを検証していきます。
Contents
条件設定
今後、Fxの自動売買ロジックを探索、構築していくことを見据え、複利運用を基本とします。
モジュールのインポート
1 2 3 4 |
import random as rd import matplotlib.pyplot as plt import pandas as pd import numpy as np |
定義する関数
1 2 3 4 5 |
def winloss(win_ratio): if rd.random() > win_ratio: return True else: return False |
勝率を表す変数win_ratioを与えると、勝率に応じて都度勝ち負けを返すだけの関数です。勝ったらTrue、負けたらFalseを返します。それだけ。
取引条件の設定
1 2 3 4 5 6 7 8 9 10 11 12 |
""" 取引条件設定パラメータ """ # 1 Lotの通貨単位 lot = 100000 # 1 pipsあたり何円か pips_yen = 0.01 # 1トレードあたりの約定ズレ slippage_pips = 1.0 # 1トレードあたりの買売値差 spread_pips = 1.0 # 1トレード片道あたりのpipsコスト cost_pips = slippage_pips + spread_pips |
取引条件を設定するパラメータです。
1 lotあたりの通貨単位は取引業者によって異なります。今回は1 lot = 10万通貨単位としました。
今回の損益は日本円で計算します。取引する通貨ペアによって1 pipsあたりの円換算は変化するので、今回はドル円を想定して10万通貨, 1 lotの1 pipsあたりの損益が1000円単位となるように、pips_yenを設定しました。(円を含まない通貨ペアの場合、円換算レートの計算が入ってくるので損益計算が少々複雑になりますが、今回は割愛します。)
約定ズレ(slippage)と買い板売り板の差(spread)は、今回どちらも1 pipsと定めておきます。この二つの値を合計した値が1トレードに掛かるコストです。
※コストを厳密に計算する場合、さらにスワップ金利とポジションの保有期間が必要となります。こちらも今回は割愛します。コストは概算なので、実際には1トレード当たりに設定値以上に有利や不利に働くこともあります。
任意に設定するパラメータ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
""" 任意設定パラメータ """ # 資金(円) amount = 100000 # 資金における許容リスク率(×100%) risk = 0.02 # 損益比(倍率) PL_ratio = 2.0 # 1トレードあたりの勝率(×100%) win_ratio = 0.5 # 1トレードあたりの損切pips loss_pips = 10 # 1トレードあたりに必要な利益pips profit_pips = ((loss_pips + cost_pips) * PL_ratio) + cost_pips |
損益シミュレーションに関わる、任意に設定するパラメーターです。
amount はトレードの原資となる資金(円)です。今回は初期資金を10万円に設定しました。
risk は1トレードあたり、損切を許容する額が資金(円)の何%かを設定しています。今回は2%、つまり初回のトレードでは2000円まで損失を許容します。
PL_ratioは1トレードあたりの損益比です。今回は2倍に設定しています。初回のトレードでは2000円の許容損失に対して、利益確定ラインが4000円になる状態です。
loss_pipsは1トレードあたりの損切pipsです。相場状況やロジックによって可変にすべき項目ですが、ここでは10 pipsに固定します。
profit_pipsは1トレードで、指定したPL_ratioを実現するために必要な利益を獲得できるpipsです。取引コストは往復でかかるため、上記のような式で定義されます。
損益シミュレーション
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# エントリー回数 TIMES = 100 # 1エントリーのlot数 entry_lot = 0 # 1エントリーごとのリターンの額 income = 0 # 結果の表準備 cols = ['amount', 'return', 'entry_lot'] df = pd.DataFrame(index=[], columns=cols) record = pd.Series([amount, income, entry_lot], index=df.columns) df = df.append(record, ignore_index=True) # TIMES回取引する for i in range(TIMES): # 1トレードの損失額が資金の損失許容額となるようなエントリーlot entry_lot = round((amount * risk)/((loss_pips + cost_pips) * lot * pips_yen),2) # 1pipsあたりの損益額 pips_PL = lot * pips_yen * entry_lot # 勝率ごとに獲得利益を場合分け(amountが0円になったら終了(以降ずっと0円)) if winloss(win_ratio): income = pips_PL * profit_pips else: income = pips_PL * (loss_pips + cost_pips) * (-1) if amount > 0: amount = round(amount + income) if amount > 0: pass else: amount = 0 else: amount = 0 record = pd.Series([amount, income, entry_lot], index=df.columns) df = df.append(record, ignore_index=True) # 結果グラフの表示 df['amount'].plot(grid=True) |
損益シミュレーションでは以下のことを行います。
- 現在の資金から計算した損失許容額と、損切時の損失額が一致するようなロット数を計算
- 算出したロット数を元に1pipsあたりの損益額(円)を計算
- 勝率に基づいて勝ち負け判定を行い、勝ったら獲得利益を資金に加算、負けたら損失額を資金から減算
- 以上を100回繰り返し、資金の推移を観察する
ただし、試行中に資金が負の値になった場合破産と見なし、以降の資金増加はありません。
こちらの結果を一度試してみると、以下のようになりました。

少し見えづらくて申し訳ないですが、今回設定したルールを守って取引すると100回取引した後には資金が10万円→20万円に増えていることが分かります。
ちなみに表データを覗いてみると、

最初はロット数0.17程度のエントリーが

終盤にはロット数0.33程になっており、複利効果が働いていることが分かります。
何度も試してみる
今回のシミュレーションは勝率の部分に乱数を使用しているので、実行ごとに最終資金量が変わります。上で行ったシミュレーションはたまたま乱数が良かっただけで、何度もうまくいくとは限らない訳です。そこで、このシミュレーションを何回も行ってみて、本当にこの条件なら必ず資金が増えるのか検証してみます。

上記は今回のシミュレーションを10回行ったときの資金の変化を1つのグラフにまとめたものです。各折れ線が、100回トレードした際の資金量変化を表しています。
このグラフを見ると、今回設定した勝率50%, 損益比2倍, 許容リスク2%で取引すれば以下のことが推測できます。
- 初期に資金が増えないこともあるが、大負けしないので破産せず、最後は利益が出る
- 最もうまくいかなかった場合は10万円→15万円ほどの利益
- 最もうまくいった場合は10万円→55万円ほどの利益
よって今回のパラメータは良い値であると言えます。
今後はこの結果を元に、実際のチャートから条件を満たすエントリーポイントを探し出すことで負けないロジックを探索していこうと思います。
以下、プログラム全文
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
import random as rd import matplotlib.pyplot as plt import pandas as pd import numpy as np def winloss(win_ratio): if rd.random() > win_ratio: return True else: return False # 試行回数 retake = 10 # 最終結果のdfの列名 col = [] for j in range(retake): col.append('test'+str(j)) trydf = pd.DataFrame(index=[], columns=col) # retake回試行 for j in range(retake): """ 取引条件設定パラメータ """ # 1 Lotの通貨単位 lot = 100000 # 1 pipsあたり何円か pips_yen = 0.01 # 1トレードあたりの約定ズレ slippage_pips = 1.0 # 1トレードあたりの買売値差 spread_pips = 1.0 # 1トレード片道あたりのpipsコスト cost_pips = slippage_pips + spread_pips """ 任意設定パラメータ """ # 資金(円) amount = 100000 # 資金における許容リスク率(×100%) risk = 0.02 # 損益比(倍率) PL_ratio = 2.0 # 1トレードあたりの勝率(×100%) win_ratio = 0.5 # 1トレードあたりの損切pips loss_pips = 10 # 1トレードあたりに必要な利益pips profit_pips = ((loss_pips + cost_pips) * PL_ratio) + cost_pips # エントリー回数 TIMES = 100 # 1エントリーのlot数 entry_lot = 0 # 1エントリーごとのリターンの額 income = 0 # 結果dfの準備 cols = ['amount', 'return', 'entry_lot'] df = pd.DataFrame(index=[], columns=cols) record = pd.Series([amount, income, entry_lot], index=df.columns) df = df.append(record, ignore_index=True) for i in range(TIMES): # 1トレードの損失額が資金の損失許容額となるようなエントリーlot entry_lot = round((amount * risk)/((loss_pips + cost_pips) * lot * pips_yen),2) # 1pipsあたりの損益額 pips_PL = lot * pips_yen * entry_lot # 勝率ごとに獲得利益を場合分け if winloss(win_ratio): income = pips_PL * profit_pips else: income = pips_PL * (loss_pips + cost_pips) * (-1) if amount > 0: amount = round(amount + income) if amount > 0: pass else: amount = 0 else: amount = 0 record = pd.Series([amount, income, entry_lot], index=df.columns) df = df.append(record, ignore_index=True) trydf[col[j]] = df['amount'] trydf.plot(grid=True) |
コメント