analyser_hj3415 2.0.0__py2.py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,369 @@
1
+ import math
2
+ import numpy
3
+ import pprint
4
+ import copy
5
+ from typing import Tuple
6
+
7
+ from .db import mongo
8
+ from .eval import EXPECT_EARN, red as eval_red, mil as eval_mil, blue as eval_blue, growth as eval_growth
9
+ from utils_hj3415 import utils
10
+
11
+ import logging
12
+
13
+ logger = logging.getLogger(__name__)
14
+ formatter = logging.Formatter('%(levelname)s: [%(name)s] %(message)s')
15
+ ch = logging.StreamHandler()
16
+ ch.setFormatter(formatter)
17
+ logger.addHandler(ch)
18
+ logger.setLevel(logging.WARNING)
19
+
20
+
21
+ def red(client, code: str) -> Tuple[int, float]:
22
+ """red price와 최근 주가의 괴리율 파악
23
+
24
+ 양수면 주가가 고평가되어 있는 상태, 음수면 저평가
25
+ 음수가 현재 주가가 싸다는 의미
26
+
27
+ Returns:
28
+ tuple : 괴리율을 기반으로한 포인트, 주가와 red price 비교한 괴리율
29
+ """
30
+ c101 = mongo.C101(client, code)
31
+
32
+ logger.debug(f'c101 {c101.get_recent()}')
33
+
34
+ try:
35
+ recent_price = utils.to_int(c101.get_recent()['주가'])
36
+ except KeyError:
37
+ recent_price = float('nan')
38
+ red_price = eval_red(client, code)['red_price']
39
+
40
+ logger.debug(f"recent_price : {recent_price}\tred_price : {red_price}")
41
+
42
+ try:
43
+ # 괴리율 구하는 공식이 두가지임. 어떤걸 사용해도 동일함
44
+ f1 = round((recent_price / red_price - 1) * 100, 2)
45
+ f2 = round((recent_price - red_price) / red_price * 100, 2)
46
+ logger.debug(f'f1 : {f1}, f2 : {f2}')
47
+ 괴리율 = round((recent_price / red_price - 1) * 100, 2)
48
+ except ZeroDivisionError:
49
+ 괴리율 = float('nan')
50
+
51
+ logger.debug(f'괴리율 : {괴리율}')
52
+
53
+ if math.isnan(괴리율) or red_price <= 0:
54
+ return 0, float('nan')
55
+ else:
56
+ try:
57
+ p = round(100*math.log10(-괴리율+31.622777)-150)
58
+ return p if p > 0 else 0, 괴리율
59
+ except ValueError:
60
+ # 괴리율+31.622777이 0이하인 경우 ValueError 발생함.
61
+ return 0, 괴리율
62
+
63
+
64
+ def mil(client, code: str) -> Tuple[int, int, int, int]:
65
+ """
66
+ - 재무활동현금흐름이 마이너스라는 것은 배당급 지급했거나, 자사주 매입했거나, 부채를 상환한 상태임.
67
+ - 반대는 채권자로 자금을 조달했거나 신주를 발행했다는 의미
68
+ <주주수익률> - 재무활동현금흐름/시가총액 => 5%이상인가?
69
+
70
+ 투하자본수익률(ROIC)가 30%이상인가
71
+ ROE(자기자본이익률) 20%이상이면 아주 우수 다른 투자이익률과 비교해볼것 10%미만이면 별로...단, 부채비율을 확인해야함.
72
+
73
+ 이익지표 ...영업현금흐름이 순이익보다 많은가 - 결과값이 음수인가..
74
+
75
+ FCF는 영업현금흐름에서 자본적 지출(유·무형투자 비용)을 차감한 순수한 현금력이라 할 수 있다.
76
+ 말 그대로 자유롭게(Free) 사용할 수 있는 여윳돈을 뜻한다.
77
+ 잉여현금흐름이 플러스라면 미래의 투자나 채무상환에 쓸 재원이 늘어난 것이다.
78
+ CAPEX(Capital expenditures)는 미래의 이윤을 창출하기 위해 지출된 비용을 말한다.
79
+ 이는 기업이 고정자산을 구매하거나, 유효수명이 당회계년도를 초과하는 기존의 고정자산에 대한 투자에 돈이 사용될 때 발생한다.
80
+
81
+ 잉여현금흐름이 마이너스일때는 설비투자가 많은 시기라 주가가 약세이며 이후 설비투자 마무리되면서 주가가 상승할수 있다.
82
+ 주가는 잉여현금흐름이 증가할때 상승하는 경향이 있다.
83
+ fcf = 영업현금흐름 - capex
84
+
85
+ 가치지표평가
86
+ price to fcf 계산
87
+ https://www.investopedia.com/terms/p/pricetofreecashflow.asp
88
+ pcr보다 정확하게 주식의 가치를 평가할수 있음. 10배이하 추천
89
+
90
+ Returns:
91
+ tuple: 주주수익률, 이익지표, 투자수익률, PFCF포인트
92
+ """
93
+ mil_dict = eval_mil(client, code)
94
+
95
+ logger.debug(pprint.pformat(mil_dict, width=200))
96
+
97
+ # 주주수익률 평가
98
+ if math.isnan(mil_dict['주주수익률']):
99
+ p1 = 0
100
+ else:
101
+ 주주수익률평가 = math.ceil(mil_dict['주주수익률'] - (EXPECT_EARN * 100))
102
+ p1 = 0 if 0 > 주주수익률평가 else 주주수익률평가
103
+
104
+ # 이익지표 평가
105
+ p2 = 10 if mil_dict['이익지표'] < 0 else 0
106
+
107
+ # 투자수익률 평가
108
+ MAX3 = 20
109
+ p3 = 0
110
+ roic = mil_dict['투자수익률']['ROIC']
111
+ roe = mil_dict['투자수익률']['ROE']
112
+ if math.isnan(roic) or roic <= 0:
113
+ # roic 가 비정상이라 평가할 수 없는 경우
114
+ if 10 < roe <= 20:
115
+ p3 += round(MAX3 * 0.333)
116
+ elif 20 < roe:
117
+ p3 += round(MAX3 * 0.666)
118
+ elif 0 < roic:
119
+ # roic 로 평가할 수 있는 경우
120
+ if 0 < roic <= 15:
121
+ p3 += round(MAX3 * 0.333)
122
+ elif 15 < roic <= 30:
123
+ p3 += round(MAX3 * 0.666)
124
+ elif 30 < roic:
125
+ p3 += MAX3
126
+
127
+ # PFCF 평가
128
+ pfcf_dict = mil_dict['가치지표']['PFCF']
129
+ _, pfcf = mongo.Corps.latest_value(pfcf_dict)
130
+
131
+ logger.debug(f'recent pfcf {_}, {pfcf}')
132
+ try:
133
+ p = round(-40 * math.log10(pfcf) + 40)
134
+ except ValueError:
135
+ p = 0
136
+ p4 = 0 if 0 > p else p
137
+
138
+ return p1, p2, p3, p4
139
+
140
+
141
+ def blue(client, code: str) -> Tuple[int, int, int, int, int]:
142
+ """회사의 안정성을 보는 지표들
143
+
144
+ 0을 기준으로 상태가 좋치 않을 수록 마이너스 값을 가진다.
145
+
146
+ Returns:
147
+ tuple : 유동비율, 이자보상배율, 순부채비율, 순운전자본회전율, 재고자산회전율 평가 포인트
148
+
149
+ Notes:
150
+ <유동비율>
151
+ 100미만이면 주의하나 현금흐름창출력이 좋으면 괜찮을수 있다.
152
+ 만약 100%이하면 유동자산에 추정영업현금흐름을 더해서 다시계산해보아 기회를 준다.
153
+ <이자보상배율>
154
+ 이자보상배율 영업이익/이자비용으로 1이면 자금사정빡빡 5이상이면 양호
155
+ <순운전자금회전율>
156
+ 순운전자금 => 기업활동을 하기 위해 필요한 자금 (매출채권 + 재고자산 - 매입채무)
157
+ 순운전자본회전율은 매출액/순운전자본으로 일정비율이 유지되는것이 좋으며 너무 작아지면 순운전자본이 많아졌다는 의미로 재고나 외상이 쌓인다는 뜻
158
+ <재고자산회전율>
159
+ 재고자산회전율은 매출액/재고자산으로 회전율이 낮을수록 재고가 많다는 이야기이므로 불리 전년도등과 비교해서 큰차이 발생하면 알람.
160
+ 재고자산회전율이 작아지면 재고가 쌓인다는뜻
161
+ <순부채비율>
162
+ 부채비율은 업종마다 달라 일괄비교 어려우나 순부채 비율이 20%이하인것이 좋고 꾸준히 늘어나지 않는것이 좋다.
163
+ 순부채 비율이 30%이상이면 좋치 않다.
164
+ """
165
+ def _calc_point_with_std(data: dict) -> int:
166
+ """표준편차를 통해 점수를 계산하는 내부 함수
167
+
168
+ Args:
169
+ data(dict): 재무재표상의 연/분기 딕셔너리 데이터
170
+ """
171
+ NEG_MAX = -5
172
+ d_values = [i for i in data.values() if not math.isnan(i)]
173
+ logger.debug(f'd_values : {d_values}')
174
+ if len(d_values) == 0:
175
+ p = NEG_MAX
176
+ else:
177
+ std = numpy.std(d_values)
178
+ # 표준편차가 작을수록 데이터의 변환가 적다는 의미임.
179
+ logger.debug(f'표준편차 : {std}')
180
+ p = NEG_MAX if float(std) > -NEG_MAX else -math.floor(float(std))
181
+
182
+ return int(p)
183
+
184
+ c104y = mongo.C104(client, code, 'c104y')
185
+
186
+ blue_dict = eval_blue(client, code)
187
+
188
+ logger.debug(pprint.pformat(blue_dict, width=200))
189
+
190
+ def 유동비율평가(유동비율: float) -> int:
191
+ # 채점은 0을 기준으로 마이너스 해간다. 즉 0이 제일 좋은 상태임.
192
+ # 유동비율 평가 - 100 이하는 문제 있음
193
+ NEG_MAX = -10
194
+ if math.isnan(유동비율) or 유동비율 <= 0:
195
+ p = NEG_MAX
196
+ elif math.isinf(유동비율):
197
+ p = 0
198
+ else:
199
+ p = 0 if 100 < round(유동비율) else NEG_MAX + round(유동비율/10)
200
+ logger.debug(f'유동비율평가 point : {p}')
201
+ return int(p)
202
+
203
+ p1 = 유동비율평가(blue_dict['유동비율'])
204
+
205
+ def 이자보상배율평가(이자보상배율: tuple) -> int:
206
+ # 이자보상배율평가 : 1이면 자금사정 빡빡 5이상이면 양호
207
+ NEG_MAX = -5
208
+ 최근이자보상배율q, dict_y = 이자보상배율
209
+
210
+ if math.isnan(최근이자보상배율q) or 최근이자보상배율q <= 1:
211
+ # 최근 분기의 값이 비정상이면 최근 년도를 한번 더 비교해 보지만 좀더 엄격하게 전년대비도 비교한다.
212
+
213
+ _, 최근이자보상배율y = mongo.Corps.latest_value(dict_y)
214
+ c104y.page = 'c104y'
215
+ _, 전년대비 = c104y.find_증감율(title='이자보상배율').popitem()
216
+
217
+ if math.isnan(최근이자보상배율y) or 최근이자보상배율y <= 1 or math.isnan(전년대비) or 전년대비 < 0:
218
+ p = NEG_MAX
219
+ else:
220
+ p = 0 if 5 < 최근이자보상배율y else NEG_MAX + round(최근이자보상배율y)
221
+ else:
222
+ p = 0 if 5 < 최근이자보상배율q else NEG_MAX + round(최근이자보상배율q)
223
+ logger.debug(f'이자보상배율평가 point : {p}')
224
+ return int(p)
225
+
226
+ p2 = 이자보상배율평가(blue_dict['이자보상배율'])
227
+
228
+ def 순부채비율평가(순부채비율: tuple) -> int:
229
+ # 부채비율은 업종마다 달라 일괄비교 어려우나 순부채 비율이 20%이하인것이 좋고 꾸준히 늘어나지 않는것이 좋다.
230
+ # 순부채 비율이 30%이상이면 좋치 않다.
231
+ NEG_MAX = -5
232
+ 최근순부채비율q, dict_y = 순부채비율
233
+
234
+ if math.isnan(최근순부채비율q) or 최근순부채비율q >= 80:
235
+ # 최근 분기의 값이 비정상이면 최근 년도를 한번 더 비교해 보지만 좀더 엄격하게 전년대비도 비교한다.
236
+ _, 최근순부채비율y = mongo.Corps.latest_value(dict_y)
237
+ c104y.page = 'c104y'
238
+ _, 전년대비 = c104y.find_증감율(title='순부채비율').popitem()
239
+ if math.isnan(최근순부채비율y) or 최근순부채비율y >= 80 or math.isnan(전년대비) or 전년대비 > 0:
240
+ p = NEG_MAX
241
+ else:
242
+ p = 0 if 최근순부채비율y < 30 else round((30 - 최근순부채비율y) / 10)
243
+ else:
244
+ p = 0 if 최근순부채비율q < 30 else round((30 - 최근순부채비율q) / 10)
245
+ logger.debug(f'순부채비율평가 point : {p}')
246
+ return int(p)
247
+
248
+ p3 = 순부채비율평가(blue_dict['순부채비율'])
249
+
250
+ def 순운전자본회전율평가(순운전자본회전율: tuple) -> int:
251
+ # 순운전자본회전율은 매출액/순운전자본으로 일정비율이 유지되는것이 좋으며 너무 작아지면 순운전자본이 많아졌다는 의미로 재고나 외상이 쌓인다는 뜻
252
+ _, dict_y = 순운전자본회전율
253
+ p = _calc_point_with_std(data=dict_y)
254
+ logger.debug(f'순운전자본회전율평가 point : {p}')
255
+ return p
256
+
257
+ p4 = 순운전자본회전율평가(blue_dict['순운전자본회전율'])
258
+
259
+ def 재고자산회전율평가(재고자산회전율: tuple) -> int:
260
+ # 재고자산회전율은 매출액/재고자산으로 회전율이 낮을수록 재고가 많다는 이야기이므로 불리 전년도등과 비교해서 큰차이 발생하면 알람.
261
+ # 재고자산회전율이 작아지면 재고가 쌓인다는뜻
262
+ _, dict_y = 재고자산회전율
263
+ p = _calc_point_with_std(data=dict_y)
264
+ logger.debug(f'재고자산회전율평가 point : {p}')
265
+ return p
266
+
267
+ p5 = 재고자산회전율평가(blue_dict['재고자산회전율'])
268
+
269
+ return p1, p2, p3, p4, p5
270
+
271
+
272
+ def growth(client, code: str) -> Tuple[int, int]:
273
+ """회사의 성장성을 보는 지표들
274
+
275
+ <매출액>
276
+ 매출액은 어떤경우에도 성장하는 기업이 좋다.매출이 20%씩 늘어나는 종목은 유망한 종목
277
+ <영업이익률>
278
+ 영업이익률은 기업의 경쟁력척도로 경쟁사에 비해 높으면 경제적해자를 갖춘셈
279
+
280
+ Returns:
281
+ tuple : 매출액증가율, 영업이익률 평가 포인트
282
+ """
283
+ growth_dict = eval_growth(client, code)
284
+
285
+ logger.debug(pprint.pformat(growth_dict, width=200))
286
+
287
+ def 매출액증가율평가(매출액증가율: tuple) -> int:
288
+ # 매출액은 어떤경우에도 성장하는 기업이 좋다.매출이 20%씩 늘어나는 종목은 유망한 종목
289
+ MAX = 20
290
+ 최근매출액증가율q, dict_y = 매출액증가율
291
+ _, 최근매출액증가율y = mongo.Corps.latest_value(dict_y)
292
+
293
+ # 최근 자료가 성장하는 중인지 판단
294
+ if math.isnan(최근매출액증가율q):
295
+ 최근매출액증가율q = 최근매출액증가율y
296
+
297
+ sp1 = 0
298
+ if math.isnan(최근매출액증가율y):
299
+ pass
300
+ elif 0 < 최근매출액증가율y and 0 < 최근매출액증가율q:
301
+ # 최근에 마이너스 성장이 아닌경우 MAX/10점 보너스
302
+ sp1 += MAX / 10
303
+ if 최근매출액증가율y < 최근매출액증가율q:
304
+ # 최근에 이전보다 더 성장중이면 MAX/10점 보너스
305
+ sp1 += MAX / 10
306
+ # 나머지는 성장률 기반 점수 배정
307
+ sp1 += MAX / 2 if 최근매출액증가율q > MAX else 최근매출액증가율q / 2
308
+ elif 최근매출액증가율y <= 0 < 최근매출액증가율q:
309
+ # 직전에 마이너스였다가 최근에 회복된 경우 MAX/10점 보너스
310
+ sp1 += MAX / 10
311
+ # 나머지는 성장률 기반 점수 배정
312
+ sp1 += MAX / 2 if 최근매출액증가율q > MAX else 최근매출액증가율q / 2
313
+ else:
314
+ # 최근 자료가 마이너스인 경우 마이너스만큼 점수를 차감한다.
315
+ sp1 += -(MAX / 2) if 최근매출액증가율q < -MAX else 최근매출액증가율q / 2
316
+
317
+ # 평균매출액증가율 구하기
318
+ d_values = [i for i in dict_y.values() if not math.isnan(i)]
319
+ logger.debug(f'평균매출액증가율 d_values : {d_values}')
320
+
321
+ if len(d_values) == 0:
322
+ 평균매출액증가율 = float('nan')
323
+ else:
324
+ 평균매출액증가율 = float(numpy.mean(d_values))
325
+ logger.debug(f'평균 : {평균매출액증가율}')
326
+
327
+ sp2 = 0
328
+ if math.isnan(평균매출액증가율):
329
+ sp2 += -(MAX/2)
330
+ elif 평균매출액증가율 <= 0:
331
+ # 평균매출액증가율이 마이너스인 경우 마이너스만큼 점수를 차감한다.
332
+ sp2 += -(MAX / 2) if 평균매출액증가율 < -MAX else 평균매출액증가율 / 2
333
+ else:
334
+ sp2 = MAX / 2 if 평균매출액증가율 > MAX else 평균매출액증가율 / 2
335
+
336
+ logger.debug(f'매출액증가율평가 point : {sp1 + sp2}')
337
+
338
+ return int(sp1 + sp2)
339
+
340
+ p1 = 매출액증가율평가(growth_dict['매출액증가율'])
341
+
342
+ def 영업이익률평가(영업이익률: dict) -> int:
343
+ # 영업이익률은 기업의 경쟁력척도로 경쟁사에 비해 높으면 경제적해자를 갖춘셈
344
+ 영업이익률 = copy.deepcopy(영업이익률)
345
+ name = mongo.Corps.get_name(client, code)
346
+
347
+ p = 0
348
+ try:
349
+ myprofit = utils.to_float(영업이익률.pop(name))
350
+ except KeyError:
351
+ logger.warning(f'{name} 영업이익률 does not exist.')
352
+ return 0
353
+ logger.debug(f'종목영업이익률 : {myprofit}')
354
+
355
+ for profit in 영업이익률.values():
356
+ profit = utils.to_float(profit)
357
+ if math.isnan(profit):
358
+ continue
359
+ elif myprofit > profit:
360
+ p += 1
361
+ else:
362
+ continue
363
+
364
+ logger.debug(f'영업이익률평가 point : {p}')
365
+ return p
366
+
367
+ p2 = 영업이익률평가(growth_dict['영업이익률'])
368
+
369
+ return p1, p2
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 Hyungjin Kim
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,232 @@
1
+ Metadata-Version: 2.1
2
+ Name: analyser_hj3415
3
+ Version: 2.0.0
4
+ Summary: Stock analyser and database processing programs
5
+ Author-email: Hyungjin Kim <hj3415@gmail.com>
6
+ Description-Content-Type: text/markdown
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Requires-Dist: pandas>=2.2.2
9
+ Requires-Dist: pymongo>=4.8.0
10
+ Requires-Dist: sqlalchemy>=2.0.31
11
+ Requires-Dist: utils-hj3415>=2.0.1
12
+ Requires-Dist: scraper2-hj3415>=0.4.0
13
+ Project-URL: Home, https://www.hyungjin.kr
14
+
15
+ ### analyser-hj3415
16
+
17
+ #### Introduction
18
+ analyser_hj3415 manage the database.
19
+
20
+ ---
21
+ #### Requirements
22
+
23
+ scrapy>=2.11.2
24
+ pandas>=2.2.2
25
+ sqlalchemy>=2.0.31
26
+ selenium>=4.22.0
27
+ utils-hj3415>=2.0.1
28
+ analyser_hj3415>=0.3.5
29
+
30
+ ---
31
+ #### API
32
+
33
+ ---
34
+ #### Install
35
+
36
+
37
+ ---
38
+ #### Composition
39
+ analyser_hj3415 모듈은 세가지 파트로 구성되어 있습니다.
40
+
41
+ 1. setting 모듈
42
+ setting 모듈은 데이터베이스를 활성화하고 주소를 설정하는 역할을 합니다.
43
+ 데이터베이스의 주소와 활성화 여부를 파일에 저장합니다.
44
+
45
+ ```python
46
+ from analyser_hj3415 import setting
47
+
48
+ # 현재 데이터 베이스 상태를 DbSetting 클래스 형식으로 반환한다.
49
+ db_setting = setting.load_df()
50
+
51
+ # 현재 데이터베이스 상태 출력
52
+ print(db_setting)
53
+
54
+ # 몽고db 주소 변경 (2가지 방식)
55
+ setting.chg_mongo_addr('mongodb://192.168.0.173:27017')
56
+ db_setting.mongo_addr = 'mongodb://192.168.0.173:27017'
57
+
58
+ # sqlite3 주소 변경 (2가지 방식)
59
+ setting.chg_sqlite3_path('/home/hj3415/Stock/_db')
60
+ db_setting.sqlite3_path = '/home/hj3415/Stock/_db'
61
+
62
+ # 데이터베이스를 기본값으로 설정합니다.
63
+ # DEF_MONGO_ADDR = 'mongodb://localhost:27017'
64
+ # DEF_WIN_SQLITE3_PATH = 'C:\\_db'
65
+ # DEF_LINUX_SQLITE3_PATH = '/home/hj3415/Stock/_db'
66
+ setting.set_default()
67
+
68
+ # 각 데이터베이스 사용 설정
69
+ setting.turn_on_mongo()
70
+ setting.turn_off_mongo()
71
+ setting.turn_off_sqlite3()
72
+ setting.turn_on_sqlite3()
73
+ ```
74
+
75
+ 2. mongo 모듈
76
+ 몽고db를 데이터베이스로 사용할 경우를 위한 함수들의 모듈입니다.
77
+ 현재는 몽고db를 비활성화 할 경우 올바로 작동하지 않기 때문에 디폴트 데이터베이스 입니다.
78
+
79
+ 1) Base 클래스
80
+
81
+ 모든 데이터베이스 클래스의 기반 클래스로 실제 직접 사용하지 않음.
82
+
83
+ ```python
84
+ from analyser_hj3415.mongo import Base
85
+ base = Base(db='mi', col='kospi')
86
+
87
+ # db 주소를 변경함. 단 파일에 저장되는 것이 아니라 클래스 내부에서 일시적으로 설정하는 것임
88
+ base.chg_addr('mongodb://192.168.0.173:27017')
89
+
90
+ # 현재 설정된 db 주소, db 명, 컬렉션을 반환함.
91
+ base.get_status()
92
+ # ('mongodb://192.168.0.173:27017', 'mi', 'kospi')
93
+
94
+ # 데이터 베이스 관리 함수
95
+ base.get_all_db()
96
+ ```
97
+
98
+ 2 - 1) Corps 클래스
99
+
100
+ DB 내에서 종목에 관련된 기반클래스로 db명은 6자리 숫자 코드명임.
101
+
102
+ ```python
103
+ from analyser_hj3415.mongo import Corps
104
+
105
+ corps = Corps(code='005930', page='c101')
106
+
107
+ # 코드를 변경함. 6자리 숫자인지 확인 후 설정함.
108
+ corps.chg_code('005490')
109
+
110
+ # 페이지를 변경함. 페이지명의 유효성 확인 후 설정함.
111
+ # ('c101', 'c104y', 'c104q', 'c106', 'c108', 'c103손익계산서q', 'c103재무상태표q', 'c103현금흐름표q', 'c103손익계산서y', 'c103재무상태표y', 'c103현금흐름표y', 'dart')
112
+ corps.chg_page(page='c108')
113
+
114
+ # 데이터 베이스 관리 함수
115
+ corps.get_all_codes()
116
+ corps.del_all_codes()
117
+ corps.drop_corp(code='005930')
118
+ corps.get_all_pages()
119
+ corps.drop_all_pages(code='005930')
120
+ corps.drop_page(code='005930', page='c101')
121
+ corps.get_all_item()
122
+ ```
123
+
124
+ 2 - 2) MI 클래스
125
+
126
+ DB 내에서 Market index 관련 클래스
127
+
128
+ ```python
129
+ from analyser_hj3415.mongo import MI
130
+ mi = MI(index='kospi')
131
+
132
+ # 인덱스를 변경함. 인덱스명의 유효성 확인 후 설정
133
+ # ('aud', 'chf', 'gbond3y', 'gold', 'silver', 'kosdaq', 'kospi', 'sp500', 'usdkrw', 'wti', 'avgper', 'yieldgap', 'usdidx')
134
+ mi.chg_index(index='gold')
135
+
136
+ # 저장된 가장 최근 값 반환
137
+ mi.get_recent()
138
+
139
+ # 데이터를 저장함.
140
+ mi.save(mi_dict={'date': '2021.07.21', 'value': '1154.50'})
141
+
142
+ # 데이터 베이스 관리 함수
143
+ mi.get_all_indexes()
144
+ mi.drop_all_indexes()
145
+ mi.drop_index(index='silver')
146
+ mi.get_all_item()
147
+ ```
148
+
149
+ 2 - 3) DartByDate 클래스
150
+
151
+ dart_hj3415의 dart 모듈에서 dart 데이터프레임을 추출하면 각 날짜별 컬렉션으로 저장하는 클래스
152
+
153
+ ```python
154
+ from dart_hj3415 import dart
155
+ from analyser_hj3415.mongo import DartByDate
156
+
157
+ date = '20210812'
158
+ dart_db = DartByDate(date=date)
159
+
160
+ # 오늘 날짜의 dart 데이터프레임을 추출하여 데이터베이스에 저장
161
+ df = dart.get_df(edate=date)
162
+ dart_db.save(df)
163
+
164
+ # 공시 데이터를 데이터프레임으로 반환한다.
165
+ dart_db.get_data()
166
+ dart_db.get_data(title='임원ㆍ주요주주특정증권등소유상황보고서')
167
+ ```
168
+
169
+ 2 - 4) EvalByDate 클래스
170
+
171
+ eval_hj3415의 eval 모듈에서 eval 데이터프레임을 추출하여 저장하거나 불러올때 사용.
172
+ (실제로 eval_hj3415.eval.make_today_eval_df()에서 오늘자 데이터프레임을 항상 저장한다)
173
+
174
+ ```python
175
+ import pandas as pd
176
+ import datetime
177
+ from analyser_hj3415.mongo import EvalByDate
178
+
179
+ today_str = datetime.datetime.today().strftime('%Y%m%d')
180
+ eval_db = EvalByDate(date=today_str)
181
+
182
+ # 오늘 날짜의 dart 데이터프레임을 추출하여 데이터베이스에 저장
183
+ eval_db.save(pd.DataFrame())
184
+
185
+ # 공시 데이터를 데이터프레임으로 반환한다.
186
+ eval_db.get_data()
187
+ ```
188
+
189
+ 2 - 5) Noti 클래스
190
+
191
+ dart_hj3415의 analysis 모듈에서 공시를 분석하여 의미있는 공시를 노티하고 노티한 기록을 저장하는 클래스
192
+
193
+ ```python
194
+ from analyser_hj3415.mongo import Noti
195
+ noti_db = Noti()
196
+
197
+ # 저장이 필요한 노티 데이터를 딕셔너리로 전달하여 데이터베이스에 저장
198
+ data = {'code': '005930',
199
+ 'rcept_no': '20210514000624',
200
+ 'rcept_dt': '20210514',
201
+ 'report_nm': '임원ㆍ주요주주특정증권등소유상황보고서',
202
+ 'point': 2,
203
+ 'text': '등기임원이 1.0억 이상 구매하지 않음.'}
204
+ noti_db.save(noti_dict=data)
205
+
206
+ # 오래된 노티 데이터를 정리하는 함수
207
+ noti_db.cleaning_data(days_ago=15)
208
+ ```
209
+
210
+ 3) Corps
211
+
212
+ C101 페이지 관리 클래스
213
+
214
+ ```python
215
+ from analyser_hj3415.mongo import C101
216
+ c101 = C101(code='005930')
217
+ ...
218
+ ```
219
+
220
+ 구현 클래스는 C101, C108, C106, C103, C104
221
+
222
+ 3. sqlite 모듈
223
+ sqlite3를 데이테베이스로 사용할 경우를 위한 함수들의 모듈입니다.
224
+ 현재 sqlite3는 사용하지 않기 때문에 작동하지 않습니다.
225
+
226
+ ```python
227
+ from analyser_hj3415 import sqlite
228
+
229
+ ```
230
+ ---
231
+
232
+
@@ -0,0 +1,18 @@
1
+ analyser_hj3415/.DS_Store,sha256=ru32hJTZXnU4wX_07F4wd6nuiLkH9bA3gTALaIXBamM,6148
2
+ analyser_hj3415/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ analyser_hj3415/analyser/.DS_Store,sha256=2TtZ8BUuHZ-ELhwey6b6MNgQgqCc4aieYOQOsBQgzhM,6148
4
+ analyser_hj3415/analyser/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ analyser_hj3415/analyser/cli.py,sha256=qzRnpDRJvQnQevSKHBpKbTsBjmSWllZjzTV4z_alg2A,4891
6
+ analyser_hj3415/analyser/eval.py,sha256=v86gNZ722GYHyQKvm1NxHLC8r9mzSx1JgKkznSCyc6Q,16951
7
+ analyser_hj3415/analyser/report.py,sha256=Sr14o6edWDwFZeR_cjE7zWw3K02Rv1nPKkgCUP-3Ah8,10917
8
+ analyser_hj3415/analyser/score.py,sha256=hQCV_i_fsXKOYVKDZ4QIpf1SwFh8iHDrQAVFuM9x4os,16693
9
+ analyser_hj3415/analyser/db/.DS_Store,sha256=1lFlJ5EFymdzGAUAaI30vcaaLHt3F1LwpG7xILf9jsM,6148
10
+ analyser_hj3415/analyser/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ analyser_hj3415/analyser/db/chk_db.py,sha256=NguwgG3TP9Lassh2eJ101AIHGVoWZCxUcESdPt19swE,10115
12
+ analyser_hj3415/analyser/db/evaltools.py,sha256=aSOnMG2uKp5kTv-UPIgnpfeeePNhScIXZVu50mioAnY,11867
13
+ analyser_hj3415/analyser/db/mongo.py,sha256=wc8GPwXhsibKWHERflVrOUCSJNmRlKKe0MzWZ6KQsfs,35309
14
+ analyser_hj3415-2.0.0.dist-info/entry_points.txt,sha256=dHaCM3eOAGONmxTWuRVqo9Zyq2C7J5TZmpH0PD6FW5k,103
15
+ analyser_hj3415-2.0.0.dist-info/LICENSE,sha256=QVKTp0dTnB5xG8RLgG17LwSWCKNEzYoVVM6KjoCPKc0,1079
16
+ analyser_hj3415-2.0.0.dist-info/WHEEL,sha256=Sgu64hAMa6g5FdzHxXv9Xdse9yxpGGMeagVtPMWpJQY,99
17
+ analyser_hj3415-2.0.0.dist-info/METADATA,sha256=_Uuz79IyD9q3T0INP85Aq5pJSGzTBLJpPseMTn-mieQ,6534
18
+ analyser_hj3415-2.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: flit 3.9.0
3
+ Root-Is-Purelib: true
4
+ Tag: py2-none-any
5
+ Tag: py3-none-any
@@ -0,0 +1,4 @@
1
+ [console_scripts]
2
+ dbmanager=analyser_hj3415.cli:dbmanager
3
+ evalmanager=analyser_hj3415.cli:evalmanager
4
+