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.
analyser_hj3415/.DS_Store CHANGED
Binary file
@@ -0,0 +1,289 @@
1
+ """red, mil, blue 3가지 분야에서 자료를 계산하여 리턴하는 함수 모음
2
+ """
3
+ import math
4
+
5
+ from analyser_hj3415 import tools
6
+ from utils_hj3415 import utils
7
+ from db_hj3415 import myredis
8
+
9
+ import logging
10
+
11
+ logger = logging.getLogger(__name__)
12
+ formatter = logging.Formatter('%(levelname)s: [%(name)s] %(message)s')
13
+ ch = logging.StreamHandler()
14
+ ch.setFormatter(formatter)
15
+ logger.addHandler(ch)
16
+ logger.setLevel(logging.WARNING)
17
+
18
+
19
+ # 주식을 통한 기대수익률 - 금리가 3%일 경우 두배인 6% 정도로 잡는다.
20
+ EXPECT_EARN = 0.06
21
+
22
+
23
+ def red(code: str) -> dict:
24
+ """
25
+ 리턴값
26
+ {
27
+ 'red_price': red_price,
28
+ '사업가치': 사업가치,
29
+ '재산가치': 재산가치,
30
+ '부채평가': 부채평가,
31
+ '발행주식수': 발행주식수,
32
+ 'date': [각 유효한 값의 년월값 리스트(ex- 2020/09)],
33
+ }
34
+ """
35
+ c103q = myredis.C103(code, 'c103재무상태표q')
36
+
37
+ d1, 지배주주당기순이익 = tools.calc당기순이익(code)
38
+ d2, 유동자산 = tools.calc유동자산(code)
39
+ d3, 유동부채 = tools.calc유동부채(code)
40
+ d4, 부채평가 = tools.calc비유동부채(code)
41
+
42
+ c103q.page = 'c103재무상태표q'
43
+ d5, 투자자산 = c103q.latest_value_pop2('투자자산')
44
+ d6, 투자부동산 = c103q.latest_value_pop2('투자부동산')
45
+
46
+ # 사업가치 계산 - 지배주주지분 당기순이익 / 기대수익률
47
+ 사업가치 = round(utils.nan_to_zero(지배주주당기순이익) / EXPECT_EARN, 2)
48
+
49
+ # 재산가치 계산 - 유동자산 - (유동부채*1.2) + 고정자산중 투자자산
50
+ 재산가치 = round(유동자산 - (유동부채 * 1.2) + utils.nan_to_zero(투자자산) + utils.nan_to_zero(투자부동산), 2)
51
+
52
+ _, 발행주식수 = c103q.latest_value_pop2('발행주식수')
53
+ if math.isnan(발행주식수):
54
+ 발행주식수 = utils.to_int(myredis.C101(code).get_recent().get('발행주식'))
55
+ else:
56
+ 발행주식수 = 발행주식수 * 1000
57
+
58
+ try:
59
+ red_price = round(((사업가치 + 재산가치 - 부채평가) * 100000000) / 발행주식수)
60
+ except (ZeroDivisionError, ValueError) as e:
61
+ red_price = math.nan
62
+
63
+ logger.debug(f'Red Price : {red_price}원')
64
+ return {
65
+ 'red_price': red_price,
66
+ '사업가치': 사업가치,
67
+ '재산가치': 재산가치,
68
+ '부채평가': 부채평가,
69
+ '발행주식수': 발행주식수,
70
+ 'date': tools.set_data(d1, d2, d3, d4, d5, d6), # ''값을 제거하고 리스트로 바꾼다.
71
+ }
72
+
73
+
74
+ def mil(code: str) -> dict:
75
+ """
76
+ 리턴값
77
+ {
78
+ '주주수익률': 주주수익률,
79
+ '이익지표': 이익지표,
80
+ '투자수익률': {'ROIC': roic, 'ROE': roe , 'ROE106': {}},
81
+ '가치지표': {'FCF': fcf_dict, 'PFCF': pfcf_dict, 'PCR': pcr_dict},
82
+ 'date': [각 유효한 값의 년월값 리스트(ex- 2020/09)],
83
+ }
84
+
85
+ - 재무활동현금흐름이 마이너스라는 것은 배당급 지급했거나, 자사주 매입했거나, 부채를 상환한 상태임.
86
+ - 반대는 채권자로 자금을 조달했거나 신주를 발행했다는 의미
87
+ <주주수익률> - 재무활동현금흐름/시가총액 => 5%이상인가?
88
+
89
+ 투하자본수익률(ROIC)가 30%이상인가
90
+ ROE(자기자본이익률) 20%이상이면 아주 우수 다른 투자이익률과 비교해볼것 10%미만이면 별로...단, 부채비율을 확인해야함.
91
+
92
+ 이익지표 ...영업현금흐름이 순이익보다 많은가 - 결과값이 음수인가..
93
+
94
+ FCF는 영업현금흐름에서 자본적 지출(유·무형투자 비용)을 차감한 순수한 현금력이라 할 수 있다.
95
+ 말 그대로 자유롭게(Free) 사용할 수 있는 여윳돈을 뜻한다.
96
+ 잉여현금흐름이 플러스라면 미래의 투자나 채무상환에 쓸 재원이 늘어난 것이다.
97
+ CAPEX(Capital expenditures)는 미래의 이윤을 창출하기 위해 지출된 비용을 말한다.
98
+ 이는 기업이 고정자산을 구매하거나, 유효수명이 당회계년도를 초과하는 기존의 고정자산에 대한 투자에 돈이 사용될 때 발생한다.
99
+
100
+ 잉여현금흐름이 마이너스일때는 설비투자가 많은 시기라 주가가 약세이며 이후 설비투자 마무리되면서 주가가 상승할수 있다.
101
+ 주가는 잉여현금흐름이 증가할때 상승하는 경향이 있다.
102
+ fcf = 영업현금흐름 - capex
103
+
104
+ 가치지표평가
105
+ price to fcf 계산
106
+ https://www.investopedia.com/terms/p/pricetofreecashflow.asp
107
+ pcr보다 정확하게 주식의 가치를 평가할수 있음. 10배이하 추천
108
+ """
109
+ c103q = myredis.C103(code, 'c103현금흐름표q')
110
+ c104q = myredis.C104(code, 'c104q')
111
+ c106q = myredis.C106(code, 'c106q')
112
+
113
+ marketcap억 = tools.get_marketcap(code) / 100000000
114
+ logger.debug(f'{code} market cap: {marketcap억}')
115
+ fcf_dict = tools.findFCF(code)
116
+ pfcf_dict = tools.findPFCF(code)
117
+ d1, 지배주주당기순이익 = tools.calc당기순이익(code)
118
+
119
+ d2, 재무활동현금흐름 = c103q.sum_recent_4q('재무활동으로인한현금흐름')
120
+ d3, 영업활동현금흐름 = c103q.sum_recent_4q('영업활동으로인한현금흐름')
121
+
122
+ d4, roic = c104q.sum_recent_4q('ROIC')
123
+ d5, roe = c104q.latest_value_pop2('ROE')
124
+ roe106 = c106q.find('ROE')
125
+
126
+ _, pcr_dict = c104q.find_without_yoy('PCR')
127
+
128
+ try:
129
+ 주주수익률 = round((재무활동현금흐름 / marketcap억 * -100), 2)
130
+ 이익지표 = round((지배주주당기순이익 - 영업활동현금흐름) / marketcap억, 5)
131
+ except ZeroDivisionError:
132
+ 주주수익률 = math.nan
133
+ 이익지표 = math.nan
134
+
135
+ if math.isnan(주주수익률) or math.isnan(이익지표):
136
+ logger.warning(f'주주수익률: {주주수익률} 이익지표: {이익지표}')
137
+ logger.warning(f'재무활동현금흐름: {재무활동현금흐름} / 지배주주당기순이익: {지배주주당기순이익} / 영업활동현금흐름: {영업활동현금흐름}')
138
+
139
+ logger.debug(f'{code} fcf_dict : {fcf_dict}')
140
+ logger.debug(f"{code} market_cap : {marketcap억}")
141
+ logger.debug(f'{code} pfcf_dict : {pfcf_dict}')
142
+ logger.debug(f'{code} pcr_dict : {pcr_dict}')
143
+
144
+ return {
145
+ '주주수익률': 주주수익률,
146
+ '이익지표': 이익지표,
147
+ '투자수익률': {'ROIC': roic, 'ROE': roe, 'ROE106': roe106},
148
+ '가치지표': {'FCF': fcf_dict, 'PFCF': pfcf_dict, 'PCR': pcr_dict},
149
+ 'date': tools.set_data(d1, d2, d3, d4, d5),
150
+ }
151
+
152
+
153
+ def blue(code: str) -> dict:
154
+ """
155
+ 리턴값
156
+ {
157
+ 'date': [각 유효한 값의 최근분기 값 리스트(ex- 2020/09)],
158
+ '순부채비율': (29.99, {'2018/12': 19.45, '2019/12': 19.52, '2020/12': 12.07, '2021/12': 82.2, '2022/12': 29.99, '2023/12': nan}),
159
+ '순운전자본회전율': (1.04, {'2018/12': 21.91, '2019/12': 23.12, '2020/12': 5.88, '2021/12': 5.6, '2022/12': 6.04, '2023/12': nan}),
160
+ '유동비율': 64.29,
161
+ '이자보상배율': (-3.64, {'2018/12': 4.01, '2019/12': 1.3, '2020/12': -5.05, '2021/12': 0.56, '2022/12': -1.28, '2023/12': nan}),
162
+ '재고자산회전율': (1.66, {'2018/12': 12.41, '2019/12': 12.44, '2020/12': 9.18, '2021/12': 9.76, '2022/12': 8.79, '2023/12': nan})
163
+ }
164
+
165
+ <유동비율>
166
+ 100미만이면 주의하나 현금흐름창출력이 좋으면 괜찮을수 있다.
167
+ 만약 100%이하면 유동자산에 추정영업현금흐름을 더해서 다시계산해보아 기회를 준다.
168
+ <이자보상배율>
169
+ 이자보상배율 영업이익/이자비용으로 1이면 자금사정빡빡 5이상이면 양호
170
+ <순운전자금회전율>
171
+ 순운전자금 => 기업활동을 하기 위해 필요한 자금 (매출채권 + 재고자산 - 매입채무)
172
+ 순운전자본회전율은 매출액/순운전자본으로 일정비율이 유지되는것이 좋으며 너무 작아지면 순운전자본이 많아졌다는 의미로 재고나 외상이 쌓인다는 뜻
173
+ <재고자산회전율>
174
+ 재고자산회전율은 매출액/재고자산으로 회전율이 낮을수록 재고가 많다는 이야기이므로 불리 전년도등과 비교해서 큰차이 발생하면 알람.
175
+ 재고자산회전율이 작아지면 재고가 쌓인다는뜻
176
+ <순부채비율>
177
+ 부채비율은 업종마다 달라 일괄비교 어려우나 순부채 비율이 20%이하인것이 좋고 꾸준히 늘어나지 않는것이 좋다.
178
+ 순부채 비율이 30%이상이면 좋치 않다.
179
+ <매출액>
180
+ 매출액은 어떤경우에도 성장하는 기업이 좋다.매출이 20%씩 늘어나는 종목은 유망한 종목
181
+ <영업이익률>
182
+ 영업이익률은 기업의 경쟁력척도로 경쟁사에 비해 높으면 경제적해자를 갖춘셈
183
+ """
184
+
185
+ d1, 유동비율 = tools.calc유동비율(code, pop_count=3)
186
+ logger.debug(f'유동비율 {유동비율} / [{d1}]')
187
+
188
+ c104y = myredis.C104(code, 'c104y')
189
+ _, dict이자보상배율y = c104y.find_with_yoy('이자보상배율')
190
+ _, dict순운전자본회전율y = c104y.find_with_yoy('순운전자본회전율')
191
+ _, dict재고자산회전율y = c104y.find_with_yoy('재고자산회전율')
192
+ _, dict순부채비율y = c104y.find_with_yoy('순부채비율')
193
+
194
+ c104q = myredis.C104(code, 'c104q')
195
+ d6, 이자보상배율q = c104q.latest_value_pop2('이자보상배율')
196
+ d7, 순운전자본회전율q = c104q.latest_value_pop2('순운전자본회전율')
197
+ d8, 재고자산회전율q = c104q.latest_value_pop2('재고자산회전율')
198
+ d9, 순부채비율q = c104q.latest_value_pop2('순부채비율')
199
+
200
+ if len(dict이자보상배율y) == 0:
201
+ logger.warning(f'empty dict - 이자보상배율 : {이자보상배율q} {dict이자보상배율y}')
202
+
203
+ if len(dict순운전자본회전율y) == 0:
204
+ logger.warning(f'empty dict - 순운전자본회전율 : {순운전자본회전율q} {dict순운전자본회전율y}')
205
+
206
+ if len(dict재고자산회전율y) == 0:
207
+ logger.warning(f'empty dict - 재고자산회전율 : {재고자산회전율q} {dict재고자산회전율y}')
208
+
209
+ if len(dict순부채비율y) == 0:
210
+ logger.warning(f'empty dict - 순부채비율 : {순부채비율q} {dict순부채비율y}')
211
+
212
+ ################################################################
213
+
214
+ return {
215
+ '유동비율': 유동비율,
216
+ '이자보상배율': (이자보상배율q, dict이자보상배율y),
217
+ '순운전자본회전율': (순운전자본회전율q, dict순운전자본회전율y),
218
+ '재고자산회전율': (재고자산회전율q, dict재고자산회전율y),
219
+ '순부채비율': (순부채비율q, dict순부채비율y),
220
+ 'date': tools.set_data(d1, d6, d7, d8, d9), # ''값을 제거하고 리스트로 바꾼다.
221
+ }
222
+
223
+
224
+ def growth(code: str) -> dict:
225
+ """
226
+ 리턴값
227
+ {'date': [각 유효한 값의 최근분기 값 리스트(ex- 2020/09)],
228
+ '매출액증가율': (-14.37, {'2018/12': -24.56, '2019/12': -20.19, '2020/12': -12.64, '2021/12': 38.65, '2022/12': -8.56, '2023/12': nan}),
229
+ '영업이익률': {'뉴프렉스': '17.36', '동일기연': '13.58', '비에이치': '16.23', '에이엔피': '-9.30', '이브이첨단소재': '-4.93'}}
230
+
231
+ <매출액>
232
+ 매출액은 어떤경우에도 성장하는 기업이 좋다.매출이 20%씩 늘어나는 종목은 유망한 종목
233
+ <영업이익률>
234
+ 영업이익률은 기업의 경쟁력척도로 경쟁사에 비해 높으면 경제적해자를 갖춘셈
235
+ """
236
+ c104y = myredis.C104(code, 'c104y')
237
+ c106y = myredis.C106(code, 'c106y')
238
+
239
+ _, dict매출액증가율y = c104y.find_with_yoy('매출액증가율')
240
+
241
+ c104q = myredis.C104(code, 'c104q')
242
+ d2, 매출액증가율q = c104q.latest_value_pop2('매출액증가율')
243
+
244
+ logger.debug(f'매출액증가율 : {매출액증가율q} {dict매출액증가율y}')
245
+
246
+ ################################################################
247
+
248
+ # c106 에서 타 기업과 영업이익률 비교
249
+ dict영업이익률 = c106y.find('영업이익률')
250
+
251
+ return {
252
+ '매출액증가율': (매출액증가율q, dict매출액증가율y),
253
+ '영업이익률': dict영업이익률,
254
+ 'date': [d2, ]}
255
+
256
+
257
+ """
258
+ - 각분기의 합이 연이 아닌 타이틀(즉 sum_4q를 사용하면 안됨)
259
+ '*(지배)당기순이익'
260
+ '*(비지배)당기순이익'
261
+ '장기차입금'
262
+ '현금및예치금'
263
+ '매도가능금융자산'
264
+ '매도파생결합증권'
265
+ '만기보유금융자산'
266
+ '당기손익-공정가치측정금융부채'
267
+ '당기손익인식(지정)금융부채'
268
+ '단기매매금융자산'
269
+ '단기매매금융부채'
270
+ '예수부채'
271
+ '차입부채'
272
+ '기타부채'
273
+ '보험계약부채(책임준비금)'
274
+ '*CAPEX'
275
+ 'ROE'
276
+ """
277
+
278
+ """
279
+ - sum_4q를 사용해도 되는 타이틀
280
+ '자산총계'
281
+ '당기순이익'
282
+ '유동자산'
283
+ '유동부채'
284
+ '비유동부채'
285
+
286
+ '영업활동으로인한현금흐름'
287
+ '재무활동으로인한현금흐름'
288
+ 'ROIC'
289
+ """
@@ -1,8 +1,8 @@
1
1
  """다양한 문자열 출력 형식에 맞춘 함수들
2
2
  """
3
- from .db import mongo
4
- from .eval import red as eval_red, mil as eval_mil, blue as eval_blue, growth as eval_growth
5
- from .score import red as score_red, mil as score_mil, blue as score_blue, growth as score_growth
3
+ from db_hj3415 import myredis
4
+ from analyser_hj3415.analysers import eval
5
+ from analyser_hj3415.analysers import score
6
6
  from utils_hj3415 import utils
7
7
  import textwrap
8
8
 
@@ -21,7 +21,7 @@ class Report:
21
21
  def __init__(self, client, code: str):
22
22
  self.client = client
23
23
  self.code = code
24
- self.name = mongo.Corps.get_name(client, code)
24
+ self.name = myredis.Corps.get_name(code)
25
25
 
26
26
  def __str__(self):
27
27
  return (self.c101() + self.separate_line
@@ -32,7 +32,7 @@ class Report:
32
32
  # + make_str.c108())
33
33
 
34
34
  def c101(self, full=True):
35
- c101 = mongo.C101(self.client, self.code).get_recent(merge_intro=True)
35
+ c101 = myredis.C101(self.code).get_recent()
36
36
  logger.info(c101)
37
37
 
38
38
  title = '=' * 35 + f"\t{c101['코드']}\t\t{c101['종목명']}\t\t{c101['업종']}\t" + '=' * 35
@@ -65,11 +65,11 @@ class Report:
65
65
  return title + '\n' + intro + self.separate_line + price + '\n' + info
66
66
 
67
67
  def red(self, full=True) -> str:
68
- red_dict = eval_red(self.client, self.code)
69
- p, 괴리율 = score_red(self.client, self.code)
68
+ red_dict = eval.red(self.code)
69
+ 괴리율 = score.red(self.code)
70
70
  logger.info(red_dict)
71
71
 
72
- title = f"Red\tPoint({p})\t괴리율({괴리율}%)\t{red_dict['date']}\n"
72
+ title = f"Red\t괴리율({괴리율}%)\t{red_dict['date']}\n"
73
73
  if full:
74
74
  contents = (f"사업가치({utils.deco_num(red_dict['사업가치'])}억) "
75
75
  f"+ 재산가치({utils.deco_num(red_dict['재산가치'])}억) "
@@ -81,8 +81,8 @@ class Report:
81
81
  return title + contents
82
82
 
83
83
  def mil(self, full=True) -> str:
84
- mil_dict = eval_mil(self.client, self.code)
85
- p1, p2, p3, p4 = score_mil(self.client, self.code)
84
+ mil_dict = eval.mil(self.code)
85
+ p1, p2, p3, p4 = score.mil(self.code)
86
86
  logger.info(mil_dict)
87
87
 
88
88
  title = f"Millenial\tPoint({p1+p2+p3+p4})\t{mil_dict['date']}\n"
@@ -104,8 +104,8 @@ class Report:
104
104
  return title + contents
105
105
 
106
106
  def blue(self, full=True) -> str:
107
- blue_dict = eval_blue(self.client, self.code)
108
- p1, p2, p3, p4, p5 = score_blue(self.client, self.code)
107
+ blue_dict = eval.blue(self.code)
108
+ p1, p2, p3, p4, p5 = score.blue(self.code)
109
109
  logger.info(blue_dict)
110
110
 
111
111
  title = f"Blue\tPoint({p1+p2+p3+p4+p5})\t{blue_dict['date']}\n"
@@ -121,8 +121,8 @@ class Report:
121
121
  return title + contents
122
122
 
123
123
  def growth(self, full=True) -> str:
124
- growth_dict = eval_growth(self.client, self.code)
125
- p1, p2 = score_growth(self.client, self.code)
124
+ growth_dict = eval.growth(self.code)
125
+ p1, p2 = score.growth(self.code)
126
126
  logger.info(growth_dict)
127
127
 
128
128
  title = f"Growth\tPoint({p1 + p2})\t{growth_dict['date']}\n"
@@ -169,50 +169,14 @@ class Report:
169
169
  'red_s': (53, -75.42)}
170
170
  """
171
171
  return {
172
- 'c101': mongo.C101(self.client, self.code).get_recent(merge_intro=True),
173
- 'red': eval_red(self.client, self.code),
174
- 'mil': eval_mil(self.client, self.code),
175
- 'blue': eval_blue(self.client, self.code),
176
- 'growth': eval_growth(self.client, self.code),
177
- # 'c108': mongo.C108(self.client, self.code).get_recent(),
178
- 'red_s': score_red(self.client, self.code),
179
- 'mil_s': score_mil(self.client, self.code),
180
- 'blue_s': score_blue(self.client, self.code),
181
- 'growth_s': score_growth(self.client, self.code),
172
+ 'c101': myredis.C101(self.code).get_recent(),
173
+ 'red': eval.red(self.code),
174
+ 'mil': eval.mil(self.code),
175
+ 'blue': eval.blue(self.code),
176
+ 'growth': eval.growth(self.code),
177
+ 'red_s': score.red(self.code),
178
+ 'mil_s': score.mil(self.code),
179
+ 'blue_s': score.blue(self.code),
180
+ 'growth_s': score.growth(self.code),
182
181
  }
183
182
 
184
-
185
- """
186
- def c108(self, full=True) -> str:
187
- if full:
188
- c108_list = mongo.C108(self.client, self.code).get_all()
189
- else:
190
- c108_list = mongo.C108(self.client, self.code).get_recent()
191
- s = ''
192
- logger.info(c108_list)
193
- for i, c108_dict in enumerate(c108_list):
194
- logger.info(c108_dict)
195
- if i == 0:
196
- pass
197
- else:
198
- s += '\n'
199
- header = f"{c108_dict['날짜']}\thprice : {c108_dict['목표가']} 원\n"
200
- title = f"<<{c108_dict['제목']}>>\n"
201
- contents = ''
202
- for line in c108_dict['내용'].split('▶'):
203
- contents += line.strip()
204
- s += header + title + textwrap.fill(contents, width=70) + self.separate_line
205
- return s
206
- """
207
-
208
-
209
-
210
- def for_telegram(client, code: str) -> str:
211
- make_str = MakeStr(client, code)
212
-
213
- return (make_str.c101(full=False) + make_str.separate_line
214
- + make_str.red(full=False) + make_str.separate_line
215
- + make_str.mil(full=False) + make_str.separate_line
216
- + make_str.blue(full=False) + make_str.separate_line
217
- + make_str.growth(full=False))
218
- # + make_str.c108(full=False))
@@ -4,9 +4,10 @@ import pprint
4
4
  import copy
5
5
  from typing import Tuple
6
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
7
+ from db_hj3415 import myredis, mymongo
8
+ from analyser_hj3415.analysers import eval
9
9
  from utils_hj3415 import utils
10
+ from analyser_hj3415 import myredis as analyser_redis
10
11
 
11
12
  import logging
12
13
 
@@ -18,50 +19,45 @@ logger.addHandler(ch)
18
19
  logger.setLevel(logging.WARNING)
19
20
 
20
21
 
21
- def red(client, code: str) -> Tuple[int, float]:
22
- """red price와 최근 주가의 괴리율 파악
22
+ def cal_deviation(v1: float, v2: float) -> float:
23
+ """
24
+ 괴리율 구하는 공식
25
+ :param v1:
26
+ :param v2:
27
+ :return:
28
+ """
29
+ try:
30
+ deviation = abs((v1 - v2) / v1) * 100
31
+ except ZeroDivisionError:
32
+ deviation = math.nan
33
+ return deviation
34
+
23
35
 
24
- 양수면 주가가 고평가되어 있는 상태, 음수면 저평가
25
- 음수가 현재 주가가 싸다는 의미
36
+ def red(code: str) -> int:
37
+ """red price와 최근 주가의 괴리율 파악
26
38
 
27
39
  Returns:
28
- tuple : 괴리율을 기반으로한 포인트, 주가와 red price 비교한 괴리율
40
+ int : 주가와 red price 비교한 괴리율
29
41
  """
30
- c101 = mongo.C101(client, code)
31
-
32
- logger.debug(f'c101 {c101.get_recent()}')
33
-
34
42
  try:
35
- recent_price = utils.to_int(c101.get_recent()['주가'])
43
+ recent_price = utils.to_int(myredis.C101(code).get_recent()['주가'])
36
44
  except KeyError:
37
45
  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}")
46
+ return 0
41
47
 
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')
48
+ red_price = analyser_redis.red(code)['red_price']
49
+ deviation = cal_deviation(recent_price, red_price)
50
+ if red_price < 0 or (recent_price >= red_price):
51
+ score = 0
52
+ else:
53
+ score = math.log10(deviation + 1) * 33 # desmos그래프상 33이 제일 적당한듯(최대100점에 가깝게)
50
54
 
51
- logger.debug(f'괴리율 : {괴리율}')
55
+ #print(f"최근주가 : {recent_price}", f"red가격 : {red_price}", f"괴리율 : {utils.to_int(deviation)}", f"score : {utils.to_int(score)}")
52
56
 
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, 괴리율
57
+ return utils.to_int(score)
62
58
 
63
59
 
64
- def mil(client, code: str) -> Tuple[int, int, int, int]:
60
+ def mil(code: str) -> Tuple[int, int, int, int]:
65
61
  """
66
62
  - 재무활동현금흐름이 마이너스라는 것은 배당급 지급했거나, 자사주 매입했거나, 부채를 상환한 상태임.
67
63
  - 반대는 채권자로 자금을 조달했거나 신주를 발행했다는 의미
@@ -90,55 +86,55 @@ def mil(client, code: str) -> Tuple[int, int, int, int]:
90
86
  Returns:
91
87
  tuple: 주주수익률, 이익지표, 투자수익률, PFCF포인트
92
88
  """
93
- mil_dict = eval_mil(client, code)
89
+ mil_dict = analyser_redis.mil(code)
94
90
 
95
- logger.debug(pprint.pformat(mil_dict, width=200))
91
+ print(pprint.pformat(mil_dict, width=200))
96
92
 
97
93
  # 주주수익률 평가
98
94
  if math.isnan(mil_dict['주주수익률']):
99
- p1 = 0
95
+ score1 = 0
100
96
  else:
101
- 주주수익률평가 = math.ceil(mil_dict['주주수익률'] - (EXPECT_EARN * 100))
102
- p1 = 0 if 0 > 주주수익률평가 else 주주수익률평가
97
+ 주주수익률평가 = math.ceil(mil_dict['주주수익률'] - (eval.EXPECT_EARN * 100))
98
+ score1 = 0 if 0 > 주주수익률평가 else 주주수익률평가
103
99
 
104
100
  # 이익지표 평가
105
- p2 = 10 if mil_dict['이익지표'] < 0 else 0
101
+ score2 = 10 if mil_dict['이익지표'] < 0 else 0
106
102
 
107
103
  # 투자수익률 평가
108
104
  MAX3 = 20
109
- p3 = 0
105
+ score3 = 0
110
106
  roic = mil_dict['투자수익률']['ROIC']
111
107
  roe = mil_dict['투자수익률']['ROE']
112
108
  if math.isnan(roic) or roic <= 0:
113
109
  # roic 가 비정상이라 평가할 수 없는 경우
114
110
  if 10 < roe <= 20:
115
- p3 += round(MAX3 * 0.333)
111
+ score3 += round(MAX3 * 0.333)
116
112
  elif 20 < roe:
117
- p3 += round(MAX3 * 0.666)
113
+ score3 += round(MAX3 * 0.666)
118
114
  elif 0 < roic:
119
115
  # roic 로 평가할 수 있는 경우
120
116
  if 0 < roic <= 15:
121
- p3 += round(MAX3 * 0.333)
117
+ score3 += round(MAX3 * 0.333)
122
118
  elif 15 < roic <= 30:
123
- p3 += round(MAX3 * 0.666)
119
+ score3 += round(MAX3 * 0.666)
124
120
  elif 30 < roic:
125
- p3 += MAX3
121
+ score3 += MAX3
126
122
 
127
123
  # PFCF 평가
128
124
  pfcf_dict = mil_dict['가치지표']['PFCF']
129
- _, pfcf = mongo.Corps.latest_value(pfcf_dict)
125
+ _, pfcf = mymongo.C1034.latest_dict_value(pfcf_dict)
130
126
 
131
127
  logger.debug(f'recent pfcf {_}, {pfcf}')
132
128
  try:
133
129
  p = round(-40 * math.log10(pfcf) + 40)
134
130
  except ValueError:
135
131
  p = 0
136
- p4 = 0 if 0 > p else p
132
+ score4 = 0 if 0 > p else p
137
133
 
138
- return p1, p2, p3, p4
134
+ return score1, score2, score3, score4
139
135
 
140
136
 
141
- def blue(client, code: str) -> Tuple[int, int, int, int, int]:
137
+ def blue(code: str) -> Tuple[int, int, int, int, int]:
142
138
  """회사의 안정성을 보는 지표들
143
139
 
144
140
  0을 기준으로 상태가 좋치 않을 수록 마이너스 값을 가진다.
@@ -181,11 +177,11 @@ def blue(client, code: str) -> Tuple[int, int, int, int, int]:
181
177
 
182
178
  return int(p)
183
179
 
184
- c104y = mongo.C104(client, code, 'c104y')
180
+ c104y = myredis.C104(code, 'c104y')
185
181
 
186
- blue_dict = eval_blue(client, code)
182
+ blue_dict = analyser_redis.blue(code)
187
183
 
188
- logger.debug(pprint.pformat(blue_dict, width=200))
184
+ print(pprint.pformat(blue_dict, width=200))
189
185
 
190
186
  def 유동비율평가(유동비율: float) -> int:
191
187
  # 채점은 0을 기준으로 마이너스 해간다. 즉 0이 제일 좋은 상태임.
@@ -210,9 +206,9 @@ def blue(client, code: str) -> Tuple[int, int, int, int, int]:
210
206
  if math.isnan(최근이자보상배율q) or 최근이자보상배율q <= 1:
211
207
  # 최근 분기의 값이 비정상이면 최근 년도를 한번 더 비교해 보지만 좀더 엄격하게 전년대비도 비교한다.
212
208
 
213
- _, 최근이자보상배율y = mongo.Corps.latest_value(dict_y)
209
+ _, 최근이자보상배율y = mymongo.C1034.latest_dict_value(dict_y)
214
210
  c104y.page = 'c104y'
215
- _, 전년대비 = c104y.find_증감율(title='이자보상배율').popitem()
211
+ 전년대비 = c104y.find_yoy(title='이자보상배율')
216
212
 
217
213
  if math.isnan(최근이자보상배율y) or 최근이자보상배율y <= 1 or math.isnan(전년대비) or 전년대비 < 0:
218
214
  p = NEG_MAX
@@ -233,9 +229,9 @@ def blue(client, code: str) -> Tuple[int, int, int, int, int]:
233
229
 
234
230
  if math.isnan(최근순부채비율q) or 최근순부채비율q >= 80:
235
231
  # 최근 분기의 값이 비정상이면 최근 년도를 한번 더 비교해 보지만 좀더 엄격하게 전년대비도 비교한다.
236
- _, 최근순부채비율y = mongo.Corps.latest_value(dict_y)
232
+ _, 최근순부채비율y = mymongo.C1034.latest_dict_value(dict_y)
237
233
  c104y.page = 'c104y'
238
- _, 전년대비 = c104y.find_증감율(title='순부채비율').popitem()
234
+ 전년대비 = c104y.find_yoy(title='순부채비율')
239
235
  if math.isnan(최근순부채비율y) or 최근순부채비율y >= 80 or math.isnan(전년대비) or 전년대비 > 0:
240
236
  p = NEG_MAX
241
237
  else:
@@ -269,7 +265,7 @@ def blue(client, code: str) -> Tuple[int, int, int, int, int]:
269
265
  return p1, p2, p3, p4, p5
270
266
 
271
267
 
272
- def growth(client, code: str) -> Tuple[int, int]:
268
+ def growth(code: str) -> Tuple[int, int]:
273
269
  """회사의 성장성을 보는 지표들
274
270
 
275
271
  <매출액>
@@ -280,7 +276,7 @@ def growth(client, code: str) -> Tuple[int, int]:
280
276
  Returns:
281
277
  tuple : 매출액증가율, 영업이익률 평가 포인트
282
278
  """
283
- growth_dict = eval_growth(client, code)
279
+ growth_dict = analyser_redis.growth(code)
284
280
 
285
281
  logger.debug(pprint.pformat(growth_dict, width=200))
286
282
 
@@ -288,7 +284,7 @@ def growth(client, code: str) -> Tuple[int, int]:
288
284
  # 매출액은 어떤경우에도 성장하는 기업이 좋다.매출이 20%씩 늘어나는 종목은 유망한 종목
289
285
  MAX = 20
290
286
  최근매출액증가율q, dict_y = 매출액증가율
291
- _, 최근매출액증가율y = mongo.Corps.latest_value(dict_y)
287
+ _, 최근매출액증가율y = mymongo.C1034.latest_dict_value(dict_y)
292
288
 
293
289
  # 최근 자료가 성장하는 중인지 판단
294
290
  if math.isnan(최근매출액증가율q):
@@ -342,7 +338,7 @@ def growth(client, code: str) -> Tuple[int, int]:
342
338
  def 영업이익률평가(영업이익률: dict) -> int:
343
339
  # 영업이익률은 기업의 경쟁력척도로 경쟁사에 비해 높으면 경제적해자를 갖춘셈
344
340
  영업이익률 = copy.deepcopy(영업이익률)
345
- name = mongo.Corps.get_name(client, code)
341
+ name = myredis.Corps.get_name(code)
346
342
 
347
343
  p = 0
348
344
  try: