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}