ksxt 0.0.8__py3-none-any.whl → 0.0.9__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.
- ksxt/__init__.py +3 -1
- ksxt/__pycache__/__init__.cpython-312.pyc +0 -0
- ksxt/__pycache__/bithumb.cpython-312.pyc +0 -0
- ksxt/__pycache__/koreainvest.cpython-312.pyc +0 -0
- ksxt/__pycache__/upbit.cpython-312.pyc +0 -0
- ksxt/api/__init__.py +26 -0
- ksxt/api/__pycache__/__init__.cpython-312.pyc +0 -0
- ksxt/api/__pycache__/bithumb.cpython-312.pyc +0 -0
- ksxt/api/__pycache__/koreainvest.cpython-312.pyc +0 -0
- ksxt/api/__pycache__/upbit.cpython-312.pyc +0 -0
- ksxt/api/auto/api_generator.py +54 -0
- ksxt/api/auto/bithumb.py +35 -0
- ksxt/api/auto/koreainvest.py +49 -0
- ksxt/api/auto/upbit.py +39 -0
- ksxt/api/bithumb.py +42 -0
- ksxt/api/koreainvest.py +40 -0
- ksxt/api/upbit.py +54 -0
- ksxt/async_/__init__.py +4 -0
- ksxt/async_/__pycache__/__init__.cpython-312.pyc +0 -0
- ksxt/async_/__pycache__/bithumb.cpython-312.pyc +0 -0
- ksxt/async_/__pycache__/koreainvest.cpython-312.pyc +0 -0
- ksxt/async_/__pycache__/upbit.cpython-312.pyc +0 -0
- ksxt/async_/base/__init__.py +0 -0
- ksxt/async_/base/__pycache__/__init__.cpython-312.pyc +0 -0
- ksxt/async_/base/__pycache__/async_exchange.cpython-312.pyc +0 -0
- ksxt/async_/base/__pycache__/throttler.cpython-312.pyc +0 -0
- ksxt/async_/base/async_exchange.py +232 -0
- ksxt/async_/base/throttler.py +63 -0
- ksxt/async_/bithumb.py +455 -0
- ksxt/async_/koreainvest.py +849 -0
- ksxt/async_/upbit.py +488 -0
- ksxt/base/__pycache__/__init__.cpython-312.pyc +0 -0
- ksxt/base/__pycache__/errors.cpython-312.pyc +0 -0
- ksxt/base/__pycache__/exchange.cpython-312.pyc +0 -0
- ksxt/base/__pycache__/rest_exchange.cpython-312.pyc +0 -0
- ksxt/base/__pycache__/types.cpython-312.pyc +0 -0
- ksxt/base/com_exchange.py +2 -2
- ksxt/base/errors.py +10 -0
- ksxt/base/exchange.py +188 -497
- ksxt/base/rest_exchange.py +297 -113
- ksxt/base/types.py +1 -36
- ksxt/bithumb.py +504 -0
- ksxt/config/__init__.py +2 -1
- ksxt/config/__pycache__/__init__.cpython-312.pyc +0 -0
- ksxt/config/bithumb.toml +380 -0
- ksxt/config/koreainvest.toml +312 -0
- ksxt/config/token.toml +7 -0
- ksxt/config/upbit.toml +428 -0
- ksxt/koreainvest.py +409 -1055
- ksxt/market/__pycache__/base.cpython-312.pyc +0 -0
- ksxt/market/__pycache__/db.cpython-312.pyc +0 -0
- ksxt/market/__pycache__/logging.cpython-312.pyc +0 -0
- ksxt/market/__pycache__/manager.cpython-312.pyc +0 -0
- ksxt/market/__pycache__/markets.cpython-312.pyc +0 -0
- ksxt/market/base.py +50 -50
- ksxt/market/db.py +5 -4
- ksxt/market/krx/__pycache__/kosdaq.cpython-312.pyc +0 -0
- ksxt/market/krx/__pycache__/kospi.cpython-312.pyc +0 -0
- ksxt/market/krx/__pycache__/stock.cpython-312.pyc +0 -0
- ksxt/market/krx/kosdaq.py +150 -147
- ksxt/market/krx/kospi.py +179 -175
- ksxt/market/krx/stock.py +136 -134
- ksxt/market/logging.py +4 -4
- ksxt/market/manager.py +10 -12
- ksxt/market/markets.py +1 -1
- ksxt/market/us/__pycache__/amex.cpython-312.pyc +0 -0
- ksxt/market/us/__pycache__/nasdaq.cpython-312.pyc +0 -0
- ksxt/market/us/__pycache__/nyse.cpython-312.pyc +0 -0
- ksxt/market/us/__pycache__/stock.cpython-312.pyc +0 -0
- ksxt/market/us/amex.py +31 -31
- ksxt/market/us/nasdaq.py +31 -31
- ksxt/market/us/nyse.py +31 -31
- ksxt/market/us/stock.py +20 -28
- ksxt/models/__init__.py +16 -0
- ksxt/models/__pycache__/__init__.cpython-312.pyc +0 -0
- ksxt/models/__pycache__/balance.cpython-312.pyc +0 -0
- ksxt/models/__pycache__/cash.cpython-312.pyc +0 -0
- ksxt/models/__pycache__/common.cpython-312.pyc +0 -0
- ksxt/models/__pycache__/error.cpython-312.pyc +0 -0
- ksxt/models/__pycache__/historical.cpython-312.pyc +0 -0
- ksxt/models/__pycache__/market.cpython-312.pyc +0 -0
- ksxt/models/__pycache__/order.cpython-312.pyc +0 -0
- ksxt/models/__pycache__/orderbook.cpython-312.pyc +0 -0
- ksxt/models/__pycache__/ticker.cpython-312.pyc +0 -0
- ksxt/models/__pycache__/token.cpython-312.pyc +0 -0
- ksxt/models/__pycache__/transaction.cpython-312.pyc +0 -0
- ksxt/models/balance.py +30 -0
- ksxt/models/cash.py +15 -0
- ksxt/models/common.py +31 -0
- ksxt/models/error.py +13 -0
- ksxt/models/historical.py +26 -0
- ksxt/models/market.py +81 -0
- ksxt/models/order.py +42 -0
- ksxt/models/orderbook.py +32 -0
- ksxt/models/ticker.py +25 -0
- ksxt/models/token.py +14 -0
- ksxt/models/transaction.py +79 -0
- ksxt/parser/__pycache__/bithumb.cpython-312.pyc +0 -0
- ksxt/parser/__pycache__/koreainvest.cpython-312.pyc +0 -0
- ksxt/parser/__pycache__/parser.cpython-312.pyc +0 -0
- ksxt/parser/__pycache__/upbit.cpython-312.pyc +0 -0
- ksxt/parser/bithumb.py +300 -0
- ksxt/parser/koreainvest.py +323 -0
- ksxt/parser/parser.py +114 -0
- ksxt/parser/upbit.py +308 -0
- ksxt/upbit.py +499 -0
- ksxt/utils/__pycache__/safer.cpython-312.pyc +0 -0
- ksxt/utils/__pycache__/sorter.cpython-312.pyc +0 -0
- ksxt/utils/__pycache__/timer.cpython-312.pyc +0 -0
- ksxt/utils/safer.py +48 -0
- ksxt/utils/sorter.py +8 -0
- ksxt/utils/timer.py +47 -0
- {ksxt-0.0.8.dist-info → ksxt-0.0.9.dist-info}/METADATA +11 -1
- ksxt-0.0.9.dist-info/RECORD +119 -0
- {ksxt-0.0.8.dist-info → ksxt-0.0.9.dist-info}/WHEEL +1 -1
- ksxt/__pycache__/__init__.cpython-39.pyc +0 -0
- ksxt/__pycache__/koreainvest.cpython-39.pyc +0 -0
- ksxt/base/__pycache__/__init__.cpython-39.pyc +0 -0
- ksxt/base/__pycache__/exchange.cpython-39.pyc +0 -0
- ksxt/base/__pycache__/rest_exchange.cpython-39.pyc +0 -0
- ksxt/base/__pycache__/restexchange.cpython-39.pyc +0 -0
- ksxt/base/__pycache__/types.cpython-39.pyc +0 -0
- ksxt/base/api_response.py +0 -68
- ksxt/config/__pycache__/__init__.cpython-39.pyc +0 -0
- ksxt/config/tr_app.json +0 -381
- ksxt/config/tr_dev.json +0 -446
- ksxt/market/__pycache__/base.cpython-39.pyc +0 -0
- ksxt/market/__pycache__/db.cpython-39.pyc +0 -0
- ksxt/market/__pycache__/logging.cpython-39.pyc +0 -0
- ksxt/market/__pycache__/manager.cpython-39.pyc +0 -0
- ksxt/market/__pycache__/markets.cpython-39.pyc +0 -0
- ksxt/market/krx/__pycache__/kosdaq.cpython-39.pyc +0 -0
- ksxt/market/krx/__pycache__/kospi.cpython-39.pyc +0 -0
- ksxt/market/krx/__pycache__/stock.cpython-39.pyc +0 -0
- ksxt/market/us/__pycache__/amex.cpython-39.pyc +0 -0
- ksxt/market/us/__pycache__/nasdaq.cpython-39.pyc +0 -0
- ksxt/market/us/__pycache__/nyse.cpython-39.pyc +0 -0
- ksxt/market/us/__pycache__/stock.cpython-39.pyc +0 -0
- ksxt-0.0.8.dist-info/RECORD +0 -49
- {ksxt-0.0.8.dist-info → ksxt-0.0.9.dist-info}/LICENSE.txt +0 -0
- {ksxt-0.0.8.dist-info → ksxt-0.0.9.dist-info}/top_level.txt +0 -0
ksxt/bithumb.py
ADDED
@@ -0,0 +1,504 @@
|
|
1
|
+
import base64
|
2
|
+
import hashlib
|
3
|
+
import hmac
|
4
|
+
import json
|
5
|
+
import time
|
6
|
+
from datetime import datetime
|
7
|
+
from typing import Any, Dict, List, Literal, Optional
|
8
|
+
from urllib.parse import urlencode
|
9
|
+
import uuid
|
10
|
+
|
11
|
+
import jwt
|
12
|
+
import pytz
|
13
|
+
|
14
|
+
from ksxt.api.bithumb import ImplicitAPI
|
15
|
+
from ksxt.base.rest_exchange import RestExchange
|
16
|
+
from ksxt.parser.bithumb import BithumbParser
|
17
|
+
|
18
|
+
import ksxt.models
|
19
|
+
|
20
|
+
|
21
|
+
class Bithumb(RestExchange, ImplicitAPI):
|
22
|
+
def __init__(self, config: Dict = None) -> None:
|
23
|
+
super().__init__(config, "bithumb.toml")
|
24
|
+
self.parser = BithumbParser()
|
25
|
+
self.timezone = pytz.timezone("Asia/Seoul")
|
26
|
+
|
27
|
+
def safe_symbol(self, base_market: str, security: str) -> str:
|
28
|
+
return f"{base_market}-{security}"
|
29
|
+
|
30
|
+
def safe_security(self, symbol: str) -> str:
|
31
|
+
if symbol.find("-") < 0:
|
32
|
+
return symbol
|
33
|
+
return symbol.split("-")[1]
|
34
|
+
|
35
|
+
def sign(
|
36
|
+
self,
|
37
|
+
path,
|
38
|
+
security_type,
|
39
|
+
method_type,
|
40
|
+
api_type: Any = "public",
|
41
|
+
headers: Optional[Any] = None,
|
42
|
+
body: Optional[Any] = None,
|
43
|
+
params: Optional[Any] = None,
|
44
|
+
config={},
|
45
|
+
):
|
46
|
+
host_url = self.apis[self.type]["hostname"]
|
47
|
+
destination = self.apis[self.type][security_type][path]["url"]
|
48
|
+
version = self.apis[self.type]["version"]
|
49
|
+
destination = self.implode_params(destination, params)
|
50
|
+
|
51
|
+
url = host_url + "/" + version + "/" + destination
|
52
|
+
|
53
|
+
if api_type == "private":
|
54
|
+
payload = {
|
55
|
+
"access_key": self.open_key,
|
56
|
+
"nonce": str(uuid.uuid4()),
|
57
|
+
"timestamp": round(self.milliseconds()),
|
58
|
+
}
|
59
|
+
|
60
|
+
if params is not None and len(params) > 0:
|
61
|
+
query = urlencode(params).encode()
|
62
|
+
|
63
|
+
hash = hashlib.sha512()
|
64
|
+
hash.update(query)
|
65
|
+
query_hash = hash.hexdigest()
|
66
|
+
|
67
|
+
payload.update({"query_hash": query_hash, "query_hash_alg": "SHA512"})
|
68
|
+
|
69
|
+
jwt_token = jwt.encode(payload=payload, key=self.secret_key)
|
70
|
+
authorization_token = f"Bearer {jwt_token}"
|
71
|
+
|
72
|
+
if headers is None:
|
73
|
+
headers = {}
|
74
|
+
headers.update(
|
75
|
+
{"Content-Type": "application/json; charset=utf-8", "Authorization": authorization_token}
|
76
|
+
)
|
77
|
+
|
78
|
+
if method_type.upper() == "POST":
|
79
|
+
body = json.dumps(params)
|
80
|
+
params = {}
|
81
|
+
|
82
|
+
return {"url": url, "method": method_type, "headers": headers, "body": body, "params": params}
|
83
|
+
|
84
|
+
def get_common_response(self, response):
|
85
|
+
if "error" in response:
|
86
|
+
return self.create_common_response(
|
87
|
+
success="1",
|
88
|
+
msg_code=self.safe_string(response["error"], "name"),
|
89
|
+
msg=self.safe_string(response["error"], "message"),
|
90
|
+
info=response,
|
91
|
+
)
|
92
|
+
|
93
|
+
return self.create_common_response(
|
94
|
+
success="0",
|
95
|
+
msg_code=self.safe_string(response, "name"),
|
96
|
+
msg=self.safe_string(response, "message"),
|
97
|
+
info=response,
|
98
|
+
)
|
99
|
+
|
100
|
+
def fetch_markets(self, market_name: str = "KRW") -> ksxt.models.KsxtMarketResponse:
|
101
|
+
params = {
|
102
|
+
# 유의종목 필드과 같은 상세 정보 노출 여부(선택 파라미터)
|
103
|
+
"isDetails": True
|
104
|
+
}
|
105
|
+
|
106
|
+
common_header = self.create_common_header(request_params=params)
|
107
|
+
|
108
|
+
response = self.public_get_fetch_markets(self.extend(params))
|
109
|
+
|
110
|
+
common_response = self.get_common_response(response=response)
|
111
|
+
if common_response.success != "0":
|
112
|
+
return ksxt.models.KsxtMarketResponse(header=common_header, response=common_response, info=None)
|
113
|
+
|
114
|
+
parsed_info = self.parser.parse_markets(response=response, base_market=market_name)
|
115
|
+
return ksxt.models.KsxtMarketResponse(header=common_header, response=common_response, info=parsed_info)
|
116
|
+
|
117
|
+
def fetch_historical_data(
|
118
|
+
self, symbol: str, time_frame: str, start: str | None = None, end: str | None = None, base_market: str = "KRW"
|
119
|
+
) -> ksxt.models.KsxtHistoricalDataResponse:
|
120
|
+
params = {"market": self.safe_symbol(base_market=base_market, security=symbol), "count": 200}
|
121
|
+
|
122
|
+
common_header = self.create_common_header(request_params=params)
|
123
|
+
|
124
|
+
# TODO : time_frame 을 어떻게 고정시킬까? 우리는 분봉, 일봉, 주봉, 월봉 만 지원한다고 가정하면?
|
125
|
+
if time_frame.endswith("m"):
|
126
|
+
# TODO : parse number
|
127
|
+
period = 1
|
128
|
+
params.update({"unit": period})
|
129
|
+
|
130
|
+
response = self.public_get_fetch_security_ohlcv_minute(self.extend(params))
|
131
|
+
|
132
|
+
elif time_frame.endswith("D"):
|
133
|
+
response = self.public_get_fetch_security_ohlcv_day(self.extend(params))
|
134
|
+
|
135
|
+
elif time_frame.endswith("W"):
|
136
|
+
response = self.public_get_fetch_security_ohlcv_week(self.extend(params))
|
137
|
+
|
138
|
+
elif time_frame.endswith("M"):
|
139
|
+
response = self.public_get_fetch_security_ohlcv_month(self.extend(params))
|
140
|
+
|
141
|
+
common_response = self.get_common_response(response=response)
|
142
|
+
if common_response.success != "0":
|
143
|
+
return ksxt.models.KsxtHistoricalDataResponse(header=common_header, response=common_response, info=None)
|
144
|
+
|
145
|
+
parsed_response = self.parser.parse_historical_data(response=response, symbol=symbol, base_market=base_market)
|
146
|
+
return ksxt.models.KsxtHistoricalDataResponse(
|
147
|
+
header=common_header, response=common_response, info=parsed_response
|
148
|
+
)
|
149
|
+
|
150
|
+
def fetch_ticker(self, symbol: str, base_market: str = "KRW") -> ksxt.models.KsxtTickerResponse:
|
151
|
+
params = {"markets": self.safe_symbol(base_market=base_market, security=symbol)}
|
152
|
+
|
153
|
+
common_header = self.create_common_header(request_params=params)
|
154
|
+
|
155
|
+
response = self.public_get_fetch_ticker_price(self.extend(params))
|
156
|
+
|
157
|
+
common_response = self.get_common_response(response=response)
|
158
|
+
|
159
|
+
# 실패 시 오류 응답 반환
|
160
|
+
if common_response.success != "0":
|
161
|
+
return ksxt.models.KsxtTickerResponse(header=common_header, response=common_response, info=[])
|
162
|
+
|
163
|
+
# 데이터 파싱
|
164
|
+
parsed_info = self.parser.parse_ticker(response, base_market)
|
165
|
+
|
166
|
+
return ksxt.models.KsxtTickerResponse(header=common_header, response=common_response, info=parsed_info)
|
167
|
+
|
168
|
+
def fetch_tickers(self, symbols: List[str], base_market: str = "KRW") -> ksxt.models.KsxtTickersResponse:
|
169
|
+
symbol = ",".join([self.safe_symbol(base_market, symbol) for symbol in symbols])
|
170
|
+
params = {"markets": symbol}
|
171
|
+
|
172
|
+
common_header = self.create_common_header(request_params=params)
|
173
|
+
|
174
|
+
response = self.public_get_fetch_tickers_price(self.extend(params))
|
175
|
+
|
176
|
+
common_response = self.get_common_response(response=response)
|
177
|
+
|
178
|
+
# 실패 시 오류 응답 반환
|
179
|
+
if common_response.success != "0":
|
180
|
+
return ksxt.models.KsxtTickersResponse(header=common_header, response=common_response, info=[])
|
181
|
+
|
182
|
+
# 데이터 파싱
|
183
|
+
parsed_info = self.parser.parse_tickers(response, base_market)
|
184
|
+
|
185
|
+
return ksxt.models.KsxtTickersResponse(header=common_header, response=common_response, info=parsed_info)
|
186
|
+
|
187
|
+
def fetch_orderbook(self, symbol: str, base_market: str = "KRW") -> ksxt.models.KsxtSingleOrderBookResponse:
|
188
|
+
params = {"markets": self.safe_symbol(base_market, symbol)}
|
189
|
+
|
190
|
+
common_header = self.create_common_header(request_params=params)
|
191
|
+
|
192
|
+
response = self.public_get_fetch_orderbook(self.extend(params))
|
193
|
+
|
194
|
+
common_response = self.get_common_response(response=response)
|
195
|
+
|
196
|
+
# 실패 시 오류 응답 반환
|
197
|
+
if common_response.success != "0":
|
198
|
+
return ksxt.models.KsxtSingleOrderBookResponse(header=common_header, response=common_response, info=None)
|
199
|
+
|
200
|
+
# 데이터 파싱
|
201
|
+
parsed_info = self.parser.parse_orderbook(response, base_market)
|
202
|
+
|
203
|
+
return ksxt.models.KsxtSingleOrderBookResponse(header=common_header, response=common_response, info=parsed_info)
|
204
|
+
|
205
|
+
def fetch_orderbooks(self, symbols: List[str], base_market: str = "KRW") -> ksxt.models.KsxtMultiOrderBookResponse:
|
206
|
+
symbol = ",".join([self.safe_symbol(base_market, symbol) for symbol in symbols])
|
207
|
+
params = {"markets": symbol}
|
208
|
+
|
209
|
+
common_header = self.create_common_header(request_params=params)
|
210
|
+
|
211
|
+
response = self.public_get_fetch_orderbooks(self.extend(params))
|
212
|
+
|
213
|
+
common_response = self.get_common_response(response=response)
|
214
|
+
|
215
|
+
# 실패 시 오류 응답 반환
|
216
|
+
if common_response.success != "0":
|
217
|
+
return ksxt.models.KsxtMultiOrderBookResponse(header=common_header, response=common_response, info=None)
|
218
|
+
|
219
|
+
# 데이터 파싱
|
220
|
+
parsed_info = self.parser.parse_orderbooks(response, base_market)
|
221
|
+
|
222
|
+
return ksxt.models.KsxtMultiOrderBookResponse(header=common_header, response=common_response, info=parsed_info)
|
223
|
+
|
224
|
+
def fetch_balance(self, acc_num: str, base_market: str = "KRW") -> ksxt.models.KsxtBalanceResponse:
|
225
|
+
params = {}
|
226
|
+
|
227
|
+
common_header = self.create_common_header(request_params=params)
|
228
|
+
|
229
|
+
response = self.private_get_fetch_balance(self.extend(params))
|
230
|
+
|
231
|
+
common_response = self.get_common_response(response=response)
|
232
|
+
|
233
|
+
# 실패 시 오류 응답 반환
|
234
|
+
if common_response.success != "0":
|
235
|
+
return ksxt.models.KsxtBalanceResponse(header=common_header, response=common_response, info=None)
|
236
|
+
|
237
|
+
# 데이터 파싱
|
238
|
+
parsed_info = self.parser.parse_balance(response, base_market)
|
239
|
+
|
240
|
+
return ksxt.models.KsxtBalanceResponse(header=common_header, response=common_response, info=parsed_info)
|
241
|
+
|
242
|
+
def fetch_cash(self, acc_num: str, base_market: str = "KRW") -> ksxt.models.KsxtCashResponse:
|
243
|
+
params = {}
|
244
|
+
|
245
|
+
common_header = self.create_common_header(request_params=params)
|
246
|
+
|
247
|
+
response = self.private_get_fetch_cash(self.extend(params))
|
248
|
+
|
249
|
+
common_response = self.get_common_response(response=response)
|
250
|
+
|
251
|
+
# 실패 시 오류 응답 반환
|
252
|
+
if common_response.success != "0":
|
253
|
+
return ksxt.models.KsxtCashResponse(header=common_header, response=common_response, info=None)
|
254
|
+
|
255
|
+
# 데이터 파싱
|
256
|
+
parsed_info = self.parser.parse_cash(response, base_market)
|
257
|
+
|
258
|
+
return ksxt.models.KsxtCashResponse(header=common_header, response=common_response, info=parsed_info)
|
259
|
+
|
260
|
+
def fetch_security(self, symbol: str, base_market: str = "KRW") -> ksxt.models.KsxtSecurityResponse:
|
261
|
+
params = {"market": self.safe_symbol(base_market, symbol)}
|
262
|
+
|
263
|
+
common_header = self.create_common_header(request_params=params)
|
264
|
+
|
265
|
+
response = self.public_get_fetch_security_info(self.extend(params))
|
266
|
+
|
267
|
+
common_response = self.get_common_response(response=response)
|
268
|
+
|
269
|
+
# 실패 시 오류 응답 반환
|
270
|
+
if common_response.success != "0":
|
271
|
+
return ksxt.models.KsxtSecurityResponse(header=common_header, response=common_response, info=None)
|
272
|
+
|
273
|
+
# 데이터 파싱
|
274
|
+
parsed_info = self.parser.parse_security(response, base_market)
|
275
|
+
|
276
|
+
return ksxt.models.KsxtSecurityResponse(header=common_header, response=common_response, info=parsed_info)
|
277
|
+
|
278
|
+
def fetch_trade_fee(self, symbol: Optional[str] = "", base_market: str = "KRW") -> ksxt.models.KsxtTradeFeeResponse:
|
279
|
+
params = {"market": self.safe_symbol(base_market, symbol)}
|
280
|
+
|
281
|
+
common_header = self.create_common_header(request_params=params)
|
282
|
+
|
283
|
+
response = self.private_get_fetch_trade_fee(self.extend(params))
|
284
|
+
|
285
|
+
common_response = self.get_common_response(response=response)
|
286
|
+
if common_response.success != "0":
|
287
|
+
return ksxt.models.KsxtTradeFeeResponse(header=common_header, response=common_response, info=None)
|
288
|
+
|
289
|
+
parsed_info = self.parser.parse_trade_fee(response, base_market)
|
290
|
+
return ksxt.models.KsxtTradeFeeResponse(header=common_header, response=common_response, info=parsed_info)
|
291
|
+
|
292
|
+
def fetch_open_order_detail(
|
293
|
+
self, acc_num: str, order_ids: List[str], base_market: str = "KRW"
|
294
|
+
) -> ksxt.models.KsxtOpenOrderResponse:
|
295
|
+
params = {
|
296
|
+
"uuids": order_ids,
|
297
|
+
#'state': 'wait' #2024.07.27 기준 default 값을 parameter로 설정해서 보내면 API 오류 발생함.
|
298
|
+
}
|
299
|
+
|
300
|
+
common_header = self.create_common_header(request_params=params)
|
301
|
+
|
302
|
+
response = self.private_get_fetch_opened_order_detail(self.extend(params))
|
303
|
+
|
304
|
+
common_response = self.get_common_response(response=response)
|
305
|
+
|
306
|
+
# 실패 시 오류 응답 반환
|
307
|
+
if common_response.success != "0":
|
308
|
+
return ksxt.models.KsxtOpenOrderResponse(header=common_header, response=common_response, info=None)
|
309
|
+
|
310
|
+
# 데이터 파싱
|
311
|
+
parsed_info = self.parser.parse_open_order_history(response, base_market)
|
312
|
+
|
313
|
+
return ksxt.models.KsxtOpenOrderResponse(header=common_header, response=common_response, info=parsed_info)
|
314
|
+
|
315
|
+
def fetch_closed_order_detail(
|
316
|
+
self, acc_num: str, order_ids: List[str], base_market: str = "KRW"
|
317
|
+
) -> ksxt.models.KsxtOpenOrderResponse:
|
318
|
+
params = {
|
319
|
+
"uuids": order_ids,
|
320
|
+
#'state': 'wait' #2024.07.27 기준 default 값을 parameter로 설정해서 보내면 API 오류 발생함.
|
321
|
+
}
|
322
|
+
|
323
|
+
common_header = self.create_common_header(request_params=params)
|
324
|
+
|
325
|
+
response = self.private_get_fetch_closed_order_detail(self.extend(params))
|
326
|
+
|
327
|
+
common_response = self.get_common_response(response=response)
|
328
|
+
|
329
|
+
# 실패 시 오류 응답 반환
|
330
|
+
if common_response.success != "0":
|
331
|
+
return ksxt.models.KsxtOpenOrderResponse(header=common_header, response=common_response, info=None)
|
332
|
+
|
333
|
+
# 데이터 파싱
|
334
|
+
parsed_info = self.parser.parse_closed_order_history(response, base_market)
|
335
|
+
|
336
|
+
return ksxt.models.KsxtOpenOrderResponse(header=common_header, response=common_response, info=parsed_info)
|
337
|
+
|
338
|
+
def fetch_open_order(
|
339
|
+
self,
|
340
|
+
acc_num: str,
|
341
|
+
symbol: str | None = "",
|
342
|
+
start: str | None = None,
|
343
|
+
end: str | None = None,
|
344
|
+
base_market: str = "KRW",
|
345
|
+
) -> ksxt.models.KsxtOpenOrderResponse:
|
346
|
+
params = {
|
347
|
+
"market": self.safe_symbol(base_market, symbol),
|
348
|
+
"uuids": "",
|
349
|
+
#'state': 'wait' #2024.07.27 기준 default 값을 parameter로 설정해서 보내면 API 오류 발생함.
|
350
|
+
}
|
351
|
+
|
352
|
+
common_header = self.create_common_header(request_params=params)
|
353
|
+
|
354
|
+
response = self.private_get_fetch_opened_order(self.extend(params))
|
355
|
+
|
356
|
+
common_response = self.get_common_response(response=response)
|
357
|
+
|
358
|
+
# 실패 시 오류 응답 반환
|
359
|
+
if common_response.success != "0":
|
360
|
+
return ksxt.models.KsxtOpenOrderResponse(header=common_header, response=common_response, info=None)
|
361
|
+
|
362
|
+
# 데이터 파싱
|
363
|
+
parsed_info = self.parser.parse_open_order_history(response, base_market)
|
364
|
+
|
365
|
+
return ksxt.models.KsxtOpenOrderResponse(header=common_header, response=common_response, info=parsed_info)
|
366
|
+
|
367
|
+
def fetch_closed_order(
|
368
|
+
self,
|
369
|
+
acc_num: str,
|
370
|
+
symbol: Optional[str] = "",
|
371
|
+
start: Optional[str] = None,
|
372
|
+
end: Optional[str] = None,
|
373
|
+
base_market: str = "KRW",
|
374
|
+
) -> ksxt.models.KsxtClosedOrderResponse:
|
375
|
+
params = {"market": self.safe_symbol(base_market, symbol), "uuids": "", "state": "done"}
|
376
|
+
|
377
|
+
common_header = self.create_common_header(request_params=params)
|
378
|
+
|
379
|
+
response = self.private_get_fetch_closed_order(self.extend(params))
|
380
|
+
|
381
|
+
common_response = self.get_common_response(response=response)
|
382
|
+
|
383
|
+
# 실패 시 오류 응답 반환
|
384
|
+
if common_response.success != "0":
|
385
|
+
return ksxt.models.KsxtClosedOrderResponse(header=common_header, response=common_response, info=None)
|
386
|
+
|
387
|
+
# 데이터 파싱
|
388
|
+
parsed_info = self.parser.parse_closed_order_history(response, base_market)
|
389
|
+
|
390
|
+
return ksxt.models.KsxtClosedOrderResponse(header=common_header, response=common_response, info=parsed_info)
|
391
|
+
|
392
|
+
def cancel_order(
|
393
|
+
self, acc_num: str, order_id: str, symbol: str | None = "", qty: float = 0, base_market: str = "KRW", **kwargs
|
394
|
+
) -> ksxt.models.KsxtCancelOrderResponse:
|
395
|
+
params = {"uuid": order_id}
|
396
|
+
|
397
|
+
common_header = self.create_common_header(request_params=params)
|
398
|
+
|
399
|
+
response = self.private_delete_send_cancel_order(self.extend(params))
|
400
|
+
|
401
|
+
common_response = self.get_common_response(response=response)
|
402
|
+
|
403
|
+
# 실패 시 오류 응답 반환
|
404
|
+
if common_response.success != "0":
|
405
|
+
return ksxt.models.KsxtCancelOrderResponse(header=common_header, response=common_response, info=None)
|
406
|
+
|
407
|
+
# 데이터 파싱
|
408
|
+
parsed_info = self.parser.parse_cancel_order(response, base_market)
|
409
|
+
|
410
|
+
return ksxt.models.KsxtCancelOrderResponse(header=common_header, response=common_response, info=parsed_info)
|
411
|
+
|
412
|
+
def create_order(
|
413
|
+
self,
|
414
|
+
acc_num: str,
|
415
|
+
symbol: str,
|
416
|
+
ticket_type: Literal["EntryLong", "EntryShort", "ExitLong", "ExitShort"],
|
417
|
+
otype: Literal["limit", "market"],
|
418
|
+
price: Optional[float] = 0,
|
419
|
+
qty: Optional[float] = 0,
|
420
|
+
amount: Optional[float] = 0,
|
421
|
+
base_market: str = "KRW",
|
422
|
+
) -> ksxt.models.KsxtCreateOrderResponse:
|
423
|
+
|
424
|
+
params = {
|
425
|
+
"market": self.safe_symbol(base_market, symbol),
|
426
|
+
}
|
427
|
+
|
428
|
+
if ticket_type == "EntryLong":
|
429
|
+
order_side = "bid"
|
430
|
+
if otype == "limit":
|
431
|
+
params.update({"side": order_side, "volume": qty, "price": price, "ord_type": "limit"})
|
432
|
+
response = self.private_post_send_order_entry(self.extend(params))
|
433
|
+
|
434
|
+
elif otype == "market":
|
435
|
+
params.update({"side": order_side, "price": amount, "ord_type": "price"})
|
436
|
+
response = self.private_post_send_order_entry_market(self.extend(params))
|
437
|
+
|
438
|
+
elif ticket_type == "ExitLong":
|
439
|
+
order_side = "ask"
|
440
|
+
if otype == "limit":
|
441
|
+
params.update({"side": order_side, "volume": qty, "price": price, "ord_type": "limit"})
|
442
|
+
response = self.private_post_send_order_exit(self.extend(params))
|
443
|
+
|
444
|
+
elif otype == "market":
|
445
|
+
params.update({"side": order_side, "volume": qty, "ord_type": "market"})
|
446
|
+
response = self.private_post_send_order_exit_market(self.extend(params))
|
447
|
+
else:
|
448
|
+
raise ValueError(
|
449
|
+
f"Unsupported ticket_type '{ticket_type}'. {__class__.__name__} supports only 'EntryLong' and 'ExitLong'."
|
450
|
+
)
|
451
|
+
|
452
|
+
common_header = self.create_common_header(request_params=params)
|
453
|
+
common_response = self.get_common_response(response=response)
|
454
|
+
|
455
|
+
# 실패 시 오류 응답 반환
|
456
|
+
if common_response.success != "0":
|
457
|
+
return ksxt.models.KsxtCreateOrderResponse(header=common_header, response=common_response, info=None)
|
458
|
+
|
459
|
+
# 데이터 파싱
|
460
|
+
parsed_info = self.parser.parse_create_order(response, base_market)
|
461
|
+
|
462
|
+
return ksxt.models.KsxtCreateOrderResponse(header=common_header, response=common_response, info=parsed_info)
|
463
|
+
|
464
|
+
def fetch_withdrawal_history(
|
465
|
+
self, acc_num: str, base_market: str = "KRW"
|
466
|
+
) -> ksxt.models.KsxtWithdrawalHistoryResponse:
|
467
|
+
params = {"state": "done", "uuids": "", "txids": ""}
|
468
|
+
|
469
|
+
common_header = self.create_common_header(request_params=params)
|
470
|
+
|
471
|
+
response = self.private_get_fetch_withdrawal_history(self.extend(params))
|
472
|
+
|
473
|
+
common_response = self.get_common_response(response=response)
|
474
|
+
|
475
|
+
# 실패 시 오류 응답 반환
|
476
|
+
if common_response.success != "0":
|
477
|
+
return ksxt.models.KsxtWithdrawalHistoryResponse(header=common_header, response=common_response, info=None)
|
478
|
+
|
479
|
+
# 데이터 파싱
|
480
|
+
parsed_info = self.parser.parse_withdrawal_history(response)
|
481
|
+
|
482
|
+
return ksxt.models.KsxtWithdrawalHistoryResponse(
|
483
|
+
header=common_header, response=common_response, info=parsed_info
|
484
|
+
)
|
485
|
+
|
486
|
+
def fetch_deposit_history(self, acc_num: str, base_market: str = "KRW") -> ksxt.models.KsxtDepositHistoryResponse:
|
487
|
+
params = {"state": "ACCEPTED", "uuids": "", "txids": ""}
|
488
|
+
|
489
|
+
common_header = self.create_common_header(request_params=params)
|
490
|
+
|
491
|
+
response = self.private_get_fetch_deposit_history(self.extend(params))
|
492
|
+
|
493
|
+
common_response = self.get_common_response(response=response)
|
494
|
+
|
495
|
+
# 실패 시 오류 응답 반환
|
496
|
+
if common_response.success != "0":
|
497
|
+
return ksxt.models.KsxtWithdrawalHistoryResponse(header=common_header, response=common_response, info=None)
|
498
|
+
|
499
|
+
# 데이터 파싱
|
500
|
+
parsed_info = self.parser.parse_deposit_history(response)
|
501
|
+
|
502
|
+
return ksxt.models.KsxtWithdrawalHistoryResponse(
|
503
|
+
header=common_header, response=common_response, info=parsed_info
|
504
|
+
)
|
ksxt/config/__init__.py
CHANGED
Binary file
|