ksxt 1.0.5__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 +7 -1
- ksxt/async_/bithumb.py +19 -2
- ksxt/async_/koreainvest.py +13 -2
- ksxt/async_/upbit.py +15 -4
- 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 +12 -1
- ksxt/base/rest_exchange.py +7 -1
- ksxt/bithumb.py +19 -2
- ksxt/config/__pycache__/__init__.cpython-312.pyc +0 -0
- ksxt/config/token.toml +2 -6
- ksxt/koreainvest.py +13 -2
- 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 -30
- 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 +41 -17
- ksxt/parser/koreainvest.py +28 -13
- ksxt/parser/parser.py +9 -5
- ksxt/parser/upbit.py +49 -19
- ksxt/upbit.py +13 -2
- 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.5.dist-info → ksxt-1.0.6.dist-info}/METADATA +1 -1
- ksxt-1.0.6.dist-info/RECORD +119 -0
- ksxt/api/auto/__pycache__/bithumb.cpython-312.pyc +0 -0
- ksxt/api/auto/__pycache__/koreainvest.cpython-312.pyc +0 -0
- ksxt/api/auto/__pycache__/upbit.cpython-312.pyc +0 -0
- ksxt/async_/base/__pycache__/throttler.cpython-312.pyc +0 -0
- ksxt-1.0.5.dist-info/RECORD +0 -123
- {ksxt-1.0.5.dist-info → ksxt-1.0.6.dist-info}/LICENSE.txt +0 -0
- {ksxt-1.0.5.dist-info → ksxt-1.0.6.dist-info}/WHEEL +0 -0
- {ksxt-1.0.5.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
|
@@ -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
|
|
ksxt/async_/bithumb.py
CHANGED
@@ -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(
|
@@ -232,7 +236,13 @@ class Bithumb(AsyncExchange, ImplicitAPI):
|
|
232
236
|
return ksxt.models.KsxtMultiOrderBookResponse(header=common_header, response=common_response, info=parsed_info)
|
233
237
|
|
234
238
|
async def fetch_balance(
|
235
|
-
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,
|
236
246
|
) -> ksxt.models.KsxtBalanceResponse:
|
237
247
|
params = {}
|
238
248
|
|
@@ -247,7 +257,14 @@ class Bithumb(AsyncExchange, ImplicitAPI):
|
|
247
257
|
return ksxt.models.KsxtBalanceResponse(header=common_header, response=common_response, info=None)
|
248
258
|
|
249
259
|
# 데이터 파싱
|
250
|
-
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
|
+
)
|
251
268
|
|
252
269
|
return ksxt.models.KsxtBalanceResponse(header=common_header, response=common_response, info=parsed_info)
|
253
270
|
|
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)
|
ksxt/async_/upbit.py
CHANGED
@@ -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
|
|
@@ -218,7 +218,13 @@ class Upbit(AsyncExchange, ImplicitAPI):
|
|
218
218
|
return ksxt.models.KsxtMultiOrderBookResponse(header=common_header, response=common_response, info=parsed_info)
|
219
219
|
|
220
220
|
async def fetch_balance(
|
221
|
-
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,
|
222
228
|
) -> ksxt.models.KsxtBalanceResponse:
|
223
229
|
params = {}
|
224
230
|
|
@@ -231,7 +237,12 @@ class Upbit(AsyncExchange, ImplicitAPI):
|
|
231
237
|
return ksxt.models.KsxtBalanceResponse(header=common_header, response=common_response, info=None)
|
232
238
|
|
233
239
|
parsed_info = self.parser.parse_balance(
|
234
|
-
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,
|
235
246
|
)
|
236
247
|
|
237
248
|
return ksxt.models.KsxtBalanceResponse(header=common_header, response=common_response, info=parsed_info)
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
ksxt/base/exchange.py
CHANGED
@@ -139,7 +139,15 @@ class Exchange:
|
|
139
139
|
"""
|
140
140
|
pass
|
141
141
|
|
142
|
-
def fetch_balance(
|
142
|
+
def fetch_balance(
|
143
|
+
self,
|
144
|
+
acc_num: str,
|
145
|
+
base_market: str = "KRW",
|
146
|
+
excluded_symbols: list[str] | None = None,
|
147
|
+
included_symbols: list[str] | None = None,
|
148
|
+
filter_delisted: bool = True,
|
149
|
+
min_amount: float = 0,
|
150
|
+
):
|
143
151
|
"""
|
144
152
|
보유 자산 조회
|
145
153
|
|
@@ -147,6 +155,9 @@ class Exchange:
|
|
147
155
|
acc_num (str): 계좌 번호
|
148
156
|
base_market (str, optional): Market 구분 코드. Defaults to 'KRW'.
|
149
157
|
excluded_symbols (list[str] | None, optional): 제외할 종목 리스트. Defaults to None.
|
158
|
+
included_symbols (list[str] | None, optional): 포함할 종목 리스트. Defaults to None.
|
159
|
+
filter_delisted (bool, optional): 거래 지원 종료되거나 상장 폐지된 종목 필터링 여부. Defaults to True.
|
160
|
+
min_amount (float, optional): 최소 자산 금액 필터링. Defaults to 0.
|
150
161
|
"""
|
151
162
|
pass
|
152
163
|
|
ksxt/base/rest_exchange.py
CHANGED
@@ -319,7 +319,13 @@ class RestExchange(Exchange):
|
|
319
319
|
|
320
320
|
@check_token
|
321
321
|
def fetch_balance(
|
322
|
-
self,
|
322
|
+
self,
|
323
|
+
acc_num: str,
|
324
|
+
base_market: str = "KRW",
|
325
|
+
excluded_symbols: list[str] | None = None,
|
326
|
+
included_symbols: list[str] | None = None,
|
327
|
+
filter_delisted: bool = True,
|
328
|
+
min_amount: float = 0,
|
323
329
|
) -> ksxt.models.KsxtBalanceResponse:
|
324
330
|
raise NotSupportedError(f"{self.id} {self.fetch_balance.__qualname__}() is not supported yet.")
|
325
331
|
|
ksxt/bithumb.py
CHANGED
@@ -25,6 +25,10 @@ class Bithumb(RestExchange, ImplicitAPI):
|
|
25
25
|
self.timezone = pytz.timezone("Asia/Seoul")
|
26
26
|
|
27
27
|
def safe_symbol(self, base_market: str, security: str) -> str:
|
28
|
+
# If security already contains a hyphen, assume it's correctly formatted
|
29
|
+
if "-" in security:
|
30
|
+
return security
|
31
|
+
|
28
32
|
return f"{base_market}-{security}"
|
29
33
|
|
30
34
|
def safe_security(self, symbol: str) -> str:
|
@@ -229,7 +233,13 @@ class Bithumb(RestExchange, ImplicitAPI):
|
|
229
233
|
return ksxt.models.KsxtMultiOrderBookResponse(header=common_header, response=common_response, info=parsed_info)
|
230
234
|
|
231
235
|
def fetch_balance(
|
232
|
-
self,
|
236
|
+
self,
|
237
|
+
acc_num: str,
|
238
|
+
base_market: str = "KRW",
|
239
|
+
excluded_symbols: list[str] | None = None,
|
240
|
+
included_symbols: list[str] | None = None,
|
241
|
+
filter_delisted: bool = True,
|
242
|
+
min_amount: float = 0,
|
233
243
|
) -> ksxt.models.KsxtBalanceResponse:
|
234
244
|
params = {}
|
235
245
|
|
@@ -244,7 +254,14 @@ class Bithumb(RestExchange, ImplicitAPI):
|
|
244
254
|
return ksxt.models.KsxtBalanceResponse(header=common_header, response=common_response, info=None)
|
245
255
|
|
246
256
|
# 데이터 파싱
|
247
|
-
parsed_info = self.parser.parse_balance(
|
257
|
+
parsed_info = self.parser.parse_balance(
|
258
|
+
response=response,
|
259
|
+
base_market=base_market,
|
260
|
+
excluded_symbols=excluded_symbols,
|
261
|
+
included_symbols=included_symbols,
|
262
|
+
filter_delisted=filter_delisted,
|
263
|
+
min_amount=min_amount,
|
264
|
+
)
|
248
265
|
|
249
266
|
return ksxt.models.KsxtBalanceResponse(header=common_header, response=common_response, info=parsed_info)
|
250
267
|
|
Binary file
|
ksxt/config/token.toml
CHANGED
@@ -1,7 +1,3 @@
|
|
1
1
|
[PSXkvBM1hQXJDRHg2rLvC7Tr8SoyPudlbx9o]
|
2
|
-
token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.
|
3
|
-
expired = 2024-08
|
4
|
-
|
5
|
-
[PSo9UuHWHtg1QzRkyu1WeXYERyUkpRK9LSii]
|
6
|
-
token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0b2tlbiIsImF1ZCI6ImNhY2NjNGZhLWMxMzktNGE5MC1hNjg2LTI2OTVmZmNiZmQ0NyIsInByZHRfY2QiOiIiLCJpc3MiOiJ1bm9ndyIsImV4cCI6MTcyMzM3ODExNSwiaWF0IjoxNzIzMjkxNzE1LCJqdGkiOiJQU285VXVIV0h0ZzFRelJreXUxV2VYWUVSeVVrcFJLOUxTaWkifQ.EnsBporS5hoD7Prx_fvXoklkxvx1u0Swp3jL9MXv3GnXtU_totbAtfDqsHWexQGJNqgEAPe6Bd2L2M0rCNUpCg"
|
7
|
-
expired = 2024-08-11T21:08:35
|
2
|
+
token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0b2tlbiIsImF1ZCI6IjEyYzYxZWIxLTU3YzQtNGFiZC1iN2JhLTM0OGIwOTBjY2NlMyIsInByZHRfY2QiOiIiLCJpc3MiOiJ1bm9ndyIsImV4cCI6MTcxOTM1OTE1NiwiaWF0IjoxNzE5MjcyNzU2LCJqdGkiOiJQU1hrdkJNMWhRWEpEUkhnMnJMdkM3VHI4U295UHVkbGJ4OW8ifQ.B1CJ7IMEkkqVpQ7ECM8otr6lVVmV2Yp_bRaBBRlcOo29MIQZ5z8g5oEcXyO-ghaUa8UJZguuo8Q7iQreRBYkZg"
|
3
|
+
expired = "2024-06-26 08:45:56"
|
ksxt/koreainvest.py
CHANGED
@@ -125,7 +125,13 @@ class KoreaInvest(RestExchange, ImplicitAPI):
|
|
125
125
|
|
126
126
|
@RestExchange.check_token
|
127
127
|
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(RestExchange, 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)
|
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
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
ksxt/models/balance.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
from pydantic import BaseModel
|
1
|
+
from pydantic import BaseModel, model_validator
|
2
2
|
from typing import List
|
3
3
|
|
4
4
|
from ksxt.models.common import GeneralResponse
|
@@ -7,14 +7,27 @@ from ksxt.models.common import GeneralResponse
|
|
7
7
|
class BalanceData(BaseModel):
|
8
8
|
symbol: str
|
9
9
|
name: str
|
10
|
-
|
10
|
+
|
11
11
|
price: float
|
12
|
-
|
13
|
-
|
12
|
+
evaluation_price: float
|
13
|
+
|
14
14
|
qty: float
|
15
15
|
free_qty: float
|
16
16
|
used_qty: float
|
17
17
|
|
18
|
+
amount: float | None = 0.0
|
19
|
+
evaluation_amount: float | None = 0.0
|
20
|
+
pnl: float | None = 0.0
|
21
|
+
pnl_ratio: float | None = 0.0
|
22
|
+
|
23
|
+
@model_validator(mode="after")
|
24
|
+
def calculate_fields(cls, values):
|
25
|
+
values.amount = values.price * values.qty
|
26
|
+
values.evaluation_amount = values.evaluation_price * values.qty
|
27
|
+
values.pnl = values.evaluation_price - values.price
|
28
|
+
values.pnl_ratio = values.pnl / values.price if values.price != 0 else 0.0
|
29
|
+
return values
|
30
|
+
|
18
31
|
|
19
32
|
class BalanceInfo(BaseModel):
|
20
33
|
currency: str
|
ksxt/models/transaction.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
from datetime import datetime
|
2
|
-
from typing import List
|
2
|
+
from typing import List
|
3
3
|
from pydantic import BaseModel
|
4
4
|
|
5
5
|
from ksxt.models.common import GeneralResponse
|
@@ -8,45 +8,37 @@ from ksxt.models.common import GeneralResponse
|
|
8
8
|
class TransactionInfo(BaseModel):
|
9
9
|
# 주문 고유 아이디
|
10
10
|
uuid: str
|
11
|
-
# 주문 종류 (ask, bid, deposit, withdrawal)
|
12
|
-
type: str
|
13
|
-
|
14
|
-
# 금액
|
15
|
-
amount: float
|
16
|
-
# 세금
|
17
|
-
tax: Optional[float] = 0
|
18
|
-
# 수수료
|
19
|
-
fee: Optional[float] = 0
|
20
|
-
|
21
11
|
# 계좌 번호
|
22
|
-
account_id:
|
23
|
-
# 화폐 통화 정보
|
24
|
-
currency: Optional[str] = None
|
12
|
+
account_id: str | None = None
|
25
13
|
|
26
|
-
# 주문
|
27
|
-
|
14
|
+
# 주문 종류 (ask, bid, deposit, withdrawal)
|
15
|
+
transaction_type: str
|
28
16
|
|
17
|
+
# order type (limit, market, default)
|
18
|
+
order_type: str | None = None
|
19
|
+
|
20
|
+
# position (long, short)
|
21
|
+
tr_position: str | None = None
|
29
22
|
|
30
|
-
class OpenedOrderInfo(TransactionInfo):
|
31
23
|
# 종목 정보
|
32
24
|
symbol: str
|
33
25
|
# 가격
|
34
26
|
price: float
|
35
27
|
# 수량
|
36
28
|
qty: float
|
37
|
-
#
|
38
|
-
|
29
|
+
# 금액
|
30
|
+
amount: float
|
39
31
|
|
32
|
+
# 세금
|
33
|
+
tax: float | None = 0
|
34
|
+
# 수수료
|
35
|
+
fee: float | None = 0
|
40
36
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
#
|
45
|
-
|
46
|
-
# 수량
|
47
|
-
qty: float
|
48
|
-
# 주문 방식
|
49
|
-
order_type: Optional[str]
|
37
|
+
# 화폐 통화 정보
|
38
|
+
currency: str | None = None
|
39
|
+
|
40
|
+
# 주문 생성 시간
|
41
|
+
created_at: datetime
|
50
42
|
|
51
43
|
|
52
44
|
class WithdrawalHistory(BaseModel):
|
@@ -58,11 +50,11 @@ class DepositHistory(BaseModel):
|
|
58
50
|
|
59
51
|
|
60
52
|
class OpenedOrderHistory(BaseModel):
|
61
|
-
history: List[
|
53
|
+
history: List[TransactionInfo]
|
62
54
|
|
63
55
|
|
64
56
|
class ClosedOrderHistory(BaseModel):
|
65
|
-
history: List[
|
57
|
+
history: List[TransactionInfo]
|
66
58
|
|
67
59
|
|
68
60
|
class KsxtWithdrawalHistoryResponse(GeneralResponse[WithdrawalHistory]):
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
ksxt/parser/bithumb.py
CHANGED
@@ -1,13 +1,10 @@
|
|
1
1
|
from datetime import datetime, timezone
|
2
|
-
from operator import attrgetter
|
3
2
|
from typing import Dict, List, Optional
|
4
3
|
|
5
4
|
from ksxt.models.transaction import (
|
6
5
|
ClosedOrderHistory,
|
7
|
-
ClosedOrderInfo,
|
8
6
|
DepositHistory,
|
9
7
|
OpenedOrderHistory,
|
10
|
-
OpenedOrderInfo,
|
11
8
|
TransactionInfo,
|
12
9
|
WithdrawalHistory,
|
13
10
|
)
|
@@ -24,6 +21,10 @@ from ksxt.utils import safer, sorter
|
|
24
21
|
|
25
22
|
class BithumbParser(BaseParser):
|
26
23
|
def safe_symbol(self, base_market: str, security: str) -> str:
|
24
|
+
# If security already contains a hyphen, assume it's correctly formatted
|
25
|
+
if "-" in security:
|
26
|
+
return security
|
27
|
+
|
27
28
|
return f"{base_market}-{security}"
|
28
29
|
|
29
30
|
def parse_markets(self, response: List[Dict], base_market: str = "KRW") -> MarketInfo:
|
@@ -175,7 +176,13 @@ class BithumbParser(BaseParser):
|
|
175
176
|
return ask_data, bid_data
|
176
177
|
|
177
178
|
def parse_balance(
|
178
|
-
self,
|
179
|
+
self,
|
180
|
+
response: List[Dict],
|
181
|
+
base_market: str = "KRW",
|
182
|
+
excluded_symbols: Optional[list[str]] = None,
|
183
|
+
included_symbols: Optional[list[str]] = None,
|
184
|
+
filter_delisted: bool = True,
|
185
|
+
min_amount: float = 0,
|
179
186
|
) -> BalanceInfo:
|
180
187
|
# 1. Filter out entries where 'currency' is not the base_market
|
181
188
|
# 2. Ensure 'unit_currency' is the base_market
|
@@ -186,11 +193,18 @@ class BithumbParser(BaseParser):
|
|
186
193
|
if data["currency"] != base_market
|
187
194
|
and data["unit_currency"] == base_market
|
188
195
|
and (excluded_symbols is None or data["currency"] not in excluded_symbols)
|
196
|
+
and (included_symbols is None or self.safe_symbol(base_market, data["currency"]) in included_symbols)
|
189
197
|
]
|
190
198
|
|
191
199
|
# Initialize balance list
|
192
200
|
balances = [self._parse_balance(data, base_market) for data in filtered_data]
|
193
201
|
|
202
|
+
if filter_delisted:
|
203
|
+
balances = [balance for balance in balances if balance.price > 0]
|
204
|
+
|
205
|
+
if min_amount > 0:
|
206
|
+
balances = [balance for balance in balances if balance.amount > min_amount]
|
207
|
+
|
194
208
|
# 총 매입금액
|
195
209
|
total_amount = sum(bal.price * bal.qty for bal in balances)
|
196
210
|
total_evaluation_amount = sum(bal.evaluation_price * bal.qty for bal in balances)
|
@@ -212,8 +226,6 @@ class BithumbParser(BaseParser):
|
|
212
226
|
name=self.safe_symbol(base_market, safer.safe_string(data, "currency")),
|
213
227
|
evaluation_price=0, # 필요에 따라 적절히 설정
|
214
228
|
price=safer.safe_number(data, "avg_buy_price"),
|
215
|
-
pnl_amount=0, # 필요에 따라 적절히 설정
|
216
|
-
pnl_ratio=0, # 필요에 따라 적절히 설정
|
217
229
|
qty=safer.safe_number(data, "balance"),
|
218
230
|
free_qty=safer.safe_number(data, "balance") - safer.safe_number(data, "locked"),
|
219
231
|
used_qty=safer.safe_number(data, "locked"),
|
@@ -287,18 +299,21 @@ class BithumbParser(BaseParser):
|
|
287
299
|
|
288
300
|
return OpenedOrderHistory(history=orders)
|
289
301
|
|
290
|
-
def _parse_open_order_info(self, order: dict, base_market: str = "KRW") ->
|
291
|
-
return
|
302
|
+
def _parse_open_order_info(self, order: dict, base_market: str = "KRW") -> TransactionInfo:
|
303
|
+
return TransactionInfo(
|
292
304
|
uuid=safer.safe_string(order, "uuid"),
|
293
|
-
|
305
|
+
account_id="",
|
306
|
+
transaction_type=safer.safe_string(order, "side"),
|
307
|
+
order_type=safer.safe_string(order, "ord_type"),
|
308
|
+
tr_position="long",
|
294
309
|
symbol=self.safe_symbol(base_market, safer.safe_string(order, "market")),
|
295
310
|
price=safer.safe_number(order, "price"),
|
296
311
|
qty=safer.safe_number(order, "volume"),
|
297
312
|
amount=safer.safe_number(order, "price") * safer.safe_number(order, "volume"),
|
298
313
|
tax=0,
|
299
314
|
fee=safer.safe_number(order, "reserved_fee"),
|
315
|
+
currency=base_market,
|
300
316
|
created_at=datetime.fromisoformat(safer.safe_string(order, "created_at")),
|
301
|
-
order_type=safer.safe_string(order, "ord_type"),
|
302
317
|
)
|
303
318
|
|
304
319
|
def parse_closed_order_history(
|
@@ -318,18 +333,21 @@ class BithumbParser(BaseParser):
|
|
318
333
|
|
319
334
|
return ClosedOrderHistory(history=orders)
|
320
335
|
|
321
|
-
def _parse_closed_order_info(self, order: dict, base_market: str = "KRW") ->
|
322
|
-
return
|
336
|
+
def _parse_closed_order_info(self, order: dict, base_market: str = "KRW") -> TransactionInfo:
|
337
|
+
return TransactionInfo(
|
323
338
|
uuid=safer.safe_string(order, "uuid"),
|
324
|
-
|
325
|
-
|
339
|
+
account_id="",
|
340
|
+
transaction_type=safer.safe_string(order, "side"),
|
341
|
+
order_type=safer.safe_string(order, "ord_type"),
|
342
|
+
tr_position="long",
|
343
|
+
symbol=self.safe_symbol(base_market, safer.safe_string(order, "market")),
|
326
344
|
price=safer.safe_number(order, "price"),
|
327
345
|
qty=safer.safe_number(order, "volume"),
|
328
346
|
amount=safer.safe_number(order, "price") * safer.safe_number(order, "volume"),
|
329
347
|
tax=0,
|
330
348
|
fee=safer.safe_number(order, "reserved_fee"),
|
349
|
+
currency=base_market,
|
331
350
|
created_at=datetime.fromisoformat(safer.safe_string(order, "created_at")),
|
332
|
-
order_type=safer.safe_string(order, "ord_type"),
|
333
351
|
)
|
334
352
|
|
335
353
|
def parse_cancel_order(self, response: dict, base_market: str = "KRW") -> CancelOrderResponse:
|
@@ -383,10 +401,16 @@ class BithumbParser(BaseParser):
|
|
383
401
|
def _parse_transaction_history_item(self, item: Dict, base_market: str = "KRW") -> TransactionInfo:
|
384
402
|
return TransactionInfo(
|
385
403
|
uuid=safer.safe_string(item, "uuid"),
|
386
|
-
|
404
|
+
account_id="",
|
405
|
+
transaction_type=safer.safe_string(item, "type"),
|
406
|
+
order_type=safer.safe_string(item, "transaction_type"),
|
407
|
+
tr_position="",
|
408
|
+
symbol=safer.safe_string(item, "currency"),
|
409
|
+
price=1,
|
410
|
+
qty=safer.safe_number(item, "amount"),
|
387
411
|
amount=safer.safe_number(item, "amount"),
|
388
412
|
tax=0,
|
389
413
|
fee=safer.safe_number(item, "fee"),
|
390
414
|
currency=safer.safe_string(item, "currency"),
|
391
|
-
created_at=datetime.fromisoformat(safer.safe_string(item, "
|
415
|
+
created_at=datetime.fromisoformat(safer.safe_string(item, "done_at")),
|
392
416
|
)
|