增加飞鼠柜台的交易接口,支持期货和金交所的黄金T+D,主要针对高频交易

This commit is contained in:
lyic 2016-03-30 20:15:09 +08:00
parent 9c3a5fce52
commit b3dcf8745a
52 changed files with 38294 additions and 0 deletions

View File

@ -0,0 +1,118 @@
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
#if !defined(Sgit_FTDCMDAPI_H)
#define Sgit_FTDCMDAPI_H
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "SgitFtdcUserApiStruct.h"
#if defined(ISLIB) && defined(WIN32)
#ifdef LIB_MD_API_EXPORT
#define MD_API_EXPORT __declspec(dllexport)
#else
#define MD_API_EXPORT __declspec(dllimport)
#endif
#else
#define MD_API_EXPORT
#endif
class CSgitFtdcMdSpi
{
public:
///当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。
virtual void OnFrontConnected(){};
///当客户端与交易后台通信连接断开时该方法被调用。当发生这个情况后API会自动重新连接客户端可不做处理。
///@param pErrMsg 错误原因
virtual void OnFrontDisconnected(char *pErrMsg){};
///登录请求响应
virtual void OnRspUserLogin(CSgitFtdcRspUserLoginField *pRspUserLogin, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///登出请求响应
virtual void OnRspUserLogout(CSgitFtdcUserLogoutField *pUserLogout, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///深度行情通知
virtual void OnRtnDepthMarketData(CSgitFtdcDepthMarketDataField *pDepthMarketData) {};
};
class MD_API_EXPORT CSgitFtdcMdApi
{
public:
///创建MdApi
///@param pszFlowPath 存贮订阅信息文件的目录,默认为当前目录
///@return 创建出的UserApi
static CSgitFtdcMdApi *CreateFtdcMdApi(const char *pszFlowPath = "");
///删除接口对象本身
///@remark 不再使用本接口对象时,调用该函数删除接口对象
virtual void Release() = 0;
///初始化
///@remark 初始化运行环境,只有调用后,接口才开始工作
///isLogged 开发调试时使用true可以打印出收到的消息包内容
virtual void Init(bool isLogged) = 0;
///等待接口线程结束运行
///@return 线程退出代码
virtual int Join() = 0;
///获取当前交易日
///@retrun 获取到的交易日
///@remark 只有登录成功后,才能得到正确的交易日
virtual const char *GetTradingDay() = 0;
///注册前置机网络地址
///@param pszFrontAddress前置机网络地址。
///@remark 网络地址的格式为“protocol://ipaddress:port””tcp://127.0.0.1:17001”。
///@remark “tcp”代表传输协议“127.0.0.1”代表服务器地址。”17001”代表服务器端口号。
virtual void RegisterFront(char *pszFrontAddress) = 0;
/**用多播时TCP配置也需要设置
*tcp模式发送行情
* MlCast://hostIP$multiaddress:port
* MlCast://ANY$multiaddress:port
* @param szMlCastAddr ip地址
*/
virtual void SetMultiCastAddr(char *szMlCastAddr) = 0;
///注册回调接口
///@param pSpi 派生自回调接口类的实例
virtual void RegisterSpi(CSgitFtdcMdSpi *pSpi) = 0;
///订阅市场流。
///@param nResumeType 公共流重传方式
/// Sgit_TERT_RESTART:从本交易日开始重传
/// Sgit_TERT_RESUME:从上次收到的续传
/// Sgit_TERT_QUICK:只传送登录后公共流的内容
///@remark 该方法要在Init方法前调用。若不调用则不会收到公共流的数据。
virtual void SubscribeMarketTopic(Sgit_TE_RESUME_TYPE nResumeType) = 0;
///
/// 发送行情订阅
/// @param iRequestID 请求号
/// @param pMBLQuotReq 行情订阅请求域
/// @return 0表示成功
/// @return 其它表示失败
///
virtual int SubQuot(CSgitSubQuotField *pSgitSubQuotField)=0;
///发送就绪指令到前置,通知前置可以给自己发送私有流与公共流
/// @return 0表示成功
/// @return 其它参见错误码
///
virtual int Ready() = 0;
///用户登录请求
virtual int ReqUserLogin(CSgitFtdcReqUserLoginField *pReqUserLoginField, int nRequestID) = 0;
///登出请求
virtual int ReqUserLogout(CSgitFtdcUserLogoutField *pUserLogout, int nRequestID) = 0;
protected:
~CSgitFtdcMdApi(){};
};
#endif

View File

@ -0,0 +1,179 @@
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
#if !defined(Sgit_FTDCTRADERAPI_H)
#define Sgit_FTDCTRADERAPI_H
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "SgitFtdcUserApiStruct.h"
#if defined(ISLIB) && defined(WIN32)
#ifdef LIB_TRADER_API_EXPORT
#define TRADER_API_EXPORT __declspec(dllexport)
#else
#define TRADER_API_EXPORT __declspec(dllimport)
#endif
#else
#define TRADER_API_EXPORT
#endif
class CSgitFtdcTraderSpi
{
public:
///当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。
virtual void OnFrontConnected(){};
///当客户端与交易后台通信连接断开时该方法被调用。当发生这个情况后API会自动重新连接客户端可不做处理。
///@param pErrMsg 错误原因
virtual void OnFrontDisconnected(char *pErrMsg){};
///登录请求响应
virtual void OnRspUserLogin(CSgitFtdcRspUserLoginField *pRspUserLogin, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///登出请求响应
virtual void OnRspUserLogout(CSgitFtdcUserLogoutField *pUserLogout, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///用户口令更新请求响应
virtual void OnRspUserPasswordUpdate(CSgitFtdcUserPasswordUpdateField *pUserPasswordUpdate, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///报单录入请求响应
virtual void OnRspOrderInsert(CSgitFtdcInputOrderField *pInputOrder, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///报单操作请求响应
virtual void OnRspOrderAction(CSgitFtdcInputOrderActionField *pInputOrderAction, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///请求查询报单响应
virtual void OnRspQryOrder(CSgitFtdcOrderField *pOrder, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///请求查询资金账户响应
virtual void OnRspQryTradingAccount(CSgitFtdcTradingAccountField *pTradingAccount, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///请求查询投资者响应
virtual void OnRspQryInvestor(CSgitFtdcInvestorField *pInvestor, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///请求查询合约响应
virtual void OnRspQryInstrument(CSgitFtdcInstrumentField *pInstrument, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///报单通知
virtual void OnRtnOrder(CSgitFtdcOrderField *pOrder,CSgitFtdcRspInfoField *pRspInfo) {};
///成交通知
virtual void OnRtnTrade(CSgitFtdcTradeField *pTrade) {};
///合约交易状态通知
virtual void OnRtnInstrumentStatus(CSgitFtdcInstrumentStatusField *pInstrumentStatus) {};
///请求查询投资者持仓明细响应
virtual void OnRspQryInvestorPositionDetail(CSgitFtdcInvestorPositionDetailField *pInvestorPositionDetail, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///请求查询投资者持仓响应
virtual void OnRspQryInvestorPosition(CSgitFtdcInvestorPositionField *pInvestorPosition, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
/// 当收到合约价位查询应答时回调该函数
virtual void onRspMBLQuot(CSgitMBLQuotData *pMBLQuotData,CSgitFtdcRspInfoField *pRspMsg,int nRequestID,bool bIsLast){};
};
class TRADER_API_EXPORT CSgitFtdcTraderApi
{
public:
///创建TraderApi
///@param pszFlowPath 存贮订阅信息文件的目录,默认为当前目录
///@return 创建出的UserApi
static CSgitFtdcTraderApi *CreateFtdcTraderApi(const char *pszFlowPath = "");
///删除接口对象本身
///@remark 不再使用本接口对象时,调用该函数删除接口对象
virtual void Release() = 0;
///初始化
///@remark 初始化运行环境,只有调用后,接口才开始工作
///isLogged 开发调试时使用true可以打印出收到的消息包内容
virtual void Init(bool isLogged) = 0;
///等待接口线程结束运行
///@return 线程退出代码
virtual int Join() = 0;
///获取当前交易日
///@retrun 获取到的交易日
///@remark 只有登录成功后,才能得到正确的交易日
virtual const char *GetTradingDay() = 0;
///注册前置机网络地址
///@param pszFrontAddress前置机网络地址。
///@remark 网络地址的格式为“protocol://ipaddress:port””tcp://127.0.0.1:17001”。
///@remark “tcp”代表传输协议“127.0.0.1”代表服务器地址。”17001”代表服务器端口号。
virtual void RegisterFront(char *pszFrontAddress) = 0;
///注册回调接口
///@param pSpi 派生自回调接口类的实例
virtual void RegisterSpi(CSgitFtdcTraderSpi *pSpi) = 0;
///订阅私有流。
///@param nResumeType 私有流重传方式
/// Sgit_TERT_RESTART:从本交易日开始重传
/// Sgit_TERT_RESUME:从上次收到的续传
/// Sgit_TERT_QUICK:只传送登录后私有流的内容
///@remark 该方法要在Init方法前调用。若不调用则不会收到私有流的数据。
virtual void SubscribePrivateTopic(Sgit_TE_RESUME_TYPE nResumeType) = 0;
///订阅公共流。
///@param nResumeType 公共流重传方式
/// Sgit_TERT_RESTART:从本交易日开始重传
/// Sgit_TERT_RESUME:从上次收到的续传
/// Sgit_TERT_QUICK:只传送登录后公共流的内容
///@remark 该方法要在Init方法前调用。若不调用则不会收到公共流的数据。
virtual void SubscribePublicTopic(Sgit_TE_RESUME_TYPE nResumeType) = 0;
///发送就绪指令到前置,通知前置可以给自己发送私有流与公共流
/// @return 0表示成功
/// @return 其它参见错误码
///
virtual int Ready() = 0;
///用户登录请求
virtual int ReqUserLogin(CSgitFtdcReqUserLoginField *pReqUserLoginField, int nRequestID) = 0;
///登出请求
virtual int ReqUserLogout(CSgitFtdcUserLogoutField *pUserLogout, int nRequestID) = 0;
///用户口令更新请求
virtual int ReqUserPasswordUpdate(CSgitFtdcUserPasswordUpdateField *pUserPasswordUpdate, int nRequestID) = 0;
///报单录入请求
virtual int ReqOrderInsert(CSgitFtdcInputOrderField *pInputOrder, int nRequestID) = 0;
///报单操作请求
virtual int ReqOrderAction(CSgitFtdcInputOrderActionField *pInputOrderAction, int nRequestID) = 0;
///请求查询报单
virtual int ReqQryOrder(CSgitFtdcQryOrderField *pQryOrder, int nRequestID) = 0;
///请求查询资金账户
virtual int ReqQryTradingAccount(CSgitFtdcQryTradingAccountField *pQryTradingAccount, int nRequestID) = 0;
///请求查询投资者
virtual int ReqQryInvestor(CSgitFtdcQryInvestorField *pQryInvestor, int nRequestID) = 0;
///请求查询合约
virtual int ReqQryInstrument(CSgitFtdcQryInstrumentField *pQryInstrument, int nRequestID) = 0;
///请求查询投资者持仓明细
virtual int ReqQryInvestorPositionDetail(CSgitFtdcQryInvestorPositionDetailField *pQryInvestorPositionDetail, int nRequestID) = 0;
///请求查询投资者持仓
virtual int ReqQryInvestorPosition(CSgitFtdcQryInvestorPositionField *pQryInvestorPosition, int nRequestID) = 0;
/// 发送合约价位查询请求
virtual int ReqMBLQuot(int iRequestID,CSgitMBLQuotReq *pMBLQuotReq) = 0;
protected:
~CSgitFtdcTraderApi(){};
};
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,111 @@
# encoding: UTF-8
__author__ = 'CHENXY'
# C++和python类型的映射字典
type_dict = {
'int': 'int',
'char': 'string',
'double': 'float'
}
def process_line(line):
"""处理每行"""
if '///' in line: # 注释
py_line = process_comment(line)
elif 'typedef' in line: # 类型申明
py_line = process_typedef(line)
elif '#define' in line: # 定义常量
py_line = process_define(line)
elif line == '\n': # 空行
py_line = line
else:
py_line = ''
return py_line
def process_comment(line):
"""处理注释"""
# if line[3] == '/':
# py_line = ''
# else:
# py_line = '#' + line[3:]
py_line = '#' + line[3:]
return py_line
def process_typedef(line):
"""处理类型申明"""
content = line.split(' ')
type_ = type_dict[content[1]]
if content[1] != 'unsigned':
keyword = content[-1]
else:
keyword = content[-1]
keyword = keyword.replace(';\n', '')
print content, keyword
if '[' in keyword:
i = keyword.index('[')
keyword = keyword[:i]
else:
keyword = keyword.replace(';\n', '') # 删除行末分号
if 'char' in line:
if '[' in line:
type_ = 'string'
else:
type_ = 'char'
py_line = 'typedefDict["%s"] = "%s"\n' % (keyword, type_)
return py_line
def process_define(line):
"""处理定义常量"""
content = line.split(' ')
constant = content[1]
if len(content)>2:
value = content[-1]
py_line = 'defineDict["%s"] = %s' % (constant, value)
else:
py_line = ''
return py_line
def main():
"""主函数"""
try:
fcpp = open('SgitFtdcUserApiDataType.h','r')
fpy = open('sgit_data_type.py', 'w')
fpy.write('# encoding: UTF-8\n')
fpy.write('\n')
fpy.write('defineDict = {}\n')
fpy.write('typedefDict = {}\n')
fpy.write('\n')
for n, line in enumerate(fcpp):
py_line = process_line(line)
if py_line:
fpy.write(py_line.decode('gbk').encode('utf-8'))
print n
fcpp.close()
fpy.close()
print u'data_type.py生成过程完成'
except Exception, e:
print u'data_type.py生成过程出错'
print e
if __name__ == '__main__':
main()

View File

@ -0,0 +1,310 @@
# encoding: UTF-8
__author__ = 'CHENXY'
from string import join
from sgit_struct import structDict
def processCallBack(line):
orignalLine = line
line = line.replace(' virtual void ', '') # 删除行首的无效内容
line = line.replace('{};\n', '') # 删除行尾的无效内容
content = line.split('(')
cbName = content[0] # 回调函数名称
cbArgs = content[1] # 回调函数参数
if cbArgs[-1] == ' ':
cbArgs = cbArgs.replace(') ', '')
else:
cbArgs = cbArgs.replace(')', '')
cbArgsList = cbArgs.split(', ') # 将每个参数转化为列表
cbArgsTypeList = []
cbArgsValueList = []
for arg in cbArgsList: # 开始处理参数
content = arg.split(' ')
if len(content) > 1:
if 'struct' not in content:
cbArgsTypeList.append(content[0]) # 参数类型列表
cbArgsValueList.append(content[1]) # 参数数据列表
else:
print content
cbArgsTypeList.append(content[1]) # 参数类型列表
cbArgsValueList.append(content[2]+content[3]) # 参数数据列表
createTask(cbName, cbArgsTypeList, cbArgsValueList, orignalLine)
createProcess(cbName, cbArgsTypeList, cbArgsValueList)
# 生成.h文件中的process部分
process_line = 'void process' + cbName[2:] + '(Task task);\n'
fheaderprocess.write(process_line)
fheaderprocess.write('\n')
# 生成.h文件中的on部分
if 'OnRspError' in cbName:
on_line = 'virtual void on' + cbName[2:] + '(dict error) {};\n'
elif 'OnRspQry' in cbName:
on_line = 'virtual void on' + cbName[2:] + '(dict data, dict error, int id, bool last) {};\n'
elif 'OnRsp' in cbName:
on_line = 'virtual void on' + cbName[2:] + '(dict data, dict error, int id, bool last) {};\n'
elif 'OnRtn' in cbName:
on_line = 'virtual void on' + cbName[2:] + '(dict data) {};\n'
elif 'OnErrRtn' in cbName:
on_line = 'virtual void on' + cbName[2:] + '(dict data, dict error) {};\n'
else:
on_line = ''
fheaderon.write(on_line)
fheaderon.write('\n')
# 生成封装部分
createWrap(cbName)
#----------------------------------------------------------------------
def createWrap(cbName):
"""在Python封装段代码中进行处理"""
# 生成.h文件中的on部分
if 'OnRspError' in cbName:
on_line = 'virtual void on' + cbName[2:] + '(dict error)\n'
override_line = '("on' + cbName[2:] + '")(error);\n'
elif 'OnRsp' in cbName:
on_line = 'virtual void on' + cbName[2:] + '(dict data, dict error, int id, bool last)\n'
override_line = '("on' + cbName[2:] + '")(data, error, id, last);\n'
elif 'OnRtn' in cbName:
on_line = 'virtual void on' + cbName[2:] + '(dict data)\n'
override_line = '("on' + cbName[2:] + '")(data);\n'
elif 'OnErrRtn' in cbName:
on_line = 'virtual void on' + cbName[2:] + '(dict data, dict error)\n'
override_line = '("on' + cbName[2:] + '")(data, error);\n'
else:
on_line = ''
if on_line is not '':
fwrap.write(on_line)
fwrap.write('{\n')
fwrap.write('\ttry\n')
fwrap.write('\t{\n')
fwrap.write('\t\tthis->get_override'+override_line)
fwrap.write('\t}\n')
fwrap.write('\tcatch (error_already_set const &)\n')
fwrap.write('\t{\n')
fwrap.write('\t\tPyErr_Print();\n')
fwrap.write('\t}\n')
fwrap.write('};\n')
fwrap.write('\n')
def createTask(cbName, cbArgsTypeList, cbArgsValueList, orignalLine):
# 从回调函数生成任务对象,并放入队列
funcline = orignalLine.replace(' virtual void ', 'void ' + apiName + '::')
funcline = funcline.replace('{};', '')
funcline = funcline.replace(' {}', '')
ftask.write(funcline)
ftask.write('{\n')
ftask.write("\tTask task = Task();\n")
ftask.write("\ttask.task_name = " + cbName.upper() + ";\n")
# define常量
global define_count
fdefine.write("#define " + cbName.upper() + ' ' + str(define_count) + '\n')
define_count = define_count + 1
# switch段代码
fswitch.write("case " + cbName.upper() + ':\n')
fswitch.write("{\n")
fswitch.write("\tthis->" + cbName.replace('On', 'process') + '(task);\n')
fswitch.write("\tbreak;\n")
fswitch.write("}\n")
fswitch.write("\n")
for i, type_ in enumerate(cbArgsTypeList):
if type_ == 'int':
ftask.write("\ttask.task_id = " + cbArgsValueList[i] + ";\n")
elif type_ == 'bool':
ftask.write("\ttask.task_last = " + cbArgsValueList[i] + ";\n")
elif 'CSgitFtdcRspInfoField' in type_:
ftask.write("\n")
ftask.write("\tif (pRspInfo)\n")
ftask.write("\t{\n")
ftask.write("\t\ttask.task_error = " + cbArgsValueList[i] + ";\n")
ftask.write("\t}\n")
ftask.write("\telse\n")
ftask.write("\t{\n")
ftask.write("\t\tCSgitFtdcRspInfoField empty_error = CSgitFtdcRspInfoField();\n")
ftask.write("\t\tmemset(&empty_error, 0, sizeof(empty_error));\n")
ftask.write("\t\ttask.task_error = empty_error;\n")
ftask.write("\t}\n")
else:
ftask.write("\n")
ftask.write("\tif (" + cbArgsValueList[i][1:] + ")\n")
ftask.write("\t{\n")
ftask.write("\t\ttask.task_data = " + cbArgsValueList[i] + ";\n")
ftask.write("\t}\n")
ftask.write("\telse\n")
ftask.write("\t{\n")
ftask.write("\t\t" + type_ + " empty_data = " + type_ + "();\n")
ftask.write("\t\tmemset(&empty_data, 0, sizeof(empty_data));\n")
ftask.write("\t\ttask.task_data = empty_data;\n")
ftask.write("\t}\n")
ftask.write("\tthis->task_queue.push(task);\n")
ftask.write("};\n")
ftask.write("\n")
def createProcess(cbName, cbArgsTypeList, cbArgsValueList):
# 从队列中提取任务并转化为python字典
fprocess.write("void " + apiName + '::' + cbName.replace('On', 'process') + '(Task task)' + "\n")
fprocess.write("{\n")
fprocess.write("\tPyLock lock;\n")
onArgsList = []
for i, type_ in enumerate(cbArgsTypeList):
if 'CSgitFtdcRspInfoField' in type_:
fprocess.write("\t"+ type_ + ' task_error = any_cast<' + type_ + '>(task.task_error);\n')
fprocess.write("\t"+ "dict error;\n")
struct = structDict[type_]
for key in struct.keys():
fprocess.write("\t"+ 'error["' + key + '"] = task_error.' + key + ';\n')
fprocess.write("\n")
onArgsList.append('error')
elif type_ in structDict:
fprocess.write("\t"+ type_ + ' task_data = any_cast<' + type_ + '>(task.task_data);\n')
fprocess.write("\t"+ "dict data;\n")
struct = structDict[type_]
for key in struct.keys():
fprocess.write("\t"+ 'data["' + key + '"] = task_data.' + key + ';\n')
fprocess.write("\n")
onArgsList.append('data')
elif type_ == 'bool':
onArgsList.append('task.task_last')
elif type_ == 'int':
onArgsList.append('task.task_id')
onArgs = join(onArgsList, ', ')
fprocess.write('\tthis->' + cbName.replace('On', 'on') + '(' + onArgs +');\n')
fprocess.write("};\n")
fprocess.write("\n")
def processFunction(line):
line = line.replace(' virtual int ', '') # 删除行首的无效内容
line = line.replace(') = 0;\n', '') # 删除行尾的无效内容
content = line.split('(')
fcName = content[0] # 回调函数名称
fcArgs = content[1] # 回调函数参数
fcArgs = fcArgs.replace(')', '')
fcArgsList = fcArgs.split(',') # 将每个参数转化为列表
fcArgsTypeList = []
fcArgsValueList = []
for arg in fcArgsList: # 开始处理参数
content = arg.split(' ')
if len(content) >= 2:
fcArgsTypeList.append(content[0]) # 参数类型列表
fcArgsValueList.append(content[1]) # 参数数据列表
print line
print fcArgs
print fcArgsList
print fcArgsTypeList
if len(fcArgsTypeList)>0 and fcArgsTypeList[0] in structDict:
createFunction(fcName, fcArgsTypeList, fcArgsValueList)
# 生成.h文件中的主动函数部分
if 'Req' in fcName:
req_line = 'int req' + fcName[3:] + '(dict req, int nRequestID);\n'
fheaderfunction.write(req_line)
fheaderfunction.write('\n')
def createFunction(fcName, fcArgsTypeList, fcArgsValueList):
type_ = fcArgsTypeList[0]
struct = structDict[type_]
ffunction.write('int ' + apiName + '::req' + fcName[3:] + '(dict req, int nRequestID)\n')
ffunction.write('{\n')
ffunction.write('\t' + type_ +' myreq = ' + type_ + '();\n')
ffunction.write('\tmemset(&myreq, 0, sizeof(myreq));\n')
for key, value in struct.items():
if value == 'string':
line = '\tgetString(req, "' + key + '", myreq.' + key + ');\n'
elif value == 'char':
line = '\tgetChar(req, "' + key + '", &myreq.' + key + ');\n'
elif value == 'int':
line = '\tgetInt(req, "' + key + '", &myreq.' + key + ');\n'
elif value == 'long':
line = '\tgetLong(req, "' + key + '", &myreq.' + key + ');\n'
elif value == 'short':
line = '\tgetShort(req, "' + key + '", &myreq.' + key + ');\n'
elif value == 'double':
line = '\tgetDouble(req, "' + key + '", &myreq.' + key + ');\n'
ffunction.write(line)
ffunction.write('\tint i = this->api->' + fcName + '(&myreq, nRequestID);\n')
ffunction.write('\treturn i;\n')
ffunction.write('};\n')
ffunction.write('\n')
#########################################################
apiName = 'MdApi'
fcpp = open('SgitFtdcMdApi.h', 'r')
ftask = open('sgit_md_task.cpp', 'w')
fprocess = open('sgit_md_process.cpp', 'w')
ffunction = open('sgit_md_function.cpp', 'w')
fdefine = open('sgit_md_define.cpp', 'w')
fswitch = open('sgit_md_switch.cpp', 'w')
fheaderprocess = open('sgit_md_header_process.h', 'w')
fheaderon = open('sgit_md_header_on.h', 'w')
fheaderfunction = open('sgit_md_header_function.h', 'w')
fwrap = open('sgit_md_wrap.cpp', 'w')
define_count = 1
for line in fcpp:
if " virtual void On" in line:
print 'callback'
processCallBack(line)
elif " virtual int" in line:
print 'function'
processFunction(line)
fcpp.close()
ftask.close()
fprocess.close()
ffunction.close()
fswitch.close()
fdefine.close()
fheaderprocess.close()
fheaderon.close()
fheaderfunction.close()
fwrap.close()

View File

@ -0,0 +1,78 @@
# encoding: UTF-8
__author__ = 'CHENXY'
from sgit_data_type import *
import re
def main():
"""主函数"""
fcpp = open('SgitFtdcUserApiStruct.h', 'r')
fpy = open('sgit_struct.py', 'w')
fpy.write('# encoding: UTF-8\n')
fpy.write('\n')
fpy.write('structDict = {}\n')
fpy.write('\n')
for no, line in enumerate(fcpp):
# 结构体申明注释
if '///' in line and '\t' not in line:
py_line = '#' + line[3:]
# 结构体变量注释
elif '\t///' in line:
py_line = '#' + line[4:]
# 结构体申明
elif 'struct' in line:
content = line.split(' ')
name = content[-1].replace('\n','')
py_line = '%s = {}\n' % name
# 结构体变量
elif ' ' in line and '///' not in line and '{' not in line:
#content = line.split('\t')
if ' ;' in line:
line = line.replace(' ;', ';')
if ' ' in line:
line = re.sub(' +', '\t', line)
if '\t\t' in line:
line = re.sub('\t+', '\t', line)
if '//' in line:
n = line.index('//')
line = line[:n]
print no, ':', line
content = line.split('\t')
print content
typedef = content[1]
type_ = typedefDict[typedef]
variable = content[2].replace(';\n', "")
if ';' in variable:
variable = variable.replace(';', '')
py_line = '%s["%s"] = "%s"\n' % (name, variable, type_)
# 结构体结束
elif '}' in line:
py_line = "structDict['%s'] = %s\n\n" % (name, name)
# 结构体开始
elif '{' in line:
py_line = ''
# 其他
else:
py_line = '\n'
fpy.write(py_line.decode('gbk').encode('utf-8'))
if __name__ == '__main__':
main()

View File

@ -0,0 +1,310 @@
# encoding: UTF-8
__author__ = 'CHENXY'
from string import join
from sgit_struct import structDict
def processCallBack(line):
orignalLine = line
line = line.replace(' virtual void ', '') # 删除行首的无效内容
line = line.replace('{};\n', '') # 删除行尾的无效内容
content = line.split('(')
cbName = content[0] # 回调函数名称
cbArgs = content[1] # 回调函数参数
if cbArgs[-1] == ' ':
cbArgs = cbArgs.replace(') ', '')
else:
cbArgs = cbArgs.replace(')', '')
cbArgsList = cbArgs.split(', ') # 将每个参数转化为列表
cbArgsTypeList = []
cbArgsValueList = []
for arg in cbArgsList: # 开始处理参数
content = arg.split(' ')
if len(content) > 1:
if 'struct' not in content:
cbArgsTypeList.append(content[0]) # 参数类型列表
cbArgsValueList.append(content[1]) # 参数数据列表
else:
print content
cbArgsTypeList.append(content[1]) # 参数类型列表
cbArgsValueList.append(content[2]+content[3]) # 参数数据列表
createTask(cbName, cbArgsTypeList, cbArgsValueList, orignalLine)
createProcess(cbName, cbArgsTypeList, cbArgsValueList)
# 生成.h文件中的process部分
process_line = 'void process' + cbName[2:] + '(Task task);\n'
fheaderprocess.write(process_line)
fheaderprocess.write('\n')
# 生成.h文件中的on部分
if 'OnRspError' in cbName:
on_line = 'virtual void on' + cbName[2:] + '(dict error) {};\n'
elif 'OnRspQry' in cbName:
on_line = 'virtual void on' + cbName[2:] + '(dict data, dict error, int id, bool last) {};\n'
elif 'OnRsp' in cbName:
on_line = 'virtual void on' + cbName[2:] + '(dict data, dict error, int id, bool last) {};\n'
elif 'OnRtn' in cbName:
on_line = 'virtual void on' + cbName[2:] + '(dict data) {};\n'
elif 'OnErrRtn' in cbName:
on_line = 'virtual void on' + cbName[2:] + '(dict data, dict error) {};\n'
else:
on_line = ''
fheaderon.write(on_line)
fheaderon.write('\n')
# 生成封装部分
createWrap(cbName)
#----------------------------------------------------------------------
def createWrap(cbName):
"""在Python封装段代码中进行处理"""
# 生成.h文件中的on部分
if 'OnRspError' in cbName:
on_line = 'virtual void on' + cbName[2:] + '(dict error)\n'
override_line = '("on' + cbName[2:] + '")(error);\n'
elif 'OnRsp' in cbName:
on_line = 'virtual void on' + cbName[2:] + '(dict data, dict error, int id, bool last)\n'
override_line = '("on' + cbName[2:] + '")(data, error, id, last);\n'
elif 'OnRtn' in cbName:
on_line = 'virtual void on' + cbName[2:] + '(dict data)\n'
override_line = '("on' + cbName[2:] + '")(data);\n'
elif 'OnErrRtn' in cbName:
on_line = 'virtual void on' + cbName[2:] + '(dict data, dict error)\n'
override_line = '("on' + cbName[2:] + '")(data, error);\n'
else:
on_line = ''
if on_line is not '':
fwrap.write(on_line)
fwrap.write('{\n')
fwrap.write('\ttry\n')
fwrap.write('\t{\n')
fwrap.write('\t\tthis->get_override'+override_line)
fwrap.write('\t}\n')
fwrap.write('\tcatch (error_already_set const &)\n')
fwrap.write('\t{\n')
fwrap.write('\t\tPyErr_Print();\n')
fwrap.write('\t}\n')
fwrap.write('};\n')
fwrap.write('\n')
def createTask(cbName, cbArgsTypeList, cbArgsValueList, orignalLine):
# 从回调函数生成任务对象,并放入队列
funcline = orignalLine.replace(' virtual void ', 'void ' + apiName + '::')
funcline = funcline.replace('{};', '')
funcline = funcline.replace(' {}', '')
ftask.write(funcline)
ftask.write('{\n')
ftask.write("\tTask task = Task();\n")
ftask.write("\ttask.task_name = " + cbName.upper() + ";\n")
# define常量
global define_count
fdefine.write("#define " + cbName.upper() + ' ' + str(define_count) + '\n')
define_count = define_count + 1
# switch段代码
fswitch.write("case " + cbName.upper() + ':\n')
fswitch.write("{\n")
fswitch.write("\tthis->" + cbName.replace('On', 'process') + '(task);\n')
fswitch.write("\tbreak;\n")
fswitch.write("}\n")
fswitch.write("\n")
for i, type_ in enumerate(cbArgsTypeList):
if type_ == 'int':
ftask.write("\ttask.task_id = " + cbArgsValueList[i] + ";\n")
elif type_ == 'bool':
ftask.write("\ttask.task_last = " + cbArgsValueList[i] + ";\n")
elif 'CSgitFtdcRspInfoField' in type_:
ftask.write("\n")
ftask.write("\tif (pRspInfo)\n")
ftask.write("\t{\n")
ftask.write("\t\ttask.task_error = " + cbArgsValueList[i] + ";\n")
ftask.write("\t}\n")
ftask.write("\telse\n")
ftask.write("\t{\n")
ftask.write("\t\tCSgitFtdcRspInfoField empty_error = CSgitFtdcRspInfoField();\n")
ftask.write("\t\tmemset(&empty_error, 0, sizeof(empty_error));\n")
ftask.write("\t\ttask.task_error = empty_error;\n")
ftask.write("\t}\n")
else:
ftask.write("\n")
ftask.write("\tif (" + cbArgsValueList[i][1:] + ")\n")
ftask.write("\t{\n")
ftask.write("\t\ttask.task_data = " + cbArgsValueList[i] + ";\n")
ftask.write("\t}\n")
ftask.write("\telse\n")
ftask.write("\t{\n")
ftask.write("\t\t" + type_ + " empty_data = " + type_ + "();\n")
ftask.write("\t\tmemset(&empty_data, 0, sizeof(empty_data));\n")
ftask.write("\t\ttask.task_data = empty_data;\n")
ftask.write("\t}\n")
ftask.write("\tthis->task_queue.push(task);\n")
ftask.write("};\n")
ftask.write("\n")
def createProcess(cbName, cbArgsTypeList, cbArgsValueList):
# 从队列中提取任务并转化为python字典
fprocess.write("void " + apiName + '::' + cbName.replace('On', 'process') + '(Task task)' + "\n")
fprocess.write("{\n")
fprocess.write("\tPyLock lock;\n")
onArgsList = []
for i, type_ in enumerate(cbArgsTypeList):
if 'CSgitFtdcRspInfoField' in type_:
fprocess.write("\t"+ type_ + ' task_error = any_cast<' + type_ + '>(task.task_error);\n')
fprocess.write("\t"+ "dict error;\n")
struct = structDict[type_]
for key in struct.keys():
fprocess.write("\t"+ 'error["' + key + '"] = task_error.' + key + ';\n')
fprocess.write("\n")
onArgsList.append('error')
elif type_ in structDict:
fprocess.write("\t"+ type_ + ' task_data = any_cast<' + type_ + '>(task.task_data);\n')
fprocess.write("\t"+ "dict data;\n")
struct = structDict[type_]
for key in struct.keys():
fprocess.write("\t"+ 'data["' + key + '"] = task_data.' + key + ';\n')
fprocess.write("\n")
onArgsList.append('data')
elif type_ == 'bool':
onArgsList.append('task.task_last')
elif type_ == 'int':
onArgsList.append('task.task_id')
onArgs = join(onArgsList, ', ')
fprocess.write('\tthis->' + cbName.replace('On', 'on') + '(' + onArgs +');\n')
fprocess.write("};\n")
fprocess.write("\n")
def processFunction(line):
line = line.replace(' virtual int ', '') # 删除行首的无效内容
line = line.replace(') = 0;\n', '') # 删除行尾的无效内容
content = line.split('(')
fcName = content[0] # 回调函数名称
fcArgs = content[1] # 回调函数参数
fcArgs = fcArgs.replace(')', '')
fcArgsList = fcArgs.split(',') # 将每个参数转化为列表
fcArgsTypeList = []
fcArgsValueList = []
for arg in fcArgsList: # 开始处理参数
content = arg.split(' ')
if len(content) >= 2:
fcArgsTypeList.append(content[0]) # 参数类型列表
fcArgsValueList.append(content[1]) # 参数数据列表
print line
print fcArgs
print fcArgsList
print fcArgsTypeList
if len(fcArgsTypeList)>0 and fcArgsTypeList[0] in structDict:
createFunction(fcName, fcArgsTypeList, fcArgsValueList)
# 生成.h文件中的主动函数部分
if 'Req' in fcName:
req_line = 'int req' + fcName[3:] + '(dict req, int nRequestID);\n'
fheaderfunction.write(req_line)
fheaderfunction.write('\n')
def createFunction(fcName, fcArgsTypeList, fcArgsValueList):
type_ = fcArgsTypeList[0]
struct = structDict[type_]
ffunction.write('int ' + apiName + '::req' + fcName[3:] + '(dict req, int nRequestID)\n')
ffunction.write('{\n')
ffunction.write('\t' + type_ +' myreq = ' + type_ + '();\n')
ffunction.write('\tmemset(&myreq, 0, sizeof(myreq));\n')
for key, value in struct.items():
if value == 'string':
line = '\tgetString(req, "' + key + '", myreq.' + key + ');\n'
elif value == 'char':
line = '\tgetChar(req, "' + key + '", &myreq.' + key + ');\n'
elif value == 'int':
line = '\tgetInt(req, "' + key + '", &myreq.' + key + ');\n'
elif value == 'long':
line = '\tgetLong(req, "' + key + '", &myreq.' + key + ');\n'
elif value == 'short':
line = '\tgetShort(req, "' + key + '", &myreq.' + key + ');\n'
elif value == 'float':
line = '\tgetDouble(req, "' + key + '", &myreq.' + key + ');\n'
ffunction.write(line)
ffunction.write('\tint i = this->api->' + fcName + '(&myreq, nRequestID);\n')
ffunction.write('\treturn i;\n')
ffunction.write('};\n')
ffunction.write('\n')
#########################################################
apiName = 'TdApi'
fcpp = open('SgitFtdcTraderApi.h', 'r')
ftask = open('sgit_td_task.cpp', 'w')
fprocess = open('sgit_td_process.cpp', 'w')
ffunction = open('sgit_td_function.cpp', 'w')
fdefine = open('sgit_td_define.cpp', 'w')
fswitch = open('sgit_td_switch.cpp', 'w')
fheaderprocess = open('sgit_td_header_process.h', 'w')
fheaderon = open('sgit_td_header_on.h', 'w')
fheaderfunction = open('sgit_td_header_function.h', 'w')
fwrap = open('sgit_td_wrap.cpp', 'w')
define_count = 1
for line in fcpp:
if " virtual void On" in line:
print 'callback'
processCallBack(line)
elif " virtual int" in line:
print 'function'
processFunction(line)
fcpp.close()
ftask.close()
fprocess.close()
ffunction.close()
fswitch.close()
fdefine.close()
fheaderprocess.close()
fheaderon.close()
fheaderfunction.close()
fwrap.close()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
#define ONFRONTCONNECTED 1
#define ONFRONTDISCONNECTED 2
#define ONRSPUSERLOGIN 3
#define ONRSPUSERLOGOUT 4
#define ONRTNDEPTHMARKETDATA 5

View File

@ -0,0 +1,37 @@
int MdApi::reqQuot(dict req, int nRequestID)
{
CSgitSubQuotField myreq = CSgitSubQuotField();
memset(&myreq, 0, sizeof(myreq));
getString(req, "ContractID", myreq.ContractID);
int i = this->api->SubQuot(&myreq, nRequestID);
return i;
};
int MdApi::reqUserLogin(dict req, int nRequestID)
{
CSgitFtdcReqUserLoginField myreq = CSgitFtdcReqUserLoginField();
memset(&myreq, 0, sizeof(myreq));
getString(req, "MacAddress", myreq.MacAddress);
getString(req, "UserProductInfo", myreq.UserProductInfo);
getString(req, "UserID", myreq.UserID);
getString(req, "TradingDay", myreq.TradingDay);
getString(req, "InterfaceProductInfo", myreq.InterfaceProductInfo);
getString(req, "BrokerID", myreq.BrokerID);
getString(req, "ClientIPAddress", myreq.ClientIPAddress);
getString(req, "OneTimePassword", myreq.OneTimePassword);
getString(req, "ProtocolInfo", myreq.ProtocolInfo);
getString(req, "Password", myreq.Password);
int i = this->api->ReqUserLogin(&myreq, nRequestID);
return i;
};
int MdApi::reqUserLogout(dict req, int nRequestID)
{
CSgitFtdcUserLogoutField myreq = CSgitFtdcUserLogoutField();
memset(&myreq, 0, sizeof(myreq));
getString(req, "UserID", myreq.UserID);
getString(req, "BrokerID", myreq.BrokerID);
int i = this->api->ReqUserLogout(&myreq, nRequestID);
return i;
};

View File

@ -0,0 +1,4 @@
int reqUserLogin(dict req, int nRequestID);
int reqUserLogout(dict req, int nRequestID);

View File

@ -0,0 +1,8 @@
virtual void onRspUserLogin(dict data, dict error, int id, bool last) {};
virtual void onRspUserLogout(dict data, dict error, int id, bool last) {};
virtual void onRtnDepthMarketData(dict data) {};

View File

@ -0,0 +1,10 @@
void processFrontConnected(Task task);
void processFrontDisconnected(Task task);
void processRspUserLogin(Task task);
void processRspUserLogout(Task task);
void processRtnDepthMarketData(Task task);

View File

@ -0,0 +1,106 @@
void MdApi::processFrontConnected(Task task)
{
PyLock lock;
this->onFrontConnected();
};
void MdApi::processFrontDisconnected(Task task)
{
PyLock lock;
this->onFrontDisconnected();
};
void MdApi::processRspUserLogin(Task task)
{
PyLock lock;
CSgitFtdcRspUserLoginField task_data = any_cast<CSgitFtdcRspUserLoginField>(task.task_data);
dict data;
data["CZCETime"] = task_data.CZCETime;
data["SHFETime"] = task_data.SHFETime;
data["MaxOrderRef"] = task_data.MaxOrderRef;
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;
CSgitFtdcRspInfoField task_error = any_cast<CSgitFtdcRspInfoField>(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;
CSgitFtdcUserLogoutField task_data = any_cast<CSgitFtdcUserLogoutField>(task.task_data);
dict data;
data["UserID"] = task_data.UserID;
data["BrokerID"] = task_data.BrokerID;
CSgitFtdcRspInfoField task_error = any_cast<CSgitFtdcRspInfoField>(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::processRtnDepthMarketData(Task task)
{
PyLock lock;
CSgitFtdcDepthMarketDataField task_data = any_cast<CSgitFtdcDepthMarketDataField>(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;
this->onRtnDepthMarketData(data);
};

View File

@ -0,0 +1,30 @@
case ONFRONTCONNECTED:
{
this->processFrontConnected(task);
break;
}
case ONFRONTDISCONNECTED:
{
this->processFrontDisconnected(task);
break;
}
case ONRSPUSERLOGIN:
{
this->processRspUserLogin(task);
break;
}
case ONRSPUSERLOGOUT:
{
this->processRspUserLogout(task);
break;
}
case ONRTNDEPTHMARKETDATA:
{
this->processRtnDepthMarketData(task);
break;
}

View File

@ -0,0 +1,107 @@
void MdApi::OnFrontConnected()
{
Task task = Task();
task.task_name = ONFRONTCONNECTED;
this->task_queue.push(task);
};
void MdApi::OnFrontDisconnected(char *pErrMsg)
{
Task task = Task();
task.task_name = ONFRONTDISCONNECTED;
if (pErrMsg{};
)
{
task.task_data = *pErrMsg{};
;
}
else
{
char empty_data = char();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
this->task_queue.push(task);
};
void MdApi::OnRspUserLogin(CSgitFtdcRspUserLoginField *pRspUserLogin, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPUSERLOGIN;
if (pRspUserLogin)
{
task.task_data = *pRspUserLogin;
}
else
{
CSgitFtdcRspUserLoginField empty_data = CSgitFtdcRspUserLoginField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CSgitFtdcRspInfoField empty_error = CSgitFtdcRspInfoField();
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(CSgitFtdcUserLogoutField *pUserLogout, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPUSERLOGOUT;
if (pUserLogout)
{
task.task_data = *pUserLogout;
}
else
{
CSgitFtdcUserLogoutField empty_data = CSgitFtdcUserLogoutField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CSgitFtdcRspInfoField empty_error = CSgitFtdcRspInfoField();
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(CSgitFtdcDepthMarketDataField *pDepthMarketData)
{
Task task = Task();
task.task_name = ONRTNDEPTHMARKETDATA;
if (pDepthMarketData)
{
task.task_data = *pDepthMarketData;
}
else
{
CSgitFtdcDepthMarketDataField empty_data = CSgitFtdcDepthMarketDataField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
this->task_queue.push(task);
};

View File

@ -0,0 +1,36 @@
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 onRtnDepthMarketData(dict data)
{
try
{
this->get_override("onRtnDepthMarketData")(data);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,16 @@
#define ONFRONTCONNECTED 1
#define ONFRONTDISCONNECTED 2
#define ONRSPUSERLOGIN 3
#define ONRSPUSERLOGOUT 4
#define ONRSPUSERPASSWORDUPDATE 5
#define ONRSPORDERINSERT 6
#define ONRSPORDERACTION 7
#define ONRSPQRYORDER 8
#define ONRSPQRYTRADINGACCOUNT 9
#define ONRSPQRYINVESTOR 10
#define ONRSPQRYINSTRUMENT 11
#define ONRTNORDER 12
#define ONRTNTRADE 13
#define ONRTNINSTRUMENTSTATUS 14
#define ONRSPQRYINVESTORPOSITIONDETAIL 15
#define ONRSPQRYINVESTORPOSITION 16

View File

@ -0,0 +1,161 @@
int TdApi::reqUserLogin(dict req, int nRequestID)
{
CSgitFtdcReqUserLoginField myreq = CSgitFtdcReqUserLoginField();
memset(&myreq, 0, sizeof(myreq));
getString(req, "MacAddress", myreq.MacAddress);
getString(req, "UserProductInfo", myreq.UserProductInfo);
getString(req, "UserID", myreq.UserID);
getString(req, "TradingDay", myreq.TradingDay);
getString(req, "InterfaceProductInfo", myreq.InterfaceProductInfo);
getString(req, "BrokerID", myreq.BrokerID);
getString(req, "ClientIPAddress", myreq.ClientIPAddress);
getString(req, "OneTimePassword", myreq.OneTimePassword);
getString(req, "ProtocolInfo", myreq.ProtocolInfo);
getString(req, "Password", myreq.Password);
int i = this->api->ReqUserLogin(&myreq, nRequestID);
return i;
};
int TdApi::reqUserLogout(dict req, int nRequestID)
{
CSgitFtdcUserLogoutField myreq = CSgitFtdcUserLogoutField();
memset(&myreq, 0, sizeof(myreq));
getString(req, "UserID", myreq.UserID);
getString(req, "BrokerID", myreq.BrokerID);
int i = this->api->ReqUserLogout(&myreq, nRequestID);
return i;
};
int TdApi::reqUserPasswordUpdate(dict req, int nRequestID)
{
CSgitFtdcUserPasswordUpdateField myreq = CSgitFtdcUserPasswordUpdateField();
memset(&myreq, 0, sizeof(myreq));
getString(req, "UserID", myreq.UserID);
getString(req, "NewPassword", myreq.NewPassword);
getString(req, "OldPassword", myreq.OldPassword);
getString(req, "BrokerID", myreq.BrokerID);
int i = this->api->ReqUserPasswordUpdate(&myreq, nRequestID);
return i;
};
int TdApi::reqOrderInsert(dict req, int nRequestID)
{
CSgitFtdcInputOrderField myreq = CSgitFtdcInputOrderField();
memset(&myreq, 0, sizeof(myreq));
getChar(req, "ContingentCondition", &myreq.ContingentCondition);
getString(req, "CombOffsetFlag", myreq.CombOffsetFlag);
getString(req, "UserID", myreq.UserID);
getDouble(req, "LimitPrice", &myreq.LimitPrice);
getInt(req, "UserForceClose", &myreq.UserForceClose);
getChar(req, "Direction", &myreq.Direction);
getInt(req, "VolumeTotalOriginal", &myreq.VolumeTotalOriginal);
getChar(req, "OrderPriceType", &myreq.OrderPriceType);
getChar(req, "TimeCondition", &myreq.TimeCondition);
getInt(req, "IsAutoSuspend", &myreq.IsAutoSuspend);
getDouble(req, "StopPrice", &myreq.StopPrice);
getString(req, "InstrumentID", myreq.InstrumentID);
getInt(req, "MinVolume", &myreq.MinVolume);
getChar(req, "ForceCloseReason", &myreq.ForceCloseReason);
getString(req, "BrokerID", myreq.BrokerID);
getString(req, "CombHedgeFlag", myreq.CombHedgeFlag);
getString(req, "GTDDate", myreq.GTDDate);
getString(req, "BusinessUnit", myreq.BusinessUnit);
getString(req, "OrderRef", myreq.OrderRef);
getString(req, "InvestorID", myreq.InvestorID);
getChar(req, "VolumeCondition", &myreq.VolumeCondition);
getInt(req, "RequestID", &myreq.RequestID);
int i = this->api->ReqOrderInsert(&myreq, nRequestID);
return i;
};
int TdApi::reqOrderAction(dict req, int nRequestID)
{
CSgitFtdcInputOrderActionField myreq = CSgitFtdcInputOrderActionField();
memset(&myreq, 0, sizeof(myreq));
getString(req, "InstrumentID", myreq.InstrumentID);
getString(req, "ExchangeID", myreq.ExchangeID);
getChar(req, "ActionFlag", &myreq.ActionFlag);
getInt(req, "OrderActionRef", &myreq.OrderActionRef);
getString(req, "UserID", myreq.UserID);
getDouble(req, "LimitPrice", &myreq.LimitPrice);
getString(req, "OrderRef", myreq.OrderRef);
getString(req, "InvestorID", myreq.InvestorID);
getInt(req, "SessionID", &myreq.SessionID);
getInt(req, "VolumeChange", &myreq.VolumeChange);
getString(req, "BrokerID", myreq.BrokerID);
getInt(req, "RequestID", &myreq.RequestID);
getString(req, "OrderSysID", myreq.OrderSysID);
getInt(req, "FrontID", &myreq.FrontID);
int i = this->api->ReqOrderAction(&myreq, nRequestID);
return i;
};
int TdApi::reqQryOrder(dict req, int nRequestID)
{
CSgitFtdcQryOrderField myreq = CSgitFtdcQryOrderField();
memset(&myreq, 0, sizeof(myreq));
getString(req, "InstrumentID", myreq.InstrumentID);
getString(req, "ExchangeID", myreq.ExchangeID);
getString(req, "InsertTimeStart", myreq.InsertTimeStart);
getString(req, "InvestorID", myreq.InvestorID);
getString(req, "BrokerID", myreq.BrokerID);
getString(req, "OrderSysID", myreq.OrderSysID);
getString(req, "InsertTimeEnd", myreq.InsertTimeEnd);
int i = this->api->ReqQryOrder(&myreq, nRequestID);
return i;
};
int TdApi::reqQryTradingAccount(dict req, int nRequestID)
{
CSgitFtdcQryTradingAccountField myreq = CSgitFtdcQryTradingAccountField();
memset(&myreq, 0, sizeof(myreq));
getString(req, "InvestorID", myreq.InvestorID);
getString(req, "BrokerID", myreq.BrokerID);
int i = this->api->ReqQryTradingAccount(&myreq, nRequestID);
return i;
};
int TdApi::reqQryInvestor(dict req, int nRequestID)
{
CSgitFtdcQryInvestorField myreq = CSgitFtdcQryInvestorField();
memset(&myreq, 0, sizeof(myreq));
getString(req, "InvestorID", myreq.InvestorID);
getString(req, "BrokerID", myreq.BrokerID);
int i = this->api->ReqQryInvestor(&myreq, nRequestID);
return i;
};
int TdApi::reqQryInstrument(dict req, int nRequestID)
{
CSgitFtdcQryInstrumentField myreq = CSgitFtdcQryInstrumentField();
memset(&myreq, 0, sizeof(myreq));
getString(req, "InstrumentID", myreq.InstrumentID);
getString(req, "ExchangeID", myreq.ExchangeID);
getString(req, "ExchangeInstID", myreq.ExchangeInstID);
getString(req, "ProductID", myreq.ProductID);
int i = this->api->ReqQryInstrument(&myreq, nRequestID);
return i;
};
int TdApi::reqQryInvestorPositionDetail(dict req, int nRequestID)
{
CSgitFtdcQryInvestorPositionDetailField myreq = CSgitFtdcQryInvestorPositionDetailField();
memset(&myreq, 0, sizeof(myreq));
getString(req, "InstrumentID", myreq.InstrumentID);
getString(req, "InvestorID", myreq.InvestorID);
getString(req, "BrokerID", myreq.BrokerID);
int i = this->api->ReqQryInvestorPositionDetail(&myreq, nRequestID);
return i;
};
int TdApi::reqQryInvestorPosition(dict req, int nRequestID)
{
CSgitFtdcQryInvestorPositionField myreq = CSgitFtdcQryInvestorPositionField();
memset(&myreq, 0, sizeof(myreq));
getString(req, "InstrumentID", myreq.InstrumentID);
getString(req, "InvestorID", myreq.InvestorID);
getString(req, "BrokerID", myreq.BrokerID);
int i = this->api->ReqQryInvestorPosition(&myreq, nRequestID);
return i;
};

View File

@ -0,0 +1,24 @@
int reqUserLogin(dict req, int nRequestID);
int reqUserLogout(dict req, int nRequestID);
int reqUserPasswordUpdate(dict req, int nRequestID);
int reqOrderInsert(dict req, int nRequestID);
int reqOrderAction(dict req, int nRequestID);
int reqQryOrder(dict req, int nRequestID);
int reqQryTradingAccount(dict req, int nRequestID);
int reqQryInvestor(dict req, int nRequestID);
int reqQryInstrument(dict req, int nRequestID);
int reqQryInvestorPositionDetail(dict req, int nRequestID);
int reqQryInvestorPosition(dict req, int nRequestID);
int reqMBLQuot(dict req, int nRequestID);

View File

@ -0,0 +1,30 @@
virtual void onRspUserLogin(dict data, dict error, int id, bool last) {};
virtual void onRspUserLogout(dict data, dict error, int id, bool last) {};
virtual void onRspUserPasswordUpdate(dict data, dict error, int id, bool last) {};
virtual void onRspOrderInsert(dict data, dict error, int id, bool last) {};
virtual void onRspOrderAction(dict data, dict error, int id, bool last) {};
virtual void onRspQryOrder(dict data, dict error, int id, bool last) {};
virtual void onRspQryTradingAccount(dict data, dict error, int id, bool last) {};
virtual void onRspQryInvestor(dict data, dict error, int id, bool last) {};
virtual void onRspQryInstrument(dict data, dict error, int id, bool last) {};
virtual void onRtnOrder(dict data) {};
virtual void onRtnTrade(dict data) {};
virtual void onRtnInstrumentStatus(dict data) {};
virtual void onRspQryInvestorPositionDetail(dict data, dict error, int id, bool last) {};
virtual void onRspQryInvestorPosition(dict data, dict error, int id, bool last) {};

View File

@ -0,0 +1,32 @@
void processFrontConnected(Task task);
void processFrontDisconnected(Task task);
void processRspUserLogin(Task task);
void processRspUserLogout(Task task);
void processRspUserPasswordUpdate(Task task);
void processRspOrderInsert(Task task);
void processRspOrderAction(Task task);
void processRspQryOrder(Task task);
void processRspQryTradingAccount(Task task);
void processRspQryInvestor(Task task);
void processRspQryInstrument(Task task);
void processRtnOrder(Task task);
void processRtnTrade(Task task);
void processRtnInstrumentStatus(Task task);
void processRspQryInvestorPositionDetail(Task task);
void processRspQryInvestorPosition(Task task);

View File

@ -0,0 +1,528 @@
void TdApi::processFrontConnected(Task task)
{
PyLock lock;
this->onFrontConnected();
};
void TdApi::processFrontDisconnected(Task task)
{
PyLock lock;
this->onFrontDisconnected();
};
void TdApi::processRspUserLogin(Task task)
{
PyLock lock;
CSgitFtdcRspUserLoginField task_data = any_cast<CSgitFtdcRspUserLoginField>(task.task_data);
dict data;
data["CZCETime"] = task_data.CZCETime;
data["SHFETime"] = task_data.SHFETime;
data["MaxOrderRef"] = task_data.MaxOrderRef;
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;
CSgitFtdcRspInfoField task_error = any_cast<CSgitFtdcRspInfoField>(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 TdApi::processRspUserLogout(Task task)
{
PyLock lock;
CSgitFtdcUserLogoutField task_data = any_cast<CSgitFtdcUserLogoutField>(task.task_data);
dict data;
data["UserID"] = task_data.UserID;
data["BrokerID"] = task_data.BrokerID;
CSgitFtdcRspInfoField task_error = any_cast<CSgitFtdcRspInfoField>(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 TdApi::processRspUserPasswordUpdate(Task task)
{
PyLock lock;
CSgitFtdcUserPasswordUpdateField task_data = any_cast<CSgitFtdcUserPasswordUpdateField>(task.task_data);
dict data;
data["UserID"] = task_data.UserID;
data["NewPassword"] = task_data.NewPassword;
data["OldPassword"] = task_data.OldPassword;
data["BrokerID"] = task_data.BrokerID;
CSgitFtdcRspInfoField task_error = any_cast<CSgitFtdcRspInfoField>(task.task_error);
dict error;
error["ErrorMsg"] = task_error.ErrorMsg;
error["ErrorID"] = task_error.ErrorID;
this->onRspUserPasswordUpdate(data, error, task.task_id, task.task_last);
};
void TdApi::processRspOrderInsert(Task task)
{
PyLock lock;
CSgitFtdcInputOrderField task_data = any_cast<CSgitFtdcInputOrderField>(task.task_data);
dict data;
data["ContingentCondition"] = task_data.ContingentCondition;
data["CombOffsetFlag"] = task_data.CombOffsetFlag;
data["UserID"] = task_data.UserID;
data["LimitPrice"] = task_data.LimitPrice;
data["UserForceClose"] = task_data.UserForceClose;
data["Direction"] = task_data.Direction;
data["VolumeTotalOriginal"] = task_data.VolumeTotalOriginal;
data["OrderPriceType"] = task_data.OrderPriceType;
data["TimeCondition"] = task_data.TimeCondition;
data["IsAutoSuspend"] = task_data.IsAutoSuspend;
data["StopPrice"] = task_data.StopPrice;
data["InstrumentID"] = task_data.InstrumentID;
data["MinVolume"] = task_data.MinVolume;
data["ForceCloseReason"] = task_data.ForceCloseReason;
data["BrokerID"] = task_data.BrokerID;
data["CombHedgeFlag"] = task_data.CombHedgeFlag;
data["GTDDate"] = task_data.GTDDate;
data["BusinessUnit"] = task_data.BusinessUnit;
data["OrderRef"] = task_data.OrderRef;
data["InvestorID"] = task_data.InvestorID;
data["VolumeCondition"] = task_data.VolumeCondition;
data["RequestID"] = task_data.RequestID;
CSgitFtdcRspInfoField task_error = any_cast<CSgitFtdcRspInfoField>(task.task_error);
dict error;
error["ErrorMsg"] = task_error.ErrorMsg;
error["ErrorID"] = task_error.ErrorID;
this->onRspOrderInsert(data, error, task.task_id, task.task_last);
};
void TdApi::processRspOrderAction(Task task)
{
PyLock lock;
CSgitFtdcInputOrderActionField task_data = any_cast<CSgitFtdcInputOrderActionField>(task.task_data);
dict data;
data["InstrumentID"] = task_data.InstrumentID;
data["ExchangeID"] = task_data.ExchangeID;
data["ActionFlag"] = task_data.ActionFlag;
data["OrderActionRef"] = task_data.OrderActionRef;
data["UserID"] = task_data.UserID;
data["LimitPrice"] = task_data.LimitPrice;
data["OrderRef"] = task_data.OrderRef;
data["InvestorID"] = task_data.InvestorID;
data["SessionID"] = task_data.SessionID;
data["VolumeChange"] = task_data.VolumeChange;
data["BrokerID"] = task_data.BrokerID;
data["RequestID"] = task_data.RequestID;
data["OrderSysID"] = task_data.OrderSysID;
data["FrontID"] = task_data.FrontID;
CSgitFtdcRspInfoField task_error = any_cast<CSgitFtdcRspInfoField>(task.task_error);
dict error;
error["ErrorMsg"] = task_error.ErrorMsg;
error["ErrorID"] = task_error.ErrorID;
this->onRspOrderAction(data, error, task.task_id, task.task_last);
};
void TdApi::processRspQryOrder(Task task)
{
PyLock lock;
CSgitFtdcOrderField task_data = any_cast<CSgitFtdcOrderField>(task.task_data);
dict data;
data["ContingentCondition"] = task_data.ContingentCondition;
data["NotifySequence"] = task_data.NotifySequence;
data["ActiveUserID"] = task_data.ActiveUserID;
data["VolumeTraded"] = task_data.VolumeTraded;
data["UserProductInfo"] = task_data.UserProductInfo;
data["CombOffsetFlag"] = task_data.CombOffsetFlag;
data["TraderID"] = task_data.TraderID;
data["UserID"] = task_data.UserID;
data["LimitPrice"] = task_data.LimitPrice;
data["UserForceClose"] = task_data.UserForceClose;
data["RelativeOrderSysID"] = task_data.RelativeOrderSysID;
data["Direction"] = task_data.Direction;
data["InstallID"] = task_data.InstallID;
data["ParticipantID"] = task_data.ParticipantID;
data["VolumeTotalOriginal"] = task_data.VolumeTotalOriginal;
data["ExchangeInstID"] = task_data.ExchangeInstID;
data["ClientID"] = task_data.ClientID;
data["VolumeTotal"] = task_data.VolumeTotal;
data["OrderPriceType"] = task_data.OrderPriceType;
data["SessionID"] = task_data.SessionID;
data["TimeCondition"] = task_data.TimeCondition;
data["OrderStatus"] = task_data.OrderStatus;
data["OrderSysID"] = task_data.OrderSysID;
data["OrderSubmitStatus"] = task_data.OrderSubmitStatus;
data["IsAutoSuspend"] = task_data.IsAutoSuspend;
data["StopPrice"] = task_data.StopPrice;
data["InstrumentID"] = task_data.InstrumentID;
data["ExchangeID"] = task_data.ExchangeID;
data["MinVolume"] = task_data.MinVolume;
data["StatusMsg"] = task_data.StatusMsg;
data["SettlementID"] = task_data.SettlementID;
data["ForceCloseReason"] = task_data.ForceCloseReason;
data["OrderType"] = task_data.OrderType;
data["UpdateTime"] = task_data.UpdateTime;
data["TradingDay"] = task_data.TradingDay;
data["ActiveTime"] = task_data.ActiveTime;
data["BrokerID"] = task_data.BrokerID;
data["InsertTime"] = task_data.InsertTime;
data["FrontID"] = task_data.FrontID;
data["SuspendTime"] = task_data.SuspendTime;
data["ClearingPartID"] = task_data.ClearingPartID;
data["CombHedgeFlag"] = task_data.CombHedgeFlag;
data["CancelTime"] = task_data.CancelTime;
data["GTDDate"] = task_data.GTDDate;
data["OrderLocalID"] = task_data.OrderLocalID;
data["BusinessUnit"] = task_data.BusinessUnit;
data["InsertDate"] = task_data.InsertDate;
data["SequenceNo"] = task_data.SequenceNo;
data["OrderRef"] = task_data.OrderRef;
data["BrokerOrderSeq"] = task_data.BrokerOrderSeq;
data["InvestorID"] = task_data.InvestorID;
data["VolumeCondition"] = task_data.VolumeCondition;
data["RequestID"] = task_data.RequestID;
data["OrderSource"] = task_data.OrderSource;
data["ActiveTraderID"] = task_data.ActiveTraderID;
CSgitFtdcRspInfoField task_error = any_cast<CSgitFtdcRspInfoField>(task.task_error);
dict error;
error["ErrorMsg"] = task_error.ErrorMsg;
error["ErrorID"] = task_error.ErrorID;
this->onRspQryOrder(data, error, task.task_id, task.task_last);
};
void TdApi::processRspQryTradingAccount(Task task)
{
PyLock lock;
CSgitFtdcTradingAccountField task_data = any_cast<CSgitFtdcTradingAccountField>(task.task_data);
dict data;
data["Mortgage"] = task_data.Mortgage;
data["ExchangeDeliveryMargin"] = task_data.ExchangeDeliveryMargin;
data["FrozenMargin"] = task_data.FrozenMargin;
data["WithdrawQuota"] = task_data.WithdrawQuota;
data["PositionProfit"] = task_data.PositionProfit;
data["Commission"] = task_data.Commission;
data["Interest"] = task_data.Interest;
data["CashIn"] = task_data.CashIn;
data["AccountID"] = task_data.AccountID;
data["Available"] = task_data.Available;
data["PreCredit"] = task_data.PreCredit;
data["PreMortgage"] = task_data.PreMortgage;
data["InterestBase"] = task_data.InterestBase;
data["ExchangeMargin"] = task_data.ExchangeMargin;
data["PreMargin"] = task_data.PreMargin;
data["SettlementID"] = task_data.SettlementID;
data["DeliveryMargin"] = task_data.DeliveryMargin;
data["TradingDay"] = task_data.TradingDay;
data["BrokerID"] = task_data.BrokerID;
data["FrozenCash"] = task_data.FrozenCash;
data["Withdraw"] = task_data.Withdraw;
data["Balance"] = task_data.Balance;
data["Reserve"] = task_data.Reserve;
data["PreDeposit"] = task_data.PreDeposit;
data["Credit"] = task_data.Credit;
data["PreBalance"] = task_data.PreBalance;
data["CurrMargin"] = task_data.CurrMargin;
data["FrozenCommission"] = task_data.FrozenCommission;
data["CloseProfit"] = task_data.CloseProfit;
data["Deposit"] = task_data.Deposit;
CSgitFtdcRspInfoField task_error = any_cast<CSgitFtdcRspInfoField>(task.task_error);
dict error;
error["ErrorMsg"] = task_error.ErrorMsg;
error["ErrorID"] = task_error.ErrorID;
this->onRspQryTradingAccount(data, error, task.task_id, task.task_last);
};
void TdApi::processRspQryInvestor(Task task)
{
PyLock lock;
CSgitFtdcInvestorField task_data = any_cast<CSgitFtdcInvestorField>(task.task_data);
dict data;
data["CommModelID"] = task_data.CommModelID;
data["InvestorName"] = task_data.InvestorName;
data["Mobile"] = task_data.Mobile;
data["IdentifiedCardNo"] = task_data.IdentifiedCardNo;
data["Telephone"] = task_data.Telephone;
data["InvestorID"] = task_data.InvestorID;
data["BrokerID"] = task_data.BrokerID;
data["Address"] = task_data.Address;
data["InvestorGroupID"] = task_data.InvestorGroupID;
data["OpenDate"] = task_data.OpenDate;
data["IsActive"] = task_data.IsActive;
data["IdentifiedCardType"] = task_data.IdentifiedCardType;
CSgitFtdcRspInfoField task_error = any_cast<CSgitFtdcRspInfoField>(task.task_error);
dict error;
error["ErrorMsg"] = task_error.ErrorMsg;
error["ErrorID"] = task_error.ErrorID;
this->onRspQryInvestor(data, error, task.task_id, task.task_last);
};
void TdApi::processRspQryInstrument(Task task)
{
PyLock lock;
CSgitFtdcInstrumentField task_data = any_cast<CSgitFtdcInstrumentField>(task.task_data);
dict data;
data["IsTrading"] = task_data.IsTrading;
data["ExpireDate"] = task_data.ExpireDate;
data["PositionDateType"] = task_data.PositionDateType;
data["LongMarginRatio"] = task_data.LongMarginRatio;
data["PositionType"] = task_data.PositionType;
data["ProductClass"] = task_data.ProductClass;
data["InstrumentName"] = task_data.InstrumentName;
data["ShortMarginRatio"] = task_data.ShortMarginRatio;
data["VolumeMultiple"] = task_data.VolumeMultiple;
data["DeliveryYear"] = task_data.DeliveryYear;
data["CreateDate"] = task_data.CreateDate;
data["InstrumentID"] = task_data.InstrumentID;
data["MaxLimitOrderVolume"] = task_data.MaxLimitOrderVolume;
data["ExchangeID"] = task_data.ExchangeID;
data["MinLimitOrderVolume"] = task_data.MinLimitOrderVolume;
data["MaxMarketOrderVolume"] = task_data.MaxMarketOrderVolume;
data["StartDelivDate"] = task_data.StartDelivDate;
data["DeliveryMonth"] = task_data.DeliveryMonth;
data["PriceTick"] = task_data.PriceTick;
data["InstLifePhase"] = task_data.InstLifePhase;
data["ExchangeInstID"] = task_data.ExchangeInstID;
data["MinMarketOrderVolume"] = task_data.MinMarketOrderVolume;
data["EndDelivDate"] = task_data.EndDelivDate;
data["OpenDate"] = task_data.OpenDate;
data["ProductID"] = task_data.ProductID;
CSgitFtdcRspInfoField task_error = any_cast<CSgitFtdcRspInfoField>(task.task_error);
dict error;
error["ErrorMsg"] = task_error.ErrorMsg;
error["ErrorID"] = task_error.ErrorID;
this->onRspQryInstrument(data, error, task.task_id, task.task_last);
};
void TdApi::processRtnOrder(Task task)
{
PyLock lock;
CSgitFtdcOrderField task_data = any_cast<CSgitFtdcOrderField>(task.task_data);
dict data;
data["ContingentCondition"] = task_data.ContingentCondition;
data["NotifySequence"] = task_data.NotifySequence;
data["ActiveUserID"] = task_data.ActiveUserID;
data["VolumeTraded"] = task_data.VolumeTraded;
data["UserProductInfo"] = task_data.UserProductInfo;
data["CombOffsetFlag"] = task_data.CombOffsetFlag;
data["TraderID"] = task_data.TraderID;
data["UserID"] = task_data.UserID;
data["LimitPrice"] = task_data.LimitPrice;
data["UserForceClose"] = task_data.UserForceClose;
data["RelativeOrderSysID"] = task_data.RelativeOrderSysID;
data["Direction"] = task_data.Direction;
data["InstallID"] = task_data.InstallID;
data["ParticipantID"] = task_data.ParticipantID;
data["VolumeTotalOriginal"] = task_data.VolumeTotalOriginal;
data["ExchangeInstID"] = task_data.ExchangeInstID;
data["ClientID"] = task_data.ClientID;
data["VolumeTotal"] = task_data.VolumeTotal;
data["OrderPriceType"] = task_data.OrderPriceType;
data["SessionID"] = task_data.SessionID;
data["TimeCondition"] = task_data.TimeCondition;
data["OrderStatus"] = task_data.OrderStatus;
data["OrderSysID"] = task_data.OrderSysID;
data["OrderSubmitStatus"] = task_data.OrderSubmitStatus;
data["IsAutoSuspend"] = task_data.IsAutoSuspend;
data["StopPrice"] = task_data.StopPrice;
data["InstrumentID"] = task_data.InstrumentID;
data["ExchangeID"] = task_data.ExchangeID;
data["MinVolume"] = task_data.MinVolume;
data["StatusMsg"] = task_data.StatusMsg;
data["SettlementID"] = task_data.SettlementID;
data["ForceCloseReason"] = task_data.ForceCloseReason;
data["OrderType"] = task_data.OrderType;
data["UpdateTime"] = task_data.UpdateTime;
data["TradingDay"] = task_data.TradingDay;
data["ActiveTime"] = task_data.ActiveTime;
data["BrokerID"] = task_data.BrokerID;
data["InsertTime"] = task_data.InsertTime;
data["FrontID"] = task_data.FrontID;
data["SuspendTime"] = task_data.SuspendTime;
data["ClearingPartID"] = task_data.ClearingPartID;
data["CombHedgeFlag"] = task_data.CombHedgeFlag;
data["CancelTime"] = task_data.CancelTime;
data["GTDDate"] = task_data.GTDDate;
data["OrderLocalID"] = task_data.OrderLocalID;
data["BusinessUnit"] = task_data.BusinessUnit;
data["InsertDate"] = task_data.InsertDate;
data["SequenceNo"] = task_data.SequenceNo;
data["OrderRef"] = task_data.OrderRef;
data["BrokerOrderSeq"] = task_data.BrokerOrderSeq;
data["InvestorID"] = task_data.InvestorID;
data["VolumeCondition"] = task_data.VolumeCondition;
data["RequestID"] = task_data.RequestID;
data["OrderSource"] = task_data.OrderSource;
data["ActiveTraderID"] = task_data.ActiveTraderID;
this->onRtnOrder(data);
};
void TdApi::processRtnTrade(Task task)
{
PyLock lock;
CSgitFtdcTradeField task_data = any_cast<CSgitFtdcTradeField>(task.task_data);
dict data;
data["TradeType"] = task_data.TradeType;
data["TraderID"] = task_data.TraderID;
data["HedgeFlag"] = task_data.HedgeFlag;
data["TradeTime"] = task_data.TradeTime;
data["Direction"] = task_data.Direction;
data["ParticipantID"] = task_data.ParticipantID;
data["Price"] = task_data.Price;
data["ClientID"] = task_data.ClientID;
data["Volume"] = task_data.Volume;
data["OrderSysID"] = task_data.OrderSysID;
data["ClearingPartID"] = task_data.ClearingPartID;
data["InstrumentID"] = task_data.InstrumentID;
data["ExchangeID"] = task_data.ExchangeID;
data["SettlementID"] = task_data.SettlementID;
data["UserID"] = task_data.UserID;
data["TradingDay"] = task_data.TradingDay;
data["BrokerID"] = task_data.BrokerID;
data["OffsetFlag"] = task_data.OffsetFlag;
data["OrderLocalID"] = task_data.OrderLocalID;
data["TradeID"] = task_data.TradeID;
data["TradeDate"] = task_data.TradeDate;
data["BusinessUnit"] = task_data.BusinessUnit;
data["SequenceNo"] = task_data.SequenceNo;
data["OrderRef"] = task_data.OrderRef;
data["BrokerOrderSeq"] = task_data.BrokerOrderSeq;
data["InvestorID"] = task_data.InvestorID;
data["ExchangeInstID"] = task_data.ExchangeInstID;
data["TradeSource"] = task_data.TradeSource;
data["PriceSource"] = task_data.PriceSource;
data["TradingRole"] = task_data.TradingRole;
this->onRtnTrade(data);
};
void TdApi::processRtnInstrumentStatus(Task task)
{
PyLock lock;
CSgitFtdcInstrumentStatusField task_data = any_cast<CSgitFtdcInstrumentStatusField>(task.task_data);
dict data;
data["InstrumentID"] = task_data.InstrumentID;
data["ExchangeID"] = task_data.ExchangeID;
data["EnterTime"] = task_data.EnterTime;
data["SettlementGroupID"] = task_data.SettlementGroupID;
data["TradingSegmentSN"] = task_data.TradingSegmentSN;
data["EnterReason"] = task_data.EnterReason;
data["InstrumentStatus"] = task_data.InstrumentStatus;
data["ExchangeInstID"] = task_data.ExchangeInstID;
this->onRtnInstrumentStatus(data);
};
void TdApi::processRspQryInvestorPositionDetail(Task task)
{
PyLock lock;
CSgitFtdcInvestorPositionDetailField task_data = any_cast<CSgitFtdcInvestorPositionDetailField>(task.task_data);
dict data;
data["PositionProfitByDate"] = task_data.PositionProfitByDate;
data["ExchMargin"] = task_data.ExchMargin;
data["TradeType"] = task_data.TradeType;
data["MarginRateByMoney"] = task_data.MarginRateByMoney;
data["HedgeFlag"] = task_data.HedgeFlag;
data["MarginRateByVolume"] = task_data.MarginRateByVolume;
data["Direction"] = task_data.Direction;
data["CloseAmount"] = task_data.CloseAmount;
data["OpenPrice"] = task_data.OpenPrice;
data["Volume"] = task_data.Volume;
data["LastSettlementPrice"] = task_data.LastSettlementPrice;
data["CloseVolume"] = task_data.CloseVolume;
data["InstrumentID"] = task_data.InstrumentID;
data["ExchangeID"] = task_data.ExchangeID;
data["CloseProfitByTrade"] = task_data.CloseProfitByTrade;
data["SettlementID"] = task_data.SettlementID;
data["TradingDay"] = task_data.TradingDay;
data["BrokerID"] = task_data.BrokerID;
data["Margin"] = task_data.Margin;
data["TradeID"] = task_data.TradeID;
data["PositionProfitByTrade"] = task_data.PositionProfitByTrade;
data["CloseProfitByDate"] = task_data.CloseProfitByDate;
data["SettlementPrice"] = task_data.SettlementPrice;
data["InvestorID"] = task_data.InvestorID;
data["CombInstrumentID"] = task_data.CombInstrumentID;
data["OpenDate"] = task_data.OpenDate;
CSgitFtdcRspInfoField task_error = any_cast<CSgitFtdcRspInfoField>(task.task_error);
dict error;
error["ErrorMsg"] = task_error.ErrorMsg;
error["ErrorID"] = task_error.ErrorID;
this->onRspQryInvestorPositionDetail(data, error, task.task_id, task.task_last);
};
void TdApi::processRspQryInvestorPosition(Task task)
{
PyLock lock;
CSgitFtdcInvestorPositionField task_data = any_cast<CSgitFtdcInvestorPositionField>(task.task_data);
dict data;
data["ShortFrozenAmount"] = task_data.ShortFrozenAmount;
data["FrozenMargin"] = task_data.FrozenMargin;
data["HedgeFlag"] = task_data.HedgeFlag;
data["PositionProfit"] = task_data.PositionProfit;
data["Commission"] = task_data.Commission;
data["MarginRateByVolume"] = task_data.MarginRateByVolume;
data["CombPosition"] = task_data.CombPosition;
data["CashIn"] = task_data.CashIn;
data["PreSettlementPrice"] = task_data.PreSettlementPrice;
data["CombLongFrozen"] = task_data.CombLongFrozen;
data["CloseAmount"] = task_data.CloseAmount;
data["PosiDirection"] = task_data.PosiDirection;
data["YdPosition"] = task_data.YdPosition;
data["MarginRateByMoney"] = task_data.MarginRateByMoney;
data["OpenVolume"] = task_data.OpenVolume;
data["CloseVolume"] = task_data.CloseVolume;
data["ExchangeMargin"] = task_data.ExchangeMargin;
data["InstrumentID"] = task_data.InstrumentID;
data["PositionDate"] = task_data.PositionDate;
data["CloseProfitByTrade"] = task_data.CloseProfitByTrade;
data["PreMargin"] = task_data.PreMargin;
data["SettlementID"] = task_data.SettlementID;
data["ShortFrozen"] = task_data.ShortFrozen;
data["LongFrozen"] = task_data.LongFrozen;
data["TodayPosition"] = task_data.TodayPosition;
data["TradingDay"] = task_data.TradingDay;
data["PositionCost"] = task_data.PositionCost;
data["BrokerID"] = task_data.BrokerID;
data["FrozenCash"] = task_data.FrozenCash;
data["OpenAmount"] = task_data.OpenAmount;
data["OpenCost"] = task_data.OpenCost;
data["Position"] = task_data.Position;
data["FrozenCommission"] = task_data.FrozenCommission;
data["CombShortFrozen"] = task_data.CombShortFrozen;
data["CloseProfitByDate"] = task_data.CloseProfitByDate;
data["SettlementPrice"] = task_data.SettlementPrice;
data["LongFrozenAmount"] = task_data.LongFrozenAmount;
data["InvestorID"] = task_data.InvestorID;
data["CloseProfit"] = task_data.CloseProfit;
data["UseMargin"] = task_data.UseMargin;
CSgitFtdcRspInfoField task_error = any_cast<CSgitFtdcRspInfoField>(task.task_error);
dict error;
error["ErrorMsg"] = task_error.ErrorMsg;
error["ErrorID"] = task_error.ErrorID;
this->onRspQryInvestorPosition(data, error, task.task_id, task.task_last);
};

View File

@ -0,0 +1,96 @@
case ONFRONTCONNECTED:
{
this->processFrontConnected(task);
break;
}
case ONFRONTDISCONNECTED:
{
this->processFrontDisconnected(task);
break;
}
case ONRSPUSERLOGIN:
{
this->processRspUserLogin(task);
break;
}
case ONRSPUSERLOGOUT:
{
this->processRspUserLogout(task);
break;
}
case ONRSPUSERPASSWORDUPDATE:
{
this->processRspUserPasswordUpdate(task);
break;
}
case ONRSPORDERINSERT:
{
this->processRspOrderInsert(task);
break;
}
case ONRSPORDERACTION:
{
this->processRspOrderAction(task);
break;
}
case ONRSPQRYORDER:
{
this->processRspQryOrder(task);
break;
}
case ONRSPQRYTRADINGACCOUNT:
{
this->processRspQryTradingAccount(task);
break;
}
case ONRSPQRYINVESTOR:
{
this->processRspQryInvestor(task);
break;
}
case ONRSPQRYINSTRUMENT:
{
this->processRspQryInstrument(task);
break;
}
case ONRTNORDER:
{
this->processRtnOrder(task);
break;
}
case ONRTNTRADE:
{
this->processRtnTrade(task);
break;
}
case ONRTNINSTRUMENTSTATUS:
{
this->processRtnInstrumentStatus(task);
break;
}
case ONRSPQRYINVESTORPOSITIONDETAIL:
{
this->processRspQryInvestorPositionDetail(task);
break;
}
case ONRSPQRYINVESTORPOSITION:
{
this->processRspQryInvestorPosition(task);
break;
}

View File

@ -0,0 +1,420 @@
void TdApi::OnFrontConnected()
{
Task task = Task();
task.task_name = ONFRONTCONNECTED;
this->task_queue.push(task);
};
void TdApi::OnFrontDisconnected(char *pErrMsg)
{
Task task = Task();
task.task_name = ONFRONTDISCONNECTED;
if (pErrMsg)
{
task.task_data = *pErrMsg;
}
else
{
char empty_data = char();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
this->task_queue.push(task);
};
void TdApi::OnRspUserLogin(CSgitFtdcRspUserLoginField *pRspUserLogin, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPUSERLOGIN;
if (pRspUserLogin)
{
task.task_data = *pRspUserLogin;
}
else
{
CSgitFtdcRspUserLoginField empty_data = CSgitFtdcRspUserLoginField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CSgitFtdcRspInfoField empty_error = CSgitFtdcRspInfoField();
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 TdApi::OnRspUserLogout(CSgitFtdcUserLogoutField *pUserLogout, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPUSERLOGOUT;
if (pUserLogout)
{
task.task_data = *pUserLogout;
}
else
{
CSgitFtdcUserLogoutField empty_data = CSgitFtdcUserLogoutField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CSgitFtdcRspInfoField empty_error = CSgitFtdcRspInfoField();
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 TdApi::OnRspUserPasswordUpdate(CSgitFtdcUserPasswordUpdateField *pUserPasswordUpdate, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPUSERPASSWORDUPDATE;
if (pUserPasswordUpdate)
{
task.task_data = *pUserPasswordUpdate;
}
else
{
CSgitFtdcUserPasswordUpdateField empty_data = CSgitFtdcUserPasswordUpdateField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CSgitFtdcRspInfoField empty_error = CSgitFtdcRspInfoField();
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 TdApi::OnRspOrderInsert(CSgitFtdcInputOrderField *pInputOrder, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPORDERINSERT;
if (pInputOrder)
{
task.task_data = *pInputOrder;
}
else
{
CSgitFtdcInputOrderField empty_data = CSgitFtdcInputOrderField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CSgitFtdcRspInfoField empty_error = CSgitFtdcRspInfoField();
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 TdApi::OnRspOrderAction(CSgitFtdcInputOrderActionField *pInputOrderAction, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPORDERACTION;
if (pInputOrderAction)
{
task.task_data = *pInputOrderAction;
}
else
{
CSgitFtdcInputOrderActionField empty_data = CSgitFtdcInputOrderActionField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CSgitFtdcRspInfoField empty_error = CSgitFtdcRspInfoField();
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 TdApi::OnRspQryOrder(CSgitFtdcOrderField *pOrder, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPQRYORDER;
if (pOrder)
{
task.task_data = *pOrder;
}
else
{
CSgitFtdcOrderField empty_data = CSgitFtdcOrderField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CSgitFtdcRspInfoField empty_error = CSgitFtdcRspInfoField();
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 TdApi::OnRspQryTradingAccount(CSgitFtdcTradingAccountField *pTradingAccount, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPQRYTRADINGACCOUNT;
if (pTradingAccount)
{
task.task_data = *pTradingAccount;
}
else
{
CSgitFtdcTradingAccountField empty_data = CSgitFtdcTradingAccountField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CSgitFtdcRspInfoField empty_error = CSgitFtdcRspInfoField();
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 TdApi::OnRspQryInvestor(CSgitFtdcInvestorField *pInvestor, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPQRYINVESTOR;
if (pInvestor)
{
task.task_data = *pInvestor;
}
else
{
CSgitFtdcInvestorField empty_data = CSgitFtdcInvestorField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CSgitFtdcRspInfoField empty_error = CSgitFtdcRspInfoField();
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 TdApi::OnRspQryInstrument(CSgitFtdcInstrumentField *pInstrument, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPQRYINSTRUMENT;
if (pInstrument)
{
task.task_data = *pInstrument;
}
else
{
CSgitFtdcInstrumentField empty_data = CSgitFtdcInstrumentField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CSgitFtdcRspInfoField empty_error = CSgitFtdcRspInfoField();
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 TdApi::OnRtnOrder(CSgitFtdcOrderField *pOrder,CSgitFtdcRspInfoField *pRspInfo)
{
Task task = Task();
task.task_name = ONRTNORDER;
if (pOrder,CSgitFtdcRspInfoField)
{
task.task_data = *pOrder,CSgitFtdcRspInfoField;
}
else
{
CSgitFtdcOrderField empty_data = CSgitFtdcOrderField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
this->task_queue.push(task);
};
void TdApi::OnRtnTrade(CSgitFtdcTradeField *pTrade)
{
Task task = Task();
task.task_name = ONRTNTRADE;
if (pTrade)
{
task.task_data = *pTrade;
}
else
{
CSgitFtdcTradeField empty_data = CSgitFtdcTradeField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
this->task_queue.push(task);
};
void TdApi::OnRtnInstrumentStatus(CSgitFtdcInstrumentStatusField *pInstrumentStatus)
{
Task task = Task();
task.task_name = ONRTNINSTRUMENTSTATUS;
if (pInstrumentStatus)
{
task.task_data = *pInstrumentStatus;
}
else
{
CSgitFtdcInstrumentStatusField empty_data = CSgitFtdcInstrumentStatusField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
this->task_queue.push(task);
};
void TdApi::OnRspQryInvestorPositionDetail(CSgitFtdcInvestorPositionDetailField *pInvestorPositionDetail, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPQRYINVESTORPOSITIONDETAIL;
if (pInvestorPositionDetail)
{
task.task_data = *pInvestorPositionDetail;
}
else
{
CSgitFtdcInvestorPositionDetailField empty_data = CSgitFtdcInvestorPositionDetailField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CSgitFtdcRspInfoField empty_error = CSgitFtdcRspInfoField();
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 TdApi::OnRspQryInvestorPosition(CSgitFtdcInvestorPositionField *pInvestorPosition, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPQRYINVESTORPOSITION;
if (pInvestorPosition)
{
task.task_data = *pInvestorPosition;
}
else
{
CSgitFtdcInvestorPositionField empty_data = CSgitFtdcInvestorPositionField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CSgitFtdcRspInfoField empty_error = CSgitFtdcRspInfoField();
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);
};

View File

@ -0,0 +1,168 @@
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 onRspUserPasswordUpdate(dict data, dict error, int id, bool last)
{
try
{
this->get_override("onRspUserPasswordUpdate")(data, error, id, last);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onRspOrderInsert(dict data, dict error, int id, bool last)
{
try
{
this->get_override("onRspOrderInsert")(data, error, id, last);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onRspOrderAction(dict data, dict error, int id, bool last)
{
try
{
this->get_override("onRspOrderAction")(data, error, id, last);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onRspQryOrder(dict data, dict error, int id, bool last)
{
try
{
this->get_override("onRspQryOrder")(data, error, id, last);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onRspQryTradingAccount(dict data, dict error, int id, bool last)
{
try
{
this->get_override("onRspQryTradingAccount")(data, error, id, last);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onRspQryInvestor(dict data, dict error, int id, bool last)
{
try
{
this->get_override("onRspQryInvestor")(data, error, id, last);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onRspQryInstrument(dict data, dict error, int id, bool last)
{
try
{
this->get_override("onRspQryInstrument")(data, error, id, last);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onRtnOrder(dict data)
{
try
{
this->get_override("onRtnOrder")(data);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onRtnTrade(dict data)
{
try
{
this->get_override("onRtnTrade")(data);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onRtnInstrumentStatus(dict data)
{
try
{
this->get_override("onRtnInstrumentStatus")(data);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onRspQryInvestorPositionDetail(dict data, dict error, int id, bool last)
{
try
{
this->get_override("onRspQryInvestorPositionDetail")(data, error, id, last);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onRspQryInvestorPosition(dict data, dict error, int id, bool last)
{
try
{
this->get_override("onRspQryInvestorPosition")(data, error, id, last);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};

View File

@ -0,0 +1,118 @@
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
#if !defined(Sgit_FTDCMDAPI_H)
#define Sgit_FTDCMDAPI_H
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "SgitFtdcUserApiStruct.h"
#if defined(ISLIB) && defined(WIN32)
#ifdef LIB_MD_API_EXPORT
#define MD_API_EXPORT __declspec(dllexport)
#else
#define MD_API_EXPORT __declspec(dllimport)
#endif
#else
#define MD_API_EXPORT
#endif
class CSgitFtdcMdSpi
{
public:
///当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。
virtual void OnFrontConnected(){};
///当客户端与交易后台通信连接断开时该方法被调用。当发生这个情况后API会自动重新连接客户端可不做处理。
///@param pErrMsg 错误原因
virtual void OnFrontDisconnected(char *pErrMsg){};
///登录请求响应
virtual void OnRspUserLogin(CSgitFtdcRspUserLoginField *pRspUserLogin, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///登出请求响应
virtual void OnRspUserLogout(CSgitFtdcUserLogoutField *pUserLogout, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///深度行情通知
virtual void OnRtnDepthMarketData(CSgitFtdcDepthMarketDataField *pDepthMarketData) {};
};
class MD_API_EXPORT CSgitFtdcMdApi
{
public:
///创建MdApi
///@param pszFlowPath 存贮订阅信息文件的目录,默认为当前目录
///@return 创建出的UserApi
static CSgitFtdcMdApi *CreateFtdcMdApi(const char *pszFlowPath = "");
///删除接口对象本身
///@remark 不再使用本接口对象时,调用该函数删除接口对象
virtual void Release() = 0;
///初始化
///@remark 初始化运行环境,只有调用后,接口才开始工作
///isLogged 开发调试时使用true可以打印出收到的消息包内容
virtual void Init(bool isLogged) = 0;
///等待接口线程结束运行
///@return 线程退出代码
virtual int Join() = 0;
///获取当前交易日
///@retrun 获取到的交易日
///@remark 只有登录成功后,才能得到正确的交易日
virtual const char *GetTradingDay() = 0;
///注册前置机网络地址
///@param pszFrontAddress前置机网络地址。
///@remark 网络地址的格式为“protocol://ipaddress:port””tcp://127.0.0.1:17001”。
///@remark “tcp”代表传输协议“127.0.0.1”代表服务器地址。”17001”代表服务器端口号。
virtual void RegisterFront(char *pszFrontAddress) = 0;
/**用多播时TCP配置也需要设置
*tcp模式发送行情
* MlCast://hostIP$multiaddress:port
* MlCast://ANY$multiaddress:port
* @param szMlCastAddr ip地址
*/
virtual void SetMultiCastAddr(char *szMlCastAddr) = 0;
///注册回调接口
///@param pSpi 派生自回调接口类的实例
virtual void RegisterSpi(CSgitFtdcMdSpi *pSpi) = 0;
///订阅市场流。
///@param nResumeType 公共流重传方式
/// Sgit_TERT_RESTART:从本交易日开始重传
/// Sgit_TERT_RESUME:从上次收到的续传
/// Sgit_TERT_QUICK:只传送登录后公共流的内容
///@remark 该方法要在Init方法前调用。若不调用则不会收到公共流的数据。
virtual void SubscribeMarketTopic(Sgit_TE_RESUME_TYPE nResumeType) = 0;
///
/// 发送行情订阅
/// @param iRequestID 请求号
/// @param pMBLQuotReq 行情订阅请求域
/// @return 0表示成功
/// @return 其它表示失败
///
virtual int SubQuot(CSgitSubQuotField *pSgitSubQuotField)=0;
///发送就绪指令到前置,通知前置可以给自己发送私有流与公共流
/// @return 0表示成功
/// @return 其它参见错误码
///
virtual int Ready() = 0;
///用户登录请求
virtual int ReqUserLogin(CSgitFtdcReqUserLoginField *pReqUserLoginField, int nRequestID) = 0;
///登出请求
virtual int ReqUserLogout(CSgitFtdcUserLogoutField *pUserLogout, int nRequestID) = 0;
protected:
~CSgitFtdcMdApi(){};
};
#endif

View File

@ -0,0 +1,179 @@
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
#if !defined(Sgit_FTDCTRADERAPI_H)
#define Sgit_FTDCTRADERAPI_H
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "SgitFtdcUserApiStruct.h"
#if defined(ISLIB) && defined(WIN32)
#ifdef LIB_TRADER_API_EXPORT
#define TRADER_API_EXPORT __declspec(dllexport)
#else
#define TRADER_API_EXPORT __declspec(dllimport)
#endif
#else
#define TRADER_API_EXPORT
#endif
class CSgitFtdcTraderSpi
{
public:
///当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。
virtual void OnFrontConnected(){};
///当客户端与交易后台通信连接断开时该方法被调用。当发生这个情况后API会自动重新连接客户端可不做处理。
///@param pErrMsg 错误原因
virtual void OnFrontDisconnected(char *pErrMsg){};
///登录请求响应
virtual void OnRspUserLogin(CSgitFtdcRspUserLoginField *pRspUserLogin, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///登出请求响应
virtual void OnRspUserLogout(CSgitFtdcUserLogoutField *pUserLogout, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///用户口令更新请求响应
virtual void OnRspUserPasswordUpdate(CSgitFtdcUserPasswordUpdateField *pUserPasswordUpdate, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///报单录入请求响应
virtual void OnRspOrderInsert(CSgitFtdcInputOrderField *pInputOrder, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///报单操作请求响应
virtual void OnRspOrderAction(CSgitFtdcInputOrderActionField *pInputOrderAction, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///请求查询报单响应
virtual void OnRspQryOrder(CSgitFtdcOrderField *pOrder, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///请求查询资金账户响应
virtual void OnRspQryTradingAccount(CSgitFtdcTradingAccountField *pTradingAccount, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///请求查询投资者响应
virtual void OnRspQryInvestor(CSgitFtdcInvestorField *pInvestor, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///请求查询合约响应
virtual void OnRspQryInstrument(CSgitFtdcInstrumentField *pInstrument, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///报单通知
virtual void OnRtnOrder(CSgitFtdcOrderField *pOrder,CSgitFtdcRspInfoField *pRspInfo) {};
///成交通知
virtual void OnRtnTrade(CSgitFtdcTradeField *pTrade) {};
///合约交易状态通知
virtual void OnRtnInstrumentStatus(CSgitFtdcInstrumentStatusField *pInstrumentStatus) {};
///请求查询投资者持仓明细响应
virtual void OnRspQryInvestorPositionDetail(CSgitFtdcInvestorPositionDetailField *pInvestorPositionDetail, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///请求查询投资者持仓响应
virtual void OnRspQryInvestorPosition(CSgitFtdcInvestorPositionField *pInvestorPosition, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
/// 当收到合约价位查询应答时回调该函数
virtual void onRspMBLQuot(CSgitMBLQuotData *pMBLQuotData,CSgitFtdcRspInfoField *pRspMsg,int nRequestID,bool bIsLast){};
};
class TRADER_API_EXPORT CSgitFtdcTraderApi
{
public:
///创建TraderApi
///@param pszFlowPath 存贮订阅信息文件的目录,默认为当前目录
///@return 创建出的UserApi
static CSgitFtdcTraderApi *CreateFtdcTraderApi(const char *pszFlowPath = "");
///删除接口对象本身
///@remark 不再使用本接口对象时,调用该函数删除接口对象
virtual void Release() = 0;
///初始化
///@remark 初始化运行环境,只有调用后,接口才开始工作
///isLogged 开发调试时使用true可以打印出收到的消息包内容
virtual void Init(bool isLogged) = 0;
///等待接口线程结束运行
///@return 线程退出代码
virtual int Join() = 0;
///获取当前交易日
///@retrun 获取到的交易日
///@remark 只有登录成功后,才能得到正确的交易日
virtual const char *GetTradingDay() = 0;
///注册前置机网络地址
///@param pszFrontAddress前置机网络地址。
///@remark 网络地址的格式为“protocol://ipaddress:port””tcp://127.0.0.1:17001”。
///@remark “tcp”代表传输协议“127.0.0.1”代表服务器地址。”17001”代表服务器端口号。
virtual void RegisterFront(char *pszFrontAddress) = 0;
///注册回调接口
///@param pSpi 派生自回调接口类的实例
virtual void RegisterSpi(CSgitFtdcTraderSpi *pSpi) = 0;
///订阅私有流。
///@param nResumeType 私有流重传方式
/// Sgit_TERT_RESTART:从本交易日开始重传
/// Sgit_TERT_RESUME:从上次收到的续传
/// Sgit_TERT_QUICK:只传送登录后私有流的内容
///@remark 该方法要在Init方法前调用。若不调用则不会收到私有流的数据。
virtual void SubscribePrivateTopic(Sgit_TE_RESUME_TYPE nResumeType) = 0;
///订阅公共流。
///@param nResumeType 公共流重传方式
/// Sgit_TERT_RESTART:从本交易日开始重传
/// Sgit_TERT_RESUME:从上次收到的续传
/// Sgit_TERT_QUICK:只传送登录后公共流的内容
///@remark 该方法要在Init方法前调用。若不调用则不会收到公共流的数据。
virtual void SubscribePublicTopic(Sgit_TE_RESUME_TYPE nResumeType) = 0;
///发送就绪指令到前置,通知前置可以给自己发送私有流与公共流
/// @return 0表示成功
/// @return 其它参见错误码
///
virtual int Ready() = 0;
///用户登录请求
virtual int ReqUserLogin(CSgitFtdcReqUserLoginField *pReqUserLoginField, int nRequestID) = 0;
///登出请求
virtual int ReqUserLogout(CSgitFtdcUserLogoutField *pUserLogout, int nRequestID) = 0;
///用户口令更新请求
virtual int ReqUserPasswordUpdate(CSgitFtdcUserPasswordUpdateField *pUserPasswordUpdate, int nRequestID) = 0;
///报单录入请求
virtual int ReqOrderInsert(CSgitFtdcInputOrderField *pInputOrder, int nRequestID) = 0;
///报单操作请求
virtual int ReqOrderAction(CSgitFtdcInputOrderActionField *pInputOrderAction, int nRequestID) = 0;
///请求查询报单
virtual int ReqQryOrder(CSgitFtdcQryOrderField *pQryOrder, int nRequestID) = 0;
///请求查询资金账户
virtual int ReqQryTradingAccount(CSgitFtdcQryTradingAccountField *pQryTradingAccount, int nRequestID) = 0;
///请求查询投资者
virtual int ReqQryInvestor(CSgitFtdcQryInvestorField *pQryInvestor, int nRequestID) = 0;
///请求查询合约
virtual int ReqQryInstrument(CSgitFtdcQryInstrumentField *pQryInstrument, int nRequestID) = 0;
///请求查询投资者持仓明细
virtual int ReqQryInvestorPositionDetail(CSgitFtdcQryInvestorPositionDetailField *pQryInvestorPositionDetail, int nRequestID) = 0;
///请求查询投资者持仓
virtual int ReqQryInvestorPosition(CSgitFtdcQryInvestorPositionField *pQryInvestorPosition, int nRequestID) = 0;
/// 发送合约价位查询请求
virtual int ReqMBLQuot(int iRequestID,CSgitMBLQuotReq *pMBLQuotReq) = 0;
protected:
~CSgitFtdcTraderApi(){};
};
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,48 @@
========================================================================
DYNAMIC LINK LIBRARY : vnsgittd Project Overview
========================================================================
AppWizard has created this vnsgittd DLL for you.
This file contains a summary of what you will find in each of the files that
make up your vnsgittd application.
vnsgittd.vcxproj
This is the main project file for VC++ projects generated using an Application Wizard.
It contains information about the version of Visual C++ that generated the file, and
information about the platforms, configurations, and project features selected with the
Application Wizard.
vnsgittd.vcxproj.filters
This is the filters file for VC++ projects generated using an Application Wizard.
It contains information about the association between the files in your project
and the filters. This association is used in the IDE to show grouping of files with
similar extensions under a specific node (for e.g. ".cpp" files are associated with the
"Source Files" filter).
vnsgittd.cpp
This is the main DLL source file.
When created, this DLL does not export any symbols. As a result, it
will not produce a .lib file when it is built. If you wish this project
to be a project dependency of some other project, you will either need to
add code to export some symbols from the DLL so that an export library
will be produced, or you can set the Ignore Input Library property to Yes
on the General propert page of the Linker folder in the project's Property
Pages dialog box.
/////////////////////////////////////////////////////////////////////////////
Other standard files:
StdAfx.h, StdAfx.cpp
These files are used to build a precompiled header (PCH) file
named vnsgittd.pch and a precompiled types file named StdAfx.obj.
/////////////////////////////////////////////////////////////////////////////
Other notes:
AppWizard uses "TODO:" comments to indicate parts of the source code you
should add to or customize.
/////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,19 @@
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

View File

@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// vnsgittd.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View File

@ -0,0 +1,16 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
// TODO: reference additional headers your program requires here

View File

@ -0,0 +1,8 @@
#pragma once
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>

View File

@ -0,0 +1,564 @@
// 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 getString(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(char *pErrMsg)
{
Task task = Task();
task.task_name = ONFRONTDISCONNECTED;
if (pErrMsg)
{
task.task_data = *pErrMsg;
}
else
{
char empty_data = char();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
this->task_queue.push(task);
};
void MdApi::OnRspUserLogin(CSgitFtdcRspUserLoginField *pRspUserLogin, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPUSERLOGIN;
if (pRspUserLogin)
{
task.task_data = *pRspUserLogin;
}
else
{
CSgitFtdcRspUserLoginField empty_data = CSgitFtdcRspUserLoginField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CSgitFtdcRspInfoField empty_error = CSgitFtdcRspInfoField();
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(CSgitFtdcUserLogoutField *pUserLogout, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
Task task = Task();
task.task_name = ONRSPUSERLOGOUT;
if (pUserLogout)
{
task.task_data = *pUserLogout;
}
else
{
CSgitFtdcUserLogoutField empty_data = CSgitFtdcUserLogoutField();
memset(&empty_data, 0, sizeof(empty_data));
task.task_data = empty_data;
}
if (pRspInfo)
{
task.task_error = *pRspInfo;
}
else
{
CSgitFtdcRspInfoField empty_error = CSgitFtdcRspInfoField();
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(CSgitFtdcDepthMarketDataField *pDepthMarketData)
{
Task task = Task();
task.task_name = ONRTNDEPTHMARKETDATA;
if (pDepthMarketData)
{
task.task_data = *pDepthMarketData;
}
else
{
CSgitFtdcDepthMarketDataField empty_data = CSgitFtdcDepthMarketDataField();
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 ONRSPUSERLOGIN:
{
this->processRspUserLogin(task);
break;
}
case ONRSPUSERLOGOUT:
{
this->processRspUserLogout(task);
break;
}
case ONRTNDEPTHMARKETDATA:
{
this->processRtnDepthMarketData(task);
break;
}
};
}
};
void MdApi::processFrontConnected(Task task)
{
PyLock lock;
this->onFrontConnected();
};
void MdApi::processFrontDisconnected(Task task)
{
PyLock lock;
string msg = any_cast<string>(task.task_data);
this->onFrontDisconnected(msg);
};
void MdApi::processRspUserLogin(Task task)
{
PyLock lock;
CSgitFtdcRspUserLoginField task_data = any_cast<CSgitFtdcRspUserLoginField>(task.task_data);
dict data;
data["CZCETime"] = task_data.CZCETime;
data["SHFETime"] = task_data.SHFETime;
data["MaxOrderRef"] = task_data.MaxOrderRef;
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;
CSgitFtdcRspInfoField task_error = any_cast<CSgitFtdcRspInfoField>(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;
CSgitFtdcUserLogoutField task_data = any_cast<CSgitFtdcUserLogoutField>(task.task_data);
dict data;
data["UserID"] = task_data.UserID;
data["BrokerID"] = task_data.BrokerID;
CSgitFtdcRspInfoField task_error = any_cast<CSgitFtdcRspInfoField>(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::processRtnDepthMarketData(Task task)
{
PyLock lock;
CSgitFtdcDepthMarketDataField task_data = any_cast<CSgitFtdcDepthMarketDataField>(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;
this->onRtnDepthMarketData(data);
};
///-------------------------------------------------------------------------------------
///主动函数
///-------------------------------------------------------------------------------------
void MdApi::createFtdcMdApi(string pszFlowPath)
{
//该函数为手动编写
this->api = CSgitFtdcMdApi::CreateFtdcMdApi(pszFlowPath.c_str());
this->api->RegisterSpi(this);
};
void MdApi::release()
{
//该函数为手动编写
this->api->Release();
};
void MdApi::init(bool isLogged)
{
//该函数为手动编写
this->api->Init(isLogged);
};
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::setMultiCastAddr(string address)
{
//该函数为手动编写
this->api->SetMultiCastAddr((char*)address.c_str());
};
void MdApi::subscribeMarketTopic(int nType)
{
//该函数为手动编写
Sgit_TE_RESUME_TYPE type = Sgit_TE_RESUME_TYPE(nType);
this->api->SubscribeMarketTopic(type);
};
int MdApi::ready()
{
//该函数为手动编写
int i = this->api->Ready();
return i;
}
int MdApi::subQuot(dict req)
{
CSgitSubQuotField myreq = CSgitSubQuotField();
memset(&myreq, 0, sizeof(myreq));
getString(req, "ContractID", myreq.ContractID);
int i = this->api->SubQuot(&myreq);
return i;
};
int MdApi::reqUserLogin(dict req, int nRequestID)
{
CSgitFtdcReqUserLoginField myreq = CSgitFtdcReqUserLoginField();
memset(&myreq, 0, sizeof(myreq));
getString(req, "MacAddress", myreq.MacAddress);
getString(req, "UserProductInfo", myreq.UserProductInfo);
getString(req, "UserID", myreq.UserID);
getString(req, "TradingDay", myreq.TradingDay);
getString(req, "InterfaceProductInfo", myreq.InterfaceProductInfo);
getString(req, "BrokerID", myreq.BrokerID);
getString(req, "ClientIPAddress", myreq.ClientIPAddress);
getString(req, "OneTimePassword", myreq.OneTimePassword);
getString(req, "ProtocolInfo", myreq.ProtocolInfo);
getString(req, "Password", myreq.Password);
int i = this->api->ReqUserLogin(&myreq, nRequestID);
return i;
};
int MdApi::reqUserLogout(dict req, int nRequestID)
{
CSgitFtdcUserLogoutField myreq = CSgitFtdcUserLogoutField();
memset(&myreq, 0, sizeof(myreq));
getString(req, "UserID", myreq.UserID);
getString(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(string msg)
{
try
{
this->get_override("onFrontDisconnected")(msg);
}
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 onRtnDepthMarketData(dict data)
{
try
{
this->get_override("onRtnDepthMarketData")(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("release", &MdApiWrap::release)
.def("init", &MdApiWrap::init)
.def("join", &MdApiWrap::join)
.def("exit", &MdApiWrap::exit)
.def("getTradingDay", &MdApiWrap::getTradingDay)
.def("registerFront", &MdApiWrap::registerFront)
.def("setMultiCastAddr", &MdApiWrap::setMultiCastAddr)
.def("subscribeMarketTopic", &MdApiWrap::subscribeMarketTopic)
.def("subQuot", &MdApiWrap::subQuot)
.def("ready", &MdApiWrap::ready)
.def("reqUserLogin", &MdApiWrap::reqUserLogin)
.def("reqUserLogout", &MdApiWrap::reqUserLogout)
.def("onFrontConnected", pure_virtual(&MdApiWrap::onFrontConnected))
.def("onFrontDisconnected", pure_virtual(&MdApiWrap::onFrontDisconnected))
.def("onRspUserLogin", pure_virtual(&MdApiWrap::onRspUserLogin))
.def("onRspUserLogout", pure_virtual(&MdApiWrap::onRspUserLogout))
.def("onRtnDepthMarketData", pure_virtual(&MdApiWrap::onRtnDepthMarketData))
;
};

View File

@ -0,0 +1,248 @@
//说明部分
//系统
#include "stdafx.h"
#include <string>
#include <queue>
//Boost
#define BOOST_PYTHON_STATIC_LIB
#include <boost/python/module.hpp> //python封装
#include <boost/python/def.hpp> //python封装
#include <boost/python/dict.hpp> //python封装
#include <boost/python/object.hpp> //python封装
#include <boost/python.hpp> //python封装
#include <boost/thread.hpp> //任务队列的线程功能
#include <boost/bind.hpp> //任务队列的线程功能
#include <boost/any.hpp> //任务队列的任务实现
//API
#include "SgitFtdcMdApi.h"
//命名空间
using namespace std;
using namespace boost::python;
using namespace boost;
//常量
#define ONFRONTCONNECTED 1
#define ONFRONTDISCONNECTED 2
#define ONRSPUSERLOGIN 3
#define ONRSPUSERLOGOUT 4
#define ONRTNDEPTHMARKETDATA 5
///-------------------------------------------------------------------------------------
///API中的部分组件
///-------------------------------------------------------------------------------------
//GIL全局锁简化获取用
//用于帮助C++线程获得GIL锁从而防止python崩溃
class PyLock
{
private:
PyGILState_STATE gil_state;
public:
//在某个函数方法中创建该对象时获得GIL锁
PyLock()
{
gil_state = PyGILState_Ensure();
}
//在某个函数完成后销毁该对象时解放GIL锁
~PyLock()
{
PyGILState_Release(gil_state);
}
};
//任务结构体
struct Task
{
int task_name; //回调函数名称对应的常量
any task_data; //数据结构体
any task_error; //错误结构体
int task_id; //请求id
bool task_last; //是否为最后返回
};
///线程安全的队列
template<typename Data>
class ConcurrentQueue
{
private:
queue<Data> the_queue; //标准库队列
mutable mutex the_mutex; //boost互斥锁
condition_variable the_condition_variable; //boost条件变量
public:
//存入新的任务
void push(Data const& data)
{
mutex::scoped_lock lock(the_mutex); //获取互斥锁
the_queue.push(data); //向队列中存入数据
lock.unlock(); //释放锁
the_condition_variable.notify_one(); //通知正在阻塞等待的线程
}
//检查队列是否为空
bool empty() const
{
mutex::scoped_lock lock(the_mutex);
return the_queue.empty();
}
//取出
Data wait_and_pop()
{
mutex::scoped_lock lock(the_mutex);
while (the_queue.empty()) //当队列为空时
{
the_condition_variable.wait(lock); //等待条件变量通知
}
Data popped_value = the_queue.front(); //获取队列中的最后一个任务
the_queue.pop(); //删除该任务
return popped_value; //返回该任务
}
};
//从字典中获取某个建值对应的整数,并赋值到请求结构体对象的值上
void getInt(dict d, string key, int* value);
//从字典中获取某个建值对应的长整数,并赋值到请求结构体对象的值上
void getLong(dict d, string key, long* value);
//从字典中获取某个建值对应的短整数,并赋值到请求结构体对象的值上
void getShort(dict d, string key, short* value);
//从字典中获取某个建值对应的浮点数,并赋值到请求结构体对象的值上
void getDouble(dict d, string key, double* value);
//从字典中获取某个建值对应的单字符,并赋值到请求结构体对象的值上
void getChar(dict d, string key, char* value);
//从字典中获取某个建值对应的字符串,并赋值到请求结构体对象的值上
void getString(dict d, string key, char* value);
///-------------------------------------------------------------------------------------
///C++ SPI的回调函数方法实现
///-------------------------------------------------------------------------------------
//API的继承实现
class MdApi : public CSgitFtdcMdSpi
{
private:
CSgitFtdcMdApi* api; //API对象
thread *task_thread; //工作线程指针向python中推送数据
ConcurrentQueue<Task> task_queue; //任务队列
public:
MdApi()
{
function0<void> f = boost::bind(&MdApi::processTask, this);
thread t(f);
this->task_thread = &t;
};
~MdApi()
{
};
//-------------------------------------------------------------------------------------
//API回调函数
//-------------------------------------------------------------------------------------
///当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。
virtual void OnFrontConnected();
///当客户端与交易后台通信连接断开时该方法被调用。当发生这个情况后API会自动重新连接客户端可不做处理。
///@param pErrMsg 错误原因
virtual void OnFrontDisconnected(char *pErrMsg);
///登录请求响应
virtual void OnRspUserLogin(CSgitFtdcRspUserLoginField *pRspUserLogin, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) ;
///登出请求响应
virtual void OnRspUserLogout(CSgitFtdcUserLogoutField *pUserLogout, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) ;
///深度行情通知
virtual void OnRtnDepthMarketData(CSgitFtdcDepthMarketDataField *pDepthMarketData) ;
//-------------------------------------------------------------------------------------
//task任务
//-------------------------------------------------------------------------------------
void processTask();
void processFrontConnected(Task task);
void processFrontDisconnected(Task task);
void processRspUserLogin(Task task);
void processRspUserLogout(Task task);
void processRtnDepthMarketData(Task task);
//-------------------------------------------------------------------------------------
//data回调函数的数据字典
//error回调函数的错误字典
//id请求id
//last是否为最后返回
//i整数
//-------------------------------------------------------------------------------------
virtual void onFrontConnected(){};
virtual void onFrontDisconnected(string msg) {};
virtual void onRspUserLogin(dict data, dict error, int id, bool last) {};
virtual void onRspUserLogout(dict data, dict error, int id, bool last) {};
virtual void onRtnDepthMarketData(dict data) {};
//-------------------------------------------------------------------------------------
//req:主动函数的请求字典
//-------------------------------------------------------------------------------------
void createFtdcMdApi(string pszFlowPath);
void release();
void init(bool isLogged);
int join();
int exit();
string getTradingDay();
void registerFront(string pszFrontAddress);
void setMultiCastAddr(string address);
void subscribeMarketTopic(int type);
int subQuot(dict req);
int ready();
int reqUserLogin(dict req, int nRequestID);
int reqUserLogout(dict req, int nRequestID);
};

View File

@ -0,0 +1,48 @@
========================================================================
DYNAMIC LINK LIBRARY : vnsgittd Project Overview
========================================================================
AppWizard has created this vnsgittd DLL for you.
This file contains a summary of what you will find in each of the files that
make up your vnsgittd application.
vnsgittd.vcxproj
This is the main project file for VC++ projects generated using an Application Wizard.
It contains information about the version of Visual C++ that generated the file, and
information about the platforms, configurations, and project features selected with the
Application Wizard.
vnsgittd.vcxproj.filters
This is the filters file for VC++ projects generated using an Application Wizard.
It contains information about the association between the files in your project
and the filters. This association is used in the IDE to show grouping of files with
similar extensions under a specific node (for e.g. ".cpp" files are associated with the
"Source Files" filter).
vnsgittd.cpp
This is the main DLL source file.
When created, this DLL does not export any symbols. As a result, it
will not produce a .lib file when it is built. If you wish this project
to be a project dependency of some other project, you will either need to
add code to export some symbols from the DLL so that an export library
will be produced, or you can set the Ignore Input Library property to Yes
on the General propert page of the Linker folder in the project's Property
Pages dialog box.
/////////////////////////////////////////////////////////////////////////////
Other standard files:
StdAfx.h, StdAfx.cpp
These files are used to build a precompiled header (PCH) file
named vnsgittd.pch and a precompiled types file named StdAfx.obj.
/////////////////////////////////////////////////////////////////////////////
Other notes:
AppWizard uses "TODO:" comments to indicate parts of the source code you
should add to or customize.
/////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,19 @@
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

View File

@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// vnsgittd.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View File

@ -0,0 +1,16 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
// TODO: reference additional headers your program requires here

View File

@ -0,0 +1,8 @@
#pragma once
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,356 @@
//说明部分
//系统
#include "stdafx.h"
#include <string>
#include <queue>
//Boost
#define BOOST_PYTHON_STATIC_LIB
#include <boost/python/module.hpp> //python封装
#include <boost/python/def.hpp> //python封装
#include <boost/python/dict.hpp> //python封装
#include <boost/python/object.hpp> //python封装
#include <boost/python.hpp> //python封装
#include <boost/thread.hpp> //任务队列的线程功能
#include <boost/bind.hpp> //任务队列的线程功能
#include <boost/any.hpp> //任务队列的任务实现
//API
#include "SgitFtdcTraderApi.h"
//命名空间
using namespace std;
using namespace boost::python;
using namespace boost;
//常量
#define ONFRONTCONNECTED 1
#define ONFRONTDISCONNECTED 2
#define ONRSPUSERLOGIN 3
#define ONRSPUSERLOGOUT 4
#define ONRSPUSERPASSWORDUPDATE 5
#define ONRSPORDERINSERT 6
#define ONRSPORDERACTION 7
#define ONRSPQRYORDER 8
#define ONRSPQRYTRADINGACCOUNT 9
#define ONRSPQRYINVESTOR 10
#define ONRSPQRYINSTRUMENT 11
#define ONRTNORDER 12
#define ONRTNTRADE 13
#define ONRTNINSTRUMENTSTATUS 14
#define ONRSPQRYINVESTORPOSITIONDETAIL 15
#define ONRSPQRYINVESTORPOSITION 16
///-------------------------------------------------------------------------------------
///API中的部分组件
///-------------------------------------------------------------------------------------
//GIL全局锁简化获取用
//用于帮助C++线程获得GIL锁从而防止python崩溃
class PyLock
{
private:
PyGILState_STATE gil_state;
public:
//在某个函数方法中创建该对象时获得GIL锁
PyLock()
{
gil_state = PyGILState_Ensure();
}
//在某个函数完成后销毁该对象时解放GIL锁
~PyLock()
{
PyGILState_Release(gil_state);
}
};
//任务结构体
struct Task
{
int task_name; //回调函数名称对应的常量
any task_data; //数据结构体
any task_error; //错误结构体
int task_id; //请求id
bool task_last; //是否为最后返回
};
///线程安全的队列
template<typename Data>
class ConcurrentQueue
{
private:
queue<Data> the_queue; //标准库队列
mutable mutex the_mutex; //boost互斥锁
condition_variable the_condition_variable; //boost条件变量
public:
//存入新的任务
void push(Data const& data)
{
mutex::scoped_lock lock(the_mutex); //获取互斥锁
the_queue.push(data); //向队列中存入数据
lock.unlock(); //释放锁
the_condition_variable.notify_one(); //通知正在阻塞等待的线程
}
//检查队列是否为空
bool empty() const
{
mutex::scoped_lock lock(the_mutex);
return the_queue.empty();
}
//取出
Data wait_and_pop()
{
mutex::scoped_lock lock(the_mutex);
while (the_queue.empty()) //当队列为空时
{
the_condition_variable.wait(lock); //等待条件变量通知
}
Data popped_value = the_queue.front(); //获取队列中的最后一个任务
the_queue.pop(); //删除该任务
return popped_value; //返回该任务
}
};
//从字典中获取某个建值对应的整数,并赋值到请求结构体对象的值上
void getInt(dict d, string key, int* value);
//从字典中获取某个建值对应的长整数,并赋值到请求结构体对象的值上
void getLong(dict d, string key, long* value);
//从字典中获取某个建值对应的短整数,并赋值到请求结构体对象的值上
void getShort(dict d, string key, short* value);
//从字典中获取某个建值对应的浮点数,并赋值到请求结构体对象的值上
void getDouble(dict d, string key, double* value);
//从字典中获取某个建值对应的单字符,并赋值到请求结构体对象的值上
void getChar(dict d, string key, char* value);
//从字典中获取某个建值对应的字符串,并赋值到请求结构体对象的值上
void getString(dict d, string key, char* value);
///-------------------------------------------------------------------------------------
///C++ SPI的回调函数方法实现
///-------------------------------------------------------------------------------------
//API的继承实现
class TdApi : public CSgitFtdcTraderSpi
{
private:
CSgitFtdcTraderApi* api; //API对象
thread *task_thread; //工作线程指针向python中推送数据
ConcurrentQueue<Task> task_queue; //任务队列
public:
TdApi()
{
function0<void> f = boost::bind(&TdApi::processTask, this);
thread t(f);
this->task_thread = &t;
};
~TdApi()
{
};
//-------------------------------------------------------------------------------------
//API回调函数
//-------------------------------------------------------------------------------------
///当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。
virtual void OnFrontConnected();
///当客户端与交易后台通信连接断开时该方法被调用。当发生这个情况后API会自动重新连接客户端可不做处理。
///@param pErrMsg 错误原因
virtual void OnFrontDisconnected(char *pErrMsg);
///登录请求响应
virtual void OnRspUserLogin(CSgitFtdcRspUserLoginField *pRspUserLogin, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) ;
///登出请求响应
virtual void OnRspUserLogout(CSgitFtdcUserLogoutField *pUserLogout, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) ;
///用户口令更新请求响应
virtual void OnRspUserPasswordUpdate(CSgitFtdcUserPasswordUpdateField *pUserPasswordUpdate, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) ;
///报单录入请求响应
virtual void OnRspOrderInsert(CSgitFtdcInputOrderField *pInputOrder, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) ;
///报单操作请求响应
virtual void OnRspOrderAction(CSgitFtdcInputOrderActionField *pInputOrderAction, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) ;
///请求查询报单响应
virtual void OnRspQryOrder(CSgitFtdcOrderField *pOrder, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) ;
///请求查询资金账户响应
virtual void OnRspQryTradingAccount(CSgitFtdcTradingAccountField *pTradingAccount, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) ;
///请求查询投资者响应
virtual void OnRspQryInvestor(CSgitFtdcInvestorField *pInvestor, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) ;
///请求查询合约响应
virtual void OnRspQryInstrument(CSgitFtdcInstrumentField *pInstrument, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) ;
///报单通知
virtual void OnRtnOrder(CSgitFtdcOrderField *pOrder, CSgitFtdcRspInfoField *pRspInfo) ;
///成交通知
virtual void OnRtnTrade(CSgitFtdcTradeField *pTrade) ;
///合约交易状态通知
virtual void OnRtnInstrumentStatus(CSgitFtdcInstrumentStatusField *pInstrumentStatus) ;
///请求查询投资者持仓明细响应
virtual void OnRspQryInvestorPositionDetail(CSgitFtdcInvestorPositionDetailField *pInvestorPositionDetail, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) ;
///请求查询投资者持仓响应
virtual void OnRspQryInvestorPosition(CSgitFtdcInvestorPositionField *pInvestorPosition, CSgitFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) ;
/// 当收到合约价位查询应答时回调该函数
virtual void onRspMBLQuot(CSgitMBLQuotData *pMBLQuotData, CSgitFtdcRspInfoField *pRspMsg, int nRequestID, bool bIsLast){};
//-------------------------------------------------------------------------------------
//task任务
//-------------------------------------------------------------------------------------
void processTask();
void processFrontConnected(Task task);
void processFrontDisconnected(Task task);
void processRspUserLogin(Task task);
void processRspUserLogout(Task task);
void processRspUserPasswordUpdate(Task task);
void processRspOrderInsert(Task task);
void processRspOrderAction(Task task);
void processRspQryOrder(Task task);
void processRspQryTradingAccount(Task task);
void processRspQryInvestor(Task task);
void processRspQryInstrument(Task task);
void processRtnOrder(Task task);
void processRtnTrade(Task task);
void processRtnInstrumentStatus(Task task);
void processRspQryInvestorPositionDetail(Task task);
void processRspQryInvestorPosition(Task task);
//-------------------------------------------------------------------------------------
//data回调函数的数据字典
//error回调函数的错误字典
//id请求id
//last是否为最后返回
//i整数
//-------------------------------------------------------------------------------------
virtual void onFrontConnected(){};
virtual void onFrontDisconnected(string msg){};
virtual void onRspUserLogin(dict data, dict error, int id, bool last) {};
virtual void onRspUserLogout(dict data, dict error, int id, bool last) {};
virtual void onRspUserPasswordUpdate(dict data, dict error, int id, bool last) {};
virtual void onRspOrderInsert(dict data, dict error, int id, bool last) {};
virtual void onRspOrderAction(dict data, dict error, int id, bool last) {};
virtual void onRspQryOrder(dict data, dict error, int id, bool last) {};
virtual void onRspQryTradingAccount(dict data, dict error, int id, bool last) {};
virtual void onRspQryInvestor(dict data, dict error, int id, bool last) {};
virtual void onRspQryInstrument(dict data, dict error, int id, bool last) {};
virtual void onRtnOrder(dict data, dict error) {};
virtual void onRtnTrade(dict data) {};
virtual void onRtnInstrumentStatus(dict data) {};
virtual void onRspQryInvestorPositionDetail(dict data, dict error, int id, bool last) {};
virtual void onRspQryInvestorPosition(dict data, dict error, int id, bool last) {};
//-------------------------------------------------------------------------------------
//req:主动函数的请求字典
//-------------------------------------------------------------------------------------
void createFtdcTraderApi(string pszFlowPath);
void release();
void init(bool isLogged);
int join();
int exit();
string getTradingDay();
void registerFront(string pszFrontAddress);
void subscribePrivateTopic(int type);
void subscribePublicTopic(int type);
int ready();
int reqUserLogin(dict req, int nRequestID);
int reqUserLogout(dict req, int nRequestID);
int reqUserPasswordUpdate(dict req, int nRequestID);
int reqOrderInsert(dict req, int nRequestID);
int reqOrderAction(dict req, int nRequestID);
int reqQryOrder(dict req, int nRequestID);
int reqQryTradingAccount(dict req, int nRequestID);
int reqQryInvestor(dict req, int nRequestID);
int reqQryInstrument(dict req, int nRequestID);
int reqQryInvestorPositionDetail(dict req, int nRequestID);
int reqQryInvestorPosition(dict req, int nRequestID);
//int reqMBLQuot(dict req, int nRequestID);
};