资讯动态

OK交易所Python API封装实战:现货、杠杆与历史数据调用指南

发布时间:2026/9/23 23:37:56 来源:尧图企业网站定制
简介这份Python资源包围绕OKEx交易所Web API的调用展开面向希望用代码接入加密货币市场的开发者与量化交易初学者。内容覆盖杠杆交易、现货交易、历史记录与历史数据获取等核心场景并涉及MVC架构下的应用组织方式适合具备Python基础、想搭建自动化交易或行情分析工具的人群。压缩包共12个文件全部为py脚本整体约11KB按功能拆分为工具函数、常量定义、期货/现货/币币杠杆等业务接口、账户管理、WebSocket推送、客户端封装与异常处理等模块结构清晰便于按需查阅。目前已有187人学习下载。通过这份代码读者可以了解如何封装HTTP请求、组织交易指令、拉取K线与成交历史并参考异常处理与接口分层思路快速搭建自己的行情监控或策略回测脚本是入门交易所API对接的实用参考。1. 从一份 ok 交易所 Web API 的 Python 封装包说起很多人第一次接触 ok 交易所的 Web API都是被一个具体需求逼的想把手里的现货网格跑起来或者想拉一段分钟级 K 线做回测结果翻官方文档翻到一半就卡在签名和限频上。这份ok交易所的web api调用应用杠杆现货交易历史记录历史数据等等python.rar就是冲着这个场景来的——它把 okex 的 REST 和 WebSocket 接口用 Python 重新包了一层拆成spot_api.py、futures_api.py、swap_api.py、lever_api.py、account_api.py、ett_api.py几个模块外加utils.py、consts.py、client.py、exceptions.py这些公共件。换句话说你不用从零去拼 HMAC-SHA256 签名也不用自己维护限频队列导入对应类就能下单、查持仓、拉历史数据。适合两类人一是想快速验证策略、不想在底层通信上耗时间的量化新手二是已经会用 python 做数据分析、但没系统写过交易接口的从业者。下面按「这套包怎么组织 → 怎么跑起来 → 哪里会翻车」的顺序拆。2. 拆开这个包模块划分与 REST 签名机制2.1 目录结构与各模块职责拿到压缩包解压后根目录下是一组平铺的.py文件没有复杂的包层级这种设计对二次开发很友好——你可以直接把整个目录丢进自己项目的vendor/下也可以只挑需要的模块拷走。核心文件的分工大致是这样文件职责典型调用场景client.py底层 HTTP 会话、请求发送、限频控制被各 api 模块内部引用utils.py签名、时间戳、参数拼装、字典排序所有私有接口的前置处理consts.py域名、路径常量、业务枚举切换实盘/模拟盘时改这里exceptions.py自定义异常类型捕获 ok 返回的错误码spot_api.py现货下单、撤单、查订单、查成交现货交易主入口lever_api.py杠杆账户、借币还币、杠杆下单杠杆交易主入口futures_api.py交割合约相关接口合约持仓与委托swap_api.py永续合约相关接口永续持仓与委托account_api.py账户余额、账单流水资金核对ett_api.py组合账户相关接口特定业务线websocket.py行情与私有推送订阅实时行情、成交回报从工程角度看这套划分基本沿用了「按业务线拆 api、按公共职责拆工具」的思路。client.py和utils.py是被复用最多的两个文件改签名逻辑或换请求库通常只需要动这两处不会牵连到业务模块。这一点比很多把签名散落在每个接口里的老代码要清爽。2.2 REST 请求的签名与参数拼装ok 的私有接口要求对请求参数做签名流程是把参数按 key 的 ASCII 升序排列拼成keyvaluekeyvalue的字符串再拼上时间戳和密钥做 HMAC-SHA256。这套逻辑在utils.py里通常长这样import hmac import hashlib import base64 import time def sign(params: dict, secret_key: str, method: str GET) - dict: # 1. 补时间戳ok 要求 ISO8601 格式且与服务器时间偏差不能过大 params[timestamp] time.strftime(%Y-%m-%dT%H:%M:%S.000Z, time.gmtime()) # 2. 按 key 的 ASCII 升序排序这是签名能否通过的关键 sorted_items sorted(params.items(), keylambda x: x[0]) # 3. 拼成 keyvaluekeyvalue 形式 sign_str .join([f{k}{v} for k, v in sorted_items]) # 4. HMAC-SHA256 后 base64 编码 mac hmac.new(secret_key.encode(), sign_str.encode(), hashlib.sha256) params[sign] base64.b64encode(mac.digest()).decode() return params逻辑说明第一步补时间戳ok 服务端会校验请求时间与服务器时间的偏差偏差过大直接返回签名错误所以本地机器时间要准。第二步排序是签名最容易出错的地方Python 的sorted默认按字符串比较和 ok 要求的 ASCII 升序一致但如果参数里混入了非字符串类型比如 int 的杠杆倍数拼字符串前要先str()转换否则会抛类型错误。第三步拼接时value 里如果含特殊字符需要确认是否要 URL 编码——ok 的规则是签名用原始值发送时才编码这两步不能混。第四步的secret_key来自 API 管理页面只显示一次丢了只能重新生成。参数说明params是业务参数加时间戳的字典secret_key是私钥字符串method在部分实现里用于区分 GET 和 POST 的签名串构造ok 的 GET 和 POST 签名规则略有差异POST 的 body 也要参与签名。如果你拿到的包在 POST 请求上签名总失败先检查 body 是否被正确序列化并参与了签名串拼接。2.3 限频与请求节流ok 对每个接口都有频率限制比如现货下单通常是每秒若干次行情类接口按 IP 或按用户维度限。client.py里一般会维护一个简单的令牌桶或时间窗口计数器import time class RateLimiter: def __init__(self, max_calls: int, period: float): self.max_calls max_calls # 窗口内允许的最大请求数 self.period period # 窗口长度单位秒 self.calls [] # 记录每次请求的时间戳 def acquire(self): now time.time() # 剔除窗口外的旧记录 self.calls [t for t in self.calls if now - t self.period] if len(self.calls) self.max_calls: sleep_time self.period - (now - self.calls[0]) time.sleep(sleep_time) self.calls self.calls[1:] self.calls.append(time.time())逻辑说明每次发请求前调用acquire()如果当前窗口内请求数已达上限就 sleep 到最早那次请求滑出窗口为止。参数max_calls和period要按 ok 官方文档里对应接口的限制来设设大了会被服务端拒绝设小了会拖慢策略。常见做法是把限频值设成官方限制的 80% 左右留一点余量应对网络抖动和重试。3. 跑通第一笔现货与杠杆调用从初始化到下单3.1 初始化客户端与账户信息查询在动真金白银之前先用只读接口验证签名和网络是否通。以现货为例初始化通常需要 API Key、Secret Key 和 Passphrase 三样东西from spot_api import SpotAPI api SpotAPI( api_keyyour_api_key, secret_keyyour_secret_key, passphraseyour_passphrase, is_simulatedTrue # 先走模拟盘确认无误再切实盘 ) # 查询账户余额验证签名是否通过 balance api.get_account_info() print(balance)逻辑说明is_simulatedTrue时consts.py里的域名常量会指向模拟盘地址这一步能过滤掉大部分签名和权限问题。如果这里就报签名错误先别怀疑代码去检查三件事本地时间是否同步、API Key 是否绑定了 IP 白名单、Passphrase 是否输错。参数说明api_key和secret_key在 ok 的 API 管理页生成passphrase是创建时自己设的口令三者缺一不可。查询余额返回的是嵌套字典里面按币种列出可用、冻结、总额建议先打印完整结构再取值不要凭猜。3.2 现货下单与订单状态轮询签名通了之后下一笔最小额度的限价单。现货下单接口一般需要交易对、方向、价格、数量这几个参数# 下一笔限价买单价格和数量按交易对精度要求传 order api.take_order( instrument_idBTC-USDT, # 交易对 sidebuy, # buy 或 sell price20000, # 限价字符串形式避免精度丢失 size0.001, # 数量注意最小交易单位 order_type0 # 0 限价1 市价具体看常量定义 ) print(order) # 用返回的 order_id 查状态 detail api.get_order_info(instrument_idBTC-USDT, order_idorder[order_id]) print(detail)逻辑说明价格和数量用字符串传是因为浮点数在序列化时可能出现20000.0这种形式部分接口对格式敏感。order_type的取值以consts.py里的枚举为准不同业务线现货、杠杆、合约的枚举值可能不一样别跨模块套用。下单成功后返回的order_id是后续撤单和查询的唯一凭据建议落库保存不要只放内存。参数说明instrument_id是交易对标识现货是BTC-USDT这种格式size要满足最小交易量太小会被拒市价单不需要price但部分接口仍要求传占位值。3.3 杠杆交易的借币、下单与风控参数杠杆交易比现货多了一层借币逻辑流程是先查可借额度借入后下单平仓后还币。lever_api.py里通常会有对应方法from lever_api import LeverAPI lever LeverAPI(api_key, secret_key, passphrase, is_simulatedTrue) # 查某币种的可借额度和已借数量 info lever.get_borrow_info(currencyUSDT) print(info) # 借入 USDT用于加杠杆买入 lever.borrow(currencyUSDT, amount100, leverage3) # 杠杆限价买入 lever.take_order( instrument_idBTC-USDT, sidebuy, price20000, size0.005, order_type0 )逻辑说明杠杆倍数在借币时指定不同币种和交易对支持的倍数不同get_borrow_info返回里会标明上限。借币会产生利息按小时计所以借了不用会持续吃成本策略里要有还币逻辑。参数说明amount是借入数量leverage是杠杆倍数这两个参数共同决定你能开多大仓位。风控上杠杆账户有维持保证金率低于阈值会触发强平代码里要定期查get_account_info里的风险指标别等爆仓了才发现。4. 历史数据与 WebSocket回测数据源和实时推送4.1 拉取 K 线与成交历史历史数据是回测的粮食。ok 的 K 线接口一般支持按时间范围分页拉取spot_api.py里会有类似get_kline的方法# 拉取 BTC-USDT 的 1 分钟 K 线granularity 单位是秒 klines api.get_kline( instrument_idBTC-USDT, granularity60, # 60 秒 1 分钟 start2024-01-01T00:00:00.000Z, end2024-01-02T00:00:00.000Z ) for k in klines: print(k)逻辑说明granularity的取值是秒数常见的有 60、300、900、3600、86400对应 1 分钟到 1 天。分页拉取时单次返回条数有上限要循环调整start和end直到覆盖目标区间。返回的每条 K 线通常是[时间戳, 开, 高, 低, 收, 量]的数组落库前先确认字段顺序不同接口可能略有差异。参数说明时间用 ISO8601 格式带毫秒和 Z 后缀如果接口对单次时间跨度有限制就按天或按小时切片拉。4.2 WebSocket 订阅行情与私有回报实时性要求高的场景轮询 REST 不够用得走 WebSocket。websocket.py一般封装了连接、订阅、心跳和重连from websocket import WsClient def on_message(msg): # 行情推送和私有成交回报都从这里出来按 channel 区分 print(msg) ws WsClient( urlwss://real.okex.com:8443/ws/v3, api_keyapi_key, secret_keysecret_key, passphrasepassphrase ) ws.subscribe([spot/ticker:BTC-USDT, spot/order:BTC-USDT]) ws.run(on_message)逻辑说明公共频道行情不需要鉴权私有频道订单、持仓需要登录登录消息里要带签名。心跳一般每 30 秒发一次超时未收会断连所以run里要有重连逻辑。参数说明url在consts.py里定义模拟盘和实盘地址不同订阅频道字符串的格式要严格按文档写写错了不会报错只是收不到数据这种静默失败最坑。5. 避坑与排查签名、限频、精度这些血泪经验5.1 签名总失败先查时间和排序现象私有接口一律返回签名错误公共接口正常。原因九成是本地时间偏差超过服务端容忍范围或者参数排序时混入了非字符串值。解决先ntpdate同步时间再在utils.py的签名函数里打印排序后的sign_str和官方文档的示例逐字符比对。如果参数里有嵌套字典或数组确认序列化方式是否和文档一致。5.2 下单被拒多半是精度和最小量现象下单返回参数错误但价格数量看着没问题。原因交易对的价格精度和数量精度有单独限制比如 BTC-USDT 价格最多两位小数数量有最小交易单位。解决调get_instruments类接口拿到tick_size和lot_size下单前对价格和数量做取整或截断别用四舍五入截断更安全。5.3 限频触发后疯狂重试越试越封现象请求返回限频错误代码里立刻重试结果被封更久。原因限频是按时间窗口算的触发后立即重试会持续占用窗口。解决捕获限频异常后做指数退避第一次等 1 秒第二次 2 秒依次翻倍同时检查client.py里的限频器参数是否设得比官方限制还大。5.4 WebSocket 断连不重连策略变瞎子现象跑了一夜早上发现行情停在凌晨三点。原因WebSocket 连接被服务端断开后没有重连逻辑或者重连了但没重新订阅。解决在run方法里加心跳超时检测断连后重连并重新发送订阅消息重连间隔用退避策略别一秒连十次。5.5 模拟盘和实盘常量混用现象模拟盘跑通的代码切实盘后接口全 404。原因consts.py里模拟盘和实盘的域名、路径不同切换时只改了is_simulated但没同步改其他常量。解决把所有环境相关的常量集中到一处切换时只改一个开关别散落在各个模块里手动改。6. 把历史数据落库并做一次简单回测验证数据拉下来不落库下次还得重拉既慢又容易触发限频。我一般会先把 K 线写进 SQLite 或本地 Parquet再做策略验证。以 SQLite 为例import sqlite3 conn sqlite3.connect(klines.db) cur conn.cursor() cur.execute( CREATE TABLE IF NOT EXISTS kline ( instrument_id TEXT, ts INTEGER, open REAL, high REAL, low REAL, close REAL, volume REAL, PRIMARY KEY (instrument_id, ts) ) ) # klines 是前面接口返回的列表逐条插入用 INSERT OR IGNORE 去重 for k in klines: cur.execute( INSERT OR IGNORE INTO kline VALUES (?,?,?,?,?,?,?), (BTC-USDT, int(k[0]), float(k[1]), float(k[2]), float(k[3]), float(k[4]), float(k[5])) ) conn.commit()逻辑说明主键用(instrument_id, ts)保证同一交易对同一时间戳只存一条重复拉取时用INSERT OR IGNORE自动跳过省去手动比对。时间戳统一存整数秒查询时好做范围过滤。参数说明ts是 K 线起始时间戳ok 返回的可能是毫秒落库前统一转成秒避免后续查询时单位混乱。落库之后用一段简单的均线交叉验证数据可用性import pandas as pd df pd.read_sql(SELECT * FROM kline WHERE instrument_idBTC-USDT ORDER BY ts, conn) df[ma5] df[close].rolling(5).mean() df[ma20] df[close].rolling(20).mean() df[signal] (df[ma5] df[ma20]).astype(int) df[position] df[signal].shift(1) # 信号次日生效避免未来函数 df[ret] df[close].pct_change() * df[position] print(累计收益:, (1 df[ret]).prod() - 1)逻辑说明shift(1)是关键信号在收盘后产生次日才能持仓否则就是用未来数据回测结果虚高。参数说明ma5和ma20是短长均线窗口可以按策略调整position为 1 表示持有多头0 表示空仓。这段代码的目的不是验证策略赚不赚钱而是确认拉下来的数据在时间序列上连续、无重复、无缺口——如果pct_change出现异常大的跳变多半是数据有断档或单位错误。从那以后我每次拿到新的交易接口封装包都强制先跑一遍「查余额 → 下一笔最小单 → 撤单 → 拉一段 K 线落库」这条链路确认签名、精度、限频、数据格式四件事都对了再往上叠策略。这套 ok 的 Python 封装把底层通信的脏活包掉了但签名排序、精度截断、限频退避这些细节还是得自己心里有数。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价