analyser_hj3415 2.10.0__py3-none-any.whl → 2.10.2__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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
|