Showing
6 changed files
with
158 additions
and
23 deletions
| 1 | +import datetime | ||
| 2 | +import sys | ||
| 3 | +import numpy as np | ||
| 4 | +import pandas as pd | ||
| 5 | +import pymysql | ||
| 6 | +from sqlalchemy.event import listen | ||
| 7 | +from sqlalchemy.pool import Pool | ||
| 8 | +from sqlalchemy.exc import InternalError,ProgrammingError | ||
| 9 | +from tensorflow.keras.callbacks import EarlyStopping | ||
| 10 | + | ||
| 11 | +from library.AIModel import load_data,create_model,evaluate,predict | ||
| 12 | +from library import cf | ||
| 13 | +from library.open_api import setup_sql_mod | ||
| 14 | + | ||
| 15 | +listen(Pool,'connect',setup_sql_mod) | ||
| 16 | +listen(Pool,'first_connect',setup_sql_mod) | ||
| 17 | + | ||
| 18 | +def filter_by_ai(db_name,simul_num): | ||
| 19 | + from library.simulator_api import simulator_api | ||
| 20 | + sf=simulator_api(simul_num,'real',db_name) | ||
| 21 | + try: | ||
| 22 | + ai_filter(sf.ai_num,sf.engine_simul) | ||
| 23 | + except AttributeError: | ||
| 24 | + sys.exit(1) | ... | ... |
proj/library/AIModel.py
0 → 100644
| 1 | +import sys | ||
| 2 | +from collections import deque | ||
| 3 | +import matplotlib.pyplot as plt | ||
| 4 | +import numpy as np | ||
| 5 | +import pandas as pd | ||
| 6 | +from sklearn import preprocessing | ||
| 7 | +from sklearn.model_selection import train_test_split | ||
| 8 | +from tensorflow.keras.layers import LSTM,Dense,Dropout | ||
| 9 | +from tensorflow.keras.models import Sequential | ||
| 10 | +from tensorflow.python.keras.callbacks import EarlyStopping | ||
| 11 | + | ||
| 12 | + | ||
| 13 | +# 학습 함수 | ||
| 14 | +# params : n_epochs - 모든 데이터셋을 몇 번 학습시킬 것인지 | ||
| 15 | +# batch_size - 데이터셋을 batch_size로 나누어서 학습 | ||
| 16 | +# verbose - 실행 과정을 콘솔에 띄울 것인지 여부 (0:끔/1:움직이는 실시간 그래프/2:정적메세지) | ||
| 17 | +def train(data,model,n_epochs=400,batch_size=64,verbose=0): | ||
| 18 | + # 더이상 성능이 증가하지 않을 경우 학습 중지 | ||
| 19 | + # monitor : 'val_loss' - validation_set's loss monitoring | ||
| 20 | + # patience : 성능이 증가하지 않는 epoch를 몇번 허용할 것인가 | ||
| 21 | + early_stopping=EarlyStopping(monitor='val_loss',patience=50) | ||
| 22 | + # 데이터 학습 | ||
| 23 | + history=model.fit(data["X_train"],data['y_train'], | ||
| 24 | + batch_size=batch_size, | ||
| 25 | + epochs=n_epochs, | ||
| 26 | + validation_data=(data["X_test"],data["y_test"]), | ||
| 27 | + callbacks=[early_stopping], | ||
| 28 | + verbose=verbose) | ||
| 29 | + return history | ||
| 30 | + | ||
| 31 | + | ||
| 32 | +# 에러 평가 함수 | ||
| 33 | +def evaluate(data,model): | ||
| 34 | + # correct : 정답률 / loss : 예측값과 실제값이 차이나는 정도를 나타내는 지표 | ||
| 35 | + correct,loss=model.evaluate(data["X_test"],data["y_test"],verbose=0) | ||
| 36 | + mean_loss=data["column_scaler"]['close'].inverse_transform([[loss]])[0][0] | ||
| 37 | + return mean_loss | ||
| 38 | + | ||
| 39 | + | ||
| 40 | +# 예측 주가 계산 함수 | ||
| 41 | +def predict(data,model,n_steps=100): | ||
| 42 | + last_sequence=data["last_sequence"][-n_steps:] | ||
| 43 | + column_scaler=data["column_scaler"] | ||
| 44 | + last_sequence=last_sequence.reshape(last_sequence.shape[1],last_sequence.shape[0]) | ||
| 45 | + last_sequence=np.expand_dims(last_sequence,axis=0) | ||
| 46 | + prediction=model.predict(last_sequence) | ||
| 47 | + predicted_price=column_scaler['close'].inverse_transform(prediction)[0][0] | ||
| 48 | + return predicted_price | ||
| 49 | + | ||
| 50 | +def load_data(df,n_steps=100,lookup_step=1,test_size=0.2,shuffle=True): | ||
| 51 | + result={} # return 할 값들을 저장하는 변수 | ||
| 52 | + column_scaler={} # 각 행별 정규화된 값을 저장하는 변수 | ||
| 53 | + | ||
| 54 | + # data 값을 0과 1사이 값으로 정규화 | ||
| 55 | + for column in df.columns: | ||
| 56 | + scaler=preprocessing.MinMaxScaler() | ||
| 57 | + df[column]=scaler.fit_transform(np.expand_dims(df[column].to_numpy(),axis=1)) | ||
| 58 | + column_scaler[column]=scaler | ||
| 59 | + | ||
| 60 | + result["column_scaler"]=column_scaler | ||
| 61 | + last_sequence=np.array(df.tail(lookup_step)) | ||
| 62 | + df['future']=df['close'].shift(-lookup_step) | ||
| 63 | + # 결측치 삭제 | ||
| 64 | + df.dropna(inplace=True) | ||
| 65 | + | ||
| 66 | + sequence_data=[] | ||
| 67 | + sequences=deque(maxlen=n_steps) | ||
| 68 | + for entry,target in zip(df.loc[:,df.columns!='future'].to_numpy(),df['future'].to_numpy()): | ||
| 69 | + sequences.append(entry) | ||
| 70 | + if len(sequences)==n_steps: | ||
| 71 | + sequence_data.append([np.array(sequences),target]) | ||
| 72 | + | ||
| 73 | + if not sequence_data: | ||
| 74 | + pass | ||
| 75 | + | ||
| 76 | + last_sequence=list(sequences)+list(last_sequence) | ||
| 77 | + last_sequence=np.array(pd.DataFrame(last_sequence).shift(-1).dropna()) | ||
| 78 | + | ||
| 79 | + X,y=[],[] | ||
| 80 | + | ||
| 81 | + for seq,target in sequence_data: | ||
| 82 | + X.append(seq) | ||
| 83 | + y.append(target) | ||
| 84 | + | ||
| 85 | + X=np.array(X) | ||
| 86 | + y=np.array(y) | ||
| 87 | + X=X.reshape((X.shape[0],X.shape[2],X.shape[1])) | ||
| 88 | + | ||
| 89 | + # dataset을 train/test용으로 분리 | ||
| 90 | + result["X_train"],result["X_test"],result["y_train"],result["y_test"]=train_test_split(X,y,test_size=test_size,shuffle=shuffle) | ||
| 91 | + | ||
| 92 | + return result | ||
| 93 | + | ||
| 94 | + | ||
| 95 | +# 모델 생성함수 | ||
| 96 | +# optimizer : 훈련과정 설정. 일반적으로 사용하는 adam 사용 | ||
| 97 | +# loss : 최적화 과정에서 최소화될 손실함수 설정. 일반적으로 사용되며 데이터가 연속된 예측값이므로 mean_squared_error 사용 | ||
| 98 | +# cell : 시계열 데이터이므로 LSTM | ||
| 99 | +def create_model(units=50,dropout=0.3,n_steps=100,loss="mse",optimizer="adam",n_layers=4,cell=LSTM): | ||
| 100 | + model=Sequential() | ||
| 101 | + for i in range(n_layers): | ||
| 102 | + if i==0: | ||
| 103 | + model.add(cell(units,return_sequences=True,input_shape=(None,n_steps))) | ||
| 104 | + elif i==n_layers-1: | ||
| 105 | + model.add(cell(units)) | ||
| 106 | + else: | ||
| 107 | + model.add(cell(units,return_sequences=True)) | ||
| 108 | + | ||
| 109 | + # 매 layer마다 과적합을 방지하기 위해 dropout | ||
| 110 | + model.add(Dropout(dropout)) | ||
| 111 | + # dense : 예측하고자 하는 target이 1개 | ||
| 112 | + model.add(Dense(1)) | ||
| 113 | + model.compile(loss=loss,metrics=[loss],optimizer=optimizer) | ||
| 114 | + | ||
| 115 | + return model | ||
| 116 | + | ||
| 117 | +# 그래프 출력 | ||
| 118 | +def plot_graph(model,data): | ||
| 119 | + y_test=data["y_test"] | ||
| 120 | + X_test=data["X_test"] | ||
| 121 | + y_pred=model.predict(X_test) | ||
| 122 | + y_test=np.squeeze(data["column_scaler"]["close"].inverse__transform(np.expand_dims(y_test,axis=0))) | ||
| 123 | + y_pred=np.squeeze(data["column_scaler"]['close'].inverse_transform[y_pred]) | ||
| 124 | + plt.plot(y_test[-200:],c="b") | ||
| 125 | + plt.plot(y_pred[-200:],c='r') | ||
| 126 | + plt.xlabel("Days") | ||
| 127 | + plt.ylabel("Price") | ||
| 128 | + plt.legend(["Actual_price","Predicted Price"]) | ||
| 129 | + plt.show() | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -511,6 +511,11 @@ class simulator_api: | ... | @@ -511,6 +511,11 @@ class simulator_api: |
| 511 | # realtime_daily_buy_list 테이블에 저장 된 종목들을 저장 | 511 | # realtime_daily_buy_list 테이블에 저장 된 종목들을 저장 |
| 512 | self.get_realtime_daily_buy_list() | 512 | self.get_realtime_daily_buy_list() |
| 513 | 513 | ||
| 514 | + # 딥러닝 알고리즘을 이용 | ||
| 515 | + if self.use_ai: | ||
| 516 | + from ai_trader import ai_filter | ||
| 517 | + ai_filter(self.ai_num, engine=self.engine_simul, until=date_rows_yesterday) | ||
| 518 | + | ||
| 514 | # 모의투자 / 실전투자 | 519 | # 모의투자 / 실전투자 |
| 515 | else: | 520 | else: |
| 516 | df_realtime_daily_buy_list['check_item'] = int(0) | 521 | df_realtime_daily_buy_list['check_item'] = int(0) | ... | ... |
proj/requirements_32.txt
deleted
100644 → 0
proj/requirements_64.txt
deleted
100644 → 0
주간보고서(2020.11.13).docx
0 → 100644
No preview for this file type
-
Please register or login to post a comment