analyser_hj3415 2.0.2__py2.py3-none-any.whl → 2.2.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,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)