analyser_hj3415 4.5.3__py3-none-any.whl → 4.6.0__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.
@@ -139,16 +139,17 @@ class Blue:
139
139
  except ZeroDivisionError:
140
140
  mylogger.info(f'유동자산: {유동자산value} + 추정영업현금흐름: {추정영업현금흐름value} / 유동부채: {유동부채value}')
141
141
  계산된유동비율 = float('inf')
142
- finally:
143
- mylogger.debug(f'{self} 계산된 유동비율 : {계산된유동비율}')
144
-
145
- try:
146
- date, *_ = Tools.date_set(유동자산date, 유동부채date, 추정영업현금흐름date)
147
- except ValueError:
148
- # 날짜 데이터가 없는경우
149
- date = ''
150
- mylogger.warning(f'{self} 유동비율 이상(100 이하 또는 nan) : {유동비율value} -> 재계산 : {계산된유동비율}')
151
- return date, 계산된유동비율
142
+
143
+ mylogger.debug(f'{self} 계산된 유동비율 : {계산된유동비율}')
144
+
145
+ try:
146
+ date, *_ = Tools.date_set(유동자산date, 유동부채date, 추정영업현금흐름date)
147
+ except ValueError:
148
+ # 날짜 데이터가 없는경우
149
+ date = ''
150
+
151
+ mylogger.warning(f'{self} 유동비율 이상(100 이하 또는 nan) : {유동비율value} -> 재계산 : {계산된유동비율}')
152
+ return date, 계산된유동비율
152
153
  else:
153
154
  return 유동비율date, 유동비율value
154
155
 
@@ -1,11 +1,26 @@
1
1
  import numpy as np
2
- from dataclasses import dataclass, field
3
- from typing import Optional
4
2
  import pandas as pd
5
- from marshmallow import fields
3
+ from dataclasses_json import config
4
+ from dataclasses import dataclass, field
5
+ from typing import Optional, List
6
+ from dataclasses_json import dataclass_json
7
+ from datetime import date
8
+ from dataclasses_json import config
9
+ from dataclasses import dataclass, field
10
+ from dataclasses_json import dataclass_json
6
11
 
7
12
 
8
13
  def is_up_by_OLS(data: dict) -> bool:
14
+ """
15
+ 주어진 데이터의 값들을 날짜 순으로 정렬한 후, 최소제곱법(OLS)을 이용해 선형 회귀 기울기를 계산합니다.
16
+ 데이터가 비어있거나 계산에 필요한 데이터 포인트(1개 이하)가 있는 경우에는 추세를 판단할 수 없으므로 False를 반환합니다.
17
+
18
+ Parameters:
19
+ data (dict): 날짜(문자열)를 키로, 해당 날짜의 값(숫자)을 값으로 하는 딕셔너리.
20
+
21
+ Returns:
22
+ bool: 계산된 기울기가 양수이면 True (우상향 추세), 그렇지 않으면 False.
23
+ """
9
24
  if not data:
10
25
  # 데이터가 비어있으면 추세를 판단할 수 없음
11
26
  return False
@@ -36,25 +51,90 @@ def is_up_by_OLS(data: dict) -> bool:
36
51
  # 4) 기울기가 양수면 "우상향 추세"로 판별
37
52
  return slope > 0
38
53
 
54
+
55
+ @dataclass
56
+ class LSTMGrade:
57
+ """
58
+ LSTM 모델 학습 결과를 평가하기 위한 데이터 클래스.
59
+
60
+ 속성:
61
+ ticker (str): 주식 티커(symbol).
62
+ train_mse (float): 학습 데이터에 대한 평균 제곱 오차(MSE).
63
+ train_mae (float): 학습 데이터에 대한 평균 절대 오차(MAE).
64
+ train_r2 (float): 학습 데이터에 대한 결정 계수(R²).
65
+ test_mse (float): 테스트 데이터에 대한 평균 제곱 오차(MSE).
66
+ test_mae (float): 테스트 데이터에 대한 평균 절대 오차(MAE).
67
+ test_r2 (float): 테스트 데이터에 대한 결정 계수(R²).
68
+ """
69
+ ticker: str
70
+ train_mse: float
71
+ train_mae: float
72
+ train_r2: float
73
+ test_mse: float
74
+ test_mae: float
75
+ test_r2: float
76
+
77
+
78
+ # ⓐ 단일 Timestamp ↔ ISO-8601 문자열
79
+ ts_enc = lambda ts: ts.isoformat()
80
+ ts_dec = lambda s: pd.Timestamp(s)
81
+
82
+ # ⓑ Timestamp 리스트 ↔ 문자열 리스트
83
+ list_enc = lambda seq: [ts.isoformat() for ts in seq]
84
+ list_dec = lambda seq: [pd.Timestamp(s) for s in seq]
85
+
86
+
87
+ @dataclass_json
88
+ @dataclass
89
+ class ChartPoint:
90
+ """prices 리스트의 각 원소(x, y)를 표현"""
91
+ x: pd.Timestamp = field(metadata=config(encoder=ts_enc, decoder=ts_dec))
92
+ y: Optional[float] = None
93
+
94
+
95
+ @dataclass_json
39
96
  @dataclass
40
- class PandasTimestampField(fields.DateTime):
41
- """pandas.Timestamp를 ISO 8601 문자열로 직렬화하고 역직렬화하는 필드"""
97
+ class ProphetChartData:
98
+ ticker: str
99
+
100
+ labels: List[pd.Timestamp] = field(metadata=config(encoder=list_enc, decoder=list_dec))
101
+ prices: List[ChartPoint]
102
+ yhats: List[ChartPoint]
103
+ yhat_uppers: List[ChartPoint]
104
+ yhat_lowers: List[ChartPoint]
42
105
 
43
- def __init__(self, *args, **kwargs):
44
- # 꼭 부모의 __init__을 호출해야 함
45
- super().__init__(*args, **kwargs)
106
+ is_prophet_up: bool
46
107
 
47
- def _serialize(self, value, attr, obj, **kwargs):
48
- return value.isoformat() if isinstance(value, pd.Timestamp) else None
49
108
 
50
- def _deserialize(self, value, attr, data, **kwargs):
51
- return pd.Timestamp(value)
109
+ # ISO-8601(YYYY-MM-DD) 포맷으로 직렬화·역직렬화
110
+ date_enc = lambda d: d.isoformat()
111
+ date_dec = lambda s: date.fromisoformat(s)
52
112
 
113
+
114
+ @dataclass_json
53
115
  @dataclass
54
- class ChartPoint:
55
- """prices 리스트의 각 원소(x, y)를 표현할 데이터 클래스"""
56
- x: pd.Timestamp = field(metadata={"marshmallow_field": PandasTimestampField()})
57
- y: Optional[float] = field(default=None, metadata={"marshmallow_field": fields.Float(allow_none=True)})
116
+ class LSTMChartData:
117
+ ticker: str
118
+
119
+ labels: List[pd.Timestamp] = field(metadata=config(encoder=list_enc, decoder=list_dec))
120
+ prices: List[ChartPoint]
121
+ future_prices: List[ChartPoint]
122
+ grade: LSTMGrade
123
+ num: int
124
+ is_lstm_up: bool
125
+
126
+
127
+ @dataclass_json
128
+ @dataclass
129
+ class ProphetLatestData:
130
+ ticker: str
58
131
 
132
+ date: date = field(metadata=config(encoder=date_enc, decoder=date_dec))
59
133
 
134
+ price: float
135
+ yhat: float
136
+ yhat_upper: float
137
+ yhat_lower: float
60
138
 
139
+ trading_action: str = ''
140
+ score: int | None = None
@@ -10,14 +10,13 @@ from tensorflow.keras.layers import LSTM, Dense, Dropout # type: ignore
10
10
  from tensorflow.keras.callbacks import EarlyStopping # type: ignore
11
11
  from tensorflow.keras import Input # type: ignore
12
12
  from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
13
- from dataclasses import dataclass, field
14
- from marshmallow import fields
13
+ from dataclasses import dataclass
15
14
 
16
15
  from utils_hj3415 import tools, setup_logger
17
16
  from db_hj3415 import myredis
18
17
  from db_hj3415.mymongo.flask import Favorites
19
18
  from analyser_hj3415.analyser import MIs, tsa
20
- from analyser_hj3415.analyser.tsa.common import PandasTimestampField, ChartPoint
19
+ from analyser_hj3415.analyser.tsa.common import LSTMChartData, LSTMGrade
21
20
 
22
21
  mylogger = setup_logger(__name__,'WARNING')
23
22
 
@@ -51,41 +50,6 @@ class LSTMData:
51
50
  y_test_1d: np.ndarray
52
51
 
53
52
 
54
- @dataclass
55
- class LSTMGrade:
56
- """
57
- LSTM 모델 학습 결과를 평가하기 위한 데이터 클래스.
58
-
59
- 속성:
60
- ticker (str): 주식 티커(symbol).
61
- train_mse (float): 학습 데이터에 대한 평균 제곱 오차(MSE).
62
- train_mae (float): 학습 데이터에 대한 평균 절대 오차(MAE).
63
- train_r2 (float): 학습 데이터에 대한 결정 계수(R²).
64
- test_mse (float): 테스트 데이터에 대한 평균 제곱 오차(MSE).
65
- test_mae (float): 테스트 데이터에 대한 평균 절대 오차(MAE).
66
- test_r2 (float): 테스트 데이터에 대한 결정 계수(R²).
67
- """
68
- ticker: str
69
- train_mse: float
70
- train_mae: float
71
- train_r2: float
72
- test_mse: float
73
- test_mae: float
74
- test_r2: float
75
-
76
-
77
- @dataclass
78
- class LSTMChartData:
79
- ticker: str
80
-
81
- labels: List[pd.Timestamp] = field(metadata={"marshmallow_field": fields.List(PandasTimestampField())})
82
- prices: List[ChartPoint]
83
- future_prices: List[ChartPoint]
84
- grade: LSTMGrade
85
- num: int
86
- is_lstm_up: bool
87
-
88
-
89
53
  class MyLSTM:
90
54
  """
91
55
  주가 데이터를 기반으로 LSTM 모델을 생성, 학습 및 예측하는 클래스.
@@ -7,44 +7,16 @@ import yfinance as yf
7
7
  import pandas as pd
8
8
  from prophet import Prophet
9
9
  from sklearn.preprocessing import StandardScaler
10
- from dataclasses import dataclass, field
11
- from marshmallow import fields
12
10
 
13
11
  from utils_hj3415 import tools, setup_logger
14
12
  from db_hj3415 import myredis
15
13
 
16
14
  from analyser_hj3415.analyser import eval, MIs, tsa
17
- from analyser_hj3415.analyser.tsa.common import PandasTimestampField, ChartPoint
15
+ from analyser_hj3415.analyser.tsa.common import ProphetChartData, ProphetLatestData
18
16
 
19
17
 
20
18
  mylogger = setup_logger(__name__,'WARNING')
21
19
 
22
- @dataclass
23
- class ProphetLatestData:
24
- ticker: str
25
-
26
- date: datetime.date = field(metadata={"marshmallow_field": fields.Date()})
27
- price: float
28
- yhat: float
29
- yhat_upper: float
30
- yhat_lower: float
31
-
32
- trading_action: str = ''
33
- score: int = None
34
-
35
-
36
- @dataclass
37
- class ProphetChartData:
38
- ticker: str
39
-
40
- labels: List[pd.Timestamp] = field(metadata={"marshmallow_field": fields.List(PandasTimestampField())})
41
- prices: List[ChartPoint]
42
- yhats: List[ChartPoint]
43
- yhat_uppers: List[ChartPoint]
44
- yhat_lowers: List[ChartPoint]
45
-
46
- is_prophet_up: bool
47
-
48
20
 
49
21
  class MyProphet:
50
22
 
@@ -123,15 +95,15 @@ class MyProphet:
123
95
  return data
124
96
  else:
125
97
  # 다운로드 자체는 성공했지만, 빈 데이터가 반환될 경우
126
- print(f"[{attempt}/{max_retries}] 다운로드 결과가 비어 있습니다. 재시도합니다...")
98
+ print(f"[{attempt}/{max_retries}] {self.ticker} 다운로드 결과가 비어 있습니다. 재시도합니다...")
127
99
  except Exception as e:
128
100
  # 예외 발생 시, 재시도
129
- print(f"[{attempt}/{max_retries}] 다운로드 실패: {e}. 재시도합니다...")
101
+ print(f"[{attempt}/{max_retries}] {self.ticker} 다운로드 실패: {e}. 재시도합니다...")
130
102
 
131
103
  # 재시도 전 대기
132
104
  time.sleep(delay_sec)
133
105
 
134
- mylogger.error(f"주가 데이터를 다운로드하지 못했습니다 (최대 {max_retries}회 시도 실패).")
106
+ mylogger.error(f"{self.ticker} 주가 데이터를 다운로드하지 못했습니다 (최대 {max_retries}회 시도 실패).")
135
107
  return pd.DataFrame()
136
108
 
137
109
  def preprocessing_for_prophet() -> pd.DataFrame:
@@ -197,7 +169,7 @@ class MyProphet:
197
169
  try:
198
170
  self.df_real = preprocessing_for_prophet()
199
171
  self.df_forecast = make_forecast()
200
- except ValueError as e:
172
+ except (ValueError, KeyError) as e:
201
173
  mylogger.error(f"{self.ticker} : 빈 데이터프레임...{e}")
202
174
  self.df_real = pd.DataFrame()
203
175
  self.df_forecast = pd.DataFrame()
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: analyser_hj3415
3
- Version: 4.5.3
3
+ Version: 4.6.0
4
4
  Summary: Stock analyser and database processing programs
5
5
  Requires-Python: >=3.6
6
6
  Description-Content-Type: text/markdown
@@ -12,7 +12,8 @@ Requires-Dist: yfinance>=0.2.54
12
12
  Requires-Dist: prophet>=1.1.6
13
13
  Requires-Dist: kaleido>=0.2.1
14
14
  Requires-Dist: matplotlib>=3.9.2
15
- Requires-Dist: marshmallow>=3.26.0
15
+ Requires-Dist: dataclasses_json>=0.6.7
16
+ Requires-Dist: pandas>=2.2.3
16
17
  Requires-Dist: tensorflow-macos>=2.16.2; platform_machine == 'arm64' and sys_platform == 'darwin'
17
18
  Requires-Dist: tensorflow-metal>=0.5.0; platform_machine == 'arm64' and sys_platform == 'darwin'
18
19
  Requires-Dist: tensorflow>=2.18.0; platform_machine != 'arm64' or sys_platform != 'darwin'
@@ -3,16 +3,16 @@ analyser_hj3415/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  analyser_hj3415/cli.py,sha256=drfh0cqZ0LUHUJMJeyXcv1QTD7VYJMr58gcY4WHsVk4,11956
4
4
  analyser_hj3415/analyser/__init__.py,sha256=N0XyBfWJNpDS_6JYziKETWePO_jtFB1m7E8Qbwt1w0Q,1096
5
5
  analyser_hj3415/analyser/eval/__init__.py,sha256=IP1d0Q3nOCAD3zK1qxrC685MkJQfUh-qaXc7xptTxk8,80
6
- analyser_hj3415/analyser/eval/blue.py,sha256=KBoKevikS74ys9zcVls6GaEdBkW-avcxHWkSPywOcPU,10644
6
+ analyser_hj3415/analyser/eval/blue.py,sha256=-t_9Tm2n8tfrPRDIDT9YU7EQLaFqPa89_7JS8wqVcfA,10593
7
7
  analyser_hj3415/analyser/eval/common.py,sha256=sNXapoofShA43ww_SLjXmIjkrAr1AhAcezdaN_X_3Us,11443
8
8
  analyser_hj3415/analyser/eval/growth.py,sha256=LunZcZvhly_2PWUZBbd0gW9ZImWYT5sAu_iixVLxGuc,6226
9
9
  analyser_hj3415/analyser/eval/mil.py,sha256=6_1SuWqG1fsuZUKuaABhSqNsYCgj5np35auWhnE5wdk,15289
10
10
  analyser_hj3415/analyser/eval/red.py,sha256=YXk7QX1No9mzGJlWnwfJ2aTUTbSS_LnPUL4PKzx0Aws,12051
11
11
  analyser_hj3415/analyser/tsa/__init__.py,sha256=7j-WshikzsDGGo_wuFoMPNmYfY-bLSEMd6o1MKSQKLI,150
12
- analyser_hj3415/analyser/tsa/common.py,sha256=iRwk88zBtEIqzSmTQWmQIWiiqZ9gN7GLtDUa5rx8IGM,1918
13
- analyser_hj3415/analyser/tsa/lstm.py,sha256=KPBTwOQT60WToRFQ4AAInK_JP7yA6wDpyTMsl_oNscY,29935
14
- analyser_hj3415/analyser/tsa/myprophet.py,sha256=NdBaH8Bd4k6nn6t7ZFKL01HLdxWYkXGr6q8NgXiYAUE,19034
15
- analyser_hj3415-4.5.3.dist-info/entry_points.txt,sha256=ZfjPnJuH8SzvhE9vftIPMBIofsc65IAWYOhqOC_L5ck,65
16
- analyser_hj3415-4.5.3.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
17
- analyser_hj3415-4.5.3.dist-info/METADATA,sha256=pg8MyWbzILy3VVy5SlwnttQnxP6oRAZWS5yzuNbikoA,6811
18
- analyser_hj3415-4.5.3.dist-info/RECORD,,
12
+ analyser_hj3415/analyser/tsa/common.py,sha256=NxssIm7z1V3W-Vt8B89eT_bUa4YJRTeUbfyBZdXns90,4180
13
+ analyser_hj3415/analyser/tsa/lstm.py,sha256=l0P79Zm1X3PMbyX6d449j8V5pI1yiQfYdtQZr06khw4,28819
14
+ analyser_hj3415/analyser/tsa/myprophet.py,sha256=INwn7tM6i9WCZkGb9uQm_Q4mmPRvZn06kW1__vnzloA,18445
15
+ analyser_hj3415-4.6.0.dist-info/entry_points.txt,sha256=ZfjPnJuH8SzvhE9vftIPMBIofsc65IAWYOhqOC_L5ck,65
16
+ analyser_hj3415-4.6.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
17
+ analyser_hj3415-4.6.0.dist-info/METADATA,sha256=Nhgb9gPJUr2dKBGW9aREyuZF-ym7ht2jMoNmvG7sNJ0,6844
18
+ analyser_hj3415-4.6.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: flit 3.10.1
2
+ Generator: flit 3.12.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any