import math
from datetime import datetime
import MetaTrader5 as mt5

# display data on the MetaTrader 5 package
print("MetaTrader5 package author: ", mt5.__author__)
print("MetaTrader5 package version: ", mt5.__version__)

# import the 'pandas' module for displaying data obtained in the tabular form
import pandas as pd

pd.set_option('display.max_columns', 50)  # how many columns to show
pd.set_option('display.width', 1500)  # max width of the table to show
# import pytz module for working with the time zone
import pytz

# establish connection to the MetaTrader 5 terminal
if not mt5.initialize():
    print("initialize() failed")
    mt5.shutdown()

# set time zone to UTC
timezone = pytz.timezone("Etc/UTC")
# creare datetime objects in the UTC timezone to avoid local timezone offset
utc_from = datetime(2020, 1, 1, tzinfo=timezone)
utc_to = datetime(2020, 12, 31, hour=23, minute=59, second=59, tzinfo=timezone)
# get EURUSD H1 bars in the interval 2020.01.01 00:00 - 2020.31.12 13:00 in the UTC timezone
rates_H1 = mt5.copy_rates_range("EURUSD", mt5.TIMEFRAME_H1, utc_from, utc_to)
# also get D1 bars in the interval 2020.01.01 00:00 - 2020.31.12 13:00 in the UTC timezone
rates_D1 = mt5.copy_rates_range("EURUSD", mt5.TIMEFRAME_D1, utc_from, utc_to)
# shut down connection to the MetaTrader 5 terminal and continue processing received bars
mt5.shutdown()

# create DataFrame out of the obtained data
rates_frame = pd.DataFrame(rates_H1)

# add the "Return" column
rates_frame['return'] = 0.0
# now calculate the return as return[i] = (close[i] - close[i-1])/close[i-1]
prev_close = 0.0
for i, row in rates_frame.iterrows():
    close = row['close']
    rates_frame.at[i, 'return'] = close / prev_close - 1 if prev_close != 0.0 else 0.0
    prev_close = close

print("\nCalculate the mean and standard deviation of returns on H1 bars")
print('H1 rates:', rates_frame.shape[0])
ret_average = rates_frame[1:]['return'].mean()  # skip the first row with zero return
print('H1 return average=', ret_average)
ret_std = rates_frame[1:]['return'].std(ddof=0) # skip the first row with zero return
print('H1 return std =', ret_std)
sharpe_H1 = ret_average / ret_std
print('H1 Sharpe = Average/STD = ', sharpe_H1)

sharpe_annual_H1 = sharpe_H1 * math.sqrt(rates_H1.shape[0]-1)
print('Sharpe_annual(H1) =', sharpe_annual_H1)

# now calculate the Sharpe ratio on the D1 timeframe
# create DataFrame out of the obtained data
rates_daily = pd.DataFrame(rates_D1)

# add the "Return" column
rates_daily['return'] = 0.0
# calculate returns
prev_return = 0.0
for i, row in rates_daily.iterrows():
    close = row['close']
    rates_daily.at[i, 'return'] = close / prev_return - 1 if prev_return != 0.0 else 0.0
    prev_return = close

print("\nCalculate the mean and standard deviation of returns on H1 bars")
print('D1 rates:', rates_daily.shape[0])
daily_average = rates_daily[1:]['return'].mean()
print('D1 return average=', daily_average)
daily_std = rates_daily[1:]['return'].std(ddof=0)
print('D1 return std =', daily_std)
sharpe_daily = daily_average / daily_std
print('D1 Sharpe =', sharpe_daily)

sharpe_annual_D1 = sharpe_daily * math.sqrt(rates_daily.shape[0]-1)
print('Sharpe_annual(D1) =', sharpe_annual_D1)
