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

退订:释放此订阅对象持有的引用;只有最后一个引用被释放时,才真正向交易所退订。

unsubscribe()

示例

  • 订阅ticker,收到10条后退订,改为订阅成交推送。

    javascript
    function main() { var tk = ctx.subscribe(exchange, {channel: "ticker"}) var n = 0 while (n < 10) { var ev = ctx.poll(tk, 1000) if (ev && ev.kind === 1) { Log("ticker", ev.last) n++ } } tk.unsubscribe() var trades = ctx.subscribe(exchange, {channel: "trade"}) while (true) { var t = ctx.poll(trades, 1000) if (t && t.kind === 4) { Log("trade", t.tradeId, t.side, t.px, t.qty) } } }
    python
    def main(): tk = ctx.subscribe(exchange, {"channel": "ticker"}) n = 0 while n < 10: ev = ctx.poll(tk, 1000) if ev is not None and ev.kind == 1: Log("ticker", ev.last) n += 1 tk.unsubscribe() trades = ctx.subscribe(exchange, {"channel": "trade"}) while True: t = ctx.poll(trades, 1000) if t is not None and t.kind == 4: Log("trade", t.tradeId, t.side, t.px, t.qty)
    rust
    fn main() { let tk = ctx::subscribe(exchange, ctx::SubOpts::ticker()).unwrap(); let mut n = 0; while n < 10 { match ctx::poll(&[tk.id()], Some(1000)) { ctx::Polled::Event(_) => n += 1, ctx::Polled::Stopped => return, _ => {} } } tk.unsubscribe().unwrap(); Log!("ticker unsubscribed after", n, "events"); }
  • 订阅归属于创建它的线程:在子线程中订阅相同内容会得到独立的事件流,且只能退订自己的订阅;主线程通过批量订阅返回的数组一次性退订两路订阅。

    javascript
    function main() { var subs = ctx.subscribe(0, {channel: "ticker", symbol: ["BTC_USDT", "ETH_USDT"]}) var t = threading.Thread(function() { // 线程里订阅同样的内容:得到自己的事件流,id与主线程的不同 var mine = ctx.subscribe(0, {channel: "ticker", symbol: "BTC_USDT"}) var id = mine.id mine.unsubscribe() // 自己的订阅可以退订 return id }) Log("main stream:", subs[0].id, "thread stream:", t.join().ret) subs.unsubscribe() // 主线程退订自己的两路 }
    python
    import threading def main(): subs = ctx.subscribe(0, {"channel": "ticker", "symbol": ["BTC_USDT", "ETH_USDT"]}) def worker(): # 线程里订阅同样的内容:得到自己的事件流,id与主线程的不同 mine = ctx.subscribe(0, {"channel": "ticker", "symbol": "BTC_USDT"}) Log("main stream:", subs[0].id, "thread stream:", mine.id) mine.unsubscribe() # 自己的订阅可以退订 try: subs[0].unsubscribe() # 订阅属于主线程,这里会抛出异常 except Exception as e: Log("cannot unsubscribe here:", e) t = threading.Thread(target=worker) t.start() t.join() subs.unsubscribe() # 主线程退订自己的两路

参考

备注

在同一线程内,身份相同(账户、品种、频道、档数、周期均相同)的订阅共用一路事件流,每调用一次ctx.subscribe即增加一个引用。unsubscribe()只释放本对象持有的那一个引用,共用同一路事件流的其他订阅对象不受影响,仍正常接收事件;其他线程订阅的相同内容也各自持有引用。所有引用都释放后,托管者才向交易所退订,此后迟到的事件将被丢弃。

只有创建该订阅的线程才能退订:在其他线程中调用会抛出异常(错误信息包含belongs to another thread),订阅仍保持有效。线程结束时,其所有订阅会自动退订。

批量订阅返回的数组同样提供unsubscribe()方法,可一次性退订数组中的全部元素(每个元素各释放一个引用)。

对同一订阅对象重复调用unsubscribe()不会产生任何效果;订阅被交易所拒绝(收到prefillStatus为2的初始化状态事件)后再调用,同样不产生任何效果。退订后不能再调用该对象的book()、positions()、balances()方法。

退订后再次订阅相同内容,将获得新的事件流ID。

Python中为sub.unsubscribe(),批量订阅返回的SubscriptionList同样提供unsubscribe()。Rust中为sub.unsubscribe() -> Result<(), String>,在其他线程中调用会返回Err。ctx::Sub可以复制,引用数按ctx::subscribe()的调用次数计算:每调用一次ctx::subscribe(),对应调用一次unsubscribe();不要对复制出的同一句柄重复退订。