FX自動売買(EA)の作り方MQL4MQL5Python

【Python】ナンピン幅をATRに連動させるFX自動売買ツールの開発③【MQL5/MQL4】

※アフィリエイト広告を利用しています

広告

この度、ナンピン幅および利確幅をATRに連動させて、破綻リスクを確率的に制御するナンピンマーチン型のFX自動売買ツール(EAまたはBOT)の開発を行いました。

この記事は、前回の記事の続きです。

MQL5で開発しMT5で稼働させるEA、MQL4で開発しMT4で稼働させるEA、Pythonで開発しMT5のPython APIを利用して稼働させるBOT、とそれぞれ用意しているのですが、この記事ではそのEAまたはBOTの開発における思考過程を少しずつ具体的に記事にしていきたいと思います。

なお、作成したMT5用EAとMT4用EAについては、以下からダウンロード可能です。

広告

前回まで

talibで複数のテクニカル指標を計算

以下のように、1分足の各種テクニカル指標を計算しました。

この記事では、勝率計算は1分足で行いますが、テクニカル指標は1時間足を使うことにして、話を進めます。

1時間足にtalibでDMIフラグを追加

以下の通り、1分足と同様の手順でテクニカル指標を追加したdf(データフレーム)を用意します。

ここで、DMI_flgというフラグを追加しています。

#DMI_flg
df['DMI_flg'] = 0
df.loc[(df['pDI'] > df['mDI']), 'DMI_flg'] = 1
df.loc[(df['pDI'] < df['mDI']), 'DMI_flg'] = -1

+DIと-DIを比較して、+DIが大きければ+1、-DIが大きければ-1、というフラグです。

DMI(Directional Movement Index 、方向性指数)は、

+DI:上昇トレンドである可能性を判断
-DI:下降トレンドである可能性を判断
ADX:トレンドの強弱を判断
という3本のラインを使って売買の判断を行うのが通常ですが、ここではADXは使っていません。
+DIと-DIだけで、DMI_flgを設定しています。

1分足に1時間足のフラグを追加

ここでの勝率シミュレーションでは、価格変動は1分足を用いて、売買判断は1時間足を用いるので、二つのデータを結合します。

bar_timeを追加

ここは少しテクニカル(技術的)な話になりますが、まずは、df_H1にbar_timeを追加します。

start_time = datetime(2017, 1, 1, 0, 0, 0, 0)

df = df_H1
df = df.dropna()
df = df.reset_index()
df['start_time'] = start_time
delta = (df['time'] - df['start_time']).dt
df['bar_time'] = (df['time'] - df['start_time'])//timedelta(minutes=60)
df = df.set_index('time')
df_H1 = df

処理の流れを簡単に解説します。

まず、start_timeとして、起点となる時間を設定します。ここでは、2017年1月1日の0時を起点としています。

そして、そのstart_timeと、それぞれのレコードの時間(time)の差を取って、1時間(minutes=60)単位の整数にします。

出来上がったdf_H1は以下の通りです。

一つ目のレコードの2017-01-06 09:00:00は、2017-01-01 00:00:00から129時間後なので、bar_timeには129が入っています。以下、1時間(1レコード)毎に1ずつ増えていくような形です。

1分足に、1時間足のテクニカル指標を結合

pandasのdfのまま追加するロジックの方がわかりやすかったりしますが、それだと処理が遅くなるので、numbaを用いて処理が速くなるようなロジックにしています。少しわかりにくいかもしれませんが、載せておきます。

@numba.njit
def calc_bar_i(
          df_len_bar,
          df_Open,
          df_bar_time,
          len_bar,
          bar_time,
          bar_DMI_flg,
          bar_ATR,
          ):
    DMI_flg = df_bar_time.copy()
    DMI_flg[:] = np.nan

    ATR = df_Open.copy()
    ATR[:] = np.nan

    for j in range(len_bar):
        if bar_time[j] == df_bar_time[0]:
            bar_j = j
            break

    for i in range(df_len_bar):

        for j in range(bar_j,len_bar):
            if bar_time[j] == df_bar_time[i]:
            bar_j = j
            DMI_flg[i] = bar_DMI_flg[j-1]
            ATR[i] = bar_ATR[j-1]
            break

    return DMI_flg, ATR

そして、このcalc_bar_i関数を用いて、以下の処理を行います。

df = df_M1

df = df.reset_index()
df['start_time'] = start_time
delta = (df['time'] - df['start_time']).dt
df['bar_time_H1'] = (df['time'] - df['start_time'])//timedelta(minutes=60)
df = df.set_index('time')

df['DMI_flg'],df['ATR']= calc_bar_i(
     df_len_bar=len(df),
     df_Open=df['Open'].values,
     df_bar_time=df['bar_time_H1'].values,
     len_bar=len(df_H1),
     bar_time=df_H1['bar_time'].values,
     bar_DMI_flg=df_H1['DMI_flg'].values,
     bar_ATR=df_H1['ATR'].values,
     )
df_ATR = df.dropna()

結果、以下のようなデータフレーム(df_ATR)が出来上がります。

処理の流れを簡単に解説しておくと、1分足のtimeから、2017年1月1日の0時を起点とした1時間単位の整数(bar_time_H1)を作成して、df_H1のbar_timeとマッチング、マッチングしたレコードの1つ前のレコードのDMI_flgとATRを取得しています。

例えば2017年1月4日の3:00であれば、2017年1月4日の2:00の1時間足で作成したDMI_flgとATRを取得することになります。

これはつまり、3:00の時点で確定している時間足は2:00のものなので、その情報(指標)を基に取引を行うという状態をイメージしてデータを作成していることになります。

勝率の変化を確認

ATRとDMIを考慮せずに勝率を計算した場合と、考慮して勝率を計算した場合で、どのように変化するかを確認してみます。

利確幅 DMI buy 勝率 sell 勝率 buy+sell 勝率
12.00固定 なし 52.9% 45.7% 49.3%
ATR×3.2 なし 50.8% 47.2% 49.0%
12.00固定 あり 54.8% 47.6% 51.1%
ATR×3.2 あり 54.1% 50.4% 52.2%

この結果からわかる考察を少しまとめます。

  • 何も考慮せずにbuyの勝率が50%を超えていて、sellの勝率が50%を下回っているので、全体的に上昇トレンドの方が多かったということが推測できます。
  • sellの勝率が、ATRとDMIを考慮するとわかりやすく50%を超えるまで上昇しており、それなりに効果がありそうに見えます。

次の記事では、この勝率を試算するコードと、もう少し深く考察していく方向に進みます。

タイトルとURLをコピーしました