exchange.IO

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

exchange.IO()函数调用交易所对象相关的其他接口时,调用成功返回请求的响应数据,调用失败返回空值。 string / number / bool / object / array / any (系统支持的所有类型)

exchange.IO(k, …args)

k参数用于设置调用类型,可选值为"api"wait。 k true string 扩展参数,根据具体调用场景传递参数,arg参数可以传递多个。由于exchange.IO()函数的多态机制,不同的参数设置对应不同的功能。exchange.IO()函数的参数个数和类型都是不确定的。 arg true string / number / bool / object / array / any (系统支持的所有类型)


function main() {
    while (!exchange.IO("status")) {
        LogStatus("正在等待与交易服务器连接, " + new Date())
    }
}

def main():
    while not exchange.IO("status"):
        LogStatus("正在等待与交易服务器连接, " + _D())

void main() {
    while(exchange.IO("status") == 0) {
        LogStatus("正在等待与交易服务器连接, " + _D());
    }
}
使用status参数判断与期货公司前置机的连接状态:exchange.IO("status"),返回true表示与CTP服务器的行情服务器和交易服务器均已成功连接。 “`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’]) cpp 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”]); } } } } 使用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”, “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) cpp 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”]); } } } } 多品种回测示例: 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)```

”`cpp 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);

} 使用instruments参数获取所有合约的列表数据:exchange.IO(“instruments”),返回交易所所有合约的列表,仅支持实盘。 使用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"))```

”`cpp 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”}) cpp 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"])```

”`cpp 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®): for ii in range(len(r[i])): if r[i][ii][“Name”] == “CThostFtdcSettlementInfoField”: s += r[i][ii][“Value”][“Content”]

Log(s)```


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);
}
复杂示例:

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

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

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

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

{@var EXCHANGE_OP_IO_CONTROL}