import pandas as pd
import numpy as np
import mpl_finance as mpf
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.ticker as ticker
from matplotlib import animation
import talib
import matplotlib.gridspec as gridspec
import datetime
import MetaTrader5 as mt5

#長期のPCで短期のチャートを表示したい場合Pathは短期のPathにする(短期の方はそのまま)

df = pd.read_csv('C:/Users/xi/MT5/in_dat/common.csv', index_col=0)
use_max = df.iat[0,0]
use = df.iat[0,1]
use_data = df.iat[0,3]
if  use_data == 'short':
    data = df.iat[0,4]
if  use_data == 'long':
    data = df.iat[0,5]
indi_number = df.iat[0,8]
flag = 0

path_ohlcv = 'C:/Users/xi/MT5/in_dat/{}/OHLCV_{}_CHART.csv'
path_ohlcv = path_ohlcv.format(use_data,use_data)
indi = ['EMA','BBAND','MACD','RSI','STOCH','DMi','ULTOSC']
path_para = []
for i in range(len(indi)):
    path = 'C:/Users/xi/MT5/out_dat/{}/para/para_{}.csv'
    path = path.format(use_data,indi[i])
    path_para.append(path)
path_para_df = pd.DataFrame(path_para)

path_Storategy = 'C:/Users/xi/MT5/out_dat/Strategy.csv'
path_Entry_short = 'C:/Users/xi/MT5/out_dat/Entry_short.csv'

# MetaTrader 5ターミナルとの接続を確立する
if not mt5.initialize():
   print("initialize() failed, error code =",mt5.last_error())
   quit()

def ATR(value1,value2,value3,n):
    high = pd.Series(value1)
    low = pd.Series(value2)
    close = pd.Series(value3)
    return talib.ATR(high, low, close, timeperiod=n)

def EMA(values, n):
    close = pd.Series(values)
    return talib.EMA(close, timeperiod=n)

def BBAND(values, n):
    close = pd.Series(values)
    return talib.BBANDS(close, timeperiod=n, nbdevup=2, nbdevdn=2, matype=0)

def MACD(values,l,m,n):
    close = pd.Series(values)
    return talib.MACD(close,fastperiod=m, slowperiod=n, signalperiod=l)

def RSI(values, n):
    close = pd.Series(values)
    return talib.RSI(close, timeperiod=n)

def STOCH(value1,value2, value3, m, n):
    high = pd.Series(value1)
    low = pd.Series(value2)
    close = pd.Series(value3)
    return talib.STOCH(high, low, close, fastk_period=m, slowk_period=n)

def DMI(value1,value2, value3,n):
    high = pd.Series(value1)
    low = pd.Series(value2)
    close = pd.Series(value3)
    ADX = talib.ADX(high, low, close, timeperiod=n)
    DIp = talib.PLUS_DI(high, low, close,timeperiod=n)
    DIm = talib.MINUS_DI(high, low, close,timeperiod=n)
    return ADX, DIp, DIm

def ULTOSC(value1,value2, value3, l, m, n):
    high = pd.Series(value1)
    low = pd.Series(value2)
    close = pd.Series(value3)
    return talib.ULTOSC(high, low, close, timeperiod1=l, timeperiod2=m, timeperiod3=n)

# 可視化
def drow(df,entry_time,first_time):
    ema_label= 'EMA('+str(EMAvalue1)+','+str(EMAvalue2)+')'
    bband_label= 'BBAND('+str(BBANDvalue)+')'
    macd_label= 'MACD('+str(MACDvalue1)+','+str(MACDvalue2)+','+str(MACDvalue3)+')'
    rsi_label= 'RSI('+str(RSIvalue)+')'
    stoch_label= 'STOCH('+str(STOCHvalue1)+','+str(STOCHvalue2)+')'
    dmi_label= 'DMI('+str(DMIvalue)+')'
    ultosc_label= 'ULTOSC('+str(ULTOSCvalue1)+','+str(ULTOSCvalue2)+','+str(ULTOSCvalue3)+')'
    fig = plt.figure(figsize=(18, 21))
    plt.subplots_adjust(left=0.1, right=0.95, bottom=0.1, top=0.95)
    gs = gridspec.GridSpec(48, 1)
    ax1 = plt.subplot(gs[0:17, 0:1]) 
    if rule[0] == 0:    #0.5*10で縦横5インチです。
        plt.ylabel(ema_label)
    if rule[0] == 1:    #0.5*10で縦横5インチです。
        plt.ylabel(ema_label,color = 'r')
    ax1_1 = ax1.twinx()
    if rule[1] == 0:    #0.5*10で縦横5インチです。
        plt.ylabel(bband_label)
    if rule[1] == 1:    #0.5*10で縦横5インチです。
        plt.ylabel(bband_label,color = 'r')
    ax2 = plt.subplot(gs[18:22, 0:1])   #縦3インチ横3インチ
    plt.ylabel('ATR')
    ax3 = plt.subplot(gs[23:27, 0:1])   #縦3インチ横2インチ
    if rule[2] == 0: 
        plt.ylabel(macd_label)
    if rule[2] == 1: 
        plt.ylabel(macd_label,color = 'r')
    ax4 = plt.subplot(gs[28:32, 0:1]) 
    if rule[3] == 0: 
        plt.ylabel(rsi_label)
    if rule[3] == 1: 
        plt.ylabel(rsi_label,color = 'r')
    ax5 = plt.subplot(gs[33:37, 0:1]) 
    if rule[4] == 0: 
        plt.ylabel(stoch_label)
    if rule[4] == 1: 
        plt.ylabel(stoch_label,color = 'r')
    ax6 = plt.subplot(gs[38:42, 0:1]) 
    if rule[5] == 0: 
        plt.ylabel(dmi_label)
    if rule[5] == 1: 
        plt.ylabel(dmi_label,color = 'r')
    ax7 = plt.subplot(gs[43:47, 0:1]) 
    if rule[6] == 0: 
        plt.ylabel(ultosc_label)
    if rule[6] == 1: 
        plt.ylabel(ultosc_label,color = 'r')
    
    ax1.grid()
    ax1.xaxis.set_major_locator(mdates.MonthLocator())
    ax1.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M:%S'))
    ax1.get_yaxis().get_major_formatter().set_useOffset(False)
    ax1.get_yaxis().set_major_locator(ticker.MaxNLocator(integer=True))
    mpf.candlestick_ohlc(ax1, df.values ,width=0.0001, colorup='b', colordown='r',alpha=0.5)
    ax1.plot(df['time'].values,indi_df['EMA1'].values,label='short')
    ax1.plot(df['time'].values,indi_df['EMA2'].values,label='long')
    ax1_1.plot(df['time'].values,indi_df['BBAND1'].values,color = 'g',label='low')
    ax1_1.plot(df['time'].values,indi_df['BBAND2'].values,color = 'g',label='middle')
    ax1_1.plot(df['time'].values,indi_df['BBAND3'].values,color = 'g',label='high')
    ax2.plot(df['time'].values,indi_df['EMA_ATR'].values,label='EMA')
    ax2.plot(df['time'].values,indi_df['BBAND_ATR'].values,label='BBAND')
    ax2.plot(df['time'].values,indi_df['MACD_ATR'].values,label='MACD')
    ax2.plot(df['time'].values,indi_df['RSI_ATR'].values,label='RSI')
    ax2.plot(df['time'].values,indi_df['STOCH_ATR'].values,label='STOCH')
    ax2.plot(df['time'].values,indi_df['DMI_ATR'].values,label='DMI')
    ax2.plot(df['time'].values,indi_df['ULTOSC_ATR'].values,label='ULTOSC')
    ax3.plot(df['time'].values,indi_df['MACD1'].values,label='macd')
    ax3.plot(df['time'].values,indi_df['MACD2'].values,label='signal')
    ax4.plot(df['time'].values,indi_df['RSI'].values,label='RSI')
    ax5.plot(df['time'].values,indi_df['STOCH1'].values,label='%K')
    ax5.plot(df['time'].values,indi_df['STOCH2'].values,label='%D')
    ax6.plot(df['time'].values,indi_df['DMI1'].values,label='ADX')
    ax6.plot(df['time'].values,indi_df['DMI2'].values,label='DIp')
    ax6.plot(df['time'].values,indi_df['DMI3'].values,label='DIm')
    ax7.plot(df['time'].values,indi_df['ULTOSC'].values,label='ULTOSC')
    #print(entry_time)
    #print(first_time)
    positions=mt5.positions_get(symbol="USDJPY")
    if len(positions) > 0:
        
        if entry_time > first_time:
            if indicator == 'EMA':
                if order == 'buy':
                    ax1.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'b', ymin=0, ymax=1) 
                else:
                    ax1.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'r', ymin=0, ymax=1)

            if indicator == 'BBAND':
                if order == 'buy':
                    ax1.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'b', ymin=0, ymax=1)
                else:
                    ax1.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'r', ymin=0, ymax=1)
            
            if indicator == 'MACD':
                if order == 'buy':
                    ax1.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'b', ymin=0, ymax=1)
                    ax3.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'b', ymin=0, ymax=1)
                else:
                    ax1.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'r', ymin=0, ymax=1)
                    ax3.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'r', ymin=0, ymax=1)

            if indicator == 'RSI':
                if order == 'buy':
                    ax1.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'b', ymin=0, ymax=1)
                    ax4.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'b', ymin=0, ymax=1)
                else:
                    ax1.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'r', ymin=0, ymax=1)
                    ax4.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'r', ymin=0, ymax=1)

            if indicator == 'STOCH':
                if order == 'buy':
                    ax1.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'b', ymin=0, ymax=1)
                    ax5.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'b', ymin=0, ymax=1)
                else:
                    ax1.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'r', ymin=0, ymax=1)
                    ax5.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'r', ymin=0, ymax=1)

            if indicator == 'DMI':
                if order == 'buy':
                    ax1.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'b', ymin=0, ymax=1)
                    ax6.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'b', ymin=0, ymax=1)
                else:
                    ax1.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'r', ymin=0, ymax=1)
                    ax6.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'r', ymin=0, ymax=1)

            if indicator == 'ULTOSC':
                if order == 'buy':
                    ax1.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'b', ymin=0, ymax=1)
                    ax7.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'b', ymin=0, ymax=1)
                else:
                    ax1.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'r', ymin=0, ymax=1)
                    ax7.axvline(x=entry_time,linestyle = 'dashdot',lw = 0.5,color = 'r', ymin=0, ymax=1)

    if len(positions) > 0:
        if order == 'buy':
            ax1.axhline(y=price,linestyle = 'dashdot',lw = 0.5,color = 'k',xmin=0,xmax=1)
            ax1.axhline(y=price-pips*0.01,linestyle = 'dashdot',lw = 0.5,color ='c',xmin=0,xmax=1)
            ax1.axhline(y=price+(pips*0.01)+0.002,linestyle = 'dashdot',lw = 0.5,color ='m',xmin=0,xmax=1)
        else:
            ax1.axhline(y=price,linestyle = 'dashed',lw = 0.5,color = 'k',xmin=0.1,xmax=0.9)
            ax1.axhline(y=price+pips*0.01,linestyle = 'dashed',lw = 0.5,color ='c',xmin=0,xmax=1)
            ax1.axhline(y=price-(pips*0.01)-0.002,linestyle = 'dashed',lw = 0.5,color ='m',xmin=0,xmax=1)

while True:
    try:
        # データの読み込み
        #EMA
        df = pd.read_csv(path_para_df.iat[0,0], index_col=0)
        EMAvalue1 = df.at[0,'EMA1']
        EMAvalue2 = df.at[0,'EMA2']
        ATRvalue_ema = df.at[0,'ATR']
        ATRweight_ema = df.at[0,'ATRweight']
        #BBAND
        df = pd.read_csv(path_para_df.iat[1,0], index_col=0)
        BBANDvalue = df.at[0,'BBAND']
        ATRvalue_bband = df.at[0,'ATR']
        ATRweight_bband = df.at[0,'ATRweight']
        #MACD
        df = pd.read_csv(path_para_df.iat[2,0], index_col=0)
        MACDvalue1 = df.at[0,'MACD1']
        MACDvalue2 = df.at[0,'MACD2']
        MACDvalue3 = df.at[0,'MACD3']
        ATRvalue_macd = df.at[0,'ATR']
        ATRweight_macd = df.at[0,'ATRweight']
        #RSI
        df = pd.read_csv(path_para_df.iat[3,0], index_col=0)
        RSIvalue = df.at[0,'RSI']
        ATRvalue_rsi = df.at[0,'ATR']
        ATRweight_rsi = df.at[0,'ATRweight']
        #STOCH
        df = pd.read_csv(path_para_df.iat[4,0], index_col=0)
        STOCHvalue1 = df.at[0,'STOCH1']
        STOCHvalue2 = df.at[0,'STOCH2']
        ATRvalue_stoch = df.at[0,'ATR']
        ATRweight_stoch = df.at[0,'ATRweight']
        #DMI
        df = pd.read_csv(path_para_df.iat[5,0], index_col=0)
        DMIvalue = df.at[0,'DMI']
        ATRvalue_dmi = df.at[0,'ATR']
        ATRweight_dmi = df.at[0,'ATRweight']
        #ULTOSC
        df = pd.read_csv(path_para_df.iat[6,0], index_col=0)
        ULTOSCvalue1 = df.at[0,'ULTOSC1']
        ULTOSCvalue2 = df.at[0,'ULTOSC2']
        ULTOSCvalue3 = df.at[0,'ULTOSC3']
        ATRvalue_ultosc = df.at[0,'ATR']
        ATRweight_ultosc = df.at[0,'ATRweight']
        #Entry
        df = pd.read_csv(path_Entry_short, index_col=0)
        df = df.tail(1)
        df = df.reset_index(drop=True)
        entry_time = df.at[0,'time']
        #Oprint(entry_time)
        indicator = df.at[0,'indi']
        order = df.at[0,'order']
        # まずdatetime型にする
        entry_time = pd.to_datetime(entry_time)
        price = df.at[0,'price']
        price = float(price)
        pips = df.at[0,'pips'] 
        pips = float(pips)
        #最適
        df = pd.read_csv(path_Storategy, index_col=0)
        rule_number = df.iat[0,0]
        rule = list(format(rule_number,'07b'))
        rule = np.array(rule,dtype='int64')
        
        #OHLCV
        #最終行を取得---------
        lastRow = sum(1 for line in open(path_ohlcv)) - 2
        #最終行からuse_max行の行数を求める
        pickRow = [lastRow - line for line in range(use_max)]
        pickRow.reverse()
        df = pd.read_csv(path_ohlcv, header=None,skiprows=lambda x: x not in pickRow)
        df.columns = ['time','Open','High','Low','Close','Volume']
        df = df.drop(0)
        # timeの型変換
        # datetime型にする
        df = df.astype({'Open':float,'High':float,'Low':float,'Close':float,'Volume':float})
        df["time"] = pd.to_datetime(df["time"])
        df_ = df.tail(60)
        # 続いて float型へ
        df["time"] = mdates.date2num(df["time"])
        df_first = df_.tail(1)
        ohlcv_last = df_first.iat[0,0]
        dt_now = datetime.datetime.now()
        dt_now = pd.to_datetime(dt_now)
        td = dt_now - ohlcv_last
        if data == '10S':
            if td.seconds < 30:
                flag = 1
            else:
                flag = 0
        if data == '30S':
            if td.seconds < 90:
                flag = 1
            else:
                flag = 0
        if data == '1T':
            if td.seconds < 180:
                flag = 1
            else:
                flag = 0
        if data == '3T':
            if td.seconds < 540:
                flag = 1
            else:
                flag = 0
        if data == '5T':
            if td.seconds < 900:
                flag = 1
            else:
                flag = 0
        if data == '10T':
            if td.seconds < 1800:
                flag = 1
            else:
                flag = 0
        if data == '15T':
            if td.seconds < 2700:
                flag = 1
            else:
                flag = 0

        if flag == 1:
            #NaN回避
            nan_count = df.isnull().sum()
            nan_count_sum = 0
            for i in range(len(nan_count)):
                nan_count_sum = nan_count_sum + nan_count[i]
            #OHLCVにNaNが含まれてなかった場合のみ次へ
            if nan_count_sum == 0:
                col = ['EMA1','EMA2','BBAND1','BBAND2','BBAND3','MACD1','MACD2','MACD3','RSI','STOCH1','STOCH2','DMI1','DMI2','DMI3','ULTOSC','EMA_ATR','BBAND_ATR','MACD_ATR','RSI_ATR','STOCH_ATR','DMI_ATR','ULTOSC_ATR',]
                indi_df = pd.DataFrame(index=[], columns=col)

                #インジケーターの計算
                #EMA
                indi_df['EMA1'] = EMA(df['Close'], EMAvalue1)
                indi_df['EMA2'] = EMA(df['Close'], EMAvalue2)

                indi_df['BBAND1'], indi_df['BBAND2'], indi_df['BBAND3'] = BBAND(df['Close'], BBANDvalue)

                indi_df['MACD1'], indi_df['MACD2'], indi_df['MACD3'] = MACD(df['Close'], MACDvalue1, MACDvalue2, MACDvalue3)

                indi_df['RSI'] = RSI(df['Close'], RSIvalue)

                indi_df['STOCH1'], indi_df['STOCH2'] = STOCH(df['High'], df['Low'], df['Close'], STOCHvalue1, STOCHvalue2)

                indi_df['DMI1'], indi_df['DMI2'], indi_df['DMI3'] = DMI(df['High'], df['Low'], df['Close'], DMIvalue)

                indi_df['ULTOSC'] = ULTOSC(df['High'], df['Low'], df['Close'], ULTOSCvalue1, ULTOSCvalue2, ULTOSCvalue3)

                indi_df['EMA_ATR'] = ATR(df['High'], df['Low'], df['Close'], ATRvalue_ema)
                indi_df['BBAND_ATR'] = ATR(df['High'], df['Low'], df['Close'], ATRvalue_bband)
                indi_df['MACD_ATR'] = ATR(df['High'], df['Low'], df['Close'], ATRvalue_macd)
                indi_df['RSI_ATR'] = ATR(df['High'], df['Low'], df['Close'], ATRvalue_rsi)
                indi_df['STOCH_ATR'] = ATR(df['High'], df['Low'], df['Close'], ATRvalue_stoch)
                indi_df['DMI_ATR'] = ATR(df['High'], df['Low'], df['Close'], ATRvalue_dmi)
                indi_df['ULTOSC_ATR'] = ATR(df['High'], df['Low'], df['Close'], ATRvalue_ultosc)

                indi_df['EMA_ATR'] = indi_df['EMA_ATR'] * ATRweight_ema
                indi_df['BBAND_ATR'] = indi_df['BBAND_ATR'] * ATRweight_bband
                indi_df['MACD_ATR'] = indi_df['MACD_ATR'] * ATRweight_macd
                indi_df['RSI_ATR'] = indi_df['RSI_ATR'] * ATRweight_rsi
                indi_df['STOCH_ATR'] = indi_df['STOCH_ATR'] * ATRweight_stoch
                indi_df['DMI_ATR'] = indi_df['DMI_ATR'] * ATRweight_dmi
                indi_df['ULTOSC_ATR'] = indi_df['ULTOSC_ATR'] * ATRweight_ultosc

                df = df.tail(60)
                indi_df = indi_df.tail(60)
                
                first_time = df_.head(1)
                first_time = first_time.iat[0,0]
                # まずdatetime型にする
                first_time = pd.to_datetime(first_time)

                

                line = drow(df,entry_time,first_time)
                if data == '10S':
                    plt.pause(11)
                if data == '30S':
                    plt.pause(31)
                if data == '1T':
                    plt.pause(61)
                if data == '3T':
                    plt.pause(181)
                if data == '5T':
                    plt.pause(301)
                if data == '10T':
                    plt.pause(601)
                if data == '15T':
                    plt.pause(901)            


                plt.close()

    except pd.errors.EmptyDataError:
        print('csvファイルが読み取れませんでした．スキップします．')
        continue

    except ValueError:
        print('ValueError')
        continue

    except AssertionError:
        print('AssertionError')
        continue

    except OverflowError:
        print('OverflowError')
        continue
    
    except OSError:
        print('OSError')
        continue
