ksxt 1.0.4__py3-none-any.whl → 1.0.6__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/__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/__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/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/__pycache__/__init__.cpython-312.pyc +0 -0
- ksxt/async_/base/__pycache__/async_exchange.cpython-312.pyc +0 -0
- ksxt/async_/base/async_exchange.py +23 -17
- ksxt/async_/bithumb.py +56 -21
- ksxt/async_/koreainvest.py +87 -8
- ksxt/async_/upbit.py +67 -24
- 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__/rate_limiter.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/exchange.py +42 -23
- ksxt/base/rest_exchange.py +32 -28
- ksxt/bithumb.py +48 -14
- ksxt/config/__pycache__/__init__.cpython-312.pyc +0 -0
- ksxt/config/token.toml +3 -7
- ksxt/koreainvest.py +37 -8
- 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/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/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/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 +17 -4
- ksxt/models/transaction.py +22 -28
- 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 +124 -23
- ksxt/parser/koreainvest.py +84 -21
- ksxt/parser/parser.py +30 -10
- ksxt/parser/upbit.py +134 -27
- ksxt/upbit.py +55 -18
- 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-1.0.4.dist-info → ksxt-1.0.6.dist-info}/METADATA +1 -1
- ksxt-1.0.6.dist-info/RECORD +119 -0
- {ksxt-1.0.4.dist-info → ksxt-1.0.6.dist-info}/WHEEL +1 -1
- ksxt/async_/base/__pycache__/throttler.cpython-312.pyc +0 -0
- ksxt-1.0.4.dist-info/RECORD +0 -120
- {ksxt-1.0.4.dist-info → ksxt-1.0.6.dist-info}/LICENSE.txt +0 -0
- {ksxt-1.0.4.dist-info → ksxt-1.0.6.dist-info}/top_level.txt +0 -0
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -85,7 +85,7 @@ class AsyncExchange(RestExchange):
|
|
85
85
|
self.rate_limiters[api_name].release()
|
86
86
|
|
87
87
|
async def fetch2(
|
88
|
-
self, path, security_type, params={}, headers:
|
88
|
+
self, path, security_type, params={}, headers: Any | None = None, body: Any | None = None, config={}
|
89
89
|
):
|
90
90
|
is_activate = self.apis[self.type][security_type][path]["activate"]
|
91
91
|
if not is_activate:
|
@@ -130,8 +130,8 @@ class AsyncExchange(RestExchange):
|
|
130
130
|
self,
|
131
131
|
symbol: str,
|
132
132
|
time_frame: str,
|
133
|
-
start:
|
134
|
-
end:
|
133
|
+
start: datetime | None = None,
|
134
|
+
end: datetime | None = None,
|
135
135
|
base_market: str = "KRW",
|
136
136
|
) -> ksxt.models.KsxtHistoricalDataResponse:
|
137
137
|
raise NotSupportedError(f"{self.id} {self.fetch_historical_data.__qualname__}() is not supported yet.")
|
@@ -143,7 +143,13 @@ class AsyncExchange(RestExchange):
|
|
143
143
|
raise NotSupportedError(f"{self.id} {self.fetch_user_info.__qualname__}() is not supported yet.")
|
144
144
|
|
145
145
|
async def fetch_balance(
|
146
|
-
self,
|
146
|
+
self,
|
147
|
+
acc_num: str,
|
148
|
+
base_market: str = "KRW",
|
149
|
+
excluded_symbols: list[str] | None = None,
|
150
|
+
included_symbols: list[str] | None = None,
|
151
|
+
filter_delisted: bool = True,
|
152
|
+
min_amount: float = 0,
|
147
153
|
) -> ksxt.models.KsxtBalanceResponse:
|
148
154
|
raise NotSupportedError(f"{self.id} {self.fetch_balance.__qualname__}() is not supported yet.")
|
149
155
|
|
@@ -157,12 +163,12 @@ class AsyncExchange(RestExchange):
|
|
157
163
|
raise NotSupportedError(f"{self.id} {self.fetch_screener.__qualname__}() is not supported yet.")
|
158
164
|
|
159
165
|
async def fetch_deposit_history(
|
160
|
-
self, acc_num: str, base_market: str = "KRW"
|
166
|
+
self, acc_num: str, start: datetime | None = None, end: datetime | None = None, base_market: str = "KRW"
|
161
167
|
) -> ksxt.models.KsxtDepositHistoryResponse:
|
162
168
|
raise NotSupportedError(f"{self.id} {self.fetch_deposit_history.__qualname__}() is not supported yet.")
|
163
169
|
|
164
170
|
async def fetch_withdrawal_history(
|
165
|
-
self, acc_num: str, base_market: str = "KRW"
|
171
|
+
self, acc_num: str, start: datetime | None = None, end: datetime | None = None, base_market: str = "KRW"
|
166
172
|
) -> ksxt.models.KsxtWithdrawalHistoryResponse:
|
167
173
|
raise NotSupportedError(f"{self.id} {self.fetch_withdrawal_history.__qualname__}() is not supported yet.")
|
168
174
|
|
@@ -172,15 +178,15 @@ class AsyncExchange(RestExchange):
|
|
172
178
|
symbol: str,
|
173
179
|
ticket_type: Literal["EntryLong", "EntryShort", "ExitLong", "ExitShort"],
|
174
180
|
otype: Literal["limit", "market"],
|
175
|
-
price:
|
176
|
-
qty:
|
177
|
-
amount:
|
181
|
+
price: float | None = 0,
|
182
|
+
qty: float | None = 0,
|
183
|
+
amount: float | None = 0,
|
178
184
|
base_market: str = "KRW",
|
179
185
|
) -> ksxt.models.KsxtCreateOrderResponse:
|
180
186
|
raise NotSupportedError(f"{self.id} {self.create_order.__qualname__}() is not supported yet.")
|
181
187
|
|
182
188
|
async def cancel_order(
|
183
|
-
self, acc_num: str, order_id: str, symbol:
|
189
|
+
self, acc_num: str, order_id: str, symbol: str | None = "", qty: float = 0, *args, base_market: str = "KRW"
|
184
190
|
) -> ksxt.models.KsxtCancelOrderResponse:
|
185
191
|
raise NotSupportedError(f"{self.id} {self.cancel_order.__qualname__}() is not supported yet.")
|
186
192
|
|
@@ -191,7 +197,7 @@ class AsyncExchange(RestExchange):
|
|
191
197
|
price: float,
|
192
198
|
qty: float,
|
193
199
|
*args,
|
194
|
-
symbol:
|
200
|
+
symbol: str | None = "",
|
195
201
|
base_market: str = "KRW",
|
196
202
|
):
|
197
203
|
raise NotSupportedError(f"{self.id} {self.modify_order.__qualname__}() is not supported yet.")
|
@@ -199,9 +205,9 @@ class AsyncExchange(RestExchange):
|
|
199
205
|
async def fetch_open_order(
|
200
206
|
self,
|
201
207
|
acc_num: str,
|
202
|
-
symbol:
|
203
|
-
start:
|
204
|
-
end:
|
208
|
+
symbol: str | None = "",
|
209
|
+
start: datetime | None = None,
|
210
|
+
end: datetime | None = None,
|
205
211
|
base_market: str = "KRW",
|
206
212
|
) -> ksxt.models.KsxtOpenOrderResponse:
|
207
213
|
raise NotSupportedError(f"{self.id} {self.fetch_open_order.__qualname__}() is not supported yet.")
|
@@ -209,9 +215,9 @@ class AsyncExchange(RestExchange):
|
|
209
215
|
async def fetch_closed_order(
|
210
216
|
self,
|
211
217
|
acc_num: str,
|
212
|
-
symbol:
|
213
|
-
start:
|
214
|
-
end:
|
218
|
+
symbol: str | None = "",
|
219
|
+
start: datetime | None = None,
|
220
|
+
end: datetime | None = None,
|
215
221
|
base_market: str = "KRW",
|
216
222
|
) -> ksxt.models.KsxtClosedOrderResponse:
|
217
223
|
raise NotSupportedError(f"{self.id} {self.fetch_closed_order.__qualname__}() is not supported yet.")
|
ksxt/async_/bithumb.py
CHANGED
@@ -3,7 +3,7 @@ import hashlib
|
|
3
3
|
import hmac
|
4
4
|
import json
|
5
5
|
import time
|
6
|
-
from datetime import datetime
|
6
|
+
from datetime import datetime, timezone
|
7
7
|
from typing import Any, Dict, List, Literal, Optional
|
8
8
|
from urllib.parse import urlencode
|
9
9
|
import uuid
|
@@ -23,6 +23,10 @@ class Bithumb(AsyncExchange, ImplicitAPI):
|
|
23
23
|
self.parser = BithumbParser()
|
24
24
|
|
25
25
|
def safe_symbol(self, base_market: str, security: str) -> str:
|
26
|
+
# If security already contains a hyphen, assume it's correctly formatted
|
27
|
+
if "-" in security:
|
28
|
+
return security
|
29
|
+
|
26
30
|
return f"{base_market}-{security}"
|
27
31
|
|
28
32
|
def sign(
|
@@ -108,10 +112,19 @@ class Bithumb(AsyncExchange, ImplicitAPI):
|
|
108
112
|
return ksxt.models.KsxtMarketResponse(header=common_header, response=common_response, info=parsed_info)
|
109
113
|
|
110
114
|
async def fetch_historical_data(
|
111
|
-
self,
|
115
|
+
self,
|
116
|
+
symbol: str,
|
117
|
+
time_frame: str,
|
118
|
+
start: datetime | None = None,
|
119
|
+
end: datetime | None = None,
|
120
|
+
base_market: str = "KRW",
|
112
121
|
) -> ksxt.models.KsxtHistoricalDataResponse:
|
113
122
|
params = {"market": self.safe_symbol(base_market=base_market, security=symbol), "count": 200}
|
114
123
|
|
124
|
+
if end:
|
125
|
+
end_utc = end.astimezone(timezone.utc)
|
126
|
+
params.update({"to": end_utc.strftime("%Y-%m-%d %H:%M:%S")})
|
127
|
+
|
115
128
|
common_header = self.create_common_header(request_params=params)
|
116
129
|
|
117
130
|
# TODO : time_frame 을 어떻게 고정시킬까? 우리는 분봉, 일봉, 주봉, 월봉 만 지원한다고 가정하면?
|
@@ -135,7 +148,10 @@ class Bithumb(AsyncExchange, ImplicitAPI):
|
|
135
148
|
if common_response.success != "0":
|
136
149
|
return ksxt.models.KsxtHistoricalDataResponse(header=common_header, response=common_response, info=None)
|
137
150
|
|
138
|
-
parsed_response = self.parser.parse_historical_data(
|
151
|
+
parsed_response = self.parser.parse_historical_data(
|
152
|
+
response=response, symbol=symbol, start=start, end=end, base_market=base_market
|
153
|
+
)
|
154
|
+
|
139
155
|
return ksxt.models.KsxtHistoricalDataResponse(
|
140
156
|
header=common_header, response=common_response, info=parsed_response
|
141
157
|
)
|
@@ -220,7 +236,13 @@ class Bithumb(AsyncExchange, ImplicitAPI):
|
|
220
236
|
return ksxt.models.KsxtMultiOrderBookResponse(header=common_header, response=common_response, info=parsed_info)
|
221
237
|
|
222
238
|
async def fetch_balance(
|
223
|
-
self,
|
239
|
+
self,
|
240
|
+
acc_num: str,
|
241
|
+
base_market: str = "KRW",
|
242
|
+
excluded_symbols: list[str] | None = None,
|
243
|
+
included_symbols: list[str] | None = None,
|
244
|
+
filter_delisted: bool = True,
|
245
|
+
min_amount: float = 0,
|
224
246
|
) -> ksxt.models.KsxtBalanceResponse:
|
225
247
|
params = {}
|
226
248
|
|
@@ -235,7 +257,14 @@ class Bithumb(AsyncExchange, ImplicitAPI):
|
|
235
257
|
return ksxt.models.KsxtBalanceResponse(header=common_header, response=common_response, info=None)
|
236
258
|
|
237
259
|
# 데이터 파싱
|
238
|
-
parsed_info = self.parser.parse_balance(
|
260
|
+
parsed_info = self.parser.parse_balance(
|
261
|
+
response=response,
|
262
|
+
base_market=base_market,
|
263
|
+
excluded_symbols=excluded_symbols,
|
264
|
+
included_symbols=included_symbols,
|
265
|
+
filter_delisted=filter_delisted,
|
266
|
+
min_amount=min_amount,
|
267
|
+
)
|
239
268
|
|
240
269
|
return ksxt.models.KsxtBalanceResponse(header=common_header, response=common_response, info=parsed_info)
|
241
270
|
|
@@ -294,9 +323,9 @@ class Bithumb(AsyncExchange, ImplicitAPI):
|
|
294
323
|
async def fetch_open_order(
|
295
324
|
self,
|
296
325
|
acc_num: str,
|
297
|
-
symbol: str
|
298
|
-
start:
|
299
|
-
end:
|
326
|
+
symbol: Optional[str] = "",
|
327
|
+
start: datetime | None = None,
|
328
|
+
end: datetime | None = None,
|
300
329
|
base_market: str = "KRW",
|
301
330
|
) -> ksxt.models.KsxtOpenOrderResponse:
|
302
331
|
params = {
|
@@ -316,7 +345,9 @@ class Bithumb(AsyncExchange, ImplicitAPI):
|
|
316
345
|
return ksxt.models.KsxtOpenOrderResponse(header=common_header, response=common_response, info=None)
|
317
346
|
|
318
347
|
# 데이터 파싱
|
319
|
-
parsed_info = self.parser.parse_open_order_history(
|
348
|
+
parsed_info = self.parser.parse_open_order_history(
|
349
|
+
response=response, start=start, end=end, base_market=base_market
|
350
|
+
)
|
320
351
|
|
321
352
|
return ksxt.models.KsxtOpenOrderResponse(header=common_header, response=common_response, info=parsed_info)
|
322
353
|
|
@@ -324,8 +355,8 @@ class Bithumb(AsyncExchange, ImplicitAPI):
|
|
324
355
|
self,
|
325
356
|
acc_num: str,
|
326
357
|
symbol: Optional[str] = "",
|
327
|
-
start:
|
328
|
-
end:
|
358
|
+
start: datetime | None = None,
|
359
|
+
end: datetime | None = None,
|
329
360
|
base_market: str = "KRW",
|
330
361
|
) -> ksxt.models.KsxtClosedOrderResponse:
|
331
362
|
params = {"market": self.safe_symbol(base_market, symbol), "uuids": "", "state": "done"}
|
@@ -341,7 +372,9 @@ class Bithumb(AsyncExchange, ImplicitAPI):
|
|
341
372
|
return ksxt.models.KsxtClosedOrderResponse(header=common_header, response=common_response, info=None)
|
342
373
|
|
343
374
|
# 데이터 파싱
|
344
|
-
parsed_info = self.parser.parse_closed_order_history(
|
375
|
+
parsed_info = self.parser.parse_closed_order_history(
|
376
|
+
response=response, start=start, end=end, base_market=base_market
|
377
|
+
)
|
345
378
|
|
346
379
|
return ksxt.models.KsxtClosedOrderResponse(header=common_header, response=common_response, info=parsed_info)
|
347
380
|
|
@@ -413,9 +446,9 @@ class Bithumb(AsyncExchange, ImplicitAPI):
|
|
413
446
|
return ksxt.models.KsxtCreateOrderResponse(header=common_header, response=common_response, info=parsed_info)
|
414
447
|
|
415
448
|
async def fetch_withdrawal_history(
|
416
|
-
self, acc_num: str, base_market: str = "KRW"
|
449
|
+
self, acc_num: str, start: datetime | None = None, end: datetime | None = None, base_market: str = "KRW"
|
417
450
|
) -> ksxt.models.KsxtWithdrawalHistoryResponse:
|
418
|
-
params = {"state": "
|
451
|
+
params = {"state": "DONE", "uuids": "", "txids": ""}
|
419
452
|
|
420
453
|
common_header = self.create_common_header(request_params=params)
|
421
454
|
|
@@ -428,14 +461,16 @@ class Bithumb(AsyncExchange, ImplicitAPI):
|
|
428
461
|
return ksxt.models.KsxtWithdrawalHistoryResponse(header=common_header, response=common_response, info=None)
|
429
462
|
|
430
463
|
# 데이터 파싱
|
431
|
-
parsed_info = self.parser.parse_withdrawal_history(
|
464
|
+
parsed_info = self.parser.parse_withdrawal_history(
|
465
|
+
response=response, start=start, end=end, base_market=base_market
|
466
|
+
)
|
432
467
|
|
433
468
|
return ksxt.models.KsxtWithdrawalHistoryResponse(
|
434
469
|
header=common_header, response=common_response, info=parsed_info
|
435
470
|
)
|
436
471
|
|
437
472
|
async def fetch_deposit_history(
|
438
|
-
self, acc_num: str, base_market: str = "KRW"
|
473
|
+
self, acc_num: str, start: datetime | None = None, end: datetime | None = None, base_market: str = "KRW"
|
439
474
|
) -> ksxt.models.KsxtDepositHistoryResponse:
|
440
475
|
params = {"state": "ACCEPTED", "uuids": "", "txids": ""}
|
441
476
|
|
@@ -447,11 +482,11 @@ class Bithumb(AsyncExchange, ImplicitAPI):
|
|
447
482
|
|
448
483
|
# 실패 시 오류 응답 반환
|
449
484
|
if common_response.success != "0":
|
450
|
-
return ksxt.models.
|
485
|
+
return ksxt.models.KsxtDepositHistoryResponse(header=common_header, response=common_response, info=None)
|
451
486
|
|
452
487
|
# 데이터 파싱
|
453
|
-
parsed_info = self.parser.parse_deposit_history(
|
454
|
-
|
455
|
-
return ksxt.models.KsxtWithdrawalHistoryResponse(
|
456
|
-
header=common_header, response=common_response, info=parsed_info
|
488
|
+
parsed_info = self.parser.parse_deposit_history(
|
489
|
+
response=response, start=start, end=end, base_market=base_market
|
457
490
|
)
|
491
|
+
|
492
|
+
return ksxt.models.KsxtDepositHistoryResponse(header=common_header, response=common_response, info=parsed_info)
|
ksxt/async_/koreainvest.py
CHANGED
@@ -125,7 +125,13 @@ class KoreaInvest(AsyncExchange, ImplicitAPI):
|
|
125
125
|
|
126
126
|
@AsyncExchange.check_token
|
127
127
|
async def fetch_balance(
|
128
|
-
self,
|
128
|
+
self,
|
129
|
+
acc_num: str,
|
130
|
+
base_market: str = "KRW",
|
131
|
+
excluded_symbols: list[str] | None = None,
|
132
|
+
included_symbols: list[str] | None = None,
|
133
|
+
filter_delisted: bool = True,
|
134
|
+
min_amount: float = 0,
|
129
135
|
) -> ksxt.models.KsxtBalanceResponse:
|
130
136
|
if base_market == "KRW":
|
131
137
|
params = {
|
@@ -153,7 +159,12 @@ class KoreaInvest(AsyncExchange, ImplicitAPI):
|
|
153
159
|
return ksxt.models.KsxtBalanceResponse(header=common_header, response=common_response, info=None)
|
154
160
|
|
155
161
|
parsed_info = self.parser.parse_balance(
|
156
|
-
response=response,
|
162
|
+
response=response,
|
163
|
+
base_market=base_market,
|
164
|
+
excluded_symbols=excluded_symbols,
|
165
|
+
included_symbols=included_symbols,
|
166
|
+
filter_delisted=filter_delisted,
|
167
|
+
min_amount=min_amount,
|
157
168
|
)
|
158
169
|
|
159
170
|
return ksxt.models.KsxtBalanceResponse(header=common_header, response=common_response, info=parsed_info)
|
@@ -248,7 +259,12 @@ class KoreaInvest(AsyncExchange, ImplicitAPI):
|
|
248
259
|
|
249
260
|
@AsyncExchange.check_token
|
250
261
|
async def fetch_historical_data_index(
|
251
|
-
self,
|
262
|
+
self,
|
263
|
+
symbol: str,
|
264
|
+
time_frame: str,
|
265
|
+
start: datetime | None = None,
|
266
|
+
end: datetime | None = None,
|
267
|
+
base_market: str = "KRW",
|
252
268
|
) -> ksxt.models.KsxtHistoricalDataResponse:
|
253
269
|
if time_frame.endswith("D"):
|
254
270
|
param_code = "D"
|
@@ -285,13 +301,22 @@ class KoreaInvest(AsyncExchange, ImplicitAPI):
|
|
285
301
|
if common_response.success != "0":
|
286
302
|
return ksxt.models.KsxtHistoricalDataResponse(header=common_header, response=common_response, info=None)
|
287
303
|
|
288
|
-
|
304
|
+
parsed_response = self.parser.parse_historical_index_data(
|
305
|
+
response=response, symbol=symbol, start=start, end=end, base_market=base_market
|
306
|
+
)
|
289
307
|
|
290
|
-
return ksxt.models.KsxtHistoricalDataResponse(
|
308
|
+
return ksxt.models.KsxtHistoricalDataResponse(
|
309
|
+
header=common_header, response=common_response, info=parsed_response
|
310
|
+
)
|
291
311
|
|
292
312
|
@AsyncExchange.check_token
|
293
313
|
async def fetch_historical_data(
|
294
|
-
self,
|
314
|
+
self,
|
315
|
+
symbol: str,
|
316
|
+
time_frame: str,
|
317
|
+
start: datetime | None = None,
|
318
|
+
end: datetime | None = None,
|
319
|
+
base_market: str = "KRW",
|
295
320
|
) -> ksxt.models.KsxtHistoricalDataResponse:
|
296
321
|
if time_frame.endswith("D"):
|
297
322
|
param_code = "D"
|
@@ -341,9 +366,63 @@ class KoreaInvest(AsyncExchange, ImplicitAPI):
|
|
341
366
|
if common_response.success != "0":
|
342
367
|
return ksxt.models.KsxtHistoricalDataResponse(header=common_header, response=common_response, info=None)
|
343
368
|
|
344
|
-
|
369
|
+
parsed_response = self.parser.parse_historical_data(
|
370
|
+
response=response, symbol=symbol, start=start, end=end, base_market=base_market
|
371
|
+
)
|
372
|
+
|
373
|
+
return ksxt.models.KsxtHistoricalDataResponse(
|
374
|
+
header=common_header, response=common_response, info=parsed_response
|
375
|
+
)
|
376
|
+
|
377
|
+
@AsyncExchange.check_token
|
378
|
+
async def fetch_deposit_history(
|
379
|
+
self, acc_num: str, start: datetime | None = None, end: datetime | None = None, base_market: str = "KRW"
|
380
|
+
) -> ksxt.models.KsxtDepositHistoryResponse:
|
381
|
+
params = {"state": "ACCEPTED", "uuids": "", "txids": ""}
|
382
|
+
|
383
|
+
common_header = self.create_common_header(request_params=params)
|
345
384
|
|
346
|
-
|
385
|
+
response = await self.private_get_fetch_deposit_history(self.extend(params))
|
386
|
+
|
387
|
+
common_response = self.get_common_response(response=response)
|
388
|
+
|
389
|
+
# 실패 시 오류 응답 반환
|
390
|
+
if common_response.success != "0":
|
391
|
+
return ksxt.models.KsxtWithdrawalHistoryResponse(header=common_header, response=common_response, info=None)
|
392
|
+
|
393
|
+
# 데이터 파싱
|
394
|
+
parsed_info = self.parser.parse_deposit_history(
|
395
|
+
response=response, start=start, end=end, base_market=base_market
|
396
|
+
)
|
397
|
+
|
398
|
+
return ksxt.models.KsxtWithdrawalHistoryResponse(
|
399
|
+
header=common_header, response=common_response, info=parsed_info
|
400
|
+
)
|
401
|
+
|
402
|
+
@AsyncExchange.check_token
|
403
|
+
async def fetch_withdrawal_history(
|
404
|
+
self, acc_num: str, start: datetime | None = None, end: datetime | None = None, base_market: str = "KRW"
|
405
|
+
) -> ksxt.models.KsxtWithdrawalHistoryResponse:
|
406
|
+
params = {"state": "done", "uuids": "", "txids": ""}
|
407
|
+
|
408
|
+
common_header = self.create_common_header(request_params=params)
|
409
|
+
|
410
|
+
response = await self.private_get_fetch_withdrawal_history(self.extend(params))
|
411
|
+
|
412
|
+
common_response = self.get_common_response(response=response)
|
413
|
+
|
414
|
+
# 실패 시 오류 응답 반환
|
415
|
+
if common_response.success != "0":
|
416
|
+
return ksxt.models.KsxtWithdrawalHistoryResponse(header=common_header, response=common_response, info=None)
|
417
|
+
|
418
|
+
# 데이터 파싱
|
419
|
+
parsed_info = self.parser.parse_withdrawal_history(
|
420
|
+
response=response, start=start, end=end, base_market=base_market
|
421
|
+
)
|
422
|
+
|
423
|
+
return ksxt.models.KsxtWithdrawalHistoryResponse(
|
424
|
+
header=common_header, response=common_response, info=parsed_info
|
425
|
+
)
|
347
426
|
|
348
427
|
@AsyncExchange.check_token
|
349
428
|
async def modify_order(
|
ksxt/async_/upbit.py
CHANGED
@@ -2,7 +2,7 @@ import hashlib
|
|
2
2
|
import json
|
3
3
|
import time
|
4
4
|
import uuid
|
5
|
-
from datetime import datetime
|
5
|
+
from datetime import datetime, timezone
|
6
6
|
from typing import Any, Dict, List, Literal, Optional
|
7
7
|
from urllib.parse import urlencode
|
8
8
|
|
@@ -90,7 +90,7 @@ class Upbit(AsyncExchange, ImplicitAPI):
|
|
90
90
|
info=response,
|
91
91
|
)
|
92
92
|
|
93
|
-
async def fetch_markets(self,
|
93
|
+
async def fetch_markets(self, market_name: str = "KRW") -> ksxt.models.KsxtMarketResponse:
|
94
94
|
params = {"isDetails": "True"}
|
95
95
|
|
96
96
|
common_header = self.create_common_header(request_params=params)
|
@@ -101,7 +101,7 @@ class Upbit(AsyncExchange, ImplicitAPI):
|
|
101
101
|
if common_response.success != "0":
|
102
102
|
return ksxt.models.KsxtMarketResponse(header=common_header, response=common_response, info=None)
|
103
103
|
|
104
|
-
parsed_info = self.parser.parse_markets(response=response, base_market=
|
104
|
+
parsed_info = self.parser.parse_markets(response=response, base_market=market_name)
|
105
105
|
|
106
106
|
return ksxt.models.KsxtMarketResponse(header=common_header, response=common_response, info=parsed_info)
|
107
107
|
|
@@ -110,6 +110,10 @@ class Upbit(AsyncExchange, ImplicitAPI):
|
|
110
110
|
) -> ksxt.models.KsxtHistoricalDataResponse:
|
111
111
|
params = {"market": self.safe_symbol(base_market, symbol), "count": 200}
|
112
112
|
|
113
|
+
if end:
|
114
|
+
end_utc = end.astimezone(timezone.utc)
|
115
|
+
params.update({"to": end_utc.strftime("%Y-%m-%d %H:%M:%S")})
|
116
|
+
|
113
117
|
# TODO : time_frame 을 어떻게 고정시킬까? 우리는 분봉, 일봉, 주봉, 월봉 만 지원한다고 가정하면?
|
114
118
|
if time_frame.endswith("m"):
|
115
119
|
# TODO : parse number
|
@@ -135,9 +139,13 @@ class Upbit(AsyncExchange, ImplicitAPI):
|
|
135
139
|
if common_response.success != "0":
|
136
140
|
return ksxt.models.KsxtHistoricalDataResponse(header=common_header, response=common_response, info=None)
|
137
141
|
|
138
|
-
|
142
|
+
parsed_response = self.parser.parse_historical_data(
|
143
|
+
response=response, symbol=symbol, start=start, end=end, base_market=base_market
|
144
|
+
)
|
139
145
|
|
140
|
-
return ksxt.models.KsxtHistoricalDataResponse(
|
146
|
+
return ksxt.models.KsxtHistoricalDataResponse(
|
147
|
+
header=common_header, response=common_response, info=parsed_response
|
148
|
+
)
|
141
149
|
|
142
150
|
async def fetch_ticker(self, symbol: str, base_market: str = "KRW") -> ksxt.models.KsxtTickerResponse:
|
143
151
|
params = {"markets": self.safe_symbol(base_market, symbol)} # 다중 조회 시, 콤마로 구분 ex. 'KRW-BTC, BTC-ETH'
|
@@ -210,7 +218,13 @@ class Upbit(AsyncExchange, ImplicitAPI):
|
|
210
218
|
return ksxt.models.KsxtMultiOrderBookResponse(header=common_header, response=common_response, info=parsed_info)
|
211
219
|
|
212
220
|
async def fetch_balance(
|
213
|
-
self,
|
221
|
+
self,
|
222
|
+
acc_num: str,
|
223
|
+
base_market: str = "KRW",
|
224
|
+
excluded_symbols: list[str] | None = None,
|
225
|
+
included_symbols: list[str] | None = None,
|
226
|
+
filter_delisted: bool = True,
|
227
|
+
min_amount: float = 0,
|
214
228
|
) -> ksxt.models.KsxtBalanceResponse:
|
215
229
|
params = {}
|
216
230
|
|
@@ -223,7 +237,12 @@ class Upbit(AsyncExchange, ImplicitAPI):
|
|
223
237
|
return ksxt.models.KsxtBalanceResponse(header=common_header, response=common_response, info=None)
|
224
238
|
|
225
239
|
parsed_info = self.parser.parse_balance(
|
226
|
-
response=response,
|
240
|
+
response=response,
|
241
|
+
base_market=base_market,
|
242
|
+
excluded_symbols=excluded_symbols,
|
243
|
+
included_symbols=included_symbols,
|
244
|
+
filter_delisted=filter_delisted,
|
245
|
+
min_amount=min_amount,
|
227
246
|
)
|
228
247
|
|
229
248
|
return ksxt.models.KsxtBalanceResponse(header=common_header, response=common_response, info=parsed_info)
|
@@ -276,7 +295,7 @@ class Upbit(AsyncExchange, ImplicitAPI):
|
|
276
295
|
|
277
296
|
async def fetch_closed_order_detail(
|
278
297
|
self, acc_num: str, order_ids: List[str], base_market: str = "KRW"
|
279
|
-
) -> ksxt.models.
|
298
|
+
) -> ksxt.models.KsxtClosedOrderResponse:
|
280
299
|
params = {
|
281
300
|
"uuids": order_ids,
|
282
301
|
}
|
@@ -289,12 +308,12 @@ class Upbit(AsyncExchange, ImplicitAPI):
|
|
289
308
|
|
290
309
|
# 실패 시 오류 응답 반환
|
291
310
|
if common_response.success != "0":
|
292
|
-
return ksxt.models.
|
311
|
+
return ksxt.models.KsxtClosedOrderResponse(header=common_header, response=common_response, info=None)
|
293
312
|
|
294
313
|
# 데이터 파싱
|
295
314
|
parsed_info = self.parser.parse_closed_order_history(response, base_market)
|
296
315
|
|
297
|
-
return ksxt.models.
|
316
|
+
return ksxt.models.KsxtClosedOrderResponse(header=common_header, response=common_response, info=parsed_info)
|
298
317
|
|
299
318
|
async def fetch_open_order_detail(
|
300
319
|
self, acc_num: str, order_ids: List[str], base_market: str = "KRW"
|
@@ -321,16 +340,28 @@ class Upbit(AsyncExchange, ImplicitAPI):
|
|
321
340
|
async def fetch_closed_order(
|
322
341
|
self,
|
323
342
|
acc_num: str,
|
324
|
-
symbol:
|
325
|
-
start:
|
326
|
-
end:
|
343
|
+
symbol: str = "",
|
344
|
+
start: datetime | None = None,
|
345
|
+
end: datetime | None = None,
|
327
346
|
base_market: str = "KRW",
|
328
347
|
) -> ksxt.models.KsxtClosedOrderResponse:
|
329
348
|
params = {"state": "done"}
|
330
349
|
|
331
|
-
if
|
350
|
+
if symbol:
|
332
351
|
params.update({"market": self.safe_symbol(base_market, symbol)})
|
333
352
|
|
353
|
+
if start and end:
|
354
|
+
duration = end - start
|
355
|
+
if duration.days > 7:
|
356
|
+
raise ValueError("The duration between start and end cannot exceed 7 days.")
|
357
|
+
|
358
|
+
elif start:
|
359
|
+
start_timestamp = int(start.timestamp() * 1000)
|
360
|
+
params.update({"start_time": start_timestamp})
|
361
|
+
elif end:
|
362
|
+
end_timestamp = int(end.timestamp() * 1000)
|
363
|
+
params.update({"end_time": end_timestamp})
|
364
|
+
|
334
365
|
common_header = self.create_common_header(request_params=params)
|
335
366
|
|
336
367
|
response = await self.private_get_fetch_closed_order(self.extend(params))
|
@@ -339,21 +370,24 @@ class Upbit(AsyncExchange, ImplicitAPI):
|
|
339
370
|
if common_response.success != "0":
|
340
371
|
return ksxt.models.KsxtClosedOrderResponse(header=common_header, response=common_response, info=None)
|
341
372
|
|
342
|
-
|
373
|
+
# 데이터 파싱
|
374
|
+
parsed_info = self.parser.parse_closed_order_history(
|
375
|
+
response=response, start=start, end=end, base_market=base_market
|
376
|
+
)
|
343
377
|
|
344
378
|
return ksxt.models.KsxtClosedOrderResponse(header=common_header, response=common_response, info=parsed_info)
|
345
379
|
|
346
380
|
async def fetch_open_order(
|
347
381
|
self,
|
348
382
|
acc_num: str,
|
349
|
-
symbol: str
|
350
|
-
start:
|
351
|
-
end:
|
383
|
+
symbol: str = "",
|
384
|
+
start: datetime | None = None,
|
385
|
+
end: datetime | None = None,
|
352
386
|
base_market: str = "KRW",
|
353
387
|
) -> ksxt.models.KsxtOpenOrderResponse:
|
354
388
|
params = {"state": "wait"}
|
355
389
|
|
356
|
-
if
|
390
|
+
if symbol:
|
357
391
|
params.update({"market": self.safe_symbol(base_market, symbol)})
|
358
392
|
|
359
393
|
common_header = self.create_common_header(request_params=params)
|
@@ -364,12 +398,15 @@ class Upbit(AsyncExchange, ImplicitAPI):
|
|
364
398
|
if common_response.success != "0":
|
365
399
|
return ksxt.models.KsxtOpenOrderResponse(header=common_header, response=common_response, info=None)
|
366
400
|
|
367
|
-
|
401
|
+
# 데이터 파싱
|
402
|
+
parsed_info = self.parser.parse_open_order_history(
|
403
|
+
response=response, start=start, end=end, base_market=base_market
|
404
|
+
)
|
368
405
|
|
369
406
|
return ksxt.models.KsxtOpenOrderResponse(header=common_header, response=common_response, info=parsed_info)
|
370
407
|
|
371
408
|
async def fetch_withdrawal_history(
|
372
|
-
self, acc_num: str, base_market: str = "KRW"
|
409
|
+
self, acc_num: str, start: datetime | None = None, end: datetime | None = None, base_market: str = "KRW"
|
373
410
|
) -> ksxt.models.KsxtWithdrawalHistoryResponse:
|
374
411
|
params = {"currency": base_market, "state": "DONE"}
|
375
412
|
|
@@ -381,14 +418,17 @@ class Upbit(AsyncExchange, ImplicitAPI):
|
|
381
418
|
if common_response.success != "0":
|
382
419
|
return ksxt.models.KsxtWithdrawalHistoryResponse(header=common_header, response=common_response, info=None)
|
383
420
|
|
384
|
-
|
421
|
+
# 데이터 파싱
|
422
|
+
parsed_info = self.parser.parse_withdrawal_history(
|
423
|
+
response=response, start=start, end=end, base_market=base_market
|
424
|
+
)
|
385
425
|
|
386
426
|
return ksxt.models.KsxtWithdrawalHistoryResponse(
|
387
427
|
header=common_header, response=common_response, info=parsed_info
|
388
428
|
)
|
389
429
|
|
390
430
|
async def fetch_deposit_history(
|
391
|
-
self, acc_num: str, base_market: str = "KRW"
|
431
|
+
self, acc_num: str, start: datetime | None = None, end: datetime | None = None, base_market: str = "KRW"
|
392
432
|
) -> ksxt.models.KsxtDepositHistoryResponse:
|
393
433
|
params = {"currency": base_market, "state": "ACCEPTED"}
|
394
434
|
|
@@ -400,7 +440,10 @@ class Upbit(AsyncExchange, ImplicitAPI):
|
|
400
440
|
if common_response.success != "0":
|
401
441
|
return ksxt.models.KsxtDepositHistoryResponse(header=common_header, response=common_response, info=None)
|
402
442
|
|
403
|
-
|
443
|
+
# 데이터 파싱
|
444
|
+
parsed_info = self.parser.parse_deposit_history(
|
445
|
+
response=response, start=start, end=end, base_market=base_market
|
446
|
+
)
|
404
447
|
|
405
448
|
return ksxt.models.KsxtDepositHistoryResponse(header=common_header, response=common_response, info=parsed_info)
|
406
449
|
|
Binary file
|