python-okx 0.3.9__tar.gz → 0.4.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. python_okx-0.4.2/MANIFEST.in +3 -0
  2. {python_okx-0.3.9/python_okx.egg-info → python_okx-0.4.2}/PKG-INFO +97 -17
  3. python_okx-0.3.9/PKG-INFO → python_okx-0.4.2/README.md +67 -27
  4. {python_okx-0.3.9 → python_okx-0.4.2}/okx/Account.py +55 -12
  5. {python_okx-0.3.9 → python_okx-0.4.2}/okx/Convert.py +9 -3
  6. python_okx-0.4.2/okx/DualInvest.py +59 -0
  7. {python_okx-0.3.9 → python_okx-0.4.2}/okx/Finance/SolStaking.py +3 -0
  8. {python_okx-0.3.9 → python_okx-0.4.2}/okx/Funding.py +7 -6
  9. {python_okx-0.3.9 → python_okx-0.4.2}/okx/Grid.py +6 -2
  10. {python_okx-0.3.9 → python_okx-0.4.2}/okx/PublicData.py +20 -0
  11. {python_okx-0.3.9 → python_okx-0.4.2}/okx/Trade.py +51 -11
  12. {python_okx-0.3.9 → python_okx-0.4.2}/okx/TradingData.py +25 -0
  13. {python_okx-0.3.9 → python_okx-0.4.2}/okx/__init__.py +1 -1
  14. {python_okx-0.3.9 → python_okx-0.4.2}/okx/consts.py +20 -1
  15. {python_okx-0.3.9 → python_okx-0.4.2}/okx/okxclient.py +10 -1
  16. {python_okx-0.3.9 → python_okx-0.4.2}/okx/utils.py +1 -1
  17. python_okx-0.4.2/okx/websocket/WsPrivateAsync.py +212 -0
  18. python_okx-0.4.2/okx/websocket/WsPublicAsync.py +133 -0
  19. python_okx-0.4.2/python_okx.egg-info/PKG-INFO +177 -0
  20. {python_okx-0.3.9 → python_okx-0.4.2}/python_okx.egg-info/SOURCES.txt +23 -1
  21. python_okx-0.4.2/python_okx.egg-info/requires.txt +12 -0
  22. python_okx-0.4.2/requirements.txt +15 -0
  23. python_okx-0.4.2/setup.py +60 -0
  24. python_okx-0.4.2/test/test_account.py +159 -0
  25. python_okx-0.4.2/test/test_block_trading.py +88 -0
  26. python_okx-0.4.2/test/test_convert.py +31 -0
  27. python_okx-0.4.2/test/test_copy_trading.py +40 -0
  28. python_okx-0.4.2/test/test_eth_staking.py +30 -0
  29. python_okx-0.4.2/test/test_flexible_loan.py +36 -0
  30. python_okx-0.4.2/test/test_funding.py +93 -0
  31. python_okx-0.4.2/test/test_grid.py +109 -0
  32. python_okx-0.4.2/test/test_market.py +68 -0
  33. python_okx-0.4.2/test/test_public_data.py +79 -0
  34. python_okx-0.4.2/test/test_savings.py +31 -0
  35. python_okx-0.4.2/test/test_sol_staking.py +30 -0
  36. python_okx-0.4.2/test/test_spread.py +47 -0
  37. python_okx-0.4.2/test/test_staking_defi.py +35 -0
  38. python_okx-0.4.2/test/test_sub_account.py +50 -0
  39. python_okx-0.4.2/test/test_trade.py +298 -0
  40. python_okx-0.4.2/test/test_trading_data.py +44 -0
  41. python_okx-0.4.2/test/test_ws_private_async.py +274 -0
  42. python_okx-0.4.2/test/test_ws_public_async.py +81 -0
  43. python_okx-0.3.9/README.md +0 -78
  44. python_okx-0.3.9/okx/websocket/WsPrivateAsync.py +0 -76
  45. python_okx-0.3.9/okx/websocket/WsPublicAsync.py +0 -55
  46. python_okx-0.3.9/python_okx.egg-info/requires.txt +0 -7
  47. python_okx-0.3.9/setup.py +0 -30
  48. {python_okx-0.3.9 → python_okx-0.4.2}/okx/BlockTrading.py +0 -0
  49. {python_okx-0.3.9 → python_okx-0.4.2}/okx/CopyTrading.py +0 -0
  50. {python_okx-0.3.9 → python_okx-0.4.2}/okx/FDBroker.py +0 -0
  51. {python_okx-0.3.9 → python_okx-0.4.2}/okx/Finance/EthStaking.py +0 -0
  52. {python_okx-0.3.9 → python_okx-0.4.2}/okx/Finance/FlexibleLoan.py +0 -0
  53. {python_okx-0.3.9 → python_okx-0.4.2}/okx/Finance/Savings.py +0 -0
  54. {python_okx-0.3.9 → python_okx-0.4.2}/okx/Finance/StakingDefi.py +0 -0
  55. {python_okx-0.3.9 → python_okx-0.4.2}/okx/Finance/__init__.py +0 -0
  56. {python_okx-0.3.9 → python_okx-0.4.2}/okx/MarketData.py +0 -0
  57. {python_okx-0.3.9 → python_okx-0.4.2}/okx/SpreadTrading.py +0 -0
  58. {python_okx-0.3.9 → python_okx-0.4.2}/okx/Status.py +0 -0
  59. {python_okx-0.3.9 → python_okx-0.4.2}/okx/SubAccount.py +0 -0
  60. {python_okx-0.3.9 → python_okx-0.4.2}/okx/exceptions.py +0 -0
  61. {python_okx-0.3.9 → python_okx-0.4.2}/okx/websocket/WebSocketFactory.py +0 -0
  62. {python_okx-0.3.9 → python_okx-0.4.2}/okx/websocket/WsUtils.py +0 -0
  63. {python_okx-0.3.9 → python_okx-0.4.2}/okx/websocket/__init__.py +0 -0
  64. {python_okx-0.3.9 → python_okx-0.4.2}/python_okx.egg-info/dependency_links.txt +0 -0
  65. {python_okx-0.3.9 → python_okx-0.4.2}/python_okx.egg-info/top_level.txt +0 -0
  66. {python_okx-0.3.9 → python_okx-0.4.2}/setup.cfg +0 -0
@@ -0,0 +1,3 @@
1
+ include requirements.txt
2
+ include README.md
3
+
@@ -1,21 +1,42 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: python-okx
3
- Version: 0.3.9
3
+ Version: 0.4.2
4
4
  Summary: Python SDK for OKX
5
5
  Home-page: https://okx.com/docs-v5/
6
6
  Author: okxv5api
7
7
  Author-email: api@okg.com
8
8
  Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.7
10
+ Classifier: Programming Language :: Python :: 3.8
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
9
15
  Classifier: License :: OSI Approved :: MIT License
10
16
  Classifier: Operating System :: OS Independent
17
+ Requires-Python: >=3.7
11
18
  Description-Content-Type: text/markdown
12
- Requires-Dist: importlib-metadata
13
- Requires-Dist: httpx[http2]
14
- Requires-Dist: keyring
15
- Requires-Dist: loguru
16
- Requires-Dist: requests
17
- Requires-Dist: Twisted
18
- Requires-Dist: pyOpenSSL
19
+ Requires-Dist: httpx[http2]>=0.24.0
20
+ Requires-Dist: requests>=2.25.0
21
+ Requires-Dist: websockets>=10.0
22
+ Requires-Dist: certifi>=2021.0.0
23
+ Requires-Dist: loguru>=0.7.0
24
+ Requires-Dist: python-dotenv>=1.0.0
25
+ Requires-Dist: pytest>=7.0.0
26
+ Requires-Dist: pytest-asyncio>=0.21.0
27
+ Requires-Dist: pytest-cov>=4.0.0
28
+ Requires-Dist: ruff>=0.1.0
29
+ Requires-Dist: build>=1.0.0
30
+ Requires-Dist: twine>=4.0.0
31
+ Dynamic: author
32
+ Dynamic: author-email
33
+ Dynamic: classifier
34
+ Dynamic: description
35
+ Dynamic: description-content-type
36
+ Dynamic: home-page
37
+ Dynamic: requires-dist
38
+ Dynamic: requires-python
39
+ Dynamic: summary
19
40
 
20
41
  ### Overview
21
42
  This is an unofficial Python wrapper for the [OKX exchange v5 API](https://www.okx.com/okx-api)
@@ -24,8 +45,6 @@ If you came here looking to purchase cryptocurrencies from the OKX exchange, ple
24
45
 
25
46
  #### Source code
26
47
  https://github.com/okxapi/python-okx
27
- #### OKX API Telegram
28
- https://t.me/OKXAPI
29
48
  #### API trading tutorials
30
49
  - Spot trading: https://www.okx.com/help/how-can-i-do-spot-trading-with-the-jupyter-notebook
31
50
  - Derivative trading: https://www.okx.com/help/how-can-i-do-derivatives-trading-with-the-jupyter-notebook
@@ -39,22 +58,83 @@ Make sure you update often and check the [Changelog](https://www.okx.com/docs-v5
39
58
  - Websocket handling with reconnection and multiplexed connections
40
59
 
41
60
  ### Quick start
42
- #### Prerequisites
43
61
 
44
- `python version:>=3.9`
62
+ #### Prerequisites
45
63
 
46
- `WebSocketAPI: websockets package advise version 6.0`
64
+ `python version:>=3.7`
47
65
 
48
- #### Step 1: register an account on OKX and apply for an API key
66
+ #### Step 1: Register an account on OKX and apply for an API key
49
67
  - Register for an account: https://www.okx.com/account/register
50
68
  - Apply for an API key: https://www.okx.com/account/users/myApi
51
69
 
52
- #### Step 2: install python-okx
70
+ #### Step 2: Install python-okx
53
71
 
54
- ```python
72
+ ```bash
55
73
  pip install python-okx
56
74
  ```
57
75
 
76
+ ### API Credentials
77
+
78
+ #### Option 1: Hardcoded credentials
79
+
80
+ ```python
81
+ from okx import Account
82
+
83
+ account = Account.AccountAPI(
84
+ api_key="your-api-key-here",
85
+ api_secret_key="your-api-secret-here",
86
+ passphrase="your-passphrase-here",
87
+ flag="1", # 0 = live trading, 1 = demo trading
88
+ debug=False
89
+ )
90
+ ```
91
+
92
+ #### Option 2: Using `.env` file (recommended)
93
+
94
+ Create a `.env` file in your project root:
95
+
96
+ ```bash
97
+ OKX_API_KEY=your-api-key-here
98
+ OKX_API_SECRET=your-api-secret-here
99
+ OKX_PASSPHRASE=your-passphrase-here
100
+ OKX_FLAG=1
101
+ ```
102
+
103
+ Then load it in your code:
104
+
105
+ ```python
106
+ import os
107
+ from dotenv import load_dotenv
108
+ from okx import Account
109
+
110
+ load_dotenv()
111
+
112
+ account = Account.AccountAPI(
113
+ api_key=os.getenv('OKX_API_KEY'),
114
+ api_secret_key=os.getenv('OKX_API_SECRET'),
115
+ passphrase=os.getenv('OKX_PASSPHRASE'),
116
+ flag=os.getenv('OKX_FLAG', '1'),
117
+ debug=False
118
+ )
119
+ ```
120
+
121
+ ### Development Setup
122
+
123
+ For contributors or local development:
124
+
125
+ ```bash
126
+ # Clone the repository
127
+ git clone https://github.com/okxapi/python-okx.git
128
+ cd python-okx
129
+
130
+ # Install dependencies
131
+ pip install -r requirements.txt
132
+ pip install -e .
133
+
134
+ # Run tests
135
+ pytest test/unit/ -v
136
+ ```
137
+
58
138
  #### Step 3: Run examples
59
139
 
60
140
  - Fill in API credentials in the corresponding examples
@@ -1,22 +1,3 @@
1
- Metadata-Version: 2.1
2
- Name: python-okx
3
- Version: 0.3.9
4
- Summary: Python SDK for OKX
5
- Home-page: https://okx.com/docs-v5/
6
- Author: okxv5api
7
- Author-email: api@okg.com
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Operating System :: OS Independent
11
- Description-Content-Type: text/markdown
12
- Requires-Dist: importlib-metadata
13
- Requires-Dist: httpx[http2]
14
- Requires-Dist: keyring
15
- Requires-Dist: loguru
16
- Requires-Dist: requests
17
- Requires-Dist: Twisted
18
- Requires-Dist: pyOpenSSL
19
-
20
1
  ### Overview
21
2
  This is an unofficial Python wrapper for the [OKX exchange v5 API](https://www.okx.com/okx-api)
22
3
 
@@ -24,8 +5,6 @@ If you came here looking to purchase cryptocurrencies from the OKX exchange, ple
24
5
 
25
6
  #### Source code
26
7
  https://github.com/okxapi/python-okx
27
- #### OKX API Telegram
28
- https://t.me/OKXAPI
29
8
  #### API trading tutorials
30
9
  - Spot trading: https://www.okx.com/help/how-can-i-do-spot-trading-with-the-jupyter-notebook
31
10
  - Derivative trading: https://www.okx.com/help/how-can-i-do-derivatives-trading-with-the-jupyter-notebook
@@ -39,22 +18,83 @@ Make sure you update often and check the [Changelog](https://www.okx.com/docs-v5
39
18
  - Websocket handling with reconnection and multiplexed connections
40
19
 
41
20
  ### Quick start
42
- #### Prerequisites
43
21
 
44
- `python version:>=3.9`
22
+ #### Prerequisites
45
23
 
46
- `WebSocketAPI: websockets package advise version 6.0`
24
+ `python version:>=3.7`
47
25
 
48
- #### Step 1: register an account on OKX and apply for an API key
26
+ #### Step 1: Register an account on OKX and apply for an API key
49
27
  - Register for an account: https://www.okx.com/account/register
50
28
  - Apply for an API key: https://www.okx.com/account/users/myApi
51
29
 
52
- #### Step 2: install python-okx
30
+ #### Step 2: Install python-okx
53
31
 
54
- ```python
32
+ ```bash
55
33
  pip install python-okx
56
34
  ```
57
35
 
36
+ ### API Credentials
37
+
38
+ #### Option 1: Hardcoded credentials
39
+
40
+ ```python
41
+ from okx import Account
42
+
43
+ account = Account.AccountAPI(
44
+ api_key="your-api-key-here",
45
+ api_secret_key="your-api-secret-here",
46
+ passphrase="your-passphrase-here",
47
+ flag="1", # 0 = live trading, 1 = demo trading
48
+ debug=False
49
+ )
50
+ ```
51
+
52
+ #### Option 2: Using `.env` file (recommended)
53
+
54
+ Create a `.env` file in your project root:
55
+
56
+ ```bash
57
+ OKX_API_KEY=your-api-key-here
58
+ OKX_API_SECRET=your-api-secret-here
59
+ OKX_PASSPHRASE=your-passphrase-here
60
+ OKX_FLAG=1
61
+ ```
62
+
63
+ Then load it in your code:
64
+
65
+ ```python
66
+ import os
67
+ from dotenv import load_dotenv
68
+ from okx import Account
69
+
70
+ load_dotenv()
71
+
72
+ account = Account.AccountAPI(
73
+ api_key=os.getenv('OKX_API_KEY'),
74
+ api_secret_key=os.getenv('OKX_API_SECRET'),
75
+ passphrase=os.getenv('OKX_PASSPHRASE'),
76
+ flag=os.getenv('OKX_FLAG', '1'),
77
+ debug=False
78
+ )
79
+ ```
80
+
81
+ ### Development Setup
82
+
83
+ For contributors or local development:
84
+
85
+ ```bash
86
+ # Clone the repository
87
+ git clone https://github.com/okxapi/python-okx.git
88
+ cd python-okx
89
+
90
+ # Install dependencies
91
+ pip install -r requirements.txt
92
+ pip install -e .
93
+
94
+ # Run tests
95
+ pytest test/unit/ -v
96
+ ```
97
+
58
98
  #### Step 3: Run examples
59
99
 
60
100
  - Fill in API credentials in the corresponding examples
@@ -23,32 +23,34 @@ class AccountAPI(OkxClient):
23
23
  return self._request_with_params(GET, ACCOUNT_INFO, params)
24
24
 
25
25
  # Get Positions
26
- def get_positions(self, instType='', instId=''):
27
- params = {'instType': instType, 'instId': instId}
26
+ def get_positions(self, instType='', instId='', posId=''):
27
+ params = {'instType': instType, 'instId': instId, 'posId': posId}
28
28
  return self._request_with_params(GET, POSITION_INFO, params)
29
29
 
30
- def position_builder(self, acctLv=None,inclRealPosAndEq=False, lever=None, greeksType=None, simPos=None,
31
- simAsset=None):
30
+ def position_builder(self, acctLv=None, inclRealPosAndEq=None, lever=None, greeksType=None, simPos=None,
31
+ simAsset=None, idxVol=None):
32
32
  params = {}
33
33
  if acctLv is not None:
34
34
  params['acctLv'] = acctLv
35
35
  if inclRealPosAndEq is not None:
36
36
  params['inclRealPosAndEq'] = inclRealPosAndEq
37
37
  if lever is not None:
38
- params['spotOffsetType'] = lever
38
+ params['lever'] = lever
39
39
  if greeksType is not None:
40
- params['greksType'] = greeksType
40
+ params['greeksType'] = greeksType
41
41
  if simPos is not None:
42
42
  params['simPos'] = simPos
43
43
  if simAsset is not None:
44
44
  params['simAsset'] = simAsset
45
+ if idxVol is not None:
46
+ params['idxVol'] = idxVol
45
47
  return self._request_with_params(POST, POSITION_BUILDER, params)
46
48
 
47
49
  # Get Bills Details (recent 7 days)
48
50
  def get_account_bills(self, instType='', ccy='', mgnMode='', ctType='', type='', subType='', after='', before='',
49
- limit=''):
51
+ limit='', begin='', end=''):
50
52
  params = {'instType': instType, 'ccy': ccy, 'mgnMode': mgnMode, 'ctType': ctType, 'type': type,
51
- 'subType': subType, 'after': after, 'before': before, 'limit': limit}
53
+ 'subType': subType, 'after': after, 'before': before, 'limit': limit, 'begin': begin, 'end': end}
52
54
  return self._request_with_params(GET, BILLS_DETAIL, params)
53
55
 
54
56
  # Get Bills Details (recent 3 months)
@@ -74,14 +76,18 @@ class AccountAPI(OkxClient):
74
76
  return self._request_with_params(POST, SET_LEVERAGE, params)
75
77
 
76
78
  # Get Maximum Tradable Size For Instrument
77
- def get_max_order_size(self, instId, tdMode, ccy='', px=''):
79
+ def get_max_order_size(self, instId, tdMode, ccy='', px='', tradeQuoteCcy=None):
78
80
  params = {'instId': instId, 'tdMode': tdMode, 'ccy': ccy, 'px': px}
81
+ if tradeQuoteCcy is not None:
82
+ params['tradeQuoteCcy'] = tradeQuoteCcy
79
83
  return self._request_with_params(GET, MAX_TRADE_SIZE, params)
80
84
 
81
85
  # Get Maximum Available Tradable Amount
82
- def get_max_avail_size(self, instId, tdMode, ccy='', reduceOnly='', unSpotOffset='', quickMgnType=''):
86
+ def get_max_avail_size(self, instId, tdMode, ccy='', reduceOnly='', unSpotOffset='', quickMgnType='', tradeQuoteCcy=None):
83
87
  params = {'instId': instId, 'tdMode': tdMode, 'ccy': ccy, 'reduceOnly': reduceOnly,
84
88
  'unSpotOffset': unSpotOffset, 'quickMgnType': quickMgnType}
89
+ if tradeQuoteCcy is not None:
90
+ params['tradeQuoteCcy'] = tradeQuoteCcy
85
91
  return self._request_with_params(GET, MAX_AVAIL_SIZE, params)
86
92
 
87
93
  # Increase / Decrease margin
@@ -100,13 +106,17 @@ class AccountAPI(OkxClient):
100
106
  return self._request_with_params(GET, GET_INSTRUMENTS, params)
101
107
 
102
108
  # Get the maximum loan of isolated MARGIN
103
- def get_max_loan(self, instId, mgnMode, mgnCcy=''):
109
+ def get_max_loan(self, instId, mgnMode, mgnCcy='', tradeQuoteCcy=None):
104
110
  params = {'instId': instId, 'mgnMode': mgnMode, 'mgnCcy': mgnCcy}
111
+ if tradeQuoteCcy is not None:
112
+ params['tradeQuoteCcy'] = tradeQuoteCcy
105
113
  return self._request_with_params(GET, MAX_LOAN, params)
106
114
 
107
115
  # Get Fee Rates
108
- def get_fee_rates(self, instType, instId='', uly='', category='', instFamily=''):
116
+ def get_fee_rates(self, instType, instId='', uly='', category='', instFamily='', groupId=None):
109
117
  params = {'instType': instType, 'instId': instId, 'uly': uly, 'category': category, 'instFamily': instFamily}
118
+ if groupId is not None:
119
+ params['groupId'] = groupId
110
120
  return self._request_with_params(GET, FEE_RATES, params)
111
121
 
112
122
  # Get interest-accrued
@@ -323,3 +333,36 @@ class AccountAPI(OkxClient):
323
333
  def spot_borrow_repay_history(self, ccy='', type='', after='', before='', limit=''):
324
334
  params = {'ccy': ccy, 'type': type, 'after': after, 'before': before, 'limit': limit}
325
335
  return self._request_with_params(GET, GET_BORROW_REPAY_HISTORY, params)
336
+
337
+ def set_auto_earn(self, ccy, action, earnType=None):
338
+ params = {'ccy': ccy, 'action': action}
339
+ if earnType is not None:
340
+ params['earnType'] = earnType
341
+ return self._request_with_params(POST, SET_AUTO_EARN, params)
342
+
343
+ # Set trading config (BROK-1724). type is required (e.g. 'stgyType');
344
+ # stgyType (0=general, 1=delta neutral) applies only when type == 'stgyType'.
345
+ def set_trading_config(self, type='', stgyType=''):
346
+ params = {'type': type}
347
+ if stgyType != '':
348
+ params['stgyType'] = stgyType
349
+ return self._request_with_params(POST, SET_TRADING_CONFIG, params)
350
+
351
+ # Pre-check whether the delta-neutral switch is allowed (BROK-1724)
352
+ def precheck_set_delta_neutral(self, stgyType=''):
353
+ params = {'stgyType': stgyType}
354
+ return self._request_with_params(GET, PRECHECK_SET_DELTA_NEUTRAL, params)
355
+
356
+ # Get the list of supported bill subtypes (BROK-1728)
357
+ def get_bill_type(self, type=''):
358
+ params = {}
359
+ if type != '':
360
+ params['type'] = type
361
+ return self._request_with_params(GET, BILL_TYPE, params)
362
+
363
+ # Apply for an asynchronous bill history archive by year + quarter (BROK-1728)
364
+ def apply_bills(self, year='', quarter='', type=''):
365
+ params = {'year': year, 'quarter': quarter}
366
+ if type != '':
367
+ params['type'] = type
368
+ return self._request_with_params(POST, BILLS_APPLY, params)
@@ -10,16 +10,22 @@ class ConvertAPI(OkxClient):
10
10
  params = {}
11
11
  return self._request_with_params(GET, GET_CURRENCIES, params)
12
12
 
13
- def get_currency_pair(self, fromCcy='', toCcy=''):
13
+ def get_currency_pair(self, fromCcy='', toCcy='', convertMode=None):
14
14
  params = {"fromCcy": fromCcy, 'toCcy': toCcy}
15
+ if convertMode is not None:
16
+ params['convertMode'] = convertMode
15
17
  return self._request_with_params(GET, GET_CURRENCY_PAIR, params)
16
18
 
17
- def estimate_quote(self, baseCcy = '', quoteCcy = '', side = '', rfqSz = '', rfqSzCcy = '', clQReqId = '',tag=''):
19
+ def estimate_quote(self, baseCcy = '', quoteCcy = '', side = '', rfqSz = '', rfqSzCcy = '', clQReqId = '',tag='', convertMode=None):
18
20
  params = {'baseCcy': baseCcy, 'quoteCcy': quoteCcy, 'side':side, 'rfqSz':rfqSz, 'rfqSzCcy':rfqSzCcy, 'clQReqId':clQReqId,'tag':tag}
21
+ if convertMode is not None:
22
+ params['convertMode'] = convertMode
19
23
  return self._request_with_params(POST, ESTIMATE_QUOTE, params)
20
24
 
21
- def convert_trade(self, quoteId = '', baseCcy = '', quoteCcy = '', side = '', sz = '', szCcy = '', clTReqId = '',tag=''):
25
+ def convert_trade(self, quoteId = '', baseCcy = '', quoteCcy = '', side = '', sz = '', szCcy = '', clTReqId = '',tag='', convertMode=None):
22
26
  params = {'quoteId': quoteId, 'baseCcy': baseCcy, 'quoteCcy':quoteCcy, 'side':side, 'sz':sz, 'szCcy':szCcy, 'clTReqId':clTReqId,'tag':tag}
27
+ if convertMode is not None:
28
+ params['convertMode'] = convertMode
23
29
  return self._request_with_params(POST, CONVERT_TRADE, params)
24
30
 
25
31
  def get_convert_history(self, after = '', before = '', limit = '',tag=''):
@@ -0,0 +1,59 @@
1
+ from .okxclient import OkxClient
2
+ from .consts import (
3
+ GET,
4
+ POST,
5
+ DUAL_INVEST_CURRENCY_PAIRS,
6
+ DUAL_INVEST_PRODUCT_INFO,
7
+ DUAL_INVEST_REQUEST_QUOTE,
8
+ DUAL_INVEST_TRADE,
9
+ DUAL_INVEST_REQUEST_REDEEM_QUOTE,
10
+ DUAL_INVEST_REDEEM,
11
+ DUAL_INVEST_ORDER_STATE,
12
+ DUAL_INVEST_ORDER_HISTORY,
13
+ )
14
+
15
+
16
+ class DualInvestAPI(OkxClient):
17
+ def __init__(self, api_key='-1', api_secret_key='-1', passphrase='-1', use_server_time=None, flag='1', domain='https://www.okx.com', debug=False, proxy=None): # NOSONAR - '-1' is the SDK-wide "no credential supplied" sentinel (auth is gated on api_key != '-1' in OkxClient), not a hard-coded secret
18
+ OkxClient.__init__(self, api_key, api_secret_key, passphrase, use_server_time, flag, domain, debug, proxy)
19
+
20
+ # GET /api/v5/finance/sfp/dcd/currency-pair
21
+ def get_currency_pairs(self):
22
+ return self._request_without_params(GET, DUAL_INVEST_CURRENCY_PAIRS)
23
+
24
+ # GET /api/v5/finance/sfp/dcd/products
25
+ def get_product_info(self, baseCcy='', quoteCcy='', optType=''):
26
+ params = {'baseCcy': baseCcy, 'quoteCcy': quoteCcy, 'optType': optType}
27
+ return self._request_with_params(GET, DUAL_INVEST_PRODUCT_INFO, params)
28
+
29
+ # POST /api/v5/finance/sfp/dcd/quote
30
+ def request_quote(self, productId='', notionalSz='', notionalCcy=''):
31
+ params = {'productId': productId, 'notionalSz': notionalSz, 'notionalCcy': notionalCcy}
32
+ return self._request_with_params(POST, DUAL_INVEST_REQUEST_QUOTE, params)
33
+
34
+ # POST /api/v5/finance/sfp/dcd/trade
35
+ def trade(self, quoteId=''):
36
+ params = {'quoteId': quoteId}
37
+ return self._request_with_params(POST, DUAL_INVEST_TRADE, params)
38
+
39
+ # POST /api/v5/finance/sfp/dcd/redeem-quote
40
+ def request_redeem_quote(self, ordId=''):
41
+ params = {'ordId': ordId}
42
+ return self._request_with_params(POST, DUAL_INVEST_REQUEST_REDEEM_QUOTE, params)
43
+
44
+ # POST /api/v5/finance/sfp/dcd/redeem
45
+ def redeem(self, ordId='', quoteId=''):
46
+ params = {'ordId': ordId, 'quoteId': quoteId}
47
+ return self._request_with_params(POST, DUAL_INVEST_REDEEM, params)
48
+
49
+ # GET /api/v5/finance/sfp/dcd/order-status
50
+ def get_order_state(self, ordId=''):
51
+ params = {'ordId': ordId}
52
+ return self._request_with_params(GET, DUAL_INVEST_ORDER_STATE, params)
53
+
54
+ # GET /api/v5/finance/sfp/dcd/order-history
55
+ def get_order_history(self, ordId='', productId='', uly='', state='',
56
+ beginId='', endId='', begin='', end='', limit=''):
57
+ params = {'ordId': ordId, 'productId': productId, 'uly': uly, 'state': state,
58
+ 'beginId': beginId, 'endId': endId, 'begin': begin, 'end': end, 'limit': limit}
59
+ return self._request_with_params(GET, DUAL_INVEST_ORDER_HISTORY, params)
@@ -46,3 +46,6 @@ class SolStakingAPI(OkxClient):
46
46
  'days': days,
47
47
  }
48
48
  return self._request_with_params(GET, STACK_SOL_APY_HISTORY, params)
49
+
50
+ def sol_product_info(self):
51
+ return self._request_without_params(GET, STACK_SOL_PRODUCT_INFO)
@@ -35,9 +35,11 @@ class FundingAPI(OkxClient):
35
35
  return self._request_with_params(POST, FUNDS_TRANSFER, params)
36
36
 
37
37
  # Withdrawal
38
- def withdrawal(self, ccy, amt, dest, toAddr, chain='', areaCode='', clientId=''):
38
+ def withdrawal(self, ccy, amt, dest, toAddr, chain='', areaCode='', clientId='', toAddrType=None):
39
39
  params = {'ccy': ccy, 'amt': amt, 'dest': dest, 'toAddr': toAddr, 'chain': chain,
40
40
  'areaCode': areaCode, 'clientId': clientId}
41
+ if toAddrType is not None:
42
+ params['toAddrType'] = toAddrType
41
43
  return self._request_with_params(POST, WITHDRAWAL_COIN, params)
42
44
 
43
45
  # Get Deposit History
@@ -46,10 +48,7 @@ class FundingAPI(OkxClient):
46
48
  'depId': depId, 'fromWdId': fromWdId}
47
49
  return self._request_with_params(GET, DEPOSIT_HISTORY, params)
48
50
 
49
- # Get Withdrawal History
50
- def get_withdrawal_history(self, ccy='', wdId='', state='', after='', before='', limit='',txId=''):
51
- params = {'ccy': ccy, 'wdId': wdId, 'state': state, 'after': after, 'before': before, 'limit': limit,'txId':txId}
52
- return self._request_with_params(GET, WITHDRAWAL_HISTORY, params)
51
+
53
52
 
54
53
  # Get Currencies
55
54
  def get_currencies(self, ccy=''):
@@ -113,7 +112,9 @@ class FundingAPI(OkxClient):
113
112
  return self._request_with_params(GET, GET_DEPOSIT_WITHDrAW_STATUS, params)
114
113
 
115
114
  #Get withdrawal history
116
- def get_withdrawal_history(self, ccy='', wdId='', clientId='', txId='', type='', state='', after='', before ='', limit=''):
115
+ def get_withdrawal_history(self, ccy='', wdId='', clientId='', txId='', type='', state='', after='', before='', limit='', toAddrType=None):
117
116
  params = {'ccy': ccy, 'wdId': wdId, 'clientId': clientId, 'txId': txId, 'type': type, 'state': state, 'after': after, 'before': before, 'limit': limit}
117
+ if toAddrType is not None:
118
+ params['toAddrType'] = toAddrType
118
119
  return self._request_with_params(GET, GET_WITHDRAWAL_HISTORY, params)
119
120
 
@@ -7,11 +7,13 @@ class GridAPI(OkxClient):
7
7
  OkxClient.__init__(self, api_key, api_secret_key, passphrase, use_server_time, flag, domain, debug, proxy)
8
8
 
9
9
  def grid_order_algo(self, instId='', algoOrdType='', maxPx='', minPx='', gridNum='', runType='', tpTriggerPx='',
10
- slTriggerPx='', tag='', quoteSz='', baseSz='', sz='', direction='', lever='', basePos=''):
10
+ slTriggerPx='', tag='', quoteSz='', baseSz='', sz='', direction='', lever='', basePos='', tradeQuoteCcy=None):
11
11
  params = {'instId': instId, 'algoOrdType': algoOrdType, 'maxPx': maxPx, 'minPx': minPx, 'gridNum': gridNum,
12
12
  'runType': runType, 'tpTriggerPx': tpTriggerPx, 'slTriggerPx': slTriggerPx, 'tag': tag,
13
13
  'quoteSz': quoteSz, 'baseSz': baseSz, 'sz': sz, 'direction': direction, 'lever': lever,
14
14
  'basePos': basePos}
15
+ if tradeQuoteCcy is not None:
16
+ params['tradeQuoteCcy'] = tradeQuoteCcy
15
17
  return self._request_with_params(POST, GRID_ORDER_ALGO, params)
16
18
 
17
19
  def grid_amend_order_algo(self, algoId='', instId='', slTriggerPx='', tpTriggerPx=''):
@@ -79,11 +81,13 @@ class GridAPI(OkxClient):
79
81
 
80
82
  # - Place recurring buy order
81
83
  def place_recurring_buy_order(self, stgyName='', recurringList=[], period='', recurringDay='', recurringTime='',
82
- timeZone='', amt='', investmentCcy='', tdMode='', algoClOrdId='', tag=''):
84
+ timeZone='', amt='', investmentCcy='', tdMode='', algoClOrdId='', tag='', tradeQuoteCcy=None):
83
85
  params = {'stgyName': stgyName, 'recurringList': recurringList, 'period': period, 'recurringDay': recurringDay,
84
86
  'recurringTime': recurringTime,
85
87
  'timeZone': timeZone, 'amt': amt, 'investmentCcy': investmentCcy, 'tdMode': tdMode,
86
88
  'algoClOrdId': algoClOrdId, 'tag': tag}
89
+ if tradeQuoteCcy is not None:
90
+ params['tradeQuoteCcy'] = tradeQuoteCcy
87
91
  return self._request_with_params(POST, PLACE_RECURRING_BUY_ORDER, params)
88
92
 
89
93
  # - Amend recurring buy order
@@ -122,3 +122,23 @@ class PublicAPI(OkxClient):
122
122
  'optType': optType
123
123
  }
124
124
  return self._request_with_params(GET, GET_OPTION_TRADES, params)
125
+
126
+ # Get historical market data
127
+ def get_market_data_history(self, module, instType, dateAggrType, begin, end, instIdList=None, instFamilyList=None):
128
+ params = {
129
+ 'module': module,
130
+ 'instType': instType,
131
+ 'dateAggrType': dateAggrType,
132
+ 'begin': begin,
133
+ 'end': end
134
+ }
135
+ if instIdList is not None:
136
+ params['instIdList'] = instIdList
137
+ if instFamilyList is not None:
138
+ params['instFamilyList'] = instFamilyList
139
+ return self._request_with_params(GET, MARKET_DATA_HISTORY, params)
140
+
141
+ # Get announcements (BROK-1730)
142
+ def get_announcements(self, annType='', page=''):
143
+ params = {'annType': annType, 'page': page}
144
+ return self._request_with_params(GET, ANNOUNCEMENTS, params)