输入/搜索内容
内置函数
Global
Version
Sleep
IsVirtual
Mail
Mail_Go
SetErrorFilter
GetPid
GetLastError
GetCommand
GetMeta
Dial
HttpQuery
HttpQuery_Go
Encode
UnixNano
Unix
GetOS
MD5
DBExec
UUID
EventLoop
__Serve
_G
_D
_N
_C
_Cross
JSON.parse
JSON.stringify
SetChannelData
GetChannelData
Log
Market
Trade
Account
Futures
Threads
threading
Thread
getThread
mainThread
currentThread
Lock
Condition
Event
Dict
pending
Thread
ThreadLock
ThreadEvent
ThreadCondition
ThreadDict
TA
Talib
talib.CDL2CROWS
talib.CDL3BLACKCROWS
talib.CDL3INSIDE
talib.CDL3LINESTRIKE
talib.CDL3OUTSIDE
talib.CDL3STARSINSOUTH
talib.CDL3WHITESOLDIERS
talib.CDLABANDONEDBABY
talib.CDLADVANCEBLOCK
talib.CDLBELTHOLD
talib.CDLBREAKAWAY
talib.CDLCLOSINGMARUBOZU
talib.CDLCONCEALBABYSWALL
talib.CDLCOUNTERATTACK
talib.CDLDARKCLOUDCOVER
talib.CDLDOJI
talib.CDLDOJISTAR
talib.CDLDRAGONFLYDOJI
talib.CDLENGULFING
talib.CDLEVENINGDOJISTAR
talib.CDLEVENINGSTAR
talib.CDLGAPSIDESIDEWHITE
talib.CDLGRAVESTONEDOJI
talib.CDLHAMMER
talib.CDLHANGINGMAN
talib.CDLHARAMI
talib.CDLHARAMICROSS
talib.CDLHIGHWAVE
talib.CDLHIKKAKE
talib.CDLHIKKAKEMOD
talib.CDLHOMINGPIGEON
talib.CDLIDENTICAL3CROWS
talib.CDLINNECK
talib.CDLINVERTEDHAMMER
talib.CDLKICKING
talib.CDLKICKINGBYLENGTH
talib.CDLLADDERBOTTOM
talib.CDLLONGLEGGEDDOJI
talib.CDLLONGLINE
talib.CDLMARUBOZU
talib.CDLMATCHINGLOW
talib.CDLMATHOLD
talib.CDLMORNINGDOJISTAR
talib.CDLMORNINGSTAR
talib.CDLONNECK
talib.CDLPIERCING
talib.CDLRICKSHAWMAN
talib.CDLRISEFALL3METHODS
talib.CDLSEPARATINGLINES
talib.CDLSHOOTINGSTAR
talib.CDLSHORTLINE
talib.CDLSPINNINGTOP
talib.CDLSTALLEDPATTERN
talib.CDLSTICKSANDWICH
talib.CDLTAKURI
talib.CDLTASUKIGAP
talib.CDLTHRUSTING
talib.CDLTRISTAR
talib.CDLUNIQUE3RIVER
talib.CDLUPSIDEGAP2CROWS
talib.CDLXSIDEGAP3METHODS
talib.AD
talib.ADOSC
talib.OBV
talib.ACOS
talib.ASIN
talib.ATAN
talib.CEIL
talib.COS
talib.COSH
talib.EXP
talib.FLOOR
talib.LN
talib.LOG10
talib.SIN
talib.SINH
talib.SQRT
talib.TAN
talib.TANH
talib.MAX
talib.MAXINDEX
talib.MIN
talib.MININDEX
talib.MINMAX
talib.MINMAXINDEX
talib.SUM
talib.HT_DCPERIOD
talib.HT_DCPHASE
talib.HT_PHASOR
talib.HT_SINE
talib.HT_TRENDMODE
talib.ATR
talib.NATR
talib.TRANGE
talib.BBANDS
talib.DEMA
talib.EMA
talib.HT_TRENDLINE
talib.KAMA
talib.MA
talib.MAMA
talib.MIDPOINT
talib.MIDPRICE
talib.SAR
talib.SAREXT
talib.SMA
talib.T3
talib.TEMA
talib.TRIMA
talib.WMA
talib.LINEARREG
talib.LINEARREG_ANGLE
talib.LINEARREG_INTERCEPT
talib.LINEARREG_SLOPE
talib.STDDEV
talib.TSF
talib.VAR
talib.ADX
talib.ADXR
talib.APO
talib.AROON
talib.AROONOSC
talib.BOP
talib.CCI
talib.CMO
talib.DX
talib.MACD
talib.MACDEXT
talib.MACDFIX
talib.MFI
talib.MINUS_DI
talib.MINUS_DM
talib.MOM
talib.PLUS_DI
talib.PLUS_DM
talib.PPO
talib.ROC
talib.ROCP
talib.ROCR
talib.ROCR100
talib.RSI
talib.STOCH
talib.STOCHF
talib.STOCHRSI
talib.TRIX
talib.ULTOSC
talib.WILLR
talib.AVGPRICE
talib.MEDPRICE
talib.TYPPRICE
talib.WCLPRICE
OS
结构体
内置变量

exchange.Buy()函数用于下达买单。Buy()函数是交易所对象exchange的成员函数。

Buy()函数操作交易所对象exchange所绑定的交易所账户。exchange对象的成员函数(方法)的用途仅与exchange相关,后续文档中不再赘述。

exchange.Buy(price, amount)
exchange.Buy(price, amount, ...args)

示例

  • exchange.Buy()返回的订单编号,可用于查询订单信息和撤销订单。

    javascript
    function main() { // 由于是测试代码,未采用商品期货策略的通用架构,此处仅通过 exchange.IO("status") 函数判断,在成功连接期货公司前置机后立即执行测试代码。股票证券无需使用 exchange.IO("status") 判断连接状态 while (!exchange.IO("status")) { Sleep(1000) } // 设置合约代码 exchange.SetContractType("rb888") // 设置下单方向 exchange.SetDirection("buy") // 注意,此处的下单价格 100 仅为示例,实际测试时可自行设置和修改 var id = exchange.Buy(100, 1) Log("id:", id) }
    python
    def main(): while not exchange.IO("status"): Sleep(1000) exchange.SetContractType("rb888") exchange.SetDirection("buy") id = exchange.Buy(100, 1) Log("id:", id)
    rust
    fn main() { // 由于是测试代码,未采用商品期货策略的通用架构,此处仅通过 exchange.IO("status") 函数判断,在成功连接期货公司前置机后立即执行测试代码。股票证券无需使用 exchange.IO("status") 判断连接状态 while exchange.IO("status").unwrap_or_default() != "true" { Sleep(1000); } // 设置合约代码 let _ = exchange.SetContractType("rb888"); // 设置下单方向 let _ = exchange.SetDirection("buy"); // 注意,此处的下单价格 100 仅为示例,实际测试时可自行设置和修改 let id = exchange.Buy(100, 1); Log!("id:", id); }
    c++
    void main() { while (exchange.IO("status") == 0) { Sleep(1000); } exchange.SetContractType("rb888"); exchange.SetDirection("buy"); auto id = exchange.Buy(100, 1); Log("id:", id); }
  • 商品期货和股票证券除了可以使用市价单(价格参数传入 -1,实际上系统会使用一个较高的买入价或较低的卖出价来确保成交),还可以使用限价单方式下单。此时可以设置一个较大的滑点,以确保与对手盘成交,具体请参看exchange.Sell中的范例。

    javascript
    function main() { // 由于是测试代码,未采用商品期货策略的通用架构,这里仅通过 exchange.IO("status") 函数判断成功连接期货公司前置机后立即执行测试代码。股票证券无需使用 exchange.IO("status") 判断连接状态 while (!exchange.IO("status")) { Sleep(1000) } // 设置合约代码 exchange.SetContractType("rb888") // 设置下单方向 exchange.SetDirection("buy") // 下单价格参数传入 -1 即为市价单 var id = exchange.Buy(-1, 1) Log("id:", id) }
    python
    def main(): while not exchange.IO("status"): Sleep(1000) exchange.SetContractType("rb888") exchange.SetDirection("buy") id = exchange.Buy(-1, 1) Log("id:", id)
    rust
    fn main() { // 由于是测试代码,未采用商品期货策略的通用架构,这里仅通过 exchange.IO("status") 函数判断成功连接期货公司前置机后立即执行测试代码。股票证券无需使用 exchange.IO("status") 判断连接状态 while exchange.IO("status").unwrap_or_default() != "true" { Sleep(1000); } // 设置合约代码 let _ = exchange.SetContractType("rb888"); // 设置下单方向 let _ = exchange.SetDirection("buy"); // 下单价格参数传入 -1 即为市价单 let id = exchange.Buy(-1, 1); Log!("id:", id); }
    c++
    void main() { while (exchange.IO("status") == 0) { Sleep(1000); } exchange.SetContractType("rb888"); exchange.SetDirection("buy"); auto id = exchange.Buy(-1, 1); Log("id:", id); }

返回值

类型描述

string / 空值

下单成功时返回订单Id,下单失败时返回空值。

参数

名称类型必填描述

price

number

price参数用于设置订单价格。

amount

number

amount参数用于设置下单量。

arg

string / number / bool / object / array / any (系统支持的所有类型)

扩展参数,可用于向该条下单日志中输出附带信息。arg参数可以传入多个。

参考

备注

期货合约下单时,必须注意交易方向是否设置正确。如果交易方向与交易函数不匹配,将会报错。参考:exchange.SetDirection

参数price设置为-1时用于下达市价单,回测系统与实盘环境均支持市价单。

股票证券下单:

下单量为股票股数,而非股票手数(在股票证券交易所对象中,如无特殊说明,相关的量均指股票股数)。下单量需符合股票信息中的每手股数要求。例如,02333.HK为港股长城汽车,每手500股,下单量必须是500的整数倍;601633.SH为A股长城汽车,每手100股,下单量必须是100的整数倍。每手股数可以从SetContractType函数返回的数据结构中获取(VolumeMultiple字段),也可以从GetTicker()函数返回的数据结构的Info属性中获取(LotSize字段)。

exchange.Sell()函数用于下达卖单。

exchange.Sell(price, amount)
exchange.Sell(price, amount, ...args)

示例

  • exchange.Sell() 返回的订单编号,可用于查询订单信息及撤销订单。

    javascript
    function main(){ // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态 while (!exchange.IO("status")) { Sleep(1000) } // 设置合约代码 exchange.SetContractType("rb888") // 设置下单方向 exchange.SetDirection("sell") // 注意,这里的下单价格100为举例,具体测试的时候可以自行设置、改动 var id = exchange.Sell(100, 1) Log("id:", id) }
    python
    def main(): while not exchange.IO("status"): Sleep(1000) exchange.SetContractType("rb888") exchange.SetDirection("sell") id = exchange.Sell(100, 1) Log("id:", id)
    rust
    fn main() { // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态 while exchange.IO("status").unwrap_or_default() != "true" { Sleep(1000); } // 设置合约代码 let _ = exchange.SetContractType("rb888"); // 设置下单方向 let _ = exchange.SetDirection("sell"); // 注意,这里的下单价格100为举例,具体测试的时候可以自行设置、改动 let id = exchange.Sell(100, 1); Log!("id:", id); }
    c++
    void main() { while (exchange.IO("status") == 0) { Sleep(1000); } exchange.SetContractType("rb888"); exchange.SetDirection("sell"); auto id = exchange.Sell(100, 1); Log("id:", id); }
  • 商品期货除了可以使用市价单下单外,还可以使用限价单下单。此时可设置一个较大的滑价,以确保与对手盘成交。

    javascript
    function main() { while(true) { if (exchange.IO("status")) { // 设置当前合约为 rb2001,测试时请根据回测时间设置合适的合约 exchange.SetContractType("rb2001") exchange.SetDirection("buy") // 获取当前行情 var ticker = exchange.GetTicker() // 获取当前卖一价格 var currSell1Price = ticker.Sell // 加 50 元滑价,即以比卖一挂单价高 50 的价格买入 1 手 var id = exchange.Buy(currSell1Price + 50, 1) Log(exchange.GetOrder(id)) break } else { Log("未连接") } } }
    python
    def main(): while True: if exchange.IO("status"): exchange.SetContractType("rb2001") exchange.SetDirection("buy") ticker = exchange.GetTicker() currSell1Price = ticker["Sell"] id = exchange.Buy(currSell1Price + 50, 1) Log(exchange.GetOrder(id)) break else : Log("未连接")
    rust
    fn main() { loop { if exchange.IO("status").unwrap_or_default() == "true" { // 设置当前合约为 rb2001,测试时请根据回测时间设置合适的合约 let _ = exchange.SetContractType("rb2001"); let _ = exchange.SetDirection("buy"); // 获取当前行情 let ticker = exchange.GetTicker(None).unwrap(); // 获取当前卖一价格 let currSell1Price = ticker.Sell; // 加 50 元滑价,即以比卖一挂单价高 50 的价格买入 1 手 let id = exchange.Buy(currSell1Price + 50.0, 1).unwrap(); Log!(exchange.GetOrder(&id)); break; } else { Log!("未连接"); } } }
    c++
    void main() { while(true) { if(exchange.IO("status") == 1) { exchange.SetContractType("rb2001"); exchange.SetDirection("buy"); auto ticker = exchange.GetTicker(); auto currSell1Price = ticker.Sell; auto id = exchange.Buy(currSell1Price + 50, 1); Log(exchange.GetOrder(id)); break; } else { Log("未连接"); } } }

返回值

类型描述

string / 空值

下单成功时返回订单Id,下单失败时返回空值。参考exchange.Buy

参数

名称类型必填描述

price

number

price参数用于设置订单价格。

amount

number

amount参数用于设置下单量。

arg

string / number / bool / object / array / any (系统支持的所有类型)

扩展参数,可用于将附带信息输出到该条下单日志中,arg参数支持传入多个。

参考

备注

期货合约下单时务必注意交易方向是否设置正确,若交易方向与交易函数不匹配将会报错。参考:exchange.SetDirection

参数price设置为-1时用于下达市价单,回测系统与实盘环境均支持市价单。

下单量为股票股数,而非股票手数(在股票证券交易所对象中,若无特殊说明,相关的量均指股票股数)。下单量需符合股票信息中每手股数的要求。参考exchange.Buy

exchange.CreateOrder()函数用于下单。

exchange.CreateOrder(symbol, side, price, amount)
exchange.CreateOrder(symbol, side, price, amount, ...args)

示例

商品期货交易所对象调用exchange.CreateOrder()函数下单。

javascript
function main() { while(!exchange.IO("status")) { Sleep(1000) } // 调用CreateOrder函数下单 var id = exchange.CreateOrder("rb2410", "buy", 3500, 1) Log(id) }
python
def main(): while not exchange.IO("status"): Sleep(1000) id = exchange.CreateOrder("rb2410", "buy", 3500, 1) Log(id)
rust
fn main() { while exchange.IO("status").unwrap_or_default() != "true" { Sleep(1000); } // 调用CreateOrder函数下单 let id = exchange.CreateOrder("rb2410", "buy", 3500, 1); Log!(id); }
c++
void main() { while (exchange.IO("status") == 0) { Sleep(1000); } auto id = exchange.CreateOrder("rb2410", "buy", 3500, 1); Log(id); }

返回值

类型描述

string / 空值

下单成功时返回订单ID,下单失败时返回空值。

参数

名称类型必填描述

symbol

string

参数symbol用于指定订单的合约代码。若传入空字符串"",则默认以当前设置的合约代码下单。

side

string

side参数的可选值为:buyclosebuysellclosesellclosesell_todayclosebuy_today

其中,buy表示开多仓,closebuy表示平多昨仓,sell表示开空仓,closesell表示平空昨仓,closebuy_today表示平多今仓,closesell_today表示平空今仓。

price

number

price参数用于设置订单价格。

amount

number

amount参数用于设置订单数量。

arg

string / number / bool / object / array / any (系统支持的所有类型)

扩展参数,用于向该条下单日志输出附带信息,arg参数可传入多个。

参考

exchange.Buy exchange.Sell exchange.IO(API限流控制)

exchange.CancelOrder()函数用于取消订单。

exchange.CancelOrder(orderId)
exchange.CancelOrder(orderId, ...args)

示例

  • 撤销订单。

    javascript
    function main(){ // 由于是测试代码,未采用商品期货策略的通用架构,此处仅通过 exchange.IO("status") 函数判断成功连接期货公司前置机后,立即执行测试代码。股票证券无需使用 exchange.IO("status") 判断连接状态 while (!exchange.IO("status")) { Sleep(1000) } // 设置合约代码 exchange.SetContractType("rb888") // 设置下单方向 exchange.SetDirection("sell") // 下单价格仅为示例,价格过高将无法成交,订单会停留在订单簿中等待成交,具体测试时可自行调整价格 var id = exchange.Sell(99999, 1) exchange.CancelOrder(id) }
    python
    def main(): while not exchange.IO("status"): Sleep(1000) exchange.SetContractType("rb888") exchange.SetDirection("sell") id = exchange.Sell(99999, 1) exchange.CancelOrder(id)
    rust
    fn main() { // 由于是测试代码,未采用商品期货策略的通用架构,此处仅通过 exchange.IO("status") 函数判断成功连接期货公司前置机后,立即执行测试代码。股票证券无需使用 exchange.IO("status") 判断连接状态 while exchange.IO("status").unwrap_or_default() != "true" { Sleep(1000); } // 设置合约代码 let _ = exchange.SetContractType("rb888"); // 设置下单方向 let _ = exchange.SetDirection("sell"); // 下单价格仅为示例,价格过高将无法成交,订单会停留在订单簿中等待成交,具体测试时可自行调整价格 let id = exchange.Sell(99999, 1).unwrap(); let _ = exchange.CancelOrder(&id); }
    c++
    void main() { while (exchange.IO("status") == 0) { Sleep(1000); } exchange.SetContractType("rb888"); exchange.SetDirection("sell"); auto id = exchange.Sell(99999, 1); exchange.CancelOrder(id); }
  • 在优宽量化的API函数中,能够产生日志输出的函数(例如Log(...)exchange.Buy(Price, Amount)exchange.CancelOrder(Id)等)均可在必要参数之后附加一些额外的输出参数。

    例如:exchange.CancelOrder(orders[j].Id, orders[j]),即在取消Id为orders[j].Id的订单时,附带输出该订单的信息,也就是orders[j]这个Order结构。

    javascript
    function main() { // 由于这是测试代码,未采用商品期货策略的一般架构,这里仅通过exchange.IO("status")函数进行判断,在成功连接期货公司前置机后立即执行测试代码。股票证券则无需使用exchange.IO("status")判断连接状态 while (!exchange.IO("status")) { Sleep(1000) } // 设置合约代码 exchange.SetContractType("rb888") // 设置下单方向 exchange.SetDirection("sell") Log("数据1", "数据2", "数据3", "...") var data2 = 200 // 下单价格仅为示例,价格过高不会成交,订单会处于订单簿中等待成交状态,实际测试时可自行调整价格 var id = exchange.Sell(100000, 0.1, "附带数据1", data2, "...") exchange.CancelOrder(id, "附带数据1", data2, "...") LogProfit(100, "附带数据1", data2, "...") }
    python
    def main(): while not exchange.IO("status"): Sleep(1000) exchange.SetContractType("rb888") exchange.SetDirection("sell") Log("数据1", "数据2", "数据3", "...") data2 = 200 id = exchange.Sell(100000, 0.1, "附带数据1", data2, "...") exchange.CancelOrder(id, "附带数据1", data2, "...") LogProfit(100, "附带数据1", data2, "...")
    rust
    fn main() { // 由于这是测试代码,未采用商品期货策略的一般架构,这里仅通过exchange.IO("status")函数进行判断,在成功连接期货公司前置机后立即执行测试代码。股票证券则无需使用exchange.IO("status")判断连接状态 while exchange.IO("status").unwrap_or_default() != "true" { Sleep(1000); } // 设置合约代码 let _ = exchange.SetContractType("rb888"); // 设置下单方向 let _ = exchange.SetDirection("sell"); Log!("数据1", "数据2", "数据3", "..."); let data2 = 200; // Rust 不支持在 exchange.Sell()、exchange.CancelOrder()、LogProfit() 等函数中传入附带输出参数,可使用 Log! 宏单独输出附带信息 // 下单价格仅为示例,价格过高不会成交,订单会处于订单簿中等待成交状态,实际测试时可自行调整价格 let id = exchange.Sell(100000, 0.1).unwrap(); Log!("附带数据1", data2, "..."); let _ = exchange.CancelOrder(&id); LogProfit(100); }
    c++
    void main() { while (exchange.IO("status") == 0) { Sleep(1000); } exchange.SetContractType("rb888"); exchange.SetDirection("sell"); Log("数据1", "数据2", "数据3", "..."); int data2 = 200; auto id = exchange.Sell(100000, 0.1, "附带数据1", data2, "..."); exchange.CancelOrder(id, "附带数据1", data2, "..."); LogProfit(100, "附带数据1", data2, "..."); }

返回值

类型描述

bool

exchange.CancelOrder()函数返回真值(例如true)表示取消订单请求发送成功,返回假值(例如false)表示取消订单请求发送失败。返回值仅代表请求发送成功或失败,如需判断交易所是否已取消订单,可调用exchange.GetOrders()进行确认。

参数

名称类型必填描述

orderId

string

orderId参数用于指定要取消的订单。

arg

string / number / bool / object / array / any (系统支持的所有类型)

扩展参数,用于向该撤单日志中输出附带信息,arg参数可传入多个。

参考

备注

参数orderId为字符串类型。

exchange.GetOrder()函数用于获取订单信息。

exchange.GetOrder(orderId)

示例

根据指定的订单Id查询订单的详细信息。

javascript
function main(){ // 由于此处为测试代码,未采用商品期货策略的通用架构,仅通过exchange.IO("status")函数判断是否成功连接期货公司前置机,连接成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态 while (!exchange.IO("status")) { Sleep(1000) } // 设置合约代码 exchange.SetContractType("rb888") // 设置下单方向 exchange.SetDirection("sell") // 此处下单价格仅为示例,价格过高不会成交,订单将处于订单簿中的待成交状态,实际测试时可自行调整价格 var id = exchange.Sell(99999, 1) // 参数id为订单号,需填入所要查询订单的订单号 var order = exchange.GetOrder(id) Log("Id:", order.Id, "Price:", order.Price, "Amount:", order.Amount, "DealAmount:", order.DealAmount, "Status:", order.Status, "Type:", order.Type) }
python
def main(): while not exchange.IO("status"): Sleep(1000) exchange.SetContractType("rb888") exchange.SetDirection("sell") id = exchange.Sell(99999, 1) order = exchange.GetOrder(id) Log("Id:", order["Id"], "Price:", order["Price"], "Amount:", order["Amount"], "DealAmount:", order["DealAmount"], "Status:", order["Status"], "Type:", order["Type"])
rust
fn main() { // 由于此处为测试代码,未采用商品期货策略的通用架构,仅通过exchange.IO("status")函数判断是否成功连接期货公司前置机,连接成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态 while exchange.IO("status").unwrap_or_default() != "true" { Sleep(1000); } // 设置合约代码 let _ = exchange.SetContractType("rb888"); // 设置下单方向 let _ = exchange.SetDirection("sell"); // 此处下单价格仅为示例,价格过高不会成交,订单将处于订单簿中的待成交状态,实际测试时可自行调整价格 let id = exchange.Sell(99999, 1).unwrap(); // 参数id为订单号,需填入所要查询订单的订单号 let order = exchange.GetOrder(&id).unwrap(); Log!("Id:", order.Id, "Price:", order.Price, "Amount:", order.Amount, "DealAmount:", order.DealAmount, "Status:", order.Status, "Type:", order.Type); }
c++
void main() { while (exchange.IO("status") == 0) { Sleep(1000); } exchange.SetContractType("rb888"); exchange.SetDirection("sell"); auto id = exchange.Sell(99999, 1); auto order = exchange.GetOrder(id); Log("Id:", order.Id, "Price:", order.Price, "Amount:", order.Amount, "DealAmount:", order.DealAmount, "Status:", order.Status, "Type:", order.Type); }

返回值

类型描述

Order / 空值

根据订单号查询订单详情,查询成功时返回Order结构,查询失败时返回空值。

参数

名称类型必填描述

orderId

string

orderId参数用于指定所要查询的订单。

参考

备注

返回值为Order结构。

exchange.GetOrders()函数用于获取所有合约当前未完成的订单,并支持查询指定合约的未完成订单。

exchange.GetOrders()
exchange.GetOrders(symbol)

示例

  • 以较高的价格下单,然后查询未成交订单的信息。

    javascript
    function main(){ // 由于是测试代码,未采用商品期货策略的通用架构,这里仅通过exchange.IO("status")函数进行判断,在成功连接期货公司前置机后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态 while (!exchange.IO("status")) { Sleep(1000) } // 设置合约代码 exchange.SetContractType("rb888") // 设置下单方向 exchange.SetDirection("sell") // 此处的下单价格仅为示例,过高的价格不会成交,订单将处于订单簿中等待成交,实际测试时可自行调整价格 exchange.Sell(99999, 1) exchange.Sell(88888, 1) var orders = exchange.GetOrders() Log("未完成订单一的信息,ID:", orders[0].Id, "Price:", orders[0].Price, "Amount:", orders[0].Amount, "DealAmount:", orders[0].DealAmount, "Type:", orders[0].Type, "Symbol:", orders[0].Symbol) Log("未完成订单二的信息,ID:", orders[1].Id, "Price:", orders[1].Price, "Amount:", orders[1].Amount, "DealAmount:", orders[1].DealAmount, "Type:", orders[1].Type, "Symbol:", orders[1].Symbol) }
    python
    def main(): while not exchange.IO("status"): Sleep(1000) exchange.SetContractType("rb888") exchange.SetDirection("sell") exchange.Sell(99999, 1) exchange.Sell(88888, 1) orders = exchange.GetOrders() Log("未完成订单一的信息,ID:", orders[0]["Id"], "Price:", orders[0]["Price"], "Amount:", orders[0]["Amount"], "DealAmount:", orders[0]["DealAmount"], "Type:", orders[0]["Type"], "Symbol:", orders[0]["Symbol"]) Log("未完成订单二的信息,ID:", orders[1]["Id"], "Price:", orders[1]["Price"], "Amount:", orders[1]["Amount"], "DealAmount:", orders[1]["DealAmount"], "Type:", orders[1]["Type"], "Symbol:", orders[1]["Symbol"])
    rust
    fn main() { // 由于是测试代码,未采用商品期货策略的通用架构,这里仅通过exchange.IO("status")函数进行判断,在成功连接期货公司前置机后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态 while exchange.IO("status").unwrap_or_default() != "true" { Sleep(1000); } // 设置合约代码 let _ = exchange.SetContractType("rb888"); // 设置下单方向 let _ = exchange.SetDirection("sell"); // 此处的下单价格仅为示例,过高的价格不会成交,订单将处于订单簿中等待成交,实际测试时可自行调整价格 let _ = exchange.Sell(99999, 1); let _ = exchange.Sell(88888, 1); let orders = exchange.GetOrders(None).unwrap(); Log!("未完成订单一的信息,ID:", orders[0].Id, "Price:", orders[0].Price, "Amount:", orders[0].Amount, "DealAmount:", orders[0].DealAmount, "Type:", orders[0].Type, "Symbol:", orders[0].Symbol); Log!("未完成订单二的信息,ID:", orders[1].Id, "Price:", orders[1].Price, "Amount:", orders[1].Amount, "DealAmount:", orders[1].DealAmount, "Type:", orders[1].Type, "Symbol:", orders[1].Symbol); }
    c++
    void main() { while (exchange.IO("status") == 0) { Sleep(1000); } exchange.SetContractType("rb888"); exchange.SetDirection("sell"); exchange.Sell(99999, 1); exchange.Sell(88888, 1); auto orders = exchange.GetOrders(); Log("未完成订单一的信息,ID:", orders[0].Id, "Price:", orders[0].Price, "Amount:", orders[0].Amount, "DealAmount:", orders[0].DealAmount, "Type:", orders[0].Type, "Symbol:", orders[0].Symbol); Log("未完成订单二的信息,ID:", orders[1].Id, "Price:", orders[1].Price, "Amount:", orders[1].Amount, "DealAmount:", orders[1].DealAmount, "Type:", orders[1].Type, "Symbol:", orders[1].Symbol); }
  • 在商品期货和股票证券中,exchange.GetOrders()函数获取的是所有未完成的订单。在商品期货中,exchange.GetOrders()函数获取的订单与当前设置的合约无关。可以使用以下示例进行回测、模拟盘和实盘测试。

    javascript
    /*backtest start: 2020-06-17 10:00:00 end: 2020-06-18 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] */ function main() { var contractTypeList = ["MA009", "rb2010", "i2009"] while (true) { if (exchange.IO("status")) { for (var i = 0; i < contractTypeList.length; i++) { var ret = exchange.SetContractType(contractTypeList[i]) var ticker = exchange.GetTicker() exchange.SetDirection("sell") var id = exchange.Sell(ticker.Sell + 5, 1) Log(contractTypeList[i], "开空仓订单ID:", id) } var orders = exchange.GetOrders() for (var j = 0; j < orders.length; j++) { Log(orders[j]) } break } else { LogStatus(_D(), "未连接") } } }
    python
    '''backtest start: 2020-06-17 10:00:00 end: 2020-06-18 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] ''' def main(): contractTypeList = ["MA009", "rb2010", "i2009"] while True: if exchange.IO("status"): for i in range(len(contractTypeList)): ret = exchange.SetContractType(contractTypeList[i]) ticker = exchange.GetTicker() exchange.SetDirection("sell") id = exchange.Sell(ticker["Sell"] + 5, 1) Log(contractTypeList[i], "开空仓订单ID:", id) orders = exchange.GetOrders() for i in range(len(orders)): Log(orders[i]) break else: LogStatus(_D(), "未连接")
    rust
    /*backtest start: 2020-06-17 10:00:00 end: 2020-06-18 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] */ fn main() { let contractTypeList = ["MA009", "rb2010", "i2009"]; loop { if exchange.IO("status").unwrap_or_default() == "true" { for i in 0..contractTypeList.len() { let ret = exchange.SetContractType(contractTypeList[i]); let ticker = exchange.GetTicker(None).unwrap(); let _ = exchange.SetDirection("sell"); let id = exchange.Sell(ticker.Sell + 5.0, 1); Log!(contractTypeList[i], "开空仓订单ID:", id); } let orders = exchange.GetOrders(None).unwrap(); for j in 0..orders.len() { Log!(orders[j]); } break; } else { LogStatus!(_D(None), "未连接"); } } }
    c++
    /*backtest start: 2020-06-17 10:00:00 end: 2020-06-18 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] */ void main() { vector<string> contractTypeList = {"MA009", "rb2010", "i2009"}; while (true) { if (exchange.IO("status") == 1) { for (int i = 0 ; i < contractTypeList.size(); i++) { auto ret = exchange.SetContractType(contractTypeList[i]); auto ticker = exchange.GetTicker(); exchange.SetDirection("sell"); auto id = exchange.Sell(ticker.Sell + 5.0, 1); Log(contractTypeList[i], "开空仓订单ID:", id); } auto orders = exchange.GetOrders(); for (int j = 0; j < orders.size(); j++) { Log(orders[j]); } break; } else { LogStatus(_D(), "未完成"); } } }

返回值

类型描述

Order数组 / 空值

exchange.GetOrders()函数在请求数据成功时返回Order结构数组,在请求数据失败时返回空值。

参数

名称类型必填描述

symbol

string

参数symbol用于指定要查询的订单所属的合约代码。若不传入该参数,则默认查询所有合约的当前未完成订单数据。

参考

备注

当交易所对象exchange所代表的账户没有挂单(即处于未成交状态的活动订单)时,调用exchange.GetOrders()函数将返回空数组,即:[]

exchange.GetOrders()函数不依赖于当前的合约代码设置;当不传入symbol参数时,将获取所有合约的未完成订单。

exchange.GetHistoryOrders() 函数用于获取当前交易日内所有合约的历史订单,并支持查询指定合约的历史订单。

exchange.GetHistoryOrders()
exchange.GetHistoryOrders(symbol)

示例

javascript
function main(){ // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态 while (!exchange.IO("status")) { Sleep(1000) } var orders = exchange.GetHistoryOrders() Log(orders) }
python
def main(): while not exchange.IO("status"): Sleep(1000) orders = exchange.GetHistoryOrders() Log(orders)
rust
fn main() { // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态 while exchange.IO("status").unwrap_or_default() != "true" { Sleep(1000); } let orders = exchange.GetHistoryOrders(None, None, None); Log!(orders); }
c++
void main() { while (exchange.IO("status") == 0) { Sleep(1000); } auto orders = exchange.GetHistoryOrders(); Log(orders); }

返回值

类型描述

Order数组 / 空值

exchange.GetHistoryOrders() 函数在请求数据成功时返回 Order 结构数组,在请求数据失败时返回空值。

参数

名称类型必填描述

symbol

string

symbol 参数用于指定所要获取历史订单的合约名称。

参考

备注

注意:exchange.GetHistoryOrders() 函数不依赖于当前合约代码的设置。未传入 symbol 参数时,获取当前交易日内所有合约的历史订单;传入 symbol 参数时,获取当前交易日内指定合约的历史订单。

exchange.SetPrecision()函数用于设置exchange交易所对象的价格精度与下单量精度。设置后,系统会自动截断并忽略超出精度范围的多余部分。

exchange.SetPrecision(pricePrecision, amountPrecision)

示例

设置价格精度与下单量精度。

javascript
function main(){ // 设置价格小数位精度为2位,品种下单量小数位精度为3位 exchange.SetPrecision(2, 3) }
python
def main(): exchange.SetPrecision(2, 3)
rust
fn main() { // 设置价格小数位精度为2位,品种下单量小数位精度为3位 exchange.SetPrecision(2, 3); }
c++
void main() { exchange.SetPrecision(2, 3); }

参数

名称类型必填描述

pricePrecision

number

pricePrecision参数用于设置价格数据的精度。

amountPrecision

number

amountPrecision参数用于设置下单量数据的精度。

参考

备注

回测系统不支持该函数,回测系统的数值精度会自动处理。pricePrecisionamountPrecision均必须为整型数值。

设置交易所对象当前的汇率。

exchange.SetRate(rate)

示例

设置交易所对象当前的汇率。

javascript
function main(){ // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态 while (!exchange.IO("status")) { Sleep(1000) } // 设置合约代码 exchange.SetContractType("rb888") // 设置汇率之前打印行情数据 Log(exchange.GetTicker()) // 设置汇率转换 exchange.SetRate(7) Log(exchange.GetTicker()) // 设置为1,不转换 exchange.SetRate(1) Log(exchange.GetTicker()) }
python
def main(): while not exchange.IO("status"): Sleep(1000) exchange.SetContractType("rb888") Log(exchange.GetTicker()) exchange.SetRate(7) Log(exchange.GetTicker()) exchange.SetRate(1) Log(exchange.GetTicker())
rust
fn main() { // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态 while exchange.IO("status").unwrap_or_default() != "true" { Sleep(1000); } // 设置合约代码 let _ = exchange.SetContractType("rb888"); // 设置汇率之前打印行情数据 Log!(exchange.GetTicker(None)); // 设置汇率转换 exchange.SetRate(7); Log!(exchange.GetTicker(None)); // 设置为1,不转换 exchange.SetRate(1); Log!(exchange.GetTicker(None)); }
c++
void main() { while (exchange.IO("status") == 0) { Sleep(1000); } exchange.SetContractType("rb888"); Log(exchange.GetTicker()); exchange.SetRate(7); Log(exchange.GetTicker()); exchange.SetRate(1); Log(exchange.GetTicker()); }

参数

名称类型必填描述

rate

number

rate参数用于指定转换汇率。

参考

备注

如果使用exchange.SetRate()函数设置了汇率值(例如设置为7),那么当前exchange交易所对象所代表交易所的行情、深度、下单价格等所有价格信息,都会乘以所设置的汇率7进行转换。例如,exchange是以美元为计价货币的交易所,执行exchange.SetRate(7)之后,实盘中所有价格都会乘以7,转换为接近CNY计价的价格。

exchange.IO()函数用于调用交易所对象相关的协议及其它接口。

exchange.IO(k, ...args)

示例

  • 使用 status 参数可判断与期货公司前置机的连接状态:exchange.IO("status"),返回 true 表示与 CTP 的行情服务器和交易数据服务器均已正常连接。

    javascript
    function main() { while (!exchange.IO("status")) { LogStatus("正在等待与交易服务器连接, " + new Date()) } }
    python
    def main(): while not exchange.IO("status"): LogStatus("正在等待与交易服务器连接, " + _D())
    rust
    fn main() { while exchange.IO("status").unwrap_or_default() != "true" { LogStatus!("正在等待与交易服务器连接,", _D(None)); } }
    c++
    void main() { while(exchange.IO("status") == 0) { LogStatus("正在等待与交易服务器连接, " + _D()); } }
  • 使用wait参数设置阻塞:

    exchange.IO("wait", Timeout),仅当当前交易所有任意品种的行情信息更新或订单成交时才返回。可通过第二个参数(毫秒数)指定超时时间:超时返回空值,正常返回EventTick/OrderEvent结构。该函数需结合exchange.IO("mode", 0)一起使用,以便程序在有最新行情时及时响应并执行相应逻辑(使用exchange.IO("mode", 0)并不影响exchange.IO("wait"),其作用是使程序中调用exchange.GetTicker()等函数时不发生阻塞)。若Timeout参数设置为-1,该函数将立即返回,在没有新事件时返回空值;若Timeout参数设置为0,则阻塞等待最新事件,效果等同于不设置Timeout参数。需要注意的是,使用exchange.IO("wait")时,必须至少已订阅一个当前处于交易状态的合约(已交割的过期合约不再提供行情数据),否则由于没有任何行情或订单更新,程序将阻塞在该函数处。仅支持商品期货实盘。

    EventTick{Event:"tick", Index:交易所索引, Nano:事件纳秒级时间, Symbol:合约名称, Ticker:行情数据}

    OrderTick{Event:"order", Index:交易所索引, Nano:事件纳秒级时间, Order:订单信息}

    简单实现回调机制:

    javascript
    function on_tick(symbol, ticker) { Log("symbol:", symbol, "update") Log("ticker:", ticker) } function on_order(order) { Log("order update", order) } function main() { while(!exchange.IO("status")) { Sleep(10) } // 如果在程序中不使用诸如exchange.GetTicker()之类的获取行情的函数,可以不设置exchange.IO("mode", 0) exchange.IO("mode", 0) _C(exchange.SetContractType, "MA005") while(true) { var e = exchange.IO("wait") if(e) { if(e.Event == "tick") { on_tick(e.Symbol, e.Ticker) } else if(e.Event == "order") { on_order(e.Order) } } } }
    python
    def on_tick(symbol, ticker): Log("symbol:", symbol, "update") # 数据结构:https://www.youquant.com/api#ticker Log("ticker:", ticker) def on_order(order): Log("order update", order) def main(): # wait connect trade server while not exchange.IO("status"): Sleep(10) # switch push mode exchange.IO("mode", 0) # subscribe instrument _C(exchange.SetContractType, "MA001") while True: e = exchange.IO("wait") if e: if e.Event == "tick": on_tick(e['Symbol'], e['Ticker']) elif e.Event == "order": on_order(e['Order'])
    rust
    fn on_tick(symbol: &JsonValue, ticker: &JsonValue) { Log!("symbol:", *symbol, "update"); Log!("ticker:", *ticker); } fn on_order(order: &JsonValue) { Log!("order update", *order); } fn main() { while exchange.IO("status").unwrap_or_default() != "true" { Sleep(10); } // 如果在程序中不使用诸如exchange.GetTicker()之类的获取行情的函数,可以不设置exchange.IO("mode", 0) let _ = exchange.IO(("mode", 0)); _C!(exchange.SetContractType("MA005")); loop { // exchange.IO("wait")返回的是JSON文本,用JSONParse解析后处理 let e = exchange.IO("wait").unwrap_or_default(); if let Some(e) = JSONParse(&e) { if e["Event"].as_str() == Some("tick") { on_tick(&e["Symbol"], &e["Ticker"]); } else if e["Event"].as_str() == Some("order") { on_order(&e["Order"]); } } } }
    c++
    void on_tick(const string &symbol, json &ticker) { Log("symbol:", symbol, "update"); Log("ticker:", ticker); } void on_order(json &order) { Log("order update", order); } void main() { while(exchange.IO("status") == 0) { Sleep(10); } exchange.IO("mode", 0); _C(exchange.SetContractType, "rb2005"); while(true) { auto e = exchange.IO("wait"); if(e != false) { if(e["Event"] == "tick") { on_tick(e["Symbol"], e["Ticker"]); } else if(e["Event"] == "order") { on_order(e["Order"]); } } } }
  • 多品种回调示例:

    javascript
    function on_tick(symbol, ticker) { Log("symbol:", symbol, "update", "ticker:", ticker) } function main() { while(!exchange.IO("status")) { Sleep(10) } _C(exchange.SetContractType, "MA101") _C(exchange.SetContractType, "rb2101") _C(exchange.SetContractType, "i2101") while(true) { var e = exchange.IO("wait", -1) if(e) { if(e.Event == "tick") { on_tick(e.Symbol, e.Ticker) } } Sleep(10) } }
    python
    def on_tick(symbol, ticker): Log("symbol:", symbol, "update", "ticker:", ticker) def main(): while not exchange.IO("status"): Sleep(10) _C(exchange.SetContractType, "MA101") _C(exchange.SetContractType, "rb2101") _C(exchange.SetContractType, "i2101") while True: e = exchange.IO("wait", -1) if e: if e.Event == "tick": on_tick(e['Symbol'], e['Ticker']) Sleep(10)
    rust
    fn on_tick(symbol: &JsonValue, ticker: &JsonValue) { Log!("symbol:", *symbol, "update", "ticker:", *ticker); } fn main() { while exchange.IO("status").unwrap_or_default() != "true" { Sleep(10); } _C!(exchange.SetContractType("MA101")); _C!(exchange.SetContractType("rb2101")); _C!(exchange.SetContractType("i2101")); loop { let e = exchange.IO(("wait", -1)).unwrap_or_default(); if let Some(e) = JSONParse(&e) { if e["Event"].as_str() == Some("tick") { on_tick(&e["Symbol"], &e["Ticker"]); } } Sleep(10); } }
    c++
    void on_tick(const string &symbol, json &ticker) { Log("symbol:", symbol, "update", "ticker:", ticker); } void main() { while(exchange.IO("status") == 0) { Sleep(10); } _C(exchange.SetContractType, "MA101"); _C(exchange.SetContractType, "rb2101"); _C(exchange.SetContractType, "i2101"); while(true) { auto e = exchange.IO("wait", -1); if(e != false) { if(e["Event"] == "tick") { on_tick(e["Symbol"], e["Ticker"]); } } } }
  • 使用instruments参数获取所有合约的列表数据:exchange.IO("instruments"),返回交易所全部合约的列表,仅支持实盘。

    javascript
    function main() { while (!exchange.IO("status")) { LogStatus("正在等待与交易服务器连接, " + new Date()) } Log("开始获取所有合约") var instruments = _C(exchange.IO, "instruments") Log("合约列表获取成功") var len = 0 for (var instrumentId in instruments) { len++ } Log("合约列表长度为:",len) }
    python
    def main(): while not exchange.IO("status"): LogStatus("正在等待与交易服务器连接, " + _D()) Log("开始获取所有合约") instruments = _C(exchange.IO, "instruments") Log("合约列表获取成功") length = 0 for i in range(len(instruments)): length += 1 Log("合约列表长度为:", length)
    rust
    fn main() { while exchange.IO("status").unwrap_or_default() != "true" { LogStatus!("正在等待与交易服务器连接,", _D(None)); } Log!("开始获取所有合约"); let instruments = _C!(exchange.IO("instruments")); Log!("合约列表获取成功"); // 返回的是JSON文本,解析后统计合约个数 let parsed = JSONParse(&instruments).unwrap_or_default(); let mut len = 0; if let Some(obj) = parsed.as_object() { for _instrumentId in obj.keys() { len += 1; } } Log!("合约列表长度为:", len); }
    c++
    void main() { while(exchange.IO("status") == 0) { LogStatus("正在等待与交易服务器连接, " + _D()); } Log("开始获取所有合约"); auto instruments = _C(exchange.IO, "instruments"); Log("合约列表获取成功"); int length = 0; for(int i = 0; i < instruments.size(); i++) { length++; } Log("合约列表长度为:", length); }
  • 使用products参数获取所有产品的列表数据:
    exchange.IO("products"),返回交易所全部产品的列表,仅支持实盘。

    使用subscribed参数获取已订阅的合约数据:
    exchange.IO("subscribed"),返回已订阅行情的合约,仅支持实盘。

    使用settlement参数获取结算单数据:
    exchange.IO("settlement")用于查询结算单。若不传入第二个参数,默认返回上一个交易日的数据;若传入如20170317的参数,则返回日期为2017-03-17的结算单,仅支持实盘。

    使用api参数调用底层接口:

    优宽量化的CTP(商品期货)终端提供了完整的全API实现。当发明者平台的API无法满足你所需的功能时,可以使用exchange.IO函数进行更深层的系统调用,且完全兼容官方的API名称。CTP的IO直接扩展函数调用请求,将在收到第一个isLast标记为true的响应包后返回。

    CTP协议接口:CTP协议接口相关资料

    以下通过几个简单的例子进行说明:

  • 查询投资者信息:

    javascript
    function main() { while (!exchange.IO("status")) { LogStatus("正在等待与交易服务器建立连接, " + new Date()) } Log(exchange.IO("api", "ReqQryInvestor")) }
    python
    def main(): while not exchange.IO("status"): LogStatus("正在等待与交易服务器建立连接, " + _D()) Log(exchange.IO("api", "ReqQryInvestor"))
    rust
    fn main() { while exchange.IO("status").unwrap_or_default() != "true" { LogStatus!("正在等待与交易服务器建立连接,", _D(None)); } Log!(exchange.IO(("api", "ReqQryInvestor"))); }
    c++
    void main() { while(exchange.IO("status") == 0) { LogStatus("正在等待与交易服务器建立连接, " + _D()); } Log(exchange.IO("api", "ReqQryInvestor")); }
  • 修改密码:

    javascript
    function main() { // CTP 协议建立连接需要一定时间 Sleep(6000) exchange.IO("api", "ReqUserPasswordUpdate", {BrokerID: "9999", UserID: "11111", OldPassword: "oldpass", NewPassword: "newpass"}) }
    python
    def main(): Sleep(6000) exchange.IO("api", "ReqUserPasswordUpdate", {"BrokerID": "9999", "UserID": "11111", "OldPassword": "oldpass", "NewPassword": "newpass"})
    rust
    fn main() { // CTP 协议建立连接需要一定时间 Sleep(6000); let _ = exchange.IO(("api", "ReqUserPasswordUpdate", r#"{"BrokerID": "9999", "UserID": "11111", "OldPassword": "oldpass", "NewPassword": "newpass"}"#)); }
    c++
    void main() { Sleep(6000); exchange.IO("api", "ReqUserPasswordUpdate", R"({"BrokerID": "9999", "UserID": "11111", "OldPassword": "oldpass", "NewPassword": "newpass"})"_json); }
  • 复杂示例:

    javascript
    function main() { // CTP 协议建立连接需要一定时间 Sleep(6000) // 若增加一个值为 false 的参数,表示不等待返回值,仅发送请求;第三个参数只需填充所需的字段,也可省略此参数;若字段类型为 char,传入长度为 1 的字符串即可 var r = exchange.IO("api", "ReqQryProduct", {ProductID: "MA"}) // CTP 未登录时调用会失败 if (!r) { return } _.each(r, function(item) { // IO 请求可能返回多个数据包,因此以数组形式返回。遍历数据包中的所有数据类型;一个数据包可能包含多条具体数据,具体数据类型的名称请参阅 CTP 官方文档 http://www.sfit.com.cn/5_2_DocumentDown.htm _.each(item, function(f) { // 取出所需的数据,Name 为该数据的类型,Value 为该数据的值 if (f.Name == 'CThostFtdcProductField') { // 打印查询到的甲醇合约信息 Log(f.Value) } }) }); }
    python
    def main(): Sleep(6000) r = exchange.IO("api", "ReqQryProduct", {"ProductID": "MA"}) if not r: return for r_index in range(len(r)): for f_index in range(len(r[r_index])): if r[r_index][f_index]["Name"] == 'CThostFtdcProductField': Log(r[r_index][f_index]["Value"])
    rust
    fn main() { // CTP 协议建立连接需要一定时间 Sleep(6000); // 第三个参数只需填充所需的字段(JSON 文本形式);若字段类型为 char,传入长度为 1 的字符串即可 let r = exchange.IO(("api", "ReqQryProduct", r#"{"ProductID": "MA"}"#)).unwrap_or_default(); // CTP 未登录时调用会失败 let r = match JSONParse(&r) { Some(v) => v, None => return, }; // IO 请求可能返回多个数据包,因此以数组形式返回。遍历数据包中的所有数据类型;一个数据包可能包含多条具体数据,具体数据类型的名称请参阅 CTP 官方文档 http://www.sfit.com.cn/5_2_DocumentDown.htm if let Some(packets) = r.as_array() { for item in packets { if let Some(fields) = item.as_array() { for f in fields { // 取出所需的数据,Name 为该数据的类型,Value 为该数据的值 if f["Name"].as_str() == Some("CThostFtdcProductField") { // 打印查询到的甲醇合约信息 Log!(f["Value"]); } } } } } }
    c++
    void main() { Sleep(6000); auto r = exchange.IO("api", "ReqQryProduct", R"({"ProductID": "MA"})"_json); if(r == false) { return; } for(auto& ele1 : r.items()) { for(auto& ele2 : ele1.value().items()) { if(ele2.value()["Name"] == "CThostFtdcProductField") { Log(ele2.value()["Value"]); } } } }
  • 复杂的示例:

    javascript
    function main() { while (!exchange.IO("status")) { LogStatus("正在等待与交易服务器建立连接, " + new Date()) } // 也可不指定日期 var r = exchange.IO("api", "ReqQrySettlementInfo", {TradingDay: "20190506"}) var s = '' _.each(r, function(item) { _.each(item, function(f) { if (f.Name == 'CThostFtdcSettlementInfoField') { s += f.Value.Content } }) }) Log(s) }
    python
    def main(): while not exchange.IO("status"): LogStatus("正在等待与交易服务器建立连接, " + _D()) r = exchange.IO("api", "ReqQrySettlementInfo", {"TradingDay": "20190506"}) s = '' for i in range(len(r)): for ii in range(len(r[i])): if r[i][ii]["Name"] == "CThostFtdcSettlementInfoField": s += r[i][ii]["Value"]["Content"] Log(s)
    rust
    fn main() { while exchange.IO("status").unwrap_or_default() != "true" { LogStatus!("正在等待与交易服务器建立连接,", _D(None)); } // 也可不指定日期 let r = exchange.IO(("api", "ReqQrySettlementInfo", r#"{"TradingDay": "20190506"}"#)).unwrap_or_default(); let parsed = JSONParse(&r).unwrap_or_default(); let mut s = String::new(); if let Some(packets) = parsed.as_array() { for item in packets { if let Some(fields) = item.as_array() { for f in fields { if f["Name"].as_str() == Some("CThostFtdcSettlementInfoField") { s += f["Value"]["Content"].as_str().unwrap_or(""); } } } } } Log!(s); }
    c++
    void main() { while(exchange.IO("status") == 0) { LogStatus("正在等待与交易服务器建立连接, " + _D()); } auto r = exchange.IO("api", "ReqQrySettlementInfo", R"({"TradingDay": "20200311"})"_json); string s = ""; for(auto& ele1 : r.items()) { for(auto& ele2 : ele1.value().items()) { if(ele2.value()["Name"] == "CThostFtdcSettlementInfoField") { s += std::string(ele2.value()["Value"]["Content"]); } } } Log(s); }
  • 限制 GetTicker 每秒最多调用 3 次,超出限制时报错并返回空值:

    javascript
    function main() { // 等待与交易服务器建立连接 while (!exchange.IO("status")) { LogStatus("正在等待与交易服务器建立连接, " + new Date()) Sleep(1000) } // 场景1:限制 GetTicker 每秒最多调用 3 次,超出限制时返回 null exchange.IO("rate", "GetTicker", 3, "1s") for (var i = 0; i < 10; i++) { if (!exchange.IO("status")) { Log("Exchange not ready, waiting...", "#FF0000") Sleep(5000) continue } var ticker = exchange.GetTicker("rb888") // 螺纹钢主力合约 if (ticker) { Log("Call", i+1, "Success, Price:", ticker.Last) } else { Log("Call", i+1, "Failed: Rate limit exceeded", "#FF0000") } Sleep(100) } }
    python
    def main(): # 等待与交易服务器建立连接 while not exchange.IO("status"): LogStatus("正在等待与交易服务器建立连接, " + _D()) Sleep(1000) # 场景1:限制 GetTicker 每秒最多调用 3 次,超出限制时返回 null exchange.IO("rate", "GetTicker", 3, "1s") for i in range(10): if not exchange.IO("status"): Log("Exchange not ready, waiting...", "#FF0000") Sleep(5000) continue ticker = exchange.GetTicker("rb888") # 螺纹钢主力合约 if ticker: Log("Call", i+1, "Success, Price:", ticker["Last"]) else: Log("Call", i+1, "Failed: Rate limit exceeded", "#FF0000") Sleep(100)
    rust
    fn main() { // 等待与交易服务器建立连接 while exchange.IO("status").unwrap_or_default() != "true" { LogStatus!("正在等待与交易服务器建立连接,", _D(None)); Sleep(1000); } // 场景1:限制 GetTicker 每秒最多调用 3 次,超出限制时返回错误 let _ = exchange.IO(("rate", "GetTicker", 3, "1s")); for i in 0..10 { if exchange.IO("status").unwrap_or_default() != "true" { Log!("Exchange not ready, waiting...", "#FF0000"); Sleep(5000); continue; } // 螺纹钢主力合约 match exchange.GetTicker("rb888") { Ok(ticker) => Log!("Call", i + 1, "Success, Price:", ticker.Last), Err(_) => Log!("Call", i + 1, "Failed: Rate limit exceeded", "#FF0000"), } Sleep(100); } }
    c++
    void main() { // 等待与交易服务器建立连接 while (exchange.IO("status") == 0) { LogStatus("正在等待与交易服务器建立连接, " + _D()); Sleep(1000); } // 场景1:限制 GetTicker 每秒最多调用 3 次,超出限制时返回无效数据 exchange.IO("rate", "GetTicker", 3, "1s"); for (int i = 0; i < 10; i++) { if (exchange.IO("status") == 0) { Log("Exchange not ready, waiting...", "#FF0000"); Sleep(5000); continue; } auto ticker = exchange.GetTicker("rb888"); // 螺纹钢主力合约 if (ticker.Valid) { Log("Call", i + 1, "Success, Price:", ticker.Last); } else { Log("Call", i + 1, "Failed: Rate limit exceeded", "#FF0000"); } Sleep(100); } }
  • 限制 GetTicker 每秒最多调用 3 次,超出频率限制时自动等待:

    javascript
    function main() { while (!exchange.IO("status")) { Sleep(1000) } // 场景 2:使用 delay 参数,超出频率限制时自动等待 exchange.IO("rate", "GetTicker", 3, "1s", "delay") Log("Start testing delay mode with m888 (soybean meal)", "#00FF00") for (var i = 0; i < 10; i++) { if (!exchange.IO("status")) { Sleep(5000) continue } var startTime = new Date().getTime() var ticker = exchange.GetTicker("m888") // 豆粕主力合约 var endTime = new Date().getTime() if (ticker) { Log("Call", i+1, "Price:", ticker.Last, "Time cost:", endTime - startTime, "ms") } } }
    python
    import time def main(): while not exchange.IO("status"): Sleep(1000) # 场景 2:使用 delay 参数,超出频率限制时自动等待 exchange.IO("rate", "GetTicker", 3, "1s", "delay") Log("Start testing delay mode with m888 (soybean meal)", "#00FF00") for i in range(10): if not exchange.IO("status"): Sleep(5000) continue startTime = time.time() * 1000 ticker = exchange.GetTicker("m888") # 豆粕主力合约 endTime = time.time() * 1000 if ticker: Log("Call", i+1, "Price:", ticker["Last"], "Time cost:", endTime - startTime, "ms")
    rust
    fn main() { while exchange.IO("status").unwrap_or_default() != "true" { Sleep(1000); } // 场景 2:使用 delay 参数,超出频率限制时自动等待 let _ = exchange.IO(("rate", "GetTicker", 3, "1s", "delay")); Log!("Start testing delay mode with m888 (soybean meal)", "#00FF00"); for i in 0..10 { if exchange.IO("status").unwrap_or_default() != "true" { Sleep(5000); continue; } let startTime = UnixNano() / 1000000; // 豆粕主力合约 let ticker = exchange.GetTicker("m888"); let endTime = UnixNano() / 1000000; if let Ok(ticker) = ticker { Log!("Call", i + 1, "Price:", ticker.Last, "Time cost:", endTime - startTime, "ms"); } } }
    c++
    void main() { while (exchange.IO("status") == 0) { Sleep(1000); } // 场景 2:使用 delay 参数,超出频率限制时自动等待 exchange.IO("rate", "GetTicker", 3, "1s", "delay"); Log("Start testing delay mode with m888 (soybean meal)", "#00FF00"); for (int i = 0; i < 10; i++) { if (exchange.IO("status") == 0) { Sleep(5000); continue; } auto startTime = UnixNano() / 1000000; auto ticker = exchange.GetTicker("m888"); // 豆粕主力合约 auto endTime = UnixNano() / 1000000; if (ticker.Valid) { Log("Call", i + 1, "Price:", ticker.Last, "Time cost:", endTime - startTime, "ms"); } } }
  • 限制多个函数的联合调用频率:

    javascript
    function main() { while (!exchange.IO("status")) { Sleep(1000) } // 场景3: GetTicker 与 GetDepth 共享调用频率限制,合计每秒最多 5 次 exchange.IO("mode", 0) // 切换为接口立即返回模式 exchange.IO("rate", "GetTicker,GetDepth", 5, "1s") for (var i = 0; i < 10; i++) { if (!exchange.IO("status")) { Sleep(5000) continue } if (i % 2 == 0) { var ticker = exchange.GetTicker("i888") // 铁矿石主力合约 Log("Call", i+1, "GetTicker:", ticker ? "Success" : "Failed") } else { var depth = exchange.GetDepth("i888") Log("Call", i+1, "GetDepth:", depth ? "Success" : "Failed") } Sleep(100) } }
    python
    def main(): while not exchange.IO("status"): Sleep(1000) # 场景3: GetTicker 与 GetDepth 共享调用频率限制,合计每秒最多 5 次 exchange.IO("mode", 0) # 切换为接口立即返回模式 exchange.IO("rate", "GetTicker,GetDepth", 5, "1s") for i in range(10): if not exchange.IO("status"): Sleep(5000) continue if i % 2 == 0: ticker = exchange.GetTicker("i888") # 铁矿石主力合约 Log("Call", i+1, "GetTicker:", "Success" if ticker else "Failed") else: depth = exchange.GetDepth("i888") Log("Call", i+1, "GetDepth:", "Success" if depth else "Failed") Sleep(100)
    rust
    fn main() { while exchange.IO("status").unwrap_or_default() != "true" { Sleep(1000); } // 场景3: GetTicker 与 GetDepth 共享调用频率限制,合计每秒最多 5 次 let _ = exchange.IO(("mode", 0)); // 切换为接口立即返回模式 let _ = exchange.IO(("rate", "GetTicker,GetDepth", 5, "1s")); for i in 0..10 { if exchange.IO("status").unwrap_or_default() != "true" { Sleep(5000); continue; } if i % 2 == 0 { // 铁矿石主力合约 let ticker = exchange.GetTicker("i888"); Log!("Call", i + 1, "GetTicker:", if ticker.is_ok() { "Success" } else { "Failed" }); } else { let depth = exchange.GetDepth("i888"); Log!("Call", i + 1, "GetDepth:", if depth.is_ok() { "Success" } else { "Failed" }); } Sleep(100); } }
    c++
    void main() { while (exchange.IO("status") == 0) { Sleep(1000); } // 场景3: GetTicker 与 GetDepth 共享调用频率限制,合计每秒最多 5 次 exchange.IO("mode", 0); // 切换为接口立即返回模式 exchange.IO("rate", "GetTicker,GetDepth", 5, "1s"); for (int i = 0; i < 10; i++) { if (exchange.IO("status") == 0) { Sleep(5000); continue; } if (i % 2 == 0) { auto ticker = exchange.GetTicker("i888"); // 铁矿石主力合约 Log("Call", i + 1, "GetTicker:", ticker.Valid ? "Success" : "Failed"); } else { auto depth = exchange.GetDepth("i888"); Log("Call", i + 1, "GetDepth:", depth.Valid ? "Success" : "Failed"); } Sleep(100); } }
  • 使用通配符限制所有 API 调用的频率:

    javascript
    function main() { while (!exchange.IO("status")) { Sleep(1000) } // 场景 4:将所有 API 调用限制为每秒最多 5 次 exchange.IO("mode", 0) // 设置为立即返回模式 exchange.IO("rate", "*", 5, "1s") var symbols = ["rb888", "m888", "i888"] // 螺纹钢、豆粕、铁矿石 for (var i = 0; i < 10; i++) { if (!exchange.IO("status")) { Sleep(5000) continue } var symbol = symbols[i % symbols.length] var ticker = exchange.GetTicker(symbol) var depth = exchange.GetDepth(symbol) var account = exchange.GetAccount() Log("Round", i+1, symbol, "Ticker:", ticker ? "✓" : "✗", "Depth:", depth ? "✓" : "✗", "Account:", account ? "✓" : "✗") Sleep(100) } }
    python
    def main(): while not exchange.IO("status"): Sleep(1000) # 场景 4:将所有 API 调用限制为每秒最多 5 次 exchange.IO("mode", 0) # 设置为立即返回模式 exchange.IO("rate", "*", 5, "1s") symbols = ["rb888", "m888", "i888"] # 螺纹钢、豆粕、铁矿石 for i in range(10): if not exchange.IO("status"): Sleep(5000) continue symbol = symbols[i % len(symbols)] ticker = exchange.GetTicker(symbol) depth = exchange.GetDepth(symbol) account = exchange.GetAccount() Log("Round", i+1, symbol, "Ticker:", "✓" if ticker else "✗", "Depth:", "✓" if depth else "✗", "Account:", "✓" if account else "✗") Sleep(100)
    rust
    fn main() { while exchange.IO("status").unwrap_or_default() != "true" { Sleep(1000); } // 场景 4:将所有 API 调用限制为每秒最多 5 次 let _ = exchange.IO(("mode", 0)); // 设置为立即返回模式 let _ = exchange.IO(("rate", "*", 5, "1s")); let symbols = ["rb888", "m888", "i888"]; // 螺纹钢、豆粕、铁矿石 for i in 0..10 { if exchange.IO("status").unwrap_or_default() != "true" { Sleep(5000); continue; } let symbol = symbols[i % symbols.len()]; let ticker = exchange.GetTicker(symbol); let depth = exchange.GetDepth(symbol); let account = exchange.GetAccount(); Log!("Round", i + 1, symbol, "Ticker:", if ticker.is_ok() { "✓" } else { "✗" }, "Depth:", if depth.is_ok() { "✓" } else { "✗" }, "Account:", if account.is_ok() { "✓" } else { "✗" }); Sleep(100); } }
    c++
    void main() { while (exchange.IO("status") == 0) { Sleep(1000); } // 场景 4:将所有 API 调用限制为每秒最多 5 次 exchange.IO("mode", 0); // 设置为立即返回模式 exchange.IO("rate", "*", 5, "1s"); std::vector<string> symbols = {"rb888", "m888", "i888"}; // 螺纹钢、豆粕、铁矿石 for (int i = 0; i < 10; i++) { if (exchange.IO("status") == 0) { Sleep(5000); continue; } auto symbol = symbols[i % symbols.size()]; auto ticker = exchange.GetTicker(symbol); auto depth = exchange.GetDepth(symbol); auto account = exchange.GetAccount(); Log("Round", i + 1, symbol, "Ticker:", ticker.Valid ? "✓" : "✗", "Depth:", depth.Valid ? "✓" : "✗", "Account:", account.Valid ? "✓" : "✗"); Sleep(100); } }
  • 使用 quota 模式实现严格的时间窗口对齐限流:

    javascript
    function main() { while (!exchange.IO("status")) { Sleep(1000) } // 场景5:quota 模式,严格的时间窗口对齐 exchange.IO("mode", 0) // 切换到立即返回模式 exchange.IO("quota", "GetTicker", 3, "1s") Log("Testing quota mode with c888 (corn)", "#00FF00") for (var i = 0; i < 8; i++) { if (!exchange.IO("status")) { Sleep(5000) continue } var ticker = exchange.GetTicker("c888") // 玉米主力合约 Log(_D(), "Call", i+1, ticker ? "Success" : "Quota exceeded") Sleep(150) // 每 150ms 调用一次,每秒约 6-7 次 } }
    python
    def main(): while not exchange.IO("status"): Sleep(1000) # 场景5:quota 模式,严格的时间窗口对齐 exchange.IO("mode", 0) # 切换到立即返回模式 exchange.IO("quota", "GetTicker", 3, "1s") Log("Testing quota mode with c888 (corn)", "#00FF00") for i in range(8): if not exchange.IO("status"): Sleep(5000) continue ticker = exchange.GetTicker("c888") # 玉米主力合约 Log(_D(), "Call", i+1, "Success" if ticker else "Quota exceeded") Sleep(150) # 每 150ms 调用一次,每秒约 6-7 次
    rust
    fn main() { while exchange.IO("status").unwrap_or_default() != "true" { Sleep(1000); } // 场景5:quota 模式,严格的时间窗口对齐 let _ = exchange.IO(("mode", 0)); // 切换到立即返回模式 let _ = exchange.IO(("quota", "GetTicker", 3, "1s")); Log!("Testing quota mode with c888 (corn)", "#00FF00"); for i in 0..8 { if exchange.IO("status").unwrap_or_default() != "true" { Sleep(5000); continue; } // 玉米主力合约 let ticker = exchange.GetTicker("c888"); Log!(_D(None), "Call", i + 1, if ticker.is_ok() { "Success" } else { "Quota exceeded" }); Sleep(150); // 每 150ms 调用一次,每秒约 6-7 次 } }
    c++
    void main() { while (exchange.IO("status") == 0) { Sleep(1000); } // 场景5:quota 模式,严格的时间窗口对齐 exchange.IO("mode", 0); // 切换到立即返回模式 exchange.IO("quota", "GetTicker", 3, "1s"); Log("Testing quota mode with c888 (corn)", "#00FF00"); for (int i = 0; i < 8; i++) { if (exchange.IO("status") == 0) { Sleep(5000); continue; } auto ticker = exchange.GetTicker("c888"); // 玉米主力合约 Log(_D(), "Call", i + 1, ticker.Valid ? "Success" : "Quota exceeded"); Sleep(150); // 每 150ms 调用一次,每秒约 6-7 次 } }

返回值

类型描述

string / number / bool / object / array / any (系统支持的所有类型)

exchange.IO()函数用于调用交易所对象相关的其它接口,调用成功时返回请求的应答数据,调用失败时返回空值。

参数

名称类型必填描述

k

string

k参数用于设置调用类型,可选值为"api"wait

arg

string / number / bool / object / array / any (系统支持的所有类型)

扩展参数,根据具体的调用场景传入,arg参数可以传入多个。由于exchange.IO()函数采用多态机制,不同的参数设置对应不同的功能,因此exchange.IO()函数的参数个数与类型都是不确定的。

参考

备注

使用mode参数切换行情模式:

  • exchange.IO("mode", 0)
    立即返回模式。如果当前尚未接收到交易所最新的行情数据推送,则立即返回旧的行情数据;如果已有新数据,则返回新数据。
    商品期货中的应用可参考:exchange.IO 函数 wait 参数的使用示例。

  • exchange.IO("mode", 1)
    缓存模式(默认模式)。如果当前尚未收到交易所最新的行情数据(与上一次接口获取的数据相比),则等待接收后再返回;如果在调用该函数之前已收到最新的行情数据,则立即返回最新数据。

  • exchange.IO("mode", 2)
    强制更新模式,进入等待状态,直到接收到交易所下一次最新推送的数据后返回。

API限流控制功能:

优宽量化平台支持对交易所 API 调用进行频率限制,以避免触发交易所自身的频率限制。平台支持两种限流模式:

  • rate模式(平滑限流):不严格对齐时间窗口,适用于一般的限流需求。

  • quota模式(额度限流):严格对齐时间窗口,例如 1m 对齐到整分钟,1s 对齐到整秒。

函数签名:

javascript
exchange.IO("rate", functionNames, maxCalls, period, [behavior]) exchange.IO("quota", functionNames, maxCalls, period, [behavior])

参数说明:

参数类型说明
modestring限流模式:"rate"(平滑限流)或 "quota"(额度限流)
functionNamesstring需要限流的函数名,支持单个函数、多个函数(以逗号分隔)或通配符(* 表示所有函数)
maxCallsnumber时间周期内允许的最大调用次数
periodstring时间周期或重置时间点。支持的时间单位:ns, us, µs, ms, s, m, h, d(例如:"1s", "1m", "1h");支持的重置时间点格式:@HHMM 或 @HHMMSS(例如:"@0815" 表示每天 08:15 重置)
behaviorstring可选参数,用于设置超限行为。默认为空(超限时返回 null 并报错);设置为 "delay" 时,超限会等待

支持的函数列表:

交易类:CreateOrder, CancelOrder

账户类:GetAccount, GetPositions

订单类:GetOrder, GetOrders, GetHistoryOrders

行情类:GetTicker, GetDepth, GetRecords

其它:IO/api

注意事项:

  • 优宽量化支持的市场:商品期货(如螺纹钢 rb888、豆粕 m888 等)

  • 使用 API 限流功能前,必须先通过exchange.IO("status")进行检查,确保与交易服务器的连接正常

  • 建议配合exchange.IO("mode", 0)立即返回模式使用,以避免不必要的等待

  • IO/api的限流仅对exchange.IO("api", ...)调用生效

  • quota模式严格对齐时间窗口,例如设置"1s"时,时间窗口按整秒对齐

  • 使用"delay"参数时,调用时间与日志记录时间之间可能存在差异,这属于正常现象

exchange.Log()函数用于在日志栏区域输出下单、撤单日志。该函数被调用时不会实际下单,仅用于输出和记录交易日志。

exchange.Log(orderType, price, amount)
exchange.Log(orderType, price, amount, ...args)

示例

使用exchange.Log(orderType, price, amount)可以进行实盘跟单测试和模拟下单,也可以辅助记录下单信息。

javascript
var id = 123 function main() { // 下单类型买入,价格999,数量 0.1 exchange.Log(LOG_TYPE_BUY, 999, 0.1) // 取消订单 exchange.Log(LOG_TYPE_CANCEL, id) }
python
id = 123 def main(): exchange.Log(LOG_TYPE_BUY, 999, 0.1) exchange.Log(LOG_TYPE_CANCEL, id)
rust
fn main() { let id = 123; // 下单类型买入,价格999,数量 0.1 exchange.Log(LOG_TYPE_BUY, 999, 0.1); // 取消订单,orderType为LOG_TYPE_CANCEL时price参数为撤单的订单Id(Rust中amount参数必传,可传0) exchange.Log(LOG_TYPE_CANCEL, id, 0); }
c++
void main() { auto id = 123; exchange.Log(LOG_TYPE_BUY, 999, 0.1); exchange.Log(LOG_TYPE_CANCEL, id); }

参数

名称类型必填描述

orderType

number

orderType参数用于设置输出的日志类型,可选值为LOG_TYPE_BUYLOG_TYPE_SELLLOG_TYPE_CANCEL

price

number

price参数用于设置日志中显示的价格。

amount

number

amount参数用于设置日志中显示的下单量。

arg

string / number / bool / object / array / any (系统支持的所有类型)

扩展参数,用于向该条日志输出附带信息,arg参数可以传入多个。

参考

备注

orderType参数为LOG_TYPE_CANCEL时,price参数表示撤单的订单Id,用于在直接调用exchange.IO()函数撤单时打印撤单日志。exchange.Log()函数是exchange交易所对象的成员函数,需与全局函数Log区分。