pyqqq 0.12.191__tar.gz → 0.12.193__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 (58) hide show
  1. {pyqqq-0.12.191 → pyqqq-0.12.193}/PKG-INFO +1 -1
  2. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyproject.toml +1 -1
  3. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/brokerage/kis/domestic_stock.py +88 -4
  4. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/brokerage/kis/simple.py +4 -2
  5. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/brokerage/kis/tr_client.py +16 -22
  6. {pyqqq-0.12.191 → pyqqq-0.12.193}/README.md +0 -0
  7. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/__init__.py +0 -0
  8. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/backtest/__init__.py +0 -0
  9. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/backtest/broker.py +0 -0
  10. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/backtest/environment.py +0 -0
  11. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/backtest/logger.py +0 -0
  12. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/backtest/positionprovider.py +0 -0
  13. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/backtest/strategy.py +0 -0
  14. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/backtest/utils.py +0 -0
  15. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/backtest/wallclock.py +0 -0
  16. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/brokerage/__init__.py +0 -0
  17. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/brokerage/ebest/__init__.py +0 -0
  18. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/brokerage/ebest/domestic_stock.py +0 -0
  19. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/brokerage/ebest/oauth.py +0 -0
  20. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/brokerage/ebest/simple.py +0 -0
  21. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/brokerage/ebest/tr_client.py +0 -0
  22. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/brokerage/helper.py +0 -0
  23. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/brokerage/kis/__init__.py +0 -0
  24. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/brokerage/kis/oauth.py +0 -0
  25. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/brokerage/kis/overseas_stock.py +0 -0
  26. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/brokerage/kis/simple_overseas.py +0 -0
  27. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/brokerage/multiprocess_tracker.py +0 -0
  28. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/brokerage/tracker.py +0 -0
  29. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/config.py +0 -0
  30. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/data/__init__.py +0 -0
  31. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/data/daily.py +0 -0
  32. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/data/domestic.py +0 -0
  33. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/data/index.py +0 -0
  34. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/data/minutes.py +0 -0
  35. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/data/overseas.py +0 -0
  36. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/data/realtime.py +0 -0
  37. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/data/ticks.py +0 -0
  38. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/data/us_stocks.py +0 -0
  39. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/datatypes.py +0 -0
  40. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/executors/__init__.py +0 -0
  41. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/executors/hook.py +0 -0
  42. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/utils/__init__.py +0 -0
  43. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/utils/api_client.py +0 -0
  44. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/utils/array.py +0 -0
  45. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/utils/casting.py +0 -0
  46. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/utils/compute.py +0 -0
  47. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/utils/copycat.py +0 -0
  48. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/utils/daily_tickers.py +0 -0
  49. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/utils/display.py +0 -0
  50. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/utils/kvstore.py +0 -0
  51. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/utils/limiter.py +0 -0
  52. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/utils/local_cache.py +0 -0
  53. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/utils/logger.py +0 -0
  54. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/utils/market_schedule.py +0 -0
  55. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/utils/mock_api.py +0 -0
  56. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/utils/position_classifier.py +0 -0
  57. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/utils/retry.py +0 -0
  58. {pyqqq-0.12.191 → pyqqq-0.12.193}/pyqqq/utils/singleton.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyqqq
3
- Version: 0.12.191
3
+ Version: 0.12.193
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.191"
3
+ version = "0.12.193"
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"
@@ -1169,12 +1169,12 @@ class KISDomesticStock:
1169
1169
 
1170
1170
  - stck_bsop_date: 주식 영업 일자
1171
1171
  - stck_cntg_hour: 주식 체결 시간
1172
- - acml_tr_pbmn: 누적 거래 대금
1173
1172
  - stck_prpr: 주식 현재가
1174
- - stck_oprc: 주식 시가2
1173
+ - stck_oprc: 주식 시가
1175
1174
  - stck_hgpr: 주식 최고가
1176
1175
  - stck_lwpr: 주식 최저가
1177
1176
  - cntg_vol: 체결 거래량
1177
+ - acml_tr_pbmn: 누적 거래 대금
1178
1178
 
1179
1179
  Raise:
1180
1180
  ValueError: API 에러 발생시
@@ -1985,7 +1985,7 @@ class KISDomesticStock:
1985
1985
  fid_input_hour_1 (dt.time): 조회 시작시간 (ex. dtm.time(15, 30, 0))
1986
1986
  fid_cond_mrkt_div_code (str): FID 조건시장분류코드 - J:주식,ETF,ETN NX:Nextrade UN:통합
1987
1987
  fid_pw_data_incu_yn (str): 과거 데이터 포함 여부 - Y:과거 N:당일만 조회
1988
- fid_fake_tick_incu_yn (str): 허봉 포함 여부 - Y:포함 N:미포함
1988
+ fid_fake_tick_incu_yn (str): 허봉 포함 여부 - 공백
1989
1989
 
1990
1990
  Returns:
1991
1991
  dict:
@@ -2034,7 +2034,7 @@ class KISDomesticStock:
2034
2034
  "FID_INPUT_DATE_1": fid_input_date_1.strftime("%Y%m%d"),
2035
2035
  "FID_INPUT_HOUR_1": fid_input_hour_1.strftime("%H%M%S"),
2036
2036
  "FID_PW_DATA_INCU_YN": fid_pw_data_incu_yn,
2037
- "FID_FAKE_TICK_INCU_YN": fid_fake_tick_incu_yn,
2037
+ "FID_FAKE_TICK_INCU_YN": "",
2038
2038
  }
2039
2039
 
2040
2040
  res_body, res_headers = self._tr_request(url_path, tr_id, params=params)
@@ -3388,6 +3388,90 @@ class KISDomesticStock:
3388
3388
 
3389
3389
  return res_body
3390
3390
 
3391
+ def order_reserve(
3392
+ self,
3393
+ cano: str,
3394
+ acnt_prdt_cd: str,
3395
+ side: str,
3396
+ pdno: str,
3397
+ ord_dvsn_cd: str,
3398
+ ord_qty: int,
3399
+ ord_unpr: int,
3400
+ loan_dt: dtm.date = None,
3401
+ rvsn_ord_end_dt: dtm.date = None,
3402
+ ldng_dt: dtm.date = None,
3403
+ ):
3404
+ """
3405
+ (국내주식주문) 주식예약주문[v1_국내주식-017]
3406
+
3407
+ 국내주식 예약주문 매수/매도 API 입니다.
3408
+
3409
+ [유의사항]
3410
+ 1. 예약주문 가능시간 : 15시 40분 ~ 다음 영업일 7시 30분
3411
+ (단, 서버 초기화 작업 시 예약주문 불가 : 23시 40분 ~ 00시 10분)
3412
+ - 예약주문 처리내역은 통보되지 않으므로 주문처리일 장 시작전에 반드시 주문처리 결과를 확인하시기 바랍니다.
3413
+
3414
+ 2. 예약주문 안내
3415
+ - 예약종료일 미입력 시 일반예약주문으로 최초 도래하는 영업일에 주문 전송됩니다.
3416
+ - 예약종료일 입력 시 기간예약주문으로 최초 예약주문수량 중 미체결 된 수량에 대해 예약종료일까지 매 영업일 주문이 실행됩니다. (예약종료일은 익영업일부터 달력일 기준으로 공휴일 포함하여 최대 30일이 되는 일자까지 입력가능)
3417
+ - 예약주문 접수 처리순서는 일반/기간예약주문 중 신청일자가 빠른 주문이 우선합니다.
3418
+ - 단, 기간예약주문 자동배치시간(약 15시35분 ~ 15시55분)사이 접수되는 주문의 경우 당일에 한해 순서와 상관없이 처리될 수 있습니다.
3419
+ - 기간예약주문 자동배치시간(약 15시35분 ~ 15시55분)에는 예약주문 조회가 제한 될 수 있습니다.
3420
+ - 기간예약주문은 계좌 당 주문건수 최대 1,000건으로 제한됩니다.
3421
+
3422
+ 3. 예약주문 접수내역 중 아래의 사유 등으로 인해 주문이 거부될 수 있사오니, 주문처리일 장 시작전에 반드시 주문처리 결과를 확인하시기 바랍니다.
3423
+ - 주문처리일 기준 : 매수가능금액 부족, 매도가능수량 부족, 주문수량/호가단위 오류, 대주 호가제한, 신용/대주가능종목 변경, 상/하한폭 변경, 시가형성 종목(신규상장 등)의 시장가, 거래서비스 미신청 등
3424
+
3425
+ 4. 익일 예상 상/하한가는 조회시점의 현재가로 계산되며 익일의 유/무상증자, 배당, 감자, 합병, 액면변경 등에 의해 변동될 수 있으며 이로 인해 상/하한가를 벗어나 주문이 거부되는 경우가 발생할 수 있사오니, 주문처리일 장 시작전에 반드시 주문처리결과를 확인하시기 바랍니다.
3426
+
3427
+ 5. 정리매매종목, ELW, 신주인수권증권, 신주인수권증서 등은 가격제한폭(상/하한가) 적용 제외됩니다.
3428
+
3429
+ 6. 영업일 장 시작 후 [기간예약주문] 내역 취소는 해당시점 이후의 예약주문이 취소되는 것으로, 일반주문으로 이미 전환된 주문에는 영향을 미치지 않습니다. 반드시 장 시작전 주문처리결과를 확인하시기 바랍니다.
3430
+
3431
+ Args:
3432
+ cano (str): 종합계좌번호 - 계좌번호 체계(8-2)의 앞 8자리
3433
+ acnt_prdt_cd (str): 계좌상품코드 - 계좌번호 체계(8-2)의 뒤 2자리
3434
+ side (str): 주문 방향 - "sell" 또는 "buy"
3435
+ pdno (str): 종목코드
3436
+ ord_dvsn_cd (str): 주문 구분 코드 - 00:지정가, 01:시장가, 02:조건부지정가, 05:장전 시간외
3437
+ ord_qty (int): 주문 수량
3438
+ ord_unpr (int): 주문 단가
3439
+ loan_dt (dtm.date): 대출일자
3440
+ rsvn_ord_end_dt(dtm.date): 예약주문 종료일자
3441
+ ldng_dt (dtm.date): 대여일자
3442
+ """
3443
+
3444
+ assert side in ["sell", "buy"]
3445
+ assert ord_dvsn_cd in ["00", "01", "02", "05"]
3446
+
3447
+ if rvsn_ord_end_dt:
3448
+ assert rvsn_ord_end_dt > dtm.date.today(), "rvsn_ord_end_dt must be greater than today"
3449
+
3450
+ url_path = "/uapi/domestic-stock/v1/trading/order-resv"
3451
+
3452
+ tr_id = "CTSC0008U"
3453
+
3454
+ req_body = {
3455
+ "CANO": cano,
3456
+ "ACNT_PRDT_CD": acnt_prdt_cd,
3457
+ "PDNO": pdno,
3458
+ "ORD_QTY": str(ord_qty),
3459
+ "ORD_UNPR": str(ord_unpr),
3460
+ "SLL_BUY_DVSN_CD": "01" if side == "sell" else "02",
3461
+ "ORD_DVSN_CD": ord_dvsn_cd,
3462
+ "ORD_OBJT_CBLC_DVSN_CD": "10", # 현금
3463
+ "LOAN_DT": "" if loan_dt is None else loan_dt.strftime("%Y%m%d"),
3464
+ "RSVN_ORD_END_DT": "" if rvsn_ord_end_dt is None else rvsn_ord_end_dt.strftime("%Y%m%d"),
3465
+ "LDNG_DT": "" if ldng_dt is None else ldng_dt.strftime("%Y%m%d"), # 대여일자
3466
+ }
3467
+
3468
+ res_body, _ = self._tr_request(url_path, tr_id, body=req_body, method="POST")
3469
+
3470
+ if res_body["rt_cd"] != "0":
3471
+ raise ValueError(f"Error: ({res_body['msg_cd']}) {res_body['msg1']}")
3472
+
3473
+ return res_body
3474
+
3391
3475
  def order_rvsecncl(
3392
3476
  self,
3393
3477
  cano: str,
@@ -1097,8 +1097,10 @@ class KISSimpleDomesticStock:
1097
1097
  event_type = "rejected"
1098
1098
  elif cancelled:
1099
1099
  event_type = "cancelled"
1100
- order_no = org_order_no # 취소 주문의 경우 원주문번호로 변경
1101
- org_order_no = None
1100
+ # IOC 취소될땐 org_order_no 비어있어서 오류 발생함
1101
+ if org_order_no:
1102
+ order_no = org_order_no # 취소 주문의 경우 원주문번호로 변경
1103
+ org_order_no = None
1102
1104
  elif accepted or updated:
1103
1105
  event_type = "accepted"
1104
1106
  elif executed:
@@ -12,20 +12,22 @@ import websockets
12
12
  class KISTRClient:
13
13
  logger = get_logger(__name__ + ".KISTRClient")
14
14
 
15
- '''
15
+ """
16
16
  한국투자증권 TR 요청을 위한 클라이언트
17
17
 
18
18
  Args:
19
19
  auth (KISAuth): 인증 정보를 담고 있는 객체
20
20
  corp_data (dict): 기업 고객의 경우 추가로 필요한 정보를 담고 있는 객체
21
- '''
21
+ """
22
+
22
23
  def __init__(self, auth: KISAuth, corp_data: dict = None):
23
24
  self.auth = auth
24
25
  self.corp_data = corp_data
26
+ self.session = requests.Session()
25
27
 
26
28
  @retry(requests.HTTPError)
27
- def request(self, path: str, tr_id: str, tr_cont: str = '', params: dict = None, body: dict = None, method: str = 'GET'):
28
- '''
29
+ def request(self, path: str, tr_id: str, tr_cont: str = "", params: dict = None, body: dict = None, method: str = "GET"):
30
+ """
29
31
  TR 요청을 보내고 응답을 받는 메서드
30
32
 
31
33
  Args:
@@ -41,28 +43,22 @@ class KISTRClient:
41
43
 
42
44
  Raises:
43
45
  requests.HTTPError: 요청이 실패한 경우
44
- '''
46
+ """
45
47
  headers = {
46
- 'content-type': 'application/json; charset=utf-8',
47
- 'authorization': f'Bearer {self.auth.get_token()}',
48
- 'appkey': self.auth.appkey,
49
- 'appsecret': self.auth.appsecret,
50
- 'custtype': 'P' if self.corp_data is None else 'B',
51
- 'tr_id': tr_id,
52
- 'tr_cont': tr_cont,
48
+ "content-type": "application/json; charset=utf-8",
49
+ "authorization": f"Bearer {self.auth.get_token()}",
50
+ "appkey": self.auth.appkey,
51
+ "appsecret": self.auth.appsecret,
52
+ "custtype": "P" if self.corp_data is None else "B",
53
+ "tr_id": tr_id,
54
+ "tr_cont": tr_cont,
53
55
  }
54
56
  if self.corp_data is not None:
55
57
  headers.update(self.corp_data)
56
58
 
57
59
  url = f"{self.auth.host_url}{path}"
58
60
 
59
- r = requests.request(
60
- method=method,
61
- url=url,
62
- headers=headers,
63
- params=params,
64
- json=body
65
- )
61
+ r = self.session.request(method=method, url=url, headers=headers, params=params, json=body)
66
62
 
67
63
  if r.status_code != 200:
68
64
  try:
@@ -160,9 +156,7 @@ class KISTRWebsocketClient:
160
156
  await asyncio.sleep(1)
161
157
  continue
162
158
 
163
- async def recv_with_timeout(
164
- self, ws: websockets.WebSocketClientProtocol, timeout: int = 1
165
- ) -> str:
159
+ async def recv_with_timeout(self, ws: websockets.WebSocketClientProtocol, timeout: int = 1) -> str:
166
160
  """timeout 초 동안 수신을 대기하고 수신이 없으면 None을 반환한다"""
167
161
  try:
168
162
  message = await asyncio.wait_for(ws.recv(), timeout=timeout)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes