输入/搜索内容
入门
欢迎使用发明者量化交易平台
快速开始
密钥安全性
平台基础
账号与计费
实盘计费与充值
子账号
交易所
通用协议
本地凭据文件
交易所特殊说明
证券与期货
加密货币
托管者
策略库
实盘
编写策略
开发工具
回测系统
进阶专题
数据与研究
对外接口

除了按固定间隔轮询,策略也可以等待事件到达后再处理,减少无效请求,也能更快地响应行情变化。

EventLoop

EventLoop 等待exchange.Go()、HttpQuery_Go()等并发任务完成、WebSocket 连接有可读数据、线程消息等事件;有事件时返回事件信息,策略再去读取对应的数据。第一次调用EventLoop()时才开始记录事件,所以先调用一次EventLoop(-1)再发起并发任务:

javascript
function main() { EventLoop(-1) // 开始记录事件,避免错过之后发生的事件 var r1 = exchange.Go("GetTicker") var r2 = exchange.Go("GetDepth") var ev = EventLoop(1000) // 等待任意一个并发任务完成,最多等 1 秒 Log("event:", ev) Log("ticker:", r1.wait(), "depth:", r2.wait()) }

ctx.subscribe / ctx.poll

JavaScript和Rust策略还可以使用托管者的事件订阅接口:ctx.subscribe()订阅某个账户、某个品种的行情或订单回报,返回流 ID;ctx.poll()取出下一条事件(可以设置等待超时),策略按事件的kind分别处理。Python策略不支持。

javascript
function main() { ctx.subscribe(0, "BTC_USDT", {channel: "ticker"}) // 第一个参数是账户在 exchanges 中的下标 ctx.subscribe(0, "", {channel: "orders"}) // 订单回报 while (true) { const ev = ctx.poll([], 1000) // [] 表示所有订阅,最多等 1 秒 if (!ev) { continue } if (ev.kind === 1) { Log("ticker:", ev.symbol, ev.bid, ev.ask, ev.last) } else if (ev.kind === 16) { Log("order:", ev.id, ev.state, ev.filledQty) } } }
  • channel可选"ticker"、"bbo"、"depth"、"trade"、"kline"(interval为周期秒数)、"orders"。
  • 事件的kind:1 为 ticker,3 为深度(事件只表示订单簿已更新,档位用ctx.book(ev.ex, ev.symbol, n)读取),4 为成交,5 为 K 线,16 为订单回报。
  • 行情类订阅消费不及时会只保留最新数据或丢弃最旧的数据,订单回报不会丢弃,策略需要持续调用ctx.poll()。

Rust策略中的写法为ctx::subscribe()、ctx::poll(),事件为原始结构,价格、数量是定点整数:

rust
fn main() { let s = ctx::subscribe(0, "BTC_USDT", ctx::SubOpts::ticker()).unwrap(); loop { match ctx::poll(&[s], Some(1000)) { ctx::Polled::Event(ev) => Log!("event kind:", ev.kind), ctx::Polled::Stopped => break, _ => {} } } }