From 3313cb2aac081d627f81a5e5f694bcd76b4ea9fe Mon Sep 17 00:00:00 2001 From: okxapi <115602548+okxapi@users.noreply.github.com> Date: Thu, 15 Dec 2022 20:27:57 +0800 Subject: [PATCH 001/139] Update WsPrivateTest.py --- test/WsPrivateTest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/WsPrivateTest.py b/test/WsPrivateTest.py index 2a8f0a01..cf2ab5ea 100644 --- a/test/WsPrivateTest.py +++ b/test/WsPrivateTest.py @@ -1,6 +1,6 @@ import time -from WsPrivate import WsPrivate +from okx.websocket.WsPrivate import WsPrivate def privateCallback(message): From 3b793251402200286a560a2cb3d2f5307569d42d Mon Sep 17 00:00:00 2001 From: okxapi <115602548+okxapi@users.noreply.github.com> Date: Thu, 15 Dec 2022 20:28:34 +0800 Subject: [PATCH 002/139] Update WsPublicTest.py --- test/WsPublicTest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/WsPublicTest.py b/test/WsPublicTest.py index 17c106e4..e0fbec58 100644 --- a/test/WsPublicTest.py +++ b/test/WsPublicTest.py @@ -1,6 +1,6 @@ import time -from WsPublic import WsPublic +from okx.websocket.WsPublic import WsPublic def publicCallback(message): From 2830a6ec270f09be91af3e232770168cb00476ac Mon Sep 17 00:00:00 2001 From: okxapi <115602548+okxapi@users.noreply.github.com> Date: Thu, 15 Dec 2022 21:18:41 +0800 Subject: [PATCH 003/139] Update WsPrivateTest.py --- test/WsPrivateTest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/WsPrivateTest.py b/test/WsPrivateTest.py index cf2ab5ea..27375bc8 100644 --- a/test/WsPrivateTest.py +++ b/test/WsPrivateTest.py @@ -1,6 +1,6 @@ import time -from okx.websocket.WsPrivate import WsPrivate +from okx.websocket.WsPublic import WsPublic def privateCallback(message): From ed9d8208df4cf0ca3c8cea0f2be81738c72fe842 Mon Sep 17 00:00:00 2001 From: okxapi <115602548+okxapi@users.noreply.github.com> Date: Thu, 15 Dec 2022 21:19:17 +0800 Subject: [PATCH 004/139] Update WsClientFactory.py --- okx/websocket/WsClientFactory.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/okx/websocket/WsClientFactory.py b/okx/websocket/WsClientFactory.py index a003ac0f..c016222b 100644 --- a/okx/websocket/WsClientFactory.py +++ b/okx/websocket/WsClientFactory.py @@ -1,7 +1,7 @@ from autobahn.twisted.websocket import WebSocketClientFactory from twisted.internet.protocol import ReconnectingClientFactory -from WsClientProtocol import * +from .WsClientProtocol import * class WsReconnectingClientFactory(ReconnectingClientFactory): From 7122e14ef7cc14d748da4642fcc807995fad8535 Mon Sep 17 00:00:00 2001 From: okxapi <115602548+okxapi@users.noreply.github.com> Date: Thu, 15 Dec 2022 21:19:58 +0800 Subject: [PATCH 005/139] Update WsConnectManager.py --- okx/websocket/WsConnectManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/okx/websocket/WsConnectManager.py b/okx/websocket/WsConnectManager.py index 7343ea77..cd71edad 100644 --- a/okx/websocket/WsConnectManager.py +++ b/okx/websocket/WsConnectManager.py @@ -5,8 +5,8 @@ from twisted.internet import reactor from twisted.internet.error import ReactorAlreadyRunning -import WsUtils -from WsClientFactory import * +from . import WsUtils +from .WsClientFactory import * class WsConnectManager(threading.Thread): From 48373d9fdbf62942f76f1546a8c7ffc77c7c1618 Mon Sep 17 00:00:00 2001 From: okxapi <115602548+okxapi@users.noreply.github.com> Date: Thu, 15 Dec 2022 21:20:23 +0800 Subject: [PATCH 006/139] Update WsPrivate.py --- okx/websocket/WsPrivate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/okx/websocket/WsPrivate.py b/okx/websocket/WsPrivate.py index 7dd8433b..e31a5af4 100644 --- a/okx/websocket/WsPrivate.py +++ b/okx/websocket/WsPrivate.py @@ -2,8 +2,8 @@ from twisted.internet import reactor -import WsUtils -from WsConnectManager import WsConnectManager +from . import WsUtils +from .WsConnectManager import WsConnectManager class WsPrivate(WsConnectManager): From 59f2b568e69fea7f1c422c02c7bebf8593776ed7 Mon Sep 17 00:00:00 2001 From: okxapi <115602548+okxapi@users.noreply.github.com> Date: Thu, 15 Dec 2022 21:20:47 +0800 Subject: [PATCH 007/139] Update WsPublic.py --- okx/websocket/WsPublic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/okx/websocket/WsPublic.py b/okx/websocket/WsPublic.py index a3f24b64..c38e9d7e 100644 --- a/okx/websocket/WsPublic.py +++ b/okx/websocket/WsPublic.py @@ -1,6 +1,6 @@ from twisted.internet import reactor -from WsConnectManager import WsConnectManager +from .WsConnectManager import WsConnectManager class WsPublic(WsConnectManager): From 0fbcb4f23f8cb60d43a0619908f11e6bfc91b950 Mon Sep 17 00:00:00 2001 From: okxapi <115602548+okxapi@users.noreply.github.com> Date: Fri, 16 Dec 2022 18:09:57 +0800 Subject: [PATCH 008/139] Update README.md --- README.md | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index e67d4b95..57fdf332 100644 --- a/README.md +++ b/README.md @@ -116,16 +116,23 @@ passphrase = "" - Run `example.py` - Uncomment the corresponding method and then pass the arguments and call the interfaces - WebSocketAPI - - Open `websocket_example.py` - - According to the `public channel`/`private channel`, select the corresponding `url`, the corresponding start method, and pass in the corresponding parameters - -```python -# WebSocket public channel -url = "wss://ws.okx.com:8443/ws/v5/public?brokerId=9999" - -# WebSocket private channel -url = "wss://ws.okx.com:8443/ws/v5/private?brokerId=9999" -``` + * Open `WsPrivate`and`WsPublic`; + * choose the right `url`(if private channel need login info). + + ```python + # WebSocket Public channel + url = "wss://ws.okx.com:8443/ws/v5/public" + # WebSocket Private channel + url = "wss://ws.okx.com:8443/ws/v5/private" + ``` + + ```python + # Public channel not need login(e.g. tickers,candle,mark-price,books,funding-rate) + refer to WsPublicTest.py + + # Private channel nedd login(e.g. account,positions,orders) + refer to WsPrivateTest.py + ``` P.S. From 41b19503a5a11cc042793d500886d33e78871a65 Mon Sep 17 00:00:00 2001 From: okxapi <115602548+okxapi@users.noreply.github.com> Date: Fri, 16 Dec 2022 18:12:05 +0800 Subject: [PATCH 009/139] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 57fdf332..ee9582bc 100644 --- a/README.md +++ b/README.md @@ -116,8 +116,8 @@ passphrase = "" - Run `example.py` - Uncomment the corresponding method and then pass the arguments and call the interfaces - WebSocketAPI - * Open `WsPrivate`and`WsPublic`; - * choose the right `url`(if private channel need login info). + - Open `WsPrivate`and`WsPublic`; + - choose the right `url`(if private channel need login info). ```python # WebSocket Public channel From 24efd1f71edcf983e2892ce10293b19b6b6bb8ef Mon Sep 17 00:00:00 2001 From: Kate Hu Date: Wed, 15 Feb 2023 18:59:11 +0800 Subject: [PATCH 010/139] enriched README.md --- README.md | 174 +++++---------- http2_example.py | 31 --- websocket_example.py | 522 ------------------------------------------- 3 files changed, 50 insertions(+), 677 deletions(-) delete mode 100644 http2_example.py delete mode 100644 websocket_example.py diff --git a/README.md b/README.md index ee9582bc..b33edd45 100644 --- a/README.md +++ b/README.md @@ -1,150 +1,79 @@ -[TOC] +### Overview +This is an unofficial Python wrapper for the [OKX exchange REST API v5](https://www.okx.com/docs-v5/en/) -### 如何使用? +If you came here looking to purchase cryptocurrencies from the OKX exchange, please go [here](https://www.okx.com/). -`python版本:>=3.9 +#### Source code +https://github.com/okxapi/python-okx +#### OKX API Telegram +https://t.me/OKXAPI +#### API trading tutorials +- Spot trading: [](https://www.okx.com/learn/spot-trading-with-jupyter-notebook) +- Derivative trading: [](https://www.okx.com/learn/derivatives-trading-with-jupyter-notebook) -`WebSocketAPI:autobahn.twisted>=22.10.0` +Make sure you update often and check the [Changelog](https://www.okx.com/docs-v5/log_en/) for new features and bug fixes. -#### 第一步:下载SDK,安装相关所需库 +### Features +- Implementation of all Rest API endpoints. +- Private and Public Websocket implementation +- Testnet support +- Websocket handling with reconnection and multiplexed connections -1.1 下载`python SDK` - -* 将SDK目录`Clone`或者`Download`到本地,选择使用`okx-python-sdk-api-v5`即可 - -1.2 安装所需库 - -```python -pip install requests -pip install autobahn\[twisted\] -pip install pyOpenSSL -``` - -#### 第二步:配置个人信息 - -2.1 如果还未有API,可[点击](https://www.okx.com/account/users/myApi)前往官网进行申请 - -```python -api_key = "" -secret_key = "" -passphrase = "" -``` - -#### 第三步:调用接口 - -* RestAPI - - * 运行`example.py` - - * 解开相应方法的注释传参调用各接口即可 - -* WebSocketAPI - * 参考Test文件夹下`WsPrivate`和`WsPublic`文件示例; - * 根据`公共频道`/`私有频道`选择对应`url`(如果是私有频道需要设置登陆信息),传入相应参数即可。 - - ```python - # WebSocket公共频道 - url = "wss://ws.okx.com:8443/ws/v5/public" - # WebSocket私有频道 - url = "wss://ws.okx.com:8443/ws/v5/private" - ``` - - ```python - # 公共频道 不需要登录(行情,持仓总量,K线,标记价格,深度,资金费率等) - 参考 WsPublicTest.py - - # 私有频道 需要登录(账户,持仓,订单等) - 参考 WsPrivateTest.py - ``` - -附言: - -* 如果对API尚不了解,建议参考`OKX`官方[API文档](https://www.okx.com/docs-v5/zh/) - -* 使用RestAPI的用户可以通过参考Test文件夹下的示例,设置正确的参数即可 - -* 使用WebSocketAPI的用户可以通过参考Test文件夹下的`WsPublicTest.py`和`WsPrivateTest.py`,设置正确的参数即可 - -* 若使用`WebSocketAPI`遇到问题建议参考相关链接 - - * `asyncio`、`websockets`文档/`github`: - https://docs.python.org/3/library/asyncio-dev.html - https://websockets.readthedocs.io/en/stable/intro.html - https://github.com/aaugustin/websockets - - * 关于`code=1006`: - https://github.com/Rapptz/discord.py/issues/1996 - https://github.com/aaugustin/websockets/issues/587 - - - -### How to use ? +### Quick start +#### Prerequisites `python version:>=3.9` -`WebSocketAPI: autobahn.twisted>=22.10.0` - -#### Step 1: Download the SDK and install the necessary libraries - -1.1 Download python SDK +`WebSocketAPI: websockets package advise version 6.0` -- `Clone` or `Download` the SDK directory to your local directory,choose to use `okx-python-sdk-api-v5` +#### Step 1: register an account on OKX and apply for an API key +- Register account: [](https://www.okx.com/account/register) +- Apply for an API key: [](https://www.okx.com/account/users/myApi) -1.2 Install the necessary libraries +#### Step 2: install python-okx ```python -pip install requests -pip install autobahn\[twisted\] -pip install pyOpenSSL +pip install python-okx ``` -#### Step 2: Configure Personal Information - -2.1 If you have no API,[Click here](https://www.okx.com/account/users/myApi) to the official websit to apply for the API - -2.2 Fill out all necessary informatiuon in `example.py(RestAPI)` and `websocket_example.py(WebSocketAPI)` +#### Step 3: Run examples +- Fill in API credentials in the corresponding examples ```python api_key = "" secret_key = "" passphrase = "" ``` - -#### Step 3: Call API - - RestAPI - - Run `example.py` - - Uncomment the corresponding method and then pass the arguments and call the interfaces + - For spot trading: run example/get_started_en.ipynb + - For derivative trading: run example/https://github.com/okxapi/python-okx/blob/master/example/trade_derivatives_en.ipynb + - Tweak the value of the parameter `flag` (live trading: 0, demo trading: 1 +) to switch between live and demo trading environment - WebSocketAPI - - Open `WsPrivate`and`WsPublic`; - - choose the right `url`(if private channel need login info). - - ```python - # WebSocket Public channel - url = "wss://ws.okx.com:8443/ws/v5/public" - # WebSocket Private channel - url = "wss://ws.okx.com:8443/ws/v5/private" - ``` - - ```python - # Public channel not need login(e.g. tickers,candle,mark-price,books,funding-rate) - refer to WsPublicTest.py - - # Private channel nedd login(e.g. account,positions,orders) - refer to WsPrivateTest.py - ``` - -P.S. + - Run test/WsPrivateTest.py for private websocket channels + - Run test/WsPublicTest.py for public websocket channels + - Use different URLs for different environment -- If you know little about API, advise consulting the offical [API document](https://www.okx.com/docs-v5/en/) +```python +# WebSocket public channel +# live trading +url = "wss://ws.okx.com:8443/ws/v5/public?brokerId=9999" +# demo trading +url = "wss://wspap.okx.com:8443/ws/v5/public?brokerId=9999" + +# WebSocket private channel +# live trading +url = "wss://ws.okx.com:8443/ws/v5/private?brokerId=9999" +# demo trading +url = "wss://wspap.okx.com:8443/ws/v5/private?brokerId=9999" -- User with RestAPI can configure parameter `flag` in `example.py` in to choose to access to real trading or demo trading +``` -- User with WebSocketAPI can ucomment the corresponding `url` to choose to access to real trading or demo trading +Note -- Rest API support request by http2, you can refer to http2_example +- To learn more about OKX API, visit official [OKX API documentation](https://www.okx.com/docs-v5/en/) -- If you face any questions when using `WebSocketAPI`,you can consult related link +- If you face any questions when using `WebSocketAPI`,you can consult the following links - `asyncio`、`websockets` document/`github`: @@ -159,7 +88,4 @@ P.S. ```python https://github.com/Rapptz/discord.py/issues/1996 https://github.com/aaugustin/websockets/issues/587 - ``` - - - + ``` \ No newline at end of file diff --git a/http2_example.py b/http2_example.py deleted file mode 100644 index 7663d235..00000000 --- a/http2_example.py +++ /dev/null @@ -1,31 +0,0 @@ -import json -import time - -import okx.Account as Account - - -async def http2_request(request, parameters): - while 1: - begin = time.time() - if type(parameters) is list: - result = request(*parameters) - else: - result = request(**parameters) - - end = time.time() - cost = end - begin - print(f'request_cost:{cost}\nresponse_body:{json.dumps(result)}') - - -api_key = "" -secret_key = "" -passphrase = "" -# flag是实盘与模拟盘的切换参数 flag is the key parameter which can help you to change between demo and real trading. -# flag = '1' # 模拟盘 demo trading -flag = '0' # 实盘 real tradiang - -if __name__ == '__main__': - # account api - accountAPI = Account.AccountAPI(api_key, secret_key, passphrase, False, flag) - accountAPI.get_account_config() - accountAPI.get_greeks('BTC') diff --git a/websocket_example.py b/websocket_example.py deleted file mode 100644 index 2b83cb07..00000000 --- a/websocket_example.py +++ /dev/null @@ -1,522 +0,0 @@ -import asyncio -import base64 -import datetime -import hmac -import json -import time -import zlib - -import requests -import websockets - - -def get_timestamp(): - now = datetime.datetime.now() - t = now.isoformat("T", "milliseconds") - return t + "Z" - - -def get_server_time(): - url = "https://www.okx.com/api/v5/public/time" - response = requests.get(url) - if response.status_code == 200: - return response.json()['data'][0]['ts'] - else: - return "" - - -def get_local_timestamp(): - return int(time.time()) - - -def login_params(timestamp, api_key, passphrase, secret_key): - message = timestamp + 'GET' + '/users/self/verify' - - mac = hmac.new(bytes(secret_key, encoding='utf8'), bytes(message, encoding='utf-8'), digestmod='sha256') - d = mac.digest() - sign = base64.b64encode(d) - - login_param = {"op": "login", "args": [{"apiKey": api_key, - "passphrase": passphrase, - "timestamp": timestamp, - "sign": sign.decode("utf-8")}]} - login_str = json.dumps(login_param) - return login_str - - -def partial(res): - data_obj = res['data'][0] - bids = data_obj['bids'] - asks = data_obj['asks'] - instrument_id = res['arg']['instId'] - # print('全量数据bids为:' + str(bids)) - # print('档数为:' + str(len(bids))) - # print('全量数据asks为:' + str(asks)) - # print('档数为:' + str(len(asks))) - return bids, asks, instrument_id - - -def update_bids(res, bids_p): - # 获取增量bids数据 - bids_u = res['data'][0]['bids'] - # print('增量数据bids为:' + str(bids_u)) - # print('档数为:' + str(len(bids_u))) - # bids合并 - for i in bids_u: - bid_price = i[0] - for j in bids_p: - if bid_price == j[0]: - if i[1] == '0': - bids_p.remove(j) - break - else: - del j[1] - j.insert(1, i[1]) - break - else: - if i[1] != "0": - bids_p.append(i) - else: - bids_p.sort(key=lambda price: sort_num(price[0]), reverse=True) - # print('合并后的bids为:' + str(bids_p) + ',档数为:' + str(len(bids_p))) - return bids_p - - -def update_asks(res, asks_p): - # 获取增量asks数据 - asks_u = res['data'][0]['asks'] - # print('增量数据asks为:' + str(asks_u)) - # print('档数为:' + str(len(asks_u))) - # asks合并 - for i in asks_u: - ask_price = i[0] - for j in asks_p: - if ask_price == j[0]: - if i[1] == '0': - asks_p.remove(j) - break - else: - del j[1] - j.insert(1, i[1]) - break - else: - if i[1] != "0": - asks_p.append(i) - else: - asks_p.sort(key=lambda price: sort_num(price[0])) - # print('合并后的asks为:' + str(asks_p) + ',档数为:' + str(len(asks_p))) - return asks_p - - -def sort_num(n): - if n.isdigit(): - return int(n) - else: - return float(n) - - -def check(bids, asks): - # 获取bid档str - bids_l = [] - bid_l = [] - count_bid = 1 - while count_bid <= 25: - if count_bid > len(bids): - break - bids_l.append(bids[count_bid - 1]) - count_bid += 1 - for j in bids_l: - str_bid = ':'.join(j[0: 2]) - bid_l.append(str_bid) - # 获取ask档str - asks_l = [] - ask_l = [] - count_ask = 1 - while count_ask <= 25: - if count_ask > len(asks): - break - asks_l.append(asks[count_ask - 1]) - count_ask += 1 - for k in asks_l: - str_ask = ':'.join(k[0: 2]) - ask_l.append(str_ask) - # 拼接str - num = '' - if len(bid_l) == len(ask_l): - for m in range(len(bid_l)): - num += bid_l[m] + ':' + ask_l[m] + ':' - elif len(bid_l) > len(ask_l): - # bid档比ask档多 - for n in range(len(ask_l)): - num += bid_l[n] + ':' + ask_l[n] + ':' - for l in range(len(ask_l), len(bid_l)): - num += bid_l[l] + ':' - elif len(bid_l) < len(ask_l): - # ask档比bid档多 - for n in range(len(bid_l)): - num += bid_l[n] + ':' + ask_l[n] + ':' - for l in range(len(bid_l), len(ask_l)): - num += ask_l[l] + ':' - - new_num = num[:-1] - int_checksum = zlib.crc32(new_num.encode()) - fina = change(int_checksum) - return fina - - -def change(num_old): - num = pow(2, 31) - 1 - if num_old > num: - out = num_old - num * 2 - 2 - else: - out = num_old - return out - - -# subscribe channels un_need login -async def subscribe_without_login(url, channels): - l = [] - while True: - try: - async with websockets.connect(url) as ws: - sub_param = {"op": "subscribe", "args": channels} - sub_str = json.dumps(sub_param) - await ws.send(sub_str) - print(f"send: {sub_str}") - - while True: - try: - res = await asyncio.wait_for(ws.recv(), timeout=25) - except (asyncio.TimeoutError, websockets.exceptions.ConnectionClosed) as e: - try: - await ws.send('ping') - res = await ws.recv() - print(res) - continue - except Exception as e: - print("连接关闭,正在重连……") - break - - print(get_timestamp() + res) - res = eval(res) - if 'event' in res: - continue - for i in res['arg']: - if 'books' in res['arg'][i] and 'books5' not in res['arg'][i]: - # 订阅频道是深度频道 - if res['action'] == 'snapshot': - for m in l: - if res['arg']['instId'] == m['instrument_id']: - l.remove(m) - # 获取首次全量深度数据 - bids_p, asks_p, instrument_id = partial(res) - d = {} - d['instrument_id'] = instrument_id - d['bids_p'] = bids_p - d['asks_p'] = asks_p - l.append(d) - - # 校验checksum - checksum = res['data'][0]['checksum'] - # print('推送数据的checksum为:' + str(checksum)) - check_num = check(bids_p, asks_p) - # print('校验后的checksum为:' + str(check_num)) - if check_num == checksum: - print("校验结果为:True") - else: - print("校验结果为:False,正在重新订阅……") - - # 取消订阅 - await unsubscribe_without_login(url, channels) - # 发送订阅 - async with websockets.connect(url) as ws: - sub_param = {"op": "subscribe", "args": channels} - sub_str = json.dumps(sub_param) - await ws.send(sub_str) - print(f"send: {sub_str}") - - elif res['action'] == 'update': - for j in l: - if res['arg']['instId'] == j['instrument_id']: - # 获取全量数据 - bids_p = j['bids_p'] - asks_p = j['asks_p'] - # 获取合并后数据 - bids_p = update_bids(res, bids_p) - asks_p = update_asks(res, asks_p) - - # 校验checksum - checksum = res['data'][0]['checksum'] - # print('推送数据的checksum为:' + str(checksum)) - check_num = check(bids_p, asks_p) - # print('校验后的checksum为:' + str(check_num)) - if check_num == checksum: - print("校验结果为:True") - else: - print("校验结果为:False,正在重新订阅……") - - # 取消订阅 - await unsubscribe_without_login(url, channels) - # 发送订阅 - async with websockets.connect(url) as ws: - sub_param = {"op": "subscribe", "args": channels} - sub_str = json.dumps(sub_param) - await ws.send(sub_str) - print(f"send: {sub_str}") - except Exception as e: - print(e) - print("连接断开,正在重连……") - continue - - -# subscribe channels need login -async def subscribe(url, api_key, passphrase, secret_key, channels): - while True: - try: - async with websockets.connect(url) as ws: - # login - timestamp = str(get_local_timestamp()) - login_str = login_params(timestamp, api_key, passphrase, secret_key) - await ws.send(login_str) - # print(f"send: {login_str}") - res = await ws.recv() - print(res) - - # subscribe - sub_param = {"op": "subscribe", "args": channels} - sub_str = json.dumps(sub_param) - await ws.send(sub_str) - print(f"send: {sub_str}") - - while True: - try: - res = await asyncio.wait_for(ws.recv(), timeout=25) - except (asyncio.TimeoutError, websockets.exceptions.ConnectionClosed) as e: - try: - await ws.send('ping') - res = await ws.recv() - print(res) - continue - except Exception as e: - print("连接关闭,正在重连……") - break - - print(get_timestamp() + res) - - except Exception as e: - print("连接断开,正在重连……") - continue - - -# trade -async def trade(url, api_key, passphrase, secret_key, trade_param): - while True: - try: - async with websockets.connect(url) as ws: - # login - timestamp = str(get_local_timestamp()) - login_str = login_params(timestamp, api_key, passphrase, secret_key) - await ws.send(login_str) - # print(f"send: {login_str}") - res = await ws.recv() - print(res) - - # trade - sub_str = json.dumps(trade_param) - await ws.send(sub_str) - print(f"send: {sub_str}") - - while True: - try: - res = await asyncio.wait_for(ws.recv(), timeout=25) - except (asyncio.TimeoutError, websockets.exceptions.ConnectionClosed) as e: - try: - await ws.send('ping') - res = await ws.recv() - print(res) - continue - except Exception as e: - print("连接关闭,正在重连……") - break - - print(get_timestamp() + res) - - except Exception as e: - print("连接断开,正在重连……") - continue - - -# unsubscribe channels -async def unsubscribe(url, api_key, passphrase, secret_key, channels): - async with websockets.connect(url) as ws: - # login - timestamp = str(get_local_timestamp()) - login_str = login_params(timestamp, api_key, passphrase, secret_key) - await ws.send(login_str) - # print(f"send: {login_str}") - - res = await ws.recv() - print(f"recv: {res}") - - # unsubscribe - sub_param = {"op": "unsubscribe", "args": channels} - sub_str = json.dumps(sub_param) - await ws.send(sub_str) - print(f"send: {sub_str}") - - res = await ws.recv() - print(f"recv: {res}") - - -# unsubscribe channels -async def unsubscribe_without_login(url, channels): - async with websockets.connect(url) as ws: - # unsubscribe - sub_param = {"op": "unsubscribe", "args": channels} - sub_str = json.dumps(sub_param) - await ws.send(sub_str) - print(f"send: {sub_str}") - - res = await ws.recv() - print(f"recv: {res}") - - -api_key = "" -secret_key = "" -passphrase = "" - -# WebSocket公共频道 public channels -# 实盘 real trading -# url = "wss://ws.okx.com:8443/ws/v5/public" -# 模拟盘 demo trading -# url = "wss://wspap.okx.com:8443/ws/v5/public" - -# WebSocket私有频道 private channels -# 实盘 real trading -# url = "wss://ws.okx.com:8443/ws/v5/private" -# 模拟盘 demo trading -# url = "wss://wspap.okx.com:8443/ws/v5/private" - -''' -公共频道 public channel -:param channel: 频道名 -:param instType: 产品类型 -:param instId: 产品ID -:param uly: 合约标的指数 - -''' - -# 产品频道 Instruments Channel -# channels = [{"channel": "instruments", "instType": "FUTURES"}] -# 行情频道 tickers channel -# channels = [{"channel": "tickers", "instId": "BTC-USDT"}, {"channel": "tickers", "instId": "ETH-USDT"}] -# 持仓总量频道 Open interest Channel -# channels = [{"channel": "open-interest", "instId": "BTC-USD-210326"}] -# K线频道 Candlesticks Channel -# channels = [{"channel": "candle1m", "instId": "BTC-USD-210326"}] -# 交易频道 Trades Channel -# channels = [{"channel": "trades", "instId": "BTC-USD-201225"}] -# 预估交割/行权价格频道 Estimated delivery/exercise Price Channel -# channels = [{"channel": "estimated-price", "instType": "FUTURES", "uly": "BTC-USD"}] -# 标记价格频道 Mark Price Channel -# channels = [{"channel": "mark-price", "instId": "BTC-USDT-210326"}] -# 标记价格K线频道 Mark Price Candlesticks Channel -# channels = [{"channel": "mark-price-candle1D", "instId": "BTC-USD-201225"}] -# 限价频道 Price Limit Channel -# channels = [{"channel": "price-limit", "instId": "BTC-USD-201225"}] -# 深度频道 Order Book Channel -# channels = [{"channel": "books", "instId": "BTC-USD-SWAP"}] -# 期权定价频道 OPTION Summary Channel -# channels = [{"channel": "opt-summary", "uly": "BTC-USD"}] -# 资金费率频道 Funding Rate Channel -# channels = [{"channel": "funding-rate", "instId": "BTC-USD-SWAP"}] -# 指数K线频道 Index Candlesticks Channel -# channels = [{"channel": "index-candle1m", "instId": "BTC-USDT"}] -# 指数行情频道 Index Tickers Channel -# channels = [{"channel": "index-tickers", "instId": "BTC-USDT"}] -# status频道 Status Channel -# channels = [{"channel": "status"}] -# 公共大宗交易频道 Public block trading channel -# channels = [{"channel": "public-struc-block-trades"}] -# 大宗交易行情频道 Block trading market channel -# channels = [{"channel": "block-tickers", "instId":"BTC-USDT-SWAP"}] - -''' -私有频道 private channel -:param channel: 频道名 -:param ccy: 币种 -:param instType: 产品类型 -:param uly: 合约标的指数 -:param instId: 产品ID - -''' - -# 账户频道 Account Channel -# channels = [{"channel": "account", "ccy": "BTC"}] -# 持仓频道 Positions Channel -# channels = [{"channel": "positions", "instType": "FUTURES", "uly": "BTC-USDT", "instId": "BTC-USDT-210326"}] -# 余额和持仓频道 Balance and Position Channel -# channels = [{"channel": "balance_and_position"}] -# 订单频道 Order Channel -# channels = [{"channel": "orders", "instType": "FUTURES", "uly": "BTC-USD", "instId": "BTC-USD-201225"}] -# 策略委托订单频道 Algo Orders Channel -# channels = [{"channel": "orders-algo", "instType": "FUTURES", "uly": "BTC-USD", "instId": "BTC-USD-201225"}] -# 高级策略委托订单频道 Cancel Advance Algos -# channels = [{"channel": "algo-advance", "instType": "SPOT","instId": "BTC-USD-201225","algoId":"12345678"}] -# 爆仓风险预警推送频道 -# channels = [{"channel": "liquidation-warning", "instType": "SWAP","instType": "","uly":"","instId":""}] -# 账户greeks频道 -# channels = [{"channel": "account-greeks", "ccy": "BTC"}] -# 询价频道 Inquiry channel -# channels = [{"channel": "rfqs"}] -# 报价频道 Quote channel -# channels = [{"channel": "quotes"}] -# 大宗交易频道 Block trading channel -# channels = [{"channel": "struc-block-trades"}] -# 现货网格策略委托订单频道 Consignment order channel of spot grid strategy -# channels = [{"channel": "grid-orders-spot", "instType": "ANY"}] -# 合约网格策略委托订单频道 Spot grid policy delegated order channel contract grid policy delegated order channel -# channels = [{"channel": "grid-orders-contract", "instType": "ANY"}] -# 合约网格持仓频道 Contract grid position channel -# channels = [{"channel": "grid-positions", "algoId": ""}] -# 网格策略子订单频道 Grid policy suborder channel -# channels = [{"channel": "grid-sub-orders", "algoId": ""}] -''' -交易 trade -''' - -# 下单 Place Order -# trade_param = {"id": "1512", "op": "order", "args": [{"side": "buy", "instId": "BTC-USDT", "tdMode": "isolated", "ordType": "limit", "px": "19777", "sz": "1"}]} -# 批量下单 Place Multiple Orders -# trade_param = {"id": "1512", "op": "batch-orders", "args": [ -# {"side": "buy", "instId": "BTC-USDT", "tdMode": "isolated", "ordType": "limit", "px": "19666", "sz": "1"}, -# {"side": "buy", "instId": "BTC-USDT", "tdMode": "isolated", "ordType": "limit", "px": "19633", "sz": "1"} -# ]} -# 撤单 Cancel Order -# trade_param = {"id": "1512", "op": "cancel-order", "args": [{"instId": "BTC-USDT", "ordId": "259424589042823169"}]} -# 批量撤单 Cancel Multiple Orders -# trade_param = {"id": "1512", "op": "batch-cancel-orders", "args": [ -# {"instId": "BTC-USDT", "ordId": ""}, -# {"instId": "BTC-USDT", "ordId": ""} -# ]} -# 改单 Amend Order -# trade_param = {"id": "1512", "op": "amend-order", "args": [{"instId": "BTC-USDT", "ordId": "259432767558135808", "newSz": "2"}]} -# 批量改单 Amend Multiple Orders -# trade_param = {"id": "1512", "op": "batch-amend-orders", "args": [ -# {"instId": "BTC-USDT", "ordId": "", "newSz": "2"}, -# {"instId": "BTC-USDT", "ordId": "", "newSz": "3"} -# ]} - - -loop = asyncio.get_event_loop() - -# 公共频道 不需要登录(行情,持仓总量,K线,标记价格,深度,资金费率等)subscribe public channel -loop.run_until_complete(subscribe_without_login(url, channels)) - -# 私有频道 需要登录(账户,持仓,订单等)subscribe private channel -# loop.run_until_complete(subscribe(url, api_key, passphrase, secret_key, channels)) - -# 交易(下单,撤单,改单等)trade -# loop.run_until_complete(trade(url, api_key, passphrase, secret_key, trade_param)) - -loop.close() From ccfc4533fb347195315ee8468be035768fb4a234 Mon Sep 17 00:00:00 2001 From: Kate Hu Date: Thu, 16 Feb 2023 14:18:25 +0800 Subject: [PATCH 011/139] modified readme --- README.md | 12 ++++++------ id_rsa_api | 7 +++++++ id_rsa_api.pub | 1 + 3 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 id_rsa_api create mode 100644 id_rsa_api.pub diff --git a/README.md b/README.md index b33edd45..f337192f 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ https://github.com/okxapi/python-okx #### OKX API Telegram https://t.me/OKXAPI #### API trading tutorials -- Spot trading: [](https://www.okx.com/learn/spot-trading-with-jupyter-notebook) -- Derivative trading: [](https://www.okx.com/learn/derivatives-trading-with-jupyter-notebook) +- Spot trading: https://www.okx.com/learn/spot-trading-with-jupyter-notebook +- Derivative trading: https://www.okx.com/learn/derivatives-trading-with-jupyter-notebook Make sure you update often and check the [Changelog](https://www.okx.com/docs-v5/log_en/) for new features and bug fixes. @@ -27,8 +27,8 @@ Make sure you update often and check the [Changelog](https://www.okx.com/docs-v5 `WebSocketAPI: websockets package advise version 6.0` #### Step 1: register an account on OKX and apply for an API key -- Register account: [](https://www.okx.com/account/register) -- Apply for an API key: [](https://www.okx.com/account/users/myApi) +- Register for an account: https://www.okx.com/account/register +- Apply for an API key: https://www.okx.com/account/users/myApi #### Step 2: install python-okx @@ -46,7 +46,7 @@ passphrase = "" ``` - RestAPI - For spot trading: run example/get_started_en.ipynb - - For derivative trading: run example/https://github.com/okxapi/python-okx/blob/master/example/trade_derivatives_en.ipynb + - For derivative trading: run example/trade_derivatives_en.ipynb - Tweak the value of the parameter `flag` (live trading: 0, demo trading: 1 ) to switch between live and demo trading environment - WebSocketAPI @@ -88,4 +88,4 @@ Note ```python https://github.com/Rapptz/discord.py/issues/1996 https://github.com/aaugustin/websockets/issues/587 - ``` \ No newline at end of file + ``` diff --git a/id_rsa_api b/id_rsa_api new file mode 100644 index 00000000..e8d588ef --- /dev/null +++ b/id_rsa_api @@ -0,0 +1,7 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACDIy/y1JnknxG11xPPGe3vkK9yW0fUReNanR38dovJcEwAAAJB+PKQSfjyk +EgAAAAtzc2gtZWQyNTUxOQAAACDIy/y1JnknxG11xPPGe3vkK9yW0fUReNanR38dovJcEw +AAAEDkxjjpG/q2+2BHVAUd7q9KNUSjZbEZ2mfBdZqplHaDMsjL/LUmeSfEbXXE88Z7e+Qr +3JbR9RF41qdHfx2i8lwTAAAAC2FwaUBva2cuY29tAQI= +-----END OPENSSH PRIVATE KEY----- diff --git a/id_rsa_api.pub b/id_rsa_api.pub new file mode 100644 index 00000000..4c8932bb --- /dev/null +++ b/id_rsa_api.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMjL/LUmeSfEbXXE88Z7e+Qr3JbR9RF41qdHfx2i8lwT api@okg.com From 7fdd9026da9358053faa88991db88f7c27302576 Mon Sep 17 00:00:00 2001 From: Kate Hu Date: Thu, 16 Feb 2023 14:32:50 +0800 Subject: [PATCH 012/139] modified readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f337192f..cd7e53e8 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ ### Overview -This is an unofficial Python wrapper for the [OKX exchange REST API v5](https://www.okx.com/docs-v5/en/) +This is an unofficial Python wrapper for the [OKX exchange v5 API](https://www.okx.com/okx-api) If you came here looking to purchase cryptocurrencies from the OKX exchange, please go [here](https://www.okx.com/). From e472ac4bb40f64c0c5a55d1108a146859aff087d Mon Sep 17 00:00:00 2001 From: Kate Hu Date: Thu, 16 Feb 2023 14:44:07 +0800 Subject: [PATCH 013/139] modified readme --- README.md | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index cd7e53e8..bae9a2b1 100644 --- a/README.md +++ b/README.md @@ -53,21 +53,8 @@ passphrase = "" - Run test/WsPrivateTest.py for private websocket channels - Run test/WsPublicTest.py for public websocket channels - Use different URLs for different environment - -```python -# WebSocket public channel -# live trading -url = "wss://ws.okx.com:8443/ws/v5/public?brokerId=9999" -# demo trading -url = "wss://wspap.okx.com:8443/ws/v5/public?brokerId=9999" - -# WebSocket private channel -# live trading -url = "wss://ws.okx.com:8443/ws/v5/private?brokerId=9999" -# demo trading -url = "wss://wspap.okx.com:8443/ws/v5/private?brokerId=9999" - -``` + - Production URLs: https://www.okx.com/docs-v5/en/#overview-production-trading-services + - Demo trading URLs: https://www.okx.com/docs-v5/en/#overview-demo-trading-services Note From 93ef09fefdeb85537501423e14b9538a668fc4a3 Mon Sep 17 00:00:00 2001 From: Kate Hu Date: Thu, 16 Feb 2023 14:45:35 +0800 Subject: [PATCH 014/139] modified readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bae9a2b1..35afb603 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ passphrase = "" - Run test/WsPrivateTest.py for private websocket channels - Run test/WsPublicTest.py for public websocket channels - Use different URLs for different environment - - Production URLs: https://www.okx.com/docs-v5/en/#overview-production-trading-services + - Live trading URLs: https://www.okx.com/docs-v5/en/#overview-production-trading-services - Demo trading URLs: https://www.okx.com/docs-v5/en/#overview-demo-trading-services Note From 48fd15ef1ffac2f2e7d0e45beeb610f37c0ac78b Mon Sep 17 00:00:00 2001 From: "shiyao.zhu" Date: Thu, 16 Feb 2023 15:22:32 +0800 Subject: [PATCH 015/139] update requirements.txt --- okx/__init__.py | 2 +- requirements.txt | 101 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 requirements.txt diff --git a/okx/__init__.py b/okx/__init__.py index 71c25d8f..64133465 100644 --- a/okx/__init__.py +++ b/okx/__init__.py @@ -2,4 +2,4 @@ Python SDK for the OKX API v5 """ -__version__="0.1.0" \ No newline at end of file +__version__="0.1.4" \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..4482a8c5 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,101 @@ +anyio==3.6.1 +appnope==0.1.2 +argon2-cffi==20.1.0 +async-generator==1.10 +attrs==22.1.0 +autobahn==23.1.2 +Automat==22.10.0 +backcall==0.2.0 +bleach==3.3.0 +certifi==2022.6.15.2 +cffi==1.14.5 +charset-normalizer==2.1.1 +commonmark==0.9.1 +constantly==15.1.0 +cryptography==38.0.3 +decorator==5.0.9 +defusedxml==0.7.1 +demjson==2.2.4 +docutils==0.19 +entrypoints==0.3 +et-xmlfile==1.1.0 +gevent==22.10.2 +greenlet==2.0.1 +h11==0.12.0 +h2==4.1.0 +hpack==4.0.0 +httpcore==0.15.0 +httpx==0.23.0 +hyperframe==6.0.1 +hyperlink==21.0.0 +idna==3.4 +importlib-metadata==4.12.0 +incremental==22.10.0 +ipykernel==5.5.5 +ipython==7.23.1 +ipython-genutils==0.2.0 +jaraco.classes==3.2.2 +jedi==0.18.0 +Jinja2==3.0.1 +jsonschema==3.2.0 +jupyter-client==6.1.12 +jupyter-core==4.7.1 +jupyterlab-pygments==0.1.2 +keyring==23.9.3 +MarkupSafe==2.0.1 +matplotlib-inline==0.1.2 +mistune==0.8.4 +more-itertools==8.14.0 +nbclient==0.5.3 +nbconvert==6.0.7 +nbformat==5.1.3 +nest-asyncio==1.5.1 +notebook==6.4.0 +numpy==1.21.2 +openpyxl==3.0.7 +packaging==20.9 +pandas==1.3.2 +pandocfilters==1.4.3 +parso==0.8.2 +pexpect==4.8.0 +pickleshare==0.7.5 +pkginfo==1.8.3 +prometheus-client==0.10.1 +prompt-toolkit==3.0.18 +ptyprocess==0.7.0 +pyasn1==0.4.8 +pyasn1-modules==0.2.8 +pycparser==2.20 +Pygments==2.9.0 +pyOpenSSL==23.0.0 +pyparsing==2.4.7 +pyrsistent==0.17.3 +python-dateutil==2.8.1 +python-okx==0.1.4 +pytz==2021.1 +pyzmq==22.1.0 +readme-renderer==37.2 +requests==2.28.2 +requests-toolbelt==0.9.1 +rfc3986==1.5.0 +rich==12.5.1 +Send2Trash==1.5.0 +service-identity==21.1.0 +six==1.16.0 +sniffio==1.3.0 +terminado==0.10.0 +testpath==0.5.0 +tornado==6.1 +traitlets==5.0.5 +twine==4.0.1 +Twisted==22.10.0 +txaio==22.2.1 +typing_extensions==4.4.0 +urllib3==1.26.12 +wcwidth==0.2.5 +webencodings==0.5.1 +websocket==0.2.1 +websockets==10.4 +zipp==3.8.1 +zope.event==4.5.0 +zope.interface==5.5.2 From 3df5503ca6321f98e225407c415119f7a4407db9 Mon Sep 17 00:00:00 2001 From: "shiyao.zhu" Date: Thu, 16 Feb 2023 15:45:02 +0800 Subject: [PATCH 016/139] update version --- okx/__init__.py | 2 +- requirements.txt | 101 ----------------------------------------------- 2 files changed, 1 insertion(+), 102 deletions(-) delete mode 100644 requirements.txt diff --git a/okx/__init__.py b/okx/__init__.py index 64133465..c514a84e 100644 --- a/okx/__init__.py +++ b/okx/__init__.py @@ -2,4 +2,4 @@ Python SDK for the OKX API v5 """ -__version__="0.1.4" \ No newline at end of file +__version__="0.1.5" \ No newline at end of file diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 4482a8c5..00000000 --- a/requirements.txt +++ /dev/null @@ -1,101 +0,0 @@ -anyio==3.6.1 -appnope==0.1.2 -argon2-cffi==20.1.0 -async-generator==1.10 -attrs==22.1.0 -autobahn==23.1.2 -Automat==22.10.0 -backcall==0.2.0 -bleach==3.3.0 -certifi==2022.6.15.2 -cffi==1.14.5 -charset-normalizer==2.1.1 -commonmark==0.9.1 -constantly==15.1.0 -cryptography==38.0.3 -decorator==5.0.9 -defusedxml==0.7.1 -demjson==2.2.4 -docutils==0.19 -entrypoints==0.3 -et-xmlfile==1.1.0 -gevent==22.10.2 -greenlet==2.0.1 -h11==0.12.0 -h2==4.1.0 -hpack==4.0.0 -httpcore==0.15.0 -httpx==0.23.0 -hyperframe==6.0.1 -hyperlink==21.0.0 -idna==3.4 -importlib-metadata==4.12.0 -incremental==22.10.0 -ipykernel==5.5.5 -ipython==7.23.1 -ipython-genutils==0.2.0 -jaraco.classes==3.2.2 -jedi==0.18.0 -Jinja2==3.0.1 -jsonschema==3.2.0 -jupyter-client==6.1.12 -jupyter-core==4.7.1 -jupyterlab-pygments==0.1.2 -keyring==23.9.3 -MarkupSafe==2.0.1 -matplotlib-inline==0.1.2 -mistune==0.8.4 -more-itertools==8.14.0 -nbclient==0.5.3 -nbconvert==6.0.7 -nbformat==5.1.3 -nest-asyncio==1.5.1 -notebook==6.4.0 -numpy==1.21.2 -openpyxl==3.0.7 -packaging==20.9 -pandas==1.3.2 -pandocfilters==1.4.3 -parso==0.8.2 -pexpect==4.8.0 -pickleshare==0.7.5 -pkginfo==1.8.3 -prometheus-client==0.10.1 -prompt-toolkit==3.0.18 -ptyprocess==0.7.0 -pyasn1==0.4.8 -pyasn1-modules==0.2.8 -pycparser==2.20 -Pygments==2.9.0 -pyOpenSSL==23.0.0 -pyparsing==2.4.7 -pyrsistent==0.17.3 -python-dateutil==2.8.1 -python-okx==0.1.4 -pytz==2021.1 -pyzmq==22.1.0 -readme-renderer==37.2 -requests==2.28.2 -requests-toolbelt==0.9.1 -rfc3986==1.5.0 -rich==12.5.1 -Send2Trash==1.5.0 -service-identity==21.1.0 -six==1.16.0 -sniffio==1.3.0 -terminado==0.10.0 -testpath==0.5.0 -tornado==6.1 -traitlets==5.0.5 -twine==4.0.1 -Twisted==22.10.0 -txaio==22.2.1 -typing_extensions==4.4.0 -urllib3==1.26.12 -wcwidth==0.2.5 -webencodings==0.5.1 -websocket==0.2.1 -websockets==10.4 -zipp==3.8.1 -zope.event==4.5.0 -zope.interface==5.5.2 From ee870fe9c5af72d5a04882a8e3945a8682d818c5 Mon Sep 17 00:00:00 2001 From: "shiyao.zhu" Date: Thu, 16 Feb 2023 15:47:56 +0800 Subject: [PATCH 017/139] add setup.py --- .gitignore | 1 - setup.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 setup.py diff --git a/.gitignore b/.gitignore index 916f0848..fb645bb2 100644 --- a/.gitignore +++ b/.gitignore @@ -29,5 +29,4 @@ build/ ### VS Code ### .vscode/ -setup.py id_rsa* \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 00000000..8f92bbeb --- /dev/null +++ b/setup.py @@ -0,0 +1,28 @@ +import setuptools +import okx +with open("README.md", "r") as fh: + long_description = fh.read() + +setuptools.setup( + name="python-okx", + version=okx.__version__, + author="okxv5api", + author_email="api@okg.com", + description="Python SDK for OKX", + long_description=long_description, + long_description_content_type="text/markdown", + url="https://okx.com/docs-v5/", + packages=setuptools.find_packages(), + classifiers=[ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + ], + install_requires=[ + "importlib-metadata", + "keyring", + "requests", + "Twisted", + "pyOpenSSL" + ] +) \ No newline at end of file From 19dc43673db7c24c5ae3c9281cd9a405edda12b9 Mon Sep 17 00:00:00 2001 From: okxapi <115602548+okxapi@users.noreply.github.com> Date: Thu, 9 Mar 2023 16:48:00 +0800 Subject: [PATCH 018/139] Update trade_derivatives_en.ipynb --- example/trade_derivatives_en.ipynb | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/example/trade_derivatives_en.ipynb b/example/trade_derivatives_en.ipynb index bb43a24d..0b96bafb 100644 --- a/example/trade_derivatives_en.ipynb +++ b/example/trade_derivatives_en.ipynb @@ -52,19 +52,6 @@ "name": "#%%\n" } }, - "outputs": [ - { - "ename": "ModuleNotFoundError", - "evalue": "No module named 'okx'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn [1], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mokx\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mTrade\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mTrade\u001b[39;00m\n", - "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'okx'" - ] - } - ], "source": [ "import okx.Trade as Trade" ] From 6867bfe0d3fc8b5a57ab681cf76996f505a16c59 Mon Sep 17 00:00:00 2001 From: okxapi <115602548+okxapi@users.noreply.github.com> Date: Thu, 9 Mar 2023 17:05:34 +0800 Subject: [PATCH 019/139] Update trade_derivatives_en.ipynb --- example/trade_derivatives_en.ipynb | 1 + 1 file changed, 1 insertion(+) diff --git a/example/trade_derivatives_en.ipynb b/example/trade_derivatives_en.ipynb index 0b96bafb..409a2e05 100644 --- a/example/trade_derivatives_en.ipynb +++ b/example/trade_derivatives_en.ipynb @@ -52,6 +52,7 @@ "name": "#%%\n" } }, + "outputs": [], "source": [ "import okx.Trade as Trade" ] From a0a946b67c52eb1eabdce87d7a96b5090b72e117 Mon Sep 17 00:00:00 2001 From: okxapi <115602548+okxapi@users.noreply.github.com> Date: Thu, 9 Mar 2023 17:10:27 +0800 Subject: [PATCH 020/139] Update get_started_en.ipynb --- example/get_started_en.ipynb | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/example/get_started_en.ipynb b/example/get_started_en.ipynb index de8db080..a255e004 100644 --- a/example/get_started_en.ipynb +++ b/example/get_started_en.ipynb @@ -102,17 +102,7 @@ "name": "#%%\n" } }, - "outputs": [ - { - "ename": "ModuleNotFoundError", - "evalue": "No module named 'okx'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn [2], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mokx\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mTrade\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mTrade\u001b[39;00m\n", - "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'okx'" - ] + "outputs": [] } ], "source": [ From 48d29f19c61fd084e2f32ceca6bf144668b17d3d Mon Sep 17 00:00:00 2001 From: okxapi <115602548+okxapi@users.noreply.github.com> Date: Thu, 9 Mar 2023 17:10:58 +0800 Subject: [PATCH 021/139] Update trade_derivatives_en.ipynb --- example/trade_derivatives_en.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/trade_derivatives_en.ipynb b/example/trade_derivatives_en.ipynb index 409a2e05..db5438a0 100644 --- a/example/trade_derivatives_en.ipynb +++ b/example/trade_derivatives_en.ipynb @@ -46,7 +46,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "pycharm": { "name": "#%%\n" From cdb0a219b5cb6bca7ec64b94e714546f1e8702c6 Mon Sep 17 00:00:00 2001 From: okxapi <115602548+okxapi@users.noreply.github.com> Date: Thu, 9 Mar 2023 17:13:06 +0800 Subject: [PATCH 022/139] Update get_started_en.ipynb --- example/get_started_en.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/get_started_en.ipynb b/example/get_started_en.ipynb index a255e004..c2af6684 100644 --- a/example/get_started_en.ipynb +++ b/example/get_started_en.ipynb @@ -96,13 +96,13 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { "pycharm": { "name": "#%%\n" } }, - "outputs": [] + "outputs": [], } ], "source": [ From 317fb0931fa92ad33eb9836977e8b396930440dd Mon Sep 17 00:00:00 2001 From: okxapi <115602548+okxapi@users.noreply.github.com> Date: Thu, 9 Mar 2023 17:14:05 +0800 Subject: [PATCH 023/139] Update get_started_en.ipynb --- example/get_started_en.ipynb | 2 -- 1 file changed, 2 deletions(-) diff --git a/example/get_started_en.ipynb b/example/get_started_en.ipynb index c2af6684..f8a0c38c 100644 --- a/example/get_started_en.ipynb +++ b/example/get_started_en.ipynb @@ -103,8 +103,6 @@ } }, "outputs": [], - } - ], "source": [ "import okx.Trade as Trade" ] From 709947bce423491cc470130c151308b3766ed629 Mon Sep 17 00:00:00 2001 From: okxapi <115602548+okxapi@users.noreply.github.com> Date: Thu, 9 Mar 2023 17:17:46 +0800 Subject: [PATCH 024/139] Update get_started_en.ipynb --- example/get_started_en.ipynb | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/example/get_started_en.ipynb b/example/get_started_en.ipynb index f8a0c38c..001587b7 100644 --- a/example/get_started_en.ipynb +++ b/example/get_started_en.ipynb @@ -15,32 +15,13 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "pycharm": { "name": "#%%\n" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: python-okx in /Users/skylerfeng/opt/anaconda3/lib/python3.9/site-packages (0.0.12)\n", - "Requirement already satisfied: h2 in /Users/skylerfeng/opt/anaconda3/lib/python3.9/site-packages (from python-okx) (4.1.0)\n", - "Requirement already satisfied: httpx in /Users/skylerfeng/opt/anaconda3/lib/python3.9/site-packages (from python-okx) (0.23.0)\n", - "Requirement already satisfied: hyperframe<7,>=6.0 in /Users/skylerfeng/opt/anaconda3/lib/python3.9/site-packages (from h2->python-okx) (6.0.1)\n", - "Requirement already satisfied: hpack<5,>=4.0 in /Users/skylerfeng/opt/anaconda3/lib/python3.9/site-packages (from h2->python-okx) (4.0.0)\n", - "Requirement already satisfied: rfc3986[idna2008]<2,>=1.3 in /Users/skylerfeng/opt/anaconda3/lib/python3.9/site-packages (from httpx->python-okx) (1.5.0)\n", - "Requirement already satisfied: certifi in /Users/skylerfeng/opt/anaconda3/lib/python3.9/site-packages (from httpx->python-okx) (2021.10.8)\n", - "Requirement already satisfied: httpcore<0.16.0,>=0.15.0 in /Users/skylerfeng/opt/anaconda3/lib/python3.9/site-packages (from httpx->python-okx) (0.15.0)\n", - "Requirement already satisfied: sniffio in /Users/skylerfeng/opt/anaconda3/lib/python3.9/site-packages (from httpx->python-okx) (1.2.0)\n", - "Requirement already satisfied: h11<0.13,>=0.11 in /Users/skylerfeng/opt/anaconda3/lib/python3.9/site-packages (from httpcore<0.16.0,>=0.15.0->httpx->python-okx) (0.12.0)\n", - "Requirement already satisfied: anyio==3.* in /Users/skylerfeng/opt/anaconda3/lib/python3.9/site-packages (from httpcore<0.16.0,>=0.15.0->httpx->python-okx) (3.5.0)\n", - "Requirement already satisfied: idna>=2.8 in /Users/skylerfeng/opt/anaconda3/lib/python3.9/site-packages (from anyio==3.*->httpcore<0.16.0,>=0.15.0->httpx->python-okx) (3.3)\n" - ] - } - ], + "outputs": [], "source": [ "! pip install python-okx --upgrade" ] From 5b9acb686411d33caedf49075c49e32ddd5950e6 Mon Sep 17 00:00:00 2001 From: zhangjiexian Date: Thu, 16 Mar 2023 15:29:33 +0800 Subject: [PATCH 025/139] httpx client not varify and no timeout --- okx/client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/okx/client.py b/okx/client.py index 26ae6033..9911080b 100644 --- a/okx/client.py +++ b/okx/client.py @@ -7,7 +7,7 @@ class Client(object): - def __init__(self, api_key = '-1', api_secret_key = '-1', passphrase = '-1', use_server_time=False, flag='1', base_api = 'https://www.okx.com',debug = 'True'): + def __init__(self, api_key = '-1', api_secret_key = '-1', passphrase = '-1', use_server_time=False, flag='1', base_api = 'https://www.okx.com',debug = False): self.API_KEY = api_key self.API_SECRET_KEY = api_secret_key @@ -16,7 +16,7 @@ def __init__(self, api_key = '-1', api_secret_key = '-1', passphrase = '-1', use self.flag = flag self.domain = base_api self.debug = debug - self.client = httpx.Client(base_url=base_api, http2=True) + self.client = httpx.Client(base_url=base_api, http2=True, verify=False, timeout=None) def _request(self, method, request_path, params): if method == c.GET: From 7f9a76d9a624f81c4776b447ca36579fbb723bb9 Mon Sep 17 00:00:00 2001 From: zhangjiexian Date: Fri, 17 Mar 2023 22:26:51 +0800 Subject: [PATCH 026/139] fix request path of server timestamp --- okx/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/okx/client.py b/okx/client.py index 9911080b..1f745162 100644 --- a/okx/client.py +++ b/okx/client.py @@ -49,7 +49,7 @@ def _request_with_params(self, method, request_path, params): return self._request(method, request_path, params) def _get_timestamp(self): - request_path = c.API_URL + c.SERVER_TIMESTAMP_URL + request_path = base_api + c.SERVER_TIMESTAMP_URL response = self.client.get(request_path) if response.status_code == 200: return response.json()['ts'] From 317ccc9bf3149077cdde416aec6995f29cec1cd5 Mon Sep 17 00:00:00 2001 From: zhangjiexian Date: Mon, 20 Mar 2023 20:52:01 +0800 Subject: [PATCH 027/139] retry while http request failed --- okx/client.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/okx/client.py b/okx/client.py index 1f745162..920f8bb0 100644 --- a/okx/client.py +++ b/okx/client.py @@ -4,6 +4,7 @@ from . import consts as c, utils, exceptions +import time class Client(object): @@ -38,15 +39,32 @@ def _request(self, method, request_path, params): response = self.client.get(request_path, headers=header) elif method == c.POST: response = self.client.post(request_path, data=body, headers=header) + return response + + def _request_until_success(self, method, request_path, params): + response = '' + retry_times = 0 + retry_times_max = 15 + while True: + try: + response = self._request(method, request_path, params) + break + except: + retry_times += 1 + if retry_times > retry_times_max: + print('reach max retry times, exit loop.') + break + print('http request failed, retry in 1 seconds ... retry times:', retry_times) + time.sleep(1) if not str(response.status_code).startswith('2'): raise exceptions.OkxAPIException(response) return response.json() def _request_without_params(self, method, request_path): - return self._request(method, request_path, {}) + return self._request_with_params(method, request_path, {}) def _request_with_params(self, method, request_path, params): - return self._request(method, request_path, params) + return self._request_until_success(method, request_path, params) def _get_timestamp(self): request_path = base_api + c.SERVER_TIMESTAMP_URL From 1c8b51a7b7fb92895f7cedb0f8bde34752685f4c Mon Sep 17 00:00:00 2001 From: zhangjiexian Date: Mon, 20 Mar 2023 23:45:49 +0800 Subject: [PATCH 028/139] show traceback msg while exception --- okx/client.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/okx/client.py b/okx/client.py index 920f8bb0..62ee6cf5 100644 --- a/okx/client.py +++ b/okx/client.py @@ -6,6 +6,8 @@ import time +import traceback + class Client(object): def __init__(self, api_key = '-1', api_secret_key = '-1', passphrase = '-1', use_server_time=False, flag='1', base_api = 'https://www.okx.com',debug = False): @@ -49,7 +51,9 @@ def _request_until_success(self, method, request_path, params): try: response = self._request(method, request_path, params) break - except: + except Exception as e: + msg = traceback.format_exc() + print(msg) retry_times += 1 if retry_times > retry_times_max: print('reach max retry times, exit loop.') From 3084294434eb99bf4ae79833b8b322e9c204a0db Mon Sep 17 00:00:00 2001 From: zhangjiexian Date: Tue, 21 Mar 2023 03:59:50 +0800 Subject: [PATCH 029/139] re connect while reaching the max request times --- okx/client.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/okx/client.py b/okx/client.py index 62ee6cf5..78326ce8 100644 --- a/okx/client.py +++ b/okx/client.py @@ -8,6 +8,8 @@ import traceback +from httpx import _client + class Client(object): def __init__(self, api_key = '-1', api_secret_key = '-1', passphrase = '-1', use_server_time=False, flag='1', base_api = 'https://www.okx.com',debug = False): @@ -19,6 +21,7 @@ def __init__(self, api_key = '-1', api_secret_key = '-1', passphrase = '-1', use self.flag = flag self.domain = base_api self.debug = debug + self.request_times = 0 self.client = httpx.Client(base_url=base_api, http2=True, verify=False, timeout=None) def _request(self, method, request_path, params): @@ -41,6 +44,13 @@ def _request(self, method, request_path, params): response = self.client.get(request_path, headers=header) elif method == c.POST: response = self.client.post(request_path, data=body, headers=header) + self.request_times += 1 + # print('request times:', self.request_times) + if (self.request_times > 512): + self.client.close() + self.client._state = _client.ClientState.UNOPENED + self.request_times = 0 + # print('close the current tcp connection while request times larger than 512.') return response def _request_until_success(self, method, request_path, params): From b47f519f79087e6d3c51ced82b5e9ed24d118a9d Mon Sep 17 00:00:00 2001 From: zhangjiexian Date: Tue, 21 Mar 2023 16:20:19 +0800 Subject: [PATCH 030/139] retry in 1 second but not raise exception --- okx/client.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/okx/client.py b/okx/client.py index 78326ce8..f050f9f6 100644 --- a/okx/client.py +++ b/okx/client.py @@ -56,22 +56,24 @@ def _request(self, method, request_path, params): def _request_until_success(self, method, request_path, params): response = '' retry_times = 0 - retry_times_max = 15 while True: try: response = self._request(method, request_path, params) + if not str(response.status_code).startswith('2'): + print('response.status_code:', response.status_code) + print('response.json.code:', response.json()['code']) + print('response.json.msg:', response.json()['msg']) + time.sleep(1) + continue break except Exception as e: msg = traceback.format_exc() - print(msg) + print(e) retry_times += 1 - if retry_times > retry_times_max: - print('reach max retry times, exit loop.') - break - print('http request failed, retry in 1 seconds ... retry times:', retry_times) + print('http request retry in 1 seconds, retry times:', retry_times) time.sleep(1) - if not str(response.status_code).startswith('2'): - raise exceptions.OkxAPIException(response) + # if not str(response.status_code).startswith('2'): + # raise exceptions.OkxAPIException(response) return response.json() def _request_without_params(self, method, request_path): @@ -81,7 +83,7 @@ def _request_with_params(self, method, request_path, params): return self._request_until_success(method, request_path, params) def _get_timestamp(self): - request_path = base_api + c.SERVER_TIMESTAMP_URL + request_path = self.domain + c.SERVER_TIMESTAMP_URL response = self.client.get(request_path) if response.status_code == 200: return response.json()['ts'] From e3fa532aeddf238ae8a05aeec81ea86665fc386c Mon Sep 17 00:00:00 2001 From: "shiyao.zhu" Date: Thu, 23 Mar 2023 14:54:44 +0800 Subject: [PATCH 031/139] update version --- okx/__init__.py | 2 +- okx/client.py | 30 +++++++++++++----------------- okx/consts.py | 2 +- setup.py | 1 + 4 files changed, 16 insertions(+), 19 deletions(-) diff --git a/okx/__init__.py b/okx/__init__.py index c514a84e..d98db503 100644 --- a/okx/__init__.py +++ b/okx/__init__.py @@ -2,4 +2,4 @@ Python SDK for the OKX API v5 """ -__version__="0.1.5" \ No newline at end of file +__version__="0.1.6" \ No newline at end of file diff --git a/okx/client.py b/okx/client.py index f050f9f6..0f5e6528 100644 --- a/okx/client.py +++ b/okx/client.py @@ -1,18 +1,17 @@ import json - -import httpx - -from . import consts as c, utils, exceptions - import time - import traceback +import httpx from httpx import _client +from . import consts as c, utils + + class Client(object): - def __init__(self, api_key = '-1', api_secret_key = '-1', passphrase = '-1', use_server_time=False, flag='1', base_api = 'https://www.okx.com',debug = False): + def __init__(self, api_key='-1', api_secret_key='-1', passphrase='-1', use_server_time=False, flag='1', + base_api=c.DOMAIN, debug=False): self.API_KEY = api_key self.API_SECRET_KEY = api_secret_key @@ -32,25 +31,24 @@ def _request(self, method, request_path, params): timestamp = self._get_timestamp() body = json.dumps(params) if method == c.POST else "" if self.API_KEY != '-1': - sign = utils.sign(utils.pre_hash(timestamp, method, request_path, str(body), self.debug), self.API_SECRET_KEY) + sign = utils.sign(utils.pre_hash(timestamp, method, request_path, str(body), self.debug), + self.API_SECRET_KEY) header = utils.get_header(self.API_KEY, sign, timestamp, self.PASSPHRASE, self.flag, self.debug) else: header = utils.get_header_no_sign(self.flag, self.debug) response = None - if self.debug == True: - print('domain:',self.domain) - print('url:',request_path) + if self.debug: + print('domain:', self.domain) + print('url:', request_path) if method == c.GET: response = self.client.get(request_path, headers=header) elif method == c.POST: response = self.client.post(request_path, data=body, headers=header) self.request_times += 1 - # print('request times:', self.request_times) - if (self.request_times > 512): + if self.request_times > 512: self.client.close() self.client._state = _client.ClientState.UNOPENED self.request_times = 0 - # print('close the current tcp connection while request times larger than 512.') return response def _request_until_success(self, method, request_path, params): @@ -67,13 +65,11 @@ def _request_until_success(self, method, request_path, params): continue break except Exception as e: - msg = traceback.format_exc() + traceback.format_exc() print(e) retry_times += 1 print('http request retry in 1 seconds, retry times:', retry_times) time.sleep(1) - # if not str(response.status_code).startswith('2'): - # raise exceptions.OkxAPIException(response) return response.json() def _request_without_params(self, method, request_path): diff --git a/okx/consts.py b/okx/consts.py index 833e44f5..ebb96c24 100644 --- a/okx/consts.py +++ b/okx/consts.py @@ -1,5 +1,5 @@ # http header -#API_URL = 'https://www.okx.com' +DOMAIN = 'https://www.okx.com' CONTENT_TYPE = 'Content-Type' OK_ACCESS_KEY = 'OK-ACCESS-KEY' diff --git a/setup.py b/setup.py index 8f92bbeb..15923cab 100644 --- a/setup.py +++ b/setup.py @@ -20,6 +20,7 @@ ], install_requires=[ "importlib-metadata", + "httpx", "keyring", "requests", "Twisted", From bb363513b9af80361ff670032a9988132ac32490 Mon Sep 17 00:00:00 2001 From: okxapi <115602548+okxapi@users.noreply.github.com> Date: Mon, 27 Mar 2023 11:45:48 +0800 Subject: [PATCH 032/139] Update get_started_en.ipynb --- example/get_started_en.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/get_started_en.ipynb b/example/get_started_en.ipynb index 001587b7..85cc1432 100644 --- a/example/get_started_en.ipynb +++ b/example/get_started_en.ipynb @@ -166,11 +166,11 @@ }, "outputs": [], "source": [ - "import okx.MarketData as MarketData\n", + "import okx.Market as MarketData\n", "\n", "flag = \"1\" # live trading: 0, demo trading: 1\n", "\n", - "marketDataAPI = MarketData.MarketAPI(flag=flag)\n", + "marketDataAPI = MarketData.Market(flag=flag)\n", "\n", "result = marketDataAPI.get_tickers(instType=\"SPOT\")\n", "print(result)" From 522c7b6d66e1c2cbc4db576a14215badcc3ab81d Mon Sep 17 00:00:00 2001 From: okxapi <115602548+okxapi@users.noreply.github.com> Date: Mon, 27 Mar 2023 11:51:33 +0800 Subject: [PATCH 033/139] Update trade_derivatives_en.ipynb --- example/trade_derivatives_en.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/trade_derivatives_en.ipynb b/example/trade_derivatives_en.ipynb index db5438a0..83950440 100644 --- a/example/trade_derivatives_en.ipynb +++ b/example/trade_derivatives_en.ipynb @@ -136,11 +136,11 @@ }, "outputs": [], "source": [ - "import okx.MarketData as MarketData\n", + "import okx.Market as MarketData\n", "\n", "flag = \"1\" # live trading: 0, demo trading: 1\n", "\n", - "marketDataAPI = MarketData.MarketAPI(flag = flag)\n", + "marketDataAPI = MarketData.Market(flag = flag)\n", "\n", "result = marketDataAPI.get_tickers(instType = \"SWAP\")\n", "print(result)" From 7b194634a8b40ef946eb914ebe4877719ce82362 Mon Sep 17 00:00:00 2001 From: okxapi <115602548+okxapi@users.noreply.github.com> Date: Mon, 27 Mar 2023 19:02:11 +0800 Subject: [PATCH 034/139] Update get_started_en.ipynb fix mistake --- example/get_started_en.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/get_started_en.ipynb b/example/get_started_en.ipynb index 85cc1432..001587b7 100644 --- a/example/get_started_en.ipynb +++ b/example/get_started_en.ipynb @@ -166,11 +166,11 @@ }, "outputs": [], "source": [ - "import okx.Market as MarketData\n", + "import okx.MarketData as MarketData\n", "\n", "flag = \"1\" # live trading: 0, demo trading: 1\n", "\n", - "marketDataAPI = MarketData.Market(flag=flag)\n", + "marketDataAPI = MarketData.MarketAPI(flag=flag)\n", "\n", "result = marketDataAPI.get_tickers(instType=\"SPOT\")\n", "print(result)" From f5e0b6dfa44cd56a9d5ab3c1f777b47b0c6ed207 Mon Sep 17 00:00:00 2001 From: okxapi <115602548+okxapi@users.noreply.github.com> Date: Tue, 28 Mar 2023 08:23:08 +0800 Subject: [PATCH 035/139] Update get_started_en.ipynb --- example/get_started_en.ipynb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/example/get_started_en.ipynb b/example/get_started_en.ipynb index 001587b7..29de8d46 100644 --- a/example/get_started_en.ipynb +++ b/example/get_started_en.ipynb @@ -286,13 +286,13 @@ }, "outputs": [], "source": [ - "import okx.MarketData as MarketData\n", + "import okx.PublicData as PublicData\n", "\n", "flag = \"1\" # live trading: 0, demo trading: 1\n", "\n", - "marketDataAPI = MarketData.MarketAPI(flag=flag)\n", + "PublicDataAPI = PublicData.PublicAPI(flag=flag)\n", "\n", - "result = marketDataAPI.get_instruments(\n", + "result = PublicDataAPI.get_instruments(\n", " instType=\"SPOT\"\n", ")\n", "print(result)" From f6338c12fe160453e7a42092767f485f1da5589c Mon Sep 17 00:00:00 2001 From: okxapi <115602548+okxapi@users.noreply.github.com> Date: Tue, 28 Mar 2023 08:26:28 +0800 Subject: [PATCH 036/139] Update trade_derivatives_en.ipynb --- example/trade_derivatives_en.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/trade_derivatives_en.ipynb b/example/trade_derivatives_en.ipynb index 83950440..db5438a0 100644 --- a/example/trade_derivatives_en.ipynb +++ b/example/trade_derivatives_en.ipynb @@ -136,11 +136,11 @@ }, "outputs": [], "source": [ - "import okx.Market as MarketData\n", + "import okx.MarketData as MarketData\n", "\n", "flag = \"1\" # live trading: 0, demo trading: 1\n", "\n", - "marketDataAPI = MarketData.Market(flag = flag)\n", + "marketDataAPI = MarketData.MarketAPI(flag = flag)\n", "\n", "result = marketDataAPI.get_tickers(instType = \"SWAP\")\n", "print(result)" From 806924e79ab71a250d28302de04a69787e9e7def Mon Sep 17 00:00:00 2001 From: "shiyao.zhu" Date: Tue, 28 Mar 2023 11:18:32 +0800 Subject: [PATCH 037/139] update dependence and version --- okx/__init__.py | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/okx/__init__.py b/okx/__init__.py index d98db503..1d14033e 100644 --- a/okx/__init__.py +++ b/okx/__init__.py @@ -2,4 +2,4 @@ Python SDK for the OKX API v5 """ -__version__="0.1.6" \ No newline at end of file +__version__="0.1.7" \ No newline at end of file diff --git a/setup.py b/setup.py index 15923cab..2b7a05da 100644 --- a/setup.py +++ b/setup.py @@ -20,7 +20,7 @@ ], install_requires=[ "importlib-metadata", - "httpx", + "httpx[http2]", "keyring", "requests", "Twisted", From 4594cda51e0e4aa585d77981bc2cedb9b30e3e71 Mon Sep 17 00:00:00 2001 From: "shiyao.zhu" Date: Tue, 28 Mar 2023 11:25:17 +0800 Subject: [PATCH 038/139] delete retry logic --- okx/__init__.py | 2 +- okx/client.py | 57 +++++++++++-------------------------------------- okx/consts.py | 2 +- 3 files changed, 15 insertions(+), 46 deletions(-) diff --git a/okx/__init__.py b/okx/__init__.py index 1d14033e..9c8f727d 100644 --- a/okx/__init__.py +++ b/okx/__init__.py @@ -2,4 +2,4 @@ Python SDK for the OKX API v5 """ -__version__="0.1.7" \ No newline at end of file +__version__="0.1.8" \ No newline at end of file diff --git a/okx/client.py b/okx/client.py index 0f5e6528..25c8a3d1 100644 --- a/okx/client.py +++ b/okx/client.py @@ -1,18 +1,13 @@ import json -import time -import traceback import httpx -from httpx import _client -from . import consts as c, utils +from . import consts as c, utils, exceptions class Client(object): - def __init__(self, api_key='-1', api_secret_key='-1', passphrase='-1', use_server_time=False, flag='1', - base_api=c.DOMAIN, debug=False): - + def __init__(self, api_key = '-1', api_secret_key = '-1', passphrase = '-1', use_server_time=False, flag='1', base_api = c.API_URL,debug = 'True'): self.API_KEY = api_key self.API_SECRET_KEY = api_secret_key self.PASSPHRASE = passphrase @@ -20,8 +15,7 @@ def __init__(self, api_key='-1', api_secret_key='-1', passphrase='-1', use_serve self.flag = flag self.domain = base_api self.debug = debug - self.request_times = 0 - self.client = httpx.Client(base_url=base_api, http2=True, verify=False, timeout=None) + self.client = httpx.Client(base_url=base_api, http2=True) def _request(self, method, request_path, params): if method == c.GET: @@ -31,57 +25,32 @@ def _request(self, method, request_path, params): timestamp = self._get_timestamp() body = json.dumps(params) if method == c.POST else "" if self.API_KEY != '-1': - sign = utils.sign(utils.pre_hash(timestamp, method, request_path, str(body), self.debug), - self.API_SECRET_KEY) + sign = utils.sign(utils.pre_hash(timestamp, method, request_path, str(body), self.debug), self.API_SECRET_KEY) header = utils.get_header(self.API_KEY, sign, timestamp, self.PASSPHRASE, self.flag, self.debug) else: header = utils.get_header_no_sign(self.flag, self.debug) response = None - if self.debug: - print('domain:', self.domain) - print('url:', request_path) + if self.debug == True: + print('domain:',self.domain) + print('url:',request_path) if method == c.GET: response = self.client.get(request_path, headers=header) elif method == c.POST: response = self.client.post(request_path, data=body, headers=header) - self.request_times += 1 - if self.request_times > 512: - self.client.close() - self.client._state = _client.ClientState.UNOPENED - self.request_times = 0 - return response - - def _request_until_success(self, method, request_path, params): - response = '' - retry_times = 0 - while True: - try: - response = self._request(method, request_path, params) - if not str(response.status_code).startswith('2'): - print('response.status_code:', response.status_code) - print('response.json.code:', response.json()['code']) - print('response.json.msg:', response.json()['msg']) - time.sleep(1) - continue - break - except Exception as e: - traceback.format_exc() - print(e) - retry_times += 1 - print('http request retry in 1 seconds, retry times:', retry_times) - time.sleep(1) + if not str(response.status_code).startswith('2'): + raise exceptions.OkxAPIException(response) return response.json() def _request_without_params(self, method, request_path): - return self._request_with_params(method, request_path, {}) + return self._request(method, request_path, {}) def _request_with_params(self, method, request_path, params): - return self._request_until_success(method, request_path, params) + return self._request(method, request_path, params) def _get_timestamp(self): - request_path = self.domain + c.SERVER_TIMESTAMP_URL + request_path = c.API_URL + c.SERVER_TIMESTAMP_URL response = self.client.get(request_path) if response.status_code == 200: return response.json()['ts'] else: - return "" + return "" \ No newline at end of file diff --git a/okx/consts.py b/okx/consts.py index ebb96c24..649e8430 100644 --- a/okx/consts.py +++ b/okx/consts.py @@ -1,5 +1,5 @@ # http header -DOMAIN = 'https://www.okx.com' +API_URL = 'https://www.okx.com' CONTENT_TYPE = 'Content-Type' OK_ACCESS_KEY = 'OK-ACCESS-KEY' From c8496e557ded5f073c258302308418c50836e6da Mon Sep 17 00:00:00 2001 From: Kate Hu Date: Tue, 28 Mar 2023 11:43:19 +0800 Subject: [PATCH 039/139] fixed typo --- .../get_started_en-checkpoint.ipynb | 1109 +++++++++++++++++ example/get_started_en.ipynb | 6 +- 2 files changed, 1112 insertions(+), 3 deletions(-) create mode 100644 example/.ipynb_checkpoints/get_started_en-checkpoint.ipynb diff --git a/example/.ipynb_checkpoints/get_started_en-checkpoint.ipynb b/example/.ipynb_checkpoints/get_started_en-checkpoint.ipynb new file mode 100644 index 00000000..706e4096 --- /dev/null +++ b/example/.ipynb_checkpoints/get_started_en-checkpoint.ipynb @@ -0,0 +1,1109 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "# Get Started\n", + "## Install python package\n", + "You can install `python-okx` from PyPi server." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "! pip install python-okx --upgrade" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "## Sign up as an OKX user\n", + "Please refer to [Create account](https://www.okx.com/account/register)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "## Create API Key\n", + "Please refer to [Create API Key](https://www.okx.com/account/my-api)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "## Import API modules\n", + "The following modules are available\n", + "- Trade\n", + "- BlockTrading\n", + "- Funding\n", + "- Account\n", + "- Convert\n", + "- Earning\n", + "- SubAccount\n", + "- MarketData\n", + "- PublicData\n", + "- TradingData\n", + "- Status\n", + "- NDBroker\n", + "- FDBroker" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "import okx.Trade as Trade" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "## Fill in your API key details" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "api_key = \"xxxxx\"\n", + "secret_key = \"xxxxx\"\n", + "passphrase = \"xxxxxx\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "## Get available funds" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "import okx.Funding as Funding\n", + "\n", + "flag = \"1\" # live trading: 0, demo trading: 1\n", + "\n", + "fundingAPI = Funding.FundingAPI(api_key, secret_key, passphrase, False, flag)\n", + "\n", + "result = fundingAPI.get_currencies()\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "## Get market data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "import okx.MarketData as MarketData\n", + "\n", + "flag = \"1\" # live trading: 0, demo trading: 1\n", + "\n", + "marketDataAPI = MarketData.MarketAPI(flag=flag)\n", + "\n", + "result = marketDataAPI.get_tickers(instType=\"SPOT\")\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "## Handle errors" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "You will the error code `51000` when. you run the following code. More details about the error code can be found in `msg`.\n", + "Please refer to [error code](https://www.okx.com/docs-v5/en/#error-code) for addtional information." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + }, + "scrolled": true + }, + "outputs": [], + "source": [ + "import okx.MarketData as MarketData\n", + "\n", + "flag = \"1\" # live trading: 0, demo trading: 1\n", + "\n", + "marketDataAPI = MarketData.MarketAPI(flag=flag)\n", + "\n", + "result = marketDataAPI.get_tickers( instType=\"SPOT\")\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "# Prepare for trading\n", + "- Make sure you understand the basic trading rules. Please refer to [Basic Trading Rules](https://www.okx.com/support/hc/en-us/sections/360011507312)\n", + "- Make sure you have enough funds in your trading account。Please refer to [Get balance](https://www.okx.com/docs-v5/en/#rest-api-account-get-balance)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "## Get account balance. Please refer to [Get balance](https://www.okx.com/docs-v5/en/#rest-api-account-get-balance)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + }, + "scrolled": true + }, + "outputs": [], + "source": [ + "import okx.Account as Account\n", + "flag = \"1\" # live trading: 0, demo trading: 1\n", + "\n", + "accountAPI = Account.AccountAPI(api_key, secret_key, passphrase, False, flag)\n", + "\n", + "result = accountAPI.get_account_balance()\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "## Get available trading pairs from [Get instruments](https://www.okx.com/docs-v5/en/#rest-api-public-data-get-instruments)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + }, + "scrolled": true + }, + "outputs": [], + "source": [ + "import okx.PublicData as PublicData\n", + "\n", + "flag = \"1\" # live trading: 0, demo trading: 1\n", + "\n", + "PublicDataAPI = PublicData.PublicAPI(flag=flag)\n", + "\n", + "result = PublicDataAPI.get_instruments(\n", + " instType=\"SPOT\"\n", + ")\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "## Make sure you have enough funds to trade a certain pair. Please refer to [Get maximum tradable amount](https://www.okx.com/docs-v5/en/#rest-api-account-get-maximum-available-tradable-amount)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "import okx.Account as Account\n", + "\n", + "flag = \"1\" # live trading: 0, demo trading: 1\n", + "\n", + "accountAPI = Account.AccountAPI(api_key, secret_key, passphrase, False, flag)\n", + "\n", + "result = accountAPI.get_max_avail_size(\n", + " instId=\"BTC-USDT\",\n", + " tdMode=\"cash\"\n", + ")\n", + "print(result)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "import okx.Account as Account\n", + "\n", + "flag = \"1\" # live trading: 0, demo trading: 1\n", + "\n", + "accountAPI = Account.AccountAPI(api_key, secret_key, passphrase, False, flag)\n", + "\n", + "result = accountAPI.get_max_avail_size(\n", + " instId=\"BTC-USDT\",\n", + " tdMode=\"cash\"\n", + ")\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "## In unified account, you can trade Spot under simple, single currency, multi currency and portfolio margin account mode. Please refer to [Introduction on Unified Account](https://www.okx.com/support/hc/en-us/articles/360054690791-1-统一交易账户介绍)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "## Get the current account configuration from the `acctLv` parameter in [Get account configuration](https://www.okx.com/docs-v5/en/#rest-api-account-get-account-configuration)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "import okx.Account as Account\n", + "\n", + "flag = \"1\" # live trading: 0, demo trading: 1\n", + "\n", + "accountAPI = Account.AccountAPI(api_key, secret_key, passphrase, False, flag)\n", + "result = accountAPI.get_account_config()\n", + "print(result)\n", + "\n", + "if result['code'] == \"0\":\n", + " acctLv = result[\"data\"][0][\"acctLv\"]\n", + " if acctLv == \"1\":\n", + " print(\"Simple mode\")\n", + " elif acctLv == \"2\":\n", + " print(\"Single-currency margin mode\")\n", + " elif acctLv == \"3\":\n", + " print(\"Multi-currency margin mode\")\n", + " elif acctLv == \"4\":\n", + " print(\"Portfolio margin mode\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "# Start Spot Trading" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "### Spot trading under simple/single-currency margin mode" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "import okx.Trade as Trade\n", + "\n", + "flag = \"1\" # live trading: 0, demo trading: 1\n", + "\n", + "tradeAPI = Trade.TradeAPI(api_key, secret_key, passphrase, False, flag)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "#### place a limit order" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "# limit order\n", + "result = tradeAPI.place_order(\n", + " instId=\"BTC-USDT\",\n", + " tdMode=\"cash\",\n", + " side=\"buy\",\n", + " ordType=\"limit\",\n", + " px=\"19000\",\n", + " sz=\"0.01\"\n", + ")\n", + "print(result)\n", + "\n", + "if result[\"code\"] == \"0\":\n", + " print(\"Successful order request,order_id = \",result[\"data\"][0][\"ordId\"])\n", + "else:\n", + " print(\"Unsuccessful order request,error_code = \",result[\"data\"][0][\"sCode\"], \", Error_message = \", result[\"data\"][0][\"sMsg\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "#### place a market order" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "# market order\n", + "result = tradeAPI.place_order(\n", + " instId=\"BTC-USDT\",\n", + " tdMode=\"cash\",\n", + " side=\"buy\",\n", + " ordType=\"market\",\n", + " sz=\"100\",\n", + ")\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "#### place an order with tgtCcy=quote_ccy (only applicable to spot)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "# market order\n", + "result = tradeAPI.place_order(\n", + " instId=\"BTC-USDT\",\n", + " tdMode=\"cash\",\n", + " side=\"buy\",\n", + " ordType=\"market\",\n", + " sz=\"100\",\n", + " tgtCcy=\"quote_ccy\" # this determines the unit of the sz parameter. base_ccy is the default value\n", + ")\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "#### place an order with your own clOrdId" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "# market order\n", + "result = tradeAPI.place_order(\n", + " instId=\"BTC-USDT\",\n", + " tdMode=\"cash\",\n", + " side=\"buy\",\n", + " ordType=\"market\",\n", + " sz=\"100\",\n", + " clOrdId=\"003\" # you can define your own client defined order ID\n", + ")\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "### Spot trading under multi-currency/porfolio margin mode" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "# cross-margin spot trading\n", + "result = tradeAPI.place_order(\n", + " instId=\"BTC-USDT\",\n", + " tdMode=\"cross\",\n", + " side=\"buy\",\n", + " ordType=\"limit\",\n", + " px=\"1000\",\n", + " sz=\"0.01\"\n", + ")\n", + "print(result)\n", + "\n", + "if result[\"code\"] == \"0\":\n", + " print(\"Successful order request,order_id = \",result[\"data\"][0][\"ordId\"])\n", + "else:\n", + " print(\"Unsuccessful order request,error_code = \",result[\"data\"][0][\"sCode\"], \", Error_message = \", result[\"data\"][0][\"sMsg\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "### For additional information on the place order endpoint,please refer to [Place order](https://www.okx.com/docs-v5/en/#rest-api-trade-place-order)\n", + "\n", + "### To place orders in a batch, please refer to [Get account configuration](https://www.okx.com/docs-v5/en/#rest-api-trade-place-multiple-orders)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "place_orders = [\n", + " {\"instId\":\"BTC-USDT\", \"tdMode\":\"cash\", \"side\":\"buy\", \"ordType\" : \"limit\",\"px\":\"1000\",\"sz\":\"0.01\"},\n", + " {\"instId\": \"BTC-USDT\", \"tdMode\": \"cash\", \"side\": \"buy\", \"ordType\": \"limit\", \"px\": \"1000\", \"sz\": \"0.02\"}\n", + "]\n", + "\n", + "result = tradeAPI.place_multiple_orders(place_orders)\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "### To amend pending orders,please refer to [Amend order](https://www.okx.com/docs-v5/en/#rest-api-trade-amend-order)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "result = tradeAPI.amend_order(\n", + " instId=\"BTC-USDT\",\n", + " ordId=\"489103565508685824\",\n", + " newSz=\"0.012\"\n", + ")\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "### To amend orders in a batch, please refer to [Amend multiple orders](https://www.okx.com/docs-v5/en/#rest-api-trade-amend-multiple-orders)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "amend_orders = [\n", + " {\"instId\": \"BTC-USDT\", \"ordId\": \"489106394289909760\",\"newSz\":\"0.001\"},\n", + " {\"instId\": \"BTC-USDT\", \"ordId\": \"489106394289909761\",\"newSz\":\"0.001\"},\n", + "]\n", + "\n", + "result = tradeAPI.amend_multiple_orders(amend_orders)\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "### To cancel pending orders,please refer to [Cancel order](https://www.okx.com/docs-v5/en/#rest-api-trade-cancel-order)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "result = tradeAPI.cancel_order(instId=\"BTC-USDT\", ordId = \"489093931993509888\")\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "### To cancel orders in a batch,please refer to [Cancel multiple orders](https://www.okx.com/docs-v5/zh/#rest-api-trade-cancel-multiple-orders)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "cancel_orders = [\n", + " {\"instId\": \"BTC-USDT\", \"ordId\": \"489102222534488064\"},\n", + " {\"instId\": \"BTC-USDT\", \"ordId\": \"489102222534488065\"},\n", + "]\n", + "\n", + "result = tradeAPI.cancel_multiple_orders(cancel_orders)\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "## Get details of a certain order, please refer to [Get order details](https://www.okx.com/docs-v5/en/#rest-api-trade-get-order-details)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "result = tradeAPI.get_order(instId=\"BTC-USDT\", clOrdId=\"002\")\n", + "print(result)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "result = tradeAPI.get_order(instId=\"BTC-USDT\", ordId=\"497819823594909696\")\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "## To get the list of open orders,please refer to [Get order List](https://www.okx.com/docs-v5/en/#rest-api-trade-get-order-list)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "result = tradeAPI.get_order_list()\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "### To get past orders,please refer to [Get order history (last 7 days)](https://www.okx.com/docs-v5/en/#rest-api-trade-get-order-history-last-7-days) and [Get order history (last 3 months)](https://www.okx.com/docs-v5/en/#rest-api-trade-get-order-history-last-3-months)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "result = tradeAPI.get_orders_history(\n", + " instType=\"SPOT\"\n", + ")\n", + "print(result)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "result = tradeAPI.get_orders_history_archive(\n", + " instType=\"SPOT\"\n", + ")\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "### To get past trades,please refer to [Get transaction details (last 3 days)](https://www.okx.com/docs-v5/en/#rest-api-trade-get-transaction-details-last-3-days) and [Get transaction details (last 3 months) ](https://www.okx.com/docs-v5/en/#rest-api-trade-get-transaction-details-last-3-months)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "result = tradeAPI.get_fills(\n", + " instType=\"SPOT\"\n", + ")\n", + "print(result)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "result = tradeAPI.get_fills_history(\n", + " instType=\"SPOT\"\n", + ")\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "### If you wish to place orders when the price reaches a certain level, you can place an algo order" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "result = tradeAPI.place_algo_order(\n", + " instId=\"BTC-USDT\",\n", + " tdMode=\"cash\",\n", + " side=\"buy\", # buy\n", + " ordType=\"trigger\", # order type\n", + " sz=\"100\", # order amount: 100USDT\n", + " triggerPx=\"10000\", # trigger price\n", + " orderPx=\"-1\", # order price. When orderPx=-1, the order will be placed as an market order\n", + " triggerPxType=\"last\" # trigger price type。last:last trade price\n", + ")\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "## You can also use Stop Loss or Take Profit order to sell the currencies in your account" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "result = tradeAPI.place_algo_order(\n", + " instId=\"BTC-USDT\",\n", + " tdMode=\"cash\",\n", + " side=\"sell\", # sell\n", + " ordType=\"conditional\", # one-way take profit or stop loss\n", + " sz=\"0.01\", # order amount: 0.01BTC\n", + " tpTriggerPx=\"30000\", # take profit trigger price\n", + " tpOrdPx=\"-1\", # taker profit order price。When it is set to -1,the order will be placed as an market order\n", + " tpTriggerPxType=\"last\" # take profit trigger price type。last:last trade price\n", + ")\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "### For additional information, please refer to [Place algo order](https://www.okx.com/docs-v5/en/#rest-api-trade-place-algo-order)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "### Cancel pending algo orders (not including Iceberg order, TWAP order, Trailing Stop order),please refer to [Cancel algo order](https://www.okx.com/docs-v5/en/#rest-api-trade-cancel-algo-order)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "algo_orders = [\n", + " {\"instId\": \"BTC-USDT\", \"algoId\": \"495001187587043328\"},\n", + "]\n", + "\n", + "result = tradeAPI.cancel_algo_order(algo_orders)\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "### To get list of currently pending algo orders,please refer to [Get algo order list](https://www.okx.com/docs-v5/en/#rest-api-trade-get-algo-order-list)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "result = tradeAPI.order_algos_list(\n", + " ordType=\"trigger\" # order type\n", + ")\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "### To get the past algo orders (last three months),please refer to [Get algo order history](https://www.okx.com/docs-v5/en/#rest-api-trade-get-algo-order-history)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "result = tradeAPI.order_algos_history(\n", + " ordType=\"conditional\", # order type\n", + " state=\"canceled\" # state of the orders\n", + ")\n", + "print(result)\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.12" + }, + "vscode": { + "interpreter": { + "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6" + } + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/example/get_started_en.ipynb b/example/get_started_en.ipynb index 29de8d46..706e4096 100644 --- a/example/get_started_en.ipynb +++ b/example/get_started_en.ipynb @@ -216,7 +216,7 @@ "\n", "marketDataAPI = MarketData.MarketAPI(flag=flag)\n", "\n", - "result = marketDataAPI.get_tickers( instType=\"SPO\")\n", + "result = marketDataAPI.get_tickers( instType=\"SPOT\")\n", "print(result)" ] }, @@ -1082,7 +1082,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3.8.9 64-bit", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -1096,7 +1096,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.9" + "version": "3.9.12" }, "vscode": { "interpreter": { From cf818540df77a0fa6b9864ca25ae4048af273b95 Mon Sep 17 00:00:00 2001 From: WuKong <903016116@qq.com> Date: Sun, 9 Apr 2023 07:26:03 +0000 Subject: [PATCH 040/139] Add the wdId parameter to the get_withdrawal_history interface. --- okx/Funding.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/okx/Funding.py b/okx/Funding.py index a4c3c659..56b4a76b 100644 --- a/okx/Funding.py +++ b/okx/Funding.py @@ -40,8 +40,8 @@ def get_deposit_history(self, ccy='', state='', after='', before='', limit='',tx return self._request_with_params(GET, DEPOSIT_HISTORIY, params) # Get Withdrawal History - def get_withdrawal_history(self, ccy='', state='', after='', before='', limit='',txId=''): - params = {'ccy': ccy, 'state': state, 'after': after, 'before': before, 'limit': limit,'txId':txId} + def get_withdrawal_history(self, ccy='', wdId='', state='', after='', before='', limit='',txId=''): + params = {'ccy': ccy, 'wdId': wdId, 'state': state, 'after': after, 'before': before, 'limit': limit,'txId':txId} return self._request_with_params(GET, WITHDRAWAL_HISTORIY, params) # Get Currencies From 0afee9205a5060ce829ea9262672de54b3a6a318 Mon Sep 17 00:00:00 2001 From: "shiyao.zhu" Date: Wed, 12 Apr 2023 14:51:16 +0800 Subject: [PATCH 041/139] update version --- okx/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/okx/__init__.py b/okx/__init__.py index 9c8f727d..8dd94604 100644 --- a/okx/__init__.py +++ b/okx/__init__.py @@ -2,4 +2,4 @@ Python SDK for the OKX API v5 """ -__version__="0.1.8" \ No newline at end of file +__version__="0.1.9" \ No newline at end of file From fcd7f52daea771526da7a087645a7dfa2e0cfabb Mon Sep 17 00:00:00 2001 From: "shiyao.zhu" Date: Thu, 11 May 2023 15:18:15 +0800 Subject: [PATCH 042/139] delete unnecessary log --- okx/exceptions.py | 1 - 1 file changed, 1 deletion(-) diff --git a/okx/exceptions.py b/okx/exceptions.py index e3dd1831..ee8e1803 100644 --- a/okx/exceptions.py +++ b/okx/exceptions.py @@ -4,7 +4,6 @@ class OkxAPIException(Exception): def __init__(self, response): - print(response.text + ', ' + str(response.status_code)) self.code = 0 try: json_res = response.json() From ceadad72106da2aa2c0dd24caef2f6351e52574b Mon Sep 17 00:00:00 2001 From: "zihao.jiang" Date: Fri, 16 Jun 2023 16:24:23 +0800 Subject: [PATCH 043/139] jzh --- .DS_Store | Bin 6148 -> 6148 bytes example/get_started_en.ipynb | 416 +++----------- okx/.DS_Store | Bin 0 -> 6148 bytes okx/Account.py | 49 +- okx/BlockTrading.py | 28 +- okx/CopyTrading.py | 71 +++ okx/Earning.py | 59 +- okx/Funding.py | 32 +- okx/Grid.py | 54 ++ okx/MarketData.py | 14 + okx/PublicData.py | 23 +- okx/SubAccount.py | 20 + okx/Trade.py | 58 +- okx/__init__.py | 2 +- okx/__pycache__/Account.cpython-310.pyc | Bin 0 -> 7981 bytes okx/__pycache__/BlockTrading.cpython-310.pyc | Bin 0 -> 4542 bytes okx/__pycache__/CopyTrading.cpython-310.pyc | Bin 0 -> 2932 bytes okx/__pycache__/Earning.cpython-310.pyc | Bin 0 -> 3458 bytes okx/__pycache__/Funding.cpython-310.pyc | Bin 0 -> 5878 bytes okx/__pycache__/Grid.cpython-310.pyc | Bin 0 -> 5740 bytes okx/__pycache__/MarketData.cpython-310.pyc | Bin 0 -> 4521 bytes okx/__pycache__/NDBroker.cpython-310.pyc | Bin 0 -> 4835 bytes okx/__pycache__/PublicData.cpython-310.pyc | Bin 0 -> 5214 bytes okx/__pycache__/Status.cpython-310.pyc | Bin 0 -> 853 bytes okx/__pycache__/SubAccount.cpython-310.pyc | Bin 0 -> 3506 bytes okx/__pycache__/Trade.cpython-310.pyc | Bin 0 -> 8198 bytes okx/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 220 bytes okx/__pycache__/client.cpython-310.pyc | Bin 0 -> 2151 bytes okx/__pycache__/consts.cpython-310.pyc | Bin 0 -> 13704 bytes okx/__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 1708 bytes okx/__pycache__/utils.cpython-310.pyc | Bin 0 -> 2114 bytes okx/client.py | 2 - okx/consts.py | 44 ++ .../WsClientFactory.cpython-310.pyc | Bin 0 -> 2513 bytes .../WsClientProtocol.cpython-310.pyc | Bin 0 -> 2373 bytes .../WsConnectManager.cpython-310.pyc | Bin 0 -> 4760 bytes .../__pycache__/WsPrivate.cpython-310.pyc | Bin 0 -> 1360 bytes .../__pycache__/WsPublic.cpython-310.pyc | Bin 0 -> 1087 bytes .../__pycache__/WsUtils.cpython-310.pyc | Bin 0 -> 2353 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 160 bytes test/.DS_Store | Bin 0 -> 6148 bytes test/AccountTest.py | 40 +- test/BlockTradingTest.py | 53 +- test/CopyTradingTest.py | 40 ++ test/EarningTest.py | 45 ++ test/FundingTest.py | 34 +- test/GridTest.py | 42 +- test/MarketTest.py | 6 +- test/PublicDataTest.py | 18 +- test/StackingTest.py | 11 +- test/SubAccountTest.py | 18 +- test/TradeTest.py | 82 ++- test/WsPublicTest.py | 3 +- test/__pycache__/AccountTest.cpython-310.pyc | Bin 0 -> 972 bytes .../BlockTradingTest.cpython-310.pyc | Bin 0 -> 1044 bytes test/__pycache__/BrokerTest.cpython-310.pyc | Bin 0 -> 1122 bytes test/__pycache__/ConvertTest.cpython-310.pyc | Bin 0 -> 756 bytes .../CopyTradingTest.cpython-310.pyc | Bin 0 -> 1046 bytes test/__pycache__/EarningTest.cpython-310.pyc | Bin 0 -> 973 bytes test/__pycache__/FundingTest.cpython-310.pyc | Bin 0 -> 1001 bytes test/__pycache__/GridTest.cpython-310.pyc | Bin 0 -> 1002 bytes test/__pycache__/MarketTest.cpython-310.pyc | Bin 0 -> 994 bytes .../PublicDataTest.cpython-310.pyc | Bin 0 -> 1000 bytes test/__pycache__/StackingTest.cpython-310.pyc | Bin 0 -> 952 bytes .../SubAccountTest.cpython-310.pyc | Bin 0 -> 1085 bytes test/__pycache__/TradeTest.cpython-310.pyc | Bin 0 -> 949 bytes .../TradingDataTest.cpython-310.pyc | Bin 0 -> 986 bytes test/ws_org.py | 542 ++++++++++++++++++ 68 files changed, 1353 insertions(+), 453 deletions(-) create mode 100644 okx/.DS_Store create mode 100644 okx/CopyTrading.py create mode 100644 okx/__pycache__/Account.cpython-310.pyc create mode 100644 okx/__pycache__/BlockTrading.cpython-310.pyc create mode 100644 okx/__pycache__/CopyTrading.cpython-310.pyc create mode 100644 okx/__pycache__/Earning.cpython-310.pyc create mode 100644 okx/__pycache__/Funding.cpython-310.pyc create mode 100644 okx/__pycache__/Grid.cpython-310.pyc create mode 100644 okx/__pycache__/MarketData.cpython-310.pyc create mode 100644 okx/__pycache__/NDBroker.cpython-310.pyc create mode 100644 okx/__pycache__/PublicData.cpython-310.pyc create mode 100644 okx/__pycache__/Status.cpython-310.pyc create mode 100644 okx/__pycache__/SubAccount.cpython-310.pyc create mode 100644 okx/__pycache__/Trade.cpython-310.pyc create mode 100644 okx/__pycache__/__init__.cpython-310.pyc create mode 100644 okx/__pycache__/client.cpython-310.pyc create mode 100644 okx/__pycache__/consts.cpython-310.pyc create mode 100644 okx/__pycache__/exceptions.cpython-310.pyc create mode 100644 okx/__pycache__/utils.cpython-310.pyc create mode 100644 okx/websocket/__pycache__/WsClientFactory.cpython-310.pyc create mode 100644 okx/websocket/__pycache__/WsClientProtocol.cpython-310.pyc create mode 100644 okx/websocket/__pycache__/WsConnectManager.cpython-310.pyc create mode 100644 okx/websocket/__pycache__/WsPrivate.cpython-310.pyc create mode 100644 okx/websocket/__pycache__/WsPublic.cpython-310.pyc create mode 100644 okx/websocket/__pycache__/WsUtils.cpython-310.pyc create mode 100644 okx/websocket/__pycache__/__init__.cpython-310.pyc create mode 100644 test/.DS_Store create mode 100644 test/CopyTradingTest.py create mode 100644 test/EarningTest.py create mode 100644 test/__pycache__/AccountTest.cpython-310.pyc create mode 100644 test/__pycache__/BlockTradingTest.cpython-310.pyc create mode 100644 test/__pycache__/BrokerTest.cpython-310.pyc create mode 100644 test/__pycache__/ConvertTest.cpython-310.pyc create mode 100644 test/__pycache__/CopyTradingTest.cpython-310.pyc create mode 100644 test/__pycache__/EarningTest.cpython-310.pyc create mode 100644 test/__pycache__/FundingTest.cpython-310.pyc create mode 100644 test/__pycache__/GridTest.cpython-310.pyc create mode 100644 test/__pycache__/MarketTest.cpython-310.pyc create mode 100644 test/__pycache__/PublicDataTest.cpython-310.pyc create mode 100644 test/__pycache__/StackingTest.cpython-310.pyc create mode 100644 test/__pycache__/SubAccountTest.cpython-310.pyc create mode 100644 test/__pycache__/TradeTest.cpython-310.pyc create mode 100644 test/__pycache__/TradingDataTest.cpython-310.pyc create mode 100644 test/ws_org.py diff --git a/.DS_Store b/.DS_Store index d3c415a6e72f62e5f95fade774264c9ed008e684..aedefaf23a2704dabba5e2aefd43a6d341980e46 100644 GIT binary patch literal 6148 zcmeHK%Wl&^6upzU#HB(+0;Fz`EU_&iX;D$dCQZ`?3pO=^1)yNprnTyNqS$VVqDWrD z$FSu`;9pq5nMW$yp(~{D(A;R|jA!m+=FBTYL~M`;J)$-d*+>Gdo5+44qFtmVY3Q2U zKqh?z&tiV;$J}4iH5G;d!@%FifY`fh|niycS$W{=Z_Z}hd%IiC<8F7p<;?cByD0DM&gZs$@4=&| zN29a&JmDV|-3(`wlv^4X@Ck*|h%Veo67%E)wZg)p0GyHQ`nSL3Pi(V~zp$)j@`W2J;uR%pM*N=-XRk7FOR4=rjEr!%^&I$&Zl%Cu^& zg`t>{JBa*&GCGBWght8@bbQAObG%MRbcp^A={c~2@zhp*L#%*u zS8S|;5OH(F?}$EBBhcrXz6ITIdF8PC*Xfl937u7m-WT@9ssfrgh5^ICKf{1H9~>ls zeT{`ed2}F?PXM5WYAGm-w}h~9H1;(X3ef^#$`q(fnSNq0WsZ7B>-9Aj3Y9rA{rF%y zGSe>K+}&{UsoasMA)|NgHUnJ>eDVc@@FfLTL#IKYtf-MTb5 xao0LX?~sHDy+WZhL8h-`SrAw8CXy7iIidjUYb+F^24emQNE%FL7+5I-KLOXp{W1Um delta 206 zcmZoMXfc=|#>B`mu~2NHo}wrV0|Nsi1A_nqgAqeKLn=cBLn1@&#KPsOAPE7642BXQ zEI^h7@^XL*^?-Ec=J~L$htgp@{^Nt z@{_3RRbV6z~H7|X^6cBakj9Q+(WR{{mTGf(Chu>?90>`*2s&9XT{WDPR_ D)e$V; diff --git a/example/get_started_en.ipynb b/example/get_started_en.ipynb index 706e4096..d75dcb65 100644 --- a/example/get_started_en.ipynb +++ b/example/get_started_en.ipynb @@ -2,37 +2,29 @@ "cells": [ { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, "source": [ "# Get Started\n", "## Install python package\n", "You can install `python-okx` from PyPi server." - ] + ], + "metadata": { + "collapsed": false + } }, { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, "outputs": [], "source": [ "! pip install python-okx --upgrade" - ] + ], + "metadata": { + "collapsed": false + } }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "## Sign up as an OKX user\n", "Please refer to [Create account](https://www.okx.com/account/register)" @@ -40,11 +32,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "## Create API Key\n", "Please refer to [Create API Key](https://www.okx.com/account/my-api)" @@ -52,11 +40,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "## Import API modules\n", "The following modules are available\n", @@ -80,7 +64,7 @@ "execution_count": null, "metadata": { "pycharm": { - "name": "#%%\n" + "is_executing": true } }, "outputs": [], @@ -90,11 +74,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "## Fill in your API key details" ] @@ -102,11 +82,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "api_key = \"xxxxx\"\n", @@ -116,11 +92,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "## Get available funds" ] @@ -130,7 +102,7 @@ "execution_count": null, "metadata": { "pycharm": { - "name": "#%%\n" + "is_executing": true } }, "outputs": [], @@ -147,11 +119,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "## Get market data" ] @@ -161,7 +129,7 @@ "execution_count": null, "metadata": { "pycharm": { - "name": "#%%\n" + "is_executing": true } }, "outputs": [], @@ -178,22 +146,14 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "## Handle errors" ] }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "You will the error code `51000` when. you run the following code. More details about the error code can be found in `msg`.\n", "Please refer to [error code](https://www.okx.com/docs-v5/en/#error-code) for addtional information." @@ -203,10 +163,10 @@ "cell_type": "code", "execution_count": null, "metadata": { + "scrolled": true, "pycharm": { - "name": "#%%\n" - }, - "scrolled": true + "is_executing": true + } }, "outputs": [], "source": [ @@ -222,11 +182,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "# Prepare for trading\n", "- Make sure you understand the basic trading rules. Please refer to [Basic Trading Rules](https://www.okx.com/support/hc/en-us/sections/360011507312)\n", @@ -235,11 +191,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "## Get account balance. Please refer to [Get balance](https://www.okx.com/docs-v5/en/#rest-api-account-get-balance)." ] @@ -248,9 +200,6 @@ "cell_type": "code", "execution_count": null, "metadata": { - "pycharm": { - "name": "#%%\n" - }, "scrolled": true }, "outputs": [], @@ -266,11 +215,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "## Get available trading pairs from [Get instruments](https://www.okx.com/docs-v5/en/#rest-api-public-data-get-instruments)." ] @@ -279,9 +224,6 @@ "cell_type": "code", "execution_count": null, "metadata": { - "pycharm": { - "name": "#%%\n" - }, "scrolled": true }, "outputs": [], @@ -300,11 +242,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "## Make sure you have enough funds to trade a certain pair. Please refer to [Get maximum tradable amount](https://www.okx.com/docs-v5/en/#rest-api-account-get-maximum-available-tradable-amount)" ] @@ -312,11 +250,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "import okx.Account as Account\n", @@ -335,11 +269,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "import okx.Account as Account\n", @@ -357,22 +287,14 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "## In unified account, you can trade Spot under simple, single currency, multi currency and portfolio margin account mode. Please refer to [Introduction on Unified Account](https://www.okx.com/support/hc/en-us/articles/360054690791-1-统一交易账户介绍)" ] }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "## Get the current account configuration from the `acctLv` parameter in [Get account configuration](https://www.okx.com/docs-v5/en/#rest-api-account-get-account-configuration)." ] @@ -380,11 +302,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "import okx.Account as Account\n", @@ -409,22 +327,14 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "# Start Spot Trading" ] }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "### Spot trading under simple/single-currency margin mode" ] @@ -432,11 +342,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "import okx.Trade as Trade\n", @@ -448,11 +354,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "#### place a limit order" ] @@ -460,11 +362,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "# limit order\n", @@ -486,11 +384,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "#### place a market order" ] @@ -498,11 +392,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "# market order\n", @@ -518,11 +408,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "#### place an order with tgtCcy=quote_ccy (only applicable to spot)" ] @@ -530,11 +416,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "# market order\n", @@ -551,11 +433,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "#### place an order with your own clOrdId" ] @@ -563,11 +441,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "# market order\n", @@ -584,11 +458,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "### Spot trading under multi-currency/porfolio margin mode" ] @@ -596,11 +466,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "# cross-margin spot trading\n", @@ -622,11 +488,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "### For additional information on the place order endpoint,please refer to [Place order](https://www.okx.com/docs-v5/en/#rest-api-trade-place-order)\n", "\n", @@ -636,11 +498,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "place_orders = [\n", @@ -654,11 +512,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "### To amend pending orders,please refer to [Amend order](https://www.okx.com/docs-v5/en/#rest-api-trade-amend-order)" ] @@ -666,11 +520,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "result = tradeAPI.amend_order(\n", @@ -683,11 +533,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "### To amend orders in a batch, please refer to [Amend multiple orders](https://www.okx.com/docs-v5/en/#rest-api-trade-amend-multiple-orders)" ] @@ -695,11 +541,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "amend_orders = [\n", @@ -713,11 +555,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "### To cancel pending orders,please refer to [Cancel order](https://www.okx.com/docs-v5/en/#rest-api-trade-cancel-order)" ] @@ -725,11 +563,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "result = tradeAPI.cancel_order(instId=\"BTC-USDT\", ordId = \"489093931993509888\")\n", @@ -738,11 +572,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "### To cancel orders in a batch,please refer to [Cancel multiple orders](https://www.okx.com/docs-v5/zh/#rest-api-trade-cancel-multiple-orders)" ] @@ -750,11 +580,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "cancel_orders = [\n", @@ -768,11 +594,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "## Get details of a certain order, please refer to [Get order details](https://www.okx.com/docs-v5/en/#rest-api-trade-get-order-details)" ] @@ -780,11 +602,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "result = tradeAPI.get_order(instId=\"BTC-USDT\", clOrdId=\"002\")\n", @@ -794,11 +612,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "result = tradeAPI.get_order(instId=\"BTC-USDT\", ordId=\"497819823594909696\")\n", @@ -807,11 +621,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "## To get the list of open orders,please refer to [Get order List](https://www.okx.com/docs-v5/en/#rest-api-trade-get-order-list)" ] @@ -819,11 +629,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "result = tradeAPI.get_order_list()\n", @@ -832,11 +638,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "### To get past orders,please refer to [Get order history (last 7 days)](https://www.okx.com/docs-v5/en/#rest-api-trade-get-order-history-last-7-days) and [Get order history (last 3 months)](https://www.okx.com/docs-v5/en/#rest-api-trade-get-order-history-last-3-months)" ] @@ -844,11 +646,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "result = tradeAPI.get_orders_history(\n", @@ -860,11 +658,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "result = tradeAPI.get_orders_history_archive(\n", @@ -875,11 +669,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "### To get past trades,please refer to [Get transaction details (last 3 days)](https://www.okx.com/docs-v5/en/#rest-api-trade-get-transaction-details-last-3-days) and [Get transaction details (last 3 months) ](https://www.okx.com/docs-v5/en/#rest-api-trade-get-transaction-details-last-3-months)" ] @@ -887,11 +677,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "result = tradeAPI.get_fills(\n", @@ -903,11 +689,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "result = tradeAPI.get_fills_history(\n", @@ -918,11 +700,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "### If you wish to place orders when the price reaches a certain level, you can place an algo order" ] @@ -930,11 +708,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "result = tradeAPI.place_algo_order(\n", @@ -952,11 +726,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "## You can also use Stop Loss or Take Profit order to sell the currencies in your account" ] @@ -964,11 +734,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "result = tradeAPI.place_algo_order(\n", @@ -986,22 +752,14 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "### For additional information, please refer to [Place algo order](https://www.okx.com/docs-v5/en/#rest-api-trade-place-algo-order)" ] }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "### Cancel pending algo orders (not including Iceberg order, TWAP order, Trailing Stop order),please refer to [Cancel algo order](https://www.okx.com/docs-v5/en/#rest-api-trade-cancel-algo-order)" ] @@ -1009,11 +767,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "algo_orders = [\n", @@ -1026,11 +780,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "### To get list of currently pending algo orders,please refer to [Get algo order list](https://www.okx.com/docs-v5/en/#rest-api-trade-get-algo-order-list)" ] @@ -1038,11 +788,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "result = tradeAPI.order_algos_list(\n", @@ -1053,11 +799,7 @@ }, { "cell_type": "markdown", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, + "metadata": {}, "source": [ "### To get the past algo orders (last three months),please refer to [Get algo order history](https://www.okx.com/docs-v5/en/#rest-api-trade-get-algo-order-history)" ] @@ -1065,11 +807,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [ "result = tradeAPI.order_algos_history(\n", diff --git a/okx/.DS_Store b/okx/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..38734ca2de71d90578b12a191d5ff30a57f26d5c GIT binary patch literal 6148 zcmeHKJ8Hu~5S@u#2;8`IxmU;y7U7)02atb(6aoc8igc=cE+5TrJ{W}TCXgn)ftj~E znx|!7q0xwlw%_Mhk+q04a6`FRn43K}pV>=h6bQ#VPI7>M$h&m2>c}_IdtuEgkdX>d0V;4;z`hR!Zden?K>u_g_y_=8 zBJGB?&l13531Cee1CfDgP=P_!95FQL$d|0EiDO{UMRWMjJXv!>Q9m8;FJ3NM0~x6R z6__fpi0#_?{~P?t{68geM+KA!1r*gxx&q`b_#;GW1zQV hY^)t`yeR65t?|4jj)6``-swR8445u7D)83|+yF)|6_)@2 literal 0 HcmV?d00001 diff --git a/okx/Account.py b/okx/Account.py index 2a087c89..e0a6d277 100644 --- a/okx/Account.py +++ b/okx/Account.py @@ -7,7 +7,6 @@ class AccountAPI(Client): def __init__(self, api_key='-1', api_secret_key='-1', passphrase='-1', use_server_time=False, flag='1', domain = 'https://www.okx.com',debug = True): Client.__init__(self, api_key, api_secret_key, passphrase, use_server_time, flag, domain,debug) - # Get Positions def get_position_risk(self, instType=''): params = {} @@ -61,8 +60,9 @@ def get_max_order_size(self, instId, tdMode, ccy='', px=''): return self._request_with_params(GET, MAX_TRADE_SIZE, params) # Get Maximum Available Tradable Amount - def get_max_avail_size(self, instId, tdMode, ccy='', reduceOnly=''): - params = {'instId': instId, 'tdMode': tdMode, 'ccy': ccy, 'reduceOnly': reduceOnly} + def get_max_avail_size(self, instId, tdMode, ccy='', reduceOnly='', unSpotOffset='', quickMgnType=''): + params = {'instId': instId, 'tdMode': tdMode, 'ccy': ccy, 'reduceOnly': reduceOnly, + 'unSpotOffset': unSpotOffset, 'quickMgnType': quickMgnType} return self._request_with_params(GET, MAX_AVAIL_SIZE, params) # Increase / Decrease margin @@ -111,8 +111,8 @@ def get_max_withdrawal(self, ccy=''): return self._request_with_params(GET, MAX_WITHDRAWAL, params) # Get borrow repay - def borrow_repay(self, ccy='', side='', amt=''): - params = {'ccy': ccy, 'side': side, 'amt': amt} + def borrow_repay(self, ccy='', side='', amt='', ordId=''): + params = {'ccy': ccy, 'side': side, 'amt': amt, 'ordId': ordId} return self._request_with_params(POST, BORROW_REPAY, params) # Get borrow repay history @@ -126,8 +126,8 @@ def get_interest_limits(self, type='',ccy=''): return self._request_with_params(GET, INTEREST_LIMITS, params) # Get Simulated Margin - def get_simulated_margin(self, instType ='',inclRealPos=True,instId='',pos=''): - params = {'instType': instType, 'inclRealPos': inclRealPos,'instId': instId,'pos': pos,} + def get_simulated_margin(self, instType='', inclRealPos=True, spotOffsetType='', simPos=[]): + params = {'instType': instType, 'inclRealPos': inclRealPos, 'spotOffsetType': spotOffsetType, 'simPos': simPos} return self._request_with_params(POST, SIMULATED_MARGIN, params) # Get Greeks @@ -162,5 +162,38 @@ def get_account_position_tiers(self,instType = '', uly = '',instFamily = ''): } return self._request_with_params(GET,GET_PM_LIMIT,params) + #- Get VIP interest accrued data + def get_VIP_interest_accrued_data(self, ccy='', ordId='', after='', before='', limit=''): + params = {'ccy': ccy, 'ordId': ordId, 'after': after, 'before': before, 'limit': limit} + return self._request_with_params(GET, GET_VIP_INTEREST_ACCRUED_DATA, params) + + #- Get VIP interest deducted data + def get_VIP_interest_deducted_data(self, ccy='', ordId='', after='', before='', limit=''): + params = {'ccy': ccy, 'ordId': ordId, 'after': after, 'before': before, 'limit': limit} + return self._request_with_params(GET, GET_VIP_INTEREST_DEDUCTED_DATA, params) + + # - Get VIP loan order list + def get_VIP_loan_order_list(self, ordId='',state='', ccy='', after='', before='', limit=''): + params = {'ordId': ordId, 'state': state, 'ccy': ccy,'after': after, 'before': before, 'limit': limit} + return self._request_with_params(GET, GET_VIP_LOAN_ORDER_LIST, params) + + #- Get VIP loan order detail + def get_VIP_loan_order_detail(self, ccy='', ordId='', after='', before='', limit=''): + params = {'ccy': ccy, 'ordId': ordId, 'after': after, 'before': before, 'limit': limit} + return self._request_with_params(GET, GET_VIP_LOAN_ORDER_DETAIL, params) + + #- Set risk offset type + def set_risk_offset_typel(self, type=''): + params = {'type': type} + return self._request_with_params(POST, SET_RISK_OFFSET_TYPE,params) + + # - Set auto loan + def set_auto_loan(self, autoLoan=''): + params = { + 'autoLoan': autoLoan + } + return self._request_with_params(POST, SET_AUTO_LOAN, params) - + #- Activate option + def activate_option(self): + return self._request_without_params(POST, ACTIVSTE_OPTION) diff --git a/okx/BlockTrading.py b/okx/BlockTrading.py index 0275555e..4ff22a14 100644 --- a/okx/BlockTrading.py +++ b/okx/BlockTrading.py @@ -10,8 +10,10 @@ def counterparties(self): params = {} return self._request_with_params(GET, COUNTERPARTIES, params) - def create_rfq(self, counterparties=[], anonymous='false', clRfqId='', legs = []): - params = {'counterparties': counterparties, 'anonymous': anonymous, 'clRfqId': clRfqId, 'legs': legs} + def create_rfq(self, counterparties=[], anonymous='false', clRfqId='', tag='', allowPartialExecution='false', + legs=[]): + params = {'counterparties': counterparties, 'anonymous': anonymous, 'clRfqId': clRfqId, 'tag': tag, + 'allowPartialExecution': allowPartialExecution, 'legs': legs} return self._request_with_params(POST, CREATE_RFQ, params) def cancel_rfq(self, rfqId = '', clRfqId = ''): @@ -26,13 +28,13 @@ def cancel_all_rfqs(self): params = {} return self._request_with_params(POST, CANCEL_ALL_RSQS, params) - def execute_quote(self, rfqId='', quoteId=''): - params = {'rfqId': rfqId, 'quoteId': quoteId} + def execute_quote(self, rfqId='', quoteId='', legs=[]): + params = {'rfqId': rfqId, 'quoteId': quoteId, 'legs': legs} return self._request_with_params(POST, EXECUTE_QUOTE, params) - def create_quote(self, rfqId='', clQuoteId='', quoteSide = '', legs = [],anonymous=False,expiresIn=''): - params = {'rfqId': rfqId, 'clQuoteId': clQuoteId, 'quoteSide': quoteSide, 'legs': legs, - 'anonymous':anonymous,'expiresIn':expiresIn} + def create_quote(self, rfqId='', clQuoteId='', tag='', quoteSide='', legs=[], anonymous=False, expiresIn=''): + params = {'rfqId': rfqId, 'clQuoteId': clQuoteId, 'tag': tag, 'quoteSide': quoteSide, 'legs': legs, + 'anonymous': anonymous, 'expiresIn': expiresIn} return self._request_with_params(POST, CREATE_QUOTE, params) def cancel_quote(self, quoteId = '', clQuoteId = ''): @@ -55,8 +57,10 @@ def get_quotes(self, rfqId = '', clRfqId = '', quoteId = '', clQuoteId = '', sta params = {'rfqId': rfqId, 'clRfqId': clRfqId, 'quoteId':quoteId,'clQuoteId':clQuoteId, 'state': state, 'beginId': beginId, 'endId': endId, 'limit':limit} return self._request_with_params(GET, GET_QUOTES, params) - def get_trades(self, rfqId = '', clRfqId = '', quoteId = '', clQuoteId = '', state = '', beginId = '', endId = '', limit = ''): - params = {'rfqId': rfqId, 'clRfqId': clRfqId, 'quoteId':quoteId,'clQuoteId':clQuoteId, 'state': state, 'beginId': beginId, 'endId': endId, 'limit':limit} + def get_trades(self, rfqId='', clRfqId='', quoteId='', clQuoteId='', state='', beginId='', endId='', beginTs='', + endTs='', limit=''): + params = {'rfqId': rfqId, 'clRfqId': clRfqId, 'quoteId': quoteId, 'clQuoteId': clQuoteId, 'state': state, + 'beginId': beginId, 'endId': endId, 'beginTs': beginTs, 'endTs': endTs, 'limit': limit} return self._request_with_params(GET, GET_RFQ_TRADES, params) def get_public_trades(self, beginId = '', endId = '', limit = ''): @@ -68,4 +72,8 @@ def reset_mmp(self): def set_marker_instrument(self,params = []): - return self._request_with_params(POST, MARKER_INSTRUMENT_SETTING, params) \ No newline at end of file + return self._request_with_params(POST, MARKER_INSTRUMENT_SETTING, params) + + #Get Quote products + def get_quote_products(self): + return self._request_without_params(GET, MARKER_INSTRUMENT_SETTING) diff --git a/okx/CopyTrading.py b/okx/CopyTrading.py new file mode 100644 index 00000000..0f412541 --- /dev/null +++ b/okx/CopyTrading.py @@ -0,0 +1,71 @@ +from .client import Client +from .consts import * + + +class CopyTradingAPI(Client): + def __init__(self, api_key='-1', api_secret_key='-1', passphrase='-1', use_server_time=False, flag='1', + domain='https://www.okx.com', debug=True): + Client.__init__(self, api_key, api_secret_key, passphrase, use_server_time, flag, domain, debug) + + # Get existing leading positions + def get_existing_leading_positions(self, instId=''): + params = { + 'instId': instId + } + return self._request_with_params(GET, GET_EXISTING_LEADING_POSITIONS, params) + + # Get leading position history + def get_leading_position_history(self, instId='', after='', before='', limit=''): + params = { + 'instId': instId, + 'after': after, + 'before': before, + 'limit': limit + } + return self._request_with_params(GET, GET_LEADING_POSITIONS_HISTORY, params) + + # Place leading stop order + def place_leading_stop_order(self, subPosId='', tpTriggerPx='', slTriggerPx='', tpTriggerPxType='', slTriggerPxType=''): + params = { + 'subPosId': subPosId, + 'tpTriggerPx': tpTriggerPx, + 'slTriggerPx': slTriggerPx, + 'tpTriggerPxType': tpTriggerPxType, + 'slTriggerPxType': slTriggerPxType + } + return self._request_with_params(POST, PLACE_LEADING_STOP_ORDER, params) + + # Close leading position + def close_leading_position(self, subPosId=''): + params = { + 'subPosId': subPosId + } + return self._request_with_params(POST, CLOSE_LEADING_POSITIONS, params) + + # Get leading instruments + def get_leading_instruments(self): + return self._request_without_params(GET, GET_LEADING_POSITIONS) + + # Amend leading instruments + def amend_leading_instruments(self, instId=''): + params = { + 'instId': instId + } + return self._request_with_params(POST, AMEND_EXISTING_LEADING_POSITIONS, params) + + # Get profit sharing details + def get_profit_sharing_details(self, after='', before='', limit=''): + params = { + 'after': after, + 'before': before, + 'limit': limit + } + return self._request_with_params(GET, GET_PROFIT_SHARING_DETAILS, params) + + # Get total profit sharing + def get_total_profit_sharing(self): + return self._request_without_params(GET, GET_TOTAL_PROFIT_SHARING) + + # Get unrealized profit sharing details + def get_unrealized_profit_sharing_details(self): + return self._request_without_params(GET, GET_UNREALIZED_PROFIT_SHARING_DETAILS) diff --git a/okx/Earning.py b/okx/Earning.py index 0ecb2566..44e3363f 100644 --- a/okx/Earning.py +++ b/okx/Earning.py @@ -14,15 +14,17 @@ def get_offers(self,productId = '',protocolType = '',ccy = ''): } return self._request_with_params(GET,STACK_DEFI_OFFERS,params) - def purchase(self,productId = '',investData = [],term = ''): + def purchase(self, productId='', investData=[], term='', tag=''): params = { - 'productId':productId, - 'investData':investData + 'productId': productId, + 'investData': investData } if term != '': params['term'] = term - return self._request_with_params(POST,STACK_DEFI_PURCHASE,params) + if tag != '': + params['tag'] = tag + return self._request_with_params(POST, STACK_DEFI_PURCHASE, params) def redeem(self,ordId = '',protocolType = '',allowEarlyRedeem = ''): params = { @@ -59,6 +61,55 @@ def get_orders_history(self,productId = '',protocolType = '',ccy = '',after = '' } return self._request_with_params(GET,STACK_DEFI_ORDERS_HISTORY,params) + # - Get saving balance + def get_saving_balance(self, ccy=''): + params = { + 'ccy': ccy + } + return self._request_with_params(GET, GET_SAVING_BALANCE, params) + + # - Savings purchase/redemption + def savings_purchase_redemption(self, ccy='', amt='', side='', rate=''): + + params = { + 'ccy': ccy, + 'amt': amt, + 'side': side, + 'rate': rate + } + return self._request_with_params(POST, SAVING_PURCHASE_REDEMPTION, params) + + # - Set lending rate + def set_lending_rate(self, ccy='', rate=''): + params = { + 'ccy': ccy, + 'rate': rate + } + return self._request_with_params(POST, SET_LENDING_RATE, params) + # - Get lending history + def get_lending_history(self, ccy='', after='', before='', limit=''): + params = { + 'ccy': ccy, + 'after': after, + 'before': before, + 'limit': limit + } + return self._request_with_params(GET, GET_LENDING_HISTORY, params) + # - Get public borrow info (public) + def get_public_borrow_info(self, ccy=''): + params = { + 'ccy': ccy + } + return self._request_with_params(GET, GET_PUBLIC_BORROW_INFO, params) + # - Get public borrow history (public) + def get_public_borrow_history(self, ccy='', after='', before='', limit=''): + params = { + 'ccy': ccy, + 'after': after, + 'before': before, + 'limit': limit + } + return self._request_with_params(GET, GET_PUBLIC_BORROW_HISTORY, params) diff --git a/okx/Funding.py b/okx/Funding.py index 56b4a76b..31cd36de 100644 --- a/okx/Funding.py +++ b/okx/Funding.py @@ -30,13 +30,15 @@ def funds_transfer(self, ccy, amt, from_, to, type='0', subAcct='', instId='', t return self._request_with_params(POST, FUNDS_TRANSFER, params) # Withdrawal - def withdrawal(self, ccy, amt, dest, toAddr, fee,chain = '', clientId = ''): - params = {'ccy': ccy, 'amt': amt, 'dest': dest, 'toAddr': toAddr, 'fee': fee,'chain':chain,'clientId':clientId} + def withdrawal(self, ccy, amt, dest, toAddr, fee, chain='', areaCode='', clientId=''): + params = {'ccy': ccy, 'amt': amt, 'dest': dest, 'toAddr': toAddr, 'fee': fee, 'chain': chain, + 'areaCode': areaCode, 'clientId': clientId} return self._request_with_params(POST, WITHDRAWAL_COIN, params) # Get Deposit History - def get_deposit_history(self, ccy='', state='', after='', before='', limit='',txId='',depId=''): - params = {'ccy': ccy, 'state': state, 'after': after, 'before': before, 'limit': limit,'txId':txId,'depId':depId} + def get_deposit_history(self, ccy='', state='', after='', before='', limit='', txId='', depId='', fromWdId=''): + params = {'ccy': ccy, 'state': state, 'after': after, 'before': before, 'limit': limit, 'txId': txId, + 'depId': depId, 'fromWdId': fromWdId} return self._request_with_params(GET, DEPOSIT_HISTORIY, params) # Get Withdrawal History @@ -72,25 +74,21 @@ def withdrawal_lightning(self, ccy,invoice,memo=''): params = {'ccy':ccy, 'invoice':invoice, 'memo':memo} return self._request_with_params(POST, WITHDRAWAL_LIGHTNING, params) - # POST SET LENDING RATE def set_lending_rate(self, ccy, rate): params = {'ccy': ccy, 'rate': rate} return self._request_with_params(POST, SET_LENDING_RATE, params) - # GET LENDING HISTORY def get_lending_history(self, ccy='', before='', after='', limit='' ): params = {'ccy': ccy, 'after': after, 'before': before, 'limit': limit } return self._request_with_params(GET, LENDING_HISTORY, params) - # GET LENDING RATE HISTORY def get_lending_rate_history(self, ccy='',after = '',before = '',limit = '' ): params = {'ccy': ccy,'after':after,'before':before,'limit':limit} return self._request_with_params(GET, LENDING_RATE_HISTORY, params) - # GET LENDING RATE SUMMARY def get_lending_rate_summary(self, ccy=''): params = {'ccy': ccy} @@ -124,3 +122,21 @@ def get_saving_balance(self,ccy = ''): 'ccy':ccy } return self._request_with_params(GET, GET_SAVING_BALANCE, params) + + #Get non-tradable assets + def get_non_tradable_assets(self, ccy=''): + params = { + 'ccy': ccy + } + return self._request_with_params(GET, GET_NON_TRADABLE_ASSETS, params) + + #Get deposit withdraw status + def get_deposit_withdraw_status(self, wdId='', txId='', ccy='', to='', chain=''): + params = {'wdId': wdId, 'txId': txId, 'ccy': ccy, 'to': to, 'chain': chain} + return self._request_with_params(GET, GET_DEPOSIT_WITHDrAW_STATUS, params) + + #Get withdrawal history + def get_withdrawal_history(self, ccy='', wdId='', clientId='', txId='', type='', state='', after='', before ='', limit=''): + params = {'ccy': ccy, 'wdId': wdId, 'clientId': clientId, 'txId': txId, 'type': type, 'state': state, 'after': after, 'before': before, 'limit': limit} + return self._request_with_params(GET, GET_WITHDRAWAL_HISTORY, params) + diff --git a/okx/Grid.py b/okx/Grid.py index 6cf49914..0e4ea9d0 100644 --- a/okx/Grid.py +++ b/okx/Grid.py @@ -76,3 +76,57 @@ def grid_ai_param(self, algoOrdType='', instId='', direction='', duration=''): 'duration':duration } return self._request_with_params(GET, GRID_AI_PARAM, params) + + # - Place recurring buy order + def place_recurring_buy_order(self, stgyName='', recurringList=[], period='', recurringDay='', recurringTime='', + timeZone='', amt='', investmentCcy='', tdMode='', algoClOrdId='', tag=''): + params = {'stgyName': stgyName, 'recurringList': recurringList, 'period': period, 'recurringDay': recurringDay, + 'recurringTime': recurringTime, + 'timeZone': timeZone, 'amt': amt, 'investmentCcy': investmentCcy, 'tdMode': tdMode, + 'algoClOrdId': algoClOrdId, 'tag': tag} + return self._request_with_params(POST, PLACE_RECURRING_BUY_ORDER, params) + + # - Amend recurring buy order + def amend_recurring_buy_order(self, algoId='', stgyName=''): + params = {'algoId': algoId, 'stgyName': stgyName} + return self._request_with_params(POST, AMEND_RECURRING_BUY_ORDER, params) + + # - Stop recurring buy order + def stop_recurring_buy_order(self, orders_data): + return self._request_with_params(POST, STOP_RECURRING_BUY_ORDER, orders_data) + + # - Get recurring buy order list + def get_recurring_buy_order_list(self, algoId='', after='', before='', limit=''): + params = { + 'algoId': algoId, + 'after': after, + 'before': before, + 'limit': limit + } + return self._request_with_params(GET, GET_RECURRING_BUY_ORDER_LIST, params) + + # - Get recurring buy order history + def get_recurring_buy_order_history(self, algoId='', after='', before='', limit=''): + params = { + 'algoId': algoId, + 'after': after, + 'before': before, + 'limit': limit + } + return self._request_with_params(GET, GET_RECURRING_BUY_ORDER_HISTORY, params) + + # - Get recurring buy order details + def get_recurring_buy_order_details(self, algoId=''): + params = {'algoId': algoId} + return self._request_with_params(GET, GET_RECURRING_BUY_ORDER_DETAILS, params) + + # - Get recurring buy sub orders + def get_recurring_buy_sub_orders(self, algoId='', ordId='', after='', before='', limit=''): + params = { + 'algoId': algoId, + 'ordId': ordId, + 'after': after, + 'before': before, + 'limit': limit + } + return self._request_with_params(GET, GET_RECURRING_BUY_SUB_ORDERS, params) diff --git a/okx/MarketData.py b/okx/MarketData.py index 1dc2bdf0..da4691bd 100644 --- a/okx/MarketData.py +++ b/okx/MarketData.py @@ -115,6 +115,20 @@ def get_block_trades(self,instId = ''): } return self._request_with_params(GET, BLOCK_TRADES, params) + #- Get order lite book + def get_order_lite_book(self,instId = ''): + params = { + 'instId':instId + } + return self._request_with_params(GET, GET_ORDER_LITE_BOOK, params) + + #- Get option trades + def get_option_trades(self,instFamily = ''): + params = { + 'instFamily':instFamily + } + return self._request_with_params(GET, GET_OPTION_TRADES, params) + diff --git a/okx/PublicData.py b/okx/PublicData.py index 10438ebc..8f915c09 100644 --- a/okx/PublicData.py +++ b/okx/PublicData.py @@ -56,13 +56,6 @@ def discount_interest_free_quota(self, ccy=''): def get_system_time(self): return self._request_without_params(GET, SYSTEM_TIME) - # Get Liquidation Orders - def get_liquidation_orders(self, instType, mgnMode='', instId='', ccy='', uly='', alias='', state='', before='', - after='', limit='',instFamily =''): - params = {'instType': instType, 'mgnMode': mgnMode, 'instId': instId, 'ccy': ccy, 'uly': uly, - 'alias': alias, 'state': state, 'before': before, 'after': after, 'limit': limit,'instFamily':instFamily} - return self._request_with_params(GET, LIQUIDATION_ORDERS, params) - # Get Mark Price def get_mark_price(self, instType, uly='', instId='',instFamily = ''): params = {'instType': instType, 'uly': uly, 'instId': instId,'instFamily':instFamily} @@ -113,5 +106,19 @@ def get_convert_contract_coin(self,type = '',instId = '',sz = '',px = '',unit = } return self._request_with_params(GET, CONVERT_CONTRACT_COIN, params) + # Get option tickBands + def get_option_tickBands(self, instType='', instFamily=''): + params = { + 'instType': instType, + 'instFamily': instFamily + } + return self._request_with_params(GET, GET_OPTION_TICKBANDS, params) - + # Get option trades + def get_option_trades(self, instId='', instFamily='', optType=''): + params = { + 'instId': instId, + 'instFamily': instFamily, + 'optType': optType + } + return self._request_with_params(GET, GET_OPTION_TRADES, params) diff --git a/okx/SubAccount.py b/okx/SubAccount.py index ea0428b4..09fce2f0 100644 --- a/okx/SubAccount.py +++ b/okx/SubAccount.py @@ -59,5 +59,25 @@ def get_funding_balance(self,subAcct='',ccy=''): } return self._request_with_params(GET, GET_ASSET_SUBACCOUNT_BALANCE, params) + # - Get the user's affiliate rebate information + def get_the_user_affiliate_rebate_information(self, apiKey=''): + params = { + 'apiKey': apiKey + } + return self._request_with_params(GET, GET_THE_USER_AFFILIATE_REBATE, params) + # - Set sub_accounts VIP loan% + def set_sub_accounts_VIP_loan(self, enable='', alloc=[]): + params = { + 'enable': enable, + 'alloc': alloc + } + return self._request_with_params(POST, SET_SUB_ACCOUNTS_VIP_LOAN, params) + # - Get sub_account borrow interest and limit + def get_sub_account_borrow_interest_and_limit(self, subAcct='', ccy=''): + params = { + 'subAcct': subAcct, + 'ccy': ccy + } + return self._request_with_params(GET, GET_SUB_ACCOUNT_BORROW_INTEREST_AND_LIMIT, params) diff --git a/okx/Trade.py b/okx/Trade.py index 2db2e833..3df71fcf 100644 --- a/okx/Trade.py +++ b/okx/Trade.py @@ -9,10 +9,13 @@ def __init__(self, api_key='-1', api_secret_key='-1', passphrase='-1', use_serve # Place Order def place_order(self, instId, tdMode, side, ordType, sz, ccy='', clOrdId='', tag='', posSide='', px='', - reduceOnly='', tgtCcy=''): + reduceOnly='', tgtCcy='', tpTriggerPx='', tpOrdPx='', slTriggerPx='', slOrdPx='', + tpTriggerPxType='', slTriggerPxType='', quickMgnType='', stpId='', stpMode=''): params = {'instId': instId, 'tdMode': tdMode, 'side': side, 'ordType': ordType, 'sz': sz, 'ccy': ccy, 'clOrdId': clOrdId, 'tag': tag, 'posSide': posSide, 'px': px, 'reduceOnly': reduceOnly, - 'tgtCcy': tgtCcy} + 'tgtCcy': tgtCcy, 'tpTriggerPx': tpTriggerPx, 'tpOrdPx': tpOrdPx, 'slTriggerPx': slTriggerPx, + 'slOrdPx': slOrdPx, 'tpTriggerPxType': tpTriggerPxType, 'slTriggerPxType': slTriggerPxType, + 'quickMgnType': quickMgnType, 'stpId': stpId, 'stpMode': stpMode} return self._request_with_params(POST, PLACR_ORDER, params) # Place Multiple Orders @@ -29,10 +32,12 @@ def cancel_multiple_orders(self, orders_data): return self._request_with_params(POST, CANAEL_BATCH_ORDERS, orders_data) # Amend Order - def amend_order(self, instId, cxlOnFail='', ordId='', clOrdId='', reqId='', newSz='', newPx=''): + def amend_order(self, instId, cxlOnFail='', ordId='', clOrdId='', reqId='', newSz='', newPx='', newTpTriggerPx='', + newTpOrdPx='', newSlTriggerPx='', newSlOrdPx='', newTpTriggerPxType='', newSlTriggerPxType=''): params = {'instId': instId, 'cxlOnFailc': cxlOnFail, 'ordId': ordId, 'clOrdId': clOrdId, 'reqId': reqId, - 'newSz': newSz, - 'newPx': newPx} + 'newSz': newSz, 'newPx': newPx, 'newTpTriggerPx': newTpTriggerPx, 'newTpOrdPx': newTpOrdPx, + 'newSlTriggerPx': newSlTriggerPx, 'newSlOrdPx': newSlOrdPx, 'newTpTriggerPxType': newTpTriggerPxType, + 'newSlTriggerPxType': newSlTriggerPxType} return self._request_with_params(POST, AMEND_ORDER, params) # Amend Multiple Orders @@ -40,8 +45,9 @@ def amend_multiple_orders(self, orders_data): return self._request_with_params(POST, AMEND_BATCH_ORDER, orders_data) # Close Positions - def close_positions(self, instId, mgnMode, posSide='', ccy='',autoCxl=''): - params = {'instId': instId, 'mgnMode': mgnMode, 'posSide': posSide, 'ccy': ccy,'autoCxl':autoCxl} + def close_positions(self, instId, mgnMode, posSide='', ccy='', autoCxl='', clOrdId='', tag=''): + params = {'instId': instId, 'mgnMode': mgnMode, 'posSide': posSide, 'ccy': ccy, 'autoCxl': autoCxl, + 'clOrdId': clOrdId, 'tag': tag} return self._request_with_params(POST, CLOSE_POSITION, params) # Get Order Details @@ -56,15 +62,19 @@ def get_order_list(self, instType='', uly='', instId='', ordType='', state='', a return self._request_with_params(GET, ORDERS_PENDING, params) # Get Order History (last 7 days) - def get_orders_history(self, instType, uly='', instId='', ordType='', state='', after='', before='', limit='',instFamily = ''): + def get_orders_history(self, instType, uly='', instId='', ordType='', state='', after='', before='', begin='', + end='', limit='', instFamily=''): params = {'instType': instType, 'uly': uly, 'instId': instId, 'ordType': ordType, 'state': state, - 'after': after, 'before': before, 'limit': limit,'instFamily':instFamily} + 'after': after, 'before': before, 'begin': begin, 'end': end, 'limit': limit, + 'instFamily': instFamily} return self._request_with_params(GET, ORDERS_HISTORY, params) # Get Order History (last 3 months) - def get_orders_history_archive(self, instType, uly='', instId='', ordType='', state='', after='', before='', limit='',instFamily = ''): + def get_orders_history_archive(self, instType, uly='', instId='', ordType='', state='', after='', before='', + begin='', end='', limit='', instFamily=''): params = {'instType': instType, 'uly': uly, 'instId': instId, 'ordType': ordType, 'state': state, - 'after': after, 'before': before, 'limit': limit,'instFamily':instFamily} + 'after': after, 'before': before, 'begin': begin, 'end': end, 'limit': limit, + 'instFamily': instFamily} return self._request_with_params(GET, ORDERS_HISTORY_ARCHIVE, params) # Get Transaction Details @@ -80,7 +90,8 @@ def place_algo_order(self, instId='', tdMode='', side='', ordType='', sz='', ccy triggerPx='', orderPx='', tgtCcy='', pxVar='', pxSpread='', szLimit='', pxLimit='', timeInterval='', tpTriggerPxType='', slTriggerPxType='', - callbackRatio='',callbackSpread='',activePx='',tag='',triggerPxType=''): + callbackRatio='',callbackSpread='',activePx='',tag='',triggerPxType='',closeFraction='' + ,quickMgnType='',algoClOrdId=''): params = {'instId': instId, 'tdMode': tdMode, 'side': side, 'ordType': ordType, 'sz': sz, 'ccy': ccy, 'posSide': posSide, 'reduceOnly': reduceOnly, 'tpTriggerPx': tpTriggerPx, 'tpOrdPx': tpOrdPx, 'slTriggerPx': slTriggerPx, 'slOrdPx': slOrdPx, 'triggerPx': triggerPx, 'orderPx': orderPx, @@ -88,11 +99,9 @@ def place_algo_order(self, instId='', tdMode='', side='', ordType='', sz='', ccy 'timeInterval': timeInterval, 'pxSpread': pxSpread, 'tpTriggerPxType': tpTriggerPxType, 'slTriggerPxType': slTriggerPxType, 'callbackRatio' : callbackRatio, 'callbackSpread':callbackSpread,'activePx':activePx, - 'tag':tag,'triggerPxType':triggerPxType,} + 'tag':tag,'triggerPxType':triggerPxType,'closeFraction':closeFraction,'quickMgnType':quickMgnType,'algoClOrdId':algoClOrdId} return self._request_with_params(POST, PLACE_ALGO_ORDER, params) - - # Cancel Algo Order def cancel_algo_order(self, params): return self._request_with_params(POST, CANCEL_ALGOS, params) @@ -102,9 +111,9 @@ def cancel_advance_algos(self,params): return self._request_with_params(POST, Cancel_Advance_Algos, params) # Get Algo Order List - def order_algos_list(self, ordType ='', algoId='', instType='', instId='', after='', before='', limit=''): + def order_algos_list(self, ordType='', algoId='', instType='', instId='', after='', before='', limit='',algoClOrdId=''): params = {'ordType': ordType, 'algoId': algoId, 'instType': instType, 'instId': instId, 'after': after, - 'before': before, 'limit': limit} + 'before': before, 'limit': limit, 'algoClOrdId': algoClOrdId} return self._request_with_params(GET, ORDERS_ALGO_OENDING, params) # Get Algo Order History @@ -157,3 +166,18 @@ def oneclick_repay_history(self,after = '',before = '',limit = ''): 'limit':limit } return self._request_with_params(GET,ONE_CLICK_REPAY_HISTORY,params) + + # Get algo order details + def get_algo_order_details(self, algoId='', algoClOrdId=''): + params = {'algoId': algoId, 'algoClOrdId': algoClOrdId} + return self._request_with_params(GET, GET_ALGO_ORDER_DETAILS, params) + + # Amend algo order + def amend_algo_order(self, instId='', algoId='', algoClOrdId='', cxlOnFail='', reqId='', newSz='', + newTpTriggerPx='', newTpOrdPx='', newSlTriggerPx='', newSlOrdPx='', newTpTriggerPxType='', + newSlTriggerPxType=''): + params = {'instId': instId, 'algoId': algoId, 'algoClOrdId': algoClOrdId, 'cxlOnFail': cxlOnFail, + 'reqId': reqId, 'newSz': newSz, 'newTpTriggerPx': newTpTriggerPx, 'newTpOrdPx': newTpOrdPx, + 'newSlTriggerPx': newSlTriggerPx, 'newSlOrdPx': newSlOrdPx, + 'newTpTriggerPxType': newTpTriggerPxType, 'newSlTriggerPxType': newSlTriggerPxType} + return self._request_with_params(POST, AMEND_ALGO_ORDER, params) diff --git a/okx/__init__.py b/okx/__init__.py index 8dd94604..6d041861 100644 --- a/okx/__init__.py +++ b/okx/__init__.py @@ -2,4 +2,4 @@ Python SDK for the OKX API v5 """ -__version__="0.1.9" \ No newline at end of file +__version__="0.2.0" \ No newline at end of file diff --git a/okx/__pycache__/Account.cpython-310.pyc b/okx/__pycache__/Account.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a2e117d9e98d8894cf65a5c4f96bc8b155df2224 GIT binary patch literal 7981 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 literal 0 HcmV?d00001 diff --git a/okx/__pycache__/BlockTrading.cpython-310.pyc b/okx/__pycache__/BlockTrading.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..386d74b9abee39b049b68c382bddd88f5e865d25 GIT binary patch literal 4542 zcmb7INpssq7RE*rfGEn^yp0#xjuXR)#n_oOlVnWGw8M!_%Oq4a!wU*RLljCNL3e{A zOGTZ=KVuH@(SHfonaiAg^Ck0MVRpg1CGWtvvAq=g6cs@%r7`ZsU{m;Ni1KeE8|oVHghB zx7F(L@$q&rJn@|V_P#%KO-F_3qz~$tupRiZYal}5XK^Hq#E~?TN6M%$DvnC;RZLG? z_#ie7iArD2fp2niX`aSUOy@jcYoOZAka0KyS0|tsJA~z z6oVWUV;k;XEY`8R;snEf=u&tadM-oLkH`~6tca&KreWueqr!phLu3U9t3Q1ZA-1^} zTcAuPl!*T-o|Q76O6ZdzHH{*@0+x|x_k;dPFBr0@Fu(6#8nn+m*P=#wfbV)2)Xbb56rDw(k(gJJq$7_)TZEEos~fOIBj0g%%G zNKpYMYY+}G@rd4mkHDc?bEp1-JEX)8eGdJxFZ03MeaH0?{012Ebn2MSS>T!BLg4f+ z41pPvq9O;#A~nfO8u%FIY69~~&D{AB!M2SAt$}FoqnL+w)rmpu+o5xam>IXa2ll78 zW+FXpyO2K=T~FA;%Ogg)lAx@;fPl7Nx9KG`o67!50tsr41H!e5UPVAR7XV5v9n5+9 zVD7X0tpJ%~TBFjNVGz1d2w0rCLRhZhJSHJ*r94kz`ZRc36vaDSuMG0}Yg%GTtlz(UwNqSC(G_4=@Z72H0-Kfc%V z!n7(b!iOCd_Um}5Om?bl5c(}f?awH_L-9R|dF8Bj;i!YF=I_9Q;qtSFw4OO|q-GAX zIDK%p$2Mm)av{&?kqVqv&$NuwTFPmab2{FF##KBAbIx5I-A&3#pCB>cm49`ZxvuNz zQ=H5{0e0^E#ku?3*w9%5%k(LOf^F_TR_L_*BWuQzy(vq&Jy;^~#? zg)Xyl&?0?MPY(#J0*w@4?yNsPy+l`D)>=Q+TUMjlHd}iy>rK-FXlA4NeD0#R$)VX4 z?l5p;Vj&&&;Qsnon26!jaFo3}4Rr1o3!_S(!Z7I}tByJ@YqWvl8H%ZBtz|^C1~ec; zCuFbC>_-r%x2Lhp8aIs+#ej{)Gg`zp-ZxCRAM%qL3b;^Y`aBJ;2EY1#{MOLN`gt{= zLwLTd;!Je*A`C8{^vwF2?i=6knqF3PlygZ&Bb{PydJl z7e4v}ioc+Ef`StU%aLNL=}#!eiQpPu{U~w+qsbnDPz6bpMEw_4(G~ow7b}XYTu?46 zdO-(G$NuDvs+8q&fq&mLl&I+N{}rkV D5>&}D literal 0 HcmV?d00001 diff --git a/okx/__pycache__/CopyTrading.cpython-310.pyc b/okx/__pycache__/CopyTrading.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e4880b283f1943fe46358936e7b4408a0f20e067 GIT binary patch literal 2932 zcmb7G&vVm86xMG$iep*`B!m#4Z2&T-#0uYJFfz*{dvW&74D7LgM5tV4qC8AOJ7qz1jy)9YBA2O(0vM@FRpY~#q z&uB0m&o_WD(|O$yKrh|0Qw_EW9Pk8)0-}Gne?i z{c5ZJT3LIrCFBRMFCD~j#J{Ojj*gDj!^7isFYMZ05lqY)%E;OVJbW1-mR`t-l*oya zsEL;7iIEgu7LlX2bS5_}g(;vVijL#={Md1y`U2itpXDY)pU<&}k7%ogH7{VnSUfBma>9Nma zIAbTE=~+8b$o<$4dwdpjUZJO&qP;1rgSDKaA71UDvsuGkGUwBf$bx~$ziFrXhyooc zu#|?S4Gq`by_hm#Jf(Xfqe2h-t{+<}TZH}CRe;WQq~Sg9okze+bN5HfIA?*a;G!D{ zHxaHOU{H)PvW!0EiEs{pp^%-RE-wKniX!9B_^WIT?oVK4+72G_khKB`*iX|0ZOb@G zbYMk4HAbu$87sOd^8V9S$m>MR#*xkZ{e8+>$6}TT=bZ~&ECjp^ zkg*5+{aG#y?&SEJwti|dvCFV2#0*0_v)H%;a%W*#DZ36ZSj`zdS>MAdpEZ>6Ymw$ZMp1UWFO{~$ux3KOFT9iQVLyJG^21oaJTcbK zOj+__>KPWZcX+>9eOzm7exNw9C0LTr zy{j(RM@FQNnfxVcr@Y_I89a4~hg4?`E6=F<;H!t323e+_YS}R)T9##Mu2N*arS)bB z&!Dy2+^XA7`%!fli|%I4uGV+jmOea)|4?U^km-npd+@pA2QI_jNw2_Vm?LLyp~pE#HP2yN`0}&LX;FH|^?9&MEde>f~Z-5nmjKu^Z%!{~nbw zvffMQX)FG(p{r=N7eHgncyM=;UqRkWesW7G}&0VO%pGv2pGE_^kC?SEa~ zfNF^`b`Dz%t2@IoZ(A~(hky92;a?6QZYGQl7pS=@YYwkTJ&1e95vJpGL(&gWE;-J# zz8ef@(mP68aoH_=A6`zGg|LQDLHGjU0YaKy=O>*?ct2p6L+BI7oGD89$ur-Wx>+zy zbGBG8HM3BhDQT%5e6oe%rMKDiHrFvcxI)A{og9m!(e9%7?a=t|urhMwsw5TVdG#N7 CU&NjO literal 0 HcmV?d00001 diff --git a/okx/__pycache__/Earning.cpython-310.pyc b/okx/__pycache__/Earning.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f961a09a571ad9109cd8cd776e58a6acaaa0990a GIT binary patch literal 3458 zcmaJ^TT|Oc6xPkMP{84y5ON{+I4!v8y=juEV@%>Hu^HP*C+>qrXxE@Yww#rKm@!Yy zZ|GBJnmqEC^xCJs@O{|C_>XIXsg=YehiSkY$3Kf5oD>8|dgrxen2pp1W zeG7&LuI}Ey!!Q*pA`vPQxj|GCe<#9DH^~^$K~spfB@m5hRfU`*<1i9~xe1a0O(nO; zc`^xFoZKc;WEwP$+#xe$7PK*Pm&}oQ&~%u+KrVuI4puCXOQ4Oz*dnp#^{S|lT?TY2r%9hrL z4s~QU1Gje>gfF}oTS7~0NiDghv|=r_75|_ikMI^TpOlycR)J<1cHQ<3BdG<7N1bXA zHygIGLz_VY6^~ks`utgMn4Z_zW~N7j^Sd5}Ikrcc;oCJDC{@SY3RL3OOuHV$2;JP> zIuh6vyyN(B>Lr+ZDR+mm)GGCMe7BKmH2rP2zU+~mWy@_eqh|mIc5hQ15>^^bhR{^F zJ#_f8creo=XeIJK5G;&tbj3iy8`)@I0uk~+#6RRir6s% z>{@<~1mmFkuH`!AW`hQ@Wi?@b)?oC_F7fKRR2xH4(9sM z_AD(#7hOnBgx32W9uO^Hl@4PqnMgY_n}8gM5&4nOQuy;6W&}~-IpQM5xrkw2pxc3N z*Y^PKs_C0-1_u7x~CWp;WHS^ugbFSceGURL)wg>|oa~a7I9))1ibR2gd_;i{@ zN+_*$kgz2%ABbZyyPD0uh~jtyro%YiL~R%XmGKQZR;<2*slKpZgP<;B;s+GSAwG zGU_gnYYODrU@k#jDJM%H=J}>iBM=L)Mdeao{uGL@z^haY8$|a)OkQz-XO?-8Z^0mAmPS9ucu6+Tx+q zWkNzGj-)(qeFHeBp=lbW^s8L{nejBej(K||hXAonj>h4cd+=E_Hcbc9Hx0IJ?0kx( z{FjhVc|T}9GLP9k*aBOH5;kestoiUEvh&9g#{L zDR(Uj%o0phCQA^Q^=y6>BU4P5vr#wUm_{O*^q}e-S|=DBq^ty+vAZA+7W-X3VRd#y zAagnqVS{NNdCYsq45m`#ai>_0I^Q1d^x)c|f#6Lea=%j}zaoOq5W&etal&w9QLry? ziw7VE9G*vqH(own&t;6Kg<`Sri;>H(71)<(jUT_hbHO~;Zew@Tu`OfMWz5}&lUmiK zX!SLSgX?|l4!1pbT=ij@h6n9YEN0CDD6$(6hu^&)8Lh%^I6BND3cFAMW34kBgH9;43 zd0NxQbxn`!WAHz&p95V_#JMF@L!esxw+%nHS5(Wbd%njfhwUF|k3uw0@RyN?Y>o?> HI4l1Tm&)qU literal 0 HcmV?d00001 diff --git a/okx/__pycache__/Funding.cpython-310.pyc b/okx/__pycache__/Funding.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..88fd90d0a49d7496d5cb2370a09db63d0ec4e5ab GIT binary patch literal 5878 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 JIfY*k{|mfl4SxUt literal 0 HcmV?d00001 diff --git a/okx/__pycache__/MarketData.cpython-310.pyc b/okx/__pycache__/MarketData.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fa48a463dbeef0e3a41d635da738616ba09a18c7 GIT binary patch literal 4521 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 literal 0 HcmV?d00001 diff --git a/okx/__pycache__/PublicData.cpython-310.pyc b/okx/__pycache__/PublicData.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1171ce5efea90049cbe6a3de6d371c2ee70b9cb3 GIT binary patch literal 5214 zcmb7I&3D_z5yuxnkfJC{mL-44juI!f>BLf;INxb%T7(?b5-F2VUZo2PV<8DoBth?j zvB*aq`szQUhxn*JskrvkvoC$_Yn+*dK@t+EHsIrMu$W!U$8Tn5=}%AR1-R%xT4ZBE z5dMibss9o|yd;L| zTGMme0dV472Zj=t40jLV%R(TouqzT_SIWt`4EcPf?)jlUVk_S#956BcL0GENW zX;K7EB{Ss0OJO$)BeP@|yMlO*B7|D}Gav4UZ$QR@axe6l%a*Zs($aGH2 zY2-_Co!o%YBFuP?ECV+KZ+f460Ne#~lY9u0v*aUk3x4Ndjoai7Jh@1|A|-McxOtHN zn0x}5y1FK_GyTwBJv2O0p7}bVZ-`>=#re##uYbPqjV9-S*myujSaurCZMiaSfB61Oj zXZFF(_&(ZgK_ajM48F#sDvCw1e`RF#DLDt76JLk|yyqxb1|~Kg;}7Pm$JwFzSv0={ z=Bpz$!;HNbxHMFsxqCi!!%Wj_c>&kEB-3lKAVr7n&Q|md<0rkoW9fg^>uW|sFKMSO zejlYjKynia+D>mEK}?JpejN=WZqoxS^(^e_-9SiH*)rwJlY}L!Aej-OM=g>;?>;+VJ zuiGYGd*7mV;9~4JrZmLV)uhJbg6I1VL8C;7P6j!l>-@N`){jQRtkrh_Y&BL6K8f_62}(?ei(dAi6}uKHRWSv2mmEcO_>*uFzX(5OsKMF6LG4xWm=8x z&CN3SHWT@l*P9hsdveZkJN!;yv2Lqn)85A*%}~!mO0gM}`@IgGflM+s0jm{@yEfIS z7ZIkAOI`~gN-XZWPf>mD*z2PZr^ubJ5CAol9S4f{SnXP<7;9^_ZC@7b{MH_IUF&(*59}|7`raDpd)@>`gc$bF+s|TR`|-QMyB#R1$Wx7-hN*8_;BNgyj7&)bFYB?uZSg((TUhrsR;I$4{bfwb zL4D$D8W_Ci`wNC=e192a2ihPv$PcCf&Qr&Q*oZ+PhVvBPX~Jx4zrE=bH!30A;fPt- ze43uk!VC)l2+`KTQ+>F9B;q)?VLaV7DrM8CRjpdRqSqUx>Bw+imA{51PrZSDgJWoS z+UluMUqH|`z2{wz*n#J_EuVto><3tbAzt!Q9yg|6i*kQ?6#4W?=U3IUJ5nC9`pLV* zN!yN!_!>yx!zgFg(XM46{mV&BMk0xp5j!iy77r$F)X88%5VObHFo;?l#B3BqH6T2O zqwWR+87hJ2(zA6+F%7+5%8iBR4cx#PsY};W#LT$*VKBtT{Fw6`Yz+^fA%^Pb>1H8d^hRJ^CtbzGR!fPNZ&kk zGJ1Vu2fCTK^zyV#E4>`((8sv6*@IqY2UKL(zDzzB# z41hC2m)dP;L9pfd3#`QEfk=`BIWYRD|1ReHr?MeA)j=1=7oHmMo_hylF!B!gC3CC} z{i4Qx$xv*Q}SC@*1; zkxPTY6~wONx8b0`e*&P%KzHk?g`!j~64c!0^ zkdEb{1LW8N5(mcFVmA**LJJx*+?Y&b?a8BZwbFo&nfDhQtL%<#{1s12@_jRdJmSu_Fay4M${wB!u#;-n+V(NxDEAkMQ_CICB{1{ z(tkoOEl}^yNs$%QCNBFci1Ph13XuBWV&?3LX-pmgf^is;b&Bw$h*J|ZMaYi`=$0H9 z-IheoL;6jUnD_wBwEyQE_%~%JS-OmWsOC;YR`5wt1kvv3FM)C+r1<8*{3?#TcjvZn6)`bUI z8pE7DfIE$6P5x~@10PibI{HeAB*GI7##BwoEBS1`n4c>k5#Gy7ctOy_dHFX8fMOf~ literal 0 HcmV?d00001 diff --git a/okx/__pycache__/Status.cpython-310.pyc b/okx/__pycache__/Status.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f8f1b727159ba7aadf45b5221014ff46e639b0c2 GIT binary patch literal 853 zcmY*XO>Yx15ViL!n~(-*Be?Xykwt1&Js}~4S`}JxiIB3r>;Y?8yUi;5RohFNYB|xr zz`Z^4YqPPMZ$Kwv-mpXo1*&~JU%HU|zz;Nm3!MHJ_# zz%j-;wsI>%XNcO=xkc1r_`4n3)SaQg`vY7kz{)$xGgeB7@T(NA{xcg+N8sWG07EgR zD7NU3dbD?ofoX^K=>Q^!J_62>>d#~%8*%*ULRzK7d4bxJ4~)t=4Xx)@{AEckgRK@Ccp;7Pp{E`GjO;CJ70AO_co&J)4Z<3=#Z@vn>%nH5Yq7kP52JX#e=Rw|dWFU{po z#Gk?&>(}8ql!~xgFdn{VVj-(KtXFbgl?Q?@HX-POlIyUOKdDz-i}JvQZgn5u?Eag~ zWYe}nsZMT8&)NkyV|WGu#VyY8H>*W=NMdQV*1Zh_u%^ltFlH9m@tAOS)i5E+GLv&s zCp;;Hvd=z5u{Vp3qw`r{^FDC#F@W;A0wb-1U30DJ8lmfi-XuNS2_R^{pQkdixiQzQL{I^{L@AR@8x*@0=+kXMGL&moN literal 0 HcmV?d00001 diff --git a/okx/__pycache__/SubAccount.cpython-310.pyc b/okx/__pycache__/SubAccount.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..06dd8acfb948e9be5aa92f5a7c178bfd6499ccae GIT binary patch literal 3506 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 aS+*r!j^oi)-tqK`-`l+mnu#dVZ1jJ?O7wXE literal 0 HcmV?d00001 diff --git a/okx/__pycache__/__init__.cpython-310.pyc b/okx/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9f23e77b9baf00edff4d53d428071cfc95b01b5f GIT binary patch literal 220 zcmd1j<>g`kf+pqc6e}S87{oyaj6jY95Et_Ri4=w?h7`sq#uTPt22JKF1+IX~l8pR3 zgKTW1v?D6p_`N{F|x47fu%TkMq zGxPJ}<5w~iF$0YS6Td9=LyLhD`uW+ZMfxtO#n~nK1^NYG3v`Q9vSG~p>f*p7@iq_uCv*s>6WCeC@LJlKpR>>LRD2YD%%!8LzLYj;fuA|ag+VDJL82U z@*YroLh66W9((1Exbhq3%Bg2=6$hTzn@y9dW6kUNcxL8#=Y3u~U0e(p%3pu{F8}ly z`-eKGi;d1*RQ(N%WRee9G<)-iOCha+7+R4%bRuWyMlNR$n6#zyoJl9~o>`GEd6R|i zE39UluQ+UI8Ml*;bgqpv&btF`f@HswWO)~Z9m1V19y)hX^?jIx;Y=0@$;$_)Csxmv z_7hJ!(tXY&M|#qK&LUS zqyzs?3bo1id#L&jOu-8lvqHe~!h#ir4Qmw+tX;UUPT|42x!3ax7YxM*4lBvtgFTSf&&8 zOQPbuJ4}rIWYFF7O_&*V2+6bs+Q4x$7|{Y0&Qo9KR?X6xBOzL$=! zY1zNlNwb4_Kke@Wx4%B)aXmXQejIm4-8_y-ahmpZ`RS+550_?fxjsjBC4Ysy#IgxdC$O%R@*qgD%clRR}2rS2ri-q$HLGRV3gjt%3iHq4~!XwP}vlwC2Jy!5P|4A*glYgT~x@y;TUzlkN+FmHv@Gg>*^;@&2tutN{U`N$-XA z1{3<5hAGOG)}c2O#jQgdI=dBepf#(!%|FYfu;l6WkyU@F))+e%A3)61P<83IGO5>aNI4GS8^_)trT% zNiY(^JDDL_z)ans<8Q)*_S?)pqp7#()z8p7=C)42uV4-@zl+&1szX1Dd7%rVT3#3( zPg##Dkn5D6))De`$|s@_Jx9{_09iyiFU3XVj|BD5-hA~pRvM9ObqS5oQ}0v1{Q5rL z{voP28{0oMw&T`!j~dO^#-ptmqov-|#{fnPNP&E;<4%fHx=K47N2d%->D5{H)dv6( zTTSUuEk#o0wm7^n_xns9ZQ@se59FvlOybxCaXd`rctGuH96uem2eX-ywW5Eqx=4m} zqP`^aH5oedR2WJ|BO>W4DyIvQs>Cf^(eaU*;ynCMXE4v ey32bQKAex^Fpd*2fd}9K9)yE<2oB+4IE+W& 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 literal 0 HcmV?d00001 diff --git a/okx/__pycache__/exceptions.cpython-310.pyc b/okx/__pycache__/exceptions.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..22ea9dc856c1f690000bbad4be211d7551e4823c GIT binary patch literal 1708 zcma)5OK%e~5VpOW-E9aW1SlzwvVf`*B#4kW@lp{W1cww+0U`&iRqT{D$!@SWkc4oe zXKq|kd+cBGl@sUQxWJ6lBz>Xam1k$hp4T_yIN?kpVelWk+}`q~zDYa^GSgEy3Qo07Q~16{N}p6>Ni4 z9pMNU{@@2}J#%8Y(S7*h*^_Qfw$rsFuA%X0Ilu(4AHmk&fCxGuob7%E)#nqgBszX zJ$Ulr?+?&hkj@OK@C5(^QdSU1KdAhIq)319S^P0-u8HvZ%5o)?N+l|6Nv)$*8P-+O z3Zck5;pZ>LttCPlr=?eoTS;Qs&#m-yDqBMv<16{0BXwFjrm!!@UDru$vah3NM?OKX z#;Yf)6{W^aWj8hcZV=-(WKWx8I*rnf<~B&6q;4m%md0O|pihZWC1i#qYc2S6V7vP8w2`A4}axlXkh?OW!B)4J{fYHfeO>O1CUWZPPc~Jri)g z7O$n8d*DiA^F7LF4!#0qe~L~PIFETWfL);d;(^xR9GTZBn2r|mI0tqH^1$E>tV7?{ zX`Rht7g(h~4c7Wk+uR!$`0KnqFhBzR9Ff~kk z9*xmUmi8|k5%J&M+827*tx=y4(SxaDgA_(nXOK*wvM3>Zmr)-A>7PHs9ugULMV-Za z6MM^9C+Fb+$8l#2wWCls73u=Sdl9LqrKcmUFoL>>#8z_&xk)xQ5d?M-^&t>j%>nPz zQB{Zr&iw4*+@?c$eH{GUVe|h$@+#ObppPp^P^y$%Gc!iVPO!z+9`31s+zk`l8@`tZ OIL~(a^G?2adgd=RU~SX@ literal 0 HcmV?d00001 diff --git a/okx/__pycache__/utils.cpython-310.pyc b/okx/__pycache__/utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e0e8fc0b18840199d5fbb6f30ea0587e938f573d GIT binary patch literal 2114 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 literal 0 HcmV?d00001 diff --git a/okx/websocket/__pycache__/WsConnectManager.cpython-310.pyc b/okx/websocket/__pycache__/WsConnectManager.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6286ff1148b7c1aad776fd3cc652e64a0c53af4d GIT binary patch literal 4760 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 literal 0 HcmV?d00001 diff --git a/okx/websocket/__pycache__/WsPublic.cpython-310.pyc b/okx/websocket/__pycache__/WsPublic.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c2b20412376651c2759a7ef75d790dcf411add5 GIT binary patch literal 1087 zcmZ`%J#Q015S`sS+h@m495B$+SpxhA5Q-E86;Y%JMY@93d3OVc*LP<3jwF`5SV~1n zpOpSf*HWb=9ThWY`#6wTX-Bg=U+>LK+Us=y&-eBR^^*bophx}q_&C7po}o~nn1Lw^ z83V2#fr8N(nQV)v4UTRqxVi*H%cekj$Ugw$0Ked7Q8#FV|3CQ5#Es JUFhY1bM&$GD7MEP)iWil%1YR_f*x` z?iprOyU_f*;KwiupYlker@ zn6W=;@ca{E@Clmv1x7N-Cv3QU^C9qs$9cpMV^xDKe6GeJT1@Qy(am9_0B#4 zCbs3eQ=46~Wm^y1HLfW;kHowqg9SnFZn@y|+jo!F`@pVE->AuhJ}!_yICSCEKDgH7E>=ZW z%DfmIHQ>2;%|&J>y>#U&rV^Qtl(D;|?1e5$tNaUf=vq~3Otqs^qg-MU31idU%7rE$ z6|ONUM|sf`PLyz^dSpJsJ{?tljV7@>pCN4zbvzKLVnPa)l{{8z>h(G$kO&>28Jf%gJ6_3*jV`a{NP|+JV|OWj0o}|Bbn4^NHE44&7>AWQ*jv$+5tfRkyV+bx-&U4HKVTGr(V7!(X0@{2EbZFx@tp&bJ{w zmgdb0OoWStV95$>Ec6HTKk{b*%+rV1{jVrJ#=s}x+gSkF;pY)}2uz4OLYP*WK5da2 zx=}6WK^@xgm@Nc^3L8+i|;scu5jf-%#Zdm?9$r~pas&XPL74#|Sk z33Xg2^uEsaEUiL)@iI-$XO-!l1;!-#Pe-PX({}!)2MBBi=5U z49+u&n99a^#8O6xXLIZ5%^hni^I^Y#aB#2*x!TOi-99wFzkj7)O}8g`)+cp;@(1<@ zk5ij!3bPZ|=y%Y;Cn45qZwmc4KG4H9RK-rseG+3$Wr*)UFx3-UXR5M*cD@)JeF}?i zp&8;T5t@WA6yE>BjWPY~##G!E)j8)2ROEo^x8R_&^1`~1KtFemKaqq?ufg0w^YYc< ze%w2yH)!rO8G@{Dllc_Jh1+F0@e1s9a!ISpH0{acX+@Ri!buL|QIg`kf~lNwDIoeWh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6vRKeRZts8~Ng zJGDsPCAB!aB)>qvpt2+*KTo$fB^$=f&#nL}sn9P^O)Ab$&Q2}SkB`sH%PfhH*DI*J W#bJ}1pHiBWY6mjBm=h6bQ#VPI7>M$h&m2>c}_IdtuEgkdX>d0V;4;z`hR!Zden?K>u_g_y_=8 zBJGB?&l13531Cee1CfDgP=P_!95FQL$d|0EiDO{UMRWMjJXv!>Q9m8;FJ3NM0~x6R z6__fpi0#_?{~P?t{68geM+KA!1r*gxx&q`b_#;GW1zQV hY^)t`yeR65t?|4jj)6``-swR8445u7D)83|+yF)|6_)@2 literal 0 HcmV?d00001 diff --git a/test/AccountTest.py b/test/AccountTest.py index 2d088487..0a4c9223 100644 --- a/test/AccountTest.py +++ b/test/AccountTest.py @@ -1,12 +1,12 @@ import unittest -from ..okx import Account +from okx import Account class AccountTest(unittest.TestCase): def setUp(self): - api_key = 'ef06bf27-6a01-4797-b801-e3897031e45d' - api_secret_key = 'D3620B2660203350EEE80FDF5BE0C960' - passphrase = 'Beijing123' + api_key = 'e2ea07df-15ca-405c-9e23-addb4aca8a42' + api_secret_key = 'DE69BED90FF154085B56020A88B2638A' + passphrase = '12345678aA.' self.AccountAPI = Account.AccountAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag='1') ''' POSITIONS_HISTORY = '/api/v5/account/positions-history' #need add @@ -73,8 +73,36 @@ def test_simulated_margin(self): def test_get_greeks(self): print(self.AccountAPI.get_greeks()) ''' - def test_simulated_margin(self): - print(self.AccountAPI.get_simulated_margin()) + # def test_simulated_margin(self): + # print(self.AccountAPI.get_simulated_margin()) + + # def test_get_VIP_interest_accrued_data(self): + # print(self.AccountAPI.get_VIP_interest_accrued_data()) + + # def test_get_VIP_interest_deducted_data(self): + # print(self.AccountAPI.get_VIP_interest_deducted_data()) + + # def test_get_VIP_loan_order_list(self): + # print(self.AccountAPI.get_VIP_loan_order_list()) + # def test_get_VIP_loan_order_detail(self): + # print(self.AccountAPI.get_VIP_loan_order_detail(ordId='1')) + + # def test_set_risk_offset_typel(self): + # print(self.AccountAPI.set_risk_offset_typel(type='1')) + # + # def test_set_auto_loan(self): + # print(self.AccountAPI.set_auto_loan()) + # + # def test_activate_option(self): + # print(self.AccountAPI.activate_option()) + + # def test_get_max_avaliable_size(self): + # print(self.AccountAPI.get_max_avail_size(instId="BTC-USDT",tdMode="cash",quickMgnType='manual')) + # def test_borrow_repay(self): + # print(self.AccountAPI.borrow_repay("BTC", "borrow", "1.0")) + + def test_simulated_margin(self): + print(self.AccountAPI.get_simulated_margin(spotOffsetType='3')) if __name__ == '__main__': unittest.main() \ No newline at end of file diff --git a/test/BlockTradingTest.py b/test/BlockTradingTest.py index 8d86974c..4d062a97 100644 --- a/test/BlockTradingTest.py +++ b/test/BlockTradingTest.py @@ -1,12 +1,12 @@ import unittest -from ..okx import BlockTrading +from okx import BlockTrading class BlockTradingTest(unittest.TestCase): def setUp(self): - api_key = 'ef06bf27-6a01-4797-b801-e3897031e45d' - api_secret_key = 'D3620B2660203350EEE80FDF5BE0C960' - passphrase = 'Beijing123' - self.BlockTradingAPI = BlockTrading.BlockTradingAPI(use_server_time=False, flag='1') + api_key = 'a6f1e378-1c03-472d-ada0-710f4d51eebf' + api_secret_key = '74A6E1E03700D5EFCC2BBB7782170189' + passphrase = 'Qa131415!' + self.BlockTradingAPI = BlockTrading.BlockTradingAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag='1') """ def test_get_counter_parties(self): @@ -42,7 +42,46 @@ def test_get_trade(self): """ - def test_get_public_trades(self): - print(self.BlockTradingAPI.get_public_trades()) + # def test_get_public_trades(self): + # print(self.BlockTradingAPI.get_public_trades()) + + # def test_get_quote_products(self): + # print(self.BlockTradingAPI.get_quote_products()) + + def test_create_rfqs(self): + counterparties=['8924'] + legs =[{ + 'instId':"BTC-USDT", + 'sz':'25', + 'side':'buy', + 'posSide':'net', + 'tdMode':'cross', + 'ccy':'USDT' + }] + print(self.BlockTradingAPI.create_rfq(counterparties,allowPartialExecution='true',tag='1234',legs = legs)) + + # def test_execute_quotes(self): + # legs = [{ + # 'instId':"BTC-USDT", + # 'sz':'0.0001', + # }] + # print(self.BlockTradingAPI.execute_quote("3IR9E68","3IR9E80",legs)) + + # def test_create_quotes(self): + # legs = [{ + # 'instId': "BTC-USDT", + # 'sz': '25', + # 'side': 'buy', + # 'posSide': 'net', + # 'tdMode': 'cross', + # 'ccy': 'USDT' + # }] + # print(self.BlockTradingAPI.create_quote(rfqId='3IR9BT8',quoteSide='buy',legs=legs)) + + # def test_get_trade(self): + # print(self.BlockTradingAPI.get_trades()) + + + if __name__ == '__main__': unittest.main() \ No newline at end of file diff --git a/test/CopyTradingTest.py b/test/CopyTradingTest.py new file mode 100644 index 00000000..dd76a434 --- /dev/null +++ b/test/CopyTradingTest.py @@ -0,0 +1,40 @@ +import unittest +from okx import CopyTrading + +class CopyTradingTest(unittest.TestCase): + def setUp(self): + api_key = 'd4ee8839-1142-41c0-add5-e2e82a91efd2' + api_secret_key = '57E5BEFAB7BD024A91647819E9BCA285' + passphrase = '123456aA.' + self.StackingAPI = CopyTrading.CopyTradingAPI(api_key, api_secret_key, passphrase, use_server_time=False, + flag='0') + + # def test_get_existing_leading_positions(self): + # print(self.StackingAPI.get_existing_leading_positions(instId='DOGE-USDT-SWAP')) + + # def test_get_leading_position_history(self): + # print(self.StackingAPI.get_leading_position_history()) + + # def test_place_leading_stop_order(self): + # print(self.StackingAPI.place_leading_stop_order(subPosId='581247467976732672',tpTriggerPx='1')) + # + # def test_close_leading_position(self): + # print(self.StackingAPI.close_leading_position(subPosId='581247467976732672')) + + # def test_get_leading_instruments(self): + # print(self.StackingAPI.get_leading_instruments()) + + # def test_amend_leading_instruments(self): + # print(self.StackingAPI.amend_leading_instruments(instId='AAVE-USDT-SWAP')) + # + # def test_get_profit_sharing_details(self): + # print(self.StackingAPI.get_profit_sharing_details()) + # + # def test_get_total_profit_sharing(self): + # print(self.StackingAPI.get_total_profit_sharing()) + # + def test_get_unrealized_profit_sharing_details(self): + print(self.StackingAPI.get_unrealized_profit_sharing_details()) + +if __name__ == "__main__": + unittest.main() \ No newline at end of file diff --git a/test/EarningTest.py b/test/EarningTest.py new file mode 100644 index 00000000..f81dd763 --- /dev/null +++ b/test/EarningTest.py @@ -0,0 +1,45 @@ +import unittest +from okx import Earning + +class EarningTest(unittest.TestCase): + def setUp(self): + api_key = 'cfa1017d-940a-445f-af52-b340cbd6b0e0' + api_secret_key = '6C50A4E980230A4BBE7046411DED0276' + passphrase = '123456aA.' + self.StackingAPI = Earning.EarningAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag='0') + + + def test_get_saving_balance(self): + print(self.StackingAPI.get_saving_balance(ccy='USDT')) + + # def test_savings_purchase_redemption(self): + # print(self.StackingAPI.savings_purchase_redemption(ccy='USDT',amt="0.1",side="redempt",rate="1")) + + # def test_set_lending_rate(self): + # print(self.StackingAPI.set_lending_rate(ccy='USDT',rate="1")) + + # def test_get_lending_history(self): + # print(self.StackingAPI.get_lending_history(ccy='USDT')) + + + # def test_get_public_borrow_info(self): + # print(self.StackingAPI.get_public_borrow_info(ccy='USDT')) + + # def test_get_public_borrow_history(self): + # print(self.StackingAPI.get_public_borrow_history(ccy='USDT')) + + + # def setUp(self): + # api_key = 'da097c9c-2f77-4dea-be18-2bfa77d0e394' + # api_secret_key = '56CC6C72D6B8A46EC993D48C83142A25' + # passphrase = '123456aA.' + # self.StackingAPI = Earning.EarningAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag='1') + # def test_purcase(self): + # investData = [{ + # 'ccy': 'USDT', + # 'amt': '50' + # }] + # print(self.StackingAPI.purchase(productId='1456', investData=investData,term='100',tag='dfg')) + +if __name__ == "__main__": + unittest.main() \ No newline at end of file diff --git a/test/FundingTest.py b/test/FundingTest.py index 2cce1e1e..ea8e8722 100644 --- a/test/FundingTest.py +++ b/test/FundingTest.py @@ -1,13 +1,13 @@ import unittest -from ..okx import Funding +from okx import Funding class FundingTest(unittest.TestCase): def setUp(self): - api_key = 'ef06bf27-6a01-4797-b801-e3897031e45d' - api_secret_key = 'D3620B2660203350EEE80FDF5BE0C960' - passphrase = 'Beijing123' - self.FundingAPI = Funding.FundingAPI(use_server_time=False, flag='0') + api_key = 'cfa1017d-940a-445f-af52-b340cbd6b0e0' + api_secret_key = '6C50A4E980230A4BBE7046411DED0276' + passphrase = '123456aA.' + self.FundingAPI = Funding.FundingAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag='0') """ CANCEL_WITHDRAWAL = '/api/v5/asset/cancel-withdrawal' #need add CONVERT_DUST_ASSETS = '/api/v5/asset/convert-dust-assets' #need add @@ -58,9 +58,25 @@ def test_get_lending_summary(self): print(self.FundingAPI.get_lending_rate_summary('BTC')) """ - def test_get_lending_summary(self): - print(self.FundingAPI.get_lending_rate_summary('BTC')) - def test_get_lending_rate_history(self): - print(self.FundingAPI.get_lending_rate_history()) + # def test_get_lending_summary(self): + # print(self.FundingAPI.get_lending_rate_summary('BTC')) + # def test_get_lending_rate_history(self): + # print(self.FundingAPI.get_lending_rate_history()) + + # def test_get_non_tradable_assets(self): + # print(self.FundingAPI.get_non_tradable_assets()) + + def test_get_deposit_withdraw_status(self): + print(self.FundingAPI.get_deposit_withdraw_status(wdId='84804812')) + + # def test_get_withdrawal_history(self): + # print(self.FundingAPI.get_withdrawal_history()) + + # def test_get_deposit_history(self): + # print(self.FundingAPI.get_deposit_history()) + + # def test_withdrawal(self): + # print(self.FundingAPI.withdrawal(ccy='USDT',amt='1',dest='3',toAddr='18740405107',fee='0',areaCode='86')) + if __name__ == '__main__': unittest.main() \ No newline at end of file diff --git a/test/GridTest.py b/test/GridTest.py index 072e67cb..5efb68a1 100644 --- a/test/GridTest.py +++ b/test/GridTest.py @@ -1,12 +1,12 @@ import unittest -from ..okx import Grid +from okx import Grid class GridTest(unittest.TestCase): def setUp(self): - api_key = 'ef06bf27-6a01-4797-b801-e3897031e45d' - api_secret_key = 'D3620B2660203350EEE80FDF5BE0C960' - passphrase = 'Beijing123' + api_key = 'da097c9c-2f77-4dea-be18-2bfa77d0e394' + api_secret_key = '56CC6C72D6B8A46EC993D48C83142A25' + passphrase = '123456aA.' self.GridAPI = Grid.GridAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag='1', debug=False) """ GRID_COMPUTE_MARIGIN_BALANCE = '/api/v5/tradingBot/grid/compute-margin-balance' @@ -49,7 +49,37 @@ def test_withdrawl_profits(self): """ - def test_order_algo(self): - print(self.GridAPI.grid_order_algo("BTC-USDT","grid","45000","20000","100","1",quoteSz="50")) + # def test_order_algo(self): + # print(self.GridAPI.grid_order_algo("BTC-USDT","grid","45000","20000","100","1",quoteSz="50")) + + # def test_place_recurring_buy_order(self): + # print(self.GridAPI.place_recurring_buy_order(stgyName="jzhtest",recurringList=[{ + # 'ccy':"ETH", + # 'ratio':'1' + # }],period="daily",recurringDay='1',recurringTime='0',timeZone='8',amt='100',investmentCcy='USDT',tdMode='cross')) + + # def test_amend_recurring_buy_order(self): + # print(self.GridAPI.amend_recurring_buy_order(algoId="581185292170952704",stgyName="changtest")) + + # def test_stop_recurring_buy_order(self): + # orderData = [{ + # "algoId": "581190894481838080" + # }] + # print(self.GridAPI.stop_recurring_buy_order(orderData)) + + # def test_get_recurring_buy_order_list(self): + # print(self.GridAPI.get_recurring_buy_order_list()) + + # def test_get_recurring_buy_order_history(self): + # print(self.GridAPI.get_recurring_buy_order_history()) + + # def test_get_recurring_buy_order_details(self): + # print(self.GridAPI.get_recurring_buy_order_details(algoId="581191143417970688")) + + # def test_get_recurring_buy_sub_orders(self): + # print(self.GridAPI.get_recurring_buy_sub_orders(algoId="581191143417970688")) + + #581191143417970688 + if __name__ == '__main__': unittest.main() \ No newline at end of file diff --git a/test/MarketTest.py b/test/MarketTest.py index fdf8df77..7ce0beca 100644 --- a/test/MarketTest.py +++ b/test/MarketTest.py @@ -1,6 +1,6 @@ import unittest -from ..okx import MarketData +from okx import MarketData ''' ORACLE = '/api/v5/market/open-oracle' #need to update? if it is open oracle @@ -58,7 +58,11 @@ def test_get_platform_24_volume(self): print(self.MarketApi.get_volume()) ''' + # def test_get_order_lite_book(self): + # print(self.MarketApi.get_order_lite_book(instId='BTC-USDT')) + def test_get_option_trades(self): + print(self.MarketApi.get_option_trades(instFamily='BTC-USD')) if __name__ == "__main__": diff --git a/test/PublicDataTest.py b/test/PublicDataTest.py index f0b51389..f723425c 100644 --- a/test/PublicDataTest.py +++ b/test/PublicDataTest.py @@ -1,10 +1,10 @@ import unittest -from ..okx import PublicData +from okx import PublicData class publicDataTest(unittest.TestCase): def setUp(self): - api_key = 'ef06bf27-6a01-4797-b801-e3897031e45d' - api_secret_key = 'D3620B2660203350EEE80FDF5BE0C960' - passphrase = 'Beijing123' + api_key = 'da097c9c-2f77-4dea-be18-2bfa77d0e394' + api_secret_key = '56CC6C72D6B8A46EC993D48C83142A25' + passphrase = '123456aA.' self.publicDataApi = PublicData.PublicAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag='1') ''' TestCase For: @@ -50,8 +50,14 @@ def test_get_mark_price(self): print(self.publicDataApi.get_mark_price('SWAP')) ''' - def test_position_tier(self): - print(self.publicDataApi.get_position_tiers('SWAP','cross',uly='ETH-USD')) + # def test_position_tier(self): + # print(self.publicDataApi.get_position_tiers('SWAP','cross',uly='ETH-USD')) + + # def test_get_option_tickBands(self): + # print(self.publicDataApi.get_option_tick_bands(instType='OPTION')) + + def test_get_option_trades(self): + print(self.publicDataApi.get_option_trades(instFamily='BTC-USD')) if __name__ == '__main__': unittest.main() \ No newline at end of file diff --git a/test/StackingTest.py b/test/StackingTest.py index 1d6a8755..feff55b5 100644 --- a/test/StackingTest.py +++ b/test/StackingTest.py @@ -1,5 +1,5 @@ import unittest -from ..okx import Status +from okx import Status class StackingTest(unittest.TestCase): def setUp(self): @@ -22,15 +22,6 @@ def test_get_offers(self): def test_purcase(self): print(self.StackingAPI.purchase(1456,"USDT","100","0")) - def test_redeem(self): - print(self.StackingAPI.redeem()) - def test_cencel(self): - print(self.StackingAPI.cancel()) - def test_order_activity(self): - print(self.StackingAPI.get_activity_orders()) - def test_order_history(self): - print(self.StackingAPI.stack_get_order_history()) - if __name__ == "__main__": unittest.main() \ No newline at end of file diff --git a/test/SubAccountTest.py b/test/SubAccountTest.py index c251c0b8..69491d9f 100644 --- a/test/SubAccountTest.py +++ b/test/SubAccountTest.py @@ -1,11 +1,11 @@ import unittest -from ..okx import SubAccount +from okx import SubAccount class SubAccountTest(unittest.TestCase): def setUp(self): - api_key = '52c37310-a8b0-454a-8191-3250acff2626' - api_secret_key = 'EC37534156E6B8C32E78FE8D8C1D506B' - passphrase = 'Hanhao0.0' + api_key = 'e2ea07df-15ca-405c-9e23-addb4aca8a42' + api_secret_key = 'DE69BED90FF154085B56020A88B2638A' + passphrase = '12345678aA.' self.SubAccountApi = SubAccount.SubAccountAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag='1') ''' ENTRUST_SUBACCOUNT_LIST = '/api/v5/users/entrust-subaccount-list' #need to add @@ -36,5 +36,15 @@ def test_subaccount_transfer(self): ''' + # def test_get_the_user_affiliate_rebate_information(self): + # print(self.SubAccountApi.get_the_user_affiliate_rebate_information(apiKey='3af380a7-72af-4cc6-80d1-4b5a34ea69ad')) + + # def test_set_sub_accounts_VIP_loan(self): + # print(self.SubAccountApi.set_sub_accounts_VIP_loan(enable='true',alloc=[{'subAcct':'coretrading7', + # 'loanAlloc':'1'}])) + + def test_get_sub_account_borrow_interest_and_limit(self): + print(self.SubAccountApi.get_sub_account_borrow_interest_and_limit(subAcct='coretrading7')) + if __name__ == "__main__": unittest.main() \ No newline at end of file diff --git a/test/TradeTest.py b/test/TradeTest.py index d963787c..04345642 100644 --- a/test/TradeTest.py +++ b/test/TradeTest.py @@ -1,10 +1,10 @@ import unittest -from ..okx import Trade +from okx import Trade class TradeTest(unittest.TestCase): def setUp(self): - api_key = '35d8f27e-63cc-45bc-a578-45d76363d47f' - api_secret_key = '0B7C968025BC2D4D71CF74771EA0E15C' - passphrase = '123456' + api_key = 'da097c9c-2f77-4dea-be18-2bfa77d0e394' + api_secret_key = '56CC6C72D6B8A46EC993D48C83142A25' + passphrase = '123456aA.' self.tradeApi = Trade.TradeAPI(api_key, api_secret_key, passphrase, False, '1') """ def test_place_order(self): @@ -112,10 +112,80 @@ def test_oneclick_repay(self): """ #485903392536264704 #485936482235191296 - def test_oneclick_repay_history(self): - print(self.tradeApi.oneclick_repay_history()) + # def test_oneclick_repay_history(self): + # print(self.tradeApi.oneclick_repay_history()) + # def test_order_algo(self): + # print(self.tradeApi.place_algo_order(instId='BTC-USDT-SWAP', tdMode='cross', side='buy', ordType='conditional', \ + # tpTriggerPx='15', tpOrdPx='18',sz='2')) + # 581628185981308928 + # def test_get_algo_order_details(self): + # print(self.tradeApi.get_algo_order_details(algoId='581628185981308928')) + #581628185981308928 + # def test_amend_algo_order(self): + # print(self.tradeApi.amend_algo_order(instId='BTC-USDT-SWAP', algoId='581628185981308928',newSz='3')) + # def test_get_order_history(self): + # print(self.tradeApi.get_orders_history(instType="SPOT",begin='1684857629313',end='1684857629313')) + + # def test_get_order_histry_archive(self): + # print(self.tradeApi.get_orders_history_archive(instType="SPOT",begin='1684857629313',end='1684857629313')) + # def test_place_order(self): + # print(self.tradeApi.place_order("BTC-USDT", tdMode="cross", clOrdId="asCai1", side="buy", ordType="limit", + # sz="0.01", px="18000")) + # def test_batch_order(self): + # orderData = [{ + # "instId": "ETH-USDT", + # "tdMode": "cross", + # "clOrdId": "b151121", + # "side": "buy", + # "ordType": "limit", + # "px": "2.15", + # "sz": "2" + # }, + # { + # "instId": "BTC-USDT", + # "tdMode": "cross", + # "clOrdId": "b152233", + # "side": "buy", + # "ordType": "limit", + # "px": "2.15", + # "sz": "2" + # }] + # print(self.tradeApi.place_multiple_orders(orderData)) + + #581616258865516544 + #581616258865516545 + # def test_amend_order(self): + # print(self.tradeApi.amend_order("BTC-USDT", ordId="581616258865516544", newSz="0.03")) + # def test_amend_order_batch(self): + # orderData = [ + # { + # 'instId': 'ETH-USDT', + # 'ordId': '581616258865516544', + # 'newSz': '0.02' + # }, + # { + # 'instId': 'BTC-USDT', + # 'ordId': '581616258865516545', + # 'newPx': '3.0' + # } + # ] + # print(self.tradeApi.amend_multiple_orders(orderData)) + + # def test_order_algo(self): + # + # print(self.tradeApi.place_algo_order(instId='BTC-USDT-SWAP', tdMode='cross', side='buy', ordType='conditional', \ + # tpTriggerPx='15', tpOrdPx='18', sz='2',algoClOrdId='7678687',quickMgnType='manual')) + + def test_order_algos_list(self): + print(self.tradeApi.order_algos_list(ordType='conditional')) + + # def test_order_algo(self): + # print(self.tradeApi.place_order(instId='BTC-USDT-SWAP', tdMode='cross', side='buy',px='121',sz='2', + # clOrdId='234234565535',ordType='market')) + # def test_close_all_positions(self): + # print(self.tradeApi.close_positions(instId="BTC-USDT-SWAP", mgnMode="cross",clOrdId='1213124')) if __name__=='__main__': unittest.main() diff --git a/test/WsPublicTest.py b/test/WsPublicTest.py index e0fbec58..957f2344 100644 --- a/test/WsPublicTest.py +++ b/test/WsPublicTest.py @@ -8,7 +8,8 @@ def publicCallback(message): if __name__ == '__main__': - url = "wss://ws.okx.com:8443/ws/v5/public" + #url = "wss://wspri.coinall.ltd:8443/ws/v5/ipublic?brokerId=9999" + url = "wss://wspap.okx.com:8443/ws/v5/public" ws = WsPublic(url=url) ws.start() args = [] diff --git a/test/__pycache__/AccountTest.cpython-310.pyc b/test/__pycache__/AccountTest.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..695099c947a21be4dbc6b7788e2775a654e50608 GIT binary patch literal 972 zcmZuvJ8u&~5Z=9qeQ}&bL68Co1QJ5J!tvX&C5Ym@5RE}f(p2M}}u$^a?SPS=WeJ99@`Kre|@R*<(XI;^=eX3&Id{lB-+z4mr@k#j4o%{bUkn zzP?x%1B^XT`51sB4>RN$3^U^zdFIM(DbHf|333Z+^)}5Zmzj?t;!bqeMbHCK`5b`Z zOGt8QF!R#P&;_33xiN>nnav6}_8bu?1SyMy*)!hYw6?>Bm3rH!l~%3oS9-kBtWd_@ zx2R9MwAJvQ93FLg`$vbp+VOF{-Kurl`|VDxQR{cR`;AVs+n=r08_ia`v(u&h?PG=O zuHkJ=Bqx%Kk6e%}h`6$bAsxAf&{M0@?J)hfuU$)7l7~aDNYj9f`P5t22g!ZGGi|F< zN~KKC1(p0O5-Sk@>t*!}a?5Hm=AwGY-QhIaqCF{ literal 0 HcmV?d00001 diff --git a/test/__pycache__/BlockTradingTest.cpython-310.pyc b/test/__pycache__/BlockTradingTest.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1c78dbfe89060c41e467530b354a7bfe1130eba6 GIT binary patch literal 1044 zcmZuwOHbQC5Z+xsVrYP>m8z;zt5!mlTq(pR0SBp~kPs>^Q48VX%gSUoA;huWT?auF zPH^o%=mC!XOTPBhztBo;XC07&=vwo6_BD@hX5)p0c?9G4yNI1WLg zFMu>a#VHpw?GJgTcf+7(6QL5%mS*$W{p@_2pbgaG?c>L_a;r!q|+EpedNKX4QD5`u+`$l>|e~KnR{54Ue zPw1Jze)!U8I;lWOOY&t8B<0!t&ek9X9mJvDj3zfb7jplmoR;f9*mKllY zN2yT$`~`l-JEN4-FQYi+z^N*}uZO%Rb7rQXdOmxqGN<>>%MY-TXG;jd)}QD4c=