Skip to content

Commit

Permalink
Merge pull request #53 from Soju06/fix/44-foreign-realtime-order-exec…
Browse files Browse the repository at this point in the history
…ution-event

해외주식 실시간 체결 이벤트 버그 수정
  • Loading branch information
Soju06 authored Nov 6, 2024
2 parents 9af14cc + acd06d2 commit f8380f2
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 16 deletions.
2 changes: 1 addition & 1 deletion pykis/api/account/order.py
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ def __eq__(self, value: object | KisOrderNumber) -> bool:
self.account_number == value.account_number # type: ignore
and self.symbol == value.symbol # type: ignore
and self.market == value.market # type: ignore
and self.branch == value.branch # type: ignore
and (self.foreign or self.branch == value.branch) # type: ignore
and int(self.number) == int(value.number) # type: ignore
)
except AttributeError:
Expand Down
7 changes: 6 additions & 1 deletion pykis/api/websocket/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
KisDomesticRealtimeOrderbook,
KisUSRealtimeOrderbook,
)
from pykis.api.websocket.order_execution import KisDomesticRealtimeOrderExecution
from pykis.api.websocket.order_execution import (
KisDomesticRealtimeOrderExecution,
KisForeignRealtimeOrderExecution,
)
from pykis.api.websocket.price import KisDomesticRealtimePrice, KisForeignRealtimePrice
from pykis.responses.websocket import KisWebsocketResponse

Expand All @@ -15,4 +18,6 @@
"HDFSASP0": KisUSRealtimeOrderbook,
"H0STCNI0": KisDomesticRealtimeOrderExecution,
"H0STCNI9": KisDomesticRealtimeOrderExecution,
"H0GSCNI0": KisForeignRealtimeOrderExecution,
"H0GSCNI9": KisForeignRealtimeOrderExecution,
}
7 changes: 6 additions & 1 deletion pykis/api/websocket/order_execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,9 @@ class KisForeignRealtimeOrderExecution(KisRealtimeExecutionBase):
None, # 12 CNTG_YN 체결여부 1:주문,정정,취소,거부 2:체결
None, # 13 ACPT_YN 접수여부 1:주문접수 2:확인 3:취소(FOK/IOC)
None, # 14 BRNC_NO 지점번호
KisDecimal["quantity"], # 15 ODER_QTY 주문수량
KisDecimal[
"quantity", Decimal(-1)
], # 15 ODER_QTY 주문수량 ,주문통보인 경우 해당 위치 미출력 (주문통보의 주문수량은 CNTG_QTY 위치에 출력). 체결통보인 경우 해당 위치에 주문수량이 출력
None, # 16 ACNT_NAME 계좌명
None, # 17 CNTG_ISNM 체결종목명
KisAny(FOREIGN_MARKET_CODE_MAP.__getitem__)[
Expand Down Expand Up @@ -469,6 +471,9 @@ def __post_init__(self):
self.timezone = get_market_timezone(self.market)
self.time = self.time_kst.astimezone(self.timezone)

if self.quantity < 0:
self.quantity = self.executed_quantity

if self.receipt:
self.quantity = self.executed_quantity
self.executed_quantity = ORDER_QUANTITY(0)
Expand Down
2 changes: 1 addition & 1 deletion pykis/event/filters/order.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def __filter__(
return not (
order.symbol == value.symbol
and order.market == value.market
and order.branch == value.branch
and (order.foreign or order.branch == value.branch)
and int(order.number) == int(value.number)
and order.account_number == value.account_number
)
23 changes: 11 additions & 12 deletions pykis/responses/websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from typing import Any, Iterable, Protocol, TypeVar, get_args, runtime_checkable

from pykis import logging
from pykis.responses.dynamic import KisNoneValueError, KisType
from pykis.responses.dynamic import KisNoneValueError, KisType, empty
from pykis.responses.types import KisAny

__all__ = [
Expand Down Expand Up @@ -111,9 +111,7 @@ def parse(
field = field.default_type()

if field.field is None:
logging.logger.warning(
f"{response_type.__name__}[{i}] 필드의 이름이 지정되지 않았습니다."
)
logging.logger.warning(f"{response_type.__name__}[{i}] 필드의 이름이 지정되지 않았습니다.")
continue

try:
Expand All @@ -124,16 +122,17 @@ def parse(

setattr(response, field.field, value)
except KisNoneValueError:
nullable = (
NoneType in get_args(anno) if (anno := annotation.get(field.field)) else False
)
nullable = NoneType in get_args(anno) if (anno := annotation.get(field.field)) else False

if not nullable:
raise ValueError(
f"{response_type.__name__}.{field.field} 필드가 None일 수 없습니다."
)
default_value = None if field.default is empty else field.default

setattr(response, field.field, None)
if callable(default_value):
default_value = default_value()

if default_value is None and not nullable:
raise ValueError(f"{response_type.__name__}.{field.field} 필드가 None일 수 없습니다.")

setattr(response, field.field, default_value)

except Exception as e:
raise ValueError(
Expand Down

0 comments on commit f8380f2

Please sign in to comment.