vnpy_okx 2025.12.28__py3-none-any.whl → 2026.1.11__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.
- vnpy_okx/__init__.py +1 -1
- vnpy_okx/okx_gateway.py +26 -11
- {vnpy_okx-2025.12.28.dist-info → vnpy_okx-2026.1.11.dist-info}/METADATA +1 -1
- vnpy_okx-2026.1.11.dist-info/RECORD +7 -0
- vnpy_okx-2025.12.28.dist-info/RECORD +0 -7
- {vnpy_okx-2025.12.28.dist-info → vnpy_okx-2026.1.11.dist-info}/WHEEL +0 -0
- {vnpy_okx-2025.12.28.dist-info → vnpy_okx-2026.1.11.dist-info}/licenses/LICENSE +0 -0
vnpy_okx/__init__.py
CHANGED
vnpy_okx/okx_gateway.py
CHANGED
|
@@ -10,6 +10,7 @@ from types import TracebackType
|
|
|
10
10
|
from collections.abc import Callable
|
|
11
11
|
from time import sleep
|
|
12
12
|
from decimal import Decimal
|
|
13
|
+
from typing import cast
|
|
13
14
|
|
|
14
15
|
from vnpy.event import EventEngine, Event, EVENT_TIMER
|
|
15
16
|
from vnpy.trader.constant import (
|
|
@@ -116,7 +117,7 @@ class OkxGateway(BaseGateway):
|
|
|
116
117
|
"Margin Currency": ""
|
|
117
118
|
}
|
|
118
119
|
|
|
119
|
-
exchanges: Exchange = [Exchange.GLOBAL]
|
|
120
|
+
exchanges: list[Exchange] = [Exchange.GLOBAL]
|
|
120
121
|
|
|
121
122
|
def __init__(self, event_engine: EventEngine, gateway_name: str) -> None:
|
|
122
123
|
"""
|
|
@@ -339,7 +340,7 @@ class OkxGateway(BaseGateway):
|
|
|
339
340
|
self.orders[order.orderid] = order
|
|
340
341
|
super().on_order(order)
|
|
341
342
|
|
|
342
|
-
def get_order(self, orderid: str) -> OrderData:
|
|
343
|
+
def get_order(self, orderid: str) -> OrderData | None:
|
|
343
344
|
"""
|
|
344
345
|
Get previously saved order by order id.
|
|
345
346
|
|
|
@@ -401,7 +402,7 @@ class OkxGateway(BaseGateway):
|
|
|
401
402
|
Returns:
|
|
402
403
|
OrderData: VeighNa order object
|
|
403
404
|
"""
|
|
404
|
-
contract: ContractData = self.get_contract_by_name(data["instId"])
|
|
405
|
+
contract: ContractData = cast(ContractData, self.get_contract_by_name(data["instId"]))
|
|
405
406
|
|
|
406
407
|
order_id: str = data["clOrdId"]
|
|
407
408
|
if order_id:
|
|
@@ -439,7 +440,7 @@ class OkxGateway(BaseGateway):
|
|
|
439
440
|
Returns:
|
|
440
441
|
OrderData: VeighNa order object
|
|
441
442
|
"""
|
|
442
|
-
contract: ContractData = self.get_contract_by_name(data["sprdId"])
|
|
443
|
+
contract: ContractData = cast(ContractData, self.get_contract_by_name(data["sprdId"]))
|
|
443
444
|
|
|
444
445
|
order_id: str = data["clOrdId"]
|
|
445
446
|
if order_id:
|
|
@@ -764,6 +765,7 @@ class RestApi(RestClient):
|
|
|
764
765
|
net_position=net_position,
|
|
765
766
|
gateway_name=self.gateway_name,
|
|
766
767
|
)
|
|
768
|
+
contract.extra = d
|
|
767
769
|
|
|
768
770
|
self.gateway.on_contract(contract)
|
|
769
771
|
|
|
@@ -795,7 +797,7 @@ class RestApi(RestClient):
|
|
|
795
797
|
leg_symbols: list[str] = []
|
|
796
798
|
for leg in d["legs"]:
|
|
797
799
|
leg_name: str = leg["instId"]
|
|
798
|
-
leg_contract: ContractData = self.gateway.get_contract_by_name(leg_name)
|
|
800
|
+
leg_contract: ContractData = cast(ContractData, self.gateway.get_contract_by_name(leg_name))
|
|
799
801
|
leg_symbols.append(leg_contract.symbol)
|
|
800
802
|
|
|
801
803
|
contract: ContractData = ContractData(
|
|
@@ -877,6 +879,11 @@ class RestApi(RestClient):
|
|
|
877
879
|
self.gateway.write_log(f"Query kline history failed, symbol not found: {req.symbol}")
|
|
878
880
|
return []
|
|
879
881
|
|
|
882
|
+
# Validate interval is not None
|
|
883
|
+
if not req.interval:
|
|
884
|
+
self.gateway.write_log(f"Query kline history failed, interval not found: {req.symbol}")
|
|
885
|
+
return []
|
|
886
|
+
|
|
880
887
|
# Initialize buffer for storing bars
|
|
881
888
|
buf: dict[datetime, BarData] = {}
|
|
882
889
|
limit: str = "100"
|
|
@@ -913,7 +920,7 @@ class RestApi(RestClient):
|
|
|
913
920
|
break
|
|
914
921
|
else:
|
|
915
922
|
data: dict = resp.json()
|
|
916
|
-
bar_data: list = data.get("data", None)
|
|
923
|
+
bar_data: list | None = data.get("data", None)
|
|
917
924
|
|
|
918
925
|
if not bar_data:
|
|
919
926
|
msg: str = data.get("msg", "No data returned.")
|
|
@@ -1395,7 +1402,7 @@ class PrivateApi(WebsocketApi):
|
|
|
1395
1402
|
# Process trade data for filled or partially filled orders
|
|
1396
1403
|
# Round trade volume number to meet minimum volume precision
|
|
1397
1404
|
trade_volume: float = float(d["fillSz"])
|
|
1398
|
-
contract: ContractData = self.gateway.get_contract_by_symbol(order.symbol)
|
|
1405
|
+
contract: ContractData | None = self.gateway.get_contract_by_symbol(order.symbol)
|
|
1399
1406
|
if contract:
|
|
1400
1407
|
trade_volume = round_to(trade_volume, contract.min_volume)
|
|
1401
1408
|
|
|
@@ -1451,7 +1458,7 @@ class PrivateApi(WebsocketApi):
|
|
|
1451
1458
|
data: list = packet["data"]
|
|
1452
1459
|
for d in data:
|
|
1453
1460
|
name: str = d["instId"]
|
|
1454
|
-
contract: ContractData = self.gateway.get_contract_by_name(name)
|
|
1461
|
+
contract: ContractData = cast(ContractData, self.gateway.get_contract_by_name(name))
|
|
1455
1462
|
|
|
1456
1463
|
pos: float = float(d["pos"])
|
|
1457
1464
|
price: float = get_float_value(d, "avgPx")
|
|
@@ -1483,9 +1490,11 @@ class PrivateApi(WebsocketApi):
|
|
|
1483
1490
|
# Wrong parameters
|
|
1484
1491
|
if packet["code"] != "0":
|
|
1485
1492
|
if not data:
|
|
1486
|
-
order: OrderData = self.reqid_order_map
|
|
1487
|
-
order
|
|
1488
|
-
|
|
1493
|
+
order: OrderData | None = self.reqid_order_map.get(packet["id"], None)
|
|
1494
|
+
if order:
|
|
1495
|
+
order.status = Status.REJECTED
|
|
1496
|
+
self.gateway.on_order(order)
|
|
1497
|
+
|
|
1489
1498
|
return
|
|
1490
1499
|
|
|
1491
1500
|
# Failed to process
|
|
@@ -1625,9 +1634,15 @@ class PrivateApi(WebsocketApi):
|
|
|
1625
1634
|
"tdMode": "cross" # Only support cross margin mode
|
|
1626
1635
|
}
|
|
1627
1636
|
|
|
1637
|
+
# Add extra field for portfolio margin
|
|
1628
1638
|
if self.margin_currency:
|
|
1629
1639
|
arg["ccy"] = self.margin_currency
|
|
1630
1640
|
|
|
1641
|
+
# Add extra field for spot
|
|
1642
|
+
if "SPOT" in req.symbol:
|
|
1643
|
+
quote_ccy_list: list[str] = contract.extra["tradeQuoteCcyList"] # type: ignore
|
|
1644
|
+
arg["tradeQuoteCcy"] = quote_ccy_list[0]
|
|
1645
|
+
|
|
1631
1646
|
# Create websocket request with unique request ID
|
|
1632
1647
|
self.reqid += 1
|
|
1633
1648
|
packet: dict = {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
vnpy_okx/__init__.py,sha256=f6oPlp_8EDCCpyWTT16niwdAtKE3BmP3CkntE6NITGc,1248
|
|
2
|
+
vnpy_okx/okx_gateway.py,sha256=9jRt6r5ReRAy15CnuF0cxR3d6f7jrtbHxxmAX5ofwNE,73037
|
|
3
|
+
vnpy_okx/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
vnpy_okx-2026.1.11.dist-info/METADATA,sha256=i6iIE4Sb-jNBO3t5YmY5dF4RQsZbFgE917kOkHtxY6I,2840
|
|
5
|
+
vnpy_okx-2026.1.11.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
6
|
+
vnpy_okx-2026.1.11.dist-info/licenses/LICENSE,sha256=vKkW-EmD7w-5lDDjg15L8feZ1nkQeNpEHfyO2v9tprs,1099
|
|
7
|
+
vnpy_okx-2026.1.11.dist-info/RECORD,,
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
vnpy_okx/__init__.py,sha256=q5WNRYb_KdEzXSfonARFuNujBAS4jL-z77Lu2pm8beY,1248
|
|
2
|
-
vnpy_okx/okx_gateway.py,sha256=eqKESbdBr5Av4TJ7HhQgp6jJjmZjgtgP6ivICOIeozI,72352
|
|
3
|
-
vnpy_okx/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
vnpy_okx-2025.12.28.dist-info/METADATA,sha256=gGPXJ52UM7FZ8oW0EkNWu3NU4k4rJZsS8iSOHay2sJk,2841
|
|
5
|
-
vnpy_okx-2025.12.28.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
6
|
-
vnpy_okx-2025.12.28.dist-info/licenses/LICENSE,sha256=vKkW-EmD7w-5lDDjg15L8feZ1nkQeNpEHfyO2v9tprs,1099
|
|
7
|
-
vnpy_okx-2025.12.28.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|