analyser_hj3415 3.2.2__py3-none-any.whl → 3.3.0__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.
@@ -1,12 +1,30 @@
1
- MIs = {
2
- "wti": "CL=F",
3
- "gold": "GC=F",
4
- "silver": "SI=F",
5
- "usdidx": "DX-Y.NYB",
6
- "usdkrw": "KRW=X",
7
- "sp500": "^GSPC",
8
- "kospi": "^KS11",
9
- "nikkei": "^N225",
10
- "china": "^HSI",
11
- "irx": "^IRX",
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,mymongo
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,12 +11,25 @@ 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
+
15
+ @dataclass
16
+ class MICompileData:
17
+ mi_type: str
18
+
19
+ prophet_data: tsa.ProphetData
20
+ lstm_grade: tsa.LSTMGrade
21
+
22
+ is_lstm_up: bool = False
23
+ is_prophet_up: bool = False
24
+
25
+ lstm_html: str = ''
26
+ prophet_html: str = ''
27
+
28
+
13
29
  class MICompile:
14
30
  def __init__(self, mi_type: str):
15
- assert mi_type in MIs.keys(), f"Invalid MI type ({MIs.keys()})"
31
+ assert mi_type in MIs._fields, f"Invalid MI type ({MIs._fields})"
16
32
  self._mi_type = mi_type
17
- self.prophet = tsa.MIProphet(mi_type)
18
- self.lstm = tsa.MILSTM(mi_type)
19
33
 
20
34
  @property
21
35
  def mi_type(self) -> str:
@@ -23,88 +37,67 @@ class MICompile:
23
37
 
24
38
  @mi_type.setter
25
39
  def mi_type(self, mi_type: str):
26
- assert mi_type in MIs.keys(), f"Invalid MI type ({MIs.keys()})"
40
+ assert mi_type in MIs._fields, f"Invalid MI type ({MIs._fields})"
27
41
  self._mi_type = mi_type
28
- self.prophet.mi_type = mi_type
29
- self.lstm.mi_type = mi_type
30
42
 
31
- def get(self, refresh=False) -> dict:
32
- """
33
- 특정 MI(Market Index) 타입 데이터를 컴파일하고 반환합니다.
34
- 데이터를 Redis 캐시에서 가져오거나, 새로 생성하여 캐시에 저장합니다.
35
-
36
- Args:
37
- refresh (bool, optional):
38
- - True: 캐시를 무시하고 데이터를 새로 생성하여 저장.
39
- - False: 캐시된 데이터를 가져오며, 없을 경우 새로 생성.
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
- }
61
- """
43
+ def get(self, refresh=False) -> MICompileData:
62
44
  print(f"{self.mi_type}의 compiling을 시작합니다.")
63
45
  redis_name = self.mi_type + '_mi_compile'
64
46
  print(
65
47
  f"redisname: '{redis_name}' / refresh : {refresh} / expire_time : {expire_time / 3600}h")
66
48
 
67
- def fetch_mi_compile() -> dict:
68
- print(f"{self.mi_type}")
69
- trading_action, prophet_score = self.prophet.scoring()
70
- prophet_html = self.prophet.export()
71
- self.lstm.initializing()
72
- _, lstm_grade = self.lstm.get_final_predictions(refresh=refresh, num=5)
73
- is_lstm_up = self.lstm.is_lstm_up()
74
- lstm_html= self.lstm.export()
75
-
76
- return {
77
- 'name': self.mi_type,
78
- 'trading_action': trading_action,
79
- 'prophet_score': prophet_score,
80
- 'lstm_grade': lstm_grade,
81
- 'is_lstm_up': is_lstm_up,
82
- 'prophet_html': prophet_html,
83
- 'lstm_html': lstm_html,
84
- }
85
-
86
- data_dict = myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_mi_compile, timer=expire_time)
87
- return data_dict
49
+ def fetch_mi_compile_data() -> MICompileData:
50
+ prophet = tsa.MIProphet(self.mi_type)
51
+ lstm = tsa.MILSTM(self.mi_type)
52
+
53
+ data = MICompileData(
54
+ mi_type=self.mi_type,
55
+ prophet_data=prophet.generate_data(refresh=refresh),
56
+ lstm_grade=lstm.get_final_predictions(refresh=refresh)[1],
57
+ )
58
+ data.is_lstm_up = lstm.is_lstm_up()
59
+ data.is_prophet_up = prophet.is_prophet_up(refresh=False)
60
+ data.lstm_html = lstm.export(refresh=False)
61
+ data.prophet_html = prophet.export()
62
+ return data
63
+
64
+ mi_compile_data = myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_mi_compile_data, timer=expire_time)
65
+ return mi_compile_data
88
66
 
89
67
  @staticmethod
90
68
  def analyser_lstm_all_mi(refresh: bool):
91
- mi_lstm = tsa.MILSTM('wti')
69
+ mi_lstm = tsa.MILSTM('WTI')
92
70
  print(f"*** LSTM prediction redis cashing Market Index items ***")
93
- for mi_type in MIs.keys():
71
+ for mi_type in MIs._fields:
94
72
  mi_lstm.mi_type = mi_type
95
73
  print(f"{mi_lstm.mi_type}")
96
74
  mi_lstm.initializing()
97
75
  mi_lstm.get_final_predictions(refresh=refresh, num=5)
98
76
 
99
77
 
78
+ @dataclass
79
+ class CorpCompileData:
80
+ code: str
81
+ name: str
82
+
83
+ red_data: eval.RedData
84
+ mil_data: eval.MilData
85
+
86
+ prophet_data: tsa.ProphetData
87
+ lstm_grade: tsa.LSTMGrade
88
+
89
+ is_lstm_up: bool = False
90
+ is_prophet_up: bool = False
91
+
92
+ lstm_html: str = ''
93
+ prophet_html: str = ''
94
+
95
+
100
96
  class CorpCompile:
101
97
  def __init__(self, code: str, expect_earn=0.06):
102
98
  assert tools.is_6digit(code), f'Invalid value : {code}'
103
99
  self._code = code
104
- self.name = mymongo.Corps.get_name(code)
105
- self.red = eval.Red(code, expect_earn)
106
- self.mil = eval.Mil(code)
107
- self.prophet = tsa.CorpProphet(code)
100
+ self.expect_earn = expect_earn
108
101
 
109
102
  @property
110
103
  def code(self) -> str:
@@ -115,70 +108,34 @@ class CorpCompile:
115
108
  assert tools.is_6digit(code), f'Invalid value : {code}'
116
109
  mylogger.info(f'change code : {self.code} -> {code}')
117
110
  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
111
 
123
112
  def get(self, refresh=False) -> dict:
124
- """
125
- 특정 기업 데이터를 컴파일하여 반환합니다.
126
- 데이터를 Redis 캐시에서 가져오거나, 새로 생성하여 캐시에 저장합니다.
127
-
128
- Args:
129
- refresh (bool, optional):
130
- - True: 캐시를 무시하고 데이터를 새로 생성하여 저장.
131
- - False: 캐시된 데이터를 가져오며, 없을 경우 새로 생성.
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
- }
154
- """
155
- print(f"{self.code}/{self.name}의 compiling을 시작합니다.")
113
+ print(f"{self.code}의 compiling을 시작합니다.")
156
114
  redis_name = self.code + '_corp_compile'
157
115
  print(
158
116
  f"redisname: '{redis_name}' / refresh : {refresh} / expire_time : {expire_time/3600}h")
159
117
 
160
- def fetch_corp_compile() -> dict:
161
- mylogger.info("Red score 계산중..")
162
- red_score = self.red.get(verbose=False).score
163
-
164
- mylogger.info("Mil data 계산중..")
165
- mil_data = self.mil.get(verbose=False)
166
-
167
- mylogger.info("\tProphet 최근 데이터 조회중..")
168
- trading_action, prophet_score = self.prophet.scoring()
169
- prophet_html = self.prophet.export()
170
-
171
- return {
172
- 'name': self.name,
173
- 'red_score': red_score,
174
- '이익지표': mil_data.이익지표,
175
- '주주수익률': mil_data.주주수익률,
176
- 'trading_action': trading_action,
177
- 'prophet_score': prophet_score,
178
- 'prophet_html': prophet_html,
179
- }
180
- data_dict = myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_corp_compile, timer=expire_time)
181
- return data_dict
118
+ def fetch_corp_compile_data() -> CorpCompileData:
119
+ prophet = tsa.CorpProphet(self.code)
120
+ lstm = tsa.CorpLSTM(self.code)
121
+
122
+ data = CorpCompileData(
123
+ code=self.code,
124
+ name=myredis.Corps(self.code,'c101').get_name(data_from='mongo'),
125
+ red_data=eval.Red(self.code, self.expect_earn).get(refresh=refresh, verbose=False),
126
+ mil_data=eval.Mil(self.code).get(refresh=refresh, verbose=False),
127
+ prophet_data=prophet.generate_data(refresh=refresh),
128
+ lstm_grade=lstm.get_final_predictions(refresh=refresh)[1],
129
+ )
130
+
131
+ data.is_lstm_up = lstm.is_lstm_up()
132
+ data.is_prophet_up = prophet.is_prophet_up(refresh=False)
133
+ data.lstm_html = lstm.export(refresh=False)
134
+ data.prophet_html = prophet.export()
135
+ return data
136
+
137
+ corp_compile_data = myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_corp_compile_data, timer=expire_time)
138
+ return corp_compile_data
182
139
 
183
140
  @staticmethod
184
141
  def red_ranking(expect_earn: float = 0.06, refresh=False) -> OrderedDict:
@@ -222,24 +179,24 @@ class CorpCompile:
222
179
  print(
223
180
  f"redisname: '{redis_name}' / refresh : {refresh} / expire_time : {expire_time/3600}h")
224
181
 
225
- def fetch_ranking() -> dict:
182
+ def fetch_prophet_ranking() -> dict:
226
183
  data = {}
227
- c = CorpCompile('005930')
184
+ c = tsa.CorpProphet('005930')
228
185
  for code in myredis.Corps.list_all_codes():
229
186
  try:
230
187
  c.code = code
231
188
  except ValueError:
232
189
  mylogger.error(f'prophet ranking error : {code}')
233
190
  continue
234
- scores= c.get(refresh=refresh)
235
- print(f'{code} compiled : {scores}')
236
- data[code] = scores
191
+ score= c.generate_data(refresh=refresh).score
192
+ print(f'{code} compiled : {score}')
193
+ data[code] = score
237
194
  return data
238
195
 
239
- data_dict = myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_ranking, timer=expire_time)
196
+ data_dict = myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_prophet_ranking, timer=expire_time)
240
197
 
241
198
  # prophet_score를 기준으로 정렬
242
- ranking = OrderedDict(sorted(data_dict.items(), key=lambda x: x[1]['prophet_score'], reverse=True))
199
+ ranking = OrderedDict(sorted(data_dict.items(), key=lambda x: x[1], reverse=True))
243
200
 
244
201
  if top == 'all':
245
202
  return ranking
@@ -258,7 +215,4 @@ class CorpCompile:
258
215
  for i, (code, _) in enumerate(ranking_topn.items()):
259
216
  corp_lstm.code = code
260
217
  print(f"{i + 1}. {corp_lstm.code}/{corp_lstm.name}")
261
- corp_lstm.initializing()
262
218
  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
- """유동비율계산 - Blue에서 사용
108
+ """
109
+ 기업의 유동비율을 계산합니다.
110
+
111
+ 유동비율 데이터가 유효하지 않거나 100 이하일 경우,
112
+ 유동자산과 유동부채를 기반으로 계산을 수행합니다.
113
+
114
+ 매개변수:
115
+ pop_count (int): 데이터 검색 시 사용할 값의 개수.
116
+ refresh (bool): 데이터를 새로고침할지 여부.
117
+
118
+ 반환값:
119
+ Tuple[str, float]: 날짜와 계산된 유동비율.
73
120
 
74
- c104q에서 최근유동비율 찾아보고 유효하지 않거나 \n
75
- 100이하인 경우에는수동으로 계산해서 다시 한번 평가해 본다.\n
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
- :param refresh:
176
- :return:
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 asdict(self._generate_data(refresh_in))
254
+ return self._generate_data(refresh_in) # type: ignore
185
255
 
186
- return BlueData \
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)