analyser_hj3415 2.0.2__py2.py3-none-any.whl → 2.2.0__py2.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.
@@ -0,0 +1,210 @@
1
+
2
+
3
+ def _make_df_part(db_addr, codes: list, q):
4
+ def make_record(my_client, my_code: str) -> dict:
5
+ # 장고에서 사용할 eval 테이블을 만들기 위해 각각의 레코드를 구성하는 함수
6
+ c101 = mongo.C101(my_client, my_code).get_recent()
7
+
8
+ red_dict = red(my_client, my_code)
9
+ mil_dict = mil(my_client, my_code)
10
+ growth_dict = growth(my_client, my_code)
11
+
12
+ mil_date = mil_dict['date']
13
+ red_date = red_dict['date']
14
+ growth_date = growth_dict['date']
15
+
16
+ return {
17
+ 'code': c101['코드'],
18
+ '종목명': c101['종목명'],
19
+ '주가': utils.to_int(c101['주가']),
20
+ 'PER': utils.to_float(c101['PER']),
21
+ 'PBR': utils.to_float(c101['PBR']),
22
+ '시가총액': utils.to_float(c101['시가총액']),
23
+ 'RED': utils.to_int(red_dict['red_price']),
24
+ '주주수익률': utils.to_float(mil_dict['주주수익률']),
25
+ '이익지표': utils.to_float(mil_dict['이익지표']),
26
+ 'ROIC': utils.to_float(mil_dict['투자수익률']['ROIC']),
27
+ 'ROE': utils.to_float(mil_dict['투자수익률']['ROE']),
28
+ 'PFCF': utils.to_float(mongo.Corps.latest_value(mil_dict['가치지표']['PFCF'])[1]),
29
+ 'PCR': utils.to_float(mongo.Corps.latest_value(mil_dict['가치지표']['PCR'])[1]),
30
+ '매출액증가율': utils.to_float(growth_dict['매출액증가율'][0]),
31
+ 'date': list(set(mil_date + red_date + growth_date))
32
+ }
33
+ # 각 코어별로 디비 클라이언트를 만들어야만 한다. 안그러면 에러발생
34
+ client = mongo.connect_mongo(db_addr)
35
+ t = len(codes)
36
+ d = []
37
+ for i, code in enumerate(codes):
38
+ print(f'{i+1}/{t} {code}')
39
+ try:
40
+ d.append(make_record(client, code))
41
+ except:
42
+ logger.error(f'error on {code}')
43
+ continue
44
+ df = pd.DataFrame(d)
45
+ logger.info(df)
46
+ q.put(df)
47
+
48
+
49
+ def make_today_eval_df(client, refresh: bool = False) -> pd.DataFrame:
50
+ """ 멀티프로세싱을 사용하여 전체 종목의 eval 을 데이터프레임으로 만들어 반환
51
+
52
+ 기본값으로 refresh 는 False 로 설정되어 당일자의 저장된 데이터프레임이 있으면 새로 생성하지 않고 mongo DB를 이용한다.
53
+ """
54
+ today_str = datetime.datetime.today().strftime('%Y%m%d')
55
+ df = mongo.EvalByDate(client, today_str).load_df()
56
+ if refresh or len(df) == 0:
57
+ codes_in_db = mongo.Corps.get_all_codes(client)
58
+
59
+ print('*' * 25, f"Eval all using multiprocess(refresh={refresh})", '*' * 25)
60
+ print(f'Total {len(codes_in_db)} items..')
61
+ logger.debug(codes_in_db)
62
+ n, divided_list = utils.code_divider_by_cpu_core(codes_in_db)
63
+
64
+ addr = mongo.extract_addr_from_client(client)
65
+
66
+ start_time = time.time()
67
+ q = Queue()
68
+ ths = []
69
+ for i in range(n):
70
+ ths.append(Process(target=_make_df_part, args=(addr, divided_list[i], q)))
71
+ for i in range(n):
72
+ ths[i].start()
73
+
74
+ df_list = []
75
+ for i in range(n):
76
+ df_list.append(q.get())
77
+ # 부분데이터프레임들을 하나로 합침
78
+ final_df = pd.concat(df_list, ignore_index=True)
79
+
80
+ for i in range(n):
81
+ ths[i].join()
82
+
83
+ print(f'Total spent time : {round(time.time() - start_time, 2)} sec.')
84
+ logger.debug(final_df)
85
+ print(f"Save to mongo db(db: eval col: {today_str})")
86
+ mongo.EvalByDate(client, today_str).save_df(final_df)
87
+ else:
88
+ print(f"Use saved dataframe from mongo db..")
89
+ final_df = df
90
+ return final_df
91
+
92
+
93
+ def yield_valid_spac(client) -> tuple:
94
+ """
95
+ 전체 스팩주의 현재가를 평가하여 2000원 이하인 경우 yield한다.
96
+
97
+ Returns:
98
+ tuple: (code, name, price)
99
+ """
100
+ codes = mongo.Corps.get_all_codes(client)
101
+ logger.debug(f'len(codes) : {len(codes)}')
102
+ print('<<< Finding valuable SPAC >>>')
103
+ for i, code in enumerate(codes):
104
+ name = mongo.Corps.get_name(client, code)
105
+ logger.debug(f'code : {code} name : {name}')
106
+ if '스팩' in str(name):
107
+ logger.debug(f'>>> spac - code : {code} name : {name}')
108
+ price, _, _ = utils.get_price_now(code=code)
109
+ if price <= 2000:
110
+ logger.warning(f'현재가:{price}')
111
+ print(f"code: {code} name: {name}, price: {price}")
112
+ yield code, name, price
113
+
114
+
115
+
116
+ class GetDFTest(unittest.TestCase):
117
+ def test_make_df_part(self):
118
+ codes = ['025320', '000040', '060280', '003240']
119
+ from multiprocessing import Queue
120
+ q = Queue()
121
+ eval._make_df_part(addr, codes, q)
122
+
123
+ def test_get_df(self):
124
+ print(eval.make_today_eval_df(client, refresh=True))
125
+ print(eval.make_today_eval_df(client, refresh=False))
126
+
127
+
128
+ class SpacTest(unittest.TestCase):
129
+ def test_valid_spac(self):
130
+ for code, name, price in eval.yield_valid_spac(client):
131
+ print(code, name, price)
132
+
133
+
134
+
135
+
136
+ def mil(code: str) -> Tuple[int, int, int, int]:
137
+ """
138
+ - 재무활동현금흐름이 마이너스라는 것은 배당급 지급했거나, 자사주 매입했거나, 부채를 상환한 상태임.
139
+ - 반대는 채권자로 자금을 조달했거나 신주를 발행했다는 의미
140
+ <주주수익률> - 재무활동현금흐름/시가총액 => 5%이상인가?
141
+
142
+ 투하자본수익률(ROIC)가 30%이상인가
143
+ ROE(자기자본이익률) 20%이상이면 아주 우수 다른 투자이익률과 비교해볼것 10%미만이면 별로...단, 부채비율을 확인해야함.
144
+
145
+ 이익지표 ...영업현금흐름이 순이익보다 많은가 - 결과값이 음수인가..
146
+
147
+ FCF는 영업현금흐름에서 자본적 지출(유·무형투자 비용)을 차감한 순수한 현금력이라 할 수 있다.
148
+ 말 그대로 자유롭게(Free) 사용할 수 있는 여윳돈을 뜻한다.
149
+ 잉여현금흐름이 플러스라면 미래의 투자나 채무상환에 쓸 재원이 늘어난 것이다.
150
+ CAPEX(Capital expenditures)는 미래의 이윤을 창출하기 위해 지출된 비용을 말한다.
151
+ 이는 기업이 고정자산을 구매하거나, 유효수명이 당회계년도를 초과하는 기존의 고정자산에 대한 투자에 돈이 사용될 때 발생한다.
152
+
153
+ 잉여현금흐름이 마이너스일때는 설비투자가 많은 시기라 주가가 약세이며 이후 설비투자 마무리되면서 주가가 상승할수 있다.
154
+ 주가는 잉여현금흐름이 증가할때 상승하는 경향이 있다.
155
+ fcf = 영업현금흐름 - capex
156
+
157
+ 가치지표평가
158
+ price to fcf 계산
159
+ https://www.investopedia.com/terms/p/pricetofreecashflow.asp
160
+ pcr보다 정확하게 주식의 가치를 평가할수 있음. 10배이하 추천
161
+
162
+ Returns:
163
+ tuple: 주주수익률, 이익지표, 투자수익률, PFCF포인트
164
+ """
165
+ mil_dict = eval.mil(code)
166
+
167
+ print(pprint.pformat(mil_dict, width=200))
168
+
169
+ # 주주수익률 평가
170
+ if math.isnan(mil_dict['주주수익률']):
171
+ score1 = 0
172
+ else:
173
+ 주주수익률평가 = math.ceil(mil_dict['주주수익률'] - (eval.EXPECT_EARN * 100))
174
+ score1 = 0 if 0 > 주주수익률평가 else 주주수익률평가
175
+
176
+ # 이익지표 평가
177
+ score2 = 10 if mil_dict['이익지표'] < 0 else 0
178
+
179
+ # 투자수익률 평가
180
+ MAX3 = 20
181
+ score3 = 0
182
+ roic = mil_dict['투자수익률']['ROIC']
183
+ roe = mil_dict['투자수익률']['ROE']
184
+ if math.isnan(roic) or roic <= 0:
185
+ # roic 가 비정상이라 평가할 수 없는 경우
186
+ if 10 < roe <= 20:
187
+ score3 += round(MAX3 * 0.333)
188
+ elif 20 < roe:
189
+ score3 += round(MAX3 * 0.666)
190
+ elif 0 < roic:
191
+ # roic 로 평가할 수 있는 경우
192
+ if 0 < roic <= 15:
193
+ score3 += round(MAX3 * 0.333)
194
+ elif 15 < roic <= 30:
195
+ score3 += round(MAX3 * 0.666)
196
+ elif 30 < roic:
197
+ score3 += MAX3
198
+
199
+ # PFCF 평가
200
+ pfcf_dict = mil_dict['가치지표']['PFCF']
201
+ _, pfcf = mongo.Corps.latest_value(pfcf_dict)
202
+
203
+ logger.debug(f'recent pfcf {_}, {pfcf}')
204
+ try:
205
+ p = round(-40 * math.log10(pfcf) + 40)
206
+ except ValueError:
207
+ p = 0
208
+ score4 = 0 if 0 > p else p
209
+
210
+ return score1, score2, score3, score4
@@ -1,15 +1,12 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: analyser_hj3415
3
- Version: 2.0.2
3
+ Version: 2.2.0
4
4
  Summary: Stock analyser and database processing programs
5
5
  Author-email: Hyungjin Kim <hj3415@gmail.com>
6
6
  Description-Content-Type: text/markdown
7
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>=2.0.0
8
+ Requires-Dist: utils-hj3415>=2.6.0
9
+ Requires-Dist: db-hj3415>=3.3.2
13
10
  Project-URL: Home, https://www.hyungjin.kr
14
11
 
15
12
  ### analyser-hj3415
@@ -20,12 +17,11 @@ analyser_hj3415 manage the database.
20
17
  ---
21
18
  #### Requirements
22
19
 
23
- scrapy>=2.11.2
24
20
  pandas>=2.2.2
21
+ pymongo>=4.8.0
25
22
  sqlalchemy>=2.0.31
26
- selenium>=4.22.0
27
23
  utils-hj3415>=2.0.1
28
- analyser_hj3415>=0.3.5
24
+ scraper-hj3415>=2.0.0
29
25
 
30
26
  ---
31
27
  #### API
@@ -0,0 +1,15 @@
1
+ analyser_hj3415/.DS_Store,sha256=OQfTSOHL-zjUtnNyBpNRVUJUstR4j6I7jihKDFQQmME,6148
2
+ analyser_hj3415/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ analyser_hj3415/cli.py,sha256=qzRnpDRJvQnQevSKHBpKbTsBjmSWllZjzTV4z_alg2A,4891
4
+ analyser_hj3415/myredis.py,sha256=zgsXO4G2VsXt4LID4VF-Y7AqkPjV8Th66a2czuma_bM,8738
5
+ analyser_hj3415/run.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ analyser_hj3415/tools.py,sha256=SNsrnL5CKmKAdFkmlwgREMIkWDRi6N9LngCdhhhop3Y,13606
7
+ analyser_hj3415/trash.py,sha256=vHrv8Q61QOkcwhmWfrj_yVdsdd5MoAxs9gXMOJEjMHM,8360
8
+ analyser_hj3415/analysers/eval.py,sha256=mlHi6EPc8l8O6vKnWyX4Cz1BaeGhUpWM8gVZRNhm-JU,13299
9
+ analyser_hj3415/analysers/report.py,sha256=whggmLXl7yF-BjQ6JKgxmhILT2T4uFP-rit_BSes9xM,9189
10
+ analyser_hj3415/analysers/score.py,sha256=C_Xiqo44o2OAXHaHiHYLa60HwKwpUt_H18uO5Iff1TM,16308
11
+ analyser_hj3415-2.2.0.dist-info/entry_points.txt,sha256=dHaCM3eOAGONmxTWuRVqo9Zyq2C7J5TZmpH0PD6FW5k,103
12
+ analyser_hj3415-2.2.0.dist-info/LICENSE,sha256=QVKTp0dTnB5xG8RLgG17LwSWCKNEzYoVVM6KjoCPKc0,1079
13
+ analyser_hj3415-2.2.0.dist-info/WHEEL,sha256=Sgu64hAMa6g5FdzHxXv9Xdse9yxpGGMeagVtPMWpJQY,99
14
+ analyser_hj3415-2.2.0.dist-info/METADATA,sha256=OJhj-1acjb5Ht817i0tzqYdLUkA94NpGVZ-dclMstKo,6417
15
+ analyser_hj3415-2.2.0.dist-info/RECORD,,
Binary file
@@ -1,240 +0,0 @@
1
- import time
2
- import sys
3
- from _datetime import datetime
4
- from typing import Dict, List, Tuple, Callable
5
- from multiprocessing import Process, Queue
6
- from . import mongo
7
- from utils_hj3415 import utils, noti
8
- from scraper2_hj3415.krx import krx
9
- from scraper2_hj3415.nfscrapy import run as nfsrun
10
- from pymongo import MongoClient
11
- from selenium.webdriver.chrome.webdriver import WebDriver
12
-
13
- import logging
14
- logger = logging.getLogger(__name__)
15
- formatter = logging.Formatter('%(levelname)s: [%(name)s] %(message)s')
16
- ch = logging.StreamHandler()
17
- ch.setFormatter(formatter)
18
- logger.addHandler(ch)
19
- logger.setLevel(logging.INFO)
20
-
21
-
22
- """
23
- chk_integrity_corps 함수로 종목코드를 데이터베이스명으로 가지는 DB의 유효성을 검사한다.
24
- """
25
-
26
-
27
- def test_corp_one(client1: MongoClient, code: str, driver: WebDriver = None, waiting_time: int = 10) -> Dict[str, list]:
28
- """
29
- 종목 하나의 컬렉션의 유효성을 검사하여 부족한 컬렉션을 딕셔너리로 만들어서 반환한다.
30
- driver와 waiting_time은 본 함수에서 사용하지는 않으나 다른 함수와 인자를 맞추기위해 인자로 받아준다.
31
- 리턴값 - {'005930': ['c104','c103'...]}
32
- """
33
-
34
- def is_same_count_of_docs(col_name1: str, col_name2: str) -> bool:
35
- logger.debug(f"In is_same_count_of_docs {code}/ {col_name1}, {col_name2}")
36
- corp_one.page = col_name1
37
- count_doc1 = corp_one.count_docs_in_col()
38
- corp_one.page = col_name2
39
- count_doc2 = corp_one.count_docs_in_col()
40
- if count_doc1 == count_doc2:
41
- return True
42
- else:
43
- return False
44
-
45
- proper_collections = {'c101', 'c104y', 'c104q', 'c106y', 'c106q', 'c103손익계산서q', 'c103재무상태표q',
46
- 'c103현금흐름표q', 'c103손익계산서y', 'c103재무상태표y', 'c103현금흐름표y'}
47
-
48
- logger.debug('In test_corp_one function...')
49
- return_dict = {}
50
-
51
- logger.debug(f'return_dict is ... {return_dict}')
52
- # 한 종목의 유효성 검사코드
53
- corp_one = mongo.Corps(client1, code, 'c101')
54
-
55
- # 차집합을 사용해서 db내에 없는 컬렉션이 있는지 확인한다.
56
- set_deficient_collentions = set.difference(proper_collections, set(corp_one.list_collection_names()))
57
-
58
- logger.debug(f'After take a set of difference : {set_deficient_collentions}')
59
-
60
- return_dict[code] = set()
61
- # 컬렉션이 아예 없는 것이 있다면 falied_codes에 추가한다.
62
- if set_deficient_collentions != set():
63
- for item in set_deficient_collentions:
64
- # 컬렉션 이름 중 앞의 네글자만 추려서 추가해준다.(ex - c103손익계산서q -> c103)
65
- return_dict[code].add(item[:4])
66
-
67
- # 각 컬렉션의 q와 y의 도큐먼트 갯수를 비교하여 차이가 있는지 확인한다.
68
- if not is_same_count_of_docs('c104y', 'c104q'):
69
- return_dict[code].add('c104')
70
- if not is_same_count_of_docs('c106y', 'c106q'):
71
- return_dict[code].add('c106')
72
- if not is_same_count_of_docs('c103손익계산서q', 'c103손익계산서y') \
73
- or not is_same_count_of_docs('c103재무상태표q', 'c103재무상태표y') \
74
- or not is_same_count_of_docs('c103현금흐름표y', 'c103현금흐름표q'):
75
- return_dict[code].add('c103')
76
-
77
- # 집합을 리스트로 바꿔서 다시 저장한다.
78
- return_dict[code] = list(return_dict[code])
79
- logger.debug(f'Going out test_corp_one : {return_dict}')
80
- return return_dict
81
-
82
-
83
- def test_corp_one_is_modified(client: MongoClient, code: str, driver: WebDriver, waiting_time: int) -> Dict[str, bool]:
84
- """
85
- 웹에서 스크랩한 c103손익계산서y와 데이터베이스에 있는 c103손익계산서y를 비교하여 다른지 확인하여 업데이트 유무를 반환한다.
86
- 리턴값 - (코드, bool-업데이트가필요한지)
87
- """
88
- df_online = nfsrun.scrape_c103_first_page(driver, code, waiting_time=waiting_time)
89
- df_mongo = mongo.C103(client, code=code, page='c103손익계산서y').load_df()
90
-
91
- logger.debug(df_online)
92
- logger.debug(df_mongo)
93
-
94
- return_dict = {code: not df_online.equals(df_mongo)}
95
- return return_dict
96
-
97
-
98
- def working_with_parts(test_func: Callable[[MongoClient, str, WebDriver, int], dict], db_addr: str, divided_code_list: list, my_q: Queue, waiting_time: int):
99
- # 각 코어별로 디비 클라이언트를 만들어야만 한다. 안그러면 에러발생
100
- client = mongo.connect_mongo(db_addr)
101
- driver = utils.get_driver()
102
- t = len(divided_code_list)
103
-
104
- failed_dict_part = {}
105
-
106
- for i, code in enumerate(divided_code_list):
107
- try:
108
- failed_one_dict = test_func(client, code, driver, waiting_time)
109
- except Exception as e:
110
- print(f"{code} has a error : {e}", file=sys.stderr)
111
- continue
112
- print(f'{i + 1}/{t} {failed_one_dict}')
113
- if failed_one_dict[code]:
114
- # 빈리스트가 아니라면...또는 C103이 변화되었다면.. 큐에 추가한다.
115
- failed_dict_part.update(failed_one_dict)
116
- else:
117
- # 큐에서 put은 함수 리턴처럼 함수에서 한번만 한다.
118
- my_q.put(failed_dict_part)
119
- driver.close()
120
-
121
-
122
- # 멀티프로세싱을 사용하기 위해서 독립된 함수로 제작하였음(피클링이 가능해야함)
123
- def chk_integrity_corps(client: MongoClient, code: str = 'all') -> Dict[str, list]:
124
- """
125
- 몽고 디비의 corps들의 integrity 검사후 이상이 있는 코드 리스트 반환
126
- 이상을 찾는 방법 - 각 컬렉션이 다 있는가. 각 컬렉션에서 연도와 분기의 도큐먼트 갯수가 같은가
127
- return - {'코드': ['cxxx',...], '코드': ['cxxx',...]...}
128
- """
129
- failed_codes = {}
130
- codes_in_db = mongo.Corps.get_all_codes(client)
131
- if code == 'all':
132
- print('*' * 25, f"Check all Corp db integrity using multiprocess", '*' * 25)
133
- print(f'Total {len(codes_in_db)} items..')
134
- n, divided_list = utils.code_divider_by_cpu_core(codes_in_db)
135
-
136
- addr = mongo.extract_addr_from_client(client)
137
-
138
- start_time = time.time()
139
- q = Queue()
140
- ths = []
141
- for i in range(n):
142
- ths.append(Process(target=working_with_parts, args=(test_corp_one, addr, divided_list[i], q, 0)))
143
- for i in range(n):
144
- ths[i].start()
145
-
146
- for i in range(n):
147
- failed_codes.update(q.get())
148
-
149
- for i in range(n):
150
- ths[i].join()
151
-
152
- logger.debug(f"failed_codes : {failed_codes}")
153
- print(f'Total spent time : {round(time.time() - start_time, 2)} sec.')
154
- else:
155
- print('*' * 25, f"Check {code} db integrity", '*' * 25)
156
- if code in codes_in_db:
157
- result_dict = test_corp_one(client, code)
158
- print(f'{code} : {result_dict[code]}')
159
- if result_dict[code]: # 빈리스트가 아니라면...
160
- failed_codes.update(result_dict)
161
-
162
- else:
163
- Exception(f'{code} is not in db..')
164
- return failed_codes
165
-
166
-
167
- def chk_modifying_corps(client, code: str = 'all', waiting_time: int = 60) -> Dict[str, bool]:
168
- """
169
- 각 종목의 웹과 DB의 C103손익계산서y를 비교하여 변화가 있어 refresh가 필요한지를 반환한다.
170
- """
171
- failed_codes = {}
172
- codes_in_db = mongo.Corps.get_all_codes(client)
173
- if code == 'all':
174
- print('*' * 25, f"Check all Corp db need for updating using multiprocess", '*' * 25)
175
- print(f'Total {len(codes_in_db)} items..')
176
- n, divided_list = utils.code_divider_by_cpu_core(codes_in_db)
177
-
178
- addr = mongo.extract_addr_from_client(client)
179
-
180
- start_time = time.time()
181
- q = Queue()
182
- ths = []
183
- for i in range(n):
184
- ths.append(Process(target=working_with_parts, args=(test_corp_one_is_modified, addr, divided_list[i], q, waiting_time)))
185
- for i in range(n):
186
- ths[i].start()
187
-
188
- for i in range(n):
189
- failed_codes.update(q.get())
190
-
191
- for i in range(n):
192
- ths[i].join()
193
-
194
- logger.debug(f"failed_codes : {failed_codes}")
195
- print(f'Total spent time : {round(time.time() - start_time, 2)} sec.')
196
- else:
197
- print('*' * 25, f"Check {code} db need for updating ", '*' * 25)
198
- driver = utils.get_driver()
199
- if code in codes_in_db:
200
- result_dict = test_corp_one_is_modified(client, code, driver)
201
- print(f'{code} : {result_dict[code]}')
202
- if result_dict[code]:
203
- failed_codes.update(result_dict)
204
-
205
- else:
206
- Exception(f'{code} is not in db..')
207
- return failed_codes
208
-
209
-
210
- def sync_mongo_with_krx(client):
211
- print('*' * 20, 'Sync with krx and mongodb', '*' * 20)
212
- all_codes_in_db = mongo.Corps.get_all_codes(client)
213
- print('*' * 20, 'Refreshing krx.db...', '*' * 20)
214
- krx.make_db()
215
- print('*' * 80)
216
- all_codes_in_krx = krx.get_codes()
217
- print('\tThe number of codes in krx: ', len(all_codes_in_krx))
218
- logger.debug(all_codes_in_krx)
219
- try:
220
- print('\tThe number of dbs in mongo: ', len(all_codes_in_db))
221
- logger.debug(all_codes_in_db)
222
- except TypeError:
223
- err_msg = "Error while sync mongo data...it's possible mongo db doesn't set yet.."
224
- logger.error(err_msg)
225
- noti.telegram_to(botname='manager', text=err_msg)
226
- return
227
- del_targets = list(set(all_codes_in_db) - set(all_codes_in_krx))
228
- add_targets = list(set(all_codes_in_krx) - set(all_codes_in_db))
229
- print('\tDelete target: ', del_targets)
230
- print('\tAdd target: ', add_targets)
231
-
232
- for target in del_targets:
233
- mongo.Corps.del_db(client, target)
234
-
235
- if add_targets:
236
- print(f'Starting.. c10346 scraper.. items : {len(add_targets)}')
237
- addr = mongo.extract_addr_from_client(client)
238
- nfsrun.c103(add_targets, addr)
239
- nfsrun.c104(add_targets, addr)
240
- nfsrun.c106(add_targets, addr)