analyser_hj3415 3.2.2__py3-none-any.whl → 3.3.1__py3-none-any.whl
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/analyser/__init__.py +30 -12
- analyser_hj3415/analyser/compile.py +222 -133
- analyser_hj3415/analyser/eval/blue.py +78 -9
- analyser_hj3415/analyser/eval/common.py +72 -110
- analyser_hj3415/analyser/eval/growth.py +77 -6
- analyser_hj3415/analyser/eval/mil.py +119 -18
- analyser_hj3415/analyser/eval/red.py +95 -66
- analyser_hj3415/analyser/tsa/__init__.py +1 -1
- analyser_hj3415/analyser/tsa/common.py +33 -0
- analyser_hj3415/analyser/tsa/lstm.py +108 -133
- analyser_hj3415/analyser/tsa/prophet.py +261 -124
- analyser_hj3415/cli.py +12 -9
- {analyser_hj3415-3.2.2.dist-info → analyser_hj3415-3.3.1.dist-info}/METADATA +1 -1
- analyser_hj3415-3.3.1.dist-info/RECORD +23 -0
- analyser_hj3415-3.2.2.dist-info/RECORD +0 -22
- {analyser_hj3415-3.2.2.dist-info → analyser_hj3415-3.3.1.dist-info}/WHEEL +0 -0
- {analyser_hj3415-3.2.2.dist-info → analyser_hj3415-3.3.1.dist-info}/entry_points.txt +0 -0
@@ -1,12 +1,30 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
"
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
1
|
+
from typing import NamedTuple
|
2
|
+
|
3
|
+
class MarketIndices(NamedTuple):
|
4
|
+
"""
|
5
|
+
주요 시장 지수를 나타내는 NamedTuple입니다.
|
6
|
+
|
7
|
+
속성:
|
8
|
+
WTI (str): 서부 텍사스 중질유(WTI) 선물 지수 (심볼: "CL=F").
|
9
|
+
GOLD (str): 금 선물 지수 (심볼: "GC=F").
|
10
|
+
SILVER (str): 은 선물 지수 (심볼: "SI=F").
|
11
|
+
USD_IDX (str): 미국 달러 인덱스 (심볼: "DX-Y.NYB").
|
12
|
+
USD_KRW (str): 달러-원 환율 (심볼: "KRW=X").
|
13
|
+
SP500 (str): S&P 500 주가지수 (심볼: "^GSPC").
|
14
|
+
KOSPI (str): 코스피 지수 (심볼: "^KS11").
|
15
|
+
NIKKEI (str): 닛케이 225 지수 (일본) (심볼: "^N225").
|
16
|
+
CHINA (str): 항셍 지수 (홍콩) (심볼: "^HSI").
|
17
|
+
IRX (str): 미국 단기 국채 금리 지수 (13주 T-빌 금리) (심볼: "^IRX").
|
18
|
+
"""
|
19
|
+
WTI: str = "CL=F"
|
20
|
+
GOLD: str = "GC=F"
|
21
|
+
SILVER: str = "SI=F"
|
22
|
+
USD_IDX: str = "DX-Y.NYB"
|
23
|
+
USD_KRW: str = "KRW=X"
|
24
|
+
SP500: str = "^GSPC"
|
25
|
+
KOSPI: str = "^KS11"
|
26
|
+
NIKKEI: str = "^N225"
|
27
|
+
CHINA: str = "^HSI"
|
28
|
+
IRX: str = "^IRX"
|
29
|
+
|
30
|
+
MIs = MarketIndices()
|
@@ -1,8 +1,9 @@
|
|
1
1
|
import os
|
2
2
|
from collections import OrderedDict
|
3
3
|
from typing import Union
|
4
|
+
from dataclasses import dataclass
|
4
5
|
|
5
|
-
from db_hj3415 import myredis
|
6
|
+
from db_hj3415 import myredis
|
6
7
|
from utils_hj3415 import tools, setup_logger
|
7
8
|
|
8
9
|
from analyser_hj3415.analyser import tsa, eval, MIs
|
@@ -10,183 +11,259 @@ from analyser_hj3415.analyser import tsa, eval, MIs
|
|
10
11
|
mylogger = setup_logger(__name__,'WARNING')
|
11
12
|
expire_time = tools.to_int(os.getenv('DEFAULT_EXPIRE_TIME_H', 48)) * 3600
|
12
13
|
|
14
|
+
@dataclass
|
15
|
+
class MICompileData:
|
16
|
+
"""
|
17
|
+
MI(Market Index) 데이터를 컴파일하여 저장하는 데이터 클래스.
|
18
|
+
|
19
|
+
속성:
|
20
|
+
mi_type (str): 시장 지수 유형.
|
21
|
+
prophet_data (tsa.ProphetData): Prophet 예측 데이터.
|
22
|
+
lstm_grade (tsa.LSTMGrade): LSTM 등급 데이터.
|
23
|
+
is_lstm_up (bool): LSTM 상승 여부.
|
24
|
+
is_prophet_up (bool): Prophet 상승 여부.
|
25
|
+
lstm_html (str): LSTM 시각화 HTML.
|
26
|
+
prophet_html (str): Prophet 시각화 HTML.
|
27
|
+
"""
|
28
|
+
mi_type: str
|
29
|
+
|
30
|
+
prophet_data: tsa.ProphetData
|
31
|
+
lstm_grade: tsa.LSTMGrade
|
32
|
+
|
33
|
+
is_lstm_up: bool = False
|
34
|
+
is_prophet_up: bool = False
|
35
|
+
|
36
|
+
lstm_html: str = ''
|
37
|
+
prophet_html: str = ''
|
38
|
+
|
39
|
+
|
13
40
|
class MICompile:
|
41
|
+
"""
|
42
|
+
MI(Market Index) 데이터를 컴파일하는 클래스.
|
43
|
+
|
44
|
+
메서드:
|
45
|
+
get(refresh=False) -> MICompileData:
|
46
|
+
MI 데이터를 컴파일하거나 캐시에서 가져옵니다.
|
47
|
+
|
48
|
+
analyser_lstm_all_mi(refresh: bool):
|
49
|
+
모든 MI에 대해 LSTM 예측 및 초기화 수행.
|
50
|
+
"""
|
14
51
|
def __init__(self, mi_type: str):
|
15
|
-
|
52
|
+
"""
|
53
|
+
MICompile 객체를 초기화합니다.
|
54
|
+
|
55
|
+
매개변수:
|
56
|
+
mi_type (str): 시장 지수 유형.
|
57
|
+
"""
|
58
|
+
assert mi_type in MIs._fields, f"Invalid MI type ({MIs._fields})"
|
16
59
|
self._mi_type = mi_type
|
17
|
-
self.prophet = tsa.MIProphet(mi_type)
|
18
|
-
self.lstm = tsa.MILSTM(mi_type)
|
19
60
|
|
20
61
|
@property
|
21
62
|
def mi_type(self) -> str:
|
63
|
+
"""
|
64
|
+
MI 유형을 반환합니다.
|
65
|
+
|
66
|
+
반환값:
|
67
|
+
str: MI 유형.
|
68
|
+
"""
|
22
69
|
return self._mi_type
|
23
70
|
|
24
71
|
@mi_type.setter
|
25
72
|
def mi_type(self, mi_type: str):
|
26
|
-
|
73
|
+
"""
|
74
|
+
MI 유형을 변경합니다.
|
75
|
+
|
76
|
+
매개변수:
|
77
|
+
mi_type (str): 새로 설정할 MI 유형.
|
78
|
+
"""
|
79
|
+
assert mi_type in MIs._fields, f"Invalid MI type ({MIs._fields})"
|
27
80
|
self._mi_type = mi_type
|
28
|
-
self.prophet.mi_type = mi_type
|
29
|
-
self.lstm.mi_type = mi_type
|
30
81
|
|
31
|
-
def get(self, refresh=False) ->
|
82
|
+
def get(self, refresh=False) -> MICompileData:
|
32
83
|
"""
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
Defaults to False.
|
41
|
-
|
42
|
-
Returns:
|
43
|
-
dict: MI 데이터를 포함하는 딕셔너리로 반환하며, 다음의 키를 포함합니다:
|
44
|
-
- 'name' (str): MI 타입 이름.
|
45
|
-
- 'trading_action' (str): 예측된 매매 신호 ('buy', 'sell', 'hold').
|
46
|
-
- 'prophet_score' (float): Prophet 모델의 예측 점수.
|
47
|
-
- 'lstm_grade' (float): LSTM 모델의 최종 예측 점수.
|
48
|
-
- 'is_lstm_up' (bool): LSTM 모델이 상승 신호를 나타내는지 여부.
|
49
|
-
- 'prophet_html' (str): prophet_html,
|
50
|
-
- 'lstm_html' (str): lstm_html ,
|
51
|
-
Example:
|
52
|
-
{
|
53
|
-
'name': 'example_mi',
|
54
|
-
'trading_action': 'buy',
|
55
|
-
'prophet_score': 0.88,
|
56
|
-
'lstm_grade': 0.92,
|
57
|
-
'is_lstm_up': True,
|
58
|
-
'prophet_html': prophet_html...,
|
59
|
-
'lstm_html': lstm_html...,
|
60
|
-
}
|
84
|
+
MI 데이터를 컴파일하거나 캐시에서 가져옵니다.
|
85
|
+
|
86
|
+
매개변수:
|
87
|
+
refresh (bool): 데이터를 새로 가져올지 여부.
|
88
|
+
|
89
|
+
반환값:
|
90
|
+
MICompileData: 컴파일된 MI 데이터.
|
61
91
|
"""
|
62
92
|
print(f"{self.mi_type}의 compiling을 시작합니다.")
|
63
93
|
redis_name = self.mi_type + '_mi_compile'
|
64
94
|
print(
|
65
95
|
f"redisname: '{redis_name}' / refresh : {refresh} / expire_time : {expire_time / 3600}h")
|
66
96
|
|
67
|
-
def
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
}
|
85
|
-
|
86
|
-
data_dict = myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_mi_compile, timer=expire_time)
|
87
|
-
return data_dict
|
97
|
+
def fetch_mi_compile_data() -> MICompileData:
|
98
|
+
prophet = tsa.MIProphet(self.mi_type)
|
99
|
+
lstm = tsa.MILSTM(self.mi_type)
|
100
|
+
|
101
|
+
data = MICompileData(
|
102
|
+
mi_type=self.mi_type,
|
103
|
+
prophet_data=prophet.generate_data(refresh=refresh),
|
104
|
+
lstm_grade=lstm.get_final_predictions(refresh=refresh)[1],
|
105
|
+
)
|
106
|
+
data.is_lstm_up = lstm.is_lstm_up()
|
107
|
+
data.is_prophet_up = prophet.is_prophet_up(refresh=False)
|
108
|
+
data.lstm_html = lstm.export(refresh=False)
|
109
|
+
data.prophet_html = prophet.export()
|
110
|
+
return data
|
111
|
+
|
112
|
+
mi_compile_data = myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_mi_compile_data, timer=expire_time)
|
113
|
+
return mi_compile_data
|
88
114
|
|
89
115
|
@staticmethod
|
90
116
|
def analyser_lstm_all_mi(refresh: bool):
|
91
|
-
|
117
|
+
"""
|
118
|
+
모든 MI(Market Index)에 대해 LSTM 예측과 초기화를 수행합니다.
|
119
|
+
|
120
|
+
매개변수:
|
121
|
+
refresh (bool): 데이터를 새로 가져올지 여부.
|
122
|
+
"""
|
123
|
+
mi_lstm = tsa.MILSTM('WTI')
|
92
124
|
print(f"*** LSTM prediction redis cashing Market Index items ***")
|
93
|
-
for mi_type in MIs.
|
125
|
+
for mi_type in MIs._fields:
|
94
126
|
mi_lstm.mi_type = mi_type
|
95
127
|
print(f"{mi_lstm.mi_type}")
|
96
128
|
mi_lstm.initializing()
|
97
129
|
mi_lstm.get_final_predictions(refresh=refresh, num=5)
|
98
130
|
|
131
|
+
@dataclass
|
132
|
+
class CorpCompileData:
|
133
|
+
"""
|
134
|
+
기업 데이터를 컴파일하여 저장하는 데이터 클래스.
|
135
|
+
|
136
|
+
속성:
|
137
|
+
code (str): 기업 코드.
|
138
|
+
name (str): 기업 이름.
|
139
|
+
red_data (eval.RedData): RED 분석 데이터.
|
140
|
+
mil_data (eval.MilData): MIL 분석 데이터.
|
141
|
+
prophet_data (tsa.ProphetData): Prophet 예측 데이터.
|
142
|
+
lstm_grade (tsa.LSTMGrade): LSTM 등급 데이터.
|
143
|
+
is_lstm_up (bool): LSTM 상승 여부.
|
144
|
+
is_prophet_up (bool): Prophet 상승 여부.
|
145
|
+
lstm_html (str): LSTM 시각화 HTML.
|
146
|
+
prophet_html (str): Prophet 시각화 HTML.
|
147
|
+
"""
|
148
|
+
code: str
|
149
|
+
name: str
|
150
|
+
|
151
|
+
red_data: eval.RedData
|
152
|
+
mil_data: eval.MilData
|
153
|
+
|
154
|
+
prophet_data: tsa.ProphetData
|
155
|
+
lstm_grade: tsa.LSTMGrade
|
156
|
+
|
157
|
+
is_lstm_up: bool = False
|
158
|
+
is_prophet_up: bool = False
|
159
|
+
|
160
|
+
lstm_html: str = ''
|
161
|
+
prophet_html: str = ''
|
162
|
+
|
99
163
|
|
100
164
|
class CorpCompile:
|
165
|
+
"""
|
166
|
+
기업 데이터를 컴파일하는 클래스.
|
167
|
+
|
168
|
+
메서드:
|
169
|
+
get(refresh=False) -> CorpCompileData:
|
170
|
+
기업 데이터를 컴파일하거나 캐시에서 가져옵니다.
|
171
|
+
|
172
|
+
red_ranking(expect_earn: float = 0.06, refresh=False) -> OrderedDict:
|
173
|
+
RED 데이터를 기반으로 기업 순위를 계산합니다.
|
174
|
+
|
175
|
+
prophet_ranking(refresh=False, top: Union[int, str]='all') -> OrderedDict:
|
176
|
+
Prophet 데이터를 기반으로 기업 순위를 계산합니다.
|
177
|
+
|
178
|
+
analyse_lstm_topn(refresh: bool, top=40):
|
179
|
+
상위 N개의 기업에 대해 LSTM 예측 수행.
|
180
|
+
"""
|
101
181
|
def __init__(self, code: str, expect_earn=0.06):
|
182
|
+
"""
|
183
|
+
CorpCompile 객체를 초기화합니다.
|
184
|
+
|
185
|
+
매개변수:
|
186
|
+
code (str): 기업 코드.
|
187
|
+
expect_earn (float, optional): 예상 수익률. 기본값은 0.06.
|
188
|
+
"""
|
102
189
|
assert tools.is_6digit(code), f'Invalid value : {code}'
|
103
190
|
self._code = code
|
104
|
-
self.
|
105
|
-
self.red = eval.Red(code, expect_earn)
|
106
|
-
self.mil = eval.Mil(code)
|
107
|
-
self.prophet = tsa.CorpProphet(code)
|
191
|
+
self.expect_earn = expect_earn
|
108
192
|
|
109
193
|
@property
|
110
194
|
def code(self) -> str:
|
195
|
+
"""
|
196
|
+
기업 코드를 반환합니다.
|
197
|
+
|
198
|
+
반환값:
|
199
|
+
str: 기업 코드.
|
200
|
+
"""
|
111
201
|
return self._code
|
112
202
|
|
113
203
|
@code.setter
|
114
204
|
def code(self, code: str):
|
205
|
+
"""
|
206
|
+
기업 코드를 변경합니다.
|
207
|
+
|
208
|
+
매개변수:
|
209
|
+
code (str): 새로 설정할 기업 코드.
|
210
|
+
"""
|
115
211
|
assert tools.is_6digit(code), f'Invalid value : {code}'
|
116
212
|
mylogger.info(f'change code : {self.code} -> {code}')
|
117
213
|
self._code = code
|
118
|
-
self.name = mymongo.Corps.get_name(code)
|
119
|
-
self.red.code = code
|
120
|
-
self.mil.code = code
|
121
|
-
self.prophet.code = code
|
122
214
|
|
123
|
-
def get(self, refresh=False) ->
|
215
|
+
def get(self, refresh=False) -> CorpCompileData:
|
124
216
|
"""
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
Defaults to False.
|
133
|
-
|
134
|
-
Returns:
|
135
|
-
dict: 기업 데이터를 포함하는 딕셔너리로 반환되며, 다음의 키를 포함합니다:
|
136
|
-
- 'name' (str): 기업 이름.
|
137
|
-
- 'red_score' (float): 기업의 Red Score (위험 점수).
|
138
|
-
- '이익지표' (float): 기업의 이익 지표.
|
139
|
-
- '주주수익률' (float): 주주 수익률.
|
140
|
-
- 'trading_action' (str): 예측된 매매 신호 ('buy', 'sell', 'hold').
|
141
|
-
- 'prophet_score' (float): Prophet 모델의 예측 점수.
|
142
|
-
- 'prophet_html' (str): prophet_html,
|
143
|
-
|
144
|
-
Example:
|
145
|
-
{
|
146
|
-
'name': 'Samsung Electronics',
|
147
|
-
'red_score': 0.85,
|
148
|
-
'이익지표': 0.75,
|
149
|
-
'주주수익률': 0.10,
|
150
|
-
'trading_action': 'buy',
|
151
|
-
'prophet_score': 0.92,
|
152
|
-
'prophet_html': prophet_html...,
|
153
|
-
}
|
217
|
+
기업 데이터를 컴파일하거나 캐시에서 가져옵니다.
|
218
|
+
|
219
|
+
매개변수:
|
220
|
+
refresh (bool): 데이터를 새로 가져올지 여부.
|
221
|
+
|
222
|
+
반환값:
|
223
|
+
CorpCompileData: 컴파일된 기업 데이터.
|
154
224
|
"""
|
155
|
-
print(f"{self.code}
|
225
|
+
print(f"{self.code}의 compiling을 시작합니다.")
|
156
226
|
redis_name = self.code + '_corp_compile'
|
157
227
|
print(
|
158
228
|
f"redisname: '{redis_name}' / refresh : {refresh} / expire_time : {expire_time/3600}h")
|
159
229
|
|
160
|
-
def
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
return data_dict
|
230
|
+
def fetch_corp_compile_data() -> CorpCompileData:
|
231
|
+
prophet = tsa.CorpProphet(self.code)
|
232
|
+
lstm = tsa.CorpLSTM(self.code)
|
233
|
+
|
234
|
+
data = CorpCompileData(
|
235
|
+
code=self.code,
|
236
|
+
name=myredis.Corps(self.code,'c101').get_name(data_from='mongo'),
|
237
|
+
red_data=eval.Red(self.code, self.expect_earn).get(refresh=refresh, verbose=False),
|
238
|
+
mil_data=eval.Mil(self.code).get(refresh=refresh, verbose=False),
|
239
|
+
prophet_data=prophet.generate_data(refresh=refresh),
|
240
|
+
lstm_grade=lstm.get_final_predictions(refresh=refresh)[1],
|
241
|
+
)
|
242
|
+
|
243
|
+
data.is_lstm_up = lstm.is_lstm_up()
|
244
|
+
data.is_prophet_up = prophet.is_prophet_up(refresh=False)
|
245
|
+
data.lstm_html = lstm.export(refresh=False)
|
246
|
+
data.prophet_html = prophet.export()
|
247
|
+
return data
|
248
|
+
|
249
|
+
corp_compile_data = myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_corp_compile_data, timer=expire_time)
|
250
|
+
return corp_compile_data
|
182
251
|
|
183
252
|
@staticmethod
|
184
253
|
def red_ranking(expect_earn: float = 0.06, refresh=False) -> OrderedDict:
|
185
|
-
|
254
|
+
"""
|
255
|
+
RED 데이터를 기반으로 기업 순위를 계산합니다.
|
256
|
+
|
257
|
+
매개변수:
|
258
|
+
expect_earn (float, optional): 예상 수익률. 기본값은 0.06.
|
259
|
+
refresh (bool): 데이터를 새로 가져올지 여부.
|
260
|
+
|
261
|
+
반환값:
|
262
|
+
OrderedDict: RED 점수를 기준으로 정렬된 기업 순위.
|
263
|
+
"""
|
186
264
|
redis_name = 'red_ranking_prev_expect_earn'
|
187
265
|
pee = tools.to_float(myredis.Base.get_value(redis_name))
|
188
266
|
if pee != expect_earn:
|
189
|
-
# expect earn의 이전 계산값이 없거나 이전 값과 다르면 새로 계산
|
190
267
|
mylogger.warning(
|
191
268
|
f"expect earn : {expect_earn} / prev expect earn : {pee} 두 값이 달라 refresh = True"
|
192
269
|
)
|
@@ -215,31 +292,39 @@ class CorpCompile:
|
|
215
292
|
|
216
293
|
@staticmethod
|
217
294
|
def prophet_ranking(refresh=False, top: Union[int, str]='all') -> OrderedDict:
|
295
|
+
"""
|
296
|
+
Prophet 데이터를 기반으로 기업 순위를 계산합니다.
|
218
297
|
|
298
|
+
매개변수:
|
299
|
+
refresh (bool): 데이터를 새로 가져올지 여부.
|
300
|
+
top (Union[int, str], optional): 상위 기업 개수. 'all'이면 전체 반환. 기본값은 'all'.
|
301
|
+
|
302
|
+
반환값:
|
303
|
+
OrderedDict: Prophet 점수를 기준으로 정렬된 기업 순위.
|
304
|
+
"""
|
219
305
|
print("**** Start Compiling scores and sorting... ****")
|
220
306
|
redis_name = 'prophet_ranking'
|
221
307
|
|
222
308
|
print(
|
223
309
|
f"redisname: '{redis_name}' / refresh : {refresh} / expire_time : {expire_time/3600}h")
|
224
310
|
|
225
|
-
def
|
311
|
+
def fetch_prophet_ranking() -> dict:
|
226
312
|
data = {}
|
227
|
-
c =
|
313
|
+
c = tsa.CorpProphet('005930')
|
228
314
|
for code in myredis.Corps.list_all_codes():
|
229
315
|
try:
|
230
316
|
c.code = code
|
231
317
|
except ValueError:
|
232
318
|
mylogger.error(f'prophet ranking error : {code}')
|
233
319
|
continue
|
234
|
-
|
235
|
-
print(f'{code} compiled : {
|
236
|
-
data[code] =
|
320
|
+
score= c.generate_data(refresh=refresh).score
|
321
|
+
print(f'{code} compiled : {score}')
|
322
|
+
data[code] = score
|
237
323
|
return data
|
238
324
|
|
239
|
-
data_dict = myredis.Base.fetch_and_cache_data(redis_name, refresh,
|
325
|
+
data_dict = myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_prophet_ranking, timer=expire_time)
|
240
326
|
|
241
|
-
|
242
|
-
ranking = OrderedDict(sorted(data_dict.items(), key=lambda x: x[1]['prophet_score'], reverse=True))
|
327
|
+
ranking = OrderedDict(sorted(data_dict.items(), key=lambda x: x[1], reverse=True))
|
243
328
|
|
244
329
|
if top == 'all':
|
245
330
|
return ranking
|
@@ -251,6 +336,13 @@ class CorpCompile:
|
|
251
336
|
|
252
337
|
@staticmethod
|
253
338
|
def analyse_lstm_topn(refresh: bool, top=40):
|
339
|
+
"""
|
340
|
+
상위 N개의 기업에 대해 LSTM 예측을 수행합니다.
|
341
|
+
|
342
|
+
매개변수:
|
343
|
+
refresh (bool): 데이터를 새로 가져올지 여부.
|
344
|
+
top (int, optional): 상위 기업 개수. 기본값은 40.
|
345
|
+
"""
|
254
346
|
ranking_topn = CorpCompile.prophet_ranking(refresh=False, top=top)
|
255
347
|
mylogger.info(ranking_topn)
|
256
348
|
corp_lstm = tsa.CorpLSTM('005930')
|
@@ -258,7 +350,4 @@ class CorpCompile:
|
|
258
350
|
for i, (code, _) in enumerate(ranking_topn.items()):
|
259
351
|
corp_lstm.code = code
|
260
352
|
print(f"{i + 1}. {corp_lstm.code}/{corp_lstm.name}")
|
261
|
-
corp_lstm.initializing()
|
262
353
|
corp_lstm.get_final_predictions(refresh=refresh, num=5)
|
263
|
-
|
264
|
-
|
@@ -15,6 +15,28 @@ expire_time = tools.to_int(os.getenv('DEFAULT_EXPIRE_TIME_H', 48)) * 3600
|
|
15
15
|
|
16
16
|
@dataclass()
|
17
17
|
class BlueData:
|
18
|
+
"""
|
19
|
+
기업의 주요 안정성 지표와 관련된 데이터를 저장하는 데이터 클래스.
|
20
|
+
|
21
|
+
이 클래스는 기업의 유동성, 부채 비율, 자산 회전율 등을 포함하며,
|
22
|
+
이를 활용하여 기업의 안정성을 평가할 수 있습니다.
|
23
|
+
|
24
|
+
속성:
|
25
|
+
code (str): 기업의 종목 코드 (6자리 숫자 문자열).
|
26
|
+
name (str): 기업명.
|
27
|
+
유동비율 (float): 유동 자산 대비 유동 부채 비율.
|
28
|
+
이자보상배율_r (float): 최근 이자보상배율 값.
|
29
|
+
이자보상배율_dict (dict): 이자보상배율 데이터.
|
30
|
+
순운전자본회전율_r (float): 최근 순운전자본회전율 값.
|
31
|
+
순운전자본회전율_dict (dict): 순운전자본회전율 데이터.
|
32
|
+
재고자산회전율_r (float): 최근 재고자산회전율 값.
|
33
|
+
재고자산회전율_dict (dict): 재고자산회전율 데이터.
|
34
|
+
재고자산회전율_c106 (dict): C106 기준 재고자산회전율 데이터.
|
35
|
+
순부채비율_r (float): 최근 순부채비율 값.
|
36
|
+
순부채비율_dict (dict): 순부채비율 데이터.
|
37
|
+
score (list): 평가 점수.
|
38
|
+
date (list): 데이터와 관련된 날짜 목록.
|
39
|
+
"""
|
18
40
|
code: str
|
19
41
|
name: str
|
20
42
|
|
@@ -38,6 +60,20 @@ class BlueData:
|
|
38
60
|
|
39
61
|
|
40
62
|
class Blue:
|
63
|
+
"""
|
64
|
+
기업의 안정성 지표를 분석하고 계산하는 클래스.
|
65
|
+
|
66
|
+
이 클래스는 주어진 기업 코드에 대해 주요 안정성 지표(예: 유동비율, 이자보상배율 등)를 수집하고,
|
67
|
+
이를 기반으로 기업의 안정성을 평가합니다. Redis 캐시를 활용하여 계산된 데이터를 저장하고
|
68
|
+
재사용할 수 있습니다.
|
69
|
+
|
70
|
+
속성:
|
71
|
+
c101 (myredis.C101): 기업 정보 및 최근 데이터 접근 객체.
|
72
|
+
c103 (myredis.C103): 재무 상태표 데이터 접근 객체.
|
73
|
+
c104 (myredis.C104): 투자 지표 데이터 접근 객체.
|
74
|
+
name (str): 기업명.
|
75
|
+
_code (str): 기업 종목 코드.
|
76
|
+
"""
|
41
77
|
def __init__(self, code: str):
|
42
78
|
assert tools.is_6digit(code), f'Invalid value : {code}'
|
43
79
|
mylogger.debug(f"Blue : 종목코드 ({code})")
|
@@ -69,10 +105,22 @@ class Blue:
|
|
69
105
|
self._code = code
|
70
106
|
|
71
107
|
def _calc유동비율(self, pop_count: int, refresh: bool) -> Tuple[str, float]:
|
72
|
-
"""
|
108
|
+
"""
|
109
|
+
기업의 유동비율을 계산합니다.
|
110
|
+
|
111
|
+
유동비율 데이터가 유효하지 않거나 100 이하일 경우,
|
112
|
+
유동자산과 유동부채를 기반으로 계산을 수행합니다.
|
113
|
+
|
114
|
+
매개변수:
|
115
|
+
pop_count (int): 데이터 검색 시 사용할 값의 개수.
|
116
|
+
refresh (bool): 데이터를 새로고침할지 여부.
|
117
|
+
|
118
|
+
반환값:
|
119
|
+
Tuple[str, float]: 날짜와 계산된 유동비율.
|
73
120
|
|
74
|
-
|
75
|
-
|
121
|
+
로그:
|
122
|
+
- 유동비율 계산 과정과 결과를 출력합니다.
|
123
|
+
- 계산 중 유효하지 않은 데이터가 있으면 경고를 출력합니다.
|
76
124
|
"""
|
77
125
|
mylogger.info(f'In the calc유동비율... refresh : {refresh}')
|
78
126
|
self.c104.page = 'c104q'
|
@@ -111,6 +159,17 @@ class Blue:
|
|
111
159
|
return [0 ,]
|
112
160
|
|
113
161
|
def _generate_data(self, refresh: bool) -> BlueData:
|
162
|
+
"""
|
163
|
+
BlueData 형식의 데이터를 생성합니다.
|
164
|
+
|
165
|
+
각종 안정성 지표를 계산하고 데이터를 정리하여 BlueData 객체로 반환합니다.
|
166
|
+
|
167
|
+
매개변수:
|
168
|
+
refresh (bool): 데이터를 새로고침할지 여부.
|
169
|
+
|
170
|
+
반환값:
|
171
|
+
BlueData: 계산된 안정성 지표 데이터.
|
172
|
+
"""
|
114
173
|
d1, 유동비율 = self._calc유동비율(pop_count=3, refresh=refresh)
|
115
174
|
mylogger.info(f'유동비율 {유동비율} / [{d1}]')
|
116
175
|
|
@@ -171,9 +230,20 @@ class Blue:
|
|
171
230
|
|
172
231
|
def get(self, refresh = False, verbose = True) -> BlueData:
|
173
232
|
"""
|
174
|
-
BlueData
|
175
|
-
|
176
|
-
|
233
|
+
BlueData 객체를 Redis 캐시에서 가져오거나 새로 생성하여 반환합니다.
|
234
|
+
|
235
|
+
캐시에서 데이터를 검색하고, 없을 경우 `_generate_data`를 호출하여 데이터를 생성합니다.
|
236
|
+
생성된 데이터는 Redis 캐시에 저장되어 재사용됩니다.
|
237
|
+
|
238
|
+
매개변수:
|
239
|
+
refresh (bool): 캐시를 무시하고 새로 데이터를 계산할지 여부. 기본값은 False.
|
240
|
+
verbose (bool): 실행 중 상세 정보를 출력할지 여부. 기본값은 True.
|
241
|
+
|
242
|
+
반환값:
|
243
|
+
BlueData: Redis 캐시에서 가져오거나 새로 생성된 BlueData 객체.
|
244
|
+
|
245
|
+
로그:
|
246
|
+
- 캐시 검색 상태와 새로 생성된 데이터를 출력합니다.
|
177
247
|
"""
|
178
248
|
redis_name = f"{self.code}_blue"
|
179
249
|
mylogger.info(f"{self} BlueData를 레디스캐시에서 가져오거나 새로 생성합니다.. refresh : {refresh}")
|
@@ -181,7 +251,6 @@ class Blue:
|
|
181
251
|
print(f"{self} redisname: '{redis_name}' / refresh : {refresh} / expire_time : {expire_time /3600}h")
|
182
252
|
|
183
253
|
def fetch_generate_data(refresh_in: bool) -> dict:
|
184
|
-
return
|
254
|
+
return self._generate_data(refresh_in) # type: ignore
|
185
255
|
|
186
|
-
return
|
187
|
-
(**myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_generate_data, refresh, timer=expire_time))
|
256
|
+
return myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_generate_data, refresh, timer=expire_time)
|