analyser_hj3415 2.6.6__py2.py3-none-any.whl → 2.7.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/cli.py +111 -41
- analyser_hj3415/eval.py +948 -0
- analyser_hj3415/workroom/__init__.py +0 -0
- analyser_hj3415/workroom/lstm.py +113 -0
- analyser_hj3415/workroom/myprophet.py +58 -0
- analyser_hj3415/workroom/mysklearn.py +50 -0
- analyser_hj3415/workroom/mysklearn2.py +39 -0
- analyser_hj3415/{analysers → workroom}/score.py +1 -52
- {analyser_hj3415-2.6.6.dist-info → analyser_hj3415-2.7.0.dist-info}/METADATA +3 -3
- analyser_hj3415-2.7.0.dist-info/RECORD +16 -0
- analyser_hj3415/analysers/eval.py +0 -274
- analyser_hj3415/analysers/report.py +0 -182
- analyser_hj3415/myredis.py +0 -187
- analyser_hj3415/tools.py +0 -247
- analyser_hj3415-2.6.6.dist-info/RECORD +0 -14
- /analyser_hj3415/{trash.py → workroom/trash.py} +0 -0
- {analyser_hj3415-2.6.6.dist-info → analyser_hj3415-2.7.0.dist-info}/LICENSE +0 -0
- {analyser_hj3415-2.6.6.dist-info → analyser_hj3415-2.7.0.dist-info}/WHEEL +0 -0
- {analyser_hj3415-2.6.6.dist-info → analyser_hj3415-2.7.0.dist-info}/entry_points.txt +0 -0
File without changes
|
@@ -0,0 +1,113 @@
|
|
1
|
+
import yfinance as yf
|
2
|
+
import numpy as np
|
3
|
+
import pandas as pd
|
4
|
+
from sklearn.preprocessing import MinMaxScaler
|
5
|
+
from tensorflow.keras.models import Sequential
|
6
|
+
from tensorflow.keras.layers import LSTM, Dense, Dropout
|
7
|
+
import matplotlib.pyplot as plt
|
8
|
+
|
9
|
+
# 1. 데이터 다운로드 (애플 주식 데이터를 사용)
|
10
|
+
#stock_data = yf.download('AAPL', start='2020-01-01', end='2023-01-01')
|
11
|
+
# 삼성전자 주식 데이터 가져오기 (KOSPI 상장)
|
12
|
+
#stock_data = yf.download('005930.KS', start='2019-01-01', end='2024-10-10')
|
13
|
+
# 크래프톤 주식 데이터 가져오기 (KOSPI 상장)
|
14
|
+
#stock_data = yf.download('259960.KS', start='2020-01-01', end='2024-10-08')
|
15
|
+
# 하이닉스 주식 데이터 가져오기 (KOSPI 상장)
|
16
|
+
stock_data = yf.download('000660.KS', start='2019-01-01', end='2024-10-10')
|
17
|
+
|
18
|
+
|
19
|
+
# 2. 필요한 열만 선택 (종가만 사용)
|
20
|
+
data = stock_data['Close'].values.reshape(-1, 1)
|
21
|
+
|
22
|
+
# 3. 데이터 정규화 (0과 1 사이로 스케일링)
|
23
|
+
scaler = MinMaxScaler(feature_range=(0, 1))
|
24
|
+
scaled_data = scaler.fit_transform(data)
|
25
|
+
|
26
|
+
# 4. 학습 데이터 생성
|
27
|
+
# 주가 데이터를 80%는 학습용, 20%는 테스트용으로 분리하는 코드
|
28
|
+
train_size = int(len(scaled_data) * 0.8)
|
29
|
+
train_data = scaled_data[:train_size]
|
30
|
+
test_data = scaled_data[train_size:]
|
31
|
+
|
32
|
+
|
33
|
+
# 학습 데이터에 대한 입력(X)과 출력(y)를 생성
|
34
|
+
def create_dataset(data, time_step=60):
|
35
|
+
X, y = [], []
|
36
|
+
for i in range(len(data) - time_step):
|
37
|
+
X.append(data[i:i + time_step, 0])
|
38
|
+
y.append(data[i + time_step, 0])
|
39
|
+
return np.array(X), np.array(y)
|
40
|
+
|
41
|
+
|
42
|
+
X_train, y_train = create_dataset(train_data)
|
43
|
+
X_test, y_test = create_dataset(test_data)
|
44
|
+
|
45
|
+
# LSTM 모델 입력을 위해 데이터를 3차원으로 변환
|
46
|
+
X_train = X_train.reshape(X_train.shape[0], X_train.shape[1], 1)
|
47
|
+
X_test = X_test.reshape(X_test.shape[0], X_test.shape[1], 1)
|
48
|
+
|
49
|
+
# 5. LSTM 모델 생성
|
50
|
+
model = Sequential()
|
51
|
+
model.add(LSTM(units=200, return_sequences=True, input_shape=(X_train.shape[1], 1)))
|
52
|
+
model.add(Dropout(0.2))
|
53
|
+
model.add(LSTM(units=100, return_sequences=False))
|
54
|
+
model.add(Dropout(0.2))
|
55
|
+
model.add(Dense(units=50))
|
56
|
+
model.add(Dropout(0.3))
|
57
|
+
model.add(Dense(units=1))
|
58
|
+
|
59
|
+
# 6. 모델 컴파일 및 학습
|
60
|
+
model.compile(optimizer='adam', loss='mean_squared_error')
|
61
|
+
model.fit(X_train, y_train, epochs=20, batch_size=32)
|
62
|
+
|
63
|
+
# 7. 테스트 데이터 예측
|
64
|
+
predictions = model.predict(X_test)
|
65
|
+
predictions = scaler.inverse_transform(predictions) # 스케일링 복원
|
66
|
+
|
67
|
+
# 8. 미래 30일 예측
|
68
|
+
# 마지막 60일간의 데이터를 기반으로 미래 30일을 예측
|
69
|
+
future_days = 30
|
70
|
+
last_60_days = test_data[-60:]
|
71
|
+
last_60_days = last_60_days.reshape(1, -1, 1)
|
72
|
+
|
73
|
+
future_predictions = []
|
74
|
+
for _ in range(future_days):
|
75
|
+
predicted_price = model.predict(last_60_days)
|
76
|
+
future_predictions.append(predicted_price[0][0])
|
77
|
+
|
78
|
+
# 예측값을 다시 입력으로 사용하여 새로운 예측을 만듦
|
79
|
+
predicted_price_reshaped = np.reshape(predicted_price, (1, 1, 1)) # 3D 배열로 변환
|
80
|
+
last_60_days = np.append(last_60_days[:, 1:, :], predicted_price_reshaped, axis=1)
|
81
|
+
|
82
|
+
# 예측된 주가를 다시 스케일링 복원
|
83
|
+
future_predictions = np.array(future_predictions).reshape(-1, 1)
|
84
|
+
future_predictions = scaler.inverse_transform(future_predictions)
|
85
|
+
|
86
|
+
# 9. 날짜 생성 (미래 예측 날짜)
|
87
|
+
last_date = stock_data.index[-1]
|
88
|
+
future_dates = pd.date_range(last_date, periods=future_days + 1).tolist()[1:]
|
89
|
+
|
90
|
+
# 10. 시각화
|
91
|
+
plt.figure(figsize=(10, 6))
|
92
|
+
|
93
|
+
# 실제 주가
|
94
|
+
plt.plot(stock_data.index, stock_data['Close'], label='Actual Price')
|
95
|
+
|
96
|
+
# 미래 주가 예측
|
97
|
+
plt.plot(future_dates, future_predictions, label='Future Predicted Price', linestyle='--')
|
98
|
+
|
99
|
+
plt.xlabel('Date')
|
100
|
+
plt.ylabel('Stock Price')
|
101
|
+
plt.legend()
|
102
|
+
plt.title('Apple Stock Price Prediction with LSTM')
|
103
|
+
plt.show()
|
104
|
+
|
105
|
+
# 8. 시각화
|
106
|
+
plt.figure(figsize=(10, 6))
|
107
|
+
plt.plot(stock_data.index[train_size + 60:], data[train_size + 60:], label='Actual Price')
|
108
|
+
plt.plot(stock_data.index[train_size + 60:], predictions, label='Predicted Price')
|
109
|
+
plt.xlabel('Date')
|
110
|
+
plt.ylabel('Price')
|
111
|
+
plt.legend()
|
112
|
+
plt.title('Apple Stock Price Prediction with LSTM')
|
113
|
+
plt.show()
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# prophet 사용 공부
|
2
|
+
|
3
|
+
import yfinance as yf
|
4
|
+
import pandas as pd
|
5
|
+
from prophet import Prophet
|
6
|
+
import matplotlib.pyplot as plt # Matplotlib 수동 임포트
|
7
|
+
|
8
|
+
|
9
|
+
# 애플 주식 데이터를 다운로드
|
10
|
+
#stock_data = yf.download('AAPL', start='2020-01-01', end='2024-10-09')
|
11
|
+
# 삼성전자 주식 데이터 가져오기 (KOSPI 상장)
|
12
|
+
#stock_data = yf.download('005930.KS', start='2020-01-01', end='2024-08-01')
|
13
|
+
# 크래프톤 주식 데이터 가져오기 (KOSPI 상장)
|
14
|
+
#stock_data = yf.download('259960.KS', start='2020-01-01', end='2024-10-08')
|
15
|
+
# 하이닉스 주식 데이터 가져오기 (KOSPI 상장)
|
16
|
+
stock_data = yf.download('000660.KS', start='2020-01-01', end='2024-10-08')
|
17
|
+
|
18
|
+
|
19
|
+
# Prophet이 사용할 수 있도록 데이터 준비
|
20
|
+
df = stock_data[['Close', 'Volume']].reset_index()
|
21
|
+
df.columns = ['ds', 'y', 'volume'] # Prophet의 형식에 맞게 열 이름 변경
|
22
|
+
|
23
|
+
from sklearn.preprocessing import StandardScaler
|
24
|
+
|
25
|
+
# 추가 변수를 정규화
|
26
|
+
scaler = StandardScaler()
|
27
|
+
df['volume_scaled'] = scaler.fit_transform(df[['volume']])
|
28
|
+
|
29
|
+
# Prophet 모델 생성 및 학습
|
30
|
+
model = Prophet()
|
31
|
+
|
32
|
+
# 정규화된 'volume_scaled' 변수를 외부 변수로 추가
|
33
|
+
model.add_regressor('volume_scaled')
|
34
|
+
|
35
|
+
model.fit(df)
|
36
|
+
|
37
|
+
# 향후 180일 동안의 주가 예측
|
38
|
+
future = model.make_future_dataframe(periods=180)
|
39
|
+
|
40
|
+
# 미래 데이터에 거래량 추가 (평균 거래량을 사용해 정규화)
|
41
|
+
future_volume = pd.DataFrame({'volume': [stock_data['Volume'].mean()] * len(future)})
|
42
|
+
future['volume_scaled'] = scaler.transform(future_volume[['volume']])
|
43
|
+
|
44
|
+
|
45
|
+
forecast = model.predict(future)
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
# 예측 결과 출력
|
50
|
+
print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail())
|
51
|
+
|
52
|
+
# 예측 결과 시각화 (Matplotlib 사용)
|
53
|
+
fig = model.plot(forecast)
|
54
|
+
|
55
|
+
# 추세 및 계절성 시각화
|
56
|
+
fig2 = model.plot_components(forecast)
|
57
|
+
|
58
|
+
plt.show() # 시각화 창 띄우기
|
@@ -0,0 +1,50 @@
|
|
1
|
+
import yfinance as yf
|
2
|
+
import numpy as np
|
3
|
+
import pandas as pd
|
4
|
+
from sklearn.model_selection import train_test_split
|
5
|
+
from sklearn.linear_model import LinearRegression
|
6
|
+
import matplotlib.pyplot as plt
|
7
|
+
|
8
|
+
# 1. 데이터 다운로드 (애플 주식 데이터를 사용)
|
9
|
+
# 데이터 기간: 2020년 1월 1일부터 2023년 1월 1일까지
|
10
|
+
#stock_data = yf.download('AAPL', start='2020-01-01', end='2023-01-01')
|
11
|
+
# 삼성전자 주식 데이터 가져오기 (KOSPI 상장)
|
12
|
+
stock_data = yf.download('005930.KS', start='2020-01-01', end='2024-08-01')
|
13
|
+
# 크래프톤 주식 데이터 가져오기 (KOSPI 상장)
|
14
|
+
#stock_data = yf.download('259960.KS', start='2020-01-01', end='2024-10-08')
|
15
|
+
|
16
|
+
# 2. 필요한 열만 선택 (종가만 사용)
|
17
|
+
df = stock_data[['Close']]
|
18
|
+
|
19
|
+
# 3. 주가 데이터를 시계열 데이터로 변환하여 예측
|
20
|
+
# 일자를 숫자로 변환 (날짜 자체는 예측 모델에 사용하기 어렵기 때문에 숫자로 변환)
|
21
|
+
df['Date'] = np.arange(len(df))
|
22
|
+
|
23
|
+
# 4. 독립 변수(X)와 종속 변수(y) 분리
|
24
|
+
X = df[['Date']] # 독립 변수 (날짜)
|
25
|
+
y = df['Close'] # 종속 변수 (주가)
|
26
|
+
|
27
|
+
# 5. 데이터를 학습용과 테스트용으로 분리 (80% 학습, 20% 테스트)
|
28
|
+
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
|
29
|
+
|
30
|
+
# 6. 선형 회귀 모델 생성 및 학습
|
31
|
+
model = LinearRegression()
|
32
|
+
model.fit(X_train, y_train)
|
33
|
+
|
34
|
+
# 7. 테스트 데이터를 사용하여 예측 수행
|
35
|
+
y_pred = model.predict(X_test)
|
36
|
+
|
37
|
+
# 8. 결과 시각화
|
38
|
+
plt.figure(figsize=(10, 6))
|
39
|
+
plt.scatter(X_train, y_train, color='blue', label='Training data') # 학습 데이터
|
40
|
+
plt.scatter(X_test, y_test, color='green', label='Test data') # 실제 테스트 데이터
|
41
|
+
plt.plot(X_test, y_pred, color='red', label='Predicted price') # 예측된 주가
|
42
|
+
plt.xlabel('Date (numeric)')
|
43
|
+
plt.ylabel('Stock Price (Close)')
|
44
|
+
plt.legend()
|
45
|
+
plt.title('Apple Stock Price Prediction')
|
46
|
+
plt.show()
|
47
|
+
|
48
|
+
# 9. 모델 평가 (R^2 스코어)
|
49
|
+
r2_score = model.score(X_test, y_test)
|
50
|
+
print(f"모델의 R^2 스코어: {r2_score:.2f}")
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# 필요한 라이브러리 불러오기
|
2
|
+
import numpy as np
|
3
|
+
from sklearn.linear_model import LinearRegression
|
4
|
+
from sklearn.model_selection import train_test_split
|
5
|
+
import matplotlib.pyplot as plt
|
6
|
+
|
7
|
+
# 1. 데이터 준비 (주택 면적, 가격)
|
8
|
+
# 예를 들어 면적에 따른 주택 가격 데이터 (면적: X, 가격: y)
|
9
|
+
X = np.array([[1500], [2000], [2500], [3000], [3500], [4000]]) # 면적 (단위: square feet)
|
10
|
+
y = np.array([300000, 400000, 500000, 600000, 700000, 800000]) # 가격 (단위: dollars)
|
11
|
+
|
12
|
+
# 2. 학습 데이터와 테스트 데이터를 나누기 (80% 학습, 20% 테스트)
|
13
|
+
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
|
14
|
+
|
15
|
+
# 3. 선형 회귀 모델 생성
|
16
|
+
model = LinearRegression()
|
17
|
+
|
18
|
+
# 4. 모델을 학습시키기 (train 데이터를 사용)
|
19
|
+
model.fit(X_train, y_train)
|
20
|
+
|
21
|
+
# 5. 테스트 데이터로 예측 수행
|
22
|
+
y_pred = model.predict(X_test)
|
23
|
+
|
24
|
+
# 6. 예측 결과 출력
|
25
|
+
print("실제 값:", y_test)
|
26
|
+
print("예측 값:", y_pred)
|
27
|
+
|
28
|
+
# 7. 시각화를 통해 학습 결과 확인
|
29
|
+
plt.scatter(X_train, y_train, color='blue', label='Training data') # 학습 데이터
|
30
|
+
plt.scatter(X_test, y_test, color='green', label='Test data') # 실제 값
|
31
|
+
plt.plot(X_test, y_pred, color='red', label='Prediction') # 예측된 값
|
32
|
+
plt.xlabel('House Size (square feet)')
|
33
|
+
plt.ylabel('Price (dollars)')
|
34
|
+
plt.legend()
|
35
|
+
plt.show()
|
36
|
+
|
37
|
+
# 9. 모델 평가 (R^2 스코어)
|
38
|
+
r2_score = model.score(X_test, y_test)
|
39
|
+
print(f"모델의 R^2 스코어: {r2_score:.2f}")
|
@@ -5,7 +5,6 @@ import copy
|
|
5
5
|
from typing import Tuple
|
6
6
|
|
7
7
|
from db_hj3415 import myredis, mymongo
|
8
|
-
from analyser_hj3415.analysers import eval
|
9
8
|
from utils_hj3415 import utils
|
10
9
|
|
11
10
|
import logging
|
@@ -18,43 +17,6 @@ logger.addHandler(ch)
|
|
18
17
|
logger.setLevel(logging.WARNING)
|
19
18
|
|
20
19
|
|
21
|
-
def cal_deviation(v1: float, v2: float) -> float:
|
22
|
-
"""
|
23
|
-
괴리율 구하는 공식
|
24
|
-
:param v1:
|
25
|
-
:param v2:
|
26
|
-
:return:
|
27
|
-
"""
|
28
|
-
try:
|
29
|
-
deviation = abs((v1 - v2) / v1) * 100
|
30
|
-
except ZeroDivisionError:
|
31
|
-
deviation = math.nan
|
32
|
-
return deviation
|
33
|
-
|
34
|
-
|
35
|
-
def red(code: str, expect_earn: float) -> int:
|
36
|
-
"""red price와 최근 주가의 괴리율 파악
|
37
|
-
|
38
|
-
Returns:
|
39
|
-
int : 주가와 red price 비교한 괴리율
|
40
|
-
"""
|
41
|
-
try:
|
42
|
-
recent_price = utils.to_int(myredis.C101(code).get_recent()['주가'])
|
43
|
-
except KeyError:
|
44
|
-
recent_price = float('nan')
|
45
|
-
return 0
|
46
|
-
|
47
|
-
red_price = eval.red(code, expect_earn)['red_price']
|
48
|
-
deviation = cal_deviation(recent_price, red_price)
|
49
|
-
if red_price < 0 or (recent_price >= red_price):
|
50
|
-
score = 0
|
51
|
-
else:
|
52
|
-
score = math.log10(deviation + 1) * 33 # desmos그래프상 33이 제일 적당한듯(최대100점에 가깝게)
|
53
|
-
|
54
|
-
#print(f"최근주가 : {recent_price}", f"red가격 : {red_price}", f"괴리율 : {utils.to_int(deviation)}", f"score : {utils.to_int(score)}")
|
55
|
-
|
56
|
-
return utils.to_int(score)
|
57
|
-
|
58
20
|
|
59
21
|
def mil(code: str, expect_earn: float) -> Tuple[int, int, int, int]:
|
60
22
|
"""
|
@@ -171,20 +133,6 @@ def blue(code: str) -> Tuple[int, int, int, int, int]:
|
|
171
133
|
tuple : 유동비율, 이자보상배율, 순부채비율, 순운전자본회전율, 재고자산회전율 평가 포인트
|
172
134
|
|
173
135
|
Notes:
|
174
|
-
<유동비율>
|
175
|
-
100미만이면 주의하나 현금흐름창출력이 좋으면 괜찮을수 있다.
|
176
|
-
만약 100%이하면 유동자산에 추정영업현금흐름을 더해서 다시계산해보아 기회를 준다.
|
177
|
-
<이자보상배율>
|
178
|
-
이자보상배율 영업이익/이자비용으로 1이면 자금사정빡빡 5이상이면 양호
|
179
|
-
<순운전자금회전율>
|
180
|
-
순운전자금 => 기업활동을 하기 위해 필요한 자금 (매출채권 + 재고자산 - 매입채무)
|
181
|
-
순운전자본회전율은 매출액/순운전자본으로 일정비율이 유지되는것이 좋으며 너무 작아지면 순운전자본이 많아졌다는 의미로 재고나 외상이 쌓인다는 뜻
|
182
|
-
<재고자산회전율>
|
183
|
-
재고자산회전율은 매출액/재고자산으로 회전율이 낮을수록 재고가 많다는 이야기이므로 불리 전년도등과 비교해서 큰차이 발생하면 알람.
|
184
|
-
재고자산회전율이 작아지면 재고가 쌓인다는뜻
|
185
|
-
<순부채비율>
|
186
|
-
부채비율은 업종마다 달라 일괄비교 어려우나 순부채 비율이 20%이하인것이 좋고 꾸준히 늘어나지 않는것이 좋다.
|
187
|
-
순부채 비율이 30%이상이면 좋치 않다.
|
188
136
|
"""
|
189
137
|
def _calc_point_with_std(data: dict) -> int:
|
190
138
|
"""표준편차를 통해 점수를 계산하는 내부 함수
|
@@ -285,6 +233,7 @@ def blue(code: str) -> Tuple[int, int, int, int, int]:
|
|
285
233
|
# 재고자산회전율이 작아지면 재고가 쌓인다는뜻
|
286
234
|
_, dict_y = 재고자산회전율
|
287
235
|
p = _calc_point_with_std(data=dict_y)
|
236
|
+
# 라이벌기업과 비교점수 추가
|
288
237
|
logger.debug(f'재고자산회전율평가 point : {p}')
|
289
238
|
return p
|
290
239
|
|
@@ -1,12 +1,12 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: analyser_hj3415
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.7.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: utils-hj3415>=2.
|
9
|
-
Requires-Dist: db-hj3415>=
|
8
|
+
Requires-Dist: utils-hj3415>=2.9.2
|
9
|
+
Requires-Dist: db-hj3415>=4.0.3
|
10
10
|
Project-URL: Home, https://www.hyungjin.kr
|
11
11
|
|
12
12
|
### analyser-hj3415
|
@@ -0,0 +1,16 @@
|
|
1
|
+
analyser_hj3415/.DS_Store,sha256=qr9-0FPn5CFKe6kEu8_dWCNhzQ0sN7bwQgffKsaJEEo,6148
|
2
|
+
analyser_hj3415/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
+
analyser_hj3415/cli.py,sha256=0_FNk0AUvnwQM1CFUOQKsbKj0bBf6AgbJ5xLjP_tXM8,11017
|
4
|
+
analyser_hj3415/eval.py,sha256=LNOa6ryDuC1lylEh5dNjOUvtS6yD9qdlGadKugZ9S-k,38258
|
5
|
+
analyser_hj3415/workroom/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
|
+
analyser_hj3415/workroom/lstm.py,sha256=O_VYURGNsLw6q_7Yi0nH4Y6nKbVBwzMojDN446cyJKM,4078
|
7
|
+
analyser_hj3415/workroom/myprophet.py,sha256=xGbs4_cCeSNAX62H6rG-bUz6_rUOyO6787WAjLexMkw,1855
|
8
|
+
analyser_hj3415/workroom/mysklearn.py,sha256=wJXKz5MqqTzADdG2mqRMMzc_G9RzwYjj5_j4gyOopxQ,2030
|
9
|
+
analyser_hj3415/workroom/mysklearn2.py,sha256=1lIy6EWEQHkOzDS-av8U0zQH6DuCLKWMI73dnJx5KRs,1495
|
10
|
+
analyser_hj3415/workroom/score.py,sha256=P6nHBJYmyhigGtT4qna4BmNtvt4B93b7SKyzdstJK24,17376
|
11
|
+
analyser_hj3415/workroom/trash.py,sha256=zF-W0piqkGr66UP6-iybo9EXh2gO0RP6R1FnIpsGkl8,12262
|
12
|
+
analyser_hj3415-2.7.0.dist-info/entry_points.txt,sha256=ZfjPnJuH8SzvhE9vftIPMBIofsc65IAWYOhqOC_L5ck,65
|
13
|
+
analyser_hj3415-2.7.0.dist-info/LICENSE,sha256=QVKTp0dTnB5xG8RLgG17LwSWCKNEzYoVVM6KjoCPKc0,1079
|
14
|
+
analyser_hj3415-2.7.0.dist-info/WHEEL,sha256=Sgu64hAMa6g5FdzHxXv9Xdse9yxpGGMeagVtPMWpJQY,99
|
15
|
+
analyser_hj3415-2.7.0.dist-info/METADATA,sha256=V7gUQ_Hry-bpBiaXZOqMMBY-5aGtgEJKYDoJtGoU9hs,6417
|
16
|
+
analyser_hj3415-2.7.0.dist-info/RECORD,,
|
@@ -1,274 +0,0 @@
|
|
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
|
-
def red(code: str, expect_earn: float) -> dict:
|
20
|
-
"""
|
21
|
-
리턴값
|
22
|
-
{
|
23
|
-
'red_price': red_price,
|
24
|
-
'사업가치': 사업가치,
|
25
|
-
'재산가치': 재산가치,
|
26
|
-
'부채평가': 부채평가,
|
27
|
-
'발행주식수': 발행주식수,
|
28
|
-
'date': [각 유효한 값의 년월값 리스트(ex- 2020/09)],
|
29
|
-
}
|
30
|
-
"""
|
31
|
-
c103q = myredis.C103(code, 'c103재무상태표q')
|
32
|
-
|
33
|
-
d1, 지배주주당기순이익 = tools.calc당기순이익(code)
|
34
|
-
# print("지배주주당기순이익: ", 지배주주당기순이익)
|
35
|
-
d2, 유동자산 = tools.calc유동자산(code)
|
36
|
-
d3, 유동부채 = tools.calc유동부채(code)
|
37
|
-
d4, 부채평가 = tools.calc비유동부채(code)
|
38
|
-
|
39
|
-
c103q.page = 'c103재무상태표q'
|
40
|
-
d5, 투자자산 = c103q.latest_value_pop2('투자자산')
|
41
|
-
d6, 투자부동산 = c103q.latest_value_pop2('투자부동산')
|
42
|
-
|
43
|
-
# 사업가치 계산 - 지배주주지분 당기순이익 / 기대수익률
|
44
|
-
사업가치 = round(utils.nan_to_zero(지배주주당기순이익) / expect_earn, 2)
|
45
|
-
|
46
|
-
# 재산가치 계산 - 유동자산 - (유동부채*1.2) + 고정자산중 투자자산
|
47
|
-
재산가치 = round(유동자산 - (유동부채 * 1.2) + utils.nan_to_zero(투자자산) + utils.nan_to_zero(투자부동산), 2)
|
48
|
-
|
49
|
-
_, 발행주식수 = c103q.latest_value_pop2('발행주식수')
|
50
|
-
if math.isnan(발행주식수):
|
51
|
-
발행주식수 = utils.to_int(myredis.C101(code).get_recent().get('발행주식'))
|
52
|
-
else:
|
53
|
-
발행주식수 = 발행주식수 * 1000
|
54
|
-
|
55
|
-
try:
|
56
|
-
red_price = round(((사업가치 + 재산가치 - 부채평가) * 100000000) / 발행주식수)
|
57
|
-
except (ZeroDivisionError, ValueError) as e:
|
58
|
-
red_price = math.nan
|
59
|
-
|
60
|
-
logger.debug(f'Red Price : {red_price}원')
|
61
|
-
return {
|
62
|
-
'red_price': red_price,
|
63
|
-
'지배주주당기순이익': 지배주주당기순이익,
|
64
|
-
'사업가치': 사업가치,
|
65
|
-
'유동자산': 유동자산,
|
66
|
-
'유동부채': 유동부채,
|
67
|
-
'투자자산': 투자자산,
|
68
|
-
'투자부동산': 투자부동산,
|
69
|
-
'재산가치': 재산가치,
|
70
|
-
'부채평가': 부채평가,
|
71
|
-
'발행주식수': 발행주식수,
|
72
|
-
'EXPECT_EARN': expect_earn,
|
73
|
-
'date': tools.set_data(d1, d2, d3, d4, d5, d6), # ''값을 제거하고 리스트로 바꾼다.
|
74
|
-
}
|
75
|
-
|
76
|
-
|
77
|
-
def mil(code: str) -> dict:
|
78
|
-
"""
|
79
|
-
리턴값
|
80
|
-
{
|
81
|
-
'주주수익률': 주주수익률,
|
82
|
-
'이익지표': 이익지표,
|
83
|
-
'투자수익률': {'ROIC': roic, 'ROE': roe , 'ROE106': {}},
|
84
|
-
'가치지표': {'FCF': fcf_dict, 'PFCF': pfcf_dict, 'PCR': pcr_dict},
|
85
|
-
'date': [각 유효한 값의 년월값 리스트(ex- 2020/09)],
|
86
|
-
}
|
87
|
-
"""
|
88
|
-
c103q = myredis.C103(code, 'c103현금흐름표q')
|
89
|
-
c104q = myredis.C104(code, 'c104q')
|
90
|
-
c106q = myredis.C106(code, 'c106q')
|
91
|
-
|
92
|
-
marketcap억 = tools.get_marketcap(code) / 100000000
|
93
|
-
logger.debug(f'{code} market cap: {marketcap억}')
|
94
|
-
fcf_dict = tools.findFCF(code)
|
95
|
-
pfcf_dict = tools.findPFCF(code)
|
96
|
-
d1, 지배주주당기순이익 = tools.calc당기순이익(code)
|
97
|
-
|
98
|
-
d2, 재무활동현금흐름 = c103q.sum_recent_4q('재무활동으로인한현금흐름')
|
99
|
-
d3, 영업활동현금흐름 = c103q.sum_recent_4q('영업활동으로인한현금흐름')
|
100
|
-
|
101
|
-
d4, roic = c104q.sum_recent_4q('ROIC')
|
102
|
-
_, roic_dict = c104q.find_without_yoy('ROIC')
|
103
|
-
d5, roe = c104q.latest_value_pop2('ROE')
|
104
|
-
roe106 = c106q.find('ROE')
|
105
|
-
d6, roa = c104q.latest_value_pop2('ROA')
|
106
|
-
|
107
|
-
_, pcr_dict = c104q.find_without_yoy('PCR')
|
108
|
-
|
109
|
-
try:
|
110
|
-
주주수익률 = round((재무활동현금흐름 / marketcap억 * -100), 2)
|
111
|
-
이익지표 = round(((지배주주당기순이익 - 영업활동현금흐름) / marketcap억) * 100, 2)
|
112
|
-
except ZeroDivisionError:
|
113
|
-
주주수익률 = math.nan
|
114
|
-
이익지표 = math.nan
|
115
|
-
|
116
|
-
if math.isnan(주주수익률) or math.isnan(이익지표):
|
117
|
-
logger.warning(f'주주수익률: {주주수익률} 이익지표: {이익지표}')
|
118
|
-
logger.warning(f'재무활동현금흐름: {재무활동현금흐름} / 지배주주당기순이익: {지배주주당기순이익} / 영업활동현금흐름: {영업활동현금흐름}')
|
119
|
-
|
120
|
-
logger.debug(f'{code} fcf_dict : {fcf_dict}')
|
121
|
-
logger.debug(f"{code} market_cap : {marketcap억}")
|
122
|
-
logger.debug(f'{code} pfcf_dict : {pfcf_dict}')
|
123
|
-
logger.debug(f'{code} pcr_dict : {pcr_dict}')
|
124
|
-
|
125
|
-
return {
|
126
|
-
'주주수익률': 주주수익률,
|
127
|
-
'이익지표': 이익지표,
|
128
|
-
'재무활동현금흐름': 재무활동현금흐름,
|
129
|
-
'지배주주당기순이익': 지배주주당기순이익,
|
130
|
-
'영업활동현금흐름': 영업활동현금흐름,
|
131
|
-
'시가총액억': marketcap억,
|
132
|
-
'투자수익률': {'ROIC': roic, 'ROIC_dict': roic_dict, 'ROE': roe, 'ROE106': roe106, 'ROA': roa},
|
133
|
-
'가치지표': {'FCF': fcf_dict, 'PFCF': pfcf_dict, 'PCR': pcr_dict},
|
134
|
-
'date': tools.set_data(d1, d2, d3, d4, d5, d6),
|
135
|
-
}
|
136
|
-
|
137
|
-
|
138
|
-
def blue(code: str) -> dict:
|
139
|
-
"""
|
140
|
-
리턴값
|
141
|
-
{
|
142
|
-
'date': [각 유효한 값의 최근분기 값 리스트(ex- 2020/09)],
|
143
|
-
'순부채비율': (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}),
|
144
|
-
'순운전자본회전율': (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}),
|
145
|
-
'유동비율': 64.29,
|
146
|
-
'이자보상배율': (-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}),
|
147
|
-
'재고자산회전율': (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})
|
148
|
-
}
|
149
|
-
|
150
|
-
<유동비율>
|
151
|
-
100미만이면 주의하나 현금흐름창출력이 좋으면 괜찮을수 있다.
|
152
|
-
만약 100%이하면 유동자산에 추정영업현금흐름을 더해서 다시계산해보아 기회를 준다.
|
153
|
-
<이자보상배율>
|
154
|
-
이자보상배율 영업이익/이자비용으로 1이면 자금사정빡빡 5이상이면 양호
|
155
|
-
<순운전자금회전율>
|
156
|
-
순운전자금 => 기업활동을 하기 위해 필요한 자금 (매출채권 + 재고자산 - 매입채무)
|
157
|
-
순운전자본회전율은 매출액/순운전자본으로 일정비율이 유지되는것이 좋으며 너무 작아지면 순운전자본이 많아졌다는 의미로 재고나 외상이 쌓인다는 뜻
|
158
|
-
<재고자산회전율>
|
159
|
-
재고자산회전율은 매출액/재고자산으로 회전율이 낮을수록 재고가 많다는 이야기이므로 불리 전년도등과 비교해서 큰차이 발생하면 알람.
|
160
|
-
재고자산회전율이 작아지면 재고가 쌓인다는뜻
|
161
|
-
<순부채비율>
|
162
|
-
부채비율은 업종마다 달라 일괄비교 어려우나 순부채 비율이 20%이하인것이 좋고 꾸준히 늘어나지 않는것이 좋다.
|
163
|
-
순부채 비율이 30%이상이면 좋치 않다.
|
164
|
-
<매출액>
|
165
|
-
매출액은 어떤경우에도 성장하는 기업이 좋다.매출이 20%씩 늘어나는 종목은 유망한 종목
|
166
|
-
<영업이익률>
|
167
|
-
영업이익률은 기업의 경쟁력척도로 경쟁사에 비해 높으면 경제적해자를 갖춘셈
|
168
|
-
"""
|
169
|
-
|
170
|
-
d1, 유동비율 = tools.calc유동비율(code, pop_count=3)
|
171
|
-
logger.debug(f'유동비율 {유동비율} / [{d1}]')
|
172
|
-
|
173
|
-
c104y = myredis.C104(code, 'c104y')
|
174
|
-
_, dict이자보상배율y = c104y.find_without_yoy('이자보상배율')
|
175
|
-
_, dict순운전자본회전율y = c104y.find_without_yoy('순운전자본회전율')
|
176
|
-
_, dict재고자산회전율y = c104y.find_without_yoy('재고자산회전율')
|
177
|
-
_, dict순부채비율y = c104y.find_without_yoy('순부채비율')
|
178
|
-
|
179
|
-
c104q = myredis.C104(code, 'c104q')
|
180
|
-
d6, 이자보상배율q = c104q.latest_value_pop2('이자보상배율')
|
181
|
-
d7, 순운전자본회전율q = c104q.latest_value_pop2('순운전자본회전율')
|
182
|
-
d8, 재고자산회전율q = c104q.latest_value_pop2('재고자산회전율')
|
183
|
-
d9, 순부채비율q = c104q.latest_value_pop2('순부채비율')
|
184
|
-
|
185
|
-
if len(dict이자보상배율y) == 0:
|
186
|
-
logger.warning(f'empty dict - 이자보상배율 : {이자보상배율q} {dict이자보상배율y}')
|
187
|
-
|
188
|
-
if len(dict순운전자본회전율y) == 0:
|
189
|
-
logger.warning(f'empty dict - 순운전자본회전율 : {순운전자본회전율q} {dict순운전자본회전율y}')
|
190
|
-
|
191
|
-
if len(dict재고자산회전율y) == 0:
|
192
|
-
logger.warning(f'empty dict - 재고자산회전율 : {재고자산회전율q} {dict재고자산회전율y}')
|
193
|
-
|
194
|
-
if len(dict순부채비율y) == 0:
|
195
|
-
logger.warning(f'empty dict - 순부채비율 : {순부채비율q} {dict순부채비율y}')
|
196
|
-
|
197
|
-
################################################################
|
198
|
-
|
199
|
-
return {
|
200
|
-
'유동비율': 유동비율,
|
201
|
-
'이자보상배율': (이자보상배율q, dict이자보상배율y),
|
202
|
-
'순운전자본회전율': (순운전자본회전율q, dict순운전자본회전율y),
|
203
|
-
'재고자산회전율': (재고자산회전율q, dict재고자산회전율y),
|
204
|
-
'순부채비율': (순부채비율q, dict순부채비율y),
|
205
|
-
'date': tools.set_data(d1, d6, d7, d8, d9), # ''값을 제거하고 리스트로 바꾼다.
|
206
|
-
}
|
207
|
-
|
208
|
-
|
209
|
-
def growth(code: str) -> dict:
|
210
|
-
"""
|
211
|
-
리턴값
|
212
|
-
{'date': [각 유효한 값의 최근분기 값 리스트(ex- 2020/09)],
|
213
|
-
'매출액증가율': (-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}),
|
214
|
-
'영업이익률': {'뉴프렉스': '17.36', '동일기연': '13.58', '비에이치': '16.23', '에이엔피': '-9.30', '이브이첨단소재': '-4.93'}}
|
215
|
-
|
216
|
-
<매출액>
|
217
|
-
매출액은 어떤경우에도 성장하는 기업이 좋다.매출이 20%씩 늘어나는 종목은 유망한 종목
|
218
|
-
<영업이익률>
|
219
|
-
영업이익률은 기업의 경쟁력척도로 경쟁사에 비해 높으면 경제적해자를 갖춘셈
|
220
|
-
"""
|
221
|
-
c104y = myredis.C104(code, 'c104y')
|
222
|
-
c106y = myredis.C106(code, 'c106y')
|
223
|
-
|
224
|
-
_, dict매출액증가율y = c104y.find_without_yoy('매출액증가율')
|
225
|
-
|
226
|
-
c104q = myredis.C104(code, 'c104q')
|
227
|
-
d2, 매출액증가율q = c104q.latest_value_pop2('매출액증가율')
|
228
|
-
|
229
|
-
logger.debug(f'매출액증가율 : {매출액증가율q} {dict매출액증가율y}')
|
230
|
-
|
231
|
-
################################################################
|
232
|
-
|
233
|
-
# c106 에서 타 기업과 영업이익률 비교
|
234
|
-
dict영업이익률 = c106y.find('영업이익률')
|
235
|
-
|
236
|
-
return {
|
237
|
-
'매출액증가율': (매출액증가율q, dict매출액증가율y),
|
238
|
-
'영업이익률': dict영업이익률,
|
239
|
-
'date': [d2, ]}
|
240
|
-
|
241
|
-
|
242
|
-
"""
|
243
|
-
- 각분기의 합이 연이 아닌 타이틀(즉 sum_4q를 사용하면 안됨)
|
244
|
-
'*(지배)당기순이익'
|
245
|
-
'*(비지배)당기순이익'
|
246
|
-
'장기차입금'
|
247
|
-
'현금및예치금'
|
248
|
-
'매도가능금융자산'
|
249
|
-
'매도파생결합증권'
|
250
|
-
'만기보유금융자산'
|
251
|
-
'당기손익-공정가치측정금융부채'
|
252
|
-
'당기손익인식(지정)금융부채'
|
253
|
-
'단기매매금융자산'
|
254
|
-
'단기매매금융부채'
|
255
|
-
'예수부채'
|
256
|
-
'차입부채'
|
257
|
-
'기타부채'
|
258
|
-
'보험계약부채(책임준비금)'
|
259
|
-
'*CAPEX'
|
260
|
-
'ROE'
|
261
|
-
"""
|
262
|
-
|
263
|
-
"""
|
264
|
-
- sum_4q를 사용해도 되는 타이틀
|
265
|
-
'자산총계'
|
266
|
-
'당기순이익'
|
267
|
-
'유동자산'
|
268
|
-
'유동부채'
|
269
|
-
'비유동부채'
|
270
|
-
|
271
|
-
'영업활동으로인한현금흐름'
|
272
|
-
'재무활동으로인한현금흐름'
|
273
|
-
'ROIC'
|
274
|
-
"""
|