😊
バイナリーオプションRSI15分足の1時間区切りの勝率を見る
当方素人のため、間違ってるかも知れません。
それでもいいならどうぞ!
プロンプト1
一時間区切りの勝率を出したいのです。ヒートマップで可視化して。可視化にsns使ってね。
プロンプト2
BUYとSELLは分けてください。
あとセルが小さいので文字が重なって見えないです。
ヒートマップのサイズを大きくしてください。
このあと何回か回答がパッとせず、
元のコードを修正する方向にします。
プロンプト3
このコードのmerged_dfにhourのカラムを追加して
プロンプト4
ヒートマップのタイトルに英語でprint(5 * i, "分後")の部分を追加して何分後のデータなのかわかるようにしてください。
プロンプト5
pltの部分を修正してください
1.buy_win_rateとsell_win_rate が混ざっている
2.そのため別々でテーブルを管理してください。
3.BUYはbuy_win_rateのみ
4. SELLはsell_win_rate のみ
プロンプト6
コード全文でください
プロンプト7
BUYとSELLを同じ表として可視化して
プロンプト8
色の濃淡を0.2~0.8に固定して
できた!
import pandas as pd
import MetaTrader5 as mt5
import talib
from datetime import timedelta
import seaborn as sns
import matplotlib.pyplot as plt
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'
# hourカラムを追加
merged_df['hour'] = merged_df['time'].dt.hour
# 条件に合致する行の抽出
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))
# 1時間ごとのデータを抽出
hourly_data = merged_df.groupby(['hour', 'action']).size().reset_index(name='count')
# 勝率の計算
win_counts_buy = merged_df[(merged_df['change'] == 'up') & (merged_df['action'] == 'BUY')].groupby('hour').size().reset_index(
name='buy_win_count')
win_counts_sell = merged_df[(merged_df['change'] == 'down') & (merged_df['action'] == 'SELL')].groupby('hour').size().reset_index(
name='sell_win_count')
hourly_data_buy = hourly_data[hourly_data['action'] == 'BUY'].copy()
hourly_data_sell = hourly_data[hourly_data['action'] == 'SELL'].copy()
hourly_data_buy = pd.merge(hourly_data_buy, win_counts_buy, on='hour', how='left')
hourly_data_sell = pd.merge(hourly_data_sell, win_counts_sell, on='hour', how='left')
hourly_data_buy['buy_win_rate'] = hourly_data_buy['buy_win_count'] / hourly_data_buy['count']
hourly_data_sell['sell_win_rate'] = hourly_data_sell['sell_win_count'] / hourly_data_sell['count']
# ヒートマップの作成
heatmap_data = pd.merge(hourly_data_buy[['hour', 'buy_win_rate']],
hourly_data_sell[['hour', 'sell_win_rate']],
on='hour', how='outer')
heatmap_data.set_index('hour', inplace=True)
plt.figure(figsize=(12, 8))
sns.heatmap(heatmap_data, annot=True, fmt=".2%", cmap='YlGnBu', cbar_kws={'label': 'Win Rate'}, vmin=0.2, vmax=0.8)
title = str(5 * i) + " minutes later"
plt.title('Win Rate by Hour ' + title)
plt.xlabel('Action')
plt.ylabel('Hour')
plt.show()
import pandas as pd
import MetaTrader5 as mt5
import talib
from datetime import timedelta
import seaborn as sns
import matplotlib.pyplot as plt
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'
# hourカラムを追加
merged_df['hour'] = merged_df['time'].dt.hour
# 条件に合致する行の抽出
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))
# 'time'カラムを分に変換
merged_df['minutes'] = merged_df['time'].dt.hour * 60 + merged_df['time'].dt.minute
# 15分毎にラベルを生成
bins = range(0, 24*60, 15)
labels = [f'{i//60:02d}:{(i%60):02d}' for i in bins][:-1] # '00:00', '00:15', '00:30', ..., '23:45' の形式
merged_df['15min'] = pd.cut(merged_df['minutes'], bins=bins, labels=labels)
# 15分ごとのデータを抽出
grouped_15min_data = merged_df.groupby(['15min', 'action']).size().reset_index(name='count')
# 勝率の計算
win_counts_buy = merged_df[(merged_df['change'] == 'up') & (merged_df['action'] == 'BUY')].groupby('15min').size().reset_index(
name='buy_win_count')
win_counts_sell = merged_df[(merged_df['change'] == 'down') & (merged_df['action'] == 'SELL')].groupby('15min').size().reset_index(
name='sell_win_count')
grouped_15min_data_buy = grouped_15min_data[grouped_15min_data['action'] == 'BUY'].copy()
grouped_15min_data_sell = grouped_15min_data[grouped_15min_data['action'] == 'SELL'].copy()
grouped_15min_data_buy = pd.merge(grouped_15min_data_buy, win_counts_buy, on='15min', how='left')
grouped_15min_data_sell = pd.merge(grouped_15min_data_sell, win_counts_sell, on='15min', how='left')
grouped_15min_data_buy['buy_win_rate'] = grouped_15min_data_buy['buy_win_count'] / grouped_15min_data_buy['count']
grouped_15min_data_sell['sell_win_rate'] = grouped_15min_data_sell['sell_win_count'] / grouped_15min_data_sell['count']
# ヒートマップの作成
heatmap_data = pd.merge(grouped_15min_data_buy[['15min', 'buy_win_rate']],
grouped_15min_data_sell[['15min', 'sell_win_rate']],
on='15min', how='outer')
heatmap_data.set_index('15min', inplace=True)
fig, ax = plt.subplots(figsize=(12, 20)) # 高さを20に設定
sns.heatmap(heatmap_data, annot=True, fmt=".2%", cmap='YlGnBu', cbar_kws={'label': 'Win Rate'}, vmin=0.2, vmax=0.8,
annot_kws={"size": 10}, ax=ax) # フォントサイズを調整
title = str(5 * i) + " minutes later"
ax.set_title('Win Rate by 15 Minutes ' + title, fontsize=20)
ax.set_xlabel('Action', fontsize=15)
ax.set_ylabel('Time (HH:MM)', fontsize=15)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.show()
Discussion