vnpy/vn.sgit/vnsgitmd/vnsgitmd/vnsgitmd.cpp

1021 lines
24 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// MdApi.cpp : 定义 DLL 应用程序的导出函数。
//
#include "stdafx.h"
#include "vnsgitmd.h"
///-------------------------------------------------------------------------------------
///从Python对象到C++类型转换用的函数
///-------------------------------------------------------------------------------------
void getInt(dict d, string key, int *value)
{
if (d.has_key(key)) //检查字典中是否存在该键值
{
object o = d[key]; //获取该键值
extract<int> x(o); //创建提取器
if (x.check()) //如果可以提取
{
*value = x(); //对目标整数指针赋值
}
}
};
void getLong(dict d, string key, long *value)
{
if (d.has_key(key)) //检查字典中是否存在该键值
{
object o = d[key]; //获取该键值
extract<int> x(o); //创建提取器
if (x.check()) //如果可以提取
{
*value = x(); //对目标整数指针赋值
}
}
};
void getShort(dict d, string key, short *value)
{
if (d.has_key(key)) //检查字典中是否存在该键值
{
object o = d[key]; //获取该键值
extract<int> x(o); //创建提取器
if (x.check()) //如果可以提取
{
*value = x(); //对目标整数指针赋值
}
}
};
void getDouble(dict d, string key, double *value)
{
if (d.has_key(key))
{
object o = d[key];
extract<double> x(o);
if (x.check())
{
*value = x();
}
}
};
void getChar(dict d, string key, char *value)
{
if (d.has_key(key))
{
object o = d[key];
extract<string> x(o);
if (x.check())
{
string s = x();
const char *buffer = s.c_str();
*value = *buffer;
}
}
};
void getStr(dict d, string key, char *value)
{
if (d.has_key(key))
{
object o = d[key];
extract<string> x(o);
if (x.check())
{
string s = x();
const char *buffer = s.c_str();
//对字符串指针赋值必须使用strcpy_s, vs2013使用strcpy编译通不过
//+1应该是因为C++字符串的结尾符号不是特别确定不加这个1会出错
strcpy_s(value, strlen(buffer) + 1, buffer);
}
}
};
///-------------------------------------------------------------------------------------
///C++的回调函数将数据保存到队列中
///-------------------------------------------------------------------------------------
void MdApi::OnFrontConnected()
{
Task task = Task();
task.task_name = ONFRONTCONNECTED;
this->task_queue.push(task);
};
void MdApi::OnFrontDisconnected(int nReason)
{
Task task = Task();
task.task_name = ONFRONTDISCONNECTED;
task.task_id = nReason;
this->task_queue.push(task);
};
void MdApi::OnHeartBeatWarning(int nTimeLapse)
{
Task task = Task();
task.task_name = ONHEARTBEATWARNING;
task.task_id = nTimeLapse;
this->task_queue.push(task);
};
void MdApi::OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPUSERLOGIN;
if (pRspUserLogin)
{
task.task_data = *pRspUserLogin;
}
else
{
CThostFtdcRspUserLoginField empty_data = CThostFtdcRspUserLoginField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CThostFtdcRspInfoField empty_error = CThostFtdcRspInfoField();
memset(&empty_error, 0, sizeof(empty_error));
task.task_error = empty_error;
}
task.task_id = nRequestID;
task.task_last = bIsLast;
this->task_queue.push(task);
};
void MdApi::OnRspUserLogout(CThostFtdcUserLogoutField *pUserLogout, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPUSERLOGOUT;
if (pUserLogout)
{
task.task_data = *pUserLogout;
}
else
{
CThostFtdcUserLogoutField empty_data = CThostFtdcUserLogoutField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CThostFtdcRspInfoField empty_error = CThostFtdcRspInfoField();
memset(&empty_error, 0, sizeof(empty_error));
task.task_error = empty_error;
}
task.task_id = nRequestID;
task.task_last = bIsLast;
this->task_queue.push(task);
};
void MdApi::OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPERROR;
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CThostFtdcRspInfoField empty_error = CThostFtdcRspInfoField();
memset(&empty_error, 0, sizeof(empty_error));
task.task_error = empty_error;
}
task.task_id = nRequestID;
task.task_last = bIsLast;
this->task_queue.push(task);
};
void MdApi::OnRspSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPSUBMARKETDATA;
if (pSpecificInstrument)
{
task.task_data = *pSpecificInstrument;
}
else
{
CThostFtdcSpecificInstrumentField empty_data = CThostFtdcSpecificInstrumentField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CThostFtdcRspInfoField empty_error = CThostFtdcRspInfoField();
memset(&empty_error, 0, sizeof(empty_error));
task.task_error = empty_error;
}
task.task_id = nRequestID;
task.task_last = bIsLast;
this->task_queue.push(task);
};
void MdApi::OnRspUnSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPUNSUBMARKETDATA;
if (pSpecificInstrument)
{
task.task_data = *pSpecificInstrument;
}
else
{
CThostFtdcSpecificInstrumentField empty_data = CThostFtdcSpecificInstrumentField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CThostFtdcRspInfoField empty_error = CThostFtdcRspInfoField();
memset(&empty_error, 0, sizeof(empty_error));
task.task_error = empty_error;
}
task.task_id = nRequestID;
task.task_last = bIsLast;
this->task_queue.push(task);
};
void MdApi::OnRspSubForQuoteRsp(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPSUBFORQUOTERSP;
if (pSpecificInstrument)
{
task.task_data = *pSpecificInstrument;
}
else
{
CThostFtdcSpecificInstrumentField empty_data = CThostFtdcSpecificInstrumentField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CThostFtdcRspInfoField empty_error = CThostFtdcRspInfoField();
memset(&empty_error, 0, sizeof(empty_error));
task.task_error = empty_error;
}
task.task_id = nRequestID;
task.task_last = bIsLast;
this->task_queue.push(task);
};
void MdApi::OnRspUnSubForQuoteRsp(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPUNSUBFORQUOTERSP;
if (pSpecificInstrument)
{
task.task_data = *pSpecificInstrument;
}
else
{
CThostFtdcSpecificInstrumentField empty_data = CThostFtdcSpecificInstrumentField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CThostFtdcRspInfoField empty_error = CThostFtdcRspInfoField();
memset(&empty_error, 0, sizeof(empty_error));
task.task_error = empty_error;
}
task.task_id = nRequestID;
task.task_last = bIsLast;
this->task_queue.push(task);
};
void MdApi::OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData)
{
Task task = Task();
task.task_name = ONRTNDEPTHMARKETDATA;
if (pDepthMarketData)
{
task.task_data = *pDepthMarketData;
}
else
{
CThostFtdcDepthMarketDataField empty_data = CThostFtdcDepthMarketDataField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
this->task_queue.push(task);
};
void MdApi::OnRtnForQuoteRsp(CThostFtdcForQuoteRspField *pForQuoteRsp)
{
Task task = Task();
task.task_name = ONRTNFORQUOTERSP;
if (pForQuoteRsp)
{
task.task_data = *pForQuoteRsp;
}
else
{
CThostFtdcForQuoteRspField empty_data = CThostFtdcForQuoteRspField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
this->task_queue.push(task);
};
void MdApi::OnRtnDeferDeliveryQuot(CThostDeferDeliveryQuot *pQuot)
{
Task task = Task();
task.task_name = ONRTNDEFERDELIVERYQUOT;
if (pQuot)
{
task.task_data = pQuot;
}
else
{
CThostDeferDeliveryQuot empty_data = CThostDeferDeliveryQuot();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
this->task_queue.push(task);
};
///-------------------------------------------------------------------------------------
///工作线程从队列中取出数据转化为python对象后进行推送
///-------------------------------------------------------------------------------------
void MdApi::processTask()
{
while (1)
{
Task task = this->task_queue.wait_and_pop();
switch (task.task_name)
{
case ONFRONTCONNECTED:
{
this->processFrontConnected(task);
break;
}
case ONFRONTDISCONNECTED:
{
this->processFrontDisconnected(task);
break;
}
case ONHEARTBEATWARNING:
{
this->processHeartBeatWarning(task);
break;
}
case ONRSPUSERLOGIN:
{
this->processRspUserLogin(task);
break;
}
case ONRSPUSERLOGOUT:
{
this->processRspUserLogout(task);
break;
}
case ONRSPERROR:
{
this->processRspError(task);
break;
}
case ONRSPSUBMARKETDATA:
{
this->processRspSubMarketData(task);
break;
}
case ONRSPUNSUBMARKETDATA:
{
this->processRspUnSubMarketData(task);
break;
}
case ONRSPSUBFORQUOTERSP:
{
this->processRspSubForQuoteRsp(task);
break;
}
case ONRSPUNSUBFORQUOTERSP:
{
this->processRspUnSubForQuoteRsp(task);
break;
}
case ONRTNDEPTHMARKETDATA:
{
this->processRtnDepthMarketData(task);
break;
}
case ONRTNFORQUOTERSP:
{
this->processRtnForQuoteRsp(task);
break;
}
case ONRTNDEFERDELIVERYQUOT:
{
this->processRtnDeferDeliveryQuot(task);
break;
}
};
}
};
void MdApi::processFrontConnected(Task task)
{
PyLock lock;
this->onFrontConnected();
};
void MdApi::processFrontDisconnected(Task task)
{
PyLock lock;
this->onFrontDisconnected(task.task_id);
};
void MdApi::processHeartBeatWarning(Task task)
{
PyLock lock;
this->onHeartBeatWarning(task.task_id);
};
void MdApi::processRspUserLogin(Task task)
{
PyLock lock;
CThostFtdcRspUserLoginField task_data = any_cast<CThostFtdcRspUserLoginField>(task.task_data);
dict data;
data["CZCETime"] = task_data.CZCETime;
data["SHFETime"] = task_data.SHFETime;
data["MaxOrderRef"] = task_data.MaxOrderRef;
data["INETime"] = task_data.INETime;
data["UserID"] = task_data.UserID;
data["TradingDay"] = task_data.TradingDay;
data["SessionID"] = task_data.SessionID;
data["SystemName"] = task_data.SystemName;
data["FrontID"] = task_data.FrontID;
data["FFEXTime"] = task_data.FFEXTime;
data["BrokerID"] = task_data.BrokerID;
data["DCETime"] = task_data.DCETime;
data["LoginTime"] = task_data.LoginTime;
CThostFtdcRspInfoField task_error = any_cast<CThostFtdcRspInfoField>(task.task_error);
dict error;
error["ErrorMsg"] = task_error.ErrorMsg;
error["ErrorID"] = task_error.ErrorID;
this->onRspUserLogin(data, error, task.task_id, task.task_last);
};
void MdApi::processRspUserLogout(Task task)
{
PyLock lock;
CThostFtdcUserLogoutField task_data = any_cast<CThostFtdcUserLogoutField>(task.task_data);
dict data;
data["UserID"] = task_data.UserID;
data["BrokerID"] = task_data.BrokerID;
CThostFtdcRspInfoField task_error = any_cast<CThostFtdcRspInfoField>(task.task_error);
dict error;
error["ErrorMsg"] = task_error.ErrorMsg;
error["ErrorID"] = task_error.ErrorID;
this->onRspUserLogout(data, error, task.task_id, task.task_last);
};
void MdApi::processRspError(Task task)
{
PyLock lock;
CThostFtdcRspInfoField task_error = any_cast<CThostFtdcRspInfoField>(task.task_error);
dict error;
error["ErrorMsg"] = task_error.ErrorMsg;
error["ErrorID"] = task_error.ErrorID;
this->onRspError(error, task.task_id, task.task_last);
};
void MdApi::processRspSubMarketData(Task task)
{
PyLock lock;
CThostFtdcSpecificInstrumentField task_data = any_cast<CThostFtdcSpecificInstrumentField>(task.task_data);
dict data;
data["InstrumentID"] = task_data.InstrumentID;
CThostFtdcRspInfoField task_error = any_cast<CThostFtdcRspInfoField>(task.task_error);
dict error;
error["ErrorMsg"] = task_error.ErrorMsg;
error["ErrorID"] = task_error.ErrorID;
this->onRspSubMarketData(data, error, task.task_id, task.task_last);
};
void MdApi::processRspUnSubMarketData(Task task)
{
PyLock lock;
CThostFtdcSpecificInstrumentField task_data = any_cast<CThostFtdcSpecificInstrumentField>(task.task_data);
dict data;
data["InstrumentID"] = task_data.InstrumentID;
CThostFtdcRspInfoField task_error = any_cast<CThostFtdcRspInfoField>(task.task_error);
dict error;
error["ErrorMsg"] = task_error.ErrorMsg;
error["ErrorID"] = task_error.ErrorID;
this->onRspUnSubMarketData(data, error, task.task_id, task.task_last);
};
void MdApi::processRspSubForQuoteRsp(Task task)
{
PyLock lock;
CThostFtdcSpecificInstrumentField task_data = any_cast<CThostFtdcSpecificInstrumentField>(task.task_data);
dict data;
data["InstrumentID"] = task_data.InstrumentID;
CThostFtdcRspInfoField task_error = any_cast<CThostFtdcRspInfoField>(task.task_error);
dict error;
error["ErrorMsg"] = task_error.ErrorMsg;
error["ErrorID"] = task_error.ErrorID;
this->onRspSubForQuoteRsp(data, error, task.task_id, task.task_last);
};
void MdApi::processRspUnSubForQuoteRsp(Task task)
{
PyLock lock;
CThostFtdcSpecificInstrumentField task_data = any_cast<CThostFtdcSpecificInstrumentField>(task.task_data);
dict data;
data["InstrumentID"] = task_data.InstrumentID;
CThostFtdcRspInfoField task_error = any_cast<CThostFtdcRspInfoField>(task.task_error);
dict error;
error["ErrorMsg"] = task_error.ErrorMsg;
error["ErrorID"] = task_error.ErrorID;
this->onRspUnSubForQuoteRsp(data, error, task.task_id, task.task_last);
};
void MdApi::processRtnDepthMarketData(Task task)
{
PyLock lock;
CThostFtdcDepthMarketDataField task_data = any_cast<CThostFtdcDepthMarketDataField>(task.task_data);
dict data;
data["HighestPrice"] = task_data.HighestPrice;
data["BidPrice5"] = task_data.BidPrice5;
data["BidPrice4"] = task_data.BidPrice4;
data["BidPrice1"] = task_data.BidPrice1;
data["BidPrice3"] = task_data.BidPrice3;
data["BidPrice2"] = task_data.BidPrice2;
data["LowerLimitPrice"] = task_data.LowerLimitPrice;
data["OpenPrice"] = task_data.OpenPrice;
data["AskPrice5"] = task_data.AskPrice5;
data["AskPrice4"] = task_data.AskPrice4;
data["AskPrice3"] = task_data.AskPrice3;
data["PreClosePrice"] = task_data.PreClosePrice;
data["AskPrice1"] = task_data.AskPrice1;
data["PreSettlementPrice"] = task_data.PreSettlementPrice;
data["AskVolume1"] = task_data.AskVolume1;
data["UpdateTime"] = task_data.UpdateTime;
data["UpdateMillisec"] = task_data.UpdateMillisec;
data["AveragePrice"] = task_data.AveragePrice;
data["BidVolume5"] = task_data.BidVolume5;
data["BidVolume4"] = task_data.BidVolume4;
data["BidVolume3"] = task_data.BidVolume3;
data["BidVolume2"] = task_data.BidVolume2;
data["PreOpenInterest"] = task_data.PreOpenInterest;
data["AskPrice2"] = task_data.AskPrice2;
data["Volume"] = task_data.Volume;
data["AskVolume3"] = task_data.AskVolume3;
data["AskVolume2"] = task_data.AskVolume2;
data["AskVolume5"] = task_data.AskVolume5;
data["AskVolume4"] = task_data.AskVolume4;
data["UpperLimitPrice"] = task_data.UpperLimitPrice;
data["BidVolume1"] = task_data.BidVolume1;
data["InstrumentID"] = task_data.InstrumentID;
data["ClosePrice"] = task_data.ClosePrice;
data["ExchangeID"] = task_data.ExchangeID;
data["TradingDay"] = task_data.TradingDay;
data["PreDelta"] = task_data.PreDelta;
data["OpenInterest"] = task_data.OpenInterest;
data["CurrDelta"] = task_data.CurrDelta;
data["Turnover"] = task_data.Turnover;
data["LastPrice"] = task_data.LastPrice;
data["SettlementPrice"] = task_data.SettlementPrice;
data["ExchangeInstID"] = task_data.ExchangeInstID;
data["LowestPrice"] = task_data.LowestPrice;
data["ActionDay"] = task_data.ActionDay;
this->onRtnDepthMarketData(data);
};
void MdApi::processRtnForQuoteRsp(Task task)
{
PyLock lock;
CThostFtdcForQuoteRspField task_data = any_cast<CThostFtdcForQuoteRspField>(task.task_data);
dict data;
data["InstrumentID"] = task_data.InstrumentID;
data["ActionDay"] = task_data.ActionDay;
data["ExchangeID"] = task_data.ExchangeID;
data["TradingDay"] = task_data.TradingDay;
data["ForQuoteSysID"] = task_data.ForQuoteSysID;
data["ForQuoteTime"] = task_data.ForQuoteTime;
this->onRtnForQuoteRsp(data);
};
void MdApi::processRtnDeferDeliveryQuot(Task task)
{
PyLock lock;
CThostDeferDeliveryQuot task_data = any_cast<CThostDeferDeliveryQuot>(task.task_data);
dict data;
data["InstrumentID"] = task_data.InstrumentID;
data["AskVolume"] = task_data.AskVolume;
data["MidBidVolume"] = task_data.MidBidVolume;
data["BidVolume"] = task_data.BidVolume;
data["MidAskVolume"] = task_data.MidAskVolume;
this->onRtnDeferDeliveryQuot(data);
};
///-------------------------------------------------------------------------------------
///主动函数
///-------------------------------------------------------------------------------------
void MdApi::createFtdcMdApi(string pszFlowPath)
{
//该函数为手动编写
this->api = CThostFtdcMdApi::CreateFtdcMdApi(pszFlowPath.c_str());
this->api->RegisterSpi(this);
};
string MdApi::getApiVersion()
{
string version = this->api->GetApiVersion();
return version;
};
void MdApi::release()
{
//该函数为手动编写
this->api->Release();
};
void MdApi::init()
{
//该函数为手动编写
this->api->Init();
};
int MdApi::exit()
{
//该函数为手动编写
this->api->Release();
this->api = NULL;
return 1;
};
int MdApi::join()
{
//该函数为手动编写
int i = this->api->Join();
return i;
}
string MdApi::getTradingDay()
{
//该函数为手动编写
string day = this->api->GetTradingDay();
return day;
};
void MdApi::registerFront(string pszFrontAddress)
{
//该函数为手动编写
this->api->RegisterFront((char*)pszFrontAddress.c_str());
};
void MdApi::registerNameServer(string pszNsAddress)
{
//该函数为手动编写
this->api->RegisterNameServer((char*)pszNsAddress.c_str());
};
int MdApi::subscribeMarketData(string instrumentID)
{
char* buffer = (char*)instrumentID.c_str();
char* myreq[1] = { buffer };
int i = this->api->SubscribeMarketData(myreq, 1);
return i;
};
int MdApi::unSubscribeMarketData(string instrumentID)
{
char* buffer = (char*)instrumentID.c_str();
char* myreq[1] = { buffer };;
int i = this->api->UnSubscribeMarketData(myreq, 1);
return i;
};
int MdApi::subscribeForQuoteRsp(string instrumentID)
{
char* buffer = (char*)instrumentID.c_str();
char* myreq[1] = { buffer };
int i = this->api->SubscribeForQuoteRsp(myreq, 1);
return i;
};
int MdApi::unSubscribeForQuoteRsp(string instrumentID)
{
char* buffer = (char*)instrumentID.c_str();
char* myreq[1] = { buffer };;
int i = this->api->UnSubscribeForQuoteRsp(myreq, 1);
return i;
};
int MdApi::reqUserLogin(dict req, int nRequestID)
{
CThostFtdcReqUserLoginField myreq = CThostFtdcReqUserLoginField();
memset(&myreq, 0, sizeof(myreq));
getStr(req, "MacAddress", myreq.MacAddress);
getStr(req, "UserProductInfo", myreq.UserProductInfo);
getStr(req, "UserID", myreq.UserID);
getStr(req, "TradingDay", myreq.TradingDay);
getStr(req, "InterfaceProductInfo", myreq.InterfaceProductInfo);
getStr(req, "BrokerID", myreq.BrokerID);
getStr(req, "ClientIPAddress", myreq.ClientIPAddress);
getStr(req, "OneTimePassword", myreq.OneTimePassword);
getStr(req, "ProtocolInfo", myreq.ProtocolInfo);
getStr(req, "Password", myreq.Password);
int i = this->api->ReqUserLogin(&myreq, nRequestID);
return i;
};
int MdApi::reqUserLogout(dict req, int nRequestID)
{
CThostFtdcUserLogoutField myreq = CThostFtdcUserLogoutField();
memset(&myreq, 0, sizeof(myreq));
getStr(req, "UserID", myreq.UserID);
getStr(req, "BrokerID", myreq.BrokerID);
int i = this->api->ReqUserLogout(&myreq, nRequestID);
return i;
};
///-------------------------------------------------------------------------------------
///Boost.Python封装
///-------------------------------------------------------------------------------------
struct MdApiWrap : MdApi, wrapper < MdApi >
{
virtual void onFrontConnected()
{
//以下的try...catch...可以实现捕捉python环境中错误的功能防止C++直接出现原因未知的崩溃
try
{
this->get_override("onFrontConnected")();
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onFrontDisconnected(int reason)
{
try
{
this->get_override("onFrontDisconnected")(reason);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onHeartBeatWarning(int timeLapse)
{
try
{
this->get_override("onHeartBeatWarning")(timeLapse);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onRspUserLogin(dict data, dict error, int id, bool last)
{
try
{
this->get_override("onRspUserLogin")(data, error, id, last);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onRspUserLogout(dict data, dict error, int id, bool last)
{
try
{
this->get_override("onRspUserLogout")(data, error, id, last);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onRspError(dict error, int id, bool last)
{
try
{
this->get_override("onRspError")(error, id, last);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onRspSubMarketData(dict data, dict error, int id, bool last)
{
try
{
this->get_override("onRspSubMarketData")(data, error, id, last);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onRspUnSubMarketData(dict data, dict error, int id, bool last)
{
try
{
this->get_override("onRspUnSubMarketData")(data, error, id, last);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onRspSubForQuoteRsp(dict data, dict error, int id, bool last)
{
try
{
this->get_override("onRspSubForQuoteRsp")(data, error, id, last);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onRspUnSubForQuoteRsp(dict data, dict error, int id, bool last)
{
try
{
this->get_override("onRspUnSubForQuoteRsp")(data, error, id, last);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onRtnDepthMarketData(dict data)
{
try
{
this->get_override("onRtnDepthMarketData")(data);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onRtnForQuoteRsp(dict data)
{
try
{
this->get_override("onRtnForQuoteRsp")(data);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onRtnDeferDeliveryQuot(dict data)
{
try
{
this->get_override("onRtnDeferDeliveryQuot")(data);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
};
BOOST_PYTHON_MODULE(vnsgitmd)
{
PyEval_InitThreads(); //导入时运行保证先创建GIL
class_<MdApiWrap, boost::noncopyable>("MdApi")
.def("createFtdcMdApi", &MdApiWrap::createFtdcMdApi)
.def("getApiVersion", &MdApiWrap::getApiVersion)
.def("release", &MdApiWrap::release)
.def("init", &MdApiWrap::init)
.def("join", &MdApiWrap::join)
.def("exit", &MdApiWrap::exit)
.def("getTradingDay", &MdApiWrap::getTradingDay)
.def("registerFront", &MdApiWrap::registerFront)
.def("registerNameServer", &MdApiWrap::registerNameServer)
.def("subscribeMarketData", &MdApiWrap::subscribeMarketData)
.def("unSubscribeMarketData", &MdApiWrap::unSubscribeMarketData)
.def("subscribeForQuoteRsp", &MdApiWrap::subscribeForQuoteRsp)
.def("unSubscribeForQuoteRsp", &MdApiWrap::unSubscribeForQuoteRsp)
.def("reqUserLogin", &MdApiWrap::reqUserLogin)
.def("reqUserLogout", &MdApiWrap::reqUserLogout)
.def("onFrontConnected", pure_virtual(&MdApiWrap::onFrontConnected))
.def("onFrontDisconnected", pure_virtual(&MdApiWrap::onFrontDisconnected))
.def("onHeartBeatWarning", pure_virtual(&MdApiWrap::onHeartBeatWarning))
.def("onRspUserLogin", pure_virtual(&MdApiWrap::onRspUserLogin))
.def("onRspUserLogout", pure_virtual(&MdApiWrap::onRspUserLogout))
.def("onRspError", pure_virtual(&MdApiWrap::onRspError))
.def("onRspSubMarketData", pure_virtual(&MdApiWrap::onRspSubMarketData))
.def("onRspUnSubMarketData", pure_virtual(&MdApiWrap::onRspUnSubMarketData))
.def("onRspSubForQuoteRsp", pure_virtual(&MdApiWrap::onRspSubForQuoteRsp))
.def("onRspUnSubForQuoteRsp", pure_virtual(&MdApiWrap::onRspUnSubForQuoteRsp))
.def("onRtnDepthMarketData", pure_virtual(&MdApiWrap::onRtnDepthMarketData))
.def("onRtnForQuoteRsp", pure_virtual(&MdApiWrap::onRtnForQuoteRsp))
.def("onRtnDeferDeliveryQuot", pure_virtual(&MdApiWrap::onRtnDeferDeliveryQuot))
;
};