币安API量化交易入门2026:从建Key到网格实盘(附9月440U福利·邀请码JN188)

为什么量化选币安
做量化,交易所的选择会直接决定策略上限。币安在三个维度上有明显优势:
REST 限速额度充足
币安现货 API 的限速额度可以从 exchangeInfo 直接读到,2026 年 9 月实测:
REQUEST_WEIGHT 6,000 / 分钟
ORDERS 100 / 10 秒
ORDERS 200,000 / 天
RAW_REQUESTS 300,000 / 5 分钟
对多品种轮询或高频撤挂单的策略,限速就是硬天花板,这个额度基本不会成为瓶颈。
⚠️ 不要跨交易所直接比「每分钟多少次」
各家的限速模型不同:币安用权重制(不同接口消耗不同权重),
Bybit 和 OKX 则按 IP / UID / 单接口 多个维度分别限制,还会区分账户等级。
这些口径无法换算成同一个数字做排名。写策略前请直接查对应交易所官方文档的具体接口限制,
不要依赖第三方文章(包括本文)的概括数字。
好处是币安在响应头里会实时告诉你用了多少权重,实测:
x-mbx-used-weight: 2
x-mbx-used-weight-1m: 2
每次请求都能读到这个值,写个自适应限流很容易——接近额度就主动降速,比被 418 封 IP 强。建议直接从 exchangeInfo.rateLimits 动态读上限,不要写死常量。
深度最好,滑点最小
BTC/USDT 是全市场深度最好的交易对之一。对网格、做市这类高频进出的策略,滑点是隐形成本,往往比手续费更贵。深度差的平台,回测赚钱实盘亏钱,多半就亏在这里。
文档和生态完善
REST + WebSocket 双协议,现货 / 合约 / 期权全覆盖,官方文档更新及时,Python / Node / Go 各语言 SDK 生态成熟。遇到问题基本都能搜到答案。
第一步:创建 API Key
创建流程
- 登录币安 → 头像 →「API 管理」
- 输入一个标签名(例如
grid-bot),点击「创建 API」 - 完成二次验证(Google Authenticator / 短信)
- 保存
apiKey和secretKey
⚠️ secretKey 只显示一次
关闭页面后再也看不到,只能删掉重建。创建时立刻存进密码管理器或写进 .env 文件。
三条安全设置(必做)
1. 绑定 IP 白名单
这是最重要的一条。在 API 设置里填入你服务器的固定 IP,绑定后即使 Key 泄露,其他 IP 也用不了。
没有固定 IP 的话(例如家用宽带),可以先用一台便宜的云服务器跑策略。不要为了图省事跳过这一步。
2. 权限最小化
- 只做数据分析 → 只勾「读取」
- 需要下单 → 加勾「现货交易」或「合约交易」
- 「提现」权限永远不要开——量化策略不需要提币,开了就是给自己埋雷
3. Key 不进代码库
写进 .env 并加入 .gitignore,不要硬编码在 .py 文件里。GitHub 上被爬走 API Key 导致资产损失的案例每个月都在发生。
# .env
BINANCE_API_KEY=your_api_key
BINANCE_SECRET_KEY=your_secret_key
import os
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.environ["BINANCE_API_KEY"]
SECRET_KEY = os.environ["BINANCE_SECRET_KEY"]
第二步:拉行情数据(不需要 API Key)
行情类接口是公开的,不用签名也不用 Key,适合先跑通再说。以下代码都是实测过的。
获取最新价格
import requests
r = requests.get(
"https://api.binance.com/api/v3/ticker/price",
params={"symbol": "BTCUSDT"},
timeout=10,
)
print(r.json())
实测返回:
{'symbol': 'BTCUSDT', 'price': '81141.99000000'}
注意价格是字符串不是浮点数。这是币安刻意的设计,避免浮点精度问题。做计算时建议转成 Decimal 而不是 float,尤其是涉及金额的地方。
获取 K 线数据
r = requests.get(
"https://api.binance.com/api/v3/klines",
params={"symbol": "BTCUSDT", "interval": "1h", "limit": 3},
timeout=10,
)
for row in r.json():
print(f"open={row[1]} high={row[2]} low={row[3]} close={row[4]}")
实测返回:
open=80656.86 high=81237.00 low=80502.87 close=81147.16
open=81147.16 high=81310.00 low=80934.24 close=81056.63
open=81056.63 high=81142.00 low=80831.14 close=81141.99
K 线返回的是数组不是对象,索引含义:
| 索引 | 含义 | 索引 | 含义 |
|---|---|---|---|
| 0 | 开盘时间(毫秒) | 5 | 成交量 |
| 1 | 开盘价 | 6 | 收盘时间 |
| 2 | 最高价 | 7 | 成交额 |
| 3 | 最低价 | 8 | 成交笔数 |
| 4 | 收盘价 | — | — |
坑提醒:最后一根 K 线是未完成的(还在变动中)。做信号计算时通常要丢掉它,否则会出现「回测赚钱、实盘乱开单」的经典问题。
常用公开接口一览
| 接口 | 用途 | 权重 |
|---|---|---|
GET /api/v3/ticker/price | 最新价格 | 2 |
GET /api/v3/klines | K 线数据 | 2 |
GET /api/v3/depth | 订单簿深度 | 5~250 |
GET /api/v3/exchangeInfo | 交易规则和精度 | 20 |
GET /api/v3/time | 服务器时间 | 1 |
第三步:签名请求与下单
涉及账户和交易的接口需要签名。这一步是新手最容易卡住的地方。
签名原理
币安用 HMAC-SHA256:把所有参数拼成 query string,用 secretKey 做签名,再把签名作为 signature 参数附上。
import hmac, hashlib, time, requests
def sign(params: dict, secret: str) -> str:
query = "&".join(f"{k}={v}" for k, v in params.items())
return hmac.new(secret.encode(), query.encode(), hashlib.sha256).hexdigest()
实测生成的签名是 64 位十六进制字符串,例如 11f08497a972cfe7fc22f9aa35b5995c...。
⚠️ 签名最常见的两个坑
① 参数顺序必须和实际发送的一致。签名时用的 query string 和最终请求的 query string 必须一字不差,用 dict 排序或字符串拼接时容易出错。
② timestamp 必须是币安服务器时间。本地时钟偏差超过 1 秒就会报 -1021 Timestamp for this request is outside of the recvWindow。
时间同步(必做)
def server_time_offset() -> int:
"""本地时间与币安服务器时间的毫秒差,启动时算一次"""
r = requests.get("https://api.binance.com/api/v3/time", timeout=10)
return r.json()["serverTime"] - int(time.time() * 1000)
OFFSET = server_time_offset()
def now_ms() -> int:
return int(time.time() * 1000) + OFFSET
实测服务器时间返回:{'serverTime': 1788519411561}。云服务器的时钟通常会漂移,建议每小时重新校准一次。
下单前必须读交易规则
这一步很多人跳过,然后被 -1013 Filter failure 卡住。币安对每个交易对有精度和最小金额限制,实测 BTC/USDT 的规则:
PRICE_FILTER tickSize=0.01 # 价格必须是 0.01 的整数倍
LOT_SIZE stepSize=0.00001 # 数量必须是 0.00001 的整数倍
minQty=0.00001 # 最小下单量
NOTIONAL minNotional=5.0 # 订单金额至少 5 USDT
用代码自动取并对齐:
from decimal import Decimal, ROUND_DOWN
def get_filters(symbol: str) -> dict:
r = requests.get(
"https://api.binance.com/api/v3/exchangeInfo",
params={"symbol": symbol}, timeout=10,
)
return {f["filterType"]: f for f in r.json()["symbols"][0]["filters"]}
def align(value: Decimal, step: str) -> Decimal:
"""按 stepSize / tickSize 向下取整,避免 -1013 报错"""
s = Decimal(step)
return (value / s).to_integral_value(rounding=ROUND_DOWN) * s
filters = get_filters("BTCUSDT")
qty = align(Decimal("0.0012345"), filters["LOT_SIZE"]["stepSize"])
print(qty) # 0.00123
限价单下单
⚠️ 两个容易误解的点
① 以下代码调的是现货接口(/api/v3/order),不是合约。合约要用 fapi 系列接口。
② LIMIT 不等于 Maker。下单价格若穿过盘口会立即成交,变成 Taker 按高费率收。
想确保只做 Maker,现货用 LIMIT_MAKER,合约用 Post Only。后文所有按 Maker 费率算的成本,都以“实际以 Maker 成交”为前提。
def place_order(symbol, side, price, quantity):
params = {
"symbol": symbol,
"side": side, # BUY / SELL
"type": "LIMIT",
"timeInForce": "GTC",
"quantity": str(quantity),
"price": str(price),
"timestamp": now_ms(),
}
params["signature"] = sign(params, SECRET_KEY)
r = requests.post(
"https://api.binance.com/api/v3/order",
params=params,
headers={"X-MBX-APIKEY": API_KEY},
timeout=10,
)
return r.json()
⚠️ 先用测试网跑通再上真钱
币安提供测试网 https://testnet.binance.vision,功能与主网一致但用的是模拟资金。
把 base URL 换成测试网,先跑通完整流程(下单 → 查单 → 撤单 → 查余额),确认无误再切主网。这一步能帮你省下真金白银。
常用交易接口
| 接口 | 方法 | 用途 |
|---|---|---|
/api/v3/order | POST | 下单 |
/api/v3/order | GET | 查询订单状态 |
/api/v3/order | DELETE | 撤单 |
/api/v3/openOrders | GET | 查询所有挂单 |
/api/v3/account | GET | 账户余额 |
第四步:一个能跑的网格框架
把上面的部件拼起来,做一个网格骨架。
🚨 这是「结构演示」,不是可以跑真钱的策略
下面代码有一个故意保留的致命缺陷:它把「下单」当成了「成交」。
限价单挂上去不等于成交,直接解除 place_order 注释拿去跑真钱,会出现:
买单未成交却记为持仓 → 后续卖出你账户里原本持有的币;部分成交被当成全部成交。
真实仓位必须以交易所返回的订单状态为准,具体见代码下方的说明。
重点看结构怎么拼,不要直接复制去实盘:
import time
from decimal import Decimal
SYMBOL = "BTCUSDT"
GRID_PCT = Decimal("0.005") # 0.5% 一格
ORDER_QTY = Decimal("0.001") # 每格数量
MAX_GRIDS = 5 # 最多持有几格
class GridBot:
def __init__(self):
self.filters = get_filters(SYMBOL)
self.base_price = self.get_price()
self.positions = [] # 已成交的买入价列表
def get_price(self) -> Decimal:
r = requests.get(
"https://api.binance.com/api/v3/ticker/price",
params={"symbol": SYMBOL}, timeout=10,
)
return Decimal(r.json()["price"])
def step(self):
price = self.get_price()
# 跌破一格 → 买入
if price <= self.base_price * (1 - GRID_PCT) and len(self.positions) < MAX_GRIDS:
qty = align(ORDER_QTY, self.filters["LOT_SIZE"]["stepSize"])
px = align(price, self.filters["PRICE_FILTER"]["tickSize"])
print(f"[BUY ] {qty} @ {px}")
# ⚠️ 实盘必须改成:下单 → 查询订单状态 → 确认 FILLED 后才记录持仓
# order = place_order(SYMBOL, "BUY", px, qty)
# if confirm_filled(order["orderId"]):
# self.positions.append(px)
self.positions.append(px) # 演示用:假设必成交(实盘不成立)
self.base_price = price
# 涨过一格且有持仓 → 卖出最低那笔
elif price >= self.base_price * (1 + GRID_PCT) and self.positions:
entry = min(self.positions)
if price > entry * (1 + GRID_PCT):
qty = align(ORDER_QTY, self.filters["LOT_SIZE"]["stepSize"])
px = align(price, self.filters["PRICE_FILTER"]["tickSize"])
print(f"[SELL] {qty} @ {px} (entry {entry})")
# ⚠️ 同上:确认成交后才能移除持仓
# order = place_order(SYMBOL, "SELL", px, qty)
# if confirm_filled(order["orderId"]):
# self.positions.remove(entry)
self.positions.remove(entry) # 演示用
self.base_price = price
def run(self, interval=5):
while True:
try:
self.step()
except Exception as e:
print("error:", e) # 生产环境请换成日志 + 告警
time.sleep(interval)
if __name__ == "__main__":
GridBot().run()
这个骨架缺什么(上真钱前必须补)
- 🔴 订单状态确认(最重要)——限价单挂上不等于成交。必须保存
orderId, 用GET /api/v3/order或 WebSocket 用户数据流确认状态, 并按executedQty(实际成交量)更新持仓。NEW/PARTIALLY_FILLED/FILLED/CANCELED/REJECTED必须分开处理—— 部分成交当全部成交处理,是网格策略爆仓的典型原因。 - 🔴 超时后不能盲重试——请求超时或 5xx 不代表下单失败,订单可能已经进了撮合引擎。
正确做法:每笔下单带唯一
newClientOrderId,异常后先用该 ID 查询而不是重发, 否则容易重复下单。同时要检查status_code和返回体里的code,不能拿到 JSON 就当成功。 - 断线重连——网络抖动、交易所维护都会中断,要有重试和状态恢复
- 持久化——进程重启后必须能恢复持仓状态,不能全靠内存
- 风控——最大回撤、单日亏损上限、异常波动暂停,缺一不可
- 日志和告警——出问题要第一时间知道,不能等亏完了才发现
网格策略最大的风险是单边下跌:价格一路跌,你一路接,最后满仓套牢。务必设置价格下限和最大持仓格数。
限速管理:别被封 IP
币安的限速是权重制不是次数制,不同接口消耗不同权重,上限 1,200 / 分钟。
好消息是每次响应都会告诉你用了多少:
resp = requests.get(url, params=params, timeout=10)
used = int(resp.headers.get("x-mbx-used-weight-1m", 0))
if used > 1000: # 接近上限主动降速
time.sleep(10)
超限的后果是递进的:
- 429——请求过于频繁,需要退避重试
- 418——收到 429 后继续请求,IP 被封,从 2 分钟递增到最长 3 天
收到 429 必须立刻停下退避,硬刚只会换来 418。建议实现指数退避,并在接近 1,000 权重时主动降频。
手续费:量化最容易被忽略的成本
高频策略的成本结构里,手续费的占比往往被低估。算笔账:
| 交易类型 | Maker | Taker | 说明 |
|---|---|---|---|
| 现货 | 0.1% | 0.1% | 持 BNB 抵扣后 0.075% |
| U 本位合约 | 0.02% | 0.05% | 可叠加 BNB 折扣 |
| JN188 返佣后 | 手续费返还 20% | 每天自动结算 | |
假设一个网格策略月交易量 100 万 USDT(对高频来说不算多)。 以下均为折扣前的毛手续费,未计 BNB 抵扣(现货 -25%),也未计滑点、价差和合约资金费:
| 项目 | 现货(0.1%) | 合约(Maker 0.02%) |
|---|---|---|
| 月手续费 | 1,000 USDT | 200 USDT |
| JN188 返还 20% | 200 USDT | 40 USDT |
| 一年返还 | 2,400 USDT | 480 USDT |
对量化来说,20% 返佣不是小钱,而是直接加在策略收益上的。很多网格策略的年化本身就在个位数到十几个点,省下的手续费可能就是盈亏的分界线。
而且这笔钱不需要你多做任何事——注册时填一个邀请码,之后每笔交易自动返还。
顺手拿:量化用户是 9 月 440U 活动最占便宜的群体
币安 9 月的新客福利活动,对量化用户格外友好。原因就在第二档的门槛。
| 档位 | 入金 | 交易量 | 奖励 | 对量化的难度 |
|---|---|---|---|---|
| 第一档 | 100U | 100U | 100U 仓位券 | 几分钟 |
| 第二档 | 1,000U | 50,000U | 再送 300U | 几小时 |
| 第三档 | 3,000U | 200,000U | 再送 40U | 看策略频率 |
5 万 USDT 的交易量,对手动交易者来说需要反复操作很多次,但对有一定频率的策略来说相对容易达到。
⚠️ 不要为了奖励刷量
完成 5 万 U 需要多久,取决于本金规模、行情波动率、网格宽度和实际成交率,
没有这些前提就无法给出时间估计。用1,000U 本金做出 5 万 U 意味着 50 倍名义周转,
频繁进出本身会带来滑点和行情风险。建议只在策略本来就会产生这些交易量时顺手领奖励,不要反过来为奖励加大交易。
成本参考:5 万 U 交易量若全部以合约 Maker 成交(0.02%),名义手续费约 10 USDT;走现货(0.1%)则约 50 USDT。实际成本还要加上滑点和价差。
但第三档要注意:在第二档基础上还要再做 15 万 U 才能拿 40U 现金券。 按现货基础费率算这 15 万 U 成本约 150 USDT,高于 40U 奖励; 若全部走合约 Maker 则约 30 USDT,但仍要计入滑点和行情风险。 策略本来就跑到这个量级就顺手领,不建议为这 40U 专门刷量。
完整的三档拆解和成本测算,见 币安 9 月 440U 新客福利全拆解。
活动截止 10 月 1 日,只限通过邀请链接注册的新用户。
常见问题
Q:API 交易需要额外付费吗?
不需要。API 交易和网页端交易的费率完全一样,都可以享受 BNB 抵扣和 JN188 的 20% 返佣。
Q:测试网的 API Key 和主网通用吗?
不通用。测试网(testnet.binance.vision)需要单独注册和申请 Key,资金也是模拟的。建议先在测试网跑通全流程再切主网。
Q:报错 -1021 Timestamp for this request is outside of the recvWindow 怎么办?
本地时钟和币安服务器有偏差。用 GET /api/v3/time 校准,代码见上文「时间同步」一节。云服务器建议每小时重新校准。
Q:报错 -1013 Filter failure 怎么办?
下单的价格或数量不符合交易对规则。用 exchangeInfo 取到 tickSize / stepSize / minNotional,按规则对齐后再下单,代码见上文「下单前必须读交易规则」。
Q:REST 和 WebSocket 该用哪个?
拉历史数据、下单撤单用 REST;实时行情和订单状态推送用 WebSocket。高频策略如果用 REST 轮询实时价格,很快就会撞上限速,应该改用 WebSocket 订阅。
Q:一定要绑 IP 白名单吗?
强烈建议绑。API Key 泄露的后果是资产损失,绑了 IP 之后即使 Key 被拿走,攻击者也用不了。这是成本最低、收益最大的一条安全措施。
Q:量化交易量能拿到活动奖励吗?
能。现货和合约的交易量都计入统计,API 下单和手动下单一视同仁。注意入金必须走链上充值或 C2C,内部转账不计入。
小结
搭一套能跑的币安量化系统,核心就四步:创建 Key 并做好安全设置 → 拉行情数据 → 签名下单 → 加上风控和监控。
技术上的坑主要集中在三处:时间同步、精度对齐、限速管理。这三个处理好,剩下的就是策略本身的事了。
成本上要记住两件事:手续费返佣是长期复利,注册时填邀请码是唯一的机会窗口;9 月的 440U 活动对量化用户门槛特别低,10 月 1 日就结束了。
相关阅读:
币安 9 月 440U 新客福利全拆解 |
币安返佣页(JN188 · 20% 永久返佣) |
币安手续费全攻略 |
币安注册教程 2026 |
全平台返佣对比
⚠️ 风险提示:本文代码为教学示例,不构成投资建议。量化策略存在亏损风险,网格策略在单边行情中可能大幅回撤。上真实资金前请先在测试网充分验证,并设置严格的风控参数。API Key 请务必绑定 IP 白名单且不开启提现权限。文中接口数据于 2026 年 9 月实测,币安可能调整接口规则,请以官方 API 文档为准。
代码范围:文中代码均为现货 API(/api/v3/*)演示,合约需改用 fapi 接口;网格示例为结构演示,未实现订单成交确认,不可直接用于实盘。
手续费测算:均为折扣前名义费用,未计 BNB 抵扣、返佣、滑点与资金费;Maker 费率以“实际以 Maker 成交”为前提(LIMIT 不保证 Maker)。
商业披露:本文包含邀请链接,通过链接注册本站可获得交易所返佣,不影响你的手续费费率。