输入/搜索内容
内置函数
Global
Log
Market
Trade
Account
Futures
Exchange
IO
Network
Storage
Threads
exchange.Go
EventLoop
ctx.subscribe
ctx.poll
ctx.order
ctx.cancel
ctx.orderAsync
ctx.cancelAsync
Subscription
threading
Thread
ThreadLock
ThreadEvent
ThreadCondition
ThreadDict
Server
TA
Talib
OS
结构体
内置变量与常量
通用约定
交易所

监听事件:当任意WebSocket有可读数据,或exchange.Go()、HttpQuery_Go()等并发任务完成时返回。

EventLoop()
EventLoop(timeout)

示例

并发获取行情、深度和成交记录,并使用EventLoop依次取回完成事件。

javascript
function main() { var routine_getTicker = exchange.Go("GetTicker") var routine_getDepth = exchange.Go("GetDepth") var routine_getTrades = exchange.Go("GetTrades") // 并发任务在提交时即已登记:即使这里先执行Sleep(2000),之后的EventLoop也不会错过这些任务的完成事件 // Log("GetDepth:", routine_getDepth.wait()) 如果在这里提前调用wait函数取出GetDepth并发调用的结果, // 则此次GetDepth收到请求结果的事件不会再由EventLoop函数返回 var ts1 = new Date().getTime() var ret1 = EventLoop(0) var ts2 = new Date().getTime() var ret2 = EventLoop(0) var ts3 = new Date().getTime() var ret3 = EventLoop(0) Log("First concurrent task completed:", _D(ts1), ret1) Log("Second concurrent task completed:", _D(ts2), ret2) Log("Third concurrent task completed:", _D(ts3), ret3) Log("GetTicker:", routine_getTicker.wait()) Log("GetDepth:", routine_getDepth.wait()) Log("GetTrades:", routine_getTrades.wait()) }
python
import time def main(): routine_getTicker = exchange.Go("GetTicker") routine_getDepth = exchange.Go("GetDepth") routine_getTrades = exchange.Go("GetTrades") ts1 = time.time() ret1 = EventLoop(0) ts2 = time.time() ret2 = EventLoop(0) ts3 = time.time() ret3 = EventLoop(0) Log("First concurrent task completed:", _D(ts1), ret1) Log("Second concurrent task completed:", _D(ts2), ret2) Log("Third concurrent task completed:", _D(ts3), ret3) Log("GetTicker:", routine_getTicker.wait()) Log("GetDepth:", routine_getDepth.wait()) Log("GetTrades:", routine_getTrades.wait())
rust
fn main() { // Rust 中 exchange.Go 使用类型化 token(如 Go::GetTicker)而非方法名字符串,无参数时传入 () let routine_getTicker = exchange.Go(Go::GetTicker, ()); let routine_getDepth = exchange.Go(Go::GetDepth, ()); let routine_getTrades = exchange.Go(Go::GetTrades, ()); // 并发任务在提交时即已登记:即使这里先执行Sleep(2000),之后的EventLoop也不会错过这些任务的完成事件 // Log!("GetDepth:", routine_getDepth.wait(0)) 如果在这里提前调用wait函数取出GetDepth并发调用的结果, // 则此次GetDepth收到请求结果的事件不会再由EventLoop函数返回 let ts1 = Unix() * 1000; let ret1 = EventLoop(0); let ts2 = Unix() * 1000; let ret2 = EventLoop(0); let ts3 = Unix() * 1000; let ret3 = EventLoop(0); Log!("First concurrent task completed:", _D(ts1), ret1); Log!("Second concurrent task completed:", _D(ts2), ret2); Log!("Third concurrent task completed:", _D(ts3), ret3); Log!("GetTicker:", routine_getTicker.wait(0).unwrap()); Log!("GetDepth:", routine_getDepth.wait(0).unwrap()); Log!("GetTrades:", routine_getTrades.wait(0).unwrap()); }

返回值

类型描述

object

事件对象,其中Event为事件类型,例如{"Seq":1,"Event":"Exchange_GetTrades","ThreadId":0,"Index":3,"Nano":1682068771309583400},结构详见EventLoop-return;超时且无事件时返回空值。

参数

名称类型必填描述

timeout

number

否

超时时间(毫秒):为0时阻塞等待,直到有事件发生才返回;大于0时为最长等待时间;小于0时立即返回最近的事件。

参考

备注

exchange.Go()、HttpQuery_Go()等并发任务在提交时即已登记,即使任务在首次调用EventLoop()之前就已完成,也不会错过其完成事件。底层系统封装的队列结构每个线程最多缓存10240个事件,如果程序运行过程中未及时调用EventLoop()函数取出事件,超出上限时最早的事件会被丢弃。
EventLoop()函数的调用不会影响系统底层WebSocket的缓存队列,也不会影响exchange.Go()等并发函数的缓存,这些缓存中的数据仍需使用各自的方法取出。在EventLoop()函数返回之前已被取出的数据,不会再由EventLoop()函数产生返回事件。
EventLoop()函数的主要用途是通知策略层:系统底层已接收到新的网络数据,从而以事件驱动整个策略。当EventLoop()函数返回事件时,只需遍历所有数据来源,例如对WebSocket连接、exchange.Go()创建的对象尝试获取数据。
EventLoop()函数仅支持实盘。

在主函数main()中调用时,监听主线程的事件。在使用JavaScript语言编写的策略中,也可以在threading.Thread()函数所创建线程的执行函数中调用,此时监听当前线程的事件。

交易所的WebSocket推送通过ctx.subscribe订阅、通过ctx.poll取出;EventLoop()仅为柜台类(只提供推送接口)的交易所自动订阅当前交易对的行情和订单回报,不会为其他交易所订阅推送。在JavaScript、Rust中,同一线程内的EventLoop()与ctx.poll()从同一个事件队列获取事件,因此一个线程只应使用其中一种;Python的EventLoop()拥有独立的队列,与ctx.poll()互不争抢。