自己建立okx的api接口

目录

我们用python程序进行代币交易时,经常会用到ccxt等的库进行交易。但是,我经常遇到,因为库不完善一些功能现有的库无法实现,再有就是随着库的升级你编写的程序可能不能正常运行,我经常遇到这样的情况。于是,我想能不能自己建立最基础的api接口,然后再通过api接口来实现我们的特定要求。那我们来试一下吧。 通过学习okx的api文档,我们要如下操作:

创建自己的APIKey

打开这个链接:https://www.okx.com/zh-hans/account/my-api

如下图: Ashampoo_Snap_2026 03 21_18h34m59s_012_Chrome Legacy Window

创建APIKey后,您将获得3个必须记住的信息:

  • APIKey

  • SecretKey

  • Passphrase

APIKey和SecretKey将由平台随机生成和提供,Passphrase将由您提供以确保API访问的安全性。平台将存储Passphrase加密后的哈希值进行验证,但如果您忘记Passphrase,则无法恢复,请您通过交易网站重新生成新的APIKey。

注意APIKey 权限

APIKey 有如下3种权限,一个 APIKey 可以有一个或多个权限。

  • 读取 :查询账单和历史记录等 读权限

  • 提现 :可以进行提币

  • 交易 :可以下单和撤单,转账,调整配置 等写权限

为了我们资金的安全一定不要选择”提现“!!!

APIKey 安全性

  • 每个APIKey最多可绑定20个IP地址,IP地址支持IPv4/IPv6和网段的格式。 未绑定IP且拥有交易或提币权限的APIKey,将在闲置14天之后自动删除。(模拟盘的 API key 不会被删除)

  • 用户调用了需要 APIKey 鉴权的接口,才会被视为 APIKey 被使用。

  • 调用了不需要 APIKey 鉴权的接口,即使传入了 APIKey的信息,也不会被视为使用过。

  • Websocket 只有在登陆的时候,才会被视为 APIKey 被使用过。在登陆后的连接中做任何操作(如 订阅/下单),也不会被认为 APIKey 被使用,这点需要注意。

用户可以在 安全中心 中看到未绑定IP且拥有交易/提现权限的 APIKey 最近使用记录。

REST 请求验证

发起请求

所有REST私有请求头都必须包含以下内容:

  • OK-ACCESS-KEY字符串类型的APIKey。

  • OK-ACCESS-SIGN使用HMAC SHA256哈希函数获得哈希值,再使用Base-64编码(请参阅签名)。

  • OK-ACCESS-TIMESTAMP发起请求的时间(UTC),如:2020-12-08T09:08:57.715Z

  • OK-ACCESS-PASSPHRASE您在创建API密钥时指定的Passphrase。

所有请求都应该含有application/json类型内容,并且是有效的JSON。

签名

OK-ACCESS-SIGN的请求头是对timestamp + method + requestPath + body字符串(+表示字符串连接),以及SecretKey,使用HMAC SHA256方法加密,通过Base-64编码输出而得到的。

如:sign=CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA256(timestamp + ‘GET’ + ‘/api/v5/account/balance?ccy=BTC’, SecretKey))

其中,timestamp的值与OK-ACCESS-TIMESTAMP请求头相同,为ISO格式,如2020-12-08T09:08:57.715Z。

method是请求方法,字母全部大写:GET/POST。

requestPath是请求接口路径。如:/api/v5/account/balance

body是指请求主体的字符串,如果请求没有主体(通常为GET请求)则body可省略。如:{“instId”:”BTC-USDT”,”lever”:”5”,”mgnMode”:”isolated”}

GET请求参数是算作requestPath,不算body SecretKey为用户申请APIKey时所生成。如:22582BD0CFF14C41EDBF1AB98506286D

程序

获取apikey等相关参数

OKX_API_KEY= # 你的API_KEY OKX_SECRET_KEY= # 你的Secret_KEY OKX_PASSPHRASE= # 你的Passphrase

获取时间戳

我们可以定义一个函数来获取时间戳:

import time  
  
def get_timestamp():
  
      return time.strftime('%Y-%m-%dT%H:%M:%S.000Z', time.gmtime())

构造签名函数

import hmac
import base64

def sign(timestamp, method, path, body=""):  

    message = timestamp + method + path + body  
    mac = hmac.new(
        SECRET_KEY.encode(),
        message.encode(),
        hashlib.sha256
    )  
    
    return base64.b64encode(mac.digest()).decode()

构造headers函数

def get_headers(method, path, body=""):

    timestamp = get_timestamp()
    method=method.upper()

    return {
        "OK-ACCESS-KEY": API_KEY,
        "OK-ACCESS-SIGN": sign(timestamp, method, path, body),
        "OK-ACCESS-TIMESTAMP": timestamp,
        "OK-ACCESS-PASSPHRASE": PASSPHRASE,
        "Content-Type": "application/json"
    }

构造request函数

import josn

session = requests.Session()
session.proxies=proxies
def request(method, path, params=None):

    url = BASE_URL + path
    method=method.upper()
    # 构建完整URL
    if method == "GET" and params:
        query_string = urlencode(params)
        full_path = f"{path}?{query_string}"
        url = f"{BASE_URL}{full_path}"
        body_str = ""
    else:
        full_path = path
        url = f"{BASE_URL}{path}"
        body_str = json.dumps(params) if params else ""

    headers = get_headers(method, full_path, body_str)
    # 确保Content-Type正确
    headers["Content-Type"] = "application/json"
    # print('url=',url)
    # print('body_str=',body_str)
    try:
        if method == "GET":
            r = session.get(url,headers=headers,timeout=10)
        else:
            # body = json.dumps(params) if params else ""
            r = session.post(url,headers=headers,data=body_str,timeout=10)

        # 检查HTTP状态码
        r.raise_for_status()
        # 解析响应
        result = r.json()
        # 检查API返回码
        if result.get('code') != '0':
            print(f"API错误: {result.get('msg', '未知错误')}")
        return result

    except requests.exceptions.RequestException as e:
        print(f"请求异常: {e}")
        return {"code": "-1", "msg": str(e)}
    except json.JSONDecodeError as e:
        print(f"JSON解析错误: {e}")
        return {"code": "-1", "msg": "响应解析失败"}
    except Exception as e:
        print(f"未知错误: {e}")
        return {"code": "-1", "msg": str(e)}

    return r.json()

函数调用

这样我们的接口函数就构造完成了,只要知道paht,method,和一些参数就可以访问了。下面我们以查询账户余额为例说明如何调用接口函数。

BASE_URL='https://www.okx.com'
path=path = "/api/v5/account/balance"
method='GET'

def get_balance(ccy):

    """
    查询指定币种余额
    ccy: 币种,比如 'BTC'、'USDT'
    """
    ccy=ccy.upper()
    path = "/api/v5/account/balance"
    params={'ccy':ccy}
    data=request("get",path,params)
    if data['code']!='0':
        print("获取余额失败:", data['msg'])
        return None
    else:
        return data['data'][0]['details'][0]['availBal']

这样,我们自己构造的api接口函数就完成了,使用也很简单。我们可以根据自己的需要随意构建自己需要的函数。

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦