😆

バイナリーオプションのRSI15分足で5分後、10分後、15分後の勝率を出すPythonコード

2023/05/28に公開

Twitterで質問いただきましたので継続で検証

https://twitter.com/noway_pway/status/1662263374007390209?s=20

5分足の5,10,15分後の勝率

import pandas as pd
import MetaTrader5 as mt5
import talib
from datetime import timedelta

# MT5への接続
mt5.initialize()

# 読み込む通貨ペアと時間枠、データの件数を指定
symbol = 'USDJPYm'
timeframe = mt5.TIMEFRAME_M5
count = 100000


# データの取得
rates = mt5.copy_rates_from_pos(symbol, timeframe, 0, count)

# DataFrameに変換
df = pd.DataFrame(rates)

# 日時をPandasの日時形式に変換し、GMT+9に変換
df['time'] = pd.to_datetime(df['time'], unit='s') + timedelta(hours=9)


for i in range(1,4):

    # RSIの計算と列の追加
    rsi_period = 14
    df['rsi'] = talib.RSI(df['close'], timeperiod=rsi_period)

    # close列の一つ先の値を新しいカラムに追加
    df['next_close'] = df['close'].shift(-1 * i)

    # open列の一つ先の値を新しいカラムに追加
    df['next_open'] = df['open'].shift(-1)

    # 条件に応じて新しいカラムを追加
    df.loc[df['next_close'] - df['next_open'] > 0, 'change'] = 'up'
    df.loc[df['next_close'] - df['next_open'] < 0, 'change'] = 'down'
    df.loc[df['next_close'] - df['next_open'] == 0, 'change'] = 'zero'

    # 前のRSIと現在のRSIを比較して条件判定
    df['action'] = None  # 初期値として空の列を追加

    prev_rsi = df['rsi'].shift(1)  # 1つ前のRSI
    current_rsi = df['rsi']  # 現在のRSI

    df.loc[(prev_rsi < 70) & (current_rsi >= 70), 'action'] = 'SELL'
    df.loc[(prev_rsi > 30) & (current_rsi <= 30), 'action'] = 'BUY'
    
    if(i == 0):
        print(df)

    # 条件に合致する行の抽出
    filtered_df = df[(df['action'] == 'BUY') | (df['action'] == 'SELL')]
    
    print(5 * (i),"分後")
    # 条件に合致する行の確率を計算
    buy_up_probability = len(filtered_df[(filtered_df['action'] == 'BUY') & (filtered_df['change'] == 'up')]) / len(filtered_df[(filtered_df['action'] == 'BUY')])
    sell_down_probability = len(filtered_df[(filtered_df['action'] == 'SELL') & (filtered_df['change'] == 'down')]) / len(filtered_df[(filtered_df['action'] == 'SELL')])
    print("全数",len(df))
    print("BUY判定数",len(filtered_df[(filtered_df['action'] == 'BUY')]))
    print("BUY正解数",len(filtered_df[(filtered_df['action'] == 'BUY') & (filtered_df['change'] == 'up')]) )
    print("BUY & up probability: {:.2f}%".format(buy_up_probability * 100))
    print("SELL判定数:", len(filtered_df[(filtered_df['action'] == 'SELL')]))
    print("SELL正解数:", len(filtered_df[(filtered_df['action'] == 'SELL') & (filtered_df['change'] == 'down')]))
    print("SELL & down probability: {:.2f}%".format(sell_down_probability * 100))

15分足の5,10,15分後の勝率

プロンプト1

df を df_5 にして
tates をrates_5にして

プロンプト2

_5 を _15にして

プロンプト3

df['rsi_15']にして

プロンプト4

ここに"rsi_15"をマージして

プロンプト5

time を主キーで

プロンプト6

df_5['action'] = None # 初期値として空の列を追加

prev_rsi = df_5['rsi'].shift(1) # 1つ前のRSI
current_rsi = df_5['rsi'] # 現在のRSI

df_5.loc[(prev_rsi < 70) & (current_rsi >= 70), 'action'] = 'SELL'
df_5.loc[(prev_rsi > 30) & (current_rsi <= 30), 'action'] = 'BUY'

この部分をrsi_15で計算するように変更してください。

15分足なので連続したデータにnan,nan,実数という形になってるのでprev_rsi はそれを考慮してください

プロンプト7

ゼロで除算してるよ

import pandas as pd
import MetaTrader5 as mt5
import talib
from datetime import timedelta



for i in range(1,4):
    # MT5への接続
    mt5.initialize()

    # 読み込む通貨ペアと時間枠、データの件数を指定
    symbol = 'USDJPYm'
    timeframe = mt5.TIMEFRAME_M5
    count = 200000

    # データの取得
    rates_5 = mt5.copy_rates_from_pos(symbol, timeframe, 0, count)

    # DataFrameに変換
    df_5 = pd.DataFrame(rates_5)

    # 日時をPandasの日時形式に変換し、GMT+9に変換
    df_5['time'] = pd.to_datetime(df_5['time'], unit='s') + timedelta(hours=9)

    # RSIの計算と列の追加
    rsi_period = 14
    df_5['rsi'] = talib.RSI(df_5['close'], timeperiod=rsi_period)

    # close列の一つ先の値を新しいカラムに追加
    df_5['next_close'] = df_5['close'].shift(-1 * i +1)

    # open列の一つ先の値を新しいカラムに追加
    df_5['next_open'] = df_5['open'].shift(-1 + 1)

    # 条件に応じて新しいカラムを追加
    df_5.loc[df_5['next_close'] - df_5['next_open'] > 0, 'change'] = 'up'
    df_5.loc[df_5['next_close'] - df_5['next_open'] < 0, 'change'] = 'down'
    df_5.loc[df_5['next_close'] - df_5['next_open'] == 0, 'change'] = 'zero'

    # 15分足のデータを取得
    timeframe_15 = mt5.TIMEFRAME_M15
    count_15 = count  # count * 5分足のデータ数 / 15分足のデータ数
    rates_15 = mt5.copy_rates_from_pos(symbol, timeframe_15, 0, count_15)

    # DataFrameに変換
    df_15 = pd.DataFrame(rates_15)

    # 日時をPandasの日時形式に変換し、GMT+9に変換
    df_15['time'] = pd.to_datetime(df_15['time'], unit='s') + timedelta(hours=9)

    # RSIの計算と列の追加
    rsi_15_period = 14
    df_15['rsi_15'] = talib.RSI(df_15['close'], timeperiod=rsi_15_period)

    # M5とM15のデータをマージ
    merged_df = pd.merge(df_5, df_15[['time', 'rsi_15']], on='time', how='left')

    # 前のRSI_15と現在のRSI_15を比較して条件判定
    merged_df['action'] = None  # 初期値として空の列を追加

    prev_rsi_15 = merged_df['rsi_15'].shift(6)  # 1つ前のRSI_15
    current_rsi_15 = merged_df['rsi_15'].shift(3)  # 現在のRSI_15

    merged_df.loc[(prev_rsi_15 < 70) & (current_rsi_15 >= 70), 'action'] = 'SELL'
    merged_df.loc[(prev_rsi_15 > 30) & (current_rsi_15 <= 30), 'action'] = 'BUY'

    # 条件に合致する行の抽出
    filtered_df = merged_df[(merged_df['action'] == 'BUY') | (merged_df['action'] == 'SELL')]

    # 条件に合致する行の確率を計算
    buy_filtered = filtered_df[filtered_df['action'] == 'BUY']
    sell_filtered = filtered_df[filtered_df['action'] == 'SELL']

    buy_up_probability = len(buy_filtered[buy_filtered['change'] == 'up']) / len(buy_filtered) if len(buy_filtered) > 0 else 0
    sell_down_probability = len(sell_filtered[sell_filtered['change'] == 'down']) / len(sell_filtered) if len(sell_filtered) > 0 else 0

    print(5 * (i),"分後")
    print("全数", len(merged_df))
    print("BUY判定数", len(buy_filtered))
    print("BUY正解数", len(buy_filtered[buy_filtered['change'] == 'up']))
    print("BUY & up probability: {:.2f}%".format(buy_up_probability * 100))
    print("全数:", len(merged_df))
    print("SELL判定数:", len(sell_filtered))
    print("SELL正解数:", len(sell_filtered[sell_filtered['change'] == 'down']))
    print("SELL & down probability: {:.2f}%".format(sell_down_probability * 100))



これであってるか調べる方法は?

コードが複雑なので自分であってるか調べよう。

merged_df.to_csv('output.csv', index=False)

こするとCSVになるので表データを目視が確認できます。

30分足の5,10,15分後の勝率

import pandas as pd
import MetaTrader5 as mt5
import talib
from datetime import timedelta

for i in range(1, 4):
    # MT5への接続
    mt5.initialize()

    # 読み込む通貨ペアと時間枠、データの件数を指定
    symbol = 'USDJPYm'
    timeframe = mt5.TIMEFRAME_M5
    count = 200000

    # データの取得
    rates_5 = mt5.copy_rates_from_pos(symbol, timeframe, 0, count)

    # DataFrameに変換
    df_5 = pd.DataFrame(rates_5)

    # 日時をPandasの日時形式に変換し、GMT+9に変換
    df_5['time'] = pd.to_datetime(df_5['time'], unit='s') + timedelta(hours=9)

    # RSIの計算と列の追加
    rsi_period = 14
    df_5['rsi'] = talib.RSI(df_5['close'], timeperiod=rsi_period)

    # close列の一つ先の値を新しいカラムに追加
    df_5['next_close'] = df_5['close'].shift(-1 * i + 1)

    # open列の一つ先の値を新しいカラムに追加
    df_5['next_open'] = df_5['open'].shift(-1 + 1)

    # 条件に応じて新しいカラムを追加
    df_5.loc[df_5['next_close'] - df_5['next_open'] > 0, 'change'] = 'up'
    df_5.loc[df_5['next_close'] - df_5['next_open'] < 0, 'change'] = 'down'
    df_5.loc[df_5['next_close'] - df_5['next_open'] == 0, 'change'] = 'zero'

    # 30分足のデータを取得
    timeframe_30 = mt5.TIMEFRAME_M30
    count_30 = count  # count * 5分足のデータ数 / 30分足のデータ数
    rates_30 = mt5.copy_rates_from_pos(symbol, timeframe_30, 0, count_30)

    # DataFrameに変換
    df_30 = pd.DataFrame(rates_30)

    # 日時をPandasの日時形式に変換し、GMT+9に変換
    df_30['time'] = pd.to_datetime(df_30['time'], unit='s') + timedelta(hours=9)

    # RSIの計算と列の追加
    rsi_30_period = 14
    df_30['rsi_30'] = talib.RSI(df_30['close'], timeperiod=rsi_30_period)

    # M5とM30のデータをマージ
    merged_df = pd.merge(df_5, df_30[['time', 'rsi_30']], on='time', how='left')

    # 前のRSI_30と現在のRSI_30を比較して条件判定
    merged_df['action'] = None  # 初期値として空の列を追加

    prev_rsi_30 = merged_df['rsi_30'].shift(12)  # 1つ前のRSI_30
    current_rsi_30 = merged_df['rsi_30'].shift(6)   # 現在のRSI_30

    merged_df.loc[(prev_rsi_30 < 70) & (current_rsi_30 >= 70), 'action'] = 'SELL'
    merged_df.loc[(prev_rsi_30 > 30) & (current_rsi_30 <= 30), 'action'] = 'BUY'

    # 条件に合致する行の抽出
    filtered_df = merged_df[(merged_df['action'] == 'BUY') | (merged_df['action'] == 'SELL')]

    # 条件に合致する行の確率を計算
    buy_filtered = filtered_df[filtered_df['action'] == 'BUY']
    sell_filtered = filtered_df[filtered_df['action'] == 'SELL']

    buy_up_probability = len(buy_filtered[buy_filtered['change'] == 'up']) / len(buy_filtered) if len(buy_filtered) > 0 else 0
    sell_down_probability = len(sell_filtered[sell_filtered['change'] == 'down']) / len(sell_filtered) if len(sell_filtered) > 0 else 0

    print(30 * i, "分後")
    print("全数", len(merged_df))
    print("BUY判定数", len(buy_filtered))
    print("BUY正解数", len(buy_filtered[buy_filtered['change'] == 'up']))
    print("BUY & up probability: {:.2f}%".format(buy_up_probability * 100))
    print("全数:", len(merged_df))
    print("SELL判定数:", len(sell_filtered))
    print("SELL正解数:", len(sell_filtered[sell_filtered['change'] == 'down']))
    print("SELL & down probability: {:.2f}%".format(sell_down_probability * 100))

やってみてわからないことはコメントで教えてください!

「もっとこうやればいいのになあ」と思う詳しい人は教えてください!

Discussion