analyser_hj3415 4.3.1__tar.gz → 4.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {analyser_hj3415-4.3.1 → analyser_hj3415-4.3.2}/PKG-INFO +1 -1
- analyser_hj3415-4.3.2/analyser_hj3415/.DS_Store +0 -0
- {analyser_hj3415-4.3.1 → analyser_hj3415-4.3.2}/analyser_hj3415/analyser/tsa/__init__.py +2 -1
- {analyser_hj3415-4.3.1 → analyser_hj3415-4.3.2}/analyser_hj3415/analyser/tsa/myprophet.py +2 -3
- {analyser_hj3415-4.3.1 → analyser_hj3415-4.3.2}/pyproject.toml +1 -1
- analyser_hj3415-4.3.1/archive/deprecated/compile.py +0 -39
- analyser_hj3415-4.3.1/archive/deprecated/compile2.py +0 -241
- analyser_hj3415-4.3.1/archive/deprecated/lstm.py +0 -168
- analyser_hj3415-4.3.1/archive/deprecated/prophet.py +0 -132
- analyser_hj3415-4.3.1/archive/deprecated/test_compile.py +0 -51
- analyser_hj3415-4.3.1/archive/workroom/mysklearn.py +0 -50
- analyser_hj3415-4.3.1/archive/workroom/mysklearn2.py +0 -39
- analyser_hj3415-4.3.1/archive/workroom/score.py +0 -342
- analyser_hj3415-4.3.1/archive/workroom/trash.py +0 -289
- {analyser_hj3415-4.3.1 → analyser_hj3415-4.3.2}/README.md +0 -0
- {analyser_hj3415-4.3.1 → analyser_hj3415-4.3.2}/analyser_hj3415/__init__.py +0 -0
- {analyser_hj3415-4.3.1 → analyser_hj3415-4.3.2}/analyser_hj3415/analyser/__init__.py +0 -0
- {analyser_hj3415-4.3.1 → analyser_hj3415-4.3.2}/analyser_hj3415/analyser/eval/__init__.py +0 -0
- {analyser_hj3415-4.3.1 → analyser_hj3415-4.3.2}/analyser_hj3415/analyser/eval/blue.py +0 -0
- {analyser_hj3415-4.3.1 → analyser_hj3415-4.3.2}/analyser_hj3415/analyser/eval/common.py +0 -0
- {analyser_hj3415-4.3.1 → analyser_hj3415-4.3.2}/analyser_hj3415/analyser/eval/growth.py +0 -0
- {analyser_hj3415-4.3.1 → analyser_hj3415-4.3.2}/analyser_hj3415/analyser/eval/mil.py +0 -0
- {analyser_hj3415-4.3.1 → analyser_hj3415-4.3.2}/analyser_hj3415/analyser/eval/red.py +0 -0
- {analyser_hj3415-4.3.1 → analyser_hj3415-4.3.2}/analyser_hj3415/analyser/tsa/common.py +0 -0
- {analyser_hj3415-4.3.1 → analyser_hj3415-4.3.2}/analyser_hj3415/analyser/tsa/lstm.py +0 -0
- {analyser_hj3415-4.3.1 → analyser_hj3415-4.3.2}/analyser_hj3415/cli.py +0 -0
Binary file
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from collections import OrderedDict
|
2
|
-
from datetime import datetime, timedelta
|
2
|
+
from datetime import datetime, timedelta, date
|
3
3
|
from typing import Tuple, List, Dict, Union
|
4
4
|
|
5
5
|
import yfinance as yf
|
@@ -18,12 +18,11 @@ from analyser_hj3415.analyser.tsa.common import PandasTimestampField, ChartPoint
|
|
18
18
|
|
19
19
|
mylogger = setup_logger(__name__,'WARNING')
|
20
20
|
|
21
|
-
|
22
21
|
@dataclass
|
23
22
|
class ProphetLatestData:
|
24
23
|
ticker: str
|
25
24
|
|
26
|
-
date:
|
25
|
+
date: date = field(metadata={"marshmallow_field": fields.Date()})
|
27
26
|
price: float
|
28
27
|
yhat: float
|
29
28
|
yhat_upper: float
|
@@ -1,39 +0,0 @@
|
|
1
|
-
class CorpCompile:
|
2
|
-
@staticmethod
|
3
|
-
def caching_corp_compile_topn(refresh: bool, top=40):
|
4
|
-
"""
|
5
|
-
상위 N개의 기업에 대해 CorpCompileData를 수집합니다..
|
6
|
-
|
7
|
-
매개변수:
|
8
|
-
refresh (bool): 데이터를 새로 가져올지 여부.
|
9
|
-
top (int, optional): 상위 기업 개수. 기본값은 40.
|
10
|
-
"""
|
11
|
-
ranking_topn = CorpCompile.prophet_ranking(refresh=False, top=top)
|
12
|
-
mylogger.info(ranking_topn)
|
13
|
-
corp_compile = CorpCompile('005930')
|
14
|
-
print(f"*** CorpCompile redis cashing top{top} items ***")
|
15
|
-
for i, (code, _) in enumerate(ranking_topn.items()):
|
16
|
-
corp_compile.code = code
|
17
|
-
print(f"{i + 1}. {code}")
|
18
|
-
corp_compile_data = corp_compile.get(refresh=refresh)
|
19
|
-
print(corp_compile_data)
|
20
|
-
|
21
|
-
@staticmethod
|
22
|
-
def caching_mi_compile_all(refresh: bool):
|
23
|
-
"""
|
24
|
-
모든 MI(Market Index)에 대해 MICompileData를 캐싱합니다..
|
25
|
-
|
26
|
-
매개변수:
|
27
|
-
refresh (bool): 데이터를 새로 가져올지 여부.
|
28
|
-
"""
|
29
|
-
mi_compile = MICompile('WTI')
|
30
|
-
print(f"*** MICompileData caching Market Index items ***")
|
31
|
-
for mi_type in MIs._fields:
|
32
|
-
mi_compile.mi_type = mi_type
|
33
|
-
print(f"{mi_type}")
|
34
|
-
mi_compile_data = mi_compile.get(refresh=refresh)
|
35
|
-
print(mi_compile_data)
|
36
|
-
|
37
|
-
|
38
|
-
def test_caching_corp_compile_topn(self):
|
39
|
-
compile.CorpCompile.caching_corp_compile_topn(refresh=True, top=1)
|
@@ -1,241 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
from collections import OrderedDict
|
3
|
-
from dataclasses import dataclass
|
4
|
-
|
5
|
-
from db_hj3415 import myredis
|
6
|
-
from utils_hj3415 import tools, setup_logger
|
7
|
-
|
8
|
-
from analyser_hj3415.analyser import tsa, eval, MIs
|
9
|
-
|
10
|
-
mylogger = setup_logger(__name__,'WARNING')
|
11
|
-
expire_time = tools.to_int(os.getenv('DEFAULT_EXPIRE_TIME_H', 48)) * 3600
|
12
|
-
|
13
|
-
@dataclass
|
14
|
-
class MICompileData:
|
15
|
-
"""
|
16
|
-
MI(Market Index) 데이터를 컴파일하여 저장하는 데이터 클래스.
|
17
|
-
|
18
|
-
속성:
|
19
|
-
mi_type (str): 시장 지수 유형.
|
20
|
-
prophet_data (tsa.ProphetData): Prophet 예측 데이터.
|
21
|
-
lstm_grade (tsa.LSTMGrade): LSTM 등급 데이터.
|
22
|
-
is_lstm_up (bool): LSTM 상승 여부.
|
23
|
-
is_prophet_up (bool): Prophet 상승 여부.
|
24
|
-
lstm_html (str): LSTM 시각화 HTML.
|
25
|
-
prophet_html (str): Prophet 시각화 HTML.
|
26
|
-
"""
|
27
|
-
mi_type: str
|
28
|
-
|
29
|
-
prophet_data: tsa.ProphetLatestData
|
30
|
-
lstm_grade: tsa.LSTMGrade
|
31
|
-
|
32
|
-
is_lstm_up: bool = False
|
33
|
-
is_prophet_up: bool = False
|
34
|
-
|
35
|
-
lstm_html: str = ''
|
36
|
-
prophet_html: str = ''
|
37
|
-
|
38
|
-
|
39
|
-
class MICompile:
|
40
|
-
"""
|
41
|
-
MI(Market Index) 데이터를 컴파일하는 클래스.
|
42
|
-
|
43
|
-
메서드:
|
44
|
-
get(refresh=False) -> MICompileData:
|
45
|
-
MI 데이터를 컴파일하거나 캐시에서 가져옵니다.
|
46
|
-
|
47
|
-
analyser_lstm_all_mi(refresh: bool):
|
48
|
-
모든 MI에 대해 LSTM 예측 및 초기화 수행.
|
49
|
-
"""
|
50
|
-
def __init__(self, mi_type: str):
|
51
|
-
"""
|
52
|
-
MICompile 객체를 초기화합니다.
|
53
|
-
|
54
|
-
매개변수:
|
55
|
-
mi_type (str): 시장 지수 유형.
|
56
|
-
"""
|
57
|
-
assert mi_type in MIs._fields, f"Invalid MI type ({MIs._fields})"
|
58
|
-
self._mi_type = mi_type
|
59
|
-
|
60
|
-
@property
|
61
|
-
def mi_type(self) -> str:
|
62
|
-
"""
|
63
|
-
MI 유형을 반환합니다.
|
64
|
-
|
65
|
-
반환값:
|
66
|
-
str: MI 유형.
|
67
|
-
"""
|
68
|
-
return self._mi_type
|
69
|
-
|
70
|
-
@mi_type.setter
|
71
|
-
def mi_type(self, mi_type: str):
|
72
|
-
"""
|
73
|
-
MI 유형을 변경합니다.
|
74
|
-
|
75
|
-
매개변수:
|
76
|
-
mi_type (str): 새로 설정할 MI 유형.
|
77
|
-
"""
|
78
|
-
assert mi_type in MIs._fields, f"Invalid MI type ({MIs._fields})"
|
79
|
-
self._mi_type = mi_type
|
80
|
-
|
81
|
-
def get(self, refresh=False) -> MICompileData:
|
82
|
-
"""
|
83
|
-
MI 데이터를 컴파일하거나 캐시에서 가져옵니다.
|
84
|
-
|
85
|
-
매개변수:
|
86
|
-
refresh (bool): 데이터를 새로 가져올지 여부.
|
87
|
-
|
88
|
-
반환값:
|
89
|
-
MICompileData: 컴파일된 MI 데이터.
|
90
|
-
"""
|
91
|
-
print(f"{self.mi_type}의 compiling을 시작합니다.")
|
92
|
-
redis_name = self.mi_type + '_mi_compile'
|
93
|
-
print(
|
94
|
-
f"redisname: '{redis_name}' / refresh : {refresh} / expire_time : {expire_time / 3600}h")
|
95
|
-
|
96
|
-
def fetch_mi_compile_data() -> MICompileData:
|
97
|
-
prophet = tsa.MIProphet(self.mi_type)
|
98
|
-
lstm = tsa.MILSTM(self.mi_type)
|
99
|
-
|
100
|
-
data = MICompileData(
|
101
|
-
mi_type=self.mi_type,
|
102
|
-
prophet_data=prophet.generate_latest_data(refresh=refresh),
|
103
|
-
lstm_grade=lstm.get_final_predictions(refresh=refresh)[1],
|
104
|
-
)
|
105
|
-
data.is_lstm_up = lstm.is_lstm_up()
|
106
|
-
data.is_prophet_up = prophet.is_prophet_up(refresh=False)
|
107
|
-
data.lstm_html = lstm.export(refresh=False)
|
108
|
-
data.prophet_html = prophet.export()
|
109
|
-
return data
|
110
|
-
|
111
|
-
mi_compile_data = myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_mi_compile_data, timer=expire_time)
|
112
|
-
return mi_compile_data
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
@dataclass
|
118
|
-
class CorpCompileData:
|
119
|
-
"""
|
120
|
-
기업 데이터를 컴파일하여 저장하는 데이터 클래스.
|
121
|
-
|
122
|
-
속성:
|
123
|
-
code (str): 기업 코드.
|
124
|
-
name (str): 기업 이름.
|
125
|
-
red_data (eval.RedData): RED 분석 데이터.
|
126
|
-
mil_data (eval.MilData): MIL 분석 데이터.
|
127
|
-
prophet_data (tsa.ProphetData): Prophet 예측 데이터.
|
128
|
-
lstm_grade (tsa.LSTMGrade): LSTM 등급 데이터.
|
129
|
-
is_lstm_up (bool): LSTM 상승 여부.
|
130
|
-
is_prophet_up (bool): Prophet 상승 여부.
|
131
|
-
lstm_html (str): LSTM 시각화 HTML.
|
132
|
-
prophet_html (str): Prophet 시각화 HTML.
|
133
|
-
"""
|
134
|
-
code: str
|
135
|
-
name: str
|
136
|
-
|
137
|
-
red_data: eval.RedData
|
138
|
-
mil_data: eval.MilData
|
139
|
-
|
140
|
-
prophet_data: tsa.ProphetLatestData
|
141
|
-
lstm_grade: tsa.LSTMGrade
|
142
|
-
|
143
|
-
is_lstm_up: bool = False
|
144
|
-
is_prophet_up: bool = False
|
145
|
-
|
146
|
-
lstm_html: str = ''
|
147
|
-
prophet_html: str = ''
|
148
|
-
|
149
|
-
|
150
|
-
class CorpCompile:
|
151
|
-
"""
|
152
|
-
기업 데이터를 컴파일하는 클래스.
|
153
|
-
|
154
|
-
메서드:
|
155
|
-
get(refresh=False) -> CorpCompileData:
|
156
|
-
기업 데이터를 컴파일하거나 캐시에서 가져옵니다.
|
157
|
-
|
158
|
-
red_ranking(expect_earn: float = 0.06, refresh=False) -> OrderedDict:
|
159
|
-
RED 데이터를 기반으로 기업 순위를 계산합니다.
|
160
|
-
|
161
|
-
prophet_ranking(refresh=False, top: Union[int, str]='all') -> OrderedDict:
|
162
|
-
Prophet 데이터를 기반으로 기업 순위를 계산합니다.
|
163
|
-
|
164
|
-
analyse_lstm_topn(refresh: bool, top=40):
|
165
|
-
상위 N개의 기업에 대해 LSTM 예측 수행.
|
166
|
-
"""
|
167
|
-
def __init__(self, code: str, expect_earn=0.06):
|
168
|
-
"""
|
169
|
-
CorpCompile 객체를 초기화합니다.
|
170
|
-
|
171
|
-
매개변수:
|
172
|
-
code (str): 기업 코드.
|
173
|
-
expect_earn (float, optional): 예상 수익률. 기본값은 0.06.
|
174
|
-
"""
|
175
|
-
assert tools.is_6digit(code), f'Invalid value : {code}'
|
176
|
-
self._code = code
|
177
|
-
self.expect_earn = expect_earn
|
178
|
-
|
179
|
-
@property
|
180
|
-
def code(self) -> str:
|
181
|
-
"""
|
182
|
-
기업 코드를 반환합니다.
|
183
|
-
|
184
|
-
반환값:
|
185
|
-
str: 기업 코드.
|
186
|
-
"""
|
187
|
-
return self._code
|
188
|
-
|
189
|
-
@code.setter
|
190
|
-
def code(self, code: str):
|
191
|
-
"""
|
192
|
-
기업 코드를 변경합니다.
|
193
|
-
|
194
|
-
매개변수:
|
195
|
-
code (str): 새로 설정할 기업 코드.
|
196
|
-
"""
|
197
|
-
assert tools.is_6digit(code), f'Invalid value : {code}'
|
198
|
-
mylogger.info(f'change code : {self.code} -> {code}')
|
199
|
-
self._code = code
|
200
|
-
|
201
|
-
def get(self, refresh=False) -> CorpCompileData:
|
202
|
-
"""
|
203
|
-
기업 데이터를 컴파일하여 캐시에 저장하거나 캐시에서 가져옵니다.
|
204
|
-
|
205
|
-
매개변수:
|
206
|
-
refresh (bool): 데이터를 새로 가져올지 여부.
|
207
|
-
|
208
|
-
반환값:
|
209
|
-
CorpCompileData: 컴파일된 기업 데이터.
|
210
|
-
"""
|
211
|
-
print(f"{self.code}의 compiling을 시작합니다.")
|
212
|
-
redis_name = self.code + '_corp_compile'
|
213
|
-
print(
|
214
|
-
f"redisname: '{redis_name}' / refresh : {refresh} / expire_time : {expire_time/3600}h")
|
215
|
-
|
216
|
-
def fetch_corp_compile_data() -> CorpCompileData:
|
217
|
-
prophet = tsa.CorpProphet(self.code)
|
218
|
-
lstm = tsa.CorpLSTM(self.code)
|
219
|
-
|
220
|
-
data = CorpCompileData(
|
221
|
-
code=self.code,
|
222
|
-
name=myredis.Corps(self.code,'c101').get_name(data_from='mongo'),
|
223
|
-
red_data=eval.Red(self.code, self.expect_earn).get(refresh=refresh, verbose=False),
|
224
|
-
mil_data=eval.Mil(self.code).get(refresh=refresh, verbose=False),
|
225
|
-
prophet_data=prophet.generate_latest_data(refresh=refresh),
|
226
|
-
lstm_grade=lstm.get_final_predictions(refresh=refresh)[1],
|
227
|
-
)
|
228
|
-
|
229
|
-
data.is_lstm_up = lstm.is_lstm_up()
|
230
|
-
data.is_prophet_up = prophet.is_prophet_up(refresh=False)
|
231
|
-
data.lstm_html = lstm.export(refresh=False)
|
232
|
-
data.prophet_html = prophet.export()
|
233
|
-
return data
|
234
|
-
|
235
|
-
corp_compile_data = myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_corp_compile_data, timer=expire_time)
|
236
|
-
return corp_compile_data
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
@@ -1,168 +0,0 @@
|
|
1
|
-
class MyLstm:
|
2
|
-
def export(self, refresh=False, to="html", num=5) -> Optional[str]:
|
3
|
-
"""
|
4
|
-
과거 및 예측된 주가 데이터를 기반으로 시각화를 생성하고 저장합니다.
|
5
|
-
|
6
|
-
매개변수:
|
7
|
-
refresh (bool): 데이터 새로고침 여부. 기본값은 False.
|
8
|
-
to (str): 그래프 출력 형식 ('hrml', 'png', 'file'). 기본값은 'html'.
|
9
|
-
num (int): 예측 모델 수. 기본값은 5.
|
10
|
-
|
11
|
-
반환값:
|
12
|
-
Optional[str]: HTML 형식의 그래프 문자열(`to='html'`인 경우).
|
13
|
-
None: PNG 또는 HTML 파일로 저장된 경우.
|
14
|
-
|
15
|
-
예외:
|
16
|
-
Exception: 잘못된 `to` 값이 주어졌을 때 발생.
|
17
|
-
"""
|
18
|
-
def prepare_past_data(past_days) -> tuple:
|
19
|
-
# 데이터 준비
|
20
|
-
raw_data_copied = self.raw_data.reset_index()
|
21
|
-
data = raw_data_copied[['Date', 'Close']][-past_days:].reset_index(drop=True)
|
22
|
-
|
23
|
-
# 'Date'와 'Close' 열 추출
|
24
|
-
past_dates = pd.to_datetime(data['Date'])
|
25
|
-
past_prices = data['Close']
|
26
|
-
|
27
|
-
# 'past_prices'가 Series인지 확인
|
28
|
-
if isinstance(past_prices, pd.DataFrame):
|
29
|
-
past_prices = past_prices.squeeze()
|
30
|
-
|
31
|
-
# 'Close' 열의 데이터 타입 변경
|
32
|
-
past_prices = past_prices.astype(float)
|
33
|
-
return past_dates, past_prices
|
34
|
-
|
35
|
-
def prepare_future_data(refresh_in, num_in) -> tuple:
|
36
|
-
future_data, lstm_grade = self.get_final_predictions(refresh=refresh_in, num=num_in)
|
37
|
-
|
38
|
-
# 예측 데이터 준비
|
39
|
-
future_dates = pd.to_datetime(list(future_data.keys()))
|
40
|
-
|
41
|
-
future_prices = pd.Series(future_data.values(), index=range(len(future_data.values()))).astype(float)
|
42
|
-
return future_dates, future_prices
|
43
|
-
|
44
|
-
self.initializing()
|
45
|
-
past_dates, past_prices = prepare_past_data(past_days=120)
|
46
|
-
future_dates, future_prices = prepare_future_data(refresh_in=refresh, num_in=num)
|
47
|
-
|
48
|
-
# 그래프 생성
|
49
|
-
fig = go.Figure()
|
50
|
-
|
51
|
-
# 실제 데이터 추가
|
52
|
-
fig.add_trace(go.Scatter(
|
53
|
-
x=past_dates,
|
54
|
-
y=past_prices,
|
55
|
-
mode='markers',
|
56
|
-
name='실제주가'
|
57
|
-
))
|
58
|
-
|
59
|
-
# 예측 데이터 추가
|
60
|
-
fig.add_trace(go.Scatter(
|
61
|
-
x=future_dates,
|
62
|
-
y=future_prices,
|
63
|
-
mode='lines+markers',
|
64
|
-
name='예측치(30일)'
|
65
|
-
))
|
66
|
-
|
67
|
-
# 레이아웃 업데이트
|
68
|
-
fig.update_layout(
|
69
|
-
xaxis_title='일자',
|
70
|
-
yaxis_title='주가(원)',
|
71
|
-
xaxis=dict(
|
72
|
-
tickformat='%Y/%m',
|
73
|
-
),
|
74
|
-
yaxis=dict(
|
75
|
-
tickformat=".0f",
|
76
|
-
),
|
77
|
-
showlegend=True,
|
78
|
-
)
|
79
|
-
|
80
|
-
mylogger.debug(f"past_dates({len(past_dates)}) - {past_dates}")
|
81
|
-
mylogger.debug(f"past_prices({len(past_prices)} - {past_prices}")
|
82
|
-
mylogger.debug(f"future_dates({len(future_dates)}) - {future_dates}")
|
83
|
-
mylogger.debug(f"future_prices({len(future_prices)}) - {future_prices}")
|
84
|
-
|
85
|
-
fig.update_layout(
|
86
|
-
# title=f'{self.code} {self.name} 주가 예측 그래프(prophet)',
|
87
|
-
xaxis_title='일자',
|
88
|
-
yaxis_title='주가(원)',
|
89
|
-
xaxis=dict(
|
90
|
-
tickformat='%Y/%m', # X축을 '연/월' 형식으로 표시
|
91
|
-
),
|
92
|
-
yaxis=dict(
|
93
|
-
tickformat=".0f", # 소수점 없이 원래 숫자 표시
|
94
|
-
),
|
95
|
-
showlegend=False,
|
96
|
-
)
|
97
|
-
|
98
|
-
if to == 'html':
|
99
|
-
# 그래프 HTML로 변환 (string 형식으로 저장)
|
100
|
-
graph_html = plot(fig, output_type='div')
|
101
|
-
return graph_html
|
102
|
-
elif to == 'png':
|
103
|
-
# 그래프를 PNG 파일로 저장
|
104
|
-
fig.write_image(f"myLSTM_{self.ticker}.png")
|
105
|
-
return None
|
106
|
-
elif to == 'file':
|
107
|
-
# 그래프를 HTML로 저장
|
108
|
-
plot(fig, filename=f'myLSTM_{self.ticker}.html', auto_open=False)
|
109
|
-
return None
|
110
|
-
else:
|
111
|
-
Exception("to 인자가 맞지 않습니다.")
|
112
|
-
|
113
|
-
def visualization(self, refresh=True):
|
114
|
-
"""
|
115
|
-
실제 주가와 예측 주가를 시각화합니다.
|
116
|
-
|
117
|
-
매개변수:
|
118
|
-
refresh (bool): 예측 데이터를 새로고침할지 여부. 기본값은 True.
|
119
|
-
|
120
|
-
반환값:
|
121
|
-
None: 시각화를 출력합니다.
|
122
|
-
"""
|
123
|
-
self.initializing()
|
124
|
-
future_data, _ = self.get_final_predictions(refresh=refresh)
|
125
|
-
mylogger.debug(f'future_data : {future_data}')
|
126
|
-
future_dates = pd.to_datetime(list(future_data.keys()))
|
127
|
-
mylogger.debug(f'future_dates : {future_dates}')
|
128
|
-
future_prices = pd.Series(future_data.values(), index=range(len(future_data.values()))).astype(float)
|
129
|
-
mylogger.debug(f'future_prices : {future_prices}')
|
130
|
-
|
131
|
-
# 시각화1
|
132
|
-
plt.figure(figsize=(10, 6))
|
133
|
-
|
134
|
-
# 실제 주가
|
135
|
-
plt.plot(self.raw_data.index, self.raw_data['Close'], label='Actual Price')
|
136
|
-
|
137
|
-
# 미래 주가 예측
|
138
|
-
plt.plot(future_dates, future_prices, label='Future Predicted Price', linestyle='--')
|
139
|
-
|
140
|
-
plt.xlabel('Date')
|
141
|
-
plt.ylabel('Stock Price')
|
142
|
-
plt.legend()
|
143
|
-
plt.title(f'{self.ticker} Stock Price Prediction with LSTM')
|
144
|
-
plt.show()
|
145
|
-
|
146
|
-
"""# 시각화2
|
147
|
-
plt.figure(figsize=(10, 6))
|
148
|
-
plt.plot(self.raw_data.index[self.lstm_data.train_size + 60:], self.lstm_data.data_2d[self.lstm_data.train_size + 60:], label='Actual Price')
|
149
|
-
plt.plot(self.raw_data.index[self.lstm_data.train_size + 60:], lstm_grade.mean_test_predictions_2d, label='Predicted Price')
|
150
|
-
plt.xlabel('Date')
|
151
|
-
plt.ylabel('Price')
|
152
|
-
plt.legend()
|
153
|
-
plt.title('Stock Price Prediction with LSTM Ensemble')
|
154
|
-
plt.show()"""
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
def test_export(my_lstm_fixture):
|
159
|
-
lstm, _, _, _ = my_lstm_fixture
|
160
|
-
html_str = lstm.export(refresh=False, to='html')
|
161
|
-
print(html_str)
|
162
|
-
lstm.export(refresh=False, to='file')
|
163
|
-
lstm.export(refresh=True, to='png', num=1)
|
164
|
-
|
165
|
-
|
166
|
-
def test_visualization(my_lstm_fixture):
|
167
|
-
lstm, _, _, _ = my_lstm_fixture
|
168
|
-
lstm.visualization(refresh=False)
|
@@ -1,132 +0,0 @@
|
|
1
|
-
class MyProphet:
|
2
|
-
|
3
|
-
def visualization(self):
|
4
|
-
"""
|
5
|
-
Prophet 모델의 예측 결과를 시각화합니다.
|
6
|
-
|
7
|
-
- Matplotlib를 사용하여 예측 결과 및 추세/계절성을 그래프로 출력.
|
8
|
-
"""
|
9
|
-
self.initializing()
|
10
|
-
# 예측 결과 출력
|
11
|
-
print(self.df_forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail())
|
12
|
-
# 예측 결과 시각화 (Matplotlib 사용)
|
13
|
-
fig = self.model.plot(self.df_forecast)
|
14
|
-
# 추세 및 계절성 시각화
|
15
|
-
fig2 = self.model.plot_components(self.df_forecast)
|
16
|
-
plt.show() # 시각화 창 띄우기
|
17
|
-
|
18
|
-
def export(self, to="html") -> Optional[str]:
|
19
|
-
"""
|
20
|
-
예측 결과를 시각화하여 다양한 형식으로 내보냅니다.
|
21
|
-
|
22
|
-
매개변수:
|
23
|
-
refresh (bool): 데이터를 새로 생성할지 여부.
|
24
|
-
to (str): 내보낼 형식 ('html', 'png', 'file').
|
25
|
-
|
26
|
-
반환값:
|
27
|
-
Optional[str]: HTML 문자열로 반환하거나 PNG/HTML 파일로 저장합니다.
|
28
|
-
|
29
|
-
예외:
|
30
|
-
Exception: 지원되지 않는 형식의 경우 예외 발생.
|
31
|
-
"""
|
32
|
-
self.initializing()
|
33
|
-
# Plotly를 사용한 시각화
|
34
|
-
fig = go.Figure()
|
35
|
-
|
36
|
-
# 실제 데이터
|
37
|
-
fig.add_trace(go.Scatter(x=self.df_real['ds'], y=self.df_real['y'], mode='markers', name='실제주가'))
|
38
|
-
# 예측 데이터
|
39
|
-
fig.add_trace(go.Scatter(x=self.df_forecast['ds'], y=self.df_forecast['yhat'], mode='lines', name='예측치'))
|
40
|
-
|
41
|
-
# 상한/하한 구간
|
42
|
-
fig.add_trace(
|
43
|
-
go.Scatter(x=self.df_forecast['ds'], y=self.df_forecast['yhat_upper'], fill=None, mode='lines', name='상한'))
|
44
|
-
fig.add_trace(
|
45
|
-
go.Scatter(x=self.df_forecast['ds'], y=self.df_forecast['yhat_lower'], fill='tonexty', mode='lines', name='하한'))
|
46
|
-
|
47
|
-
fig.update_layout(
|
48
|
-
# title=f'{self.code} {self.name} 주가 예측 그래프(prophet)',
|
49
|
-
xaxis_title='일자',
|
50
|
-
yaxis_title='주가(원)',
|
51
|
-
xaxis = dict(
|
52
|
-
tickformat='%Y/%m', # X축을 '연/월' 형식으로 표시
|
53
|
-
),
|
54
|
-
yaxis = dict(
|
55
|
-
tickformat=".0f", # 소수점 없이 원래 숫자 표시
|
56
|
-
),
|
57
|
-
showlegend=False,
|
58
|
-
)
|
59
|
-
|
60
|
-
if to == 'html':
|
61
|
-
# 그래프 HTML로 변환 (string 형식으로 저장)
|
62
|
-
graph_html = plot(fig, output_type='div')
|
63
|
-
return graph_html
|
64
|
-
elif to == 'png':
|
65
|
-
# 그래프를 PNG 파일로 저장
|
66
|
-
fig.write_image(f"myprophet_{self.ticker}.png")
|
67
|
-
return None
|
68
|
-
elif to == 'file':
|
69
|
-
# 그래프를 HTML 파일로 저장
|
70
|
-
plot(fig, filename=f'myprophet_{self.ticker}.html', auto_open=False)
|
71
|
-
return None
|
72
|
-
else:
|
73
|
-
Exception("to 인자가 맞지 않습니다.")
|
74
|
-
|
75
|
-
class CorpProphet(MyProphet):
|
76
|
-
@staticmethod
|
77
|
-
def prophet_ranking(refresh=False, top: Union[int, str] = 'all') -> OrderedDict:
|
78
|
-
"""
|
79
|
-
Prophet 데이터를 기반으로 기업 순위를 계산합니다.
|
80
|
-
|
81
|
-
매개변수:
|
82
|
-
refresh (bool): 데이터를 새로 가져올지 여부.
|
83
|
-
top (Union[int, str], optional): 상위 기업 개수. 'all'이면 전체 반환. 기본값은 'all'.
|
84
|
-
|
85
|
-
반환값:
|
86
|
-
OrderedDict: Prophet 점수를 기준으로 정렬된 기업 순위.
|
87
|
-
"""
|
88
|
-
print("**** Start Compiling scores and sorting... ****")
|
89
|
-
redis_name = 'prophet_ranking'
|
90
|
-
|
91
|
-
print(
|
92
|
-
f"redisname: '{redis_name}' / refresh : {refresh} / expire_time : {expire_time / 3600}h")
|
93
|
-
|
94
|
-
def fetch_prophet_ranking() -> dict:
|
95
|
-
data = {}
|
96
|
-
c = tsa.CorpProphet('005930')
|
97
|
-
for code in myredis.Corps.list_all_codes():
|
98
|
-
try:
|
99
|
-
c.code = code
|
100
|
-
except ValueError:
|
101
|
-
mylogger.error(f'prophet ranking error : {code}')
|
102
|
-
continue
|
103
|
-
score = c.generate_latest_data(refresh=refresh).score
|
104
|
-
print(f'{code} compiled : {score}')
|
105
|
-
data[code] = score
|
106
|
-
return data
|
107
|
-
|
108
|
-
data_dict = myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_prophet_ranking, timer=expire_time)
|
109
|
-
|
110
|
-
ranking = OrderedDict(sorted(data_dict.items(), key=lambda x: x[1], reverse=True))
|
111
|
-
|
112
|
-
if top == 'all':
|
113
|
-
return ranking
|
114
|
-
else:
|
115
|
-
if isinstance(top, int):
|
116
|
-
return OrderedDict(list(ranking.items())[:top])
|
117
|
-
else:
|
118
|
-
raise ValueError("top 인자는 'all' 이나 int형 이어야 합니다.")
|
119
|
-
|
120
|
-
|
121
|
-
def test_export(self):
|
122
|
-
#print(self.prophet.export_to(to='str'))
|
123
|
-
#self.prophet.export_to(to='png')
|
124
|
-
#self.prophet.export_to(to='htmlfile')
|
125
|
-
self.prophet.export(to='show')
|
126
|
-
self.prophet.ticker = self.test_tickers[2]
|
127
|
-
self.prophet.export(to='show')
|
128
|
-
|
129
|
-
def test_visualization(self):
|
130
|
-
self.prophet.visualization()
|
131
|
-
self.prophet.ticker = self.test_tickers[2]
|
132
|
-
self.prophet.visualization()
|
@@ -1,51 +0,0 @@
|
|
1
|
-
import unittest
|
2
|
-
import pprint
|
3
|
-
|
4
|
-
from analyser_hj3415.analyser import compile, MIs
|
5
|
-
from db_hj3415 import myredis
|
6
|
-
|
7
|
-
|
8
|
-
class CorpCompileTests(unittest.TestCase):
|
9
|
-
def setUp(self):
|
10
|
-
self.test_codes = myredis.Corps.list_all_codes()
|
11
|
-
self.compile = compile.CorpCompile('005930')
|
12
|
-
|
13
|
-
def tearDown(self):
|
14
|
-
pass
|
15
|
-
|
16
|
-
def test_get_one(self):
|
17
|
-
pprint.pprint(self.compile.get(refresh=True), compact=True)
|
18
|
-
pprint.pprint(self.compile.get(refresh=False), compact=True)
|
19
|
-
|
20
|
-
def test_get_all(self):
|
21
|
-
for code in self.test_codes[:2]:
|
22
|
-
self.compile.code = code
|
23
|
-
pprint.pprint(self.compile.get(refresh=True), compact=True)
|
24
|
-
|
25
|
-
def test_red_ranking(self):
|
26
|
-
# 이전이랑 다른 기대수익률세팅이라 리프레시함
|
27
|
-
print(compile.CorpCompile.red_ranking(expect_earn=0.10, refresh=False))
|
28
|
-
print(myredis.Base.get_ttl('red_ranking'))
|
29
|
-
# 강제리프레시
|
30
|
-
print(compile.CorpCompile.red_ranking(refresh=True))
|
31
|
-
print(myredis.Base.get_ttl('red_ranking'))
|
32
|
-
# 이전과 같은 기대수익률로 레디스캐시사용함.
|
33
|
-
print(compile.CorpCompile.red_ranking(refresh=False))
|
34
|
-
|
35
|
-
|
36
|
-
class MICompileTests(unittest.TestCase):
|
37
|
-
def setUp(self):
|
38
|
-
self.mi_types = list(MIs._fields)
|
39
|
-
self.compile = compile.MICompile('WTI')
|
40
|
-
|
41
|
-
def tearDown(self):
|
42
|
-
pass
|
43
|
-
|
44
|
-
def test_get_one(self):
|
45
|
-
pprint.pprint(self.compile.get(refresh=True), compact=True)
|
46
|
-
pprint.pprint(self.compile.get(refresh=False), compact=True)
|
47
|
-
|
48
|
-
def test_get_all(self):
|
49
|
-
for mi_type in self.mi_types:
|
50
|
-
self.compile.mi_type = mi_type
|
51
|
-
pprint.pprint(self.compile.get(refresh=False), compact=True)
|