[Python3]MT5에서 데이터를 가져와 close와 200EMA와 볼리반을 그리기
머리
Python3과 MT5를 연동시켜 자동매매 시스템을 만들고 싶었기 때문에, 완성까지 걸리는 공수를 근사하기 위해 조금 손을 움직였습니다.
일단 움직이게 한 상태이므로 코드는 전혀 정리되어 있지 않습니다.
향후 완성시킬지 어떨지는 미정입니다만, 현시점의 더러운 코드에서도 누군가의 도움이 될지도 생각해 기사로 했습니다.
환경
그리기 결과
그림 1: 그리기 직후
그림 2: 그림 1의 왼쪽 위 그림의 사각형 선택 부분을 확대. 다른 2개의 그림에 관해서도 같은 부분을 확대.
그림 3: 그림 2의 왼쪽 위 그림의 사각형 선택 부분을 확대. 다른 2개의 그림에 관해서도 같은 부분을 확대.
그림 4: 그림 3의 왼쪽 위 그림의 사각형 선택 부분을 확대. 다른 2개의 그림에 대해서는 그림 3에서 변화 없음.
소스 코드
import MetaTrader5 as mt5
from datetime import datetime
from pytz import timezone
import numpy as np
import pandas as pd
import talib as ta
import matplotlib.pyplot as plt
def filterColumns(rates, dict_columns):
"""
必要なカラムのみに絞り込む
Parameters
---------
rates : numpy.ndarray | pandas.DataFrame
MT5から読み込んだデータ
dict_columns : dictionary
必要なカラム
{置換前のカラム名1:置換後のカラム名1, 置換前のカラム名2:置換後のカラム名2, ...}
Returns
---------
df_rates : pandas.DataFrame
必要なカラムのみに絞ったDataFrame
"""
df_rates = pd.DataFrame(rates)
df_rates['time'] = pd.to_datetime(df_rates['time'], unit='s')
df_rates = df_rates.rename(columns=dict_columns)
return_columns = ['time'] + list(dict_columns.values())
return df_rates.loc[:, return_columns]
utc_tz = timezone('UTC')
pd.set_option('max_row', None)
###########################
# MT5からデータを取得
###########################
mt5.initialize()
EURJPY_D1_rates = mt5.copy_rates_range("GBPUSD", mt5.TIMEFRAME_D1, datetime(2019,6,12,0), datetime(2021,6,12,0))
EURJPY_H4_rates = mt5.copy_rates_range("GBPUSD", mt5.TIMEFRAME_H4, datetime(2019,6,12,0), datetime(2021,6,12,0))
EURJPY_H1_rates = mt5.copy_rates_range("GBPUSD", mt5.TIMEFRAME_H1, datetime(2019,6,12,0), datetime(2021,6,12,0))
mt5.shutdown()
###########################
# テクニカルデータの作成とデータの整形
###########################
# D1
# MT5から読み込んだデータをpandasのDataFrame型に変換
df_EURJPY_D1_rates = pd.DataFrame(EURJPY_D1_rates)
# TA-Libを使用して200EMAの値を算出し、DataFrameの新規カラムとして追加
df_EURJPY_D1_rates['ema'] = ta.EMA(df_EURJPY_D1_rates.close, timeperiod=200)
# 必要なカラムのみに絞り込み
df_EURJPY_D1_rates = filterColumns(df_EURJPY_D1_rates, {'close':'D1_close', 'ema':'D1_200ema'})
# H4
df_EURJPY_H4_rates = pd.DataFrame(EURJPY_H4_rates)
df_EURJPY_H4_rates['ema'] = ta.EMA(df_EURJPY_H4_rates.close, timeperiod=200)
df_EURJPY_H4_rates['upper_band'], df_EURJPY_H4_rates['middle_band'], df_EURJPY_H4_rates['lower_band'] = ta.BBANDS(df_EURJPY_H4_rates.close, timeperiod=20)
df_EURJPY_H4_rates = filterColumns(df_EURJPY_H4_rates, {'close':'H4_close', 'ema':'H4_200ema', 'upper_band':'H4_20band_upper', 'middle_band':'H4_20band_middle', 'lower_band':'H4_20band_lower'})
# H1
df_EURJPY_H1_rates = pd.DataFrame(EURJPY_H1_rates)
df_EURJPY_H1_rates['ema'] = ta.EMA(df_EURJPY_H1_rates.close, timeperiod=200)
df_EURJPY_H1_rates['upper_band'], df_EURJPY_H1_rates['middle_band'], df_EURJPY_H1_rates['lower_band'] = ta.BBANDS(df_EURJPY_H1_rates.close, timeperiod=20)
df_EURJPY_H1_rates = filterColumns(df_EURJPY_H1_rates, {'close':'H1_close', 'ema':'H1_200ema', 'upper_band':'H1_20band_upper', 'middle_band':'H1_20band_middle', 'lower_band':'H1_20band_lower'})
# H1のデータに対して右からH4, D1の順で日時データをキーとして結合
df_EURJPY_H4_D1_rates = pd.merge(df_EURJPY_H4_rates, df_EURJPY_D1_rates, on='time', how='outer')
df_EURJPY_H1_H4_D1_rates = pd.merge(df_EURJPY_H1_rates, df_EURJPY_H4_D1_rates, on='time', how='outer')
###########################
# 4650~4750行目を表示
# - 4686行目以前はデータが足りないためD1_200emaのデータは作られていない
###########################
print('\n---------------------------')
print('- GBPUSD rates')
print('- length: ', len(df_EURJPY_H1_H4_D1_rates))
print('---------------------------')
print(df_EURJPY_H1_H4_D1_rates[4650:4750])
# TODO H1がNaNとなる原因を調査する
# TODO H1がNaNとなっている行だけ日付順に並んでおらず、結合後のDataFrameの最後に纏められてしまう原因を調査する
# TODO H1がNaNの行は削除する
# CSVに出力
df_EURJPY_H1_H4_D1_rates.to_csv('20210613_0504.csv')
###########################
# チャートの描画設定
###########################
fig = plt.figure()
ax1 = fig.add_subplot(221)
ax2 = fig.add_subplot(222)
ax3 = fig.add_subplot(223)
ax1.plot(df_EURJPY_H1_rates.loc[:,'time'], df_EURJPY_H1_rates.loc[:,'H1_close'], linestyle = "solid", label = "H1_close")
ax1.plot(df_EURJPY_H1_rates.loc[:,'time'], df_EURJPY_H1_rates.loc[:,'H1_200ema'], linestyle = "dashed", label = "H1_200ema")
ax1.plot(df_EURJPY_H1_rates.loc[:,'time'], df_EURJPY_H1_rates.loc[:,'H1_20band_upper'], linestyle = "dotted", label = "H1_20band_upper", color = "red")
ax1.plot(df_EURJPY_H1_rates.loc[:,'time'], df_EURJPY_H1_rates.loc[:,'H1_20band_middle'], linestyle = "dotted", label = "H1_20band_middle", color = "red")
ax1.plot(df_EURJPY_H1_rates.loc[:,'time'], df_EURJPY_H1_rates.loc[:,'H1_20band_lower'], linestyle = "dotted", label = "H1_20band_lower", color = "red")
ax1.legend()
ax2.plot(df_EURJPY_H4_rates.loc[:,'time'], df_EURJPY_H4_rates.loc[:,'H4_close'], linestyle = "solid", label = "H1_close")
ax2.plot(df_EURJPY_H4_rates.loc[:,'time'], df_EURJPY_H4_rates.loc[:,'H4_200ema'], linestyle = "dashed", label = "H1_200ema")
ax2.plot(df_EURJPY_H4_rates.loc[:,'time'], df_EURJPY_H4_rates.loc[:,'H4_20band_upper'], linestyle = "dotted", label = "H1_20band_upper", color = "red")
ax2.plot(df_EURJPY_H4_rates.loc[:,'time'], df_EURJPY_H4_rates.loc[:,'H4_20band_middle'], linestyle = "dotted", label = "H1_20band_middle", color = "red")
ax2.plot(df_EURJPY_H4_rates.loc[:,'time'], df_EURJPY_H4_rates.loc[:,'H4_20band_lower'], linestyle = "dotted", label = "H1_20band_lower", color = "red")
ax2.legend()
ax3.plot(df_EURJPY_D1_rates.loc[:,'time'], df_EURJPY_D1_rates.loc[:,'D1_close'], linestyle = "solid", label = "H1_close")
ax3.plot(df_EURJPY_D1_rates.loc[:,'time'], df_EURJPY_D1_rates.loc[:,'D1_200ema'], linestyle = "dashed", label = "H1_200ema")
ax3.legend()
###########################
# チャートの描画
###########################
plt.show()
Reference
이 문제에 관하여([Python3]MT5에서 데이터를 가져와 close와 200EMA와 볼리반을 그리기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/y_kani/items/bc2118e0f430cb1a2abf
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
import MetaTrader5 as mt5
from datetime import datetime
from pytz import timezone
import numpy as np
import pandas as pd
import talib as ta
import matplotlib.pyplot as plt
def filterColumns(rates, dict_columns):
"""
必要なカラムのみに絞り込む
Parameters
---------
rates : numpy.ndarray | pandas.DataFrame
MT5から読み込んだデータ
dict_columns : dictionary
必要なカラム
{置換前のカラム名1:置換後のカラム名1, 置換前のカラム名2:置換後のカラム名2, ...}
Returns
---------
df_rates : pandas.DataFrame
必要なカラムのみに絞ったDataFrame
"""
df_rates = pd.DataFrame(rates)
df_rates['time'] = pd.to_datetime(df_rates['time'], unit='s')
df_rates = df_rates.rename(columns=dict_columns)
return_columns = ['time'] + list(dict_columns.values())
return df_rates.loc[:, return_columns]
utc_tz = timezone('UTC')
pd.set_option('max_row', None)
###########################
# MT5からデータを取得
###########################
mt5.initialize()
EURJPY_D1_rates = mt5.copy_rates_range("GBPUSD", mt5.TIMEFRAME_D1, datetime(2019,6,12,0), datetime(2021,6,12,0))
EURJPY_H4_rates = mt5.copy_rates_range("GBPUSD", mt5.TIMEFRAME_H4, datetime(2019,6,12,0), datetime(2021,6,12,0))
EURJPY_H1_rates = mt5.copy_rates_range("GBPUSD", mt5.TIMEFRAME_H1, datetime(2019,6,12,0), datetime(2021,6,12,0))
mt5.shutdown()
###########################
# テクニカルデータの作成とデータの整形
###########################
# D1
# MT5から読み込んだデータをpandasのDataFrame型に変換
df_EURJPY_D1_rates = pd.DataFrame(EURJPY_D1_rates)
# TA-Libを使用して200EMAの値を算出し、DataFrameの新規カラムとして追加
df_EURJPY_D1_rates['ema'] = ta.EMA(df_EURJPY_D1_rates.close, timeperiod=200)
# 必要なカラムのみに絞り込み
df_EURJPY_D1_rates = filterColumns(df_EURJPY_D1_rates, {'close':'D1_close', 'ema':'D1_200ema'})
# H4
df_EURJPY_H4_rates = pd.DataFrame(EURJPY_H4_rates)
df_EURJPY_H4_rates['ema'] = ta.EMA(df_EURJPY_H4_rates.close, timeperiod=200)
df_EURJPY_H4_rates['upper_band'], df_EURJPY_H4_rates['middle_band'], df_EURJPY_H4_rates['lower_band'] = ta.BBANDS(df_EURJPY_H4_rates.close, timeperiod=20)
df_EURJPY_H4_rates = filterColumns(df_EURJPY_H4_rates, {'close':'H4_close', 'ema':'H4_200ema', 'upper_band':'H4_20band_upper', 'middle_band':'H4_20band_middle', 'lower_band':'H4_20band_lower'})
# H1
df_EURJPY_H1_rates = pd.DataFrame(EURJPY_H1_rates)
df_EURJPY_H1_rates['ema'] = ta.EMA(df_EURJPY_H1_rates.close, timeperiod=200)
df_EURJPY_H1_rates['upper_band'], df_EURJPY_H1_rates['middle_band'], df_EURJPY_H1_rates['lower_band'] = ta.BBANDS(df_EURJPY_H1_rates.close, timeperiod=20)
df_EURJPY_H1_rates = filterColumns(df_EURJPY_H1_rates, {'close':'H1_close', 'ema':'H1_200ema', 'upper_band':'H1_20band_upper', 'middle_band':'H1_20band_middle', 'lower_band':'H1_20band_lower'})
# H1のデータに対して右からH4, D1の順で日時データをキーとして結合
df_EURJPY_H4_D1_rates = pd.merge(df_EURJPY_H4_rates, df_EURJPY_D1_rates, on='time', how='outer')
df_EURJPY_H1_H4_D1_rates = pd.merge(df_EURJPY_H1_rates, df_EURJPY_H4_D1_rates, on='time', how='outer')
###########################
# 4650~4750行目を表示
# - 4686行目以前はデータが足りないためD1_200emaのデータは作られていない
###########################
print('\n---------------------------')
print('- GBPUSD rates')
print('- length: ', len(df_EURJPY_H1_H4_D1_rates))
print('---------------------------')
print(df_EURJPY_H1_H4_D1_rates[4650:4750])
# TODO H1がNaNとなる原因を調査する
# TODO H1がNaNとなっている行だけ日付順に並んでおらず、結合後のDataFrameの最後に纏められてしまう原因を調査する
# TODO H1がNaNの行は削除する
# CSVに出力
df_EURJPY_H1_H4_D1_rates.to_csv('20210613_0504.csv')
###########################
# チャートの描画設定
###########################
fig = plt.figure()
ax1 = fig.add_subplot(221)
ax2 = fig.add_subplot(222)
ax3 = fig.add_subplot(223)
ax1.plot(df_EURJPY_H1_rates.loc[:,'time'], df_EURJPY_H1_rates.loc[:,'H1_close'], linestyle = "solid", label = "H1_close")
ax1.plot(df_EURJPY_H1_rates.loc[:,'time'], df_EURJPY_H1_rates.loc[:,'H1_200ema'], linestyle = "dashed", label = "H1_200ema")
ax1.plot(df_EURJPY_H1_rates.loc[:,'time'], df_EURJPY_H1_rates.loc[:,'H1_20band_upper'], linestyle = "dotted", label = "H1_20band_upper", color = "red")
ax1.plot(df_EURJPY_H1_rates.loc[:,'time'], df_EURJPY_H1_rates.loc[:,'H1_20band_middle'], linestyle = "dotted", label = "H1_20band_middle", color = "red")
ax1.plot(df_EURJPY_H1_rates.loc[:,'time'], df_EURJPY_H1_rates.loc[:,'H1_20band_lower'], linestyle = "dotted", label = "H1_20band_lower", color = "red")
ax1.legend()
ax2.plot(df_EURJPY_H4_rates.loc[:,'time'], df_EURJPY_H4_rates.loc[:,'H4_close'], linestyle = "solid", label = "H1_close")
ax2.plot(df_EURJPY_H4_rates.loc[:,'time'], df_EURJPY_H4_rates.loc[:,'H4_200ema'], linestyle = "dashed", label = "H1_200ema")
ax2.plot(df_EURJPY_H4_rates.loc[:,'time'], df_EURJPY_H4_rates.loc[:,'H4_20band_upper'], linestyle = "dotted", label = "H1_20band_upper", color = "red")
ax2.plot(df_EURJPY_H4_rates.loc[:,'time'], df_EURJPY_H4_rates.loc[:,'H4_20band_middle'], linestyle = "dotted", label = "H1_20band_middle", color = "red")
ax2.plot(df_EURJPY_H4_rates.loc[:,'time'], df_EURJPY_H4_rates.loc[:,'H4_20band_lower'], linestyle = "dotted", label = "H1_20band_lower", color = "red")
ax2.legend()
ax3.plot(df_EURJPY_D1_rates.loc[:,'time'], df_EURJPY_D1_rates.loc[:,'D1_close'], linestyle = "solid", label = "H1_close")
ax3.plot(df_EURJPY_D1_rates.loc[:,'time'], df_EURJPY_D1_rates.loc[:,'D1_200ema'], linestyle = "dashed", label = "H1_200ema")
ax3.legend()
###########################
# チャートの描画
###########################
plt.show()
Reference
이 문제에 관하여([Python3]MT5에서 데이터를 가져와 close와 200EMA와 볼리반을 그리기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/y_kani/items/bc2118e0f430cb1a2abf텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)