vnpy_okx 2025.11.4__py3-none-any.whl → 2025.12.4__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 +23 -15
- vnpy_okx/py.typed +0 -0
- {vnpy_okx-2025.11.4.dist-info → vnpy_okx-2025.12.4.dist-info}/METADATA +2 -2
- vnpy_okx-2025.12.4.dist-info/RECORD +7 -0
- {vnpy_okx-2025.11.4.dist-info → vnpy_okx-2025.12.4.dist-info}/WHEEL +1 -1
- vnpy_okx-2025.11.4.dist-info/RECORD +0 -6
- {vnpy_okx-2025.11.4.dist-info → vnpy_okx-2025.12.4.dist-info}/licenses/LICENSE +0 -0
vnpy_okx/__init__.py
CHANGED
vnpy_okx/okx_gateway.py
CHANGED
|
@@ -8,6 +8,7 @@ from datetime import datetime
|
|
|
8
8
|
from urllib.parse import urlencode
|
|
9
9
|
from types import TracebackType
|
|
10
10
|
from collections.abc import Callable
|
|
11
|
+
from time import sleep
|
|
11
12
|
|
|
12
13
|
from vnpy.event import EventEngine, Event, EVENT_TIMER
|
|
13
14
|
from vnpy.trader.constant import (
|
|
@@ -47,12 +48,6 @@ REAL_PUBLIC_HOST: str = "wss://ws.okx.com:8443/ws/v5/public"
|
|
|
47
48
|
REAL_PRIVATE_HOST: str = "wss://ws.okx.com:8443/ws/v5/private"
|
|
48
49
|
REAL_BUSINESS_HOST: str = "wss://ws.okx.com:8443/ws/v5/business"
|
|
49
50
|
|
|
50
|
-
# AWS server hosts
|
|
51
|
-
AWS_REST_HOST: str = "https://aws.okx.com"
|
|
52
|
-
AWS_PUBLIC_HOST: str = "wss://wsaws.okx.com:8443/ws/v5/public"
|
|
53
|
-
AWS_PRIVATE_HOST: str = "wss://wsaws.okx.com:8443/ws/v5/private"
|
|
54
|
-
AWS_BUSINESS_HOST: str = "wss://wsaws.okx.com:8443/ws/v5/business"
|
|
55
|
-
|
|
56
51
|
# Demo server hosts
|
|
57
52
|
DEMO_REST_HOST: str = "https://www.okx.com"
|
|
58
53
|
DEMO_PUBLIC_HOST: str = "wss://wspap.okx.com:8443/ws/v5/public"
|
|
@@ -113,10 +108,11 @@ class OkxGateway(BaseGateway):
|
|
|
113
108
|
"API Key": "",
|
|
114
109
|
"Secret Key": "",
|
|
115
110
|
"Passphrase": "",
|
|
116
|
-
"Server": ["REAL", "
|
|
111
|
+
"Server": ["REAL", "DEMO"],
|
|
117
112
|
"Proxy Host": "",
|
|
118
113
|
"Proxy Port": 0,
|
|
119
114
|
"Spread Trading": ["False", "True"],
|
|
115
|
+
"Margin Currency": ""
|
|
120
116
|
}
|
|
121
117
|
|
|
122
118
|
exchanges: Exchange = [Exchange.GLOBAL]
|
|
@@ -137,6 +133,7 @@ class OkxGateway(BaseGateway):
|
|
|
137
133
|
self.proxy_host: str = ""
|
|
138
134
|
self.proxy_port: int = 0
|
|
139
135
|
self.spread_trading: bool = False
|
|
136
|
+
self.margin_currency: str = ""
|
|
140
137
|
|
|
141
138
|
self.orders: dict[str, OrderData] = {}
|
|
142
139
|
self.local_orderids: set[str] = set()
|
|
@@ -172,6 +169,7 @@ class OkxGateway(BaseGateway):
|
|
|
172
169
|
self.proxy_host = setting["Proxy Host"]
|
|
173
170
|
self.proxy_port = setting["Proxy Port"]
|
|
174
171
|
self.spread_trading = setting["Spread Trading"] == "True"
|
|
172
|
+
self.margin_currency = setting["Margin Currency"]
|
|
175
173
|
|
|
176
174
|
self.rest_api.connect(
|
|
177
175
|
self.key,
|
|
@@ -199,6 +197,7 @@ class OkxGateway(BaseGateway):
|
|
|
199
197
|
self.server,
|
|
200
198
|
self.proxy_host,
|
|
201
199
|
self.proxy_port,
|
|
200
|
+
self.margin_currency,
|
|
202
201
|
)
|
|
203
202
|
|
|
204
203
|
if self.spread_trading:
|
|
@@ -566,7 +565,7 @@ class RestApi(RestClient):
|
|
|
566
565
|
key: API Key for authentication
|
|
567
566
|
secret: API Secret for request signing
|
|
568
567
|
passphrase: API Passphrase for authentication
|
|
569
|
-
server: Server type ("REAL"
|
|
568
|
+
server: Server type ("REAL" or "DEMO")
|
|
570
569
|
proxy_host: Proxy server hostname or IP
|
|
571
570
|
proxy_port: Proxy server port
|
|
572
571
|
spread_trading: Whether to enable spread trading
|
|
@@ -582,7 +581,6 @@ class RestApi(RestClient):
|
|
|
582
581
|
|
|
583
582
|
server_hosts: dict[str, str] = {
|
|
584
583
|
"REAL": REAL_REST_HOST,
|
|
585
|
-
"AWS": AWS_REST_HOST,
|
|
586
584
|
"DEMO": DEMO_REST_HOST,
|
|
587
585
|
}
|
|
588
586
|
|
|
@@ -889,6 +887,9 @@ class RestApi(RestClient):
|
|
|
889
887
|
|
|
890
888
|
# Loop until no more data or request fails
|
|
891
889
|
while True:
|
|
890
|
+
# Add small delay to avoid rate limit
|
|
891
|
+
sleep(0.1)
|
|
892
|
+
|
|
892
893
|
# Create query params
|
|
893
894
|
params: dict = {
|
|
894
895
|
id_key: contract.name,
|
|
@@ -1098,7 +1099,10 @@ class WebsocketApi(WebsocketClient):
|
|
|
1098
1099
|
def send_ping(self) -> None:
|
|
1099
1100
|
"""Send heartbeat ping to server"""
|
|
1100
1101
|
if self.connected:
|
|
1101
|
-
|
|
1102
|
+
try:
|
|
1103
|
+
self.wsapp.send("ping")
|
|
1104
|
+
except Exception:
|
|
1105
|
+
pass
|
|
1102
1106
|
|
|
1103
1107
|
|
|
1104
1108
|
class PublicApi(WebsocketApi):
|
|
@@ -1124,7 +1128,6 @@ class PublicApi(WebsocketApi):
|
|
|
1124
1128
|
|
|
1125
1129
|
self.server_hosts: dict[str, str] = {
|
|
1126
1130
|
"REAL": REAL_PUBLIC_HOST,
|
|
1127
|
-
"AWS": AWS_PUBLIC_HOST,
|
|
1128
1131
|
"DEMO": DEMO_PUBLIC_HOST,
|
|
1129
1132
|
}
|
|
1130
1133
|
|
|
@@ -1267,6 +1270,7 @@ class PrivateApi(WebsocketApi):
|
|
|
1267
1270
|
self.key: str = ""
|
|
1268
1271
|
self.secret: bytes = b""
|
|
1269
1272
|
self.passphrase: str = ""
|
|
1273
|
+
self.margin_currency: str = ""
|
|
1270
1274
|
|
|
1271
1275
|
self.reqid: int = 0
|
|
1272
1276
|
self.order_count: int = 0
|
|
@@ -1284,7 +1288,6 @@ class PrivateApi(WebsocketApi):
|
|
|
1284
1288
|
|
|
1285
1289
|
self.server_hosts: dict[str, str] = {
|
|
1286
1290
|
"REAL": REAL_PRIVATE_HOST,
|
|
1287
|
-
"AWS": AWS_PRIVATE_HOST,
|
|
1288
1291
|
"DEMO": DEMO_PRIVATE_HOST,
|
|
1289
1292
|
}
|
|
1290
1293
|
|
|
@@ -1298,6 +1301,7 @@ class PrivateApi(WebsocketApi):
|
|
|
1298
1301
|
server: str,
|
|
1299
1302
|
proxy_host: str,
|
|
1300
1303
|
proxy_port: int,
|
|
1304
|
+
margin_currency: str,
|
|
1301
1305
|
) -> None:
|
|
1302
1306
|
"""
|
|
1303
1307
|
Start server connection.
|
|
@@ -1308,13 +1312,15 @@ class PrivateApi(WebsocketApi):
|
|
|
1308
1312
|
key: API Key for authentication
|
|
1309
1313
|
secret: API Secret for request signing
|
|
1310
1314
|
passphrase: API Passphrase for authentication
|
|
1311
|
-
server: Server type ("REAL"
|
|
1315
|
+
server: Server type ("REAL" or "DEMO")
|
|
1312
1316
|
proxy_host: Proxy server hostname or IP
|
|
1313
1317
|
proxy_port: Proxy server port
|
|
1318
|
+
margin_currency: Margin currency
|
|
1314
1319
|
"""
|
|
1315
1320
|
self.key = key
|
|
1316
1321
|
self.secret = secret.encode()
|
|
1317
1322
|
self.passphrase = passphrase
|
|
1323
|
+
self.margin_currency = margin_currency
|
|
1318
1324
|
|
|
1319
1325
|
self.connect_time = int(datetime.now().strftime("%y%m%d%H%M%S"))
|
|
1320
1326
|
|
|
@@ -1617,6 +1623,9 @@ class PrivateApi(WebsocketApi):
|
|
|
1617
1623
|
"tdMode": "cross" # Only support cross margin mode
|
|
1618
1624
|
}
|
|
1619
1625
|
|
|
1626
|
+
if self.margin_currency:
|
|
1627
|
+
arg["ccy"] = self.margin_currency
|
|
1628
|
+
|
|
1620
1629
|
# Create websocket request with unique request ID
|
|
1621
1630
|
self.reqid += 1
|
|
1622
1631
|
packet: dict = {
|
|
@@ -1710,7 +1719,6 @@ class BusinessApi(WebsocketApi):
|
|
|
1710
1719
|
|
|
1711
1720
|
self.server_hosts: dict[str, str] = {
|
|
1712
1721
|
"REAL": REAL_BUSINESS_HOST,
|
|
1713
|
-
"AWS": AWS_BUSINESS_HOST,
|
|
1714
1722
|
"DEMO": DEMO_BUSINESS_HOST,
|
|
1715
1723
|
}
|
|
1716
1724
|
|
|
@@ -1734,7 +1742,7 @@ class BusinessApi(WebsocketApi):
|
|
|
1734
1742
|
key: API Key for authentication
|
|
1735
1743
|
secret: API Secret for request signing
|
|
1736
1744
|
passphrase: API Passphrase for authentication
|
|
1737
|
-
server: Server type ("REAL"
|
|
1745
|
+
server: Server type ("REAL" or "DEMO")
|
|
1738
1746
|
proxy_host: Proxy server hostname or IP
|
|
1739
1747
|
proxy_port: Proxy server port
|
|
1740
1748
|
"""
|
vnpy_okx/py.typed
ADDED
|
File without changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vnpy_okx
|
|
3
|
-
Version: 2025.
|
|
3
|
+
Version: 2025.12.4
|
|
4
4
|
Summary: OKX trading gateway for VeighNa.
|
|
5
5
|
Project-URL: Homepage, https://www.github.com/veighna-global
|
|
6
6
|
Project-URL: Source, https://www.github.com/veighna-global
|
|
@@ -33,7 +33,7 @@ Description-Content-Type: text/markdown
|
|
|
33
33
|
</p>
|
|
34
34
|
|
|
35
35
|
<p align="center">
|
|
36
|
-
<img src ="https://img.shields.io/badge/version-2025.
|
|
36
|
+
<img src ="https://img.shields.io/badge/version-2025.12.04-blueviolet.svg"/>
|
|
37
37
|
<img src ="https://img.shields.io/badge/platform-windows|linux|macos-yellow.svg"/>
|
|
38
38
|
<img src ="https://img.shields.io/badge/python-3.10|3.11|3.12|3.13-blue.svg" />
|
|
39
39
|
<img src ="https://img.shields.io/github/license/veighna-global/vnpy_okx.svg?color=orange"/>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
vnpy_okx/__init__.py,sha256=lIy9uxHMJ86ksqMI4kUnXUQ-1-sS-WAQnOiilGyK_j8,1248
|
|
2
|
+
vnpy_okx/okx_gateway.py,sha256=7t_EAAYdW4SNDfjvzYxt8vWJvSbSCAaBcMTYfDChjJc,72250
|
|
3
|
+
vnpy_okx/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
vnpy_okx-2025.12.4.dist-info/METADATA,sha256=QJg2kGtlW_2Hcpf_Y4RuZe-YwOVZuzdOzofAGQ9pg2Y,2840
|
|
5
|
+
vnpy_okx-2025.12.4.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
6
|
+
vnpy_okx-2025.12.4.dist-info/licenses/LICENSE,sha256=vKkW-EmD7w-5lDDjg15L8feZ1nkQeNpEHfyO2v9tprs,1099
|
|
7
|
+
vnpy_okx-2025.12.4.dist-info/RECORD,,
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
vnpy_okx/__init__.py,sha256=WKbwROSXbveQfJah7xCqB3ej97hai8IzHnDgR2T6yw0,1248
|
|
2
|
-
vnpy_okx/okx_gateway.py,sha256=-mNb33nTBVFo3RF9jHVAdomR1NrQ6KhM5vv9SJ1XzIE,72105
|
|
3
|
-
vnpy_okx-2025.11.4.dist-info/METADATA,sha256=PdUSP1DfJuD64Vx9dfK6Xsp1N2zBpoTLv-v6VEQvjaU,2840
|
|
4
|
-
vnpy_okx-2025.11.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
5
|
-
vnpy_okx-2025.11.4.dist-info/licenses/LICENSE,sha256=vKkW-EmD7w-5lDDjg15L8feZ1nkQeNpEHfyO2v9tprs,1099
|
|
6
|
-
vnpy_okx-2025.11.4.dist-info/RECORD,,
|
|
File without changes
|