analyser_hj3415 4.0.10__py3-none-any.whl → 4.1.1__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.
@@ -1,12 +1,13 @@
1
1
  import os
2
2
  from dataclasses import dataclass
3
- from typing import Tuple
3
+ from typing import Tuple, List, Dict
4
4
  import math
5
5
 
6
6
  from utils_hj3415 import tools, setup_logger
7
7
  from db_hj3415 import myredis, mymongo
8
8
 
9
9
  from analyser_hj3415.analyser.eval.common import Tools
10
+ import pickle
10
11
 
11
12
 
12
13
  mylogger = setup_logger(__name__,'INFO')
@@ -85,6 +86,9 @@ class Mil:
85
86
  name (str): 기업명.
86
87
  _code (str): 기업 종목 코드.
87
88
  """
89
+
90
+ REDIS_MIL_DATA_SUFFIX = "mil_data"
91
+
88
92
  def __init__(self, code: str):
89
93
  assert tools.is_6digit(code), f'Invalid value : {code}'
90
94
  mylogger.debug(f"Mil : 종목코드 ({code})")
@@ -364,10 +368,57 @@ class Mil:
364
368
  로그:
365
369
  - 캐시 검색 상태와 새로 생성된 데이터를 출력합니다.
366
370
  """
367
- redis_name = f"{self.code}_mil"
371
+ redis_name = f"{self.code}_{self.REDIS_MIL_DATA_SUFFIX}"
368
372
  mylogger.debug(f"{self} redisname: '{redis_name}' / refresh : {refresh} / expire_time : {expire_time/3600}h")
369
373
 
370
374
  def fetch_generate_data(refresh_in: bool) -> dict:
371
375
  return self._generate_data(refresh_in) # type: ignore
372
376
 
373
- return myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_generate_data, refresh, timer=expire_time)
377
+ return myredis.Base.fetch_and_cache_data(redis_name, refresh, fetch_generate_data, refresh, timer=expire_time)
378
+
379
+ @classmethod
380
+ def bulk_generate_data(cls, codes: List[str], refresh: bool) -> Dict[str, MilData]:
381
+ # --- (1) 파이프라인 GET ---
382
+ pipe = myredis.Base.redis_client.pipeline()
383
+ redis_keys = [f"{code}_{cls.REDIS_MIL_DATA_SUFFIX}" for code in codes]
384
+ for redis_key in redis_keys:
385
+ pipe.get(redis_key)
386
+ results_from_redis = pipe.execute() # [val1, val2, ...]
387
+
388
+ final_results = {}
389
+ missing_codes = []
390
+
391
+ # refresh=True 이면 기존 데이터 무시하고 다시 계산해야 하므로 모두 missing 처리
392
+ if refresh:
393
+ missing_codes = codes[:]
394
+ else:
395
+ # refresh=False 이면, Redis 값이 None인 티커만 다시 계산
396
+ for code, val in zip(codes, results_from_redis):
397
+ if val is None:
398
+ missing_codes.append(code)
399
+ else:
400
+ # Redis에 pickled 데이터가 있다면 언피클해서 담기
401
+ red_data = pickle.loads(val)
402
+ final_results[code] = red_data
403
+
404
+ # --- (2) 필요한 티커만 직접 연산 ---
405
+ newly_computed_data = {}
406
+ for code in missing_codes:
407
+ mylogger.debug(f"*** bulk_generate_data : {code}")
408
+ data = cls(code)._generate_data(refresh=True)
409
+ newly_computed_data[code] = data
410
+
411
+ # --- (3) 파이프라인 SET ---
412
+ if newly_computed_data:
413
+ pipe = myredis.Base.redis_client.pipeline()
414
+ for code, data in newly_computed_data.items():
415
+ redis_key = f"{code}_{cls.REDIS_MIL_DATA_SUFFIX}"
416
+ # ProphetLatestData 객체를 pickle로 직렬화
417
+ pickled_data = pickle.dumps(data)
418
+ # SET + expire_time
419
+ pipe.setex(redis_key, expire_time, pickled_data)
420
+ pipe.execute()
421
+
422
+ # 최종 결과 딕셔너리 (캐시에 있었던 것 + 새로 만든 것)
423
+ final_results.update(newly_computed_data)
424
+ return final_results
@@ -306,7 +306,7 @@ class Red:
306
306
  newly_computed_data = {}
307
307
  for code in missing_codes:
308
308
  mylogger.debug(f"*** bulk_generate_data : {code}")
309
- data = cls(code, expect_earn)._generate_data(refresh=refresh)
309
+ data = cls(code, expect_earn)._generate_data(refresh=True)
310
310
  newly_computed_data[code] = data
311
311
 
312
312
  # --- (3) 파이프라인 SET ---
@@ -99,6 +99,7 @@ class MyLSTM:
99
99
  """
100
100
  # 미래 몇일을 예측할 것인가?
101
101
  future_days = 30
102
+ REDIS_LSTM_DATA_SUFFIX = "lstm_chart_data"
102
103
 
103
104
  def __init__(self, ticker: str):
104
105
  mylogger.debug(f'MyLSTM set up ticker : {ticker}')
@@ -479,7 +480,7 @@ class MyLSTM:
479
480
 
480
481
  def generate_chart_data(self, refresh:bool, num=5) -> LSTMChartData:
481
482
  mylogger.info("**** Start generate_lstm_chart_data... ****")
482
- redis_name = f'{self.ticker}_lstm_chart_data'
483
+ redis_name = f'{self.ticker}_{MyLSTM.REDIS_LSTM_DATA_SUFFIX}'
483
484
 
484
485
  mylogger.info(
485
486
  f"redisname: '{redis_name}' / refresh : {refresh} / expire_time : {expire_time / 3600}h")
@@ -546,13 +547,22 @@ class MyLSTM:
546
547
 
547
548
  def get_chart_data(self) -> Optional[LSTMChartData]:
548
549
  mylogger.debug("**** Start get_lstm_chart_data... ****")
549
- redis_name = f'{self.ticker}_lstm_chart_data'
550
+ redis_name = f'{self.ticker}_{MyLSTM.REDIS_LSTM_DATA_SUFFIX}'
550
551
  if myredis.Base.exists(redis_name):
551
552
  mylogger.debug(f"ttl: {myredis.Base.get_ttl(redis_name)}")
552
553
  return myredis.Base.get_value(redis_name)
553
554
  else:
554
555
  return None
555
556
 
557
+ @staticmethod
558
+ def bulk_get_chart_data(tickers: List[str]) -> Dict[str, Optional[LSTMChartData]]:
559
+ redis_keys = [f"{ticker}_{MyLSTM.REDIS_LSTM_DATA_SUFFIX}" for ticker in tickers]
560
+ redis_key_data = myredis.Base.bulk_get_data(redis_keys)
561
+ ticker_data = {}
562
+ for redis_key, data in redis_key_data.items():
563
+ ticker_data[redis_key.split('_')[0]] = data
564
+ return ticker_data
565
+
556
566
  @staticmethod
557
567
  def caching_chart_data(tickers:list, num:int):
558
568
  mylogger.info(f"*** caching_chart_data ***")
@@ -605,10 +615,18 @@ class CorpLSTM(MyLSTM):
605
615
  MyLSTM.caching_chart_data([CorpLSTM.code_to_ticker(code) for code in ranking_topn.keys() ], num=num)
606
616
 
607
617
  @staticmethod
608
- def caching_chart_data_bulk(codes: list, num=5):
618
+ def caching_chart_data_bulk(codes: List[str], num=5):
609
619
  mylogger.info(f"*** caching_chart_data_bulk : {len(codes)} items ***")
610
620
  MyLSTM.caching_chart_data([CorpLSTM.code_to_ticker(code) for code in codes], num=num)
611
621
 
622
+ @staticmethod
623
+ def bulk_get_chart_data(codes: List[str]) -> Dict[str, Optional[LSTMChartData]]:
624
+ ticker_data = MyLSTM.bulk_get_chart_data([CorpLSTM.code_to_ticker(code) for code in codes])
625
+ code_data = {}
626
+ for ticker, data in ticker_data.items():
627
+ code_data[CorpLSTM.ticker_to_code(ticker)] = data
628
+ return code_data
629
+
612
630
 
613
631
  class MILSTM(MyLSTM):
614
632
  """
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: analyser_hj3415
3
- Version: 4.0.10
3
+ Version: 4.1.1
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>=3.0.10
8
- Requires-Dist: db-hj3415>=4.3.5
8
+ Requires-Dist: db-hj3415>=4.4.0
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
@@ -5,13 +5,13 @@ analyser_hj3415/analyser/eval/__init__.py,sha256=IP1d0Q3nOCAD3zK1qxrC685MkJQfUh-
5
5
  analyser_hj3415/analyser/eval/blue.py,sha256=p5JPwkQYoO0dsOe3VnfMV3pOWLzNsAFvLCUK56f85Xo,10782
6
6
  analyser_hj3415/analyser/eval/common.py,sha256=sNXapoofShA43ww_SLjXmIjkrAr1AhAcezdaN_X_3Us,11443
7
7
  analyser_hj3415/analyser/eval/growth.py,sha256=tlHxLx4u5h7bNG0T8ViJujX20QllfrSaBl-TBqFNkEs,6362
8
- analyser_hj3415/analyser/eval/mil.py,sha256=uaS7MHNlytrjEgdLc9S1zhXb5bzVAwlSMlnQWop2Hbw,15017
9
- analyser_hj3415/analyser/eval/red.py,sha256=DZBV0qMzWD8KGvAbdxrohCVT0a5luduuhKQoN3OtNwc,13909
8
+ analyser_hj3415/analyser/eval/mil.py,sha256=OXj_J5cMuOxDKobOGEVKFOon1qVcJTPGbLS9vRFyNPo,17143
9
+ analyser_hj3415/analyser/eval/red.py,sha256=1wbZWFBWQjnnE4uQQVE34Wfl2YXePzJ2yqKmfLxicoc,13906
10
10
  analyser_hj3415/analyser/tsa/__init__.py,sha256=pg20ZQRABedTdaIoOr5t043RNKtJ7ji_WmnZrD1IhPg,147
11
11
  analyser_hj3415/analyser/tsa/common.py,sha256=ZLUkifupOlLKsrPiqR3y6FaEN4M_loZhxCZXYxkX0us,1874
12
- analyser_hj3415/analyser/tsa/lstm.py,sha256=tezdQcyLJn5rSNXbU_zApZV-kCTHPX9i7x5YujioWZI,28129
12
+ analyser_hj3415/analyser/tsa/lstm.py,sha256=oENuJyyo6U9MMn4UF4ZauGai51_dJisMSUNBiH8udXo,28998
13
13
  analyser_hj3415/analyser/tsa/prophet.py,sha256=a8XPiikRFbqHjbDT7C3hK5RsqOp5JyAbY7lDFNQfBzM,17884
14
- analyser_hj3415-4.0.10.dist-info/entry_points.txt,sha256=ZfjPnJuH8SzvhE9vftIPMBIofsc65IAWYOhqOC_L5ck,65
15
- analyser_hj3415-4.0.10.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
16
- analyser_hj3415-4.0.10.dist-info/METADATA,sha256=T5Qh8sutQmZYCb_RUFYKCB5kcVUJnwqYHhzO0mJbpx4,6778
17
- analyser_hj3415-4.0.10.dist-info/RECORD,,
14
+ analyser_hj3415-4.1.1.dist-info/entry_points.txt,sha256=ZfjPnJuH8SzvhE9vftIPMBIofsc65IAWYOhqOC_L5ck,65
15
+ analyser_hj3415-4.1.1.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
16
+ analyser_hj3415-4.1.1.dist-info/METADATA,sha256=p8fA-R8Cw1vWd2VnZcgGvJh-yjYH7uo2KWkGOEvAZAI,6777
17
+ analyser_hj3415-4.1.1.dist-info/RECORD,,