pyqqq 0.12.195__tar.gz → 0.12.197__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.

Potentially problematic release.


This version of pyqqq might be problematic. Click here for more details.

Files changed (59) hide show
  1. {pyqqq-0.12.195 → pyqqq-0.12.197}/PKG-INFO +1 -1
  2. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyproject.toml +1 -1
  3. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/backtest/broker.py +11 -2
  4. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/brokerage/kis/domestic_stock.py +22 -3
  5. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/brokerage/kis/tr_client.py +1 -1
  6. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/utils/compute.py +2 -2
  7. pyqqq-0.12.197/pyqqq/utils/indicators.py +1011 -0
  8. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/utils/retry.py +4 -2
  9. {pyqqq-0.12.195 → pyqqq-0.12.197}/README.md +0 -0
  10. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/__init__.py +0 -0
  11. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/backtest/__init__.py +0 -0
  12. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/backtest/environment.py +0 -0
  13. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/backtest/logger.py +0 -0
  14. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/backtest/positionprovider.py +0 -0
  15. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/backtest/strategy.py +0 -0
  16. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/backtest/utils.py +0 -0
  17. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/backtest/wallclock.py +0 -0
  18. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/brokerage/__init__.py +0 -0
  19. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/brokerage/ebest/__init__.py +0 -0
  20. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/brokerage/ebest/domestic_stock.py +0 -0
  21. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/brokerage/ebest/oauth.py +0 -0
  22. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/brokerage/ebest/simple.py +0 -0
  23. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/brokerage/ebest/tr_client.py +0 -0
  24. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/brokerage/helper.py +0 -0
  25. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/brokerage/kis/__init__.py +0 -0
  26. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/brokerage/kis/oauth.py +0 -0
  27. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/brokerage/kis/overseas_stock.py +0 -0
  28. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/brokerage/kis/simple.py +0 -0
  29. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/brokerage/kis/simple_overseas.py +0 -0
  30. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/brokerage/multiprocess_tracker.py +0 -0
  31. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/brokerage/tracker.py +0 -0
  32. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/config.py +0 -0
  33. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/data/__init__.py +0 -0
  34. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/data/daily.py +0 -0
  35. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/data/domestic.py +0 -0
  36. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/data/index.py +0 -0
  37. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/data/minutes.py +0 -0
  38. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/data/overseas.py +0 -0
  39. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/data/realtime.py +0 -0
  40. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/data/ticks.py +0 -0
  41. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/data/us_stocks.py +0 -0
  42. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/datatypes.py +0 -0
  43. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/executors/__init__.py +0 -0
  44. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/executors/hook.py +0 -0
  45. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/utils/__init__.py +0 -0
  46. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/utils/api_client.py +0 -0
  47. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/utils/array.py +0 -0
  48. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/utils/casting.py +0 -0
  49. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/utils/copycat.py +0 -0
  50. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/utils/daily_tickers.py +0 -0
  51. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/utils/display.py +0 -0
  52. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/utils/kvstore.py +0 -0
  53. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/utils/limiter.py +0 -0
  54. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/utils/local_cache.py +0 -0
  55. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/utils/logger.py +0 -0
  56. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/utils/market_schedule.py +0 -0
  57. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/utils/mock_api.py +0 -0
  58. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/utils/position_classifier.py +0 -0
  59. {pyqqq-0.12.195 → pyqqq-0.12.197}/pyqqq/utils/singleton.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyqqq
3
- Version: 0.12.195
3
+ Version: 0.12.197
4
4
  Summary: Package for quantitative strategy development on the PyQQQ platform
5
5
  License: MIT
6
6
  Author: PyQQQ team
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pyqqq"
3
- version = "0.12.195"
3
+ version = "0.12.197"
4
4
  description = "Package for quantitative strategy development on the PyQQQ platform"
5
5
  authors = ["PyQQQ team <pyqqq.cs@gmail.com>"]
6
6
  readme = "README.md"
@@ -597,11 +597,17 @@ class MockBroker(BaseBroker):
597
597
  # 현재 시간 데이터가 없을 경우 전일 종가로 대체
598
598
  last_trading_day = get_last_trading_day(today, exchange=self._get_exchange_code())
599
599
  df = self.get_daily_price(code, last_trading_day, last_trading_day) # 전일 종가는 일봉, 분봉 구분이 필요 없다.
600
- return typed_result(df["close"].iloc[-1])
600
+ if not df.empty:
601
+ return typed_result(df["close"].iloc[-1])
602
+ else:
603
+ return Decimal(0)
601
604
 
602
605
  elif self.time_unit == "days":
603
606
  df = self.get_daily_price(code, today, today)
604
- return typed_result(df["close"].iloc[-1])
607
+ if not df.empty:
608
+ return typed_result(df["close"].iloc[-1])
609
+ else:
610
+ return Decimal(0)
605
611
 
606
612
  else:
607
613
  raise ValueError(f"Invalid time unit: {self.time_unit}")
@@ -814,6 +820,9 @@ class MockBroker(BaseBroker):
814
820
  else:
815
821
  dfs = get_kr_daily_data([code], from_date, end_date, adjusted=True, ascending=True, exchange=DataExchange.KRX)
816
822
 
823
+ if code not in dfs:
824
+ return pd.DataFrame()
825
+
817
826
  df = dfs[code]
818
827
 
819
828
  if not df.empty and end_date == today:
@@ -1700,6 +1700,7 @@ class KISDomesticStock:
1700
1700
  fid_input_price_1: int = None,
1701
1701
  fid_input_price_2: int = None,
1702
1702
  fid_vol_cnt: int = None,
1703
+ fid_cond_mrkt_div_code: str = "J",
1703
1704
  ):
1704
1705
  """
1705
1706
  (국내주식시세) 거래량순위[v1_국내주식-047]
@@ -1745,6 +1746,8 @@ class KISDomesticStock:
1745
1746
  | ex) 100000
1746
1747
  | 전체 거래량 대상 조회 시 FID_VOL_CNT None
1747
1748
 
1749
+ fid_cond_mrkt_div_code (str): FID 조건시장분류코드 - J:KRX, NX:NXT
1750
+
1748
1751
  Returns:
1749
1752
  dict:
1750
1753
 
@@ -1786,11 +1789,12 @@ class KISDomesticStock:
1786
1789
  assert fid_input_price_1 is None or isinstance(fid_input_price_1, int), "fid_input_price_1 must be None or int"
1787
1790
  assert fid_input_price_2 is None or isinstance(fid_input_price_2, int), "fid_input_price_2 must be None or int"
1788
1791
  assert fid_vol_cnt is None or isinstance(fid_vol_cnt, int), "fid_vol_cnt must be None or int"
1792
+ assert fid_cond_mrkt_div_code in ["J", "NX"], "fid_cond_mrkt_div_code must be 'J' or 'NX'"
1789
1793
 
1790
1794
  url_path = "/uapi/domestic-stock/v1/quotations/volume-rank"
1791
1795
  tr_id = "FHPST01710000"
1792
1796
  params = {
1793
- "FID_COND_MRKT_DIV_CODE": "J",
1797
+ "FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code,
1794
1798
  "FID_COND_SCR_DIV_CODE": "20171",
1795
1799
  "FID_INPUT_ISCD": fid_input_iscd,
1796
1800
  "FID_DIV_CLS_CODE": fid_div_cls_code,
@@ -2194,7 +2198,14 @@ class KISDomesticStock:
2194
2198
 
2195
2199
  return result
2196
2200
 
2197
- def inquire_daily_trade_volume(self, fid_input_iscd: str, fid_input_date_1: dtm.date, fid_input_date_2: dtm.date, tr_cont: str = ""):
2201
+ def inquire_daily_trade_volume(
2202
+ self,
2203
+ fid_input_iscd: str,
2204
+ fid_input_date_1: dtm.date,
2205
+ fid_input_date_2: dtm.date,
2206
+ tr_cont: str = "",
2207
+ fid_cond_mrkt_div_code: str = "J",
2208
+ ):
2198
2209
  """
2199
2210
  (국내주식시세) 종목별일별매수매도체결량 [v1_국내주식-056]
2200
2211
 
@@ -2206,6 +2217,7 @@ class KISDomesticStock:
2206
2217
  fid_input_date_1 (dtm.date): 입력 일자1 - from
2207
2218
  fid_input_date_2 (dtm.date): 입력 일자2 - to
2208
2219
  tr_cont (str): 연속조회여부
2220
+ fid_cond_mrkt_div_code (str): FID 조건시장분류코드 - J:KRX, NX:NXT, UN:통합
2209
2221
 
2210
2222
  Returns:
2211
2223
  dict:
@@ -2230,10 +2242,17 @@ class KISDomesticStock:
2230
2242
  ValueError: API 에러 발생시
2231
2243
  """
2232
2244
  assert not self.auth.paper_trading, "실전계좌에서만 사용 가능한 API입니다."
2245
+ assert fid_cond_mrkt_div_code in ["J", "NX", "UN"], "fid_cond_mrkt_div_code must be 'J', 'NX' or 'UN'"
2233
2246
 
2234
2247
  url_path = "/uapi/domestic-stock/v1/quotations/inquire-daily-trade-volume"
2235
2248
  tr_id = "FHKST03010800"
2236
- params = {"FID_COND_MRKT_DIV_CODE": "J", "FID_INPUT_ISCD": fid_input_iscd, "FID_INPUT_DATE_1": fid_input_date_1.strftime("%Y%m%d"), "FID_INPUT_DATE_2": fid_input_date_2.strftime("%Y%m%d"), "FID_PERIOD_DIV_CODE": "D"}
2249
+ params = {
2250
+ "FID_COND_MRKT_DIV_CODE": fid_cond_mrkt_div_code,
2251
+ "FID_INPUT_ISCD": fid_input_iscd,
2252
+ "FID_INPUT_DATE_1": fid_input_date_1.strftime("%Y%m%d"),
2253
+ "FID_INPUT_DATE_2": fid_input_date_2.strftime("%Y%m%d"),
2254
+ "FID_PERIOD_DIV_CODE": "D",
2255
+ }
2237
2256
  res_body, res_headers = self._tr_request(url_path, tr_id, tr_cont, params=params)
2238
2257
 
2239
2258
  if res_body["rt_cd"] != "0":
@@ -25,7 +25,7 @@ class KISTRClient:
25
25
  self.corp_data = corp_data
26
26
  self.session = requests.Session()
27
27
 
28
- @retry(requests.HTTPError)
28
+ @retry(requests.RequestException)
29
29
  def request(self, path: str, tr_id: str, tr_cont: str = "", params: dict = None, body: dict = None, method: str = "GET"):
30
30
  """
31
31
  TR 요청을 보내고 응답을 받는 메서드
@@ -1,6 +1,6 @@
1
1
  import datetime
2
2
  from decimal import ROUND_CEILING, ROUND_FLOOR, ROUND_HALF_UP, Decimal
3
- from typing import Union
3
+ from typing import Union, Optional
4
4
 
5
5
 
6
6
  def quantize_krx_price(price: Union[Decimal, int, float], etf_etn: bool, rounding: str = "floor") -> int:
@@ -50,7 +50,7 @@ def get_krx_tick_size(
50
50
  price: float,
51
51
  etf_etn: bool,
52
52
  market: str = "KOSPI",
53
- date: datetime.date = None,
53
+ date: Optional[datetime.date] = None,
54
54
  ) -> int:
55
55
  """
56
56
  주어진 가격과 금융 상품 유형에 따라 적절한 호가가격단위를 반환합니다.