analyser_hj3415 2.1.0__tar.gz → 2.3.0__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/PKG-INFO +1 -1
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/analyser_hj3415/analysers/score.py +2 -2
- analyser_hj3415-2.3.0/analyser_hj3415/myredis.py +179 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/pyproject.toml +1 -1
- analyser_hj3415-2.3.0/tests/_trial_temp/test.log +1 -0
- analyser_hj3415-2.3.0/tests/testmyredis.py +58 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/tests/testscore.py +6 -0
- analyser_hj3415-2.1.0/tests/_trial_temp/test.log +0 -1
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/.DS_Store +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/.gitattributes +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/.gitignore +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/.idea/.gitignore +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/.idea/analyser-hj3415.iml +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/.idea/inspectionProfiles/profiles_settings.xml +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/.idea/misc.xml +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/.idea/modules.xml +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/.idea/vcs.xml +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/LICENSE +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/README.md +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/analyser_hj3415/.DS_Store +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/analyser_hj3415/__init__.py +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/analyser_hj3415/analysers/eval.py +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/analyser_hj3415/analysers/report.py +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/analyser_hj3415/cli.py +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/analyser_hj3415/run.py +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/analyser_hj3415/tools.py +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/analyser_hj3415/trash.py +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/tests/_trial_temp/_trial_marker +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/tests/testeval.py +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/tests/testreport.py +0 -0
- {analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/tests/testtools.py +0 -0
@@ -87,7 +87,7 @@ def mil(code: str) -> Tuple[int, int, int, int]:
|
|
87
87
|
"""
|
88
88
|
mil_dict = eval.mil(code)
|
89
89
|
|
90
|
-
print(pprint.pformat(mil_dict, width=200))
|
90
|
+
# print(pprint.pformat(mil_dict, width=200))
|
91
91
|
|
92
92
|
# 주주수익률 평가
|
93
93
|
if math.isnan(mil_dict['주주수익률']):
|
@@ -180,7 +180,7 @@ def blue(code: str) -> Tuple[int, int, int, int, int]:
|
|
180
180
|
|
181
181
|
blue_dict = eval.blue(code)
|
182
182
|
|
183
|
-
print(pprint.pformat(blue_dict, width=200))
|
183
|
+
# print(pprint.pformat(blue_dict, width=200))
|
184
184
|
|
185
185
|
def 유동비율평가(유동비율: float) -> int:
|
186
186
|
# 채점은 0을 기준으로 마이너스 해간다. 즉 0이 제일 좋은 상태임.
|
@@ -0,0 +1,179 @@
|
|
1
|
+
from analyser_hj3415.analysers import eval, score
|
2
|
+
from db_hj3415.myredis import Base
|
3
|
+
import json
|
4
|
+
|
5
|
+
page = '.analyser'
|
6
|
+
|
7
|
+
|
8
|
+
def red_n_score(code: str) -> dict:
|
9
|
+
"""
|
10
|
+
redis 사용 - 소멸타이머 사용
|
11
|
+
리턴값
|
12
|
+
{
|
13
|
+
'red_price': red_price,
|
14
|
+
'사업가치': 사업가치,
|
15
|
+
'재산가치': 재산가치,
|
16
|
+
'부채평가': 부채평가,
|
17
|
+
'발행주식수': 발행주식수,
|
18
|
+
'date': [각 유효한 값의 년월값 리스트(ex- 2020/09)],
|
19
|
+
}
|
20
|
+
"""
|
21
|
+
redis_name = code + page + '_eval_' + 'red'
|
22
|
+
try:
|
23
|
+
cached_data = Base.redis_client.get(redis_name).decode('utf-8')
|
24
|
+
except AttributeError:
|
25
|
+
# redis에 해당하는 값이 없는 경우
|
26
|
+
data = eval.red(code)
|
27
|
+
data['score'] = score.red(code)
|
28
|
+
# print(data)
|
29
|
+
if data:
|
30
|
+
# 데이터를 Redis에 캐싱
|
31
|
+
Base.redis_client.set(redis_name, json.dumps(data))
|
32
|
+
# 60분후 키가 자동으로 제거됨
|
33
|
+
Base.redis_client.expire(redis_name, 3600)
|
34
|
+
print("analysers.eval 데이터 계산하기 - myredis.red")
|
35
|
+
return data
|
36
|
+
else:
|
37
|
+
print(f"Redis 캐시에서 데이터 가져오기(남은시간:{Base.redis_client.ttl(redis_name)}초) - myredis.red")
|
38
|
+
return json.loads(cached_data)
|
39
|
+
|
40
|
+
|
41
|
+
def mil_n_score(code: str) -> dict:
|
42
|
+
"""
|
43
|
+
redis 사용 - 소멸타이머 사용
|
44
|
+
리턴값
|
45
|
+
{
|
46
|
+
'주주수익률': 주주수익률,
|
47
|
+
'이익지표': 이익지표,
|
48
|
+
'투자수익률': {'ROIC': roic, 'ROE': roe , 'ROE106': {}},
|
49
|
+
'가치지표': {'FCF': fcf_dict, 'PFCF': pfcf_dict, 'PCR': pcr_dict},
|
50
|
+
'date': [각 유효한 값의 년월값 리스트(ex- 2020/09)],
|
51
|
+
}
|
52
|
+
|
53
|
+
- 재무활동현금흐름이 마이너스라는 것은 배당급 지급했거나, 자사주 매입했거나, 부채를 상환한 상태임.
|
54
|
+
- 반대는 채권자로 자금을 조달했거나 신주를 발행했다는 의미
|
55
|
+
<주주수익률> - 재무활동현금흐름/시가총액 => 5%이상인가?
|
56
|
+
|
57
|
+
투하자본수익률(ROIC)가 30%이상인가
|
58
|
+
ROE(자기자본이익률) 20%이상이면 아주 우수 다른 투자이익률과 비교해볼것 10%미만이면 별로...단, 부채비율을 확인해야함.
|
59
|
+
|
60
|
+
이익지표 ...영업현금흐름이 순이익보다 많은가 - 결과값이 음수인가..
|
61
|
+
|
62
|
+
FCF는 영업현금흐름에서 자본적 지출(유·무형투자 비용)을 차감한 순수한 현금력이라 할 수 있다.
|
63
|
+
말 그대로 자유롭게(Free) 사용할 수 있는 여윳돈을 뜻한다.
|
64
|
+
잉여현금흐름이 플러스라면 미래의 투자나 채무상환에 쓸 재원이 늘어난 것이다.
|
65
|
+
CAPEX(Capital expenditures)는 미래의 이윤을 창출하기 위해 지출된 비용을 말한다.
|
66
|
+
이는 기업이 고정자산을 구매하거나, 유효수명이 당회계년도를 초과하는 기존의 고정자산에 대한 투자에 돈이 사용될 때 발생한다.
|
67
|
+
|
68
|
+
잉여현금흐름이 마이너스일때는 설비투자가 많은 시기라 주가가 약세이며 이후 설비투자 마무리되면서 주가가 상승할수 있다.
|
69
|
+
주가는 잉여현금흐름이 증가할때 상승하는 경향이 있다.
|
70
|
+
fcf = 영업현금흐름 - capex
|
71
|
+
|
72
|
+
가치지표평가
|
73
|
+
price to fcf 계산
|
74
|
+
https://www.investopedia.com/terms/p/pricetofreecashflow.asp
|
75
|
+
pcr보다 정확하게 주식의 가치를 평가할수 있음. 10배이하 추천
|
76
|
+
"""
|
77
|
+
redis_name = code + page + '_eval_' + 'mil'
|
78
|
+
try:
|
79
|
+
cached_data = Base.redis_client.get(redis_name).decode('utf-8')
|
80
|
+
except AttributeError:
|
81
|
+
# redis에 해당하는 값이 없는 경우
|
82
|
+
data = eval.mil(code)
|
83
|
+
data['score'] = score.mil(code)
|
84
|
+
# print(data)
|
85
|
+
if data:
|
86
|
+
# 데이터를 Redis에 캐싱
|
87
|
+
Base.redis_client.set(redis_name, json.dumps(data))
|
88
|
+
# 60분후 키가 자동으로 제거됨
|
89
|
+
Base.redis_client.expire(redis_name, 3600)
|
90
|
+
print("analysers.eval 데이터 계산하기 - myredis.mil")
|
91
|
+
return data
|
92
|
+
else:
|
93
|
+
print(f"Redis 캐시에서 데이터 가져오기(남은시간:{Base.redis_client.ttl(redis_name)}초) - myredis.mil")
|
94
|
+
return json.loads(cached_data)
|
95
|
+
|
96
|
+
|
97
|
+
def blue_n_score(code: str) -> dict:
|
98
|
+
"""
|
99
|
+
redis 사용 - 소멸타이머 사용
|
100
|
+
리턴값
|
101
|
+
{
|
102
|
+
'date': [각 유효한 값의 최근분기 값 리스트(ex- 2020/09)],
|
103
|
+
'순부채비율': (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}),
|
104
|
+
'순운전자본회전율': (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}),
|
105
|
+
'유동비율': 64.29,
|
106
|
+
'이자보상배율': (-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}),
|
107
|
+
'재고자산회전율': (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})
|
108
|
+
}
|
109
|
+
|
110
|
+
<유동비율>
|
111
|
+
100미만이면 주의하나 현금흐름창출력이 좋으면 괜찮을수 있다.
|
112
|
+
만약 100%이하면 유동자산에 추정영업현금흐름을 더해서 다시계산해보아 기회를 준다.
|
113
|
+
<이자보상배율>
|
114
|
+
이자보상배율 영업이익/이자비용으로 1이면 자금사정빡빡 5이상이면 양호
|
115
|
+
<순운전자금회전율>
|
116
|
+
순운전자금 => 기업활동을 하기 위해 필요한 자금 (매출채권 + 재고자산 - 매입채무)
|
117
|
+
순운전자본회전율은 매출액/순운전자본으로 일정비율이 유지되는것이 좋으며 너무 작아지면 순운전자본이 많아졌다는 의미로 재고나 외상이 쌓인다는 뜻
|
118
|
+
<재고자산회전율>
|
119
|
+
재고자산회전율은 매출액/재고자산으로 회전율이 낮을수록 재고가 많다는 이야기이므로 불리 전년도등과 비교해서 큰차이 발생하면 알람.
|
120
|
+
재고자산회전율이 작아지면 재고가 쌓인다는뜻
|
121
|
+
<순부채비율>
|
122
|
+
부채비율은 업종마다 달라 일괄비교 어려우나 순부채 비율이 20%이하인것이 좋고 꾸준히 늘어나지 않는것이 좋다.
|
123
|
+
순부채 비율이 30%이상이면 좋치 않다.
|
124
|
+
<매출액>
|
125
|
+
매출액은 어떤경우에도 성장하는 기업이 좋다.매출이 20%씩 늘어나는 종목은 유망한 종목
|
126
|
+
<영업이익률>
|
127
|
+
영업이익률은 기업의 경쟁력척도로 경쟁사에 비해 높으면 경제적해자를 갖춘셈
|
128
|
+
"""
|
129
|
+
redis_name = code + page + '_eval_' + 'blue'
|
130
|
+
try:
|
131
|
+
cached_data = Base.redis_client.get(redis_name).decode('utf-8')
|
132
|
+
except AttributeError:
|
133
|
+
# redis에 해당하는 값이 없는 경우
|
134
|
+
data = eval.blue(code)
|
135
|
+
data['score'] = score.blue(code)
|
136
|
+
# print(data)
|
137
|
+
if data:
|
138
|
+
# 데이터를 Redis에 캐싱
|
139
|
+
Base.redis_client.set(redis_name, json.dumps(data))
|
140
|
+
# 60분후 키가 자동으로 제거됨
|
141
|
+
Base.redis_client.expire(redis_name, 3600)
|
142
|
+
print("analysers.eval 데이터 계산하기 - myredis.blue")
|
143
|
+
return data
|
144
|
+
else:
|
145
|
+
print(f"Redis 캐시에서 데이터 가져오기(남은시간:{Base.redis_client.ttl(redis_name)}초) - myredis.blue")
|
146
|
+
return json.loads(cached_data)
|
147
|
+
|
148
|
+
|
149
|
+
def growth_n_score(code: str) -> dict:
|
150
|
+
"""
|
151
|
+
redis 사용 - 소멸타이머 사용
|
152
|
+
리턴값
|
153
|
+
{'date': [각 유효한 값의 최근분기 값 리스트(ex- 2020/09)],
|
154
|
+
'매출액증가율': (-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}),
|
155
|
+
'영업이익률': {'뉴프렉스': '17.36', '동일기연': '13.58', '비에이치': '16.23', '에이엔피': '-9.30', '이브이첨단소재': '-4.93'}}
|
156
|
+
|
157
|
+
<매출액>
|
158
|
+
매출액은 어떤경우에도 성장하는 기업이 좋다.매출이 20%씩 늘어나는 종목은 유망한 종목
|
159
|
+
<영업이익률>
|
160
|
+
영업이익률은 기업의 경쟁력척도로 경쟁사에 비해 높으면 경제적해자를 갖춘셈
|
161
|
+
"""
|
162
|
+
redis_name = code + page + '_eval_' + 'growth'
|
163
|
+
try:
|
164
|
+
cached_data = Base.redis_client.get(redis_name).decode('utf-8')
|
165
|
+
except AttributeError:
|
166
|
+
# redis에 해당하는 값이 없는 경우
|
167
|
+
data = eval.growth(code)
|
168
|
+
data['score'] = score.growth(code)
|
169
|
+
# print(data)
|
170
|
+
if data:
|
171
|
+
# 데이터를 Redis에 캐싱
|
172
|
+
Base.redis_client.set(redis_name, json.dumps(data))
|
173
|
+
# 60분후 키가 자동으로 제거됨
|
174
|
+
Base.redis_client.expire(redis_name, 3600)
|
175
|
+
print("analysers.eval 데이터 계산하기 - myredis.growth")
|
176
|
+
return data
|
177
|
+
else:
|
178
|
+
print(f"Redis 캐시에서 데이터 가져오기(남은시간:{Base.redis_client.ttl(redis_name)}초) - myredis.growth")
|
179
|
+
return json.loads(cached_data)
|
@@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "analyser_hj3415"
|
7
|
-
version = "2.
|
7
|
+
version = "2.3.0"
|
8
8
|
authors = [{name = "Hyungjin Kim", email = "hj3415@gmail.com"}]
|
9
9
|
description = "Stock analyser and database processing programs"
|
10
10
|
readme = "README.md"
|
@@ -0,0 +1 @@
|
|
1
|
+
2024-08-21 16:23:57+0900 [-] Log opened.
|
@@ -0,0 +1,58 @@
|
|
1
|
+
import time
|
2
|
+
import unittest
|
3
|
+
import pprint
|
4
|
+
import random
|
5
|
+
from analyser_hj3415 import myredis
|
6
|
+
from db_hj3415 import cli
|
7
|
+
from db_hj3415.myredis import Corps
|
8
|
+
print("테스트용 서버로 주소 설정")
|
9
|
+
cli.save_mongo_addr('mongodb://hj3415:piyrw421@192.168.100.175:27017')
|
10
|
+
cli.save_redis_addr('192.168.100.175')
|
11
|
+
|
12
|
+
|
13
|
+
class MyredisTests(unittest.TestCase):
|
14
|
+
def setUp(self):
|
15
|
+
self.test_codes = Corps.list_all_codes()
|
16
|
+
|
17
|
+
def tearDown(self):
|
18
|
+
pass
|
19
|
+
|
20
|
+
def test_red_n_score(self):
|
21
|
+
test_one = random.choice(self.test_codes)
|
22
|
+
print(test_one, '/', Corps.get_name(test_one))
|
23
|
+
pprint.pprint(myredis.red_n_score(test_one))
|
24
|
+
|
25
|
+
time.sleep(2)
|
26
|
+
|
27
|
+
print(test_one, '/', Corps.get_name(test_one))
|
28
|
+
pprint.pprint(myredis.red_n_score(test_one))
|
29
|
+
|
30
|
+
def test_mil_n_score(self):
|
31
|
+
test_one = random.choice(self.test_codes)
|
32
|
+
print(test_one, '/', Corps.get_name(test_one))
|
33
|
+
pprint.pprint(myredis.mil_n_score(test_one))
|
34
|
+
|
35
|
+
time.sleep(2)
|
36
|
+
|
37
|
+
print(test_one, '/', Corps.get_name(test_one))
|
38
|
+
pprint.pprint(myredis.mil_n_score(test_one))
|
39
|
+
|
40
|
+
def test_blue_n_score(self):
|
41
|
+
test_one = random.choice(self.test_codes)
|
42
|
+
print(test_one, '/', Corps.get_name(test_one))
|
43
|
+
pprint.pprint(myredis.blue_n_score(test_one))
|
44
|
+
|
45
|
+
time.sleep(2)
|
46
|
+
|
47
|
+
print(test_one, '/', Corps.get_name(test_one))
|
48
|
+
pprint.pprint(myredis.blue_n_score(test_one))
|
49
|
+
|
50
|
+
def test_growth_n_score(self):
|
51
|
+
test_one = random.choice(self.test_codes)
|
52
|
+
print(test_one, '/', Corps.get_name(test_one))
|
53
|
+
pprint.pprint(myredis.growth_n_score(test_one))
|
54
|
+
|
55
|
+
time.sleep(2)
|
56
|
+
|
57
|
+
print(test_one, '/', Corps.get_name(test_one))
|
58
|
+
pprint.pprint(myredis.growth_n_score(test_one))
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import time
|
1
2
|
import unittest
|
2
3
|
import random
|
3
4
|
|
@@ -21,6 +22,11 @@ class ScoreTests(unittest.TestCase):
|
|
21
22
|
print(test_one, '/', myredis.Corps.get_name(test_one))
|
22
23
|
print(score.red(test_one))
|
23
24
|
|
25
|
+
time.sleep(1)
|
26
|
+
|
27
|
+
print(test_one, '/', myredis.Corps.get_name(test_one))
|
28
|
+
print(score.red(test_one))
|
29
|
+
|
24
30
|
def test_red_all(self):
|
25
31
|
print(f'Totol {len(self.test_codes)} items')
|
26
32
|
for i, code in enumerate(self.test_codes):
|
@@ -1 +0,0 @@
|
|
1
|
-
2024-08-19 11:31:37+0900 [-] Log opened.
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{analyser_hj3415-2.1.0 → analyser_hj3415-2.3.0}/.idea/inspectionProfiles/profiles_settings.xml
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|