量化喵是独立第三方信息站,不是欧易(OKX)官方。站内含推广链接。 完整披露 →

欧易 · 基础

欧易模拟盘怎么用:先拿假钱把策略跑通

欧易的模拟盘(Demo Trading)用虚拟资金下单,和实盘用同一个登录账号,登录后直接切过去就能用。用脚本连它有两处和实盘不同:要在模拟环境里另建一把 API Key;每个请求要带上 x-simulated-trading: 1 这个请求头。第二处最容易出事,漏了它,请求打到的是实盘。

下面依次是入口、建 Key、ccxt 的连接写法和自检、REST 与 WebSocket 地址的差别,以及模拟盘验证不了的东西。

欧易模拟盘能做什么,不支持什么

欧易帮助中心《什么是模拟交易?》的说法是:模拟交易里可以交易现货、合约、期权等产品,并可以体验统一账户的各个模式;模拟盘中有一定数量和金额的虚拟交易资金。API 这一侧,API 文档的模拟盘交易一节写明目前可以进行 API 的模拟盘交易,部分功能不支持,例如提币、充值、申购赎回。

对写脚本的人,模拟盘适合确认这几件事:三个凭证填对没有、下单参数交易所收不收、返回的字段是不是你以为的结构、撤单和查单的顺序对不对。买卖方向写反、循环漏了退出条件这类错,在这里暴露出来只消耗虚拟资金。

模拟盘入口在哪,模拟盘 API Key 怎么建

帮助中心给的入口:

  • 网页端:打开欧易官网登录,点【交易】,在下拉菜单中选择【模拟交易】。
  • App:登录后在首页点左上角图标,进入个人中心,选择【模拟交易】。
  • 重置虚拟资金:点【资产】页面的重置按钮,可以更新模拟资产的币种和金额。

只想在界面上试网格、跟单这类内置策略,进到模拟交易里直接开就行。要用脚本连,还得在模拟环境里单独建一把 API Key,API 文档给的路径是:登录欧易账户 → 交易 → 模拟交易 → 个人中心 → 创建模拟盘 APIKey。文档的原话是「模拟盘API交易需要在模拟盘上创建APIKey」,两边各用各的 Key。建 Key 时权限和 Passphrase 怎么填,和实盘是同一套,见 API 量化入门。

ccxt 怎么连模拟盘:set_sandbox_mode 和自检

用 ccxt 连模拟盘,跟连实盘的区别有两处:多一行开关,以及凭证填的是模拟盘那把 Key。字段还是那三个:apiKey、secret,以及 password(建 Key 时设的 Passphrase,ccxt 里这个字段叫 password)。

import ccxt

# 注意:这三项要填模拟盘(Demo Trading)那把 Key,不是实盘的
okx = ccxt.okx({
    'apiKey':   '模拟盘的_apiKey',
    'secret':   '模拟盘的_secret',
    'password': '模拟盘的_Passphrase',   # 欧易特有,ccxt 里叫 password
})

# 关键一行:让 ccxt 给后续请求带上模拟盘标记头
okx.set_sandbox_mode(True)

# 自检:这一行必须打印 1,否则你还在实盘
print(okx.headers.get('x-simulated-trading'))

# 之后所有请求都带模拟盘标记,用的是虚拟资金
balance = okx.fetch_balance()
print('模拟盘 USDT 可用:', balance['USDT']['free'])

set_sandbox_mode(True) 这一行做的事,是让 ccxt 给后续所有请求都带上模拟盘标记头 x-simulated-trading: 1。欧易的模拟盘和实盘用的是同一个 REST 主机,请求落在哪个环境全看这个头,所以别想着靠 URL 分辨。加上它,你的查余额、下单、撤单全部走假钱;去掉它(或改成 False),同一份代码就回到真金。

你可能在别处见过「在初始化时把 sandboxMode 写进 options 里」的写法。那个写法切不到模拟盘:ccxt 里给请求加模拟盘标记头的动作,是 set_sandbox_mode() 这个方法自己做的,构造函数里写 options 根本不会调到它,头没加、标记也没置上,发出去的请求和实盘一模一样。所以别拿配置项代替上面那一行,老老实实调 okx.set_sandbox_mode(True),再用那句 print 自检。

漏掉 set_sandbox_mode(True) 会怎样:请求不带 x-simulated-trading: 1,不管填的是哪把 Key,它都被当成实盘请求。填的如果是实盘 Key,fetch_balance 返回的就是实盘余额,账户是空的时候最容易看走眼;下一步的下单也是真实订单。所以别靠「有没有报错」判断自己在哪一边,每次启动都把上面那行自检打印出来看,不是 1 就停。开关切好了还报鉴权错误,先查是不是把实盘那套凭证填进了模拟盘脚本,再对照 API 报错排查。

连接和自检通过后,下单、查单、撤单的代码和实盘是同一套,本站放在 API 量化入门 里,这里不重复。搬过来时留意一点:撤单接口的返回里没有订单状态字段(只有 ordId、clOrdId、sCode、sMsg 等),sCode 为 0 表示撤单请求被受理,要确认真撤掉了,得再查一次这笔订单。

模拟盘的 REST 和 WebSocket 地址

REST 和 WebSocket 区分环境的方式不一样,API 文档列的地址如下:

通道实盘模拟盘
RESThttps://openapi.okx.comhttps://openapi.okx.com,另加请求头 x-simulated-trading: 1
WebSocket 公共频道wss://ws.okx.com/ws/v5/publicwss://wspap.okx.com/ws/v5/public
WebSocket 私有频道wss://ws.okx.com/ws/v5/privatewss://wspap.okx.com/ws/v5/private
WebSocket 业务频道wss://ws.okx.com/ws/v5/businesswss://wspap.okx.com/ws/v5/business

REST 两边是同一个主机,看 URL 分不出环境,只能看请求头。WebSocket 反过来,模拟盘是 wspap.okx.com 这组单独的地址。自己写 WebSocket 连接时两处都要换:地址换成 wspap,登录用模拟盘那把 Key。用 WebSocket 订阅行情和订单的写法见 欧易 WebSocket 实时行情。

模拟盘验证不了什么

模拟盘能确认的是流程。下面三件它确认不了:

  • 成交价和滑点。模拟盘里的成交,不等于同一笔单在实盘盘口上能拿到的价格。实盘的滑点取决于当时的挂单深度和你的下单量,只能上了实盘用小额去量。
  • 冷门交易对的流动性。一笔单在模拟盘里成交了,说明不了实盘里这个交易对接不接得住同样的量。
  • 极端行情下的表现。插针、闪崩时的延迟和拒单,要靠脚本里的超时、重试和止损兜住,见 API 自动交易风控。
风险提示:模拟盘验证的是「流程对不对」,不是「能赚多少」,模拟盘里的盈亏不代表实盘结果。加密资产价格波动剧烈,本金可能大幅缩水;本文不构成投资建议。

从模拟盘切实盘的顺序

每次上新策略,建议按这个顺序走:

  • 模拟盘连续跑一段。跑通一次还不够,要让它连着跑够时间,覆盖几轮涨跌,确认下单、撤单、回调、余额变化全都符合预期。
  • 切实盘:一行开关 + 一套凭证。把 set_sandbox_mode(True) 去掉或改 False,同时把凭证换回实盘那把 Key(模拟盘的 Demo Trading Key 在实盘上用不了)。先在模拟盘验证过,切换时要动的就只有这两处。
  • 实盘第一次只用很小的钱。用你就算全亏了也不心疼的金额,把它当学费。模拟盘没法复现的滑点和深度,这时候才会露出来。
  • 盯着它跑头几天。别真撒手,确认实盘行为和模拟盘看到的一致,再逐步加码。

常见问题

模拟盘要单独申请 API Key 吗?

要单独建。模拟盘的 Key 必须在模拟环境里另建一把:登录欧易 → 交易 → 模拟交易 → 个人中心 → 模拟盘 API,在那里创建 Demo Trading API Key;官方给的就是这条路径,不是给实盘 Key 加个开关。更要留神的是,模拟盘和实盘用的是同一个 REST 主机,两边只靠请求头 x-simulated-trading: 1 区分,所以想靠 URL 看出自己在哪个环境是靠不住的。在 ccxt 里调 set_sandbox_mode(True) 会自动带上这个头,跑之前打印一次 okx.headers.get('x-simulated-trading'),不是 1 就说明你还在实盘。

模拟盘的钱是真的吗?亏了用补吗?

模拟盘用的是虚拟资金,不是真钱,亏了不会从你的真实账户扣。欧易帮助中心《什么是模拟交易?》写的是:模拟盘中会有一定数量和金额的虚拟交易资金,点击【资产】页面的重置按钮,即可更新模拟资产的币种和金额。

模拟盘的 WebSocket 地址和实盘一样吗?

不一样。按欧易 API 文档,REST 两边都是 https://openapi.okx.com,靠请求头 x-simulated-trading: 1 区分;WebSocket 则是另一组地址,实盘是 wss://ws.okx.com/ws/v5/public、private、business,模拟盘是 wss://wspap.okx.com/ws/v5/public、private、business。自己写 WebSocket 连接时,模拟盘要换成 wspap 这组地址,并用模拟盘那把 Key 登录。

set_sandbox_mode 和配置里的 sandboxMode 有什么区别?

不等价,只在配置里写 sandboxMode 不会切到模拟盘。ccxt 的 set_sandbox_mode() 是个方法:它把接口地址切到测试那一组,把 options 里的 sandboxMode 设上,并给 headers 加上 x-simulated-trading: 1。加这个头的动作只发生在这个方法里。而在构造函数的 options 里写 sandboxMode 根本不会调到这个方法,头没加、标记也没置上,发出去的请求和实盘一模一样。所以只用 okx.set_sandbox_mode(True),写完打印一次 okx.headers.get('x-simulated-trading') 自检,是 1 才算切过去了。

模拟盘跑通了,切实盘要改几行代码?

代码本身只动一行,把 set_sandbox_mode(True) 去掉或改成 False;但凭证要跟着换,模拟盘那把 Demo Trading Key 在实盘上用不了,得填回实盘的 apiKey、secret 和 Passphrase。这正是先在模拟盘跑的好处:验证逻辑时用假钱,确认无误后改一行就上真金。但切实盘的第一次,务必只用很小的金额,并盯着它跑一阵,因为模拟盘没法复现真实的滑点和深度。