analyser_hj3415 4.5.4__tar.gz → 4.6.0__tar.gz

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.
Files changed (18) hide show
  1. {analyser_hj3415-4.5.4 → analyser_hj3415-4.6.0}/PKG-INFO +4 -3
  2. {analyser_hj3415-4.5.4 → analyser_hj3415-4.6.0}/analyser_hj3415/analyser/eval/blue.py +11 -10
  3. analyser_hj3415-4.6.0/analyser_hj3415/analyser/tsa/common.py +140 -0
  4. {analyser_hj3415-4.5.4 → analyser_hj3415-4.6.0}/analyser_hj3415/analyser/tsa/lstm.py +2 -38
  5. {analyser_hj3415-4.5.4 → analyser_hj3415-4.6.0}/analyser_hj3415/analyser/tsa/myprophet.py +1 -29
  6. {analyser_hj3415-4.5.4 → analyser_hj3415-4.6.0}/pyproject.toml +3 -2
  7. analyser_hj3415-4.5.4/analyser_hj3415/analyser/tsa/common.py +0 -60
  8. {analyser_hj3415-4.5.4 → analyser_hj3415-4.6.0}/README.md +0 -0
  9. {analyser_hj3415-4.5.4 → analyser_hj3415-4.6.0}/analyser_hj3415/.DS_Store +0 -0
  10. {analyser_hj3415-4.5.4 → analyser_hj3415-4.6.0}/analyser_hj3415/__init__.py +0 -0
  11. {analyser_hj3415-4.5.4 → analyser_hj3415-4.6.0}/analyser_hj3415/analyser/__init__.py +0 -0
  12. {analyser_hj3415-4.5.4 → analyser_hj3415-4.6.0}/analyser_hj3415/analyser/eval/__init__.py +0 -0
  13. {analyser_hj3415-4.5.4 → analyser_hj3415-4.6.0}/analyser_hj3415/analyser/eval/common.py +0 -0
  14. {analyser_hj3415-4.5.4 → analyser_hj3415-4.6.0}/analyser_hj3415/analyser/eval/growth.py +0 -0
  15. {analyser_hj3415-4.5.4 → analyser_hj3415-4.6.0}/analyser_hj3415/analyser/eval/mil.py +0 -0
  16. {analyser_hj3415-4.5.4 → analyser_hj3415-4.6.0}/analyser_hj3415/analyser/eval/red.py +0 -0
  17. {analyser_hj3415-4.5.4 → analyser_hj3415-4.6.0}/analyser_hj3415/analyser/tsa/__init__.py +0 -0
  18. {analyser_hj3415-4.5.4 → analyser_hj3415-4.6.0}/analyser_hj3415/cli.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: analyser_hj3415
3
- Version: 4.5.4
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'
@@ -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
 
@@ -0,0 +1,140 @@
1
+ import numpy as np
2
+ import pandas as pd
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
11
+
12
+
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
+ """
24
+ if not data:
25
+ # 데이터가 비어있으면 추세를 판단할 수 없음
26
+ return False
27
+
28
+ # 1) 날짜(키) 기준 오름차순 정렬
29
+ sorted_dates = sorted(data.keys())
30
+ values = [data[d] for d in sorted_dates]
31
+
32
+ # 2) x 축을 0,1,2... 형태로 부여 (날짜 간격을 동일하게 가정)
33
+ x = np.arange(len(values), dtype=float)
34
+ y = np.array(values, dtype=float)
35
+
36
+ # 3) 선형 회귀(최소제곱법)로 기울기(slope) 계산
37
+ x_mean = np.mean(x)
38
+ y_mean = np.mean(y)
39
+
40
+ # 분자: sum((xi - x_mean) * (yi - y_mean))
41
+ numerator = np.sum((x - x_mean) * (y - y_mean))
42
+ # 분모: sum((xi - x_mean)^2)
43
+ denominator = np.sum((x - x_mean) ** 2)
44
+
45
+ if denominator == 0:
46
+ # 데이터가 1개 이하인 경우 등
47
+ return False
48
+
49
+ slope = numerator / denominator
50
+
51
+ # 4) 기울기가 양수면 "우상향 추세"로 판별
52
+ return slope > 0
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
96
+ @dataclass
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]
105
+
106
+ is_prophet_up: bool
107
+
108
+
109
+ # ISO-8601(YYYY-MM-DD) 포맷으로 직렬화·역직렬화
110
+ date_enc = lambda d: d.isoformat()
111
+ date_dec = lambda s: date.fromisoformat(s)
112
+
113
+
114
+ @dataclass_json
115
+ @dataclass
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
131
+
132
+ date: date = field(metadata=config(encoder=date_enc, decoder=date_dec))
133
+
134
+ price: float
135
+ yhat: float
136
+ yhat_upper: float
137
+ yhat_lower: float
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
 
@@ -5,7 +5,7 @@ build-backend = "flit_core.buildapi"
5
5
 
6
6
  [project]
7
7
  name = "analyser_hj3415"
8
- version = "4.5.4"
8
+ version = "4.6.0"
9
9
  description = "Stock analyser and database processing programs"
10
10
  readme = "README.md"
11
11
  requires-python = ">=3.6"
@@ -28,7 +28,8 @@ dependencies = [
28
28
  "prophet>=1.1.6",
29
29
  "kaleido>=0.2.1", #plotly로 이미지출력위해
30
30
  "matplotlib>=3.9.2",
31
- "marshmallow>=3.26.0",
31
+ "dataclasses_json>=0.6.7",
32
+ "pandas>=2.2.3",
32
33
  # Apple Silicon (ARM, macOS)에서 tensorflow-macos 사용
33
34
  "tensorflow-macos>=2.16.2; platform_machine == 'arm64' and sys_platform == 'darwin'",
34
35
  "tensorflow-metal>=0.5.0; platform_machine == 'arm64' and sys_platform == 'darwin'",
@@ -1,60 +0,0 @@
1
- import numpy as np
2
- from dataclasses import dataclass, field
3
- from typing import Optional
4
- import pandas as pd
5
- from marshmallow import fields
6
-
7
-
8
- def is_up_by_OLS(data: dict) -> bool:
9
- if not data:
10
- # 데이터가 비어있으면 추세를 판단할 수 없음
11
- return False
12
-
13
- # 1) 날짜(키) 기준 오름차순 정렬
14
- sorted_dates = sorted(data.keys())
15
- values = [data[d] for d in sorted_dates]
16
-
17
- # 2) x 축을 0,1,2... 형태로 부여 (날짜 간격을 동일하게 가정)
18
- x = np.arange(len(values), dtype=float)
19
- y = np.array(values, dtype=float)
20
-
21
- # 3) 선형 회귀(최소제곱법)로 기울기(slope) 계산
22
- x_mean = np.mean(x)
23
- y_mean = np.mean(y)
24
-
25
- # 분자: sum((xi - x_mean) * (yi - y_mean))
26
- numerator = np.sum((x - x_mean) * (y - y_mean))
27
- # 분모: sum((xi - x_mean)^2)
28
- denominator = np.sum((x - x_mean) ** 2)
29
-
30
- if denominator == 0:
31
- # 데이터가 1개 이하인 경우 등
32
- return False
33
-
34
- slope = numerator / denominator
35
-
36
- # 4) 기울기가 양수면 "우상향 추세"로 판별
37
- return slope > 0
38
-
39
- @dataclass
40
- class PandasTimestampField(fields.DateTime):
41
- """pandas.Timestamp를 ISO 8601 문자열로 직렬화하고 역직렬화하는 필드"""
42
-
43
- def __init__(self, *args, **kwargs):
44
- # 꼭 부모의 __init__을 호출해야 함
45
- super().__init__(*args, **kwargs)
46
-
47
- def _serialize(self, value, attr, obj, **kwargs):
48
- return value.isoformat() if isinstance(value, pd.Timestamp) else None
49
-
50
- def _deserialize(self, value, attr, data, **kwargs):
51
- return pd.Timestamp(value)
52
-
53
- @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)})
58
-
59
-
60
-