exchange.IO("rate", ...)
按函数限制API函数的调用频率:rate为平滑限流,quota为额度限流。
exchange.IO(k, functionNames, maxCalls, period)
exchange.IO(k, functionNames, maxCalls, period, behavior)示例
-
rate模式限流 - 限制GetTicker每秒最多调用10次,超限返回null。
javascriptfunction main() { exchange.IO("rate", "GetTicker", 10, "1s") for (var i = 0; i < 20; i++) { var ticker = exchange.GetTicker("BTC_USDT") if (ticker) { Log("Ticker:", ticker.Last) } else { Log("Rate limit exceeded") } } }pythondef main(): exchange.IO("rate", "GetTicker", 10, "1s") for i in range(20): ticker = exchange.GetTicker("BTC_USDT") if ticker: Log("Ticker:", ticker["Last"]) else: Log("Rate limit exceeded")rustfn main() { let _ = exchange.IO(("rate", "GetTicker", 10, "1s")); for _i in 0..20 { // 超限时GetTicker返回Err match exchange.GetTicker("BTC_USDT") { Ok(ticker) => Log!("Ticker:", ticker.Last), Err(_) => Log!("Rate limit exceeded"), } } } -
rate模式限流 - 使用
delay参数,超限时自动等待而非返回null。javascriptfunction main() { exchange.IO("rate", "GetTicker", 10, "1s", "delay") for (var i = 0; i < 20; i++) { var ticker = exchange.GetTicker("BTC_USDT") Log("Call", i+1, "Ticker:", ticker.Last) } }pythondef main(): exchange.IO("rate", "GetTicker", 10, "1s", "delay") for i in range(20): ticker = exchange.GetTicker("BTC_USDT") Log("Call", i+1, "Ticker:", ticker["Last"])rustfn main() { let _ = exchange.IO(("rate", "GetTicker", 10, "1s", "delay")); for i in 0..20 { let ticker = exchange.GetTicker("BTC_USDT").unwrap(); Log!("Call", i + 1, "Ticker:", ticker.Last); } } -
多个函数共享限流额度。
javascriptfunction main() { // GetTicker和GetDepth共享限制,合计每秒最多10次 exchange.IO("rate", "GetTicker,GetDepth", 10, "1s") for (var i = 0; i < 20; i++) { if (i % 2 == 0) { Log("Ticker:", exchange.GetTicker("BTC_USDT")) } else { Log("Depth:", exchange.GetDepth("BTC_USDT")) } } }pythondef main(): exchange.IO("rate", "GetTicker,GetDepth", 10, "1s") for i in range(20): if i % 2 == 0: Log("Ticker:", exchange.GetTicker("BTC_USDT")) else: Log("Depth:", exchange.GetDepth("BTC_USDT"))rustfn main() { // GetTicker和GetDepth共享限制,合计每秒最多10次 let _ = exchange.IO(("rate", "GetTicker,GetDepth", 10, "1s")); for i in 0..20 { if i % 2 == 0 { Log!("Ticker:", exchange.GetTicker("BTC_USDT")); } else { Log!("Depth:", exchange.GetDepth("BTC_USDT")); } } } -
使用通配符限制所有API调用频率。
javascriptfunction main() { exchange.IO("rate", "*", 100, "1m") for (var i = 0; i < 10; i++) { exchange.GetTicker("BTC_USDT") exchange.GetDepth("BTC_USDT") exchange.GetAccount() Log("Round", i+1, "completed") Sleep(1000) } }pythondef main(): exchange.IO("rate", "*", 100, "1m") for i in range(10): exchange.GetTicker("BTC_USDT") exchange.GetDepth("BTC_USDT") exchange.GetAccount() Log("Round", i+1, "completed") Sleep(1000)rustfn main() { let _ = exchange.IO(("rate", "*", 100, "1m")); for i in 0..10 { let _ = exchange.GetTicker("BTC_USDT"); let _ = exchange.GetDepth("BTC_USDT"); let _ = exchange.GetAccount(); Log!("Round", i + 1, "completed"); Sleep(1000); } } -
quota模式 - 严格时间窗口对齐限流。
javascriptfunction main() { exchange.IO("quota", "GetTicker", 3, "1s") for (var i = 0; i < 10; i++) { var ticker = exchange.GetTicker("BTC_USDT") if (ticker) { Log(_D(), "Ticker:", ticker.Last) } else { Log(_D(), "Quota exceeded, waiting for next window") } Sleep(100) } }pythondef main(): exchange.IO("quota", "GetTicker", 3, "1s") for i in range(10): ticker = exchange.GetTicker("BTC_USDT") if ticker: Log(_D(), "Ticker:", ticker["Last"]) else: Log(_D(), "Quota exceeded, waiting for next window") Sleep(100)rustfn main() { let _ = exchange.IO(("quota", "GetTicker", 3, "1s")); for _i in 0..10 { match exchange.GetTicker("BTC_USDT") { Ok(ticker) => Log!(_D(None), "Ticker:", ticker.Last), Err(_) => Log!(_D(None), "Quota exceeded, waiting for next window"), } Sleep(100); } } -
quota模式 - 日内配额,每天指定时间重置。
javascriptfunction main() { exchange.IO("quota", "GetTicker", 1000, "@0815") var count = 0 while (true) { var ticker = exchange.GetTicker("BTC_USDT") if (ticker) { count++ Log("Call count:", count, "Ticker:", ticker.Last) } else { Log("Daily quota exceeded, waiting for reset at 08:15") Sleep(60000) // Wait 1 minute } Sleep(1000) } }pythondef main(): exchange.IO("quota", "GetTicker", 1000, "@0815") count = 0 while True: ticker = exchange.GetTicker("BTC_USDT") if ticker: count += 1 Log("Call count:", count, "Ticker:", ticker["Last"]) else: Log("Daily quota exceeded, waiting for reset at 08:15") Sleep(60000) # Wait 1 minute Sleep(1000)rustfn main() { let _ = exchange.IO(("quota", "GetTicker", 1000, "@0815")); let mut count = 0; loop { match exchange.GetTicker("BTC_USDT") { Ok(ticker) => { count += 1; Log!("Call count:", count, "Ticker:", ticker.Last); } Err(_) => { Log!("Daily quota exceeded, waiting for reset at 08:15"); Sleep(60000); // Wait 1 minute } } Sleep(1000); } } -
组合使用多个限流规则。
javascriptfunction main() { exchange.IO("rate", "GetTicker", 10, "1s") // GetTicker每秒10次 exchange.IO("rate", "GetDepth", 5, "1s") // GetDepth每秒5次 exchange.IO("rate", "CreateOrder", 2, "1s") // CreateOrder每秒2次 exchange.IO("quota", "*", 1000, "@0000") // 所有API每天00:00重置,限1000次 Log("Rate limits configured successfully") for (var i = 0; i < 5; i++) { exchange.GetTicker("BTC_USDT") exchange.GetDepth("BTC_USDT") Sleep(200) } }pythondef main(): exchange.IO("rate", "GetTicker", 10, "1s") # GetTicker每秒10次 exchange.IO("rate", "GetDepth", 5, "1s") # GetDepth每秒5次 exchange.IO("rate", "CreateOrder", 2, "1s") # CreateOrder每秒2次 exchange.IO("quota", "*", 1000, "@0000") # 所有API每天00:00重置,限1000次 Log("Rate limits configured successfully") for i in range(5): exchange.GetTicker("BTC_USDT") exchange.GetDepth("BTC_USDT") Sleep(200)rustfn main() { let _ = exchange.IO(("rate", "GetTicker", 10, "1s")); // GetTicker每秒10次 let _ = exchange.IO(("rate", "GetDepth", 5, "1s")); // GetDepth每秒5次 let _ = exchange.IO(("rate", "CreateOrder", 2, "1s")); // CreateOrder每秒2次 let _ = exchange.IO(("quota", "*", 1000, "@0000")); // 所有API每天00:00重置,限1000次 Log!("Rate limits configured successfully"); for _i in 0..5 { let _ = exchange.GetTicker("BTC_USDT"); let _ = exchange.GetDepth("BTC_USDT"); Sleep(200); } }
返回值
| 类型 | 描述 |
string / number / bool / object / array / any | 调用成功时返回指令的结果,调用失败时返回空值。 |
参数
| 名称 | 类型 | 必填 | 描述 |
k | string | 是 |
|
functionNames | string | 是 | API函数名(如 |
maxCalls | number | 是 | 一个周期内允许的最大调用次数,小于等于0时删除 |
period | string | 是 | 周期,写法同Go语言的时间长度: |
behavior | string | 否 | 超限时的行为: |
参考
备注
API限流控制(rate / quota模式)
javascript
exchange.IO("rate", functionNames, maxCalls, period, [behavior])
exchange.IO("quota", functionNames, maxCalls, period, [behavior])
- rate:平滑限流(令牌桶)。桶容量为突发量,按「次数/周期」的速度补充,开始时是满的。
- quota:额度限流。每个周期最多调用指定次数,周期按整点对齐(例如
1m在每分钟0秒重置,1d在UTC零点即北京时间8点重置)。
| 参数 | 类型 | 说明 |
|---|---|---|
| functionNames | string | 函数名,逗号分隔多个;*为兜底规则,只作用于没有单独规则的函数 |
| maxCalls | number / string | 时间周期内最大调用次数;rate可写"次数/突发";小于等于0删除规则 |
| period | string | 时间周期(500ms/1s/1h30m/1d)或每日重置时间点(@0815,北京时间) |
| behavior | string | 可选,delay超限时等待,默认返回null |
Buy/Sell的限流遵循CreateOrder的设置。Go遵循实际并发函数的设置。IO/api仅对exchange.IO("api", ...)生效。
规则按交易所对象分别设置,只在本次运行中有效。超限时默认报错并返回空值,错误信息形如rate limit exceeded: GetTicker 10/1s(quota规则为quota limit exceeded: ...,每日定点重置的规则形如quota limit exceeded: GetTicker 1000/day (resets at 0815));设置delay时等待到可以调用为止,停止实盘时等待会被打断。GetAccount与GetAssets是同一个请求,为其中任一个名字设置的规则对两者都生效。
可以限流的函数名
| 类别 | 函数名 |
|---|---|
| 行情 | GetTicker、GetTickers、GetDepth、GetTrades、GetRecords、GetMarkets、GetFundings |
| 账户 | GetAccount、GetAssets、GetPositions、SetMarginLevel |
| 交易 | CreateOrder(Buy、Sell也计入)、CancelOrder、ModifyOrder |
| 订单查询 | GetOrder、GetOrders、GetHistoryOrders |
| 条件单 | CreateConditionOrder、ModifyConditionOrder、CancelConditionOrder、GetConditionOrder、GetConditionOrders、GetHistoryConditionOrders |
| 自定义请求 | IO/api:只限制exchange.IO("api", ...),不影响其它exchange.IO()指令 |
| 兜底 | *:作用于没有单独规则的交易所请求 |
- 限流只作用于交易所对象发出的上述请求;
HttpQuery()、Dial()以及exchange.IO()的其它指令不受影响。 - 一次调用只按一条规则计数:有单独规则的函数不再计入
*。 - 通过
exchange.Go()并发调用时按实际调用的函数计数。