import statsmodels.api as sm
import statsmodels.stats.diagnostic
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
np.set_printoptions(suppress=True)
import itertools
import warnings
import statsmodels.tsa.stattools as ts
from statsmodels.tsa.seasonal import seasonal_decompose
from statsmodels.tsa.arima_model import ARIMA
#建模分析
from imp import reload
import matplotlib.pyplot as plt
from math import sqrt as sqrt
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
import statsmodels.api as sm
import pandas as pd
import numpy as np
from imp import reload
import matplotlib.pyplot as plt
from math import sqrt as sqrt
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
import statsmodels.api as sm
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import r2_score



def data_split(df):
    print(df.shape)
    column=['Close','Open', 'High', 'Low', 'Volume', 'Rpos', 'Rsize']
    df2=df[column].dropna()
    train_size=int(0.8*df.shape[0])
    test_size=int(df.shape[0]-train_size)
    X1 = df2[['Close']].values
    train=X1[0:train_size]
    test=X1[train_size:]
    return [train,test,train_size,test_size,X1]


# 通过网格搜索对seasonal_order进行定阶
def get_ARIMA_params(train):
    p = d =q= range(0, 2)
    pdq = [(x[0], x[1], x[2]) for x in list(itertools.product(p, d, q))]
    score_aic = 1000000.0
    warnings.filterwarnings("ignore")  # specify to ignore warning messages

    for param in pdq:
        try:

            mod = ARIMA(train, order=param)
            #             mod = sm.tsa.statespace.SARIMAX(endog=train,
            #                                             exog= trainX,
            #                                             order=param,
            #                                             seasonal_order=param_seasonal,
            #                                             simple_differencing=False)
            results = mod.fit()
            print('ARIMA{} - AIC:{}'.format(param, results.aic))
            if results.aic < score_aic:
                score_aic = results.aic
                params = param, results.aic
        except ValueError:
            print('wrong parameters:', param)
            continue
    param, results.aic = params
    print('最优ARIMA{}- AIC:{}'.format(param, results.aic))
    return param

def ARIMA_model(train,param):  #100%历史数据
    regressor1 = ARIMA(train, order=(param[0], param[1], param[2]))  # ARIMA(5,1,3)模型
    results1 = regressor1.fit(disp=0)
    return results1



def mape(y_true, y_pred):
    return np.mean(np.abs(( y_true- y_pred) / y_true)) * 100

if __name__ == '__main__':
    data1 = pd.read_csv('C:/Users/Big Data/Desktop/output/实验2/fuzzy2/WTI.csv', parse_dates=['Date'], index_col=0,
                        encoding='utf-8')
    df = data1.reset_index()
    df = df.dropna()
    #seq_len=6
    train,test,train_size,test_size,X1= data_split(df)
    param=get_ARIMA_params(train)
    #param=(2, 1, 2)
    #结果比较
    regressor1 = ARIMA_model(train,param)
    print(regressor1.summary())

    print(train_size)

    #训练集
    y_train_pred= regressor1.predict(start=1,end =train_size,dynamic=False,typ='levels')#

    #测试集
    #y_test_pred= regressor1.forecast(steps=len(test))[0]

    y_test_pred= regressor1.predict(start=train_size,end=train_size+test_size-1,dynamic=False,typ='levels')
    print(y_test_pred.shape)
    plt.figure(figsize=(10, 4))
    plt.plot(train, color='red')
    plt.plot(y_train_pred, color='blue',label='Predicted Price By ARIMA On Train dataset')
    plt.xlabel('Time')
    plt.ylabel('Price')
    plt.legend()
    plt.show()
    rmse1 = np.sqrt(mean_squared_error(train, y_train_pred))
    mape1 = mape(train ,y_train_pred)
    print('=============训练集===============')
    print("The R2 score on the Train set is:\t{:0.8f}".format(r2_score(train, y_train_pred)))
    print("The MSE on the Train set is:\t{:0.8f}".format(mean_squared_error(train, y_train_pred)))
    print("The RMSE on the Train set is:\t{:0.8f}".format(rmse1))
    print("The MAPE on the Train set is:\t{:0.8f}".format(mape1))
    print("The MAE on the Train set is:\t{:0.8f}".format(mean_absolute_error(train, y_train_pred)))


    plt.figure(figsize=(10, 4))
    plt.plot(test, color='red')
    plt.plot(y_test_pred, color='blue',
             label='Predicted Price By ARIMA On Test dataset')
    plt.xlabel('Time')
    plt.ylabel('Price')
    plt.legend()
    plt.show()
    rmse2 = np.sqrt(mean_squared_error(test, y_test_pred))
    mape2 = mape(test ,y_test_pred)
    print('=============测试集===============')
    print("The R2 score on the Test set is:\t{:0.8f}".format(r2_score(test, y_test_pred)))
    print("The MSE on the Test set is:\t{:0.8f}".format(mean_squared_error(test, y_test_pred)))
    print("The RMSE on the Test set is:\t{:0.8f}".format(rmse2))
    print("The MAPE on the Train set is:\t{:0.8f}".format(mape2))
    print("The MAE on the Test set is:\t{:0.8f}".format(mean_absolute_error(test, y_test_pred)))

    y_var_test = test[1:] - test[:len(test) - 1]
    y_var_predict = y_test_pred[1:] - y_test_pred[:len(y_test_pred) - 1]
    txt = np.zeros(len(y_var_test))
    for i in range(len(y_var_test - 1)):
        txt[i] = np.sign(y_var_test[i]) == np.sign(y_var_predict[i])
    result = sum(txt) / len(txt)
    print('预测涨跌正确:', result)

    print(' ')
    print(r2_score(train, y_train_pred))
    print(mean_squared_error(train, y_train_pred))
    print(rmse1)
    print(mape1)
    print(mean_absolute_error(train, y_train_pred))
    print(' ')
    print(r2_score(test, y_test_pred))
    print(mean_squared_error(test, y_test_pred))
    print(rmse2)
    print(mape2)
    print(mean_absolute_error(test, y_test_pred))
    print(result)