Giter Site home page Giter Site logo

python-okx's Introduction

Overview

This is an unofficial Python wrapper for the OKX exchange v5 API

If you came here looking to purchase cryptocurrencies from the OKX exchange, please go here.

Source code

https://github.com/okxapi/python-okx

OKX API Telegram

https://t.me/OKXAPI

API trading tutorials

Make sure you update often and check the Changelog for new features and bug fixes.

Features

  • Implementation of all Rest API endpoints.
  • Private and Public Websocket implementation
  • Testnet support
  • Websocket handling with reconnection and multiplexed connections

Quick start

Prerequisites

python version:>=3.9

WebSocketAPI: websockets package advise version 6.0

Step 1: register an account on OKX and apply for an API key

Step 2: install python-okx

pip install python-okx

Step 3: Run examples

  • Fill in API credentials in the corresponding examples
api_key = ""
secret_key = ""
passphrase = ""

Note

  • To learn more about OKX API, visit official OKX API documentation

  • If you face any questions when using WebSocketAPI,you can consult the following links

    • asynciowebsockets document/github

      https://docs.python.org/3/library/asyncio-dev.html
      https://websockets.readthedocs.io/en/stable/intro.html
      https://github.com/aaugustin/websockets
    • About code=1006

      https://github.com/Rapptz/discord.py/issues/1996
      https://github.com/aaugustin/websockets/issues/587

python-okx's People

Contributors

007live avatar dalton-cole avatar grzhan avatar kkathena avatar mumu212 avatar nort007 avatar okxapi avatar perryzhu avatar sharp-lee avatar woleo-z avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

python-okx's Issues

Unable to subscribe ws channels

Hi! I tried to run the test script for the public websocket in test/WsPublicTest.py. But it's unable to subscribe to the channels and kept on returning this ConnectionDone error:
WsClientFactory execute clientConnectionLost. Reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.],retried 1 times WsClientFactory execute clientConnectionLost. Reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.],retried 1 times 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.],retried 4 times ...
i'm using python 3.10.6 and python-okx 0.1.8

module 'okx.consts' has no attribute 'API_URL'

in _request
timestamp = self._get_timestamp()
File "C:\Users\Hearty\AppData\Local\Programs\Python\Python310\lib\site-packages\okx\client.py", line 52, in _get_timestamp
request_path = c.API_URL + c.SERVER_TIMESTAMP_URL
AttributeError: module 'okx.consts' has no attribute 'API_URL'

使用use_server_time=True以后出现上述问题,另外是否使用server_time区别是什么?

关于python api在**大陆只能使用VPN代理请求问题

image

为什么在浏览器上直接访问url可以得到返回结果,并且在**内陆可以不用代理而正常使用app。而python的api却需要使用VPN代理才能获取数据,否则就会出现如下错误,这是为什么?

result = marketapi.get_ticker(self.instid)

"C:\Users\Hearty\AppData\Local\Programs\Python\Python310\lib\site-packages\httpx_transports\default.py", line 77, in map_httpcore_exceptions
raise mapped_exc(message) from exc
httpx.ConnectError: [Errno 11004] getaddrinfo failed

How to add Stop Loss?

i am doing future trading, but i don't know how can i place stop loss?
symbol = "ADA"
result = tradeAPI.place_order( instId=f"{symbol}-USDT-SWAP", tdMode="isolated", side="buy", posSide="short", ordType="market", px="10", sz="100" )

client.py中的获取系统时间json解析是不是有问题?

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 ""

image

看起来应该是:
return response.json()['data'][0]['ts']

并且为什么use_server_time为True,会出现Timestamp request expired错误呢?

websocket不能用

websocket订阅报错:
WsClientFactory execute clientConnectionLost. Reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.

Trade API missing tag, clOrdId params for closing orders

Trade API missing tag, clOrdId params are missing for closing orders which leads to a loss in commission calculations. However, opening order has those params.

PROBLEM:
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)

while opening orders are ok and you can see that tag and clOrdId are present. Please update

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}

Add method for withdrawal status

Hello
Didn't found a method for GET /api/v5/asset/deposit-withdraw-status?wdId=200045249 to get a withdrawal status
Is there by chance in development or I am blind))?
Thank you

unable to run WsPublicTest.py, keeps returning clientConnectionLost

Hi! I tried to run the test script for the public websocket in test/WsPublicTest.py. But it's unable to subscribe to the channels and kept on returning this ConnectionDone error:

WsClientFactory execute clientConnectionLost. Reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.],retried 1 times
WsClientFactory execute clientConnectionLost. Reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.],retried 1 times
WsClientFactory execute clientConnectionLost. Reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.],retried 2 times
WsClientFactory execute clientConnectionLost. Reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.],retried 2 times
WsClientFactory execute clientConnectionLost. Reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.],retried 3 times
WsClientFactory execute clientConnectionLost. Reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.],retried 3 times
WsClientFactory execute clientConnectionLost. Reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.],retried 4 times
WsClientFactory execute clientConnectionLost. Reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.],retried 4 times
WsClientFactory execute clientConnectionLost. Reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.],retried 5 times
WsClientFactory execute clientConnectionLost. Reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.],retried 5 times
WsClientFactory execute clientConnectionLost. Reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.],retried 6 times
publicCallback {'e': 'error', 'm': 'reached max connect retries'}
WsClientFactory execute clientConnectionLost. Reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.],retried 6 times

Is there anyway to solve this and reproduce the test run? Thanks!


I'm using Python 3.9.1 with this packages:

autobahn==22.7.1
pyOpenSSL==22.1.0
requests==2.28.1
Twisted==22.10.0
service-identity==21.1.0

Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x000002278900B340>: Failed to establish a new connection: [WinError 10065] 套接字操作尝试一个无法连接的主机。

ConnectionError: HTTPSConnectionPool(host='www.okx.com', port=443): Max retries exceeded with url: /cn/api/v5/market/ticker?instId=BTC-USDT-SWAP (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x000002278900B340>: Failed to establish a new connection: [WinError 10065] 套接字操作尝试一个无法连接的主机。'))

Incorrect Timestamp Format in 'OK-ACCESS-TIMESTAMP' Header When use_server_time=True is Used

Description:

In the python-odx library, when creating an API instance (e.g., AccountAPI) with the use_server_time=True parameter, the OkxClient._get_timestamp method retrieves the server time as a Unix millisecond timestamp (e.g., "1607417337715"). However, the OKX API expects the 'OK-ACCESS-TIMESTAMP' request header to be in ISO 8601 format (e.g., "2020-12-08T09:08:57.715Z"). Due to this mismatch in the timestamp format, requests to the OKX API fail with error code 50102, indicating an expired timestamp.

Steps to Reproduce:

import okx.Account as Account

API_KEY = 'xxxxx'
SECRET_KEY = 'xxxxxx'
PASSPHRASE = 'xxxxxx'

flag = '0' 
accountAPI = Account.AccountAPI(API_KEY, SECRET_KEY, PASSPHRASE, flag=flag, use_server_time=True)

result = accountAPI.get_account_balance()
print(result)
  1. Initialize an AccountAPI instance with use_server_time=True.
  2. Perform any API request that requires the 'OK-ACCESS-TIMESTAMP' header.
  3. Observe that the OKX API returns an error code 50102, indicating that the request timestamp is expired.

Expected Behavior:

The OkxClient._get_timestamp method should correctly format the server time as an ISO 8601 timestamp to match the OKX API's expectations, ensuring that API requests with use_server_time=True succeed without timestamp-related errors.

Actual Behavior:

API requests fail with error code 50102 due to a mismatch in the expected timestamp format in the 'OK-ACCESS-TIMESTAMP' request header.

Possible Solution:

Adjust the OkxClient._get_timestamp method to convert the Unix millisecond timestamp to an ISO 8601 formatted string before including it in the 'OK-ACCESS-TIMESTAMP' header. This conversion should account for the necessary precision and timezone (UTC) to ensure compatibility with OKX API requirements.

Environment:

  • Library version: 0.2.8
  • Python version: 3.11.8
  • Operating System: Windows 11 Professional Edition

Additional Context:

This issue prevents all python-odx users from successfully making API requests with use_server_time=True, affecting operations that rely on accurate server time synchronization.

TypeError: Client.__init__() got an unexpected keyword argument 'proxy'

import okx.Funding as Funding

flag = "1" # live trading: 0, demo trading: 1

fundingAPI = Funding.FundingAPI(api_key, secret_key, passphrase, False, flag,proxy=None)

result = fundingAPI.get_currencies()
print(result)

run this get an error,

TypeError: Client.init() got an unexpected keyword argument 'proxy'

获取历史数据时的before和after参数应该是什么格式?

marketDataAPI.get_history_candlesticks(instId =symbol,after = after,before = before,bar='1Dutc',limit=100)
我使用这个函数获取某一个标的的日线数据,after和before按照官方文档都设置为l毫秒的Unix 时间戳,但提取的数据始终为空
时间戳的代码如下:
date_obj = datetime.strptime(date, "%Y-%m-%d") after = int(date_obj.timestamp()*1000)
请问应该如何呢?谢谢

Missing stop loss and take profit in Trade API

Referring to the official OKX REST API Documentation specifically to the "Place order" request, I see that many optional parameter are missing in the Python wrapper method (Trade.TradeAPI.place_order).

I'm developing a bot which is already working on Bybit exchange, I would like to integrate it also with OKX. For doing that I need the possibility to set stop loss and take profit when placing an order, so the parameter that are missing in the Python method are tpTriggerPx, tpOrdPx, tpTriggerPxType, slTriggerPx, slOrdPx and slTriggerPxType.

I am using what should currently be the latest version, 0.1.9. I really appreciate your work and look forward to this feature!

httpx.RemoteProtocolError

response = transport.handle_request(request)

File "C:\Users\Hearty\AppData\Local\Programs\Python\Python310\lib\site-packages\httpx_transports\default.py", line 217, in handle_request
with map_httpcore_exceptions():
File "C:\Users\Hearty\AppData\Local\Programs\Python\Python310\lib\contextlib.py", line 153, in exit
self.gen.throw(typ, value, traceback)
File "C:\Users\Hearty\AppData\Local\Programs\Python\Python310\lib\site-packages\httpx_transports\default.py", line 77, in map_httpcore_exceptions
raise mapped_exc(message) from exc
httpx.RemoteProtocolError: <ConnectionTerminated error_code:ErrorCodes.NO_ERROR, last_stream_id:1999,

Error during connection: Client.__init__() got an unexpected keyword argument 'proxy'

my code :

from flask import Flask, render_template, request, redirect, url_for, session, flash
import ccxt
import os
import datetime as dt
import pandas as pd
import pandas_ta as ta
import okx.Account as Account
import okx
from websocket import WebSocketApp

app = Flask(name)
app.secret_key = os.urandom(24)

SUPPORTED_EXCHANGES = ['binance', 'coinbasepro', 'okx', 'kraken', 'kucoin', 'bitfinex']

Global cache for WebSocket connections

websocket_connections = {}

Function to create a WebSocket connection with OKX

def create_okx_websocket(api_key, api_secret, passphrase):
ws_url = "wss://ws.okx.com:8443/ws/v5/private"
ws = WebSocketApp(ws_url)
return ws

Function to create a connection with OKX

def create_okx_connection(api_key, api_secret, passphrase):
flag = "1" # Production trading: 0, demo trading: 1
return okx.Account.AccountAPI(api_key, api_secret, passphrase, False, flag, proxy=False)

Function to create a CCXT exchange instance

def create_exchange_instance(exchange_name, api_key, api_secret, passphrase=None):
exchange_params = {
'apiKey': api_key,
'secret': api_secret,
'timeout': 30000,
'enableRateLimit': True,
}

if passphrase:
    exchange_params['password'] = passphrase

return getattr(ccxt, exchange_name)(exchange_params)

Function to get the connection status

def get_connection_status():
exchange_name = session.get("exchange_name")
if exchange_name:
return f"Connected to {exchange_name.capitalize()}"
else:
return "Not connected"

@app.route('/', methods=['GET', 'POST'])
def index():
error = None

if request.method == 'POST':
    exchange_name = request.form['exchange_name']
    api_key = request.form['api_key']
    api_secret = request.form['api_secret']
    passphrase = request.form['passphrase']

    try:
        if exchange_name == "okx":
            connection = create_okx_connection(api_key, api_secret, passphrase)
            websocket_connections[exchange_name] = create_okx_websocket(api_key, api_secret, passphrase)

            session.update({
                "exchange_name": exchange_name,
                "api_key": api_key,
                "api_secret": api_secret,
                "passphrase": passphrase,
            })

            flash(f"Successfully connected to {exchange_name.capitalize()}!", "success")
            return redirect(url_for('ia_control'))
        else:
            connection = create_exchange_instance(exchange_name, api_key, api_secret, passphrase)
            session["exchange_connection"] = connection
            flash(f"Successfully connected to {exchange_name.capitalize()}!", "success")
            return redirect(url_for('ia_control'))

    except Exception as e:
        error = f"Error during connection: {e}"

return render_template(
    'index.html',
    supported_exchanges=SUPPORTED_EXCHANGES,
    error=error,
    get_connection_status=get_connection_status,  # Pass the function, not the result
)

@app.route('/logout')
def logout():
session.clear() # Clear the session to log out
websocket_connections.clear() # Clear WebSocket connections
flash("You have been logged out.", "success")
return redirect(url_for('index'))

@app.route('/trade', methods=['GET', 'POST'])
def trade():
exchange_name = session.get('exchange_name')
api_key = session.get('api_key')
api_secret = session.get('api_secret')
passphrase = session.get('passphrase', None)

if not (exchange_name and api_key and api_secret):
    flash("Please connect to an exchange to use trading.", "error")
    return redirect(url_for('index'))

try:
    exchange = create_exchange_instance(exchange_name, api_key, api_secret, passphrase)
except Exception as e:
    flash(f"Error connecting to the exchange: {e}", "error")
    return redirect(url_for('index'))

if request.method == 'POST':
    symbol = request.form.get('symbol').upper()
    amount = float(request.form.get('amount'))
    stop_loss = request.form.get('stop_loss', None)
    take_profit = request.form.get('take_profit', None)

    try:
        order = exchange.create_market_buy_order(symbol, amount)

        if stop_loss:
            # Logic for stop-loss
            pass

        if take_profit:
            # Logic for take-profit
            pass

        flash("Market buy order placed successfully!", "success")
    except Exception as e:
        flash(f"Error placing order: {e}", "error")

return render_template('trade.html', get_connection_status=get_connection_status())

@app.route('/ia_control', methods=['GET'])
def ia_control():
exchange_name = session.get('exchange_name')
api_key = session.get('api_key')
api_secret = session.get('api_secret')
passphrase = session.get('passphrase', None)

if not (exchange_name and api_key and api_secret):
    flash("Please connect to an exchange to access this page.", "error")
    return redirect(url_for('index'))

try:
    exchange = create_exchange_instance(exchange_name, api_key, api_secret, passphrase)
    symbol = 'BTC/USDT'
    timeframe = '1h'
    since = dt.datetime.now() - dt.timedelta(days=7)

    ohlcv = exchange.fetch_ohlcv(symbol, timeframe)

    df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
    df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')

    df['rsi'] = df.ta.rsi(length=14)
    df['macd'], df['signal'], df['histogram'] = df.ta.macd(fast=12, slow=26, signal=9)
    df['sma_50'] = df.ta.sma(length=50)
    df['sma_200'] = df.ta.sma(length=200)

    recommendations = []

    if df['rsi'].iloc[-1] > 70:
        recommendations.append("RSI indicates overbought.")
    elif df['rsi'].iloc[-1] < 30:
        recommendations.append("RSI indicates oversold.")

    if df['macd'].iloc[-1] > df['signal']:
        recommendations.append("MACD suggests bullish momentum.")
    else:
        recommendations.append("MACD indicates bearish momentum.")

    return render_template(
        'ia_control.html',
        symbol=symbol,
        dataframe=df,
        recommendations=recommendations,
        get_connection_status=get_connection_status(),
    )

except Exception as e:
    flash(f"Error connecting to the exchange: {e}", "error")
    return redirect(url_for('index'))

if name == 'main':
app.run(debug=True)

websocket无法使用代理连接

WsClientFactory execute clientConnectionLost. Reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.
],retried 2 times

请教能用API实现涨幅榜吗?

app内的涨幅榜,不完善,只能用“今日涨跌”排序,来挑选涨幅前列的品种。

想实现:用15分钟涨幅,来排序(遍历所有的永续品种)。

不知道用API,有没有可能实现?

Error while try to subscribe to chanel tickers

  1. According to https://www.okx.com/docs-v5/en/#overview I use URL: wss://ws.okx.com:8443/ws/v5/public as public websocket API endpoint

  2. I connect to this URL, successfully

  3. According to manual https://www.okx.com/docs-v5/en/#websocket-api-subscribe I try to send to websocket data
    "{
    "op": "subscribe",
    "args": [
    {
    "channel": "tickers",
    "instId": "LTC-USD"
    }
    ]
    }"

  4. I see response with Error: "{"event":"error","msg":"channel:tickers,instId:LTC-USD doesn't exist","code":"60018"}"

What is wrong? I repeat steps from official guide

APIKey does not match current environment

调用 AccountAPI get_account_balance
报错:APIKey does not match current environment
用之前版本的 sdk 是可以正常运行的,不知道这是什么原因

response.status_code: 504

print('response.status_code:', response.status_code)
print('response.json.code:', response.json()['code'])
print('response.json.msg:', response.json()['msg'])

得到一个504的错误码,这个错误码在https://www.vkhwabf.cn/docs-v5/zh/#error-code-rest-public 中没有给出说明,并且导致后面索引okxapi级别的'code'时候出错。应该是这个response中的json不包含code和msg,但是错误码没有504代码也没有给出响应示例。

get_account_bills_archive can we add begin and end so we can find info within a specified timeframe?

# 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)

https://www.okx.com/docs-v5/en/?python#trading-account-rest-api-get-bills-details-last-3-months
in this docs begin and end we can utilize so be great if we can add these 2 into the params

whitelist address function

Hello
When trying to implement a withdrawl method, I do get response with { address is not whitelisted} is there any method or other solution how to get address whitelisted or perform withdrawl without whitelisting the address?

Timestamp request expired with input param useServerTime=True

Try to open the private WS connection with 'useServerTime=True' for trading, but got error response.
{"event":"error","msg":"Timestamp request expired","code":"60006","connId":"589e9aec"}
No such error observed if open the private WS connection with 'useServerTime=False'. What gets wrong here? Is there a way to sync the time with okx server and how?
Thanks

tradeDataWS = WsPrivateAsync(apiKey=API_KEY, passphrase=API_PASSPHRASE, secretKey=API_KEY_SECRET, url=tradeUrl, useServerTime=True)

Parameter posSide error

result = tradeAPI.place_order( instId="MATIC-USDT-SWAP", tdMode="isolated", side="buy", ordType="market", sz="1", tag=tag )

I have a this error [{'clOrdId': '', 'ordId': '', 'sCode': '51000', 'sMsg': 'Parameter posSide error

websocket 发送消息时 错误

调用 ws.subscribe(args, callback=privateCallback) 函数时
127.0.0.1 - - [08/Jun/2023 09:26:01] "POST /app/signal HTTP/1.1" 200 -
Unhandled Error
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/threading.py", line 1038, in _bootstrap_inner
self.run()
File "/Users/home-pc/Documents/python/pythonObject/tvProjict/venv/lib/python3.11/site-packages/okx/websocket/WsConnectManager.py", line 124, in run
reactor.run(installSignalHandlers=False)
File "/Users/home-pc/Documents/python/pythonObject/tvProjict/venv/lib/python3.11/site-packages/twisted/internet/base.py", line 1318, in run
self.mainLoop()
File "/Users/home-pc/Documents/python/pythonObject/tvProjict/venv/lib/python3.11/site-packages/twisted/internet/base.py", line 1328, in mainLoop
reactorBaseSelf.runUntilCurrent()
--- ---
File "/Users/home-pc/Documents/python/pythonObject/tvProjict/venv/lib/python3.11/site-packages/twisted/internet/base.py", line 967, in runUntilCurrent
f(*a, **kw)
File "/Users/home-pc/Documents/python/pythonObject/tvProjict/venv/lib/python3.11/site-packages/okx/websocket/WsConnectManager.py", line 114, in resetConnection
raise ValueError("instance must not none")
builtins.ValueError: instance must not none

WsClientFactory execute clientConnectionLost. Reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.
],retried 2 times
WsClientFactory execute clientConnectionLost. Reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.
],retried 3 times
WsClientFactory execute clientConnectionLost. Reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.
],retried 4 times
WsClientFactory execute clientConnectionLost. Reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.
],retried 5 times
loginSocket callback: {'e': 'error', 'm': 'reached max connect retries'}
WsClientFactory execute clientConnectionLost. Reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.
],retried 6 times

对于此SDK原生不支持代理及和clash for windows开启全局代理报错问题的解决方案

由于众所周知的原因,国内不能直接访问okx服务器,必须使用魔法工具,但这个库并不支持设置代理服务器,在本人尝试后得出以下解决方案,当然,这仅仅是为了方便开发和调试,生产环境需要考虑延迟和稳定性等因素建议直接使用国外VPS。
方案1:
直接开启clash for windows的TUN mode
方案2:
使用monkeypatch对本库底层进行修改,此法需要安装httpx的socks代理支持库 pip install httpx[socks]
代码如下

PROXY_HOST='localhost'
PROXY_PORT=7890
#为底层httpx库强行设置代理
os.environ['HTTP_PROXY']='socks5://{}:{}'.format(PROXY_HOST, PROXY_PORT)
os.environ['HTTPS_PROXY']='socks5://{}:{}'.format(PROXY_HOST,PROXY_PORT)
#打个猴子补丁强行为WebSocket设置代理
from okx.websocket.WsConnectManager import WsConnectManager

old_addConnection=WsConnectManager.addConnection

def ProxyMonkeyPatch(self, channel):
    self.factories[channel].proxy={'host':PROXY_HOST,'port':PROXY_PORT}
    old_addConnection(self, channel)

WsConnectManager.addConnection=ProxyMonkeyPatch

place order error ? or am i being idiot ?

result = tradeAPI.place_order(
instId="BCH-USDT-SWAP",
tdMode="cross",
side="buy",
ordType="market",
# reduceOnly=True,
sz=1
)
print(result)

throwing error :

Traceback (most recent call last):
File "/home/feca/PycharmProjects/OKX/xx_pg_place_order.py", line 20, in
result = tradeAPI.place_order(
File "/home/feca/PycharmProjects/OKX/env_OKX/lib/python3.10/site-packages/okx/Trade.py", line 19, in place_order
return self._request_with_params(POST, PLACR_ORDER, params)
File "/home/feca/PycharmProjects/OKX/env_OKX/lib/python3.10/site-packages/okx/client.py", line 46, in _request_with_params
return self._request(method, request_path, params)
File "/home/feca/PycharmProjects/OKX/env_OKX/lib/python3.10/site-packages/okx/client.py", line 39, in _request
response = self.client.post(request_path, data=body, headers=header)
File "/home/feca/PycharmProjects/OKX/env_OKX/lib/python3.10/site-packages/httpx/_client.py", line 1132, in post
return self.request(
File "/home/feca/PycharmProjects/OKX/env_OKX/lib/python3.10/site-packages/httpx/_client.py", line 801, in request
request = self.build_request(
File "/home/feca/PycharmProjects/OKX/env_OKX/lib/python3.10/site-packages/httpx/_client.py", line 347, in build_request
headers = self._merge_headers(headers)
File "/home/feca/PycharmProjects/OKX/env_OKX/lib/python3.10/site-packages/httpx/_client.py", line 414, in _merge_headers
merged_headers.update(headers)
File "/home/feca/PycharmProjects/OKX/env_OKX/lib/python3.10/site-packages/httpx/_models.py", line 200, in update
headers = Headers(headers)
File "/home/feca/PycharmProjects/OKX/env_OKX/lib/python3.10/site-packages/httpx/_models.py", line 71, in init
self._list = [
File "/home/feca/PycharmProjects/OKX/env_OKX/lib/python3.10/site-packages/httpx/_models.py", line 75, in
normalize_header_value(v, encoding),
File "/home/feca/PycharmProjects/OKX/env_OKX/lib/python3.10/site-packages/httpx/_utils.py", line 54, in normalize_header_value
return value.encode(encoding or "ascii")
AttributeError: 'int' object has no attribute 'encode'

there is a spelling mistake in the project file 'WsPprivateAsync'

actually it should be WsPrivateAsync

it is ok in the code:
class WsPrivateAsync:
def init(self, apiKey, passphrase, secretKey, url, useServerTime):
self.url = url
self.subscriptions = set()
self.callback = None
self.loop = asyncio.get_event_loop()
self.factory = WebSocketFactory(url)
self.apiKey = apiKey
self.passphrase = passphrase
self.secretKey = secretKey
self.useServerTime = useServerTime

but the py file is 'WsPprivateAsync.py'

TP/SL not showing when using tradeAPI.get_order_list()

Hi,

Does anyone know how to amend the TP and SL with the api. When i request my order lists i am not getting any of the TP or SL orders. Without them being listed i am unable to get the orderIDs to amend the orders. I also cant see a way to amend a positions with an equivalent tradeAPI.amend_position().

Any help would be really appreciated

httpx.ConnectError: [WinError 10054] 远程主机强迫关闭了一个现有的连接。

result = accountapi.get_account_balance(self.ccy)

File "C:\Users\Hearty\AppData\Local\Programs\Python\Python310\lib\site-packages\okx\Account.py", line 23, in get_account_balance
return self._request_with_params(GET, ACCOUNT_INFO, params)
File "C:\Users\Hearty\AppData\Local\Programs\Python\Python310\lib\site-packages\okx\client.py", line 49, in _request_with_params
return self._request(method, request_path, params)
File "C:\Users\Hearty\AppData\Local\Programs\Python\Python310\lib\site-packages\okx\client.py", line 38, in _request
response = self.client.get(request_path, headers=header)
File "C:\Users\Hearty\AppData\Local\Programs\Python\Python310\lib\site-packages\httpx_client.py", line 1045, in get
return self.request(
File "C:\Users\Hearty\AppData\Local\Programs\Python\Python310\lib\site-packages\httpx_client.py", line 821, in request
return self.send(request, auth=auth, follow_redirects=follow_redirects)
File "C:\Users\Hearty\AppData\Local\Programs\Python\Python310\lib\site-packages\httpx_client.py", line 908, in send
response = self._send_handling_auth(
File "C:\Users\Hearty\AppData\Local\Programs\Python\Python310\lib\site-packages\httpx_client.py", line 936, in _send_handling_auth
response = self._send_handling_redirects(
File "C:\Users\Hearty\AppData\Local\Programs\Python\Python310\lib\site-packages\httpx_client.py", line 973, in _send_handling_redirects
response = self._send_single_request(request)
File "C:\Users\Hearty\AppData\Local\Programs\Python\Python310\lib\site-packages\httpx_client.py", line 1009, in _send_single_request
response = transport.handle_request(request)
File "C:\Users\Hearty\AppData\Local\Programs\Python\Python310\lib\site-packages\httpx_transports\default.py", line 217, in handle_request
with map_httpcore_exceptions():
File "C:\Users\Hearty\AppData\Local\Programs\Python\Python310\lib\contextlib.py", line 153, in exit
self.gen.throw(typ, value, traceback)
File "C:\Users\Hearty\AppData\Local\Programs\Python\Python310\lib\site-packages\httpx_transports\default.py", line 77, in map_httpcore_exceptions
raise mapped_exc(message) from exc
httpx.ConnectError: [WinError 10054] 远程主机强迫关闭了一个现有的连接。

ws have no auto reconnect,need some example to handle

ERROR:asyncio:Task exception was never retrieved
future: <Task finished name='Task-6' coro=<WsPublicAsync.consume() done, defined at /root/anaconda3/lib/python3.9/site-packages/okx/websocket/WsPublicAsync.py:22> exception=ConnectionClosedError(None, Close(code=1011, reason='keepalive ping timeout'), None)>
Traceback (most recent call last):
  File "/root/anaconda3/lib/python3.9/site-packages/websockets/legacy/protocol.py", line 979, in transfer_data
    await asyncio.shield(self._put_message_waiter)
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/root/anaconda3/lib/python3.9/site-packages/okx/websocket/WsPublicAsync.py", line 23, in consume
    async for message in self.websocket:
  File "/root/anaconda3/lib/python3.9/site-packages/websockets/legacy/protocol.py", line 497, in __aiter__
    yield await self.recv()
  File "/root/anaconda3/lib/python3.9/site-packages/websockets/legacy/protocol.py", line 568, in recv
    await self.ensure_open()
  File "/root/anaconda3/lib/python3.9/site-packages/websockets/legacy/protocol.py", line 953, in ensure_open
    raise self.connection_closed_exc()
websockets.exceptions.ConnectionClosedError: sent 1011 (unexpected error) keepalive ping timeout; no close frame received

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.