analyser_hj3415 2.10.0__py3-none-any.whl → 2.10.2__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/cli.py +2 -3
- analyser_hj3415/eval.py +1 -1
- analyser_hj3415/score.py +157 -0
- analyser_hj3415/tsa.py +33 -40
- {analyser_hj3415-2.10.0.dist-info → analyser_hj3415-2.10.2.dist-info}/METADATA +1 -1
- {analyser_hj3415-2.10.0.dist-info → analyser_hj3415-2.10.2.dist-info}/RECORD +8 -7
- {analyser_hj3415-2.10.0.dist-info → analyser_hj3415-2.10.2.dist-info}/WHEEL +0 -0
- {analyser_hj3415-2.10.0.dist-info → analyser_hj3415-2.10.2.dist-info}/entry_points.txt +0 -0
analyser_hj3415/cli.py
CHANGED
@@ -114,7 +114,7 @@ def analyser_manager():
|
|
114
114
|
|
115
115
|
args = parser.parse_args()
|
116
116
|
|
117
|
-
from
|
117
|
+
from . import eval, tsa, score
|
118
118
|
|
119
119
|
if args.type == 'red':
|
120
120
|
if args.command == 'get':
|
@@ -206,8 +206,7 @@ def analyser_manager():
|
|
206
206
|
|
207
207
|
elif args.type == 'prophet':
|
208
208
|
if args.command == 'ranking':
|
209
|
-
|
210
|
-
result = myprophet.ranking(refresh=args.refresh, expire_time_h=48)
|
209
|
+
result = score.Score.ranking(refresh=args.refresh, expire_time_h=48)
|
211
210
|
print(result)
|
212
211
|
mymongo.Logs.save('cli','INFO', 'run >> analyser prophet ranking')
|
213
212
|
|
analyser_hj3415/eval.py
CHANGED
@@ -4,7 +4,7 @@ from utils_hj3415 import utils, helpers
|
|
4
4
|
from typing import Tuple
|
5
5
|
from db_hj3415 import myredis, mymongo
|
6
6
|
import math
|
7
|
-
from
|
7
|
+
from .cli import AnalyserSettingsManager
|
8
8
|
from collections import OrderedDict
|
9
9
|
import logging
|
10
10
|
|
analyser_hj3415/score.py
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
from db_hj3415 import myredis
|
2
|
+
from utils_hj3415 import utils, helpers
|
3
|
+
import datetime
|
4
|
+
from collections import OrderedDict
|
5
|
+
from . import eval, tsa
|
6
|
+
|
7
|
+
import logging
|
8
|
+
|
9
|
+
score_logger = helpers.setup_logger('score_logger', logging.WARNING)
|
10
|
+
|
11
|
+
|
12
|
+
def is_within_last_three_days(date_to_check: datetime.datetime.date) -> bool:
|
13
|
+
today = datetime.datetime.now().date() # 현재 날짜 (시간은 무시)
|
14
|
+
# print('today - ', today)
|
15
|
+
three_days_ago = today - datetime.timedelta(days=3) # 3일 전 날짜
|
16
|
+
return three_days_ago <= date_to_check <= today
|
17
|
+
|
18
|
+
|
19
|
+
class Score:
|
20
|
+
def __init__(self, code):
|
21
|
+
self._code = code
|
22
|
+
self.c101 = myredis.C101(code)
|
23
|
+
self.name = self.c101.get_name()
|
24
|
+
self.c108 = myredis.C108(code)
|
25
|
+
self.dart = myredis.Dart(code)
|
26
|
+
self.red = eval.Red(code)
|
27
|
+
self.mil = eval.Mil(code)
|
28
|
+
self.lstm = tsa.MyLSTM(code)
|
29
|
+
self.prophet = tsa.MyProphet(code)
|
30
|
+
|
31
|
+
@property
|
32
|
+
def code(self) -> str:
|
33
|
+
return self._code
|
34
|
+
|
35
|
+
@code.setter
|
36
|
+
def code(self, code: str):
|
37
|
+
assert utils.is_6digit(code), f'Invalid value : {code}'
|
38
|
+
score_logger.info(f'change code : {self.code} -> {code}')
|
39
|
+
self._code = code
|
40
|
+
self.c101.code = code
|
41
|
+
self.name = self.c101.get_name()
|
42
|
+
self.c108.code = code
|
43
|
+
self.dart.code = code
|
44
|
+
self.red.code = code
|
45
|
+
self.mil.code = code
|
46
|
+
self.lstm.code = code
|
47
|
+
self.prophet.code = code
|
48
|
+
|
49
|
+
def get(self, refresh=False, expire_time_h=24) -> dict:
|
50
|
+
"""
|
51
|
+
한 종목의 각분야 평가를 모아서 딕셔너리 형태로 반환함.
|
52
|
+
redis_name = self.code + '_score'
|
53
|
+
|
54
|
+
Returns:
|
55
|
+
dict: A dictionary containing the following key-value pairs:
|
56
|
+
|
57
|
+
- 'code': str - 종목코드
|
58
|
+
- 'name': str - 종목명
|
59
|
+
- '시가총액': str - 시가총액
|
60
|
+
- 'is_update_c108': bool - 최근 3일 이내에 c108이 없데이트 되었는가
|
61
|
+
- 'is_update_dart': bool - 최근 3일 이내에 Dart가 없데이트 되었는가
|
62
|
+
- 'red_score': float - Red score
|
63
|
+
- '이익지표': float - Mil의 이익지표
|
64
|
+
- '주주수익률': float - Mil의 주주수익률
|
65
|
+
- 'is_lstm_up': Union[bool, None] - lstm 예측치가 상승인지 아닌지, returns None - 데이터가 없으면..
|
66
|
+
- 'prophet_score': int - prophet score
|
67
|
+
"""
|
68
|
+
print(f"{self.code}/{self.name}의 scoring을 시작합니다.")
|
69
|
+
redis_name = self.code + '_score'
|
70
|
+
print(
|
71
|
+
f"redisname: '{redis_name}' / refresh : {refresh} / expire_time : {expire_time_h}h")
|
72
|
+
|
73
|
+
def fetch_score() -> dict:
|
74
|
+
score_logger.info("시가총액 데이터 추출중..")
|
75
|
+
시가총액 = utils.format_large_number(int(self.c101.get_recent()['시가총액']))
|
76
|
+
|
77
|
+
score_logger.info("C108 최근 데이터 추출중..")
|
78
|
+
# c108이 최근에 업데이트 되었는지...
|
79
|
+
c108_recent_date = self.c108.get_recent_date()
|
80
|
+
# print('code - ', code, ' | c108 recent date - ', c108_recent_date.date())
|
81
|
+
if c108_recent_date is None:
|
82
|
+
is_update_c108 = False
|
83
|
+
else:
|
84
|
+
is_update_c108 = is_within_last_three_days(c108_recent_date.date())
|
85
|
+
|
86
|
+
score_logger.info("Dart 최근 데이터 추출중..")
|
87
|
+
# dart가 최근에 업데이트 되었는지...
|
88
|
+
dart_recent_date = self.dart.get_recent_date()
|
89
|
+
# print('code - ', code, ' | dart recent date - ', dart_recent_date.date())
|
90
|
+
if dart_recent_date is None:
|
91
|
+
is_update_dart = False
|
92
|
+
else:
|
93
|
+
is_update_dart = is_within_last_three_days(dart_recent_date.date())
|
94
|
+
|
95
|
+
score_logger.info("Red score 계산중..")
|
96
|
+
red_score = self.red.get(verbose=False).score
|
97
|
+
|
98
|
+
score_logger.info("Mil data 계산중..")
|
99
|
+
mil_data = self.mil.get(verbose=False)
|
100
|
+
|
101
|
+
score_logger.info("Lstm 최근 데이터 조회중..")
|
102
|
+
if myredis.Base.exists(f'{self.code}_mylstm_predictions'):
|
103
|
+
is_lstm_up = self.lstm.is_up()
|
104
|
+
else:
|
105
|
+
is_lstm_up = None
|
106
|
+
|
107
|
+
score_logger.info("\tProphet 최근 데이터 조회중..")
|
108
|
+
prophet_score = self.prophet.scoring()
|
109
|
+
|
110
|
+
return {
|
111
|
+
'code': self.code,
|
112
|
+
'name': self.name,
|
113
|
+
'시가총액': 시가총액,
|
114
|
+
'is_update_c108': is_update_c108,
|
115
|
+
'is_update_dart': is_update_dart,
|
116
|
+
'red_score': red_score,
|
117
|
+
'이익지표': mil_data.이익지표,
|
118
|
+
'주주수익률': mil_data.주주수익률,
|
119
|
+
'is_lstm_up': is_lstm_up,
|
120
|
+
'prophet_score': prophet_score,
|
121
|
+
}
|
122
|
+
data_dict = myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_score, timer=expire_time_h * 3600)
|
123
|
+
return data_dict
|
124
|
+
|
125
|
+
@classmethod
|
126
|
+
def ranking(self, refresh=False, expire_time_h=24, top='all') -> OrderedDict:
|
127
|
+
print("**** Start score_ranking... ****")
|
128
|
+
redis_name = 'score_ranking'
|
129
|
+
|
130
|
+
print(
|
131
|
+
f"redisname: '{redis_name}' / refresh : {refresh} / expire_time : {expire_time_h}h")
|
132
|
+
|
133
|
+
def fetch_ranking() -> dict:
|
134
|
+
data = {}
|
135
|
+
s = Score('005930')
|
136
|
+
for code in myredis.Corps.list_all_codes():
|
137
|
+
try:
|
138
|
+
s.code = code
|
139
|
+
except ValueError:
|
140
|
+
score_logger.error(f'score ranking error : {code}')
|
141
|
+
continue
|
142
|
+
score = s.get()
|
143
|
+
data[code] = score
|
144
|
+
return data
|
145
|
+
|
146
|
+
data_dict = myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_ranking, timer=expire_time_h * 3600)
|
147
|
+
|
148
|
+
# prophet_score를 기준으로 정렬
|
149
|
+
ranking = OrderedDict(sorted(data_dict.items(), key=lambda x: x[1]['prophet_score'], reverse=True))
|
150
|
+
|
151
|
+
if top == 'all':
|
152
|
+
return ranking
|
153
|
+
else:
|
154
|
+
if isinstance(top, int):
|
155
|
+
return OrderedDict(list(ranking.items())[:top])
|
156
|
+
else:
|
157
|
+
raise ValueError("top 인자는 'all' 이나 int형 이어야 합니다.")
|
analyser_hj3415/tsa.py
CHANGED
@@ -192,50 +192,37 @@ class MyProphet:
|
|
192
192
|
else:
|
193
193
|
Exception("to 인자가 맞지 않습니다.")
|
194
194
|
|
195
|
-
|
196
|
-
def ranking(cls, refresh = False, expire_time_h = 24, top='all') -> OrderedDict:
|
195
|
+
def scoring(self) -> int:
|
197
196
|
"""
|
198
|
-
|
199
|
-
:param refresh:
|
200
|
-
:return:
|
201
|
-
"""
|
202
|
-
print("**** Start myprophet_ranking... ****")
|
203
|
-
redis_name = 'myprophet_ranking'
|
197
|
+
prophet의 yhat_lower 예측치와 주가를 비교하여 주가가 낮으면 양의 점수를 높으면 음의 점수를 준다.
|
204
198
|
|
205
|
-
|
206
|
-
|
199
|
+
Returns:
|
200
|
+
int: The calculated score based on the deviation between the recent price
|
201
|
+
and the expected lower limit.
|
202
|
+
|
203
|
+
Parameters:
|
204
|
+
None
|
207
205
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
if recent_price < yhat_lower:
|
224
|
-
deviation = int(eval.Tools.cal_deviation(recent_price, yhat_lower))
|
225
|
-
data[code] = deviation
|
226
|
-
print(f"{i}.{p.code}/{p.name} date: {recent_date} 가격:{recent_price} 기대하한값:{yhat_lower} 편차:{deviation}")
|
227
|
-
return data
|
228
|
-
|
229
|
-
data_dict = myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_ranking, timer=expire_time_h * 3600)
|
230
|
-
|
231
|
-
ranking = OrderedDict(sorted(data_dict.items(), key=lambda item: item[1], reverse=True))
|
232
|
-
if top == 'all':
|
233
|
-
return ranking
|
206
|
+
Raises:
|
207
|
+
AttributeError: Raised if the necessary attributes like `df_real` or methods like `get_yhat`
|
208
|
+
are not correctly set or implemented.
|
209
|
+
KeyError: Raised if the expected keys (`'yhat_lower'` or `'y'`) are not found in the data involved.
|
210
|
+
ValueError: Raised if the format of data does not conform to expected structure for calculations.
|
211
|
+
"""
|
212
|
+
last_real_data = self.df_real.iloc[-1]
|
213
|
+
recent_price = last_real_data['y']
|
214
|
+
recent_date = datetime.strftime(last_real_data['ds'], '%Y-%m-%d')
|
215
|
+
yhat_dict = self.get_yhat()
|
216
|
+
tsa_logger.info(f'recent_price: {recent_price}, yhat_dict: {yhat_dict}')
|
217
|
+
yhat_lower = int(yhat_dict['yhat_lower'])
|
218
|
+
deviation = int(eval.Tools.cal_deviation(recent_price, yhat_lower))
|
219
|
+
if recent_price > yhat_lower:
|
220
|
+
score = -deviation
|
234
221
|
else:
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
222
|
+
score = deviation
|
223
|
+
tsa_logger.info(f"{self.code}/{self.name} date: {recent_date} 가격:{recent_price} 기대하한값:{yhat_lower} 편차:{deviation} score:{score}")
|
224
|
+
return score
|
225
|
+
|
239
226
|
|
240
227
|
@dataclass
|
241
228
|
class LSTMData:
|
@@ -691,6 +678,12 @@ class MyLSTM:
|
|
691
678
|
plt.show()"""
|
692
679
|
|
693
680
|
def is_up(self)-> bool:
|
681
|
+
"""
|
682
|
+
lstm 데이터가 증가하는 추세인지 확인후 참/거짓 반환
|
683
|
+
|
684
|
+
Returns:
|
685
|
+
bool: True if the data is strictly increasing, False otherwise.
|
686
|
+
"""
|
694
687
|
# 튜플의 [0]은 날짜 [1]은 값 배열
|
695
688
|
data = self.get_final_predictions(refresh=False, expire_time_h=24)[1]
|
696
689
|
# 데이터를 1D 배열로 변환
|
@@ -1,13 +1,14 @@
|
|
1
1
|
analyser_hj3415/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
analyser_hj3415/cli.py,sha256=
|
3
|
-
analyser_hj3415/eval.py,sha256=
|
4
|
-
analyser_hj3415/
|
2
|
+
analyser_hj3415/cli.py,sha256=eRaFtkioooe2Rgzq5J3Lxd2oX17OnIwDZPo2msutjM0,12497
|
3
|
+
analyser_hj3415/eval.py,sha256=9rWNTa3vbUnegOfpfVtWLXmt8cxU2zWZD5yEsFlfTzQ,38796
|
4
|
+
analyser_hj3415/score.py,sha256=ZEbkP_utCinaLCJeCw71ER3Ed1tCs0mH7FVS5TIcjGk,6310
|
5
|
+
analyser_hj3415/tsa.py,sha256=X62ypwSWRMAAU72IJoBdEeyU8rVaaMRqZ3XsslziBfM,28111
|
5
6
|
analyser_hj3415/workroom/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
7
|
analyser_hj3415/workroom/mysklearn.py,sha256=wJXKz5MqqTzADdG2mqRMMzc_G9RzwYjj5_j4gyOopxQ,2030
|
7
8
|
analyser_hj3415/workroom/mysklearn2.py,sha256=1lIy6EWEQHkOzDS-av8U0zQH6DuCLKWMI73dnJx5KRs,1495
|
8
9
|
analyser_hj3415/workroom/score.py,sha256=P6nHBJYmyhigGtT4qna4BmNtvt4B93b7SKyzdstJK24,17376
|
9
10
|
analyser_hj3415/workroom/trash.py,sha256=zF-W0piqkGr66UP6-iybo9EXh2gO0RP6R1FnIpsGkl8,12262
|
10
|
-
analyser_hj3415-2.10.
|
11
|
-
analyser_hj3415-2.10.
|
12
|
-
analyser_hj3415-2.10.
|
13
|
-
analyser_hj3415-2.10.
|
11
|
+
analyser_hj3415-2.10.2.dist-info/entry_points.txt,sha256=ZfjPnJuH8SzvhE9vftIPMBIofsc65IAWYOhqOC_L5ck,65
|
12
|
+
analyser_hj3415-2.10.2.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
|
13
|
+
analyser_hj3415-2.10.2.dist-info/METADATA,sha256=k-rEXIyDhOMG4k5niqEudEZ5g0pYOkvgGjx_7a3zkzY,6777
|
14
|
+
analyser_hj3415-2.10.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|