币安 API 自动交易怎么起步?现货测试网、第一段代码、常见报错
先别拿真账户试代码。下面按四步走:分清测试网、模拟交易和正式账户;拿一把测试网密钥;用官方示例把签名算对;读懂发出去的请求和最常见的几种报错。代码只给最小示例,不含任何交易策略。
文 韩砚发布 约 11 分钟读完
在币安用 API 自动交易,起步那一下不该发生在真账户上。先去币安现货测试网拿一把测试密钥,把签名算对,发一笔「只校验、不成交」的测试单,确认从签名到发请求这一整条路都走通了,再谈策略。测试网里的余额是虚拟的,代码写错了,最坏也只是虚拟余额乱掉。
这篇不教策略,也不给能直接拿去交易的程序。只做四件事:分清三个地方,拿到测试密钥,把签名算对,看懂发出去的请求和返回的报错。

测试网、模拟交易、正式账户:先分清三个地方
币安给写程序的人准备了两个练手的地方:现货测试网(Spot Testnet)和现货模拟交易(Demo Mode)。它们和正式账户的 API 写法几乎一样,区别在钱和行情。
| 现货测试网 | 现货模拟交易 | 正式账户 | |
|---|---|---|---|
| REST 地址 | testnet.binance.vision/api | demo-api.binance.com/api | api.binance.com/api 等 |
| 钱 | 虚拟资产,每月重置一次 | 余额可以在界面上随时重置 | 真钱 |
| 价格和订单簿 | 独立于正式交易所 | 与正式交易所相似 | 真实行情 |
| 新功能 | 有时会先于正式交易所上线 | 与正式交易所功能相同 | — |
| 密钥在哪拿 | 测试网网站上登录后生成 | 登录币安账户,进入模拟交易的 API 管理页 | 币安账户的「API 管理」 |
前两列的对照取自币安官方 API 文档里的测试网说明和模拟交易说明。选哪个练手?如果你只是想把代码跑通、看懂签名和报错,测试网就够了。如果你想让程序面对接近真实的价格,模拟交易更合适,但它挂在你的币安账户下面,要先登录。
测试网还有几条限制,写代码前就该知道:
- 只有 API,没有网页界面。 官方 README 的原话是「现在只能通过 API 来测试交易,没有 UI」。你在测试网上的余额、订单,都只能用代码查。
- 只开放 /api 开头的接口。 /sapi 开头的接口(比如钱包、子母账户这一类)在测试网上用不了。
- 大约每月清空一次,不提前通知。 挂单、成交记录全部清掉,余额重新发放。测试网的更新日志里能看到重置记录,2026 年 10 月 7 日就重置过一次。别在测试网上存任何你在意的东西。
- 限频和过滤器「通常」与正式环境相同。 官方用的是「generally」这个词,也就是大体一致、不保证完全一致。
第一步:拿一把测试网密钥
测试网的密钥和正式账户的密钥是两套,互不通用。官方文档里的步骤只有两句:在 testnet.binance.vision 这个网站上登录并生成 API Key;然后照正式环境的文档写代码,把接口地址换成测试网的地址。
生成时会让你选密钥类型。币安支持三种:HMAC、RSA、Ed25519。区别在签名方式:
- HMAC 是对称方式。币安生成一把 secret key 交给你,你用它签名,币安用同一把验签。上手最简单,下面的示例就用它。
- Ed25519 和 RSA 是非对称方式。你在本地生成一对密钥,只把公钥交给币安,私钥始终留在你手里。
币安官方的「API Key 类型」说明写得很直接:不建议使用 HMAC keys,建议换成 Ed25519 或 RSA 这类非对称密钥。理由是对称方式下,那把 secret key 币安那边也有一份。练手时用 HMAC 无妨;等到要在正式账户上跑,值得换成 Ed25519。
拿到密钥后,别把它写进代码文件里。放进环境变量,代码运行时去读。哪怕是测试网的密钥也照这个习惯来,因为到了正式环境,一份不小心传到网上的代码,就等于把账户的操作权送了出去。
第二步:把签名算对
除了公开行情这类接口,币安 API 里凡是涉及你账户的请求,都要带一个 signature 参数,叫「签名请求」(SIGNED)。签名算错,服务器直接拒绝,返回 -1022。好在它有标准答案可以对:官方文档在 HMAC 一节给了一组示例密钥、一组示例参数,以及这组参数应该算出的签名。
规则分三步,照官方文档的说法:
- 把要发送的参数写成「参数=取值」,用
&连起来,这串文字叫 payload。参数里有中文这类非 ASCII 字符的,签名前要先做百分号编码。 - 用你的 secretKey 作为 HMAC-SHA256 的密钥,对 payload 签名,结果写成十六进制字符串。secretKey 和 payload 区分大小写,算出来的签名不区分。
- 把
signature=签名加到参数最后,连同 API Key 一起发出去。API Key 不放在参数里,放在请求头X-MBX-APIKEY里。
下面这段代码只用 Python 自带的库,把官方示例的 secretKey 和 payload 代进去,看能不能算出官方给的那个签名。
import hashlib
import hmac
# 币安 API 文档里给的示例密钥,只用来对答案,不是任何人的真密钥
secret = "NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j"
payload = ("symbol=LTCBTC&side=BUY&type=LIMIT&timeInForce=GTC"
"&quantity=1&price=0.1&recvWindow=5000×tamp=1499827319559")
signature = hmac.new(secret.encode(), payload.encode(), hashlib.sha256).hexdigest()
print(signature)
print(signature == "c8db56825ae71d6d79447849e617115f4a920fa2acdcab2b053c4b2838bd6b71")
c8db56825ae71d6d79447849e617115f4a920fa2acdcab2b053c4b2838bd6b71
True
第二行打印出 True,说明签名的算法写对了。以后你自己的程序报 -1022,先拿这段对一下:示例能算对、你的请求却不对,就查 secret 和 payload 两处:secret 有没有用错;payload 要看签名时用的参数和实际发出去的参数是否一致,比如签完名又往请求里加了一个参数,或者顺序、编码在签名之后被改了。官方文档对 -1022 的解释是:请求里带的签名和服务器按规则算出的不一致,通常是因为代码里用错了 secret。
payload 里那两个参数 timestamp 和 recvWindow,是下一步最容易出错的地方。
第三步:看懂一个签名请求由哪几部分组成
一个发往测试网的签名请求,拆开看只有五样东西:
| 组成部分 | 写什么 | 出错时会看到 |
|---|---|---|
| 地址 | https://testnet.binance.vision | 地址写成正式环境,用的却是测试网密钥:-2015 |
| 路径 | 比如 /api/v3/account、/api/v3/order/test | — |
| 参数 | 接口自己的参数 + timestamp + 可选的 recvWindow | 少了必填参数:-1102 |
| 签名 | 按上一步算出的 signature,放在参数最后 | 算错或参数被改:-1022 |
| 请求头 | X-MBX-APIKEY: 你的 API Key | Key 格式不对:-2014 |
timestamp 是发请求那一刻的时间,单位毫秒(也可以用微秒)。recvWindow 是这个请求的有效期,不写默认 5000 毫秒,最大 60000,官方不推荐超过 5 秒。服务器的判断规则写在文档的伪代码里:你的时间戳不能比服务器时间超前 1 秒以上,服务器收到请求的时间减去你的时间戳,也不能超过 recvWindow。两条有一条不满足,就返回 -1021。
第一次连测试网,建议按这个顺序发请求,每一步都能单独确认一件事:
GET /api/v3/ping:不用签名,返回空对象{}就说明网络通了。GET /api/v3/time:不用签名,返回服务器时间serverTime。拿它和你电脑的时间比一比,差得多就先校准系统时钟,省得后面撞上 -1021。GET /api/v3/account:要签名,只读账户信息,不会动你的资产。能返回余额,说明密钥和签名都对了。POST /api/v3/order/test:要签名。官方说明它会创建并校验一个新订单,但不会发送到撮合引擎。参数校验通过时返回空对象{},订单不会真的成交,哪怕在测试网上。
这四步走通,一个自动交易程序最底层的那一截就算接上了。之后不管你用自己写的代码还是官方的 SDK,都是在这一截上往上叠。
说到 SDK:币安在 GitHub 组织 binance 下维护 Python 连接库 binance-connector-python,现货部分是 binance-sdk-spot,要求 Python 3.10 及以上、低于 3.15(PyPI 上 13.2.0 版的标注,装之前以 PyPI 当期写的为准)。它的说明写明,不填 base_path 时默认连正式环境 api.binance.com。用它练手时,第一件事就是把地址换成测试网常量,否则你以为在测试,请求其实发进了正式环境。另有一个由个人维护的第三方 Python 库,它自己的说明里写着「非官方」(unofficial);用不用由你判断,但要清楚它不是币安提供的。
常见报错 -1022、-1021、-2015、429 怎么处理:按返回的那一行分
币安的错误返回是一段 JSON,里面有 code(错误码)和 msg(说明)。同一个错误码可能对应好几种说明,所以先看 code 定大类,再看 msg 找具体原因。下面按你最可能先碰到的顺序排。
完整原文是「Service unavailable from a restricted location according to ‘b. Eligibility’ in https://www.binance.com/en/terms. Please contact customer service if you believe you received this message in error.」。这是币安按你的网络出口位置判定为受限地区,直接拒绝服务,连 ping 都不会通,测试网也一样(2026 年 10 月从受限地区的网络出口请求测试网时返回的就是这一句)。它不是代码的问题,改代码没用。这句返回点名的是币安使用条款里「Eligibility(使用资格)」那一节;本站不教怎么绕开地区限制。
你的时间戳超出了有效期,或者比服务器时间超前了 1 秒以上(那时的说明是「…was 1000ms ahead of the server’s time」)。币安支持中心的处理建议是:多数情况是你电脑的时间和服务器不同步,先同步系统时钟;同步后还出现,可能是网络延迟,可以适当调整 recvWindow。别一上来就把 recvWindow 调到最大,官方不推荐使用 5 秒以上的 recvWindow。
回到第二步,用官方示例核对算法。算法没问题,就查 payload:签名之后有没有再改动参数,参数里有没有中文没做百分号编码,secret 有没有复制少一个字符。
官方中文说明列了三种可能:这把 Key 不存在;请求不是从允许的 IP 发出的;或者这个接口要的权限没开。练手时要留意第一种的一个变体:用测试网的 Key 去请求正式地址,或者反过来。到了正式账户,后两种也要留意:换了网络,请求不是从白名单里的 IP 发出的,或者想下单却没开交易权限(官方写明,API 密钥默认不能交易,要先在 API 管理里启用交易权限)。
请求被 API 拒绝,没到撮合引擎。每个交易对都有自己的价格步进、数量步进和最小订单金额,订单不满足其中一项就会被拒。msg 里写的是哪个过滤器,就去查哪一项:PRICE_FILTER 查价格上下限和步进,LOT_SIZE 查数量,NOTIONAL 查价格乘数量是否在允许范围内。各交易对的现行规则在 /api/v3/exchangeInfo 的返回里。
撮合引擎拒绝了新订单。-2010 后面的 msg 有好几种,这一种是余额不足;另几种常见的是「Market is closed.」(交易对暂停交易)和「Rest API trading is not enabled.」(官方说明是下单时服务器没有设置为允许访问 TRADE 接口)。测试网大约每月重置一次余额,重置前后余额会变。
-1003 和 429 说明请求超了限频,比如请求权重用超了;未成交订单数超限也会返回 429,-1003 还可能是排队的请求过多。请求权重按 IP 计算,不按 API Key 计算;未成交订单数则按账户统计。收到 429 之后,官方要求你停止发送请求;继续发就会被封 IP,返回 418,封禁时间从最短 2 分钟到最长 3 天,越频繁越长。418 和 429 的响应头里有 Retry-After,告诉你要等多少秒。币安支持中心还写明:被封之后改好代码也不能提前解封,只能等。
这一种在测试网上无所谓,到了正式账户最要命。官方英文文档专门强调:收到 5XX 时不要当作失败处理,执行状态是未知的,订单可能已经成功了。-1007 超时的说明也是「下单状态未知」。正确做法是先查一下订单状态,再决定要不要重发;直接重发,可能就下了两单。
从测试网切到正式环境,要改什么
测试网上跑通之后,切到真账户确实只改一行地址,但下面几件事要先想好:
- 密钥要重新申请,而且只开需要的权限。 正式账户的密钥在「API 管理」里创建,读取、交易、提现这些权限分开勾选。提现权限任何时候都别开,IP 白名单必须填,密钥不交给任何第三方,这是本站的立场。怎么申请、权限怎么勾、IP 白名单怎么填,见币安 API 怎么申请。
- 5XX 和超时要有处理逻辑。 测试网上你可以不管,正式账户上必须先查状态再重发。
- 请求权重按 IP 算。 同一台机器上跑几个程序,权重会叠加;未成交订单数则按账户统计。币安支持中心还提到三种限制:硬性限制、机器学习(ML)限制、WAF 限制。交易行为和普通用户偏差过大,可能被系统限制交易,从 5 分钟到 3 天不等。
- 想清楚密钥放在哪台机器上。 放在自己的电脑或自己租的服务器上,和填进别人的平台,是两回事;本站的建议是只放在自己的机器上。后一种意味着什么,见把 API 密钥交给第三方量化平台意味着什么。
本文依据币安在 GitHub 公开的官方 API 文档仓库 binance-spot-api-docs:REST 接口说明(rest-api_CN.md 与英文版 rest-api.md,中英冲突时官方声明以英文为准)、错误代码汇总(errors_CN.md)、测试网说明(testnet/general-info.md 与 testnet/CHANGELOG.md)、现货模拟交易说明(demo-mode/general-info_CN.md)、API Key 类型说明(faqs/api_key_types_CN.md),以及币安支持中心的《API 常见问题》和官方 Python 连接库的说明。签名示例的密钥、参数与期望签名逐字取自官方文档。文中的限频、recvWindow、封禁时长和 SDK 的版本要求,是 2026 年 10 月对照官方文档和 PyPI 写的;限频的现行值以 /api/v3/exchangeInfo 返回的 rateLimits 为准,其余以官方文档和 PyPI 当期写法为准。
正文没展开的三个问题
测试网里的币能提出来,或者转到正式账户吗?
不能。币安的测试网说明写明,测试网上的资金全部是虚拟的,不能转入,也不能转出测试网,只能在测试网内使用。
测试网里的挂单和成交记录怎么突然全没了?
测试网会定期重置成空白状态,挂单和成交记录全部清空,重置后自动重新发放资产。官方说明这种重置大约每月一次,而且不提前通知;从 2020 年 8 月起,重置时 API Key 会保留,不用重新申请。
官方有没有现成的 Python 库?
有。币安在 GitHub 组织 binance 下维护 binance-connector-python,现货部分的包叫 binance-sdk-spot,要求 Python 3.10 及以上、低于 3.15(PyPI 上 13.2.0 版的标注,以 PyPI 当期为准)。它默认连正式环境,用测试网要在配置里把 base_path 换成测试网地址。