pyqqq-script 0.0.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.
- pyqqq3/__init__.py +15 -0
- pyqqq3/application/__init__.py +0 -0
- pyqqq3/application/backtest.py +213 -0
- pyqqq3/application/live.py +142 -0
- pyqqq3/application/messaging/__init__.py +5 -0
- pyqqq3/application/messaging/bus.py +38 -0
- pyqqq3/application/session.py +48 -0
- pyqqq3/application/store.py +87 -0
- pyqqq3/auth.py +28 -0
- pyqqq3/infra/__init__.py +0 -0
- pyqqq3/infra/broker/__init__.py +0 -0
- pyqqq3/infra/broker/kis.py +134 -0
- pyqqq3/infra/broker/mock.py +599 -0
- pyqqq3/infra/data/__init__.py +0 -0
- pyqqq3/infra/data/historical.py +159 -0
- pyqqq3/infra/data/symbols.py +49 -0
- pyqqq3/infra/presentation/__init__.py +9 -0
- pyqqq3/infra/presentation/cli_reporter.py +60 -0
- pyqqq3/infra/store/__init__.py +0 -0
- pyqqq3/infra/store/file.py +168 -0
- pyqqq3/infra/store/http.py +403 -0
- pyqqq3/infra/store/mongo.py +361 -0
- pyqqq3/model/__init__.py +0 -0
- pyqqq3/model/account.py +127 -0
- pyqqq3/model/execution/__init__.py +24 -0
- pyqqq3/model/execution/events.py +64 -0
- pyqqq3/model/execution/journal.py +132 -0
- pyqqq3/model/execution/order.py +32 -0
- pyqqq3/model/result.py +280 -0
- pyqqq3/model/symbol.py +39 -0
- pyqqq3/model/symbol_repository.py +31 -0
- pyqqq3/model/types.py +90 -0
- pyqqq3/strategy/__init__.py +11 -0
- pyqqq3/strategy/base.py +132 -0
- pyqqq3/strategy/series.py +101 -0
- pyqqq3/strategy/ta.py +269 -0
- pyqqq3/trading/__init__.py +0 -0
- pyqqq3/trading/broker.py +47 -0
- pyqqq3/trading/engine.py +122 -0
- pyqqq3/trading/feed.py +27 -0
- pyqqq_script-0.0.1.dist-info/METADATA +75 -0
- pyqqq_script-0.0.1.dist-info/RECORD +43 -0
- pyqqq_script-0.0.1.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"""KISDomesticBroker — 한국투자증권 REST/Websocket 어댑터 (스켈레톤).
|
|
2
|
+
|
|
3
|
+
실제 API 연동은 추후 작성한다. 이 파일은 Broker 계약 형태와
|
|
4
|
+
이벤트 발행 헬퍼만 제공해 LiveTrading 이 Backtest 와 동일한 구조로
|
|
5
|
+
조립될 수 있음을 보여준다.
|
|
6
|
+
|
|
7
|
+
외부로 나가는 것 (이 어댑터의 책임):
|
|
8
|
+
buy/sell/cancel → KIS REST 주문 API
|
|
9
|
+
set_stop_loss/set_take_profit/set_trailing_stop → 로컬 상태
|
|
10
|
+
|
|
11
|
+
외부에서 들어오는 것 (Account 에 반영될 이벤트):
|
|
12
|
+
OrderSubmitted — 주문 접수 응답
|
|
13
|
+
OrderRejected — 주문 거부 응답
|
|
14
|
+
FillExecuted — 체결 통보 (websocket)
|
|
15
|
+
CashDeposited — 초기 잔고 조회 응답
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import datetime as dt
|
|
21
|
+
import logging
|
|
22
|
+
from decimal import Decimal
|
|
23
|
+
from typing import TYPE_CHECKING, Callable
|
|
24
|
+
|
|
25
|
+
from pyqqq3.model.types import Bar, OrderSide, Position
|
|
26
|
+
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from pyqqq3.model.execution.events import ExecutionEvent
|
|
29
|
+
from pyqqq3.model.symbol import Symbol
|
|
30
|
+
|
|
31
|
+
_log = logging.getLogger("pyqqq3.broker.kis")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class KISDomesticBroker:
|
|
35
|
+
"""한국투자증권 브로커 어댑터 (스켈레톤 / 미구현).
|
|
36
|
+
|
|
37
|
+
Attributes:
|
|
38
|
+
symbol: 단일 종목 전용 (향후 멀티심볼 확장 여지).
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def __init__(
|
|
42
|
+
self,
|
|
43
|
+
symbol: "Symbol",
|
|
44
|
+
event_sink: "Callable[[ExecutionEvent], None]",
|
|
45
|
+
account_no: str = "",
|
|
46
|
+
) -> None:
|
|
47
|
+
self._symbol = symbol
|
|
48
|
+
self._emit: Callable[[ExecutionEvent], None] = event_sink
|
|
49
|
+
self._account_no = account_no
|
|
50
|
+
self._seq = 0
|
|
51
|
+
self._stop_loss_pct: float | None = None
|
|
52
|
+
self._take_profit_pct: float | None = None
|
|
53
|
+
self._trailing_pct: float | None = None
|
|
54
|
+
|
|
55
|
+
# ------------------------------------------------------------------ Broker interface
|
|
56
|
+
|
|
57
|
+
def process(self, bar: Bar) -> None:
|
|
58
|
+
"""실시간 모드에서는 no-op. 체결은 외부 이벤트로 들어온다."""
|
|
59
|
+
# 향후: 봉 단위 리스크 체크가 필요하면 여기에. 단, 실제 손절/익절 주문은
|
|
60
|
+
# 거래소에 미리 걸어두거나(OCO), websocket 에서 판단.
|
|
61
|
+
|
|
62
|
+
def buy(
|
|
63
|
+
self,
|
|
64
|
+
current_price: Decimal,
|
|
65
|
+
qty: int | None = None,
|
|
66
|
+
amount: int | None = None,
|
|
67
|
+
pct: float | None = None,
|
|
68
|
+
) -> None:
|
|
69
|
+
raise NotImplementedError("KIS 주문 API 연동 필요")
|
|
70
|
+
|
|
71
|
+
def sell(
|
|
72
|
+
self,
|
|
73
|
+
current_price: Decimal,
|
|
74
|
+
qty: int | None = None,
|
|
75
|
+
pct: float | None = None,
|
|
76
|
+
) -> None:
|
|
77
|
+
raise NotImplementedError("KIS 주문 API 연동 필요")
|
|
78
|
+
|
|
79
|
+
def set_stop_loss(self, pct: float) -> None:
|
|
80
|
+
self._stop_loss_pct = float(pct)
|
|
81
|
+
|
|
82
|
+
def set_take_profit(self, pct: float) -> None:
|
|
83
|
+
self._take_profit_pct = float(pct)
|
|
84
|
+
|
|
85
|
+
def set_trailing_stop(self, pct: float) -> None:
|
|
86
|
+
self._trailing_pct = float(pct)
|
|
87
|
+
|
|
88
|
+
def get_position(self, current_price: Decimal) -> Position:
|
|
89
|
+
raise NotImplementedError("Account 애그리게이트 조회로 위임 예정")
|
|
90
|
+
|
|
91
|
+
# ------------------------------------------------------------------ event emission helpers
|
|
92
|
+
|
|
93
|
+
def _next_seq(self) -> int:
|
|
94
|
+
self._seq += 1
|
|
95
|
+
return self._seq
|
|
96
|
+
|
|
97
|
+
def emit_cash_deposited(self, amount: Decimal) -> None:
|
|
98
|
+
"""초기 잔고 조회 결과를 이벤트로 발행 (run 시작 시 1회)."""
|
|
99
|
+
from pyqqq3.model.execution.events import CashDeposited
|
|
100
|
+
|
|
101
|
+
self._emit(
|
|
102
|
+
CashDeposited(
|
|
103
|
+
occurred_at=dt.datetime.now(),
|
|
104
|
+
bar_index=0,
|
|
105
|
+
seq=self._next_seq(),
|
|
106
|
+
amount=amount,
|
|
107
|
+
)
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
def emit_fill(
|
|
111
|
+
self,
|
|
112
|
+
order_id: str,
|
|
113
|
+
side: OrderSide,
|
|
114
|
+
price: Decimal,
|
|
115
|
+
quantity: int,
|
|
116
|
+
commission: Decimal,
|
|
117
|
+
occurred_at: dt.datetime,
|
|
118
|
+
bar_index: int = 0,
|
|
119
|
+
) -> None:
|
|
120
|
+
"""체결 통보 (websocket callback) → 이벤트로 변환."""
|
|
121
|
+
from pyqqq3.model.execution.events import FillExecuted
|
|
122
|
+
|
|
123
|
+
self._emit(
|
|
124
|
+
FillExecuted(
|
|
125
|
+
occurred_at=occurred_at,
|
|
126
|
+
bar_index=bar_index,
|
|
127
|
+
seq=self._next_seq(),
|
|
128
|
+
order_id=order_id,
|
|
129
|
+
side=side,
|
|
130
|
+
price=price,
|
|
131
|
+
quantity=quantity,
|
|
132
|
+
commission=commission,
|
|
133
|
+
)
|
|
134
|
+
)
|