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