first commit

This commit is contained in:
shiyao.zhu@okg.com 2022-10-12 10:53:50 +08:00
commit b6cef36dba
52 changed files with 2920 additions and 0 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

33
.gitignore vendored Normal file
View File

@ -0,0 +1,33 @@
README.md
build/
dist/
python_okx.egg-info/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
setup.py

80
Test/AccountTest.py Normal file
View File

@ -0,0 +1,80 @@
import unittest
from ..okx import Account
class AccountTest(unittest.TestCase):
def setUp(self):
api_key = 'ef06bf27-6a01-4797-b801-e3897031e45d'
api_secret_key = 'D3620B2660203350EEE80FDF5BE0C960'
passphrase = 'Beijing123'
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
GET_PM_LIMIT = '/api/v5/account/position-tiers' #need add
ACCOUNT_RISK = '/api/v5/account/risk-state' #need add
def test_account_risk(self):
print(self.AccountAPI.get_account_risk())
def test_get_pm_limit(self):
print(self.AccountAPI.get_pm_limit("SWAP","BTC-USDT"))
#positions-history
def test_get_positions_history(self):
print(self.AccountAPI.get_positions_history())
def test_get_user_config(self):
print(self.AccountAPI.get_account_config())
def test_get_positions(self):
print(self.AccountAPI.get_positions("SWAP"))
def test_get_balance(self):
print(self.AccountAPI.get_account())
def test_get_positions_risk(self):
print(self.AccountAPI.get_position_risk("SWAP"))
def test_get_bills(self):
print(self.AccountAPI.get_bills_detail())
def test_get_bills_arch(self):
print(self.AccountAPI.get_bills_details())
def test_set_position_mode(self):
print(self.AccountAPI.set_position_mode("long_short_mode"))
def test_set_leverage(self):
print(self.AccountAPI.set_leverage(instId="BTC-USDT",lever="5",mgnMode="isolated"))
def test_get_max_avaliable_size(self):
print(self.AccountAPI.get_max_avail_size(instId="BTC-USDT",tdMode="cash"))
def test_get_max_size(self):
print(self.AccountAPI.get_maximum_trade_size(instId="BTC-USDT",tdMode="cash"))
def test_get_positions(self):
print(self.AccountAPI.get_positions("MARGIN"))
def test_set_margin_balance(self):
print(self.AccountAPI.Adjustment_margin(instId="BTC-USDT",posSide="net",type="add",amt="1"))
def test_get_lev_info(self):
print(self.AccountAPI.get_leverage("BTC-USDT","cross"));
def test_get_max_loan(self):
print(self.AccountAPI.get_max_loan("BTC-USDT","cross","USDT"))
def test_get_trade_fee(self):
print(self.AccountAPI.get_fee_rates("SPOT"))
def test_get_insterested_accrued(self):
print(self.AccountAPI.get_interest_accrued())
def test_get_interestred_rate(self):
print(self.AccountAPI.get_interest_rate())
def test_set_greeks(self):
print(self.AccountAPI.set_greeks("BS"))
def test_set_isolated_mode(self):
print(self.AccountAPI.set_isolated_mode("automatic","MARGIN"))
def test_set_max_withdraw(self):
print(self.AccountAPI.get_max_withdrawal("USDT"))
def test_borrow_repay(self):
print(self.AccountAPI.borrow_repay("BTC","borrow","1.0"))
def test_borrow_repay_history(self):
print(self.AccountAPI.get_borrow_repay_history())
def test_get_interest_limits(self):
print(self.AccountAPI.get_interest_limits())
def test_simulated_margin(self):
print(self.AccountAPI.get_simulated_margin())
def test_get_greeks(self):
print(self.AccountAPI.get_greeks())
'''
def test_simulated_margin(self):
print(self.AccountAPI.get_simulated_margin())
if __name__ == '__main__':
unittest.main()

48
Test/BlockTradingTest.py Normal file
View File

@ -0,0 +1,48 @@
import unittest
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')
"""
def test_get_counter_parties(self):
print(self.BlockTradingAPI.counterparties())
def test_create_rfqs(self):
counterparties=['HWZ']
legs =[{
'instId':"BTC-USDT",
'sz':'25',
'side':'buy'
}]
print(self.BlockTradingAPI.create_rfq(counterparties,legs = legs))
def test_cancel_rfq(self):###'rfqId': '3I1MK3O'
print(self.BlockTradingAPI.cancel_rfq(rfqId='3I1MK3O'))
def test_cancel_batch_rfqs(self):
#3I1MK40
#3I1MK48
print(self.BlockTradingAPI.cancel_batch_rfqs(["3I1MK40","3I1MK48"]))
def test_cancel_all_rfqs(self):
print(self.BlockTradingAPI.cancel_all_rfqs())
def test_execute_quotes(self):
print(self.BlockTradingAPI.execute_quote("3I1MJE0","AC1233"))
def test_create_quotes(self):
print(self.BlockTradingAPI.create_quote("3I1MJE0",))
def test_get_rfqs(self):
print(self.BlockTradingAPI.get_rfqs())
def test_get_quotes(self):
print(self.BlockTradingAPI.get_quotes())
def test_get_public_trades(self):
print(self.BlockTradingAPI.get_public_trades())
def test_get_trade(self):
print(self.BlockTradingAPI.get_trades())
"""
def test_get_public_trades(self):
print(self.BlockTradingAPI.get_public_trades())
if __name__ == '__main__':
unittest.main()

70
Test/BrokerTest.py Normal file
View File

@ -0,0 +1,70 @@
import unittest
from ..okx import NDBroker
class BrokerTest(unittest.TestCase):
def setUp(self):
'''
52c37310-a8b0-454a-8191-3250acff2626
EC37534156E6B8C32E78FE8D8C1D506B
Hanhao0.0
'''
api_key = '52c37310-a8b0-454a-8191-3250acff2626'
api_secret_key = 'EC37534156E6B8C32E78FE8D8C1D506B'
passphrase = 'Hanhao0.0'
self.NDBrokerAPI = NDBroker.NDBrokerAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag='1')
'''
def test_get_broker_info(self):
result = self.NDBrokerAPI.get_broker_info()
print(result)
def test_create_subAccount(self):
print(self.NDBrokerAPI.create_subaccount("",""))
#{'code': '0', 'data': [{'acctLv': '1', 'label': 'unitTest', 'subAcct': 'unitTest1298', 'ts': '1660789737257', 'uid': '346146586377719875'}], 'msg': ''}
def test_get_subaccount_info(self):
print(self.NDBrokerAPI.get_subaccount_info())
def test_subaccount_create_apikey(self):
print(self.NDBrokerAPI.create_subaccount_apikey("unitTest1298",'test2222',"114514A.bc","142.112.128.63","trade"))
#{'code': '0', 'data': [{'apiKey': 'faf24bd1-dc25-45ab-9f78-ebfea58614bd', 'ip': '142.112.128.63', 'label': 'test2222', 'passphrase': '114514A.bc', 'perm': 'read_only,trade', 'secretKey': 'DB4F607380AA04313BB0DEDBFE576FF1', 'subAcct': 'unitTest1298', 'ts': '1660793476848'}], 'msg': ''}
def test_subaccount_get_apikey(self):
print(self.NDBrokerAPI.get_subaccount_apikey("unitTest1298","faf24bd1-dc25-45ab-9f78-ebfea58614bd"))
def test_delete_subAccount(self):
print(self.NDBrokerAPI.delete_subaccount("hanhaoBras1234"))
def test_modifiy_subaccount_apikey(self):
print(self.NDBrokerAPI.reset_subaccount_apikey("unitTest1298","faf24bd1-dc25-45ab-9f78-ebfea58614bd","csuihssssiani",perm="trade",ip = "192.168.1.1"))
def test_delete_subaccount_apikey(self):
print(self.NDBrokerAPI.delete_subaccount_apikey("unitTest1298","faf24bd1-dc25-45ab-9f78-ebfea58614bd"))
def test_set_account_lv(self):
print(self.NDBrokerAPI.set_subaccount_level("unitTest1298","4"))
def test_delete_subaccount_apikey(self):
print(self.NDBrokerAPI.delete_subaccount_apikey("unitTest1298","faf24bd1-dc25-45ab-9f78-ebfea58614bd"))
def test_set_fee_rate(self):
print(self.NDBrokerAPI.set_subaccount_fee_rate("unitTest1298","SPOT","absolute","90","90"))
def test_create_desposit(self):
print(self.NDBrokerAPI.create_subaccount_deposit_address("unitTest1298","ETH"))
def test_rebate_daily(self):
print(self.NDBrokerAPI.get_rebate_daily())
def test_create_rebate_per_order(self):
print(self.NDBrokerAPI.generate_rebate_per_orders("20220501","20220801"))
'''
def test_get_rebate_per_order(self):
print(self.NDBrokerAPI.get_rebate_per_orders("false",begin="20220501",end = "20220801"))
if __name__ == '__main__':
unittest.main()

30
Test/ConvertTest.py Normal file
View File

@ -0,0 +1,30 @@
import unittest
from ..okx import Convert
class ConvertTest(unittest.TestCase):
def setUp(self):
api_key = 'ef06bf27-6a01-4797-b801-e3897031e45d'
api_secret_key = 'D3620B2660203350EEE80FDF5BE0C960'
passphrase = 'Beijing123'
self.ConvertAPI = Convert.ConvertAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag='1')
'''
def test_get_currencies(self):
print(self.ConvertAPI.get_currencies())
def test_get_currency_pair(self):
print(self.ConvertAPI.get_currency_pair("USDT","BTC"))
def test_query_estimate(self):
print(self.ConvertAPI.estimate_quote("BTC","USDT","buy","0.1","BTC"))
def test_query_estimate(self):
print(self.ConvertAPI.estimate_quote("BTC", "USDT", "buy", "0.1", "BTC"))
def test_convert_trade(self):
print(self.ConvertAPI.convert_trade('quotersBTC-USDT16618704214351712','BTC',"USDT",'buy','0.1','BTC'))
def test_get_convert_history(self):
print(self.ConvertAPI.get_convert_history())
'''
#def test_query_estimate(self):
# print(self.ConvertAPI.estimate_quote("BTC", "USDT", "buy", "0.1", "BTC"))
if __name__ == '__main__':
unittest.main()

66
Test/FundingTest.py Normal file
View File

@ -0,0 +1,66 @@
import unittest
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')
"""
CANCEL_WITHDRAWAL = '/api/v5/asset/cancel-withdrawal' #need add
CONVERT_DUST_ASSETS = '/api/v5/asset/convert-dust-assets' #need add
ASSET_VALUATION = '/api/v5/asset/asset-valuation' #need add
GET_SAVING_BALANCE = '/api/v5/asset/saving-balance' #need to add
def test_asset_evluation(self):
print(self.FundingAPI.get_asset_valuation("USDT"))
def test_dust_convert_asset(self):
print(self.FundingAPI.convert_dust_assets(["USDT"]))
def test_saving_balance(self):
print(self.FundingAPI.get_saving_balance())
def test_asset_get_currency(self):
print(self.FundingAPI.get_currency())
def test_get_balance(self):
print(self.FundingAPI.get_balances())
def test_transfer(self):
print(self.FundingAPI.funds_transfer("USDT","100","6","18"))
def test_transfer_state(self):
print(self.FundingAPI.transfer_state("11"))
def test_get_bills(self):
print(self.FundingAPI.get_bills())
def test_deposit_lighting(self):
print(self.FundingAPI.get_deposit_lightning("BTC","10"))
def test_get_deposit_address(self):
print(self.FundingAPI.get_deposit_address("BTC"))
def test_get_deposit_history(self):
print(self.FundingAPI.get_deposit_history())
def test_withdraw(self):
print(self.FundingAPI.coin_withdraw(ccy="USDT",amt = '10.0',dest = '3',toAddr="1391224291",fee="10"))
def test_lighting_withdrawl(self):
print(self.FundingAPI.withdrawal_lightning("BTC","jdsnjvhofhenogvne",memo="222"))
def test_cancel_withdrawl(self):
print(self.FundingAPI.cancel_withdrawal("sdhiadhsfdjknvjdaodns"))
def test_get_withdrawal_history(self):
print(self.FundingAPI.get_withdrawal_history())
def test_purchase_redempt(self):
print(self.FundingAPI.purchase_redempt("BTC",'1.0','purchase','0.1'))
def test_set_lending_rate(self):
print(self.FundingAPI.set_lending_rate("USDT","0.1"))
def test_get_lending_history(self):
print(self.FundingAPI.get_lending_history(ccy="USDT"))
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_summary(self):
print(self.FundingAPI.get_lending_rate_summary('BTC'))
def test_get_lending_rate_history(self):
print(self.FundingAPI.get_lending_rate_history())
if __name__ == '__main__':
unittest.main()

55
Test/GridTest.py Normal file
View File

@ -0,0 +1,55 @@
import unittest
from ..okx import Grid
class GridTest(unittest.TestCase):
def setUp(self):
api_key = 'ef06bf27-6a01-4797-b801-e3897031e45d'
api_secret_key = 'D3620B2660203350EEE80FDF5BE0C960'
passphrase = 'Beijing123'
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'
GRID_MARGIN_BALANCE = '/api/v5/tradingBot/grid/margin-balance'
GRID_AI_PARAM = '/api/v5/tradingBot/grid/ai-param'
def test_ai_param(self):
print(self.GridAPI.grid_ai_param("grid","BTC-USDT"))
def test_order_algo(self):
print(self.GridAPI.grid_order_algo("BTC-USDT","grid","45000","20000","100","1",quoteSz="50"))
#479973849967362048
def test_grid_margin_balance(self):
print(self.GridAPI.grid_adjust_margin_balance())
def test_compute_margin_balance(self):
print(self.GridAPI.grid_compute_margin_balance("479978879210491904","add","100"))
def test_pending_grid_order(self):
print(self.GridAPI.grid_orders_algo_pending("grid"))
def test_amend_order_algo(self):
print(self.GridAPI.grid_amend_order_algo('485238792325173248','BTC-USDT-SWAP',tpTriggerPx='50000'))
def test_stop_order_algo(self):
print(self.GridAPI.grid_stop_order_algo('485238792325173248','BTC-USDT-SWAP','contract_grid','1'))
def test_pending_grid_order(self):
print(self.GridAPI.grid_orders_algo_pending("grid"))
def test_algo_history(self):
print(self.GridAPI.grid_orders_algo_history('contract_grid'))
def test_orders_algo_details(self):
print(self.GridAPI.grid_orders_algo_details('contract_grid','485238792325173248'))
def test_get_sub_orders(self):
print(self.GridAPI.grid_sub_orders('485238792325173248','contract_grid','filled'))
def test_order_algo2(self):
print(self.GridAPI.grid_order_algo("BTC-USDT-SWAP","contract_grid","45000","20000","100","1",sz='3000',direction='long',lever='3.0'))
def test_get_positions(self):
print(self.GridAPI.grid_positions('contract_grid','485379848832286720'))
def test_withdrawl_profits(self):
print(self.GridAPI.grid_withdraw_income('11111'))
def test_withdrawl_profits(self):
print(self.GridAPI.grid_withdraw_income('485380442313723904'))
"""
def test_order_algo(self):
print(self.GridAPI.grid_order_algo("BTC-USDT","grid","45000","20000","100","1",quoteSz="50"))
if __name__ == '__main__':
unittest.main()

65
Test/MarketTest.py Normal file
View File

@ -0,0 +1,65 @@
import unittest
from ..okx import MarketData
'''
ORACLE = '/api/v5/market/open-oracle' #need to update? if it is open oracle
INDEX_COMPONENTS = '/api/v5/market/index-components' #need to add
EXCHANGE_RATE = '/api/v5/market/exchange-rate' #need to add
HISTORY_TRADES = '/api/v5/market/history-trades' #need to add
BLOCK_TICKERS = '/api/v5/market/block-tickers' #need to add
BLOCK_TICKER = '/api/v5/market/block-ticker'#need to add
BLOCK_TRADES = '/api/v5/market/block-trades'#need to add
'''
class MarketAPITest(unittest.TestCase):
def setUp(self):
api_key = 'ef06bf27-6a01-4797-b801-e3897031e45d'
api_secret_key = 'D3620B2660203350EEE80FDF5BE0C960'
passphrase = 'Beijing123'
self.MarketApi = MarketData.MarketAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag='1')
'''
def test_oracle(self):
print(self.MarketApi.get_oracle())
def test_index_component(self):
print(self.MarketApi.get_index_components("BTC-USDT"))
def test_exchange_rate(self):
print(self.MarketApi.get_exchange_rate())
def test_history_trades(self):
print(self.MarketApi.get_history_trades("BTC-USDT"))
def test_block_tickers(self):
print(self.MarketApi.get_block_tickers("SPOT"))
def test_block_ticker(self):
print(self.MarketApi.get_block_ticker("BTC-USD-SWAP"))
def test_block_trades(self):
print(self.MarketApi.get_block_trades("BTC-USDT"))
def test_get_tickers(self):
print(self.MarketApi.get_tickers('SPOT'))
def test_get_ticker(self):
print(self.MarketApi.get_ticker('BTC-USD-SWAP'))
def test_index_ticker(self):
print(self.MarketApi.get_index_ticker('USDT'))
def test_get_books(self):
print(self.MarketApi.get_orderbook('BTC-USDT'))
def test_get_candles(self):
print(self.MarketApi.get_candlesticks('BTC-USDT'))
def test_get_candles_history(self):
print(self.MarketApi.get_history_candlesticks('BTC-USDT'))
def test_get_index_candles(self):
print(self.MarketApi.get_index_candlesticks('BTC-USD'))
def test_get_market_price_candles(self):
print(self.MarketApi.get_mark_price_candlesticks('BTC-USD-SWAP'))
def test_get_trade(self):
print(self.MarketApi.get_trades('BTC-USDT'))
def test_get_history_trades(self):
print(self.MarketApi.get_history_trades('BTC-USDT'))
def test_get_platform_24_volume(self):
print(self.MarketApi.get_volume())
'''
if __name__ == "__main__":
unittest.main()

57
Test/PublicDataTest.py Normal file
View File

@ -0,0 +1,57 @@
import unittest
from ..okx import PublicData
class publicDataTest(unittest.TestCase):
def setUp(self):
api_key = 'ef06bf27-6a01-4797-b801-e3897031e45d'
api_secret_key = 'D3620B2660203350EEE80FDF5BE0C960'
passphrase = 'Beijing123'
self.publicDataApi = PublicData.PublicAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag='1')
'''
TestCase For:
INTEREST_LOAN = '/api/v5/public/interest-rate-loan-quota' #need to add
UNDERLYING = '/api/v5/public/underlying' #need to add
VIP_INTEREST_RATE_LOAN_QUOTA = '/api/v5/public/vip-interest-rate-loan-quota' #need to add
INSURANCE_FUND = '/api/v5/public/insurance-fund'#need to add
CONVERT_CONTRACT_COIN = '/api/v5/public/convert-contract-coin' #need to add
def test_interest_loan(self):
print(self.publicDataApi.get_interest_rate_loan_quota())
def test_get_underlying(self):
print(self.publicDataApi.get_underlying("SWAP"))
def test_get_vip_loan(self):
print(self.publicDataApi.get_vip_interest_rate_loan_quota())
def test_insurance_fund(self):
print(self.publicDataApi.get_insurance_fund("SWAP",uly= "BTC-USD"))
def test_convert_contract_coin(self):
print(self.publicDataApi.get_convert_contract_coin(instId="BTC-USD-SWAP",sz = "1",px = "27000"))
def test_get_instruments(self):
print(self.publicDataApi.get_instruments("SPOT"))
def test_delivery_exercise_history(self):
print(self.publicDataApi.get_deliver_history("FUTURES","BTC-USD"))
def test_get_open_interest(self):
print(self.publicDataApi.get_open_interest("SWAP"))
def test_get_funding_rate(self):
print(self.publicDataApi.get_funding_rate("BTC-USD-SWAP"))
def test_get_funding_rate_history(self):
print(self.publicDataApi.funding_rate_history('BTC-USD-SWAP'))
def test_get_price_limited(self):
print(self.publicDataApi.get_price_limit("BTC-USD-SWAP"))
def test_get_opt_summary(self):
print(self.publicDataApi.get_opt_summary('BTC-USD'))
def test_estimate_price(self):
print(self.publicDataApi.get_estimated_price("BTC-USD-220831-17000-P"))
def test_get_discount_rate_interest(self):
print(self.publicDataApi.discount_interest_free_quota(ccy='ETH'))
def test_get_systime(self):
print(self.publicDataApi.get_system_time())
def test_get_liquid_order(self):
print(self.publicDataApi.get_liquidation_orders("SWAP",uly='BTC-USD',state='filled'))
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'))
if __name__ == '__main__':
unittest.main()

36
Test/StackingTest.py Normal file
View File

@ -0,0 +1,36 @@
import unittest
from ..okx import Status
class StackingTest(unittest.TestCase):
def setUp(self):
api_key = 'ef06bf27-6a01-4797-b801-e3897031e45d'
api_secret_key = 'D3620B2660203350EEE80FDF5BE0C960'
passphrase = 'Beijing123'
self.StackingAPI = Status.StackingAPI(api_key, api_secret_key, passphrase, use_server_time=False, flag='1')
'''
STACK_DEFI_OFFERS = '/api/v5/finance/staking-defi/offers'
STACK_DEFI_PURCHASE = '/api/v5/finance/staking-defi/purchase'
STACK_DEFI_REDEEM = '/api/v5/finance/staking-defi/redeem'
STACK_DEFI_CANCEL = '/api/v5/finance/staking-defi/cancel'
STACK_DEFI_ORDERS_ACTIVITY = '/api/v5/finance/staking-defi/orders-active'
STACK_DEFI_ORDERS_HISTORY = '/api/v5/finance/staking-defi/orders-history'
'''
def test_get_offers(self):
print(self.StackingAPI.get_offers(ccy="USDT"))
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()

40
Test/SubAccountTest.py Normal file
View File

@ -0,0 +1,40 @@
import unittest
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'
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
SET_TRSNSFER_OUT = '/api/v5/users/subaccount/set-transfer-out' #need to add
GET_ASSET_SUBACCOUNT_BALANCE = '/api/v5/asset/subaccount/balances' #need to add
def test_set_permission_transfer_out(self):
print(self.SubAccountApi.set_permission_transfer_out("tst123qwerq", "false"))
def test_entrust_subaccount_list(self):
print(self.SubAccountApi.get_entrust_subaccount_list())
def test_subaccount_funding_balance(self):
print(self.SubAccountApi.subaccount_funding_balance("unitTest1298"))
def test_get_subaccount_list(self):
print(self.SubAccountApi.view_list())
def test_modified_apiKey(self):
print(self.SubAccountApi.reset(''))
def test_get_subaccount_balance(self):
#zsynoaff02
print(self.SubAccountApi.balances('zsynoaff02'))
def test_get_subaccount_bills(self):
print(self.SubAccountApi.bills())
def test_subaccount_transfer(self):
print(self.SubAccountApi.subAccount_transfer())
def test_subaccount_transfer(self):
print(self.SubAccountApi.subAccount_transfer(ccy = 'BTC', amt = '1.0', froms= '18', to='18', fromSubAccount='zsynoaff02',toSubAccount = 'unitTest1298'))
'''
if __name__ == "__main__":
unittest.main()

121
Test/TradeTest.py Normal file
View File

@ -0,0 +1,121 @@
import unittest
from ..okx import Trade
class TradeTest(unittest.TestCase):
def setUp(self):
api_key = '35d8f27e-63cc-45bc-a578-45d76363d47f'
api_secret_key = '0B7C968025BC2D4D71CF74771EA0E15C'
passphrase = '123456'
self.tradeApi = Trade.TradeAPI(api_key, api_secret_key, passphrase, False, '1')
"""
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_cancel_order(self):
print(self.tradeApi.cancel_order(instId="ETH-USDT",ordId="480702180748558336"))
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))
#480702180748558336
def test_cancel_batch_orders(self):
data=[
{
'instId':"ETH-USDT",
'ordId':"480702885353881600"
},
{
'instId':"BTC-USDT",
'ordId':'480702885353881601'
}
]
print(self.tradeApi.cancel_multiple_orders(data))
def test_amend_order(self):
print(self.tradeApi.amend_order("BTC-USDT",ordId="480706017781743616",newSz="0.03"))
def test_amend_order_batch(self):
orderData = [
{
'instId':'ETH-USDT',
'ordId':'480707205436669952',
'newSz':'0.02'
},
{
'instId':'BTC-USDT',
'ordId':'480707205436669953',
'newPx':'3.0'
}
]
print(self.tradeApi.amend_multiple_orders(orderData))
def test_close_all_positions(self):
print(self.tradeApi.close_positions("BTC-USDT",mgnMode="cross"))
def test_get_order_info(self):
print(self.tradeApi.get_orders("ETH-USDT","480707205436669952"))
def test_get_order_pending(self):
print(self.tradeApi.get_order_list("SPOT"))
def test_get_order_history(self):
print(self.tradeApi.get_orders_history("SPOT"))
def test_get_order_histry_archive(self):
print(self.tradeApi.orders_history_archive("SPOT"))
def test_get_fills(self):
print(self.tradeApi.get_fills("SPOT"))
def test_get_fills_history(self):
print(self.tradeApi.get_fills_history("SPOT"))
def test_get_order_algo_pending(self):
print(self.tradeApi.order_algos_list('oco'))
def test_order_algo(self):
print(self.tradeApi.place_algo_order('BTC-USDT-SWAP', 'cross', side='buy', ordType='trigger', posSide='long',
sz='100', triggerPx='22000', triggerPxType ='index', orderPx='-1'))
def test_cancel_algos(self):
params = [{
'algoId': '485903392536264704',
'instId': 'BTC-USDT-SWAP'
}]
print(self.tradeApi.cancel_algo_order(params))
def test_cancel_adv_algos(self):
params = [{
'algoId': '485936482235191296',
'instId': 'BTC-USDT-SWAP'
}]
print(self.tradeApi.cancel_advance_algos(params)))
def test_orders_algo_pending(self):
print(self.tradeApi.order_algos_list(ordType='iceberg'))
def test_algo_order_history(self):
print(self.tradeApi.order_algos_history(algoId='485903392536264704',ordType='conditional'))
def test_get_easy_convert_list(self):
print(self.tradeApi.get_easy_convert_currency_list())
def test_easy_convert(self):
print(self.tradeApi.easy_convert(fromCcy=['BTC'],toCcy='OKB'))
def test_get_convert_history(self):
print(self.tradeApi.get_easy_convert_history())
def test_get_oneclick_repay_support_list(self):
print(self.tradeApi.get_oneclick_repay_list('cross'))
def test_oneclick_repay(self):
print(self.tradeApi.oneclick_repay(['BTC'],'USDT'))
"""
#485903392536264704
#485936482235191296
def test_oneclick_repay_history(self):
print(self.tradeApi.oneclick_repay_history())
if __name__=='__main__':
unittest.main()

37
Test/TradingDataTest.py Normal file
View File

@ -0,0 +1,37 @@
import unittest
from ..okx import TradingData
class TradingDataTest(unittest.TestCase):
def setUp(self):
api_key = '52c37310-a8b0-454a-8191-3250acff2626'
api_secret_key = 'EC37534156E6B8C32E78FE8D8C1D506B'
passphrase = 'Hanhao0.0'
self.TradingDataAPI = TradingData.TradingDataAPI(api_key, api_secret_key, passphrase, use_server_time=False,
flag='1')
"""
def test_get_support_coins(self):
print(self.TradingDataAPI.get_support_coin())
def test_get_taker_vol(self):
print(self.TradingDataAPI.get_taker_volume(ccy="BTC",instType="SPOT"))
def test_get_loan_ratio(self):
print(self.TradingDataAPI.get_margin_lending_ratio('ETH'))
def test_get_long_short_account(self):
print(self.TradingDataAPI.get_long_short_ratio('BTC'))
def test_get_contracts_vol_open(self):
print(self.TradingDataAPI.get_contracts_interest_volume(ccy="BTC"))
def test_get_option_vol_open(self):
print(self.TradingDataAPI.get_options_interest_volume(ccy="ETH"))
def test_get_option_ratio(self):
print(self.TradingDataAPI.get_put_call_ratio(ccy='BTC'))
def test_get_open_interest_expiry(self):
print(self.TradingDataAPI.get_interest_volume_expiry("BTC"))
def test_open_interest_volume_strike(self):
print(self.TradingDataAPI.get_interest_volume_strike(ccy="BTC",expTime="20220901"))
"""
def test_taker_block_vol(self):
print(self.TradingDataAPI.get_taker_flow(ccy='BTC'))
if __name__ == "__main__":
unittest.main()

31
http2_example.py Normal file
View File

@ -0,0 +1,31 @@
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')

166
okx/Account.py Normal file
View File

@ -0,0 +1,166 @@
from .client import Client
from .consts import *
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 = {}
if instType:
params['instType'] = instType
return self._request_with_params(GET, POSITION_RISK, params)
# Get Balance
def get_account_balance(self, ccy=''):
params = {}
if ccy:
params['ccy'] = ccy
return self._request_with_params(GET, ACCOUNT_INFO, params)
# Get Positions
def get_positions(self, instType='', instId=''):
params = {'instType': instType, 'instId': instId}
return self._request_with_params(GET, POSITION_INFO, params)
# Get Bills Details (recent 7 days)
def get_account_bills(self, instType='', ccy='', mgnMode='', ctType='', type='', subType='', after='', before='',
limit=''):
params = {'instType': instType, 'ccy': ccy, 'mgnMode': mgnMode, 'ctType': ctType, 'type': type,
'subType': subType, 'after': after, 'before': before, 'limit': limit}
return self._request_with_params(GET, BILLS_DETAIL, params)
# Get Bills Details (recent 3 months)
def get_account_bills_archive(self, instType='', ccy='', mgnMode='', ctType='', type='', subType='', after='', before='',
limit=''):
params = {'instType': instType, 'ccy': ccy, 'mgnMode': mgnMode, 'ctType': ctType, 'type': type,
'subType': subType, 'after': after, 'before': before, 'limit': limit}
return self._request_with_params(GET, BILLS_ARCHIVE, params)
# Get Account Configuration
def get_account_config(self):
return self._request_without_params(GET, ACCOUNT_CONFIG)
# Get Account Configuration
def set_position_mode(self, posMode):
params = {'posMode': posMode}
return self._request_with_params(POST, POSITION_MODE, params)
# Get Account Configuration
def set_leverage(self, lever, mgnMode, instId='', ccy='', posSide=''):
params = {'lever': lever, 'mgnMode': mgnMode, 'instId': instId, 'ccy': ccy, 'posSide': posSide}
return self._request_with_params(POST, SET_LEVERAGE, params)
# Get Maximum Tradable Size For Instrument
def get_max_order_size(self, instId, tdMode, ccy='', px=''):
params = {'instId': instId, 'tdMode': tdMode, 'ccy': ccy, 'px': 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}
return self._request_with_params(GET, MAX_AVAIL_SIZE, params)
# Increase / Decrease margin
def adjustment_margin(self, instId, posSide, type, amt,loanTrans=''):
params = {'instId': instId, 'posSide': posSide, 'type': type, 'amt': amt,'loanTrans':loanTrans}
return self._request_with_params(POST, ADJUSTMENT_MARGIN, params)
# Get Leverage
def get_leverage(self, instId, mgnMode):
params = {'instId': instId, 'mgnMode': mgnMode}
return self._request_with_params(GET, GET_LEVERAGE, params)
# Get the maximum loan of isolated MARGIN
def get_max_loan(self, instId, mgnMode, mgnCcy):
params = {'instId': instId, 'mgnMode': mgnMode, 'mgnCcy': mgnCcy}
return self._request_with_params(GET, MAX_LOAN, params)
# Get Fee Rates
def get_fee_rates(self, instType, instId='', uly='', category='',instFamily = ''):
params = {'instType': instType, 'instId': instId, 'uly': uly, 'category': category,'instFamily':instFamily}
return self._request_with_params(GET, FEE_RATES, params)
# Get interest-accrued
def get_interest_accrued(self, instId='', ccy='', mgnMode='', after='', before='', limit=''):
params = {'instId': instId, 'ccy': ccy, 'mgnMode': mgnMode, 'after': after, 'before': before, 'limit': limit}
return self._request_with_params(GET, INTEREST_ACCRUED, params)
# Get interest-accrued
def get_interest_rate(self, ccy=''):
params = {'ccy': ccy}
return self._request_with_params(GET, INTEREST_RATE, params)
# Set Greeks (PA/BS)
def set_greeks(self, greeksType):
params = {'greeksType': greeksType}
return self._request_with_params(POST, SET_GREEKS, params)
# Set Isolated Mode
def set_isolated_mode(self, isoMode,type):
params = {'isoMode': isoMode, 'type':type}
return self._request_with_params(POST, ISOLATED_MODE, params)
# Get Maximum Withdrawals
def get_max_withdrawal(self, ccy=''):
params = {'ccy': 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}
return self._request_with_params(POST, BORROW_REPAY, params)
# Get borrow repay history
def get_borrow_repay_history(self, ccy='', after='', before='', limit=''):
params = {'ccy': ccy, 'after': after, 'before': before, 'limit':limit}
return self._request_with_params(GET, BORROW_REPAY_HISTORY, params)
# Get Obtain borrowing rate and limit
def get_interest_limits(self, type='',ccy=''):
params = {'type': type, 'ccy': 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,}
return self._request_with_params(POST, SIMULATED_MARGIN, params)
# Get Greeks
def get_greeks(self, ccy=''):
params = {'ccy': ccy}
return self._request_with_params(GET, GREEKS, params)
#GET /api/v5/account/risk-state
def get_account_position_risk(self):
return self._request_without_params(GET, ACCOUNT_RISK)
#GET /api/v5/account/positions-history
def get_positions_history(self,instType = '', instId = '',mgnMode = '',type = '',posId = '',after = '',before ='',limit = ''):
params = {
'instType':instType,
'instId':instId,
'mgnMode':mgnMode,
'type':type,
'posId':posId,
'after':after,
'before':before,
'limit':limit
}
return self._request_with_params(GET,POSITIONS_HISTORY,params)
#GET /api/v5/account/position-tiers
def get_account_position_tiers(self,instType = '', uly = '',instFamily = ''):
params = {
'instType':instType,
'uly':uly,
'instFamily':instFamily
}
return self._request_with_params(GET,GET_PM_LIMIT,params)

71
okx/BlockTrading.py Normal file
View File

@ -0,0 +1,71 @@
from .client import Client
from .consts import *
class BlockTradingAPI(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)
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}
return self._request_with_params(POST, CREATE_RFQ, params)
def cancel_rfq(self, rfqId = '', clRfqId = ''):
params = {'rfqId': rfqId, 'clRfqId': clRfqId}
return self._request_with_params(POST, CANCEL_RFQ, params)
def cancel_batch_rfqs(self, rfqIds=[], clRfqIds=[]):
params = {'rfqIds': rfqIds, 'clRfqIds': clRfqIds}
return self._request_with_params(POST, CANCEL_BATCH_RFQS, params)
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}
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}
return self._request_with_params(POST, CREATE_QUOTE, params)
def cancel_quote(self, quoteId = '', clQuoteId = ''):
params = {'quoteId': quoteId, 'clQuoteId': clQuoteId}
return self._request_with_params(POST, CANCEL_QUOTE, params)
def cancel_batch_quotes(self, quoteIds='', clQuoteIds=''):
params = {'quoteIds': quoteIds, 'clQuoteIds': clQuoteIds}
return self._request_with_params(POST, CANCEL_BATCH_QUOTES, params)
def cancel_all_quotes(self):
params = {}
return self._request_with_params(POST, CANCEL_ALL_QUOTES, params)
def get_rfqs(self, rfqId = '', clRfqId = '', state = '', beginId = '', endId = '', limit = ''):
params = {'rfqId': rfqId, 'clRfqId': clRfqId, 'state': state, 'beginId': beginId, 'endId': endId, 'limit':limit}
return self._request_with_params(GET, GET_RFQS, params)
def get_quotes(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}
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}
return self._request_with_params(GET, GET_RFQ_TRADES, params)
def get_public_trades(self, beginId = '', endId = '', limit = ''):
params = {'beginId': beginId, 'endId': endId, 'limit': limit}
return self._request_with_params(GET, GET_PUBLIC_TRADES, params)
def reset_mmp(self):
return self._request_without_params(POST, MMP_RESET)
def set_marker_instrument(self,params = []):
return self._request_with_params(POST, MARKER_INSTRUMENT_SETTING, params)

27
okx/Convert.py Normal file
View File

@ -0,0 +1,27 @@
from .client import Client
from .consts import *
class ConvertAPI(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)
def get_currencies(self):
params = {}
return self._request_with_params(GET, GET_CURRENCIES, params)
def get_currency_pair(self, fromCcy='', toCcy=''):
params = {"fromCcy": fromCcy, 'toCcy': toCcy}
return self._request_with_params(GET, GET_CURRENCY_PAIR, params)
def estimate_quote(self, baseCcy = '', quoteCcy = '', side = '', rfqSz = '', rfqSzCcy = '', clQReqId = '',tag=''):
params = {'baseCcy': baseCcy, 'quoteCcy': quoteCcy, 'side':side, 'rfqSz':rfqSz, 'rfqSzCcy':rfqSzCcy, 'clQReqId':clQReqId,'tag':tag}
return self._request_with_params(POST, ESTIMATE_QUOTE, params)
def convert_trade(self, quoteId = '', baseCcy = '', quoteCcy = '', side = '', sz = '', szCcy = '', clTReqId = '',tag=''):
params = {'quoteId': quoteId, 'baseCcy': baseCcy, 'quoteCcy':quoteCcy, 'side':side, 'sz':sz, 'szCcy':szCcy, 'clTReqId':clTReqId,'tag':tag}
return self._request_with_params(POST, CONVERT_TRADE, params)
def get_convert_history(self, after = '', before = '', limit = '',tag=''):
params = {'after': after, 'before': before, 'limit':limit,'tag':tag}
return self._request_with_params(GET, CONVERT_HISTORY, params)

64
okx/Earning.py Normal file
View File

@ -0,0 +1,64 @@
from .client import Client
from .consts import *
class EarningAPI(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)
def get_offers(self,productId = '',protocolType = '',ccy = ''):
params = {
'productId':productId,
'protocolType':protocolType,
'ccy':ccy
}
return self._request_with_params(GET,STACK_DEFI_OFFERS,params)
def purchase(self,productId = '',investData = [],term = ''):
params = {
'productId':productId,
'investData':investData
}
if term != '':
params['term'] = term
return self._request_with_params(POST,STACK_DEFI_PURCHASE,params)
def redeem(self,ordId = '',protocolType = '',allowEarlyRedeem = ''):
params = {
'ordId':ordId,
'protocolType':protocolType,
'allowEarlyRedeem':allowEarlyRedeem
}
return self._request_with_params(POST,STACK_DEFI_REDEEM,params)
def cancel(self,ordId = '',protocolType = ''):
params = {
'ordId':ordId,
'protocolType':protocolType
}
return self._request_with_params(POST,STACK_DEFI_CANCEL,params)
def get_activity_orders(self,productId = '',protocolType = '',ccy = '',state = ''):
params = {
'productId':productId,
'protocolType':protocolType,
'ccy':ccy,
'state':state
}
return self._request_with_params(GET,STACK_DEFI_ORDERS_ACTIVITY,params)
def get_orders_history(self,productId = '',protocolType = '',ccy = '',after = '',before = '',limit = ''):
params = {
'productId':productId,
'protocolType':protocolType,
'ccy':ccy,
'after':after,
'before':before,
'limit':limit
}
return self._request_with_params(GET,STACK_DEFI_ORDERS_HISTORY,params)

15
okx/FDBroker.py Normal file
View File

@ -0,0 +1,15 @@
from .client import Client
from .consts import *
class FDBrokerAPI(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)
def generate_rebate_details_download_link(self, begin ='', end = ''):
params = {'begin': begin, 'end': end}
return self._request_with_params(POST, FD_REBATE_PER_ORDERS, params)
def get_rebate_details_download_link(self, type = '', begin = '', end = ''):
params = {'type': type, 'begin': begin, 'end': end}
return self._request_with_params(GET, FD_GET_REBATE_PER_ORDERS, params)

126
okx/Funding.py Normal file
View File

@ -0,0 +1,126 @@
from .client import Client
from .consts import *
class FundingAPI(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 Deposit Address
def get_deposit_address(self, ccy):
params = {'ccy': ccy}
return self._request_with_params(GET, DEPOSIT_ADDRESS, params)
# Get Transfer State
def transfer_state(self, transId,type=''):
params = {'transId': transId, 'type': type}
return self._request_with_params(GET, TRANSFER_STATE, params)
# Get Balance
def get_balances(self, ccy=''):
params = {'ccy': ccy}
return self._request_with_params(GET, GET_BALANCES, params)
# Get Account Configuration
def funds_transfer(self, ccy, amt, from_, to, type='0', subAcct='', instId='', toInstId='',loanTrans=''):
params = {'ccy': ccy, 'amt': amt, 'from': from_, 'to': to, 'type': type, 'subAcct': subAcct, 'instId': instId,
'toInstId': toInstId,'loanTrans':loanTrans}
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}
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}
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}
return self._request_with_params(GET, WITHDRAWAL_HISTORIY, params)
# Get Currencies
def get_currencies(self, ccy=''):
params = {'ccy': ccy}
return self._request_with_params(GET, CURRENCY_INFO, params)
# PiggyBank Purchase/Redemption
def purchase_redempt(self, ccy, amt, side, rate):
params = {'ccy': ccy, 'amt': amt, 'side': side,'rate':rate}
return self._request_with_params(POST, PURCHASE_REDEMPT, params)
# Get Withdrawal History
def get_bills(self, ccy='', type='', after='', before='', limit=''):
params = {'ccy': ccy, 'type': type, 'after': after, 'before': before, 'limit': limit}
return self._request_with_params(GET, BILLS_INFO, params)
#Get Deposit Lightning
def get_deposit_lightning(self, ccy,amt,to=""):
params = {'ccy':ccy,'amt':amt}
if to:
params = {'to':to}
return self._request_with_params(GET, DEPOSIT_LIGHTNING, params)
# Withdrawal Lightning
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}
return self._request_with_params(GET, LENDING_RATE_SUMMARY, params)
#POST /api/v5/asset/cancel-withdrawal
def cancel_withdrawal(self,wdId = ''):
params = {
'wdId':wdId
}
return self._request_with_params(POST, CANCEL_WITHDRAWAL, params)
#POST /api/v5/asset/convert-dust-assets
def convert_dust_assets(self,ccy = []):
params = {
'ccy':ccy
}
return self._request_with_params(POST, CONVERT_DUST_ASSETS, params)
#GET /api/v5/asset/asset-valuation
def get_asset_valuation(self,ccy = ''):
params = {
'ccy':ccy
}
return self._request_with_params(GET, ASSET_VALUATION, params)
#GET / api / v5 / asset / saving - balance
def get_saving_balance(self,ccy = ''):
params = {
'ccy':ccy
}
return self._request_with_params(GET, GET_SAVING_BALANCE, params)

78
okx/Grid.py Normal file
View File

@ -0,0 +1,78 @@
from .client import Client
from .consts import *
class GridAPI(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)
def grid_order_algo(self, instId='', algoOrdType='', maxPx='', minPx='', gridNum='', runType='', tpTriggerPx='',
slTriggerPx='', tag='', quoteSz='', baseSz='', sz='', direction='', lever='', basePos=''):
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}
return self._request_with_params(POST, GRID_ORDER_ALGO, params)
def grid_amend_order_algo(self, algoId='', instId='', slTriggerPx='', tpTriggerPx=''):
params = {'algoId': algoId, 'instId': instId, 'slTriggerPx': slTriggerPx, 'tpTriggerPx': tpTriggerPx}
return self._request_with_params(POST, GRID_AMEND_ORDER_ALGO, params)
def grid_stop_order_algo(self, algoId='', instId='', algoOrdType='', stopType=''):
params = [{'algoId': algoId, 'instId': instId, 'algoOrdType': algoOrdType, 'stopType': stopType}]
return self._request_with_params(POST, GRID_STOP_ORDER_ALGO, params)
def grid_orders_algo_pending(self, algoOrdType='', algoId='', instId='', instType='', after='', before='',
limit='', instFamily = ''):
params = {'algoOrdType': algoOrdType, 'algoId': algoId, 'instId': instId, 'instType': instType, 'after': after,
'before': before, 'limit': limit,'instFamily':instFamily}
return self._request_with_params(GET, GRID_ORDERS_ALGO_PENDING, params)
def grid_orders_algo_history(self, algoOrdType='', algoId='', instId='', instType='', after='', before='',
limit='',instFamily = ''):
params = {'algoOrdType': algoOrdType, 'algoId': algoId, 'instId': instId, 'instType': instType, 'after': after,
'before': before, 'limit': limit,'instFamily':instFamily}
return self._request_with_params(GET, GRID_ORDERS_ALGO_HISTORY, params)
def grid_orders_algo_details(self, algoOrdType='', algoId=''):
params = {'algoOrdType': algoOrdType, 'algoId': algoId}
return self._request_with_params(GET, GRID_ORDERS_ALGO_DETAILS, params)
def grid_sub_orders(self, algoId='', algoOrdType='', type='', groupId='', after='', before='', limit=''):
params = {'algoId': algoId, 'algoOrdType': algoOrdType, 'type': type, 'groupId': groupId, 'after': after,
'before': before, 'limit': limit}
return self._request_with_params(GET, GRID_SUB_ORDERS, params)
def grid_positions(self, algoOrdType='', algoId=''):
params = {'algoOrdType': algoOrdType, 'algoId': algoId}
return self._request_with_params(GET, GRID_POSITIONS, params)
def grid_withdraw_income(self, algoId=''):
params = {'algoId': algoId}
return self._request_with_params(POST, GRID_WITHDRAW_INCOME, params)
def grid_compute_margin_balance(self, algoId='', type='', amt=''):
params = {
'algoId': algoId,
'type': type,
'amt': amt
}
return self._request_with_params(POST, GRID_COMPUTE_MARIGIN_BALANCE, params)
def grid_adjust_margin_balance(self, algoId='', type='', amt='', percent=''):
params = {
'algoId': algoId,
'type': type,
'amt': amt,
'percent': percent
}
return self._request_with_params(POST, GRID_MARGIN_BALANCE, params)
def grid_ai_param(self, algoOrdType='', instId='', direction='', duration=''):
params = {
'algoOrdType': algoOrdType,
'instId': instId,
'direction': direction,
'duration':duration
}
return self._request_with_params(GET, GRID_AI_PARAM, params)

122
okx/MarketData.py Normal file
View File

@ -0,0 +1,122 @@
from .client import Client
from .consts import *
class MarketAPI(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 Tickers
def get_tickers(self, instType, uly='', instFamily =''):
if uly:
params = {'instType': instType, 'uly': uly, 'instFamily': instFamily}
else:
params = {'instType': instType, 'instFamily': instFamily}
return self._request_with_params(GET, TICKERS_INFO, params)
# Get Ticker
def get_ticker(self, instId):
params = {'instId': instId}
return self._request_with_params(GET, TICKER_INFO, params)
# Get Index Tickers
def get_index_tickers(self, quoteCcy='', instId=''):
params = {'quoteCcy': quoteCcy, 'instId': instId}
return self._request_with_params(GET, INDEX_TICKERS, params)
# Get Order Book
def get_orderbook(self, instId, sz=''):
params = {'instId': instId, 'sz': sz}
return self._request_with_params(GET, ORDER_BOOKS, params)
# Get Candlesticks
def get_candlesticks(self, instId, after='', before='', bar='', limit=''):
params = {'instId': instId, 'after': after, 'before': before, 'bar': bar, 'limit': limit}
return self._request_with_params(GET, MARKET_CANDLES, params)
# GGet Candlesticks Historytop currencies only
def get_history_candlesticks(self, instId, after='', before='', bar='', limit=''):
params = {'instId': instId, 'after': after, 'before': before, 'bar': bar, 'limit': limit}
return self._request_with_params(GET, HISTORY_CANDLES, params)
# Get Index Candlesticks
def get_index_candlesticks(self, instId, after='', before='', bar='', limit=''):
params = {'instId': instId, 'after': after, 'before': before, 'bar': bar, 'limit': limit}
return self._request_with_params(GET, INDEX_CANSLES, params)
# Get Mark Price Candlesticks
def get_mark_price_candlesticks(self, instId, after='', before='', bar='', limit=''):
params = {'instId': instId, 'after': after, 'before': before, 'bar': bar, 'limit': limit}
return self._request_with_params(GET, MARKPRICE_CANDLES, params)
# Get Index Candlesticks
def get_trades(self, instId, limit=''):
params = {'instId': instId, 'limit': limit}
return self._request_with_params(GET, MARKET_TRADES, params)
# Get Volume
def get_volume(self):
return self._request_without_params(GET, VOLUMNE)
# Get Oracle
def get_oracle(self):
return self._request_without_params(GET, ORACLE)
# Get Tier
def get_tier(self, instType='', tdMode='', uly='', instId='', ccy='', tier=''):
params = {'instType': instType, 'tdMode': tdMode, 'uly': uly, 'instId': instId, 'ccy': ccy, 'tier': tier}
return self._request_with_params(GET, TIER, params)
#GET /api/v5/market/index-components
def get_index_components(self,index = ''):
param = {
'index':index
}
return self._request_with_params(GET,INDEX_COMPONENTS,param)
#GET /api/v5/market/exchange-rate
def get_exchange_rate(self):
return self._request_without_params(GET, EXCHANGE_RATE)
#GET /api/v5/market/history-trades
def get_history_trades(self,instId = '',type = '',after = '',before = '',limit = ''):
params = {
'instId':instId,
'type':type,
'after':after,
'before':before,
'limit':limit
}
return self._request_with_params(GET,HISTORY_TRADES,params)
#GET /api/v5/market/block-ticker
def get_block_ticker(self,instId = ''):
params = {
'instId':instId
}
return self._request_with_params(GET,BLOCK_TICKER,params)
#GET /api/v5/market/block-tickers
def get_block_tickers(self,instType = '',uly = '', instFamily = ''):
params = {
'instType':instType,
'uly':uly,
'instFamily':instFamily
}
return self._request_with_params(GET, BLOCK_TICKERS, params)
#GET /api/v5/market/block-trades
def get_block_trades(self,instId = ''):
params = {
'instId':instId
}
return self._request_with_params(GET, BLOCK_TRADES, params)

150
okx/NDBroker.py Normal file
View File

@ -0,0 +1,150 @@
from .client import Client
from .consts import *
class NDBrokerAPI(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 /api/v5/broker/nd/info
def get_broker_info(self):
return self._request_without_params(GET, BROKER_INFO)
#POST /api/v5/broker/nd/create-subaccount
def create_subaccount(self,subAcct = '',label = ''):
params = {
'subAcct':subAcct,
'label':label
}
return self._request_with_params(POST,CREATE_SUBACCOUNT,params)
def delete_subaccount(self,subAcct = ''):
params = {
'subAcct':subAcct
}
return self._request_with_params(POST,DELETE_SUBACCOUNT,params)
def get_subaccount_info(self,subAcct = '',page = '',limit = ''):
params = {
'subAcct':subAcct,
'page':page,
'limit':limit
}
return self._request_with_params(GET,SUBACCOUNT_INFO,params)
def create_subaccount_apikey(self,subAcct = '',label='',passphrase='',ip='',perm=''):
params = {
'subAcct':subAcct,
'label':label,
'passphrase':passphrase,
'ip':ip,
'perm':perm
}
return self._request_with_params(POST,ND_CREAET_APIKEY,params)
def get_subaccount_apikey(self,subAcct = '',apiKey = ''):
params = {
'subAcct':subAcct,
'apiKey':apiKey
}
return self._request_with_params(GET,ND_SELECT_APIKEY,params)
def reset_subaccount_apikey(self,subAcct = '',apiKey = '',label='',perm = '',ip = ''):
params = {
'subAcct':subAcct,
'apiKey':apiKey,
'label':label,
'perm':perm,
'ip':ip
}
return self._request_with_params(POST,ND_MODIFY_APIKEY,params)
def delete_subaccount_apikey(self,subAcct = '',apiKey = ''):
params = {
'subAcct':subAcct,
'apiKey':apiKey
}
return self._request_with_params(POST,ND_DELETE_APIKEY,params)
def set_subaccount_level(self,subAcct = '',acctLv = ''):
params = {
'subAcct':subAcct,
'acctLv':acctLv
}
return self._request_with_params(POST,SET_SUBACCOUNT_LEVEL,params)
def set_subaccount_fee_rate(self,subAcct = '',instType = '',chgType = '',chgTaker = '',chgMaker = '',effDate = ''):
params = {
'subAcct':subAcct,
'instType':instType,
'chgType':chgType,
'chgTaker':chgTaker,
'chgMaker':chgMaker,
'effDate':effDate
}
return self._request_with_params(POST,SET_SUBACCOUNT_FEE_REAT,params)
def create_subaccount_deposit_address(self,subAcct = '',ccy = '',chain = '',addrType = '', to =''):
params = {
'subAcct':subAcct,
'ccy':ccy,
'chain':chain,
'addrType':addrType,
'to':to
}
return self._request_with_params(POST,SUBACCOUNT_DEPOSIT_ADDRESS,params)
def reset_subaccount_deposit_address(self,subAcct = '',ccy = '',chain = '',addr = '',to = ''):
params = {
'subAcct':subAcct,
'ccy':ccy,
'chain':chain,
'addr':addr,
'to':to
}
return self._request_with_params(POST,MODIFY_SUBACCOUNT_DEPOSIT_ADDRESS,params)
def get_subaccount_deposit_address(self,subAcct = '',ccy = ''):
params = {
'subAcct':subAcct,
'ccy':ccy
}
return self._request_with_params(GET,GET_SUBACCOUNT_DEPOSIT,params)
def get_subaccount_deposit_history(self,subAcct = '',ccy = '',txId = '',state = '',after = '',before = '',limit = ''):
params = {
'subAcct':subAcct,
'ccy':ccy,
'txId':txId,
'state':state,
'after':after,
'before':before,
'limit':limit
}
return self._request_with_params(GET,SUBACCOUNT_DEPOSIT_HISTORY,params)
def get_rebate_daily(self,subAcct = '',begin = '',end = '',page = '',limit = ''):
params = {
'subAcct':subAcct,
'begin':begin,
'end':end,
'page':page,
'limit':limit
}
return self._request_with_params(GET,REBATE_DAILY,params)
def get_rebate_details_download_link(self,type ='',begin = '',end = ''):
params ={
'type':type,
'begin':begin,
'end':end
}
return self._request_with_params(GET,GET_REBATE_PER_ORDERS,params)
def generate_rebate_details_download_link(self,begin = '',end = ''):
params = {
'begin':begin,
'end':end
}
return self._request_with_params(POST,REBATE_PER_ORDERS,params)

117
okx/PublicData.py Normal file
View File

@ -0,0 +1,117 @@
from .client import Client
from .consts import *
class PublicAPI(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 Instruments
def get_instruments(self, instType, uly='', instId='',instFamily = ''):
params = {'instType': instType, 'uly': uly, 'instId': instId,'instFamily':instFamily}
return self._request_with_params(GET, INSTRUMENT_INFO, params)
# Get Delivery/Exercise History
def get_delivery_exercise_history(self, instType, uly = '', after='', before='', limit='',instFamily = ''):
params = {'instType': instType, 'uly': uly, 'after': after, 'before': before, 'limit': limit,'instFamily':instFamily}
return self._request_with_params(GET, DELIVERY_EXERCISE, params)
# Get Open Interest
def get_open_interest(self, instType, uly='', instId='' ,instFamily =''):
params = {'instType': instType, 'uly': uly, 'instId': instId,'instFamily':instFamily}
return self._request_with_params(GET, OPEN_INTEREST, params)
# Get Funding Rate
def get_funding_rate(self, instId):
params = {'instId': instId}
return self._request_with_params(GET, FUNDING_RATE, params)
# Get Funding Rate History
def funding_rate_history(self, instId, after='', before='', limit=''):
params = {'instId': instId, 'after': after, 'before': before, 'limit': limit}
return self._request_with_params(GET, FUNDING_RATE_HISTORY, params)
# Get Limit Price
def get_price_limit(self, instId):
params = {'instId': instId}
return self._request_with_params(GET, PRICE_LIMIT, params)
# Get Option Market Data
def get_opt_summary(self, uly = '', expTime='',instFamily=''):
params = {'uly': uly, 'expTime': expTime,'instFamily':instFamily}
return self._request_with_params(GET, OPT_SUMMARY, params)
# Get Estimated Delivery/Excercise Price
def get_estimated_price(self, instId):
params = {'instId': instId}
return self._request_with_params(GET, ESTIMATED_PRICE, params)
# Get Discount Rate And Interest-Free Quota
def discount_interest_free_quota(self, ccy=''):
params = {'ccy': ccy}
return self._request_with_params(GET, DICCOUNT_INTETEST_INFO, params)
# Get System Time
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}
return self._request_with_params(GET, MARK_PRICE, params)
# Get Tier
def get_position_tiers(self, instType, tdMode, uly='', instId='', ccy='', tier='',instFamily =''):
params = {'instType': instType, 'tdMode': tdMode, 'uly': uly, 'instId': instId, 'ccy': ccy, 'tier': tier,'instFamily':instFamily}
return self._request_with_params(GET, TIER, params)
#GET /api/v5/public/interest-rate-loan-quota
def get_interest_rate_loan_quota(self):
return self._request_without_params(GET,INTEREST_LOAN)
#GET /api/v5/public/vip-interest-rate-loan-quota
def get_vip_interest_rate_loan_quota(self):
return self._request_without_params(GET, VIP_INTEREST_RATE_LOAN_QUOTA)
#GET /api/v5/public/underlying
def get_underlying(self,instType = ''):
params = {
'instType':instType
}
return self._request_with_params(GET, UNDERLYING, params)
#GET /api/v5/public/insurance-fund
def get_insurance_fund(self,instType = '',type = '',uly = '',ccy='',before = '',after = '',limit = '',instFamily=''):
params = {
'instType':instType,
'type':type,
'uly':uly,
'ccy':ccy,
'before':before,
'after':after,
'limit':limit,
'instFamily':instFamily
}
return self._request_with_params(GET, INSURANCE_FUND, params)
#GET /api/v5/public/convert-contract-coin
def get_convert_contract_coin(self,type = '',instId = '',sz = '',px = '',unit = ''):
params = {
'type':type,
'instId':instId,
'sz':sz,
'px':px,
'unit':unit
}
return self._request_with_params(GET, CONVERT_CONTRACT_COIN, params)

11
okx/Status.py Normal file
View File

@ -0,0 +1,11 @@
from .client import Client
from .consts import *
class StatusAPI(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)
def status(self, state=''):
params = {'state': state}
return self._request_with_params(GET, STATUS, params)

63
okx/SubAccount.py Normal file
View File

@ -0,0 +1,63 @@
from .client import Client
from .consts import *
class SubAccountAPI(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)
def get_account_balance(self, subAcct):
params = {"subAcct": subAcct}
return self._request_with_params(GET, BALANCE, params)
def bills(self, ccy='', type='', subAcct='', after='', before='', limit=''):
params = {"ccy": ccy, 'type': type, 'subAcct': subAcct, 'after': after, 'before': before, 'limit': limit}
return self._request_with_params(GET, BILLs, params)
def reset_subaccount_apikey(self, subAcct,apiKey, label='', perm='', ip='-1'):
params = {'subAcct': subAcct, 'apiKey': apiKey}
if ip != '-1':
params['ip'] = ip
if label != '':
params['label'] = label
if perm != '':
params['perm'] = perm
#params = {'subAcct': subAcct, 'label': label, 'apiKey': apiKey, 'perm': perm, 'ip': ip}
return self._request_with_params(POST, RESET, params)
def get_subaccount_list(self, enable='', subAcct='', after='', before='', limit=''):
params = {'enable': enable, 'subAcct': subAcct, 'after': after, 'before': before, 'limit': limit}
return self._request_with_params(GET, VIEW_LIST, params)
def subAccount_transfer(self, ccy, amt, froms, to, fromSubAccount,toSubAccount,loanTrans='false',omitPosRisk = 'false'):
params = {'ccy': ccy, 'amt': amt, 'from': froms, 'to': to, 'fromSubAccount': fromSubAccount, 'toSubAccount': toSubAccount,'loanTrans':loanTrans,'omitPosRisk':omitPosRisk}
return self._request_with_params(POST, SUBACCOUNT_TRANSFER, params)
#GET /api/v5/users/entrust-subaccount-list
def get_entrust_subaccount_list(self,subAcct = ''):
params = {
'subAcct':subAcct
}
return self._request_with_params(GET, ENTRUST_SUBACCOUNT_LIST, params)
#POST /api/v5/users/subaccount/set-transfer-out
def set_permission_transfer_out(self,subAcct = '',canTransOut = ''):
params = {
'subAcct':subAcct,
'canTransOut':canTransOut
}
return self._request_with_params(POST, SET_TRSNSFER_OUT, params)
#GET /api/v5/asset/subaccount/balances
def get_funding_balance(self,subAcct='',ccy=''):
params = {
'subAcct':subAcct,
'ccy':ccy
}
return self._request_with_params(GET, GET_ASSET_SUBACCOUNT_BALANCE, params)

159
okx/Trade.py Normal file
View File

@ -0,0 +1,159 @@
from .client import Client
from .consts import *
class TradeAPI(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)
# Place Order
def place_order(self, instId, tdMode, side, ordType, sz, ccy='', clOrdId='', tag='', posSide='', px='',
reduceOnly='', tgtCcy=''):
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}
return self._request_with_params(POST, PLACR_ORDER, params)
# Place Multiple Orders
def place_multiple_orders(self, orders_data):
return self._request_with_params(POST, BATCH_ORDERS, orders_data)
# Cancel Order
def cancel_order(self, instId, ordId='', clOrdId=''):
params = {'instId': instId, 'ordId': ordId, 'clOrdId': clOrdId}
return self._request_with_params(POST, CANAEL_ORDER, params)
# Cancel Multiple Orders
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=''):
params = {'instId': instId, 'cxlOnFailc': cxlOnFail, 'ordId': ordId, 'clOrdId': clOrdId, 'reqId': reqId,
'newSz': newSz,
'newPx': newPx}
return self._request_with_params(POST, AMEND_ORDER, params)
# Amend Multiple Orders
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}
return self._request_with_params(POST, CLOSE_POSITION, params)
# Get Order Details
def get_order(self, instId, ordId='', clOrdId=''):
params = {'instId': instId, 'ordId': ordId, 'clOrdId': clOrdId}
return self._request_with_params(GET, ORDER_INFO, params)
# Get Order List
def get_order_list(self, instType='', uly='', instId='', ordType='', state='', after='', before='', limit='',instFamily = ''):
params = {'instType': instType, 'uly': uly, 'instId': instId, 'ordType': ordType, 'state': state,
'after': after, 'before': before, 'limit': limit,'instFamily':instFamily}
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 = ''):
params = {'instType': instType, 'uly': uly, 'instId': instId, 'ordType': ordType, 'state': state,
'after': after, 'before': before, '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 = ''):
params = {'instType': instType, 'uly': uly, 'instId': instId, 'ordType': ordType, 'state': state,
'after': after, 'before': before, 'limit': limit,'instFamily':instFamily}
return self._request_with_params(GET, ORDERS_HISTORY_ARCHIVE, params)
# Get Transaction Details
def get_fills(self, instType='', uly='', instId='', ordId='', after='', before='', limit='',instFamily = ''):
params = {'instType': instType, 'uly': uly, 'instId': instId, 'ordId': ordId, 'after': after, 'before': before,
'limit': limit,'instFamily':instFamily}
return self._request_with_params(GET, ORDER_FILLS, params)
# Place Algo Order
def place_algo_order(self, instId='', tdMode='', side='', ordType='', sz='', ccy='',
posSide='', reduceOnly='', tpTriggerPx='',
tpOrdPx='', slTriggerPx='', slOrdPx='',
triggerPx='', orderPx='', tgtCcy='', pxVar='',
pxSpread='',
szLimit='', pxLimit='', timeInterval='', tpTriggerPxType='', slTriggerPxType='',
callbackRatio='',callbackSpread='',activePx='',tag='',triggerPxType=''):
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,
'tgtCcy': tgtCcy, 'pxVar': pxVar, 'szLimit': szLimit, 'pxLimit': pxLimit,
'timeInterval': timeInterval,
'pxSpread': pxSpread, 'tpTriggerPxType': tpTriggerPxType, 'slTriggerPxType': slTriggerPxType,
'callbackRatio' : callbackRatio, 'callbackSpread':callbackSpread,'activePx':activePx,
'tag':tag,'triggerPxType':triggerPxType,}
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)
# Cancel Advance Algos
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=''):
params = {'ordType': ordType, 'algoId': algoId, 'instType': instType, 'instId': instId, 'after': after,
'before': before, 'limit': limit}
return self._request_with_params(GET, ORDERS_ALGO_OENDING, params)
# Get Algo Order History
def order_algos_history(self, ordType, state='', algoId='', instType='', instId='', after='', before='', limit=''):
params = {'ordType': ordType, 'state': state, 'algoId': algoId, 'instType': instType, 'instId': instId,
'after': after, 'before': before, 'limit': limit}
return self._request_with_params(GET, ORDERS_ALGO_HISTORY, params)
# Get Transaction Details History
def get_fills_history(self, instType, uly='', instId='', ordId='', after='', before='', limit='',instFamily=''):
params = {'instType': instType, 'uly': uly, 'instId': instId, 'ordId': ordId, 'after': after, 'before': before,
'limit': limit,'instFamily':instFamily}
return self._request_with_params(GET, ORDERS_FILLS_HISTORY, params)
def get_easy_convert_currency_list(self):
return self._request_without_params(GET, EASY_CONVERT_CURRENCY_LIST)
def easy_convert(self,fromCcy = [],toCcy = ''):
params = {
'fromCcy':fromCcy,
'toCcy':toCcy
}
return self._request_with_params(POST, EASY_CONVERT, params)
def get_easy_convert_history(self,before = '',after = '',limit = ''):
params = {
'before':before,
'after':after,
'limit':limit
}
return self._request_with_params(GET,CONVERT_EASY_HISTORY,params)
def get_oneclick_repay_list(self,debtType = ''):
params = {
'debtType':debtType
}
return self._request_with_params(GET,ONE_CLICK_REPAY_SUPPORT,params)
def oneclick_repay(self,debtCcy = [] , repayCcy=''):
params = {
'debtCcy':debtCcy,
'repayCcy':repayCcy
}
return self._request_with_params(POST,ONE_CLICK_REPAY,params)
def oneclick_repay_history(self,after = '',before = '',limit = ''):
params = {
'after':after,
'before':before,
'limit':limit
}
return self._request_with_params(GET,ONE_CLICK_REPAY_HISTORY,params)

55
okx/TradingData.py Normal file
View File

@ -0,0 +1,55 @@
from .client import Client
from .consts import *
class TradingDataAPI(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)
def get_support_coin(self):
return self._request_without_params(GET, SUPPORT_COIN)
def get_taker_volume(self, ccy, instType, begin='', end='', period=''):
params = {'ccy': ccy, 'instType': instType, 'begin': begin, 'end': end, 'period': period}
return self._request_with_params(GET, TAKER_VOLUME, params)
def get_margin_lending_ratio(self, ccy, begin='', end='', period=''):
params = {'ccy': ccy, 'begin': begin, 'end': end, 'period': period}
return self._request_with_params(GET, MARGIN_LENDING_RATIO, params)
def get_long_short_ratio(self, ccy, begin='', end='', period=''):
params = {'ccy': ccy, 'begin': begin, 'end': end, 'period': period}
return self._request_with_params(GET, LONG_SHORT_RATIO, params)
def get_contracts_interest_volume(self, ccy, begin='', end='', period=''):
params = {'ccy': ccy, 'begin': begin, 'end': end, 'period': period}
return self._request_with_params(GET, CONTRACTS_INTEREST_VOLUME, params)
def get_options_interest_volume(self, ccy, period=''):
params = {'ccy': ccy, 'period': period}
return self._request_with_params(GET, OPTIONS_INTEREST_VOLUME, params)
def get_put_call_ratio(self, ccy, period=''):
params = {'ccy': ccy, 'period': period}
return self._request_with_params(GET, PUT_CALL_RATIO, params)
def get_interest_volume_expiry(self, ccy, period=''):
params = {'ccy': ccy, 'period': period}
return self._request_with_params(GET, OPEN_INTEREST_VOLUME_EXPIRY, params)
def get_interest_volume_strike(self, ccy, expTime, period=''):
params = {'ccy': ccy, 'expTime': expTime, 'period': period}
return self._request_with_params(GET, INTEREST_VOLUME_STRIKE, params)
def get_taker_block_volume(self, ccy, period=''):
params = {'ccy': ccy, 'period': period}
return self._request_with_params(GET, TAKER_FLOW, params)

6
okx/__init__.py Normal file
View File

@ -0,0 +1,6 @@
"""An unofficial Python wrapper for the OKEx exchange API v3
.. moduleauthor:: Sam McHardy
"""
__version__="0.0.12"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

57
okx/client.py Normal file
View File

@ -0,0 +1,57 @@
import json
import httpx
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 = 'https://www.okx.com',debug = 'True'):
self.API_KEY = api_key
self.API_SECRET_KEY = api_secret_key
self.PASSPHRASE = passphrase
self.use_server_time = use_server_time
self.flag = flag
self.domain = base_api
self.debug = debug
self.client = httpx.Client(base_url=base_api, http2=True)
def _request(self, method, request_path, params):
if method == c.GET:
request_path = request_path + utils.parse_params_to_str(params)
timestamp = utils.get_timestamp()
if self.use_server_time:
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)
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 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)
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, {})
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
response = self.client.get(request_path)
if response.status_code == 200:
return response.json()['ts']
else:
return ""

235
okx/consts.py Normal file
View File

@ -0,0 +1,235 @@
# http header
#API_URL = 'https://www.okx.com'
CONTENT_TYPE = 'Content-Type'
OK_ACCESS_KEY = 'OK-ACCESS-KEY'
OK_ACCESS_SIGN = 'OK-ACCESS-SIGN'
OK_ACCESS_TIMESTAMP = 'OK-ACCESS-TIMESTAMP'
OK_ACCESS_PASSPHRASE = 'OK-ACCESS-PASSPHRASE'
ACEEPT = 'Accept'
COOKIE = 'Cookie'
LOCALE = 'Locale='
APPLICATION_JSON = 'application/json'
GET = "GET"
POST = "POST"
SERVER_TIMESTAMP_URL = '/api/v5/public/time'
# account-complete-testcomplete
POSITION_RISK='/api/v5/account/account-position-risk'
ACCOUNT_INFO = '/api/v5/account/balance'
POSITION_INFO = '/api/v5/account/positions'
BILLS_DETAIL = '/api/v5/account/bills'
BILLS_ARCHIVE = '/api/v5/account/bills-archive'
ACCOUNT_CONFIG = '/api/v5/account/config'
POSITION_MODE = '/api/v5/account/set-position-mode'
SET_LEVERAGE = '/api/v5/account/set-leverage'
MAX_TRADE_SIZE = '/api/v5/account/max-size'
MAX_AVAIL_SIZE = '/api/v5/account/max-avail-size'
ADJUSTMENT_MARGIN = '/api/v5/account/position/margin-balance'
GET_LEVERAGE = '/api/v5/account/leverage-info'
MAX_LOAN = '/api/v5/account/max-loan'
FEE_RATES = '/api/v5/account/trade-fee'
INTEREST_ACCRUED = '/api/v5/account/interest-accrued'
INTEREST_RATE = '/api/v5/account/interest-rate'
SET_GREEKS = '/api/v5/account/set-greeks'
ISOLATED_MODE = '/api/v5/account/set-isolated-mode'
MAX_WITHDRAWAL = '/api/v5/account/max-withdrawal'
ACCOUNT_RISK = '/api/v5/account/risk-state' #need add
BORROW_REPAY = '/api/v5/account/borrow-repay'
BORROW_REPAY_HISTORY = '/api/v5/account/borrow-repay-history'
INTEREST_LIMITS = '/api/v5/account/interest-limits'
SIMULATED_MARGIN = '/api/v5/account/simulated_margin'
GREEKS = '/api/v5/account/greeks'
POSITIONS_HISTORY = '/api/v5/account/positions-history' #need add
GET_PM_LIMIT = '/api/v5/account/position-tiers' #need add
# funding-complete-testcomplete
DEPOSIT_ADDRESS = '/api/v5/asset/deposit-address'
GET_BALANCES = '/api/v5/asset/balances'
FUNDS_TRANSFER = '/api/v5/asset/transfer'
TRANSFER_STATE = '/api/v5/asset/transfer-state'
WITHDRAWAL_COIN = '/api/v5/asset/withdrawal'
DEPOSIT_HISTORIY = '/api/v5/asset/deposit-history'
CURRENCY_INFO = '/api/v5/asset/currencies'
PURCHASE_REDEMPT = '/api/v5/asset/purchase_redempt'
BILLS_INFO = '/api/v5/asset/bills'
DEPOSIT_LIGHTNING = '/api/v5/asset/deposit-lightning'
WITHDRAWAL_LIGHTNING = '/api/v5/asset/withdrawal-lightning'
CANCEL_WITHDRAWAL = '/api/v5/asset/cancel-withdrawal' #need add
WITHDRAWAL_HISTORIY = '/api/v5/asset/withdrawal-history'
CONVERT_DUST_ASSETS = '/api/v5/asset/convert-dust-assets' #need add
ASSET_VALUATION = '/api/v5/asset/asset-valuation' #need add
SET_LENDING_RATE = '/api/v5/asset/set-lending-rate'
LENDING_HISTORY = '/api/v5/asset/lending-history'
LENDING_RATE_HISTORY = '/api/v5/asset/lending-rate-history'
LENDING_RATE_SUMMARY = '/api/v5/asset/lending-rate-summary'
GET_SAVING_BALANCE = '/api/v5/asset/saving-balance' #need to add
# Market Data-Complete-testComplete
TICKERS_INFO = '/api/v5/market/tickers'
TICKER_INFO = '/api/v5/market/ticker'
INDEX_TICKERS = '/api/v5/market/index-tickers'
ORDER_BOOKS = '/api/v5/market/books'
MARKET_CANDLES = '/api/v5/market/candles'
HISTORY_CANDLES = '/api/v5/market/history-candles'
INDEX_CANSLES = '/api/v5/market/index-candles'
MARKPRICE_CANDLES = '/api/v5/market/mark-price-candles'
MARKET_TRADES = '/api/v5/market/trades'
VOLUMNE = '/api/v5/market/platform-24-volume'
ORACLE = '/api/v5/market/open-oracle' #need to update? if it is open oracle
INDEX_COMPONENTS = '/api/v5/market/index-components' #need to add
EXCHANGE_RATE = '/api/v5/market/exchange-rate' #need to add
HISTORY_TRADES = '/api/v5/market/history-trades' #need to add
BLOCK_TICKERS = '/api/v5/market/block-tickers' #need to add
BLOCK_TICKER = '/api/v5/market/block-ticker'#need to add
BLOCK_TRADES = '/api/v5/market/block-trades'#need to add
# Public Data-Complete-testComplete
INSTRUMENT_INFO = '/api/v5/public/instruments'
DELIVERY_EXERCISE = '/api/v5/public/delivery-exercise-history'
OPEN_INTEREST = '/api/v5/public/open-interest'
FUNDING_RATE = '/api/v5/public/funding-rate'
FUNDING_RATE_HISTORY = '/api/v5/public/funding-rate-history'
PRICE_LIMIT = '/api/v5/public/price-limit'
OPT_SUMMARY = '/api/v5/public/opt-summary'
ESTIMATED_PRICE = '/api/v5/public/estimated-price'
DICCOUNT_INTETEST_INFO = '/api/v5/public/discount-rate-interest-free-quota'
SYSTEM_TIME = '/api/v5/public/time'
LIQUIDATION_ORDERS = '/api/v5/public/liquidation-orders'
MARK_PRICE = '/api/v5/public/mark-price'
TIER = '/api/v5/public/position-tiers'
INTEREST_LOAN = '/api/v5/public/interest-rate-loan-quota' #need to add
UNDERLYING = '/api/v5/public/underlying' #need to add
VIP_INTEREST_RATE_LOAN_QUOTA = '/api/v5/public/vip-interest-rate-loan-quota' #need to add
INSURANCE_FUND = '/api/v5/public/insurance-fund'#need to add
CONVERT_CONTRACT_COIN = '/api/v5/public/convert-contract-coin' #need to add
# TRADING DATA-COMPLETE
SUPPORT_COIN = '/api/v5/rubik/stat/trading-data/support-coin'
TAKER_VOLUME = '/api/v5/rubik/stat/taker-volume'
MARGIN_LENDING_RATIO = '/api/v5/rubik/stat/margin/loan-ratio'
LONG_SHORT_RATIO = '/api/v5/rubik/stat/contracts/long-short-account-ratio'
CONTRACTS_INTEREST_VOLUME = '/api/v5/rubik/stat/contracts/open-interest-volume'
OPTIONS_INTEREST_VOLUME = '/api/v5/rubik/stat/option/open-interest-volume'
PUT_CALL_RATIO = '/api/v5/rubik/stat/option/open-interest-volume-ratio'
OPEN_INTEREST_VOLUME_EXPIRY = '/api/v5/rubik/stat/option/open-interest-volume-expiry'
INTEREST_VOLUME_STRIKE = '/api/v5/rubik/stat/option/open-interest-volume-strike'
TAKER_FLOW = '/api/v5/rubik/stat/option/taker-block-volume'
# TRADE-Complete
PLACR_ORDER = '/api/v5/trade/order'
BATCH_ORDERS = '/api/v5/trade/batch-orders'
CANAEL_ORDER = '/api/v5/trade/cancel-order'
CANAEL_BATCH_ORDERS = '/api/v5/trade/cancel-batch-orders'
AMEND_ORDER = '/api/v5/trade/amend-order'
AMEND_BATCH_ORDER = '/api/v5/trade/amend-batch-orders'
CLOSE_POSITION = '/api/v5/trade/close-position'
ORDER_INFO = '/api/v5/trade/order'
ORDERS_PENDING = '/api/v5/trade/orders-pending'
ORDERS_HISTORY = '/api/v5/trade/orders-history'
ORDERS_HISTORY_ARCHIVE = '/api/v5/trade/orders-history-archive'
ORDER_FILLS = '/api/v5/trade/fills'
ORDERS_FILLS_HISTORY = '/api/v5/trade/fills-history'
PLACE_ALGO_ORDER = '/api/v5/trade/order-algo'
CANCEL_ALGOS = '/api/v5/trade/cancel-algos'
Cancel_Advance_Algos = '/api/v5/trade/cancel-advance-algos'
ORDERS_ALGO_OENDING = '/api/v5/trade/orders-algo-pending'
ORDERS_ALGO_HISTORY = '/api/v5/trade/orders-algo-history'
EASY_CONVERT_CURRENCY_LIST = '/api/v5/trade/easy-convert-currency-list'
EASY_CONVERT = '/api/v5/trade/easy-convert'
CONVERT_EASY_HISTORY = '/api/v5/trade/easy-convert-history'
ONE_CLICK_REPAY_SUPPORT = '/api/v5/trade/one-click-repay-currency-list'
ONE_CLICK_REPAY = '/api/v5/trade/one-click-repay'
ONE_CLICK_REPAY_HISTORY = '/api/v5/trade/one-click-repay-history'
# SubAccount-complete-testwriteComplete
BALANCE = '/api/v5/account/subaccount/balances'
BILLs = '/api/v5/asset/subaccount/bills'
RESET = '/api/v5/users/subaccount/modify-apikey'
VIEW_LIST = '/api/v5/users/subaccount/list'
SUBACCOUNT_TRANSFER = '/api/v5/asset/subaccount/transfer'
ENTRUST_SUBACCOUNT_LIST = '/api/v5/users/entrust-subaccount-list' #need to add
SET_TRSNSFER_OUT = '/api/v5/users/subaccount/set-transfer-out' #need to add
GET_ASSET_SUBACCOUNT_BALANCE = '/api/v5/asset/subaccount/balances' #need to add
# Broker-all need to implmented-completed
BROKER_INFO = '/api/v5/broker/nd/info'
CREATE_SUBACCOUNT = '/api/v5/broker/nd/create-subaccount'
DELETE_SUBACCOUNT = '/api/v5/broker/nd/delete-subaccount'
SUBACCOUNT_INFO = '/api/v5/broker/nd/subaccount-info'
SET_SUBACCOUNT_LEVEL = '/api/v5/broker/nd/set-subaccount-level'
SET_SUBACCOUNT_FEE_REAT = '/api/v5/broker/nd/set-subaccount-fee-rate'
SUBACCOUNT_DEPOSIT_ADDRESS = '/api/v5/asset/broker/nd/subaccount-deposit-address'
SUBACCOUNT_DEPOSIT_HISTORY = '/api/v5/asset/broker/nd/subaccount-deposit-history'
REBATE_DAILY = '/api/v5/broker/nd/rebate-daily'
ND_CREAET_APIKEY = '/api/v5/broker/nd/subaccount/apikey'
ND_SELECT_APIKEY = '/api/v5/broker/nd/subaccount/apikey'
ND_MODIFY_APIKEY = '/api/v5/broker/nd/subaccount/modify-apikey'
ND_DELETE_APIKEY = '/api/v5/broker/nd/subaccount/delete-apikey'
GET_REBATE_PER_ORDERS = '/api/v5/broker/nd/rebate-per-orders'
REBATE_PER_ORDERS = '/api/v5/broker/nd/rebate-per-orders'
MODIFY_SUBACCOUNT_DEPOSIT_ADDRESS = '/api/v5/asset/broker/nd/modify-subaccount-deposit-address'
GET_SUBACCOUNT_DEPOSIT='/api/v5/asset/broker/nd/subaccount-deposit-address'
# Convert-Complete
GET_CURRENCIES = '/api/v5/asset/convert/currencies'
GET_CURRENCY_PAIR = '/api/v5/asset/convert/currency-pair'
ESTIMATE_QUOTE = '/api/v5/asset/convert/estimate-quote'
CONVERT_TRADE = '/api/v5/asset/convert/trade'
CONVERT_HISTORY = '/api/v5/asset/convert/history'
# FDBroker -completed
FD_GET_REBATE_PER_ORDERS = '/api/v5/broker/fd/rebate-per-orders'
FD_REBATE_PER_ORDERS = '/api/v5/broker/fd/rebate-per-orders'
# Rfq/BlcokTrading-completed
COUNTERPARTIES = '/api/v5/rfq/counterparties'
CREATE_RFQ = '/api/v5/rfq/create-rfq'
CANCEL_RFQ = '/api/v5/rfq/cancel-rfq'
CANCEL_BATCH_RFQS = '/api/v5/rfq/cancel-batch-rfqs'
CANCEL_ALL_RSQS = '/api/v5/rfq/cancel-all-rfqs'
EXECUTE_QUOTE = '/api/v5/rfq/execute-quote'
CREATE_QUOTE = '/api/v5/rfq/create-quote'
CANCEL_QUOTE = '/api/v5/rfq/cancel-quote'
CANCEL_BATCH_QUOTES = '/api/v5/rfq/cancel-batch-quotes'
CANCEL_ALL_QUOTES = '/api/v5/rfq/cancel-all-quotes'
GET_RFQS = '/api/v5/rfq/rfqs'
GET_QUOTES = '/api/v5/rfq/quotes'
GET_RFQ_TRADES = '/api/v5/rfq/trades'
GET_PUBLIC_TRADES = '/api/v5/rfq/public-trades'
MMP_RESET = '/api/v5/rfq/mmp-reset'
MARKER_INSTRUMENT_SETTING = '/api/v5/rfq/maker-instrument-settings'
# tradingBot-Grid-complete-testcomplete
GRID_ORDER_ALGO = '/api/v5/tradingBot/grid/order-algo'
GRID_AMEND_ORDER_ALGO = '/api/v5/tradingBot/grid/amend-order-algo'
GRID_STOP_ORDER_ALGO = '/api/v5/tradingBot/grid/stop-order-algo'
GRID_ORDERS_ALGO_PENDING = '/api/v5/tradingBot/grid/orders-algo-pending'
GRID_ORDERS_ALGO_HISTORY = '/api/v5/tradingBot/grid/orders-algo-history'
GRID_ORDERS_ALGO_DETAILS = '/api/v5/tradingBot/grid/orders-algo-details'
GRID_SUB_ORDERS = '/api/v5/tradingBot/grid/sub-orders'
GRID_POSITIONS = '/api/v5/tradingBot/grid/positions'
GRID_WITHDRAW_INCOME = '/api/v5/tradingBot/grid/withdraw-income'
#--------need to add:
GRID_COMPUTE_MARIGIN_BALANCE = '/api/v5/tradingBot/grid/compute-margin-balance'
GRID_MARGIN_BALANCE = '/api/v5/tradingBot/grid/margin-balance'
GRID_AI_PARAM = '/api/v5/tradingBot/grid/ai-param'
#stacking - all need to implement-testcomplete
STACK_DEFI_OFFERS = '/api/v5/finance/staking-defi/offers'
STACK_DEFI_PURCHASE = '/api/v5/finance/staking-defi/purchase'
STACK_DEFI_REDEEM = '/api/v5/finance/staking-defi/redeem'
STACK_DEFI_CANCEL = '/api/v5/finance/staking-defi/cancel'
STACK_DEFI_ORDERS_ACTIVITY = '/api/v5/finance/staking-defi/orders-active'
STACK_DEFI_ORDERS_HISTORY = '/api/v5/finance/staking-defi/orders-history'
# status-complete
STATUS = '/api/v5/system/status'

44
okx/exceptions.py Normal file
View File

@ -0,0 +1,44 @@
# coding=utf-8
class OkxAPIException(Exception):
def __init__(self, response):
print(response.text + ', ' + str(response.status_code))
self.code = 0
try:
json_res = response.json()
except ValueError:
self.message = 'Invalid JSON error message from Okx: {}'.format(response.text)
else:
if "code" in json_res.keys() and "msg" in json_res.keys():
self.code = json_res['code']
self.message = json_res['msg']
else:
self.code = 'None'
self.message = 'System error'
self.status_code = response.status_code
self.response = response
self.request = getattr(response, 'request', None)
def __str__(self): # pragma: no cover
return 'API Request Error(code=%s): %s' % (self.code, self.message)
class OkxRequestException(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return 'OkxRequestException: %s' % self.message
class OkxParamsException(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return 'OkxParamsException: %s' % self.message

63
okx/utils.py Normal file
View File

@ -0,0 +1,63 @@
import hmac
import base64
import datetime
from . import consts as c
def sign(message, secretKey):
mac = hmac.new(bytes(secretKey, encoding='utf8'), bytes(message, encoding='utf-8'), digestmod='sha256')
d = mac.digest()
return base64.b64encode(d)
def pre_hash(timestamp, method, request_path, body,debug = True):
if debug == True:
print('body: ',body)
return str(timestamp) + str.upper(method) + request_path + body
def get_header(api_key, sign, timestamp, passphrase, flag,debug = True):
header = dict()
header[c.CONTENT_TYPE] = c.APPLICATION_JSON
header[c.OK_ACCESS_KEY] = api_key
header[c.OK_ACCESS_SIGN] = sign
header[c.OK_ACCESS_TIMESTAMP] = str(timestamp)
header[c.OK_ACCESS_PASSPHRASE] = passphrase
header['x-simulated-trading'] = flag
if debug == True:
print('header: ',header)
return header
def get_header_no_sign(flag,debug = True):
header = dict()
header[c.CONTENT_TYPE] = c.APPLICATION_JSON
header['x-simulated-trading'] = flag
if debug == True:
print('header: ',header)
return header
def parse_params_to_str(params):
url = '?'
for key, value in params.items():
if(value != ''):
url = url + str(key) + '=' + str(value) + '&'
url = url[0:-1]
#print('url:',url)
return url
def get_timestamp():
now = datetime.datetime.utcnow()
t = now.isoformat("T", "milliseconds")
return t + "Z"
def signature(timestamp, method, request_path, body, secret_key):
if str(body) == '{}' or str(body) == 'None':
body = ''
message = str(timestamp) + str.upper(method) + request_path + str(body)
mac = hmac.new(bytes(secret_key, encoding='utf8'), bytes(message, encoding='utf-8'), digestmod='sha256')
d = mac.digest()
return base64.b64encode(d)

522
websocket_example.py Normal file
View File

@ -0,0 +1,522 @@
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()