analyser_hj3415 2.9.7__tar.gz → 2.9.9__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ /dist/
@@ -1,18 +1,20 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: analyser_hj3415
3
- Version: 2.9.7
3
+ Version: 2.9.9
4
4
  Summary: Stock analyser and database processing programs
5
5
  Requires-Python: >=3.6
6
6
  Description-Content-Type: text/markdown
7
7
  Requires-Dist: utils-hj3415>=2.9.2
8
- Requires-Dist: db-hj3415>=4.0.3
8
+ Requires-Dist: db-hj3415>=4.1.4
9
9
  Requires-Dist: scikit-learn>=1.5.2
10
10
  Requires-Dist: plotly>=5.24.1
11
11
  Requires-Dist: yfinance>=0.2.44
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: tensorflow>=2.18.0
15
+ Requires-Dist: tensorflow-macos>=2.16.2; platform_machine == 'arm64' and sys_platform == 'darwin'
16
+ Requires-Dist: tensorflow-metal>=0.5.0; platform_machine == 'arm64' and sys_platform == 'darwin'
17
+ Requires-Dist: tensorflow>=2.18.0; platform_machine != 'arm64' or sys_platform != 'darwin'
16
18
 
17
19
  ### analyser-hj3415
18
20
 
@@ -4,8 +4,7 @@ import pprint
4
4
 
5
5
  from utils_hj3415 import noti, utils
6
6
  from utils_hj3415.helpers import SettingsManager
7
- from db_hj3415 import myredis
8
-
7
+ from db_hj3415 import myredis, mypeewee
9
8
 
10
9
  class AnalyserSettingsManager(SettingsManager):
11
10
  DEFAULT_SETTINGS = {
@@ -34,6 +33,8 @@ class AnalyserSettingsManager(SettingsManager):
34
33
  print(f"{title}이 기본값 ({self.DEFAULT_SETTINGS[title]}) 으로 초기화 되었습니다.")
35
34
 
36
35
 
36
+ log_cli = mypeewee.LogManager('cli')
37
+
37
38
  def analyser_manager():
38
39
  settings_manager = AnalyserSettingsManager()
39
40
  expect_earn_from_setting = settings_manager.get_value('EXPECT_EARN')
@@ -47,7 +48,6 @@ def analyser_manager():
47
48
  # ranking 파서
48
49
  ranking_parser = prophet_subparser.add_parser('ranking', help='prophet 랭킹 책정 및 레디스 저장')
49
50
  ranking_parser.add_argument('-r', '--refresh', action='store_true', help='래디스 캐시를 사용하지 않고 강제로 재계산 할지')
50
- ranking_parser.add_argument('-n', '--noti', action='store_true', help='작업 완료 후 메시지 전송 여부')
51
51
 
52
52
  # lstm 명령어 서브파서
53
53
  lstm_parser = type_subparsers.add_parser('lstm', help='MyLSTM 타입')
@@ -56,12 +56,10 @@ def analyser_manager():
56
56
  caching_parser = lstm_subparser.add_parser('caching', help='lstm 랭킹 책정 및 레디스 저장')
57
57
  caching_parser.add_argument('-r', '--refresh', action='store_true', help='래디스 캐시를 사용하지 않고 강제로 재계산 할지')
58
58
  caching_parser.add_argument('-t', '--top', type=int, help='prophet ranking 몇위까지 작업을 할지')
59
- caching_parser.add_argument('-n', '--noti', action='store_true', help='작업 완료 후 메시지 전송 여부')
60
59
  # red - get 파서
61
60
  lstm_get_parser = lstm_subparser.add_parser('get', help='lstm get 책정 및 레디스 저장')
62
61
  lstm_get_parser.add_argument('code', type=str, help='종목코드')
63
62
  lstm_get_parser.add_argument('-r', '--refresh', action='store_true', help='래디스 캐시를 사용하지 않고 강제로 재계산 할지')
64
- lstm_get_parser.add_argument('-n', '--noti', action='store_true', help='작업 완료 후 메시지 전송 여부')
65
63
 
66
64
  # red 명령어 서브파서
67
65
  red_parser = type_subparsers.add_parser('red', help='red 타입')
@@ -70,13 +68,11 @@ def analyser_manager():
70
68
  ranking_parser = red_subparser.add_parser('ranking', help='red 랭킹 책정 및 레디스 저장')
71
69
  ranking_parser.add_argument('-e', '--expect_earn', type=float, help='기대수익률 (실수 값 입력)')
72
70
  ranking_parser.add_argument('-r', '--refresh', action='store_true', help='래디스 캐시를 사용하지 않고 강제로 재계산 할지')
73
- ranking_parser.add_argument('-n', '--noti', action='store_true', help='작업 완료 후 메시지 전송 여부')
74
71
  # red - get 파서
75
72
  red_get_parser = red_subparser.add_parser('get', help='red get 책정 및 레디스 저장')
76
73
  red_get_parser.add_argument('code', type=str, help='종목코드 or all')
77
74
  red_get_parser.add_argument('-e', '--expect_earn', type=float, help='기대수익률 (실수 값 입력)')
78
75
  red_get_parser.add_argument('-r', '--refresh', action='store_true', help='래디스 캐시를 사용하지 않고 강제로 재계산 할지')
79
- red_get_parser.add_argument('-n', '--noti', action='store_true', help='작업 완료 후 메시지 전송 여부')
80
76
 
81
77
  # mil 명령어 서브파서
82
78
  mil_parser = type_subparsers.add_parser('mil', help='millennial 타입')
@@ -86,7 +82,6 @@ def analyser_manager():
86
82
  mil_get_parser.add_argument('code', type=str, help='종목코드 or all')
87
83
  mil_get_parser.add_argument('-e', '--expect_earn', type=float, help='기대수익률 (실수 값 입력)')
88
84
  mil_get_parser.add_argument('-r', '--refresh', action='store_true', help='래디스 캐시를 사용하지 않고 강제로 재계산 할지')
89
- mil_get_parser.add_argument('-n', '--noti', action='store_true', help='작업 완료 후 메시지 전송 여부')
90
85
 
91
86
  # blue 명령어 서브파서
92
87
  blue_parser = type_subparsers.add_parser('blue', help='Blue 타입')
@@ -96,7 +91,6 @@ def analyser_manager():
96
91
  blue_get_parser.add_argument('code', type=str, help='종목코드 or all')
97
92
  blue_get_parser.add_argument('-e', '--expect_earn', type=float, help='기대수익률 (실수 값 입력)')
98
93
  blue_get_parser.add_argument('-r', '--refresh', action='store_true', help='래디스 캐시를 사용하지 않고 강제로 재계산 할지')
99
- blue_get_parser.add_argument('-n', '--noti', action='store_true', help='작업 완료 후 메시지 전송 여부')
100
94
 
101
95
  # growth 명령어 서브파서
102
96
  growth_parser = type_subparsers.add_parser('growth', help='Growth 타입')
@@ -106,7 +100,6 @@ def analyser_manager():
106
100
  growth_get_parser.add_argument('code', type=str, help='종목코드 or all')
107
101
  growth_get_parser.add_argument('-e', '--expect_earn', type=float, help='기대수익률 (실수 값 입력)')
108
102
  growth_get_parser.add_argument('-r', '--refresh', action='store_true', help='래디스 캐시를 사용하지 않고 강제로 재계산 할지')
109
- growth_get_parser.add_argument('-n', '--noti', action='store_true', help='작업 완료 후 메시지 전송 여부')
110
103
 
111
104
  # setting 명령어 서브파서
112
105
  setting_parser = type_subparsers.add_parser('setting', help='Set and Get settings')
@@ -158,14 +151,12 @@ def analyser_manager():
158
151
 
159
152
  # 원래 저장되었던 기대수익률로 다시 복원
160
153
  eval.Red.expect_earn = ee_orig
161
- if args.noti:
162
- noti.telegram_to('manager', f"오늘의 Red({args.code})를 레디스캐시에 저장했습니다.(유효 12시간)")
154
+ log_cli.save('INFO', f'run >> analyser red get {args.code}')
163
155
 
164
156
  elif args.command == 'ranking':
157
+ log_cli.save('INFO', 'run >> analyser red ranking')
165
158
  result = eval.Red.ranking(expect_earn=args.expect_earn, refresh=args.refresh)
166
159
  print(result)
167
- if args.noti:
168
- noti.telegram_to('manager', "오늘의 red ranking을 레디스캐시에 저장했습니다.(유효 12시간)")
169
160
 
170
161
  elif args.type == 'mil':
171
162
  if args.command == 'get':
@@ -181,8 +172,7 @@ def analyser_manager():
181
172
  mil = eval.Mil(args.code)
182
173
  print(f"*** Mil - {mil} ***")
183
174
  pprint.pprint(mil.get(args.refresh))
184
- if args.noti:
185
- noti.telegram_to('manager', f"오늘의 Mil({args.code})를 레디스 캐시에 저장했습니다.(유효 12시간)")
175
+ log_cli.save('INFO', f'run >> analyser mil get {args.code}')
186
176
 
187
177
  elif args.type == 'blue':
188
178
  if args.command == 'get':
@@ -198,8 +188,7 @@ def analyser_manager():
198
188
  blue = eval.Blue(args.code)
199
189
  print(f"*** Blue - {blue} ***")
200
190
  pprint.pprint(blue.get(args.refresh))
201
- if args.noti:
202
- noti.telegram_to('manager', f"오늘의 Blue({args.code})를 레디스 캐시에 저장했습니다.(유효 12시간)")
191
+ log_cli.save('INFO', f'run >> analyser blue get {args.code}')
203
192
 
204
193
  elif args.type == 'growth':
205
194
  if args.command == 'get':
@@ -215,27 +204,30 @@ def analyser_manager():
215
204
  growth = eval.Growth(args.code)
216
205
  print(f"*** growth - {growth} ***")
217
206
  pprint.pprint(growth.get(args.refresh))
218
- if args.noti:
219
- noti.telegram_to('manager', f"오늘의 Growth({args.code})를 레디스 캐시에 저장했습니다.(유효 12시간)")
207
+ log_cli.save('INFO', f'run >> analyser growth get {args.code}')
208
+
220
209
  elif args.type == 'prophet':
221
210
  if args.command == 'ranking':
222
- result = tsa.MyProphet.ranking(refresh=args.refresh)
211
+ myprophet = tsa.MyProphet
212
+ myprophet.expire_time_h = 72
213
+ result = myprophet.ranking(refresh=args.refresh)
223
214
  print(result)
224
- if args.noti:
225
- noti.telegram_to('manager', "오늘의 prophet ranking을 레디스캐시에 저장했습니다.(유효 24시간)")
215
+ log_cli.save('INFO', 'run >> analyser prophet ranking')
216
+
226
217
  elif args.type == 'lstm':
218
+ mylstm = tsa.MyLSTM
219
+ mylstm.expire_time_h = 72
227
220
  if args.command == 'caching':
228
221
  if args.top:
229
- tsa.MyLSTM.caching_based_on_prophet_ranking(refresh=args.refresh, top=args.top)
222
+ mylstm.caching_based_on_prophet_ranking(refresh=args.refresh, top=args.top)
230
223
  else:
231
- tsa.MyLSTM.caching_based_on_prophet_ranking(refresh=args.refresh)
232
- if args.noti:
233
- noti.telegram_to('manager', f"오늘의 lstm caching(top={args.top if args.top else 20})을 레디스캐시에 저장했습니다.(유효 24시간)")
224
+ mylstm.caching_based_on_prophet_ranking(refresh=args.refresh)
225
+ log_cli.save('INFO', f'run >> analyser lstm caching / top={args.top if args.top else 20})')
234
226
  elif args.command == 'get':
235
227
  assert utils.is_6digit(args.code), "code 인자는 6자리 숫자이어야 합니다."
236
- result = tsa.MyLSTM(args.code).get_final_predictions(refresh=args.refresh)
237
- if args.noti:
238
- noti.telegram_to('manager', f"LSTM 분석을({args.code})를 레디스 캐시에 저장했습니다.(유효 12시간)")
228
+ result = mylstm(args.code).get_final_predictions(refresh=args.refresh)
229
+ log_cli.save('INFO', f'run >> analyser lstm get {args.code}')
230
+
239
231
  elif args.type == 'setting':
240
232
  if args.command == 'set':
241
233
  settings_manager.set_value(args.title, args.value)
@@ -244,5 +236,8 @@ def analyser_manager():
244
236
  print(f"{args.title} 값: {value}")
245
237
  elif args.command == 'print':
246
238
  print(settings_manager.load_settings())
239
+
247
240
  else:
248
241
  parser.print_help()
242
+
243
+ log_cli.close()
@@ -33,6 +33,7 @@ tsa_logger = helpers.setup_logger('tsa_logger', logging.WARNING)
33
33
  expire_time = 3600 * 24
34
34
 
35
35
  class MyProphet:
36
+ expire_time_h = 24
36
37
  def __init__(self, code: str):
37
38
  assert utils.is_6digit(code), f'Invalid value : {code}'
38
39
  self.scaler = StandardScaler()
@@ -204,7 +205,7 @@ class MyProphet:
204
205
  redis_name = 'myprophet_ranking'
205
206
 
206
207
  print(
207
- f"redisname: '{redis_name}' / refresh : {refresh} / expire_time : {expire_time / 3600}h")
208
+ f"redisname: '{redis_name}' / refresh : {refresh} / expire_time : {MyProphet.expire_time_h}h")
208
209
 
209
210
  def fetch_ranking() -> dict:
210
211
  data = {}
@@ -223,7 +224,7 @@ class MyProphet:
223
224
  print(f"{i}.{p.code}/{p.name} date: {recent_date} 가격:{recent_price} 기대하한값:{yhat_lower} 편차:{deviation}")
224
225
  return data
225
226
 
226
- data_dict = myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_ranking, timer=expire_time)
227
+ data_dict = myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_ranking, timer=MyProphet.expire_time_h * 3600)
227
228
 
228
229
  return OrderedDict(sorted(data_dict.items(), key=lambda item: item[1], reverse=True))
229
230
 
@@ -264,6 +265,7 @@ class MyLSTM:
264
265
  """
265
266
  # 미래 몇일을 예측할 것인가?
266
267
  future_days = 30
268
+ expire_time_h = 48
267
269
 
268
270
  def __init__(self, code: str):
269
271
  assert utils.is_6digit(code), f'Invalid value : {code}'
@@ -498,7 +500,7 @@ class MyLSTM:
498
500
  redis_name = f'{self.code}_mylstm_predictions'
499
501
 
500
502
  print(
501
- f"redisname: '{redis_name}' / refresh : {refresh} / expire_time : {expire_time / 3600}h")
503
+ f"redisname: '{redis_name}' / refresh : {refresh} / expire_time : {MyLSTM.expire_time_h}h")
502
504
 
503
505
  def fetch_final_predictions(num_in) -> tuple:
504
506
  """
@@ -529,7 +531,7 @@ class MyLSTM:
529
531
 
530
532
  return future_dates_str, final_future_predictions.tolist()
531
533
 
532
- future_dates_str, final_future_predictions = myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_final_predictions, num, timer=expire_time)
534
+ future_dates_str, final_future_predictions = myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_final_predictions, num, timer=MyLSTM.expire_time_h * 3600)
533
535
 
534
536
  # 문자열을 날짜 형식으로 변환
535
537
  future_dates = [datetime.strptime(date, '%Y-%m-%d') for date in future_dates_str]
@@ -5,7 +5,7 @@ build-backend = "flit_core.buildapi"
5
5
 
6
6
  [project]
7
7
  name = "analyser_hj3415"
8
- version = "2.9.7"
8
+ version = "2.9.9"
9
9
  description = "Stock analyser and database processing programs"
10
10
  readme = "README.md"
11
11
  requires-python = ">=3.6"
@@ -21,14 +21,19 @@ requires-python = ">=3.6"
21
21
  #]
22
22
  dependencies = [
23
23
  "utils-hj3415>=2.9.2",
24
- "db-hj3415>=4.0.3",
24
+ "db-hj3415>=4.1.4",
25
25
  "scikit-learn>=1.5.2",
26
26
  "plotly>=5.24.1",
27
27
  "yfinance>=0.2.44",
28
28
  "prophet>=1.1.6",
29
29
  "kaleido>=0.2.1", #plotly로 이미지출력위해
30
30
  "matplotlib>=3.9.2",
31
- "tensorflow>=2.18.0",
31
+ # Apple Silicon (ARM, macOS)에서 tensorflow-macos 사용
32
+ "tensorflow-macos>=2.16.2; platform_machine == 'arm64' and sys_platform == 'darwin'",
33
+ "tensorflow-metal>=0.5.0; platform_machine == 'arm64' and sys_platform == 'darwin'",
34
+ # 그 외 환경에서는 일반 tensorflow 사용
35
+ "tensorflow>=2.18.0; platform_machine != 'arm64' or sys_platform != 'darwin'"
36
+
32
37
  ]
33
38
 
34
39
  [project.scripts]
Binary file