vnpy接口的subscribeMarketData 只能提交一个symbol 效率太低
环境:win10+visual Studio 2017+python3.10 vnpy3.9.1
修改如下
打开
vnttsmd.cpp 找到 subscribeMarketData 函数如下
int MdApi::subscribeMarketData(string instrumentID)
{
char buffer = (char) instrumentID.c_str();
char* myreq[1] = { buffer };
int i = this->api->SubscribeMarketData(myreq, 1);
return i;
};
可以看到原始ctp是提交的数组,而这里给缩减到了只能提交一个品种。
做如下修改:
int MdApi::subscribeMarketData(pybind11::list instrumentID_list)
{
unsigned int num = static_cast<unsigned>(instrumentID_list.size());
char *myreq=new char[num];
int num_i = 0;
string x;
for (auto item : instrumentID_list)
{
x = new std::string(pybind11::str(item));
myreq[num_i] = (char)(*x).c_str();
num_i++;
}
int i = this->api->SubscribeMarketData(myreq, num);
delete[]myreq;
return i;
};
int MdApi::unSubscribeMarketData(pybind11::list instrumentID_list)
{
unsigned int num = static_cast<unsigned>(instrumentID_list.size());
char *myreq = new char[num];
int num_i = 0;
string x;
for (auto item : instrumentID_list)
{
x = new std::string(pybind11::str(item));
myreq[num_i] = (char)(*x).c_str();
num_i++;
}
int i = this->api->UnSubscribeMarketData(myreq, num);
delete[]myreq;
return i;
};
在 vnctpmd.h 注释掉原来的声明,添加新的声明如下
//int subscribeMarketData(string instrumentID);
int subscribeMarketData(pybind11::list instrumentID_list);
//int unSubscribeMarketData(string instrumentID);
int unSubscribeMarketData(pybind11::list instrumentID_list);
重新编译生成新的vnctpmd.pyd
复制该文件到 vnpy_ctp\api\ 下
修改ctp_gateway.py 文件中的几处
修改函数 CtpMdApi.onRspUserLogin 如下
def onRspUserLogin(self, data: dict, error: dict, reqid: int, last: bool) -> None:
"""用户登录请求回报"""
if not error["ErrorID"]:
self.login_status = True
self.gateway.write_log("行情服务器登录成功")
if len(self.subscribed)>0:
self.subscribe(self.subscribed)
# for symbol in self.subscribed:
# self.subscribeMarketData(symbol)
else:
self.gateway.write_error("行情服务器登录失败", error)
修改 CtpMdApi.subscribe 如下
def subscribe(self, req:list=[]) -> None:
"""订阅行情"""
if self.login_status:
self.subscribeMarketData(req)
for symbol in req:
self.subscribed.add(symbol)
修改 CtpGateWay.subscribe 如下
def subscribe(self, req:list=[]) -> None:
"""订阅行情"""
self.md_api.subscribe(req)
修改vnpy\trader\engine.py 下的MainEngine.subscribe
def subscribe(self, req: SubscribeRequest, gateway_name: str) -> None:
"""
Subscribe tick data update of a specific gateway.
"""
gateway: BaseGateway = self.get_gateway(gateway_name)
if gateway:
gateway.subscribe([req.symbol])
就可以使用 subscribeMarketData([‘rb2410’,’TA409’]) 这样的方式进行调用了。