Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# OKX API Credentials
# Copy this file to .env and fill in your actual credentials
# NEVER commit .env to version control!

OKX_API_KEY=your_api_key_here
OKX_API_SECRET=your_api_secret_here
OKX_PASSPHRASE=your_passphrase_here

# Optional: Set to '0' for live trading, '1' for demo trading
OKX_FLAG=1
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,9 @@ build/

### VS Code ###
.vscode/
id_rsa*
id_rsa*

# Environment files
.env
.env.local
.env.*.local
4 changes: 3 additions & 1 deletion okx/Account.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,10 @@ def get_instruments(self, instType='', ugly='', instFamily='', instId=''):
return self._request_with_params(GET, GET_INSTRUMENTS, params)

# Get the maximum loan of isolated MARGIN
def get_max_loan(self, instId, mgnMode, mgnCcy=''):
def get_max_loan(self, instId, mgnMode, mgnCcy='', tradeQuoteCcy=None):
params = {'instId': instId, 'mgnMode': mgnMode, 'mgnCcy': mgnCcy}
if tradeQuoteCcy is not None:
params['tradeQuoteCcy'] = tradeQuoteCcy
return self._request_with_params(GET, MAX_LOAN, params)

# Get Fee Rates
Expand Down
8 changes: 6 additions & 2 deletions okx/Grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ def __init__(self, api_key='-1', api_secret_key='-1', passphrase='-1', use_serve
OkxClient.__init__(self, api_key, api_secret_key, passphrase, use_server_time, flag, domain, debug, proxy)

def grid_order_algo(self, instId='', algoOrdType='', maxPx='', minPx='', gridNum='', runType='', tpTriggerPx='',
slTriggerPx='', tag='', quoteSz='', baseSz='', sz='', direction='', lever='', basePos=''):
slTriggerPx='', tag='', quoteSz='', baseSz='', sz='', direction='', lever='', basePos='', tradeQuoteCcy=None):
params = {'instId': instId, 'algoOrdType': algoOrdType, 'maxPx': maxPx, 'minPx': minPx, 'gridNum': gridNum,
'runType': runType, 'tpTriggerPx': tpTriggerPx, 'slTriggerPx': slTriggerPx, 'tag': tag,
'quoteSz': quoteSz, 'baseSz': baseSz, 'sz': sz, 'direction': direction, 'lever': lever,
'basePos': basePos}
if tradeQuoteCcy is not None:
params['tradeQuoteCcy'] = tradeQuoteCcy
return self._request_with_params(POST, GRID_ORDER_ALGO, params)

def grid_amend_order_algo(self, algoId='', instId='', slTriggerPx='', tpTriggerPx=''):
Expand Down Expand Up @@ -79,11 +81,13 @@ def grid_ai_param(self, algoOrdType='', instId='', direction='', duration=''):

# - Place recurring buy order
def place_recurring_buy_order(self, stgyName='', recurringList=[], period='', recurringDay='', recurringTime='',
timeZone='', amt='', investmentCcy='', tdMode='', algoClOrdId='', tag=''):
timeZone='', amt='', investmentCcy='', tdMode='', algoClOrdId='', tag='', tradeQuoteCcy=None):
params = {'stgyName': stgyName, 'recurringList': recurringList, 'period': period, 'recurringDay': recurringDay,
'recurringTime': recurringTime,
'timeZone': timeZone, 'amt': amt, 'investmentCcy': investmentCcy, 'tdMode': tdMode,
'algoClOrdId': algoClOrdId, 'tag': tag}
if tradeQuoteCcy is not None:
params['tradeQuoteCcy'] = tradeQuoteCcy
return self._request_with_params(POST, PLACE_RECURRING_BUY_ORDER, params)

# - Amend recurring buy order
Expand Down
22 changes: 16 additions & 6 deletions okx/Trade.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@ 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='', stpMode='', attachAlgoOrds=None, pxUsd='', pxVol='', banAmend='', tradeQuoteCcy=''):
reduceOnly='', tgtCcy='', stpMode='', attachAlgoOrds=None, pxUsd='', pxVol='', banAmend='', tradeQuoteCcy=None, pxAmendType=None):
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, 'stpMode': stpMode, 'pxUsd': pxUsd, 'pxVol': pxVol, 'banAmend': banAmend, 'tradeQuoteCcy': tradeQuoteCcy}
'tgtCcy': tgtCcy, 'stpMode': stpMode, 'pxUsd': pxUsd, 'pxVol': pxVol, 'banAmend': banAmend}
if tradeQuoteCcy is not None:
params['tradeQuoteCcy'] = tradeQuoteCcy
if pxAmendType is not None:
params['pxAmendType'] = pxAmendType
params['attachAlgoOrds'] = attachAlgoOrds
return self._request_with_params(POST, PLACR_ORDER, params)

Expand All @@ -35,11 +39,13 @@ def cancel_multiple_orders(self, orders_data):
# Amend Order
def amend_order(self, instId, cxlOnFail='', ordId='', clOrdId='', reqId='', newSz='', newPx='', newTpTriggerPx='',
newTpOrdPx='', newSlTriggerPx='', newSlOrdPx='', newTpTriggerPxType='', newSlTriggerPxType='',
attachAlgoOrds='', newTriggerPx='', newOrdPx=''):
attachAlgoOrds='', newTriggerPx='', newOrdPx='', pxAmendType=None):
params = {'instId': instId, 'cxlOnFail': cxlOnFail, 'ordId': ordId, 'clOrdId': clOrdId, 'reqId': reqId,
'newSz': newSz, 'newPx': newPx, 'newTpTriggerPx': newTpTriggerPx, 'newTpOrdPx': newTpOrdPx,
'newSlTriggerPx': newSlTriggerPx, 'newSlOrdPx': newSlOrdPx, 'newTpTriggerPxType': newTpTriggerPxType,
'newSlTriggerPxType': newSlTriggerPxType, 'newTriggerPx': newTriggerPx, 'newOrdPx': newOrdPx}
if pxAmendType is not None:
params['pxAmendType'] = pxAmendType
params['attachAlgoOrds'] = attachAlgoOrds
return self._request_with_params(POST, AMEND_ORDER, params)

Expand Down Expand Up @@ -95,8 +101,8 @@ def place_algo_order(self, instId='', tdMode='', side='', ordType='', sz='', ccy
pxSpread='',
szLimit='', pxLimit='', timeInterval='', tpTriggerPxType='', slTriggerPxType='',
callbackRatio='', callbackSpread='', activePx='', tag='', triggerPxType='', closeFraction=''
, quickMgnType='', algoClOrdId='', tradeQuoteCcy='', tpOrdKind='', cxlOnClosePos=''
, chaseType='', chaseVal='', maxChaseType='', maxChaseVal='', attachAlgoOrds=[]):
, quickMgnType='', algoClOrdId='', tradeQuoteCcy=None, tpOrdKind='', cxlOnClosePos=''
, chaseType='', chaseVal='', maxChaseType='', maxChaseVal='', attachAlgoOrds=[], pxAmendType=None):
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,
Expand All @@ -105,9 +111,13 @@ def place_algo_order(self, instId='', tdMode='', side='', ordType='', sz='', ccy
'pxSpread': pxSpread, 'tpTriggerPxType': tpTriggerPxType, 'slTriggerPxType': slTriggerPxType,
'callbackRatio': callbackRatio, 'callbackSpread': callbackSpread, 'activePx': activePx,
'tag': tag, 'triggerPxType': triggerPxType, 'closeFraction': closeFraction,
'quickMgnType': quickMgnType, 'algoClOrdId': algoClOrdId, 'tradeQuoteCcy': tradeQuoteCcy,
'quickMgnType': quickMgnType, 'algoClOrdId': algoClOrdId,
'tpOrdKind': tpOrdKind, 'cxlOnClosePos': cxlOnClosePos, 'chaseType': chaseType, 'chaseVal': chaseVal,
'maxChaseType': maxChaseType, 'maxChaseVal': maxChaseVal, 'attachAlgoOrds': attachAlgoOrds}
if tradeQuoteCcy is not None:
params['tradeQuoteCcy'] = tradeQuoteCcy
if pxAmendType is not None:
params['pxAmendType'] = pxAmendType
return self._request_with_params(POST, PLACE_ALGO_ORDER, params)

# Cancel Algo Order
Expand Down
34 changes: 34 additions & 0 deletions test/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""
Test configuration module - loads API credentials from environment variables.

Usage:
from test.config import get_api_credentials

api_key, api_secret, passphrase, flag = get_api_credentials()
"""
import os
from pathlib import Path

# Try to load from .env file if python-dotenv is available
try:
from dotenv import load_dotenv
env_path = Path(__file__).parent.parent / '.env'
load_dotenv(env_path)
except ImportError:
pass # python-dotenv not installed, rely on system environment variables


def get_api_credentials():
"""
Get API credentials from environment variables.

Returns:
tuple: (api_key, api_secret, passphrase, flag)
"""
api_key = os.getenv('OKX_API_KEY', '')
api_secret = os.getenv('OKX_API_SECRET', '')
passphrase = os.getenv('OKX_PASSPHRASE', '')
flag = os.getenv('OKX_FLAG', '1') # Default to demo trading

return api_key, api_secret, passphrase, flag

18 changes: 12 additions & 6 deletions test/AccountTest.py → test/test_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
from loguru import logger

from okx import Account
from test.config import get_api_credentials


class AccountTest(unittest.TestCase):
def setUp(self):
api_key = 'your_apiKey'
api_secret_key = 'your_secretKey'
passphrase = 'your_secretKey'
self.AccountAPI = Account.AccountAPI(api_key, api_secret_key, passphrase, flag='1')
api_key, api_secret_key, passphrase, flag = get_api_credentials()
self.AccountAPI = Account.AccountAPI(api_key, api_secret_key, passphrase, flag=flag)

# '''
# POSITIONS_HISTORY = '/api/v5/account/positions-history' #need add
Expand Down Expand Up @@ -146,8 +145,15 @@ def setUp(self):
# logger.info(f'{self.AccountAPI.set_auto_repay(autoRepay=True)}')
# def test_spot_borrow_repay_history(self):
# logger.debug(self.AccountAPI.spot_borrow_repay_history(ccy="USDT",type="auto_borrow",after="1597026383085"))
def test_set_auto_earn(self):
logger.debug(self.AccountAPI.set_auto_earn(ccy="USDT", action="turn_on", earnType='0'))
# def test_set_auto_earn(self):
# logger.debug(self.AccountAPI.set_auto_earn(ccy="USDT", action="turn_on", earnType='0'))
#def test_get_max_loan_with_trade_quote_ccy(self):
# logger.debug(self.AccountAPI.get_max_loan(
# instId="BTC-USDT",
# mgnMode="isolated",
# mgnCcy="USDT",
# tradeQuoteCcy="USDT"
# ))

if __name__ == '__main__':
unittest.main()
9 changes: 5 additions & 4 deletions test/BlockTradingTest.py → test/test_block_trading.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@

import unittest
from okx import BlockTrading
from test.config import get_api_credentials


class BlockTradingTest(unittest.TestCase):
def setUp(self):
api_key = 'your_apiKey'
api_secret_key = 'your_secretKey'
passphrase = 'your_secretKey'
self.BlockTradingAPI = BlockTrading.BlockTradingAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag='1')
api_key, api_secret_key, passphrase, flag = get_api_credentials()
self.BlockTradingAPI = BlockTrading.BlockTradingAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag=flag)

"""
def test_get_counter_parties(self):
Expand Down
11 changes: 6 additions & 5 deletions test/ConvertTest.py → test/test_convert.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import unittest
from ..okx import Convert
from okx import Convert
from test.config import get_api_credentials


class ConvertTest(unittest.TestCase):
def setUp(self):
api_key = 'your_apiKey'
api_secret_key = 'your_secretKey'
passphrase = 'your_secretKey'
self.ConvertAPI = Convert.ConvertAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag='1')
api_key, api_secret_key, passphrase, flag = get_api_credentials()
self.ConvertAPI = Convert.ConvertAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag=flag)
'''

def test_get_currencies(self):
Expand Down
8 changes: 4 additions & 4 deletions test/CopyTradingTest.py → test/test_copy_trading.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import unittest
from okx import CopyTrading
from test.config import get_api_credentials


class CopyTradingTest(unittest.TestCase):
def setUp(self):
api_key = 'your_apiKey'
api_secret_key = 'your_secretKey'
passphrase = 'your_secretKey'
api_key, api_secret_key, passphrase, flag = get_api_credentials()
self.StackingAPI = CopyTrading.CopyTradingAPI(api_key, api_secret_key, passphrase, use_server_time=False,
flag='0')
flag=flag)

# def test_get_existing_leading_positions(self):
# print(self.StackingAPI.get_existing_leading_positions(instId='DOGE-USDT-SWAP'))
Expand Down
8 changes: 4 additions & 4 deletions test/EthStakingTest.py → test/test_eth_staking.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import unittest
from okx.Finance import EthStaking
from test.config import get_api_credentials


class EthStakingTest(unittest.TestCase):
def setUp(self):
api_key = 'your_apiKey'
api_secret_key = 'your_secretKey'
passphrase = 'your_secretKey'
self.StackingAPI = EthStaking.EthStakingAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag='1')
api_key, api_secret_key, passphrase, flag = get_api_credentials()
self.StackingAPI = EthStaking.EthStakingAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag=flag)

def test_eth_product_info(self):
print(self.StackingAPI.eth_product_info())
Expand Down
8 changes: 4 additions & 4 deletions test/FlexibleLoanTest.py → test/test_flexible_loan.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import unittest
from okx.Finance import FlexibleLoan
from test.config import get_api_credentials


class FlexibleLoanTest(unittest.TestCase):
def setUp(self):
api_key = 'your_apiKey'
api_secret_key = 'your_secretKey'
passphrase = 'your_secretKey'
self.FlexibleLoanAPI = FlexibleLoan.FlexibleLoanAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag='1')
api_key, api_secret_key, passphrase, flag = get_api_credentials()
self.FlexibleLoanAPI = FlexibleLoan.FlexibleLoanAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag=flag)

def test_borrow_currencies(self):
print(self.FlexibleLoanAPI.borrow_currencies())
Expand Down
8 changes: 4 additions & 4 deletions test/FundingTest.py → test/test_funding.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@

import unittest
from okx import Funding
from test.config import get_api_credentials


class FundingTest(unittest.TestCase):
def setUp(self):
api_key = 'your_apiKey'
api_secret_key = 'your_secretKey'
passphrase = 'your_secretKey'
self.FundingAPI = Funding.FundingAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag='0')
api_key, api_secret_key, passphrase, flag = get_api_credentials()
self.FundingAPI = Funding.FundingAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag=flag)
"""
CANCEL_WITHDRAWAL = '/api/v5/asset/cancel-withdrawal' #need add
CONVERT_DUST_ASSETS = '/api/v5/asset/convert-dust-assets' #need add
Expand Down
34 changes: 29 additions & 5 deletions test/GridTest.py → test/test_grid.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@

import unittest
from okx import Grid
from test.config import get_api_credentials


class GridTest(unittest.TestCase):
def setUp(self):
api_key = 'your_apiKey'
api_secret_key = 'your_secretKey'
passphrase = 'your_secretKey'
self.GridAPI = Grid.GridAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag='1', debug=False)
api_key, api_secret_key, passphrase, flag = get_api_credentials()
self.GridAPI = Grid.GridAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag=flag, debug=False)
"""
GRID_COMPUTE_MARIGIN_BALANCE = '/api/v5/tradingBot/grid/compute-margin-balance'
GRID_MARGIN_BALANCE = '/api/v5/tradingBot/grid/margin-balance'
Expand Down Expand Up @@ -79,7 +79,31 @@ def test_withdrawl_profits(self):
# def test_get_recurring_buy_sub_orders(self):
# print(self.GridAPI.get_recurring_buy_sub_orders(algoId="581191143417970688"))

#581191143417970688
#def test_grid_order_algo_with_trade_quote_ccy(self):
# print(self.GridAPI.grid_order_algo(
# instId="BTC-USDT",
# algoOrdType="grid",
# maxPx="45000",
# minPx="20000",
# gridNum="100",
# runType="1",
# quoteSz="50",
# tradeQuoteCcy="USDT"
# ))

#def test_place_recurring_buy_order_with_trade_quote_ccy(self):
# print(self.GridAPI.place_recurring_buy_order(
# stgyName="test_strategy",
# recurringList=[{'ccy': 'ETH', 'ratio': '1'}],
# period="daily",
# recurringDay='1',
# recurringTime='0',
# timeZone='8',
# amt='100',
# investmentCcy='USDT',
# tdMode='cash',
# tradeQuoteCcy="USDT"
# ))

if __name__ == '__main__':
unittest.main()
9 changes: 5 additions & 4 deletions test/MarketTest.py → test/test_market.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@
BLOCK_TRADES = '/api/v5/market/block-trades'#need to add
'''

from test.config import get_api_credentials


class MarketAPITest(unittest.TestCase):
def setUp(self):
api_key = 'your_apiKey'
api_secret_key = 'your_secretKey'
passphrase = 'your_secretKey'
self.MarketApi = MarketData.MarketAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag='1')
api_key, api_secret_key, passphrase, flag = get_api_credentials()
self.MarketApi = MarketData.MarketAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag=flag)
'''

def test_index_component(self):
Expand Down
9 changes: 5 additions & 4 deletions test/PublicDataTest.py → test/test_public_data.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import unittest
from okx import PublicData
from test.config import get_api_credentials


class publicDataTest(unittest.TestCase):
def setUp(self):
api_key = 'your_apiKey'
api_secret_key = 'your_secretKey'
passphrase = 'your_secretKey'
self.publicDataApi = PublicData.PublicAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag='1')
api_key, api_secret_key, passphrase, flag = get_api_credentials()
self.publicDataApi = PublicData.PublicAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag=flag)
'''
TestCase For:
INTEREST_LOAN = '/api/v5/public/interest-rate-loan-quota' #need to add
Expand Down
Loading
Loading