from sqlalchemy import create_engine
import pymysql
import pandas as pd
import numpy as np

pymysql.install_as_MySQLdb()
engine = create_engine("mysql+mysqldb://root:"+"swhacademy!"+"@192.168.0.41/market", encoding='utf-8')
conn = engine.connect()

df = pd.read_sql_query("select * from stock_trade where 종목코드 = '000660'", conn)
df.name = "주가변동"
print(df.head())

import matplotlib.pyplot as plt
# 화면 크기
plt.figure(figsize=(16,8))

# 인덱스 확인 (그래프의 X축 : DB로 부터 읽어온 값은 DataFrame으로 불러올 시, 0부터 숫자가 붙어있음)
print(df.index)

# 날짜를 그래프 Y축으로, X축은 디폴트로 0부터 붙은 인덱스 값
#plt.plot(df['날짜'], label='종가 그래프')

# 날짜 포맷 변경 
#df['날짜'] = pd.to_datetime (df.날짜, format = '%Y-%m-%d')    # 날짜 포맷이 동일하기 때문에 수행할 필요가 없음

# 종가를 그래프 Y축으로, X축은 날짜
df.index = df['날짜']
plt.plot(df['종가'], label='종가 그래프')
#plt.show()
print(df)



# 정렬
# df.sort_index() 는 인덱스인 날짜로 정렬
# df.sort_index(ascending=True, axis=0) 역시 인덱스 정렬
# df.sort_index(ascending=True, axis=1) 컬럼 이름으로 왼쪽부터 오른쪽으로 정렬
df = df.sort_index(ascending=True, axis=0)    # 수행하지 않아도 이미 DB로부터 읽어올 때 날짜로 정렬




# 날짜와 목표변수인 종가로 이루어진 DataFrame 만들기

# Case1. 빈 DataFrame을 만든 후, 복사하기

# 날짜와 목표변수로 빈 dataframe 만들기
new_data = pd.DataFrame(index=range(0, len(df)), columns=['날짜', '종가'])
print(new_data)

# 날짜와 목표변수인 종가로 dataframe 에 df값 매칭
for i in range(0,len(df)):
     new_data['날짜'][i] = df['날짜'][i]
     new_data['종가'][i] = df['종가'][i]
print(new_data.head())  # 날짜와 종가에 대한 데이터


# Case2. 기존 DataFrame을 복사한 후, 불 필요한 컬럼 제거
# copy()함수에는 행 또는 열을 제거할 때 사용, axis=1일때 세로 축 삭제, axis=0일때 가로 축 삭제
# drop()함수에는 행 또는 열을 제거할 때 사용, axis=1일때 세로 축 삭제, axis=0일때 가로 축 삭제
new_data = df.copy(deep=True)
new_data = new_data.drop(['시가', '고가', '저가', '거래량', '종목코드'], axis=1)
new_data.index = range(len(df))
print(new_data.head())




# raw 데이터 생성 완료, 이후에는 validation과 train데이터를 통한 평균제곱근 오차 수행

# 데이터를 train과 validation 세트로 분할하는 동안 '날짜' 요소가 손상되므로 임의 분할(random splitting)을 사용할 수 없음
# 작년의 데이터를 validation 세트로 설정하고 4년 전의 데이터를 train 세트로 설정

# splitting into train and validation
print(new_data['날짜'] < '2019-01-01')
train = new_data[new_data['날짜'] < '2019-01-01']
valid = new_data[new_data['날짜'] >= '2019-01-01']

# shapes of training set
print('\n Shape of training set:')
print(train.shape)

# shapes of validation set
print('\n Shape of validation set:')
print(valid.shape)

# validation 세트에 대한 예측을 만들고, 실제 값을 사용하여 RMSE(평균 제곱근 오차)을 점검
# validation 세트에 대한 예측 (Observed value값의 범위를 valid.shape[0] 로 선정)
print('유효성 검사를 위한 행의 수 : %d' % valid.shape[0])
validRaw = valid.shape[0]
preds = []  # 훈련 셋을 각 구간(Observed value값) 마다 이동평균 값을 저장
for i in range(0, validRaw):
    a = train['종가'][len(train) - validRaw + i:].sum() + sum(preds)
    b = a / validRaw
    preds.append(b)
print(preds)
print(len(preds))

# 실제 값을 사용하여 RMSE(평균 제곱근 오차)을 점검
rms = np.sqrt(np.mean(np.power((np.array(valid['종가']) - preds), 2)))
print('\n RMSE value on validation set:')
print(rms)



# RMSE를 확인하는 것만으로는 모델의 성능을 이해하는 데 도움이되지 않습니다. 
# 더 직관적으로 이해하기 위해 이것을 시각화 해 봅시다. 여기에 실제 값과 함께 예측 된 값의 도표을 확인
# Pandas에서는 파생 DataFrame에 수정을 가하는 것을 권장하지 않습니다.(그래서 경고를 띄우는 것이죠.) 
# 대신 Pandas는 copy() 메서드를 통해 파생 DataFrame에 독립적인 메모리를 부여한 뒤 여기에 수정을 가하도록 유도하지요.
#valid['예측'] = 0
#valid['예측'] = preds
#print(valid)

valid = valid.copy();
valid['예측'] = preds
print(valid)
#train.index = train['날짜']
print(train.index)
plt.plot(train['종가'])
#plt.show()
print(valid.index)
plt.plot(valid[['종가', '예측']])
#plt.show()