增加直达期货的外盘交易接口

This commit is contained in:
chenxy123 2016-08-10 23:09:51 +08:00
parent 6f6641b345
commit bbfaac1b74
56 changed files with 66102 additions and 3 deletions

View File

@ -36,6 +36,7 @@
对于想研究API封装的用户可以参考[vnpy.org](http://vnpy.org)上面的教程一步步操作。 对于想研究API封装的用户可以参考[vnpy.org](http://vnpy.org)上面的教程一步步操作。
其他作者建议使用的软件工具: 其他作者建议使用的软件工具:
* [WingIDE](http://wingware.com/)非常好用的Python集成开发环境作者就是用它写的vn.py * [WingIDE](http://wingware.com/)非常好用的Python集成开发环境作者就是用它写的vn.py
* [Robomongo](https://robomongo.org/)MongoDB的图形化客户端方便监控和修改数据 * [Robomongo](https://robomongo.org/)MongoDB的图形化客户端方便监控和修改数据
@ -49,26 +50,31 @@
##### 注意: ##### 注意:
按照以上方式配置后你便可以使用vn.py的CTP, LTS, KSOTP等大多数交易接口但在启动vtMain.py时 你可能会遇到以下错误:
按照以上方式配置后便可以使用vn.py的CTP, LTS, KSOTP等大多数交易接口但在启动vtMain.py时 你可能会遇到以下错误:
``` ```
请先安装WindPy接口 请先安装WindPy接口
global name 'w' is not defined global name 'w' is not defined
No module named ib.ext.Contract No module named ib.ext.Contract
No module named websocket No module named websocket
``` ```
它们分别对应Wind, IB, OKCOIN三个交易接口如果你不使用这三个接口可以直接忽略这些错误不会影响使用。 它们分别对应Wind, IB, OKCOIN三个交易接口如果你不使用这三个接口可以直接忽略这些错误不会影响使用。
但如果你需要,可以通过以下方式安装其对应的库: 但如果你需要,可以通过以下方式安装其对应的库:
* WIND - 到[大奖章网站](http://www.dajiangzhang.com/document)注册并下载安装**Wind资讯开放应用接口**个人版即可 * WIND - 到[大奖章网站](http://www.dajiangzhang.com/document)注册并下载安装**Wind资讯开放应用接口**个人版即可使用机构版Wind终端的用户可以直接在终端里安装Python接口
* IB - 参考https://github.com/blampe/IbPy 基本上是两步: * IB - 参考https://github.com/blampe/IbPy 基本上是两步:
``` ```
git clone https://github.com/blampe/IbPy.git git clone https://github.com/blampe/IbPy.git
cd IbPy cd IbPy
python setup.py install python setup.py install
``` ```
* OKCOIN - ```pip install websocket``` or ```conda install websocket``` * OKCOIN - ```pip install websocket``` or ```conda install websocket```
@ -78,10 +84,15 @@ python setup.py install
vn.py使用github托管其源代码贡献代码使用github的PR(Pull Request)的流程,十分的强大与便利: vn.py使用github托管其源代码贡献代码使用github的PR(Pull Request)的流程,十分的强大与便利:
1. [创建 Issue](https://github.com/vnpy/vnpy/issues/new) - 对于较大的改动(如新功能,大型重构等)最好先开issue讨论一下较小的improvement(如文档改进bugfix等)直接发PR即可 1. [创建 Issue](https://github.com/vnpy/vnpy/issues/new) - 对于较大的改动(如新功能,大型重构等)最好先开issue讨论一下较小的improvement(如文档改进bugfix等)直接发PR即可
2. Fork [vn.py](https://github.com/vnpy/vnpy) - 点击右上角**Fork**按钮 2. Fork [vn.py](https://github.com/vnpy/vnpy) - 点击右上角**Fork**按钮
3. Clone你自己的fork: ```git clone https://github.com/$userid/vnpy.git``` 3. Clone你自己的fork: ```git clone https://github.com/$userid/vnpy.git```
4. 在**dev**修改并将修改push到你的fork上 4. 在**dev**修改并将修改push到你的fork上
5. 创建从你的fork的**dev**分支到主项目的**dev**分支的[Pull Request] - [在此](https://github.com/vnpy/vnpy)点击**Compare & pull request** 5. 创建从你的fork的**dev**分支到主项目的**dev**分支的[Pull Request] - [在此](https://github.com/vnpy/vnpy)点击**Compare & pull request**
6. 等待review, 需要继续改进或者被Merge! 6. 等待review, 需要继续改进或者被Merge!
--- ---

12
vn.shzd/README.md Normal file
View File

@ -0,0 +1,12 @@
# vn.shzd
### 简介
直达期货接口的Python封装主要用于外盘期货交易可以提供比IB更低的行情和交易延时以及更好的交易稳定性适合专业机构使用。
### API版本
日期2015-10-16
名称ShZd-Dll_20151016
链接:[http://www.directaccess.com.hk/software/download.html](http://www.directaccess.com.hk/software/download.html)

Binary file not shown.

View File

@ -0,0 +1,39 @@
code msg
00000 或“ ” 处理成功
00001 服务器已断开,请联系客服或者稍后重新登录系统
00002 指令失败,请联系客服或者稍后重新登录系统!
10001 用户名不正确
10002 登录密码错误
10003 密码错误次数超限,用户已冻结,请联系客服解冻!
10004 用户已被冻结,请联系客服解冻!
20000 下单失败
20001 资金不足
20002 交易服务器未连接
20003 您已被禁止交易,请联系客服解禁
20004 下单被拒绝
20005 系统号生成失败
20006 您的资金账户中没有该合约交易所需的币种
20007 该合约已经到期,不能交易
20008 该交易市场未开市,不能交易
20009 该交易市场已闭市,不能交易
20010 下单价格超出限定范围
20011 下单数量过大
20012 您被禁止交易该合约,请联系客服
20013 您的资金账户风险率过高,已被禁止交易
20014 撤单失败
20015 您的账户交易数据出现异常,暂停交易
20016 改单失败
20019 下单数量超过客户持仓限量
20020 下单数量超过客户可下单买量
20021 下单数量超过客户可下单卖量
20022 下单数量超过公司持仓限量
20023 下单数量超过公司可下单买量
20024 下单数量超过公司可下单卖量
20026 合约临近交割,只可平仓,不能开仓
20027 该合约已过最后交易日时间,禁止电子盘交易
20028 商品未开放,禁止交易
20029 单笔下单数量超过该商品单笔最大可下单数
7、17服务器连接成功前置服务器连接成功行情服务器连接成功
8、18服务器断开前置断开、行情服务器断开
3000 请求未输入账号

View File

@ -0,0 +1,27 @@
#pragma once
#include <map>
using namespace std;
#ifndef ShZdMessage_H
#define ShZdMessage_H
#ifdef DLL_FILE
class _declspec(dllexport) CShZdMessage //导出类CShZdMessage
#else
class _declspec(dllimport) CShZdMessage //导入类CShZdMessage
#endif
{
public:
CShZdMessage(void);
~CShZdMessage(void);
bool SetTag(const int tag,const char* value);
char* GetString(int tag);
bool SetAllRead(int read);//设置所有信息结构体为已读或未读
const char* GetMesgType();
bool SetMsgType(const char *msgType);
string GetAllString();//返回所有的字符串
private:
map<int,string> MsgBody;//信息体
};
#endif

Binary file not shown.

View File

@ -0,0 +1,60 @@
//==================================================================================
//下列 ifdef 块是创建使从 DLL 导出更简单的
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 SHZDTRADELIB_EXPORTS
// 符号编译的。在使用此 DLL 的
// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
// SHZDTRADELIB_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
// 符号视为是被导出的。
// 向少中 2013-03-22
//===================================================================================
#pragma once
#include "ShZdMessage.h"
#ifdef SHZDTRADELIB_EXPORTS
#define SHZDTRADELIB_API __declspec(dllexport)
#else
#define SHZDTRADELIB_API __declspec(dllimport)
#endif
#ifdef __cplusplus
//===================================================================================
// 对外导出的接口
//===================================================================================
//接收信息的虚类
class SHZDTRADELIB_API IShZdTradeOutLib
{
public:
virtual int OnReceiveTradeInfo(const CShZdMessage * re)=0;
virtual int OnReceiveMarketInfo(const CShZdMessage * re)=0;
virtual int OnReceiveErrorInfo(int errorCode,const char* re)=0;
};
typedef IShZdTradeOutLib* IShZdTradeOutLibHandler;
//发送信息的虚类
class SHZDTRADELIB_API IShZdTradeInLib
{
public:
virtual void Release() = 0;
virtual int InitShZdServer()=0;//初始化服务器
virtual int RegisterFront(const char *pszFrontAddress,int portNum)=0; //连接前置服务器
virtual int RegisterMarket(const char *pszMarketAddress,int portNum)=0;//连接行情服务器
virtual int ShZdSendInfoToTrade(const CShZdMessage *send)=0; //向前置服务器发送交易请求
virtual int ShZdSendInfoToMarket(const CShZdMessage *send)=0;//向行情服务器发送行情请求
virtual int RegisterOutLib(IShZdTradeOutLibHandler handler)=0;
};
typedef IShZdTradeInLib* ShZdTradeInLibHandle;
// 此类是从 ShZdTradeLib.dll 导出的
class SHZDTRADELIB_API CShZdTradeLib {
public:
};
#else
#endif
#ifdef __cplusplus
# define EXTERN_C extern "C"
#else
# define EXTERN_C
#endif
EXTERN_C SHZDTRADELIB_API ShZdTradeInLibHandle GetShZdTradeLib(void);

Binary file not shown.

Binary file not shown.

75
vn.shzd/test/test.py Normal file
View File

@ -0,0 +1,75 @@
# encoding: UTF-8
from time import sleep
from vnshzd import *
#----------------------------------------------------------------------
def printDict(d):
""""""
l = d.keys()
l.sort()
for key in l:
print '%s:%s' %(key, d[key])
########################################################################
class TestApi(ShzdApi):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
super(TestApi, self).__init__()
pass
#----------------------------------------------------------------------
def onReceiveErrorInfo(self, errcode, errmsg):
""""""
print '-' * 50
print 'errorcode %s, error msg %s' %(errcode, errmsg)
#----------------------------------------------------------------------
def onReceiveMarketInfo(self, data):
""""""
print '-' * 50
printDict(data)
#----------------------------------------------------------------------
def onReceiveTradeInfo(self, data):
""""""
print '-' * 50
printDict(data)
if __name__ == '__main__':
api = TestApi()
# 初始化连接
api.initShZdServer()
# 注册前置机地址
print api.registerFront('222.73.119.230', 7003)
print api.registerMarket('222.73.119.230', 9003)
# 登录
sleep(1)
data = {}
data['msgtype'] = 'A'
data['12'] = 'demo000604'
data['16'] = '888888'
api.shzdSendInfoToTrade(data)
# 订阅行情
sleep(1)
data = {}
data['msgtype'] = 'MA'
data['11'] = '00010337'
data['201'] = '+'
data['307'] = "CME,6J1609"
api.shzdSendInfoToMarket(data)
raw_input()

BIN
vn.shzd/test/vnshzd.pyd Normal file

Binary file not shown.

View File

@ -0,0 +1,48 @@
========================================================================
DYNAMIC LINK LIBRARY : vnshzd Project Overview
========================================================================
AppWizard has created this vnshzd DLL for you.
This file contains a summary of what you will find in each of the files that
make up your vnshzd application.
vnshzd.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.
vnshzd.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).
vnshzd.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 vnshzd.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
// vnshzd.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,362 @@
// vnctpmd.cpp : 定义 DLL 应用程序的导出函数。
//
#include "stdafx.h"
#include "vnshzd.h"
///-------------------------------------------------------------------------------------
///C++的回调函数将数据保存到队列中
///-------------------------------------------------------------------------------------
int ShzdApi::OnReceiveTradeInfo(const CShZdMessage * re)
{
if (re)
{
CShZdMessage *msg = new CShZdMessage();
*msg = *re;
Task *task = new Task();
task->task_name = ONRECEIVETRADEINFO;
task->task_data = msg;
this->task_queue.push(task);
}
return 0;
};
int ShzdApi::OnReceiveMarketInfo(const CShZdMessage * re)
{
if (re)
{
CShZdMessage *msg = new CShZdMessage();
*msg = *re;
Task *task = new Task();
task->task_name = ONRECEIVEMARKETINFO;
task->task_data = msg;
this->task_queue.push(task);
}
return 0;
};
int ShzdApi::OnReceiveErrorInfo(int errorCode, const char* re)
{
Task *task = new Task();
task->task_name = ONRECEIVEERRORINFO;
task->task_errcode = errorCode;
task->task_errmsg = string(re);
this->task_queue.push(task);
return 0;
};
///-------------------------------------------------------------------------------------
///工作线程从队列中取出数据转化为python对象后进行推送
///-------------------------------------------------------------------------------------
void ShzdApi::processTask()
{
while (1)
{
Task *task = this->task_queue.wait_and_pop();
switch (task->task_name)
{
case ONRECEIVETRADEINFO:
{
this->processTradeInfo(task);
break;
}
case ONRECEIVEMARKETINFO:
{
this->processMarketInfo(task);
break;
}
case ONRECEIVEERRORINFO:
{
this->processErrorInfo(task);
break;
}
};
}
};
void ShzdApi::processTradeInfo(Task* task)
{
PyLock lock;
dict data;
CShZdMessage *tr = (CShZdMessage*)task->task_data;
//读取信息类型
string type = tr->GetMesgType();
data["msgtype"] = type;
//读取具体数据
string allstr = tr->GetAllString();
vector<string> strvector;
boost::split(strvector, allstr, boost::is_any_of(",")); //首先基于","把字符串分解
for (int i = 0; i < strvector.size(); i++) //遍历上一步分解的段落,再用"="分解每段
{
string temp = strvector[i];
if (temp.find("=") != string::npos) //忽略没有"="的段落
{
vector<string> tempvector;
boost::split(tempvector, temp, boost::is_any_of("="));
data[tempvector[0]] = tempvector[1];
}
}
this->onReceiveTradeInfo(data);
delete task->task_data;
delete task;
};
void ShzdApi::processMarketInfo(Task* task)
{
PyLock lock;
dict data;
CShZdMessage *tr = (CShZdMessage*)task->task_data;
//读取信息类型
string type = tr->GetMesgType();
data["msgtype"] = type;
//读取具体数据
string allstr = tr->GetAllString();
vector<string> strvector;
boost::split(strvector, allstr, boost::is_any_of(",")); //首先基于","把字符串分解
for (int i = 0; i < strvector.size(); i++) //遍历上一步分解的段落,再用"="分解每段
{
string temp = strvector[i];
if (temp.find("=") != string::npos) //忽略没有"="的段落
{
vector<string> tempvector;
boost::split(tempvector, temp, boost::is_any_of("="));
data[tempvector[0]] = tempvector[1];
}
}
this->onReceiveTradeInfo(data);
delete task->task_data;
delete task;
};
void ShzdApi::processErrorInfo(Task* task)
{
PyLock lock;
this->onReceiveErrorInfo(task->task_errcode, task->task_errmsg);
delete task;
};
///-------------------------------------------------------------------------------------
///主动函数
///-------------------------------------------------------------------------------------
void ShzdApi::release()
{
this->api->Release();
};
int ShzdApi::initShZdServer()
{
this->api = GetShZdTradeLib();
int n = this->api->InitShZdServer();
this->api->RegisterOutLib(this);
return n;
};
int ShzdApi::registerFront(string address, int port)
{
return this->api->RegisterFront(address.c_str(), port);
};
int ShzdApi::registerMarket(string address, int port)
{
return this->api->RegisterMarket(address.c_str(), port);
};
int ShzdApi::shzdSendInfoToTrade(dict data)
{
CShZdMessage msg = CShZdMessage();
//插入信息类型
if (data.has_key("msgtype"))
{
object msgtype = data["msgtype"];
extract<string> x(msgtype);
if (x.check())
{
string typestr = x();
msg.SetMsgType(typestr.c_str());
}
}
//插入字段
boost::python::list keyList = data.keys();
boost::python::list valueList = data.values();
for (int n = 0; n < len(keyList); n++)
{
//声明
int keyint = 0;
string valuestr = "";
//获取整数型的key
object key = keyList[n];
extract<string> x1(key);
if (x1.check())
{
string keystr = x1();
stringstream ss;
ss << keystr;
ss >> keyint;
}
//获取字符串的value
object value = valueList[n];
extract<string> x2(value);
if (x2.check())
{
valuestr = x2();
}
//添加到msg中
msg.SetTag(keyint, valuestr.c_str());
}
return this->api->ShZdSendInfoToTrade(&msg);
};
int ShzdApi::shzdSendInfoToMarket(dict data)
{
CShZdMessage msg = CShZdMessage();
//插入信息类型
if (data.has_key("msgtype"))
{
object msgtype = data["msgtype"];
extract<string> x(msgtype);
if (x.check())
{
string typestr = x();
msg.SetMsgType(typestr.c_str());
}
}
//插入字段
boost::python::list keyList = data.keys();
boost::python::list valueList = data.values();
for (int n = 0; n < len(keyList); n++)
{
//声明
int keyint = 0;
string valuestr = "";
//获取整数型的key
object key = keyList[n];
extract<string> x1(key);
if (x1.check())
{
string keystr = x1();
stringstream ss;
ss << keystr;
ss >> keyint;
}
//获取字符串的value
object value = valueList[n];
extract<string> x2(value);
if (x2.check())
{
valuestr = x2();
}
//添加到msg中
msg.SetTag(keyint, valuestr.c_str());
}
return this->api->ShZdSendInfoToMarket(&msg);
};
///-------------------------------------------------------------------------------------
///Boost.Python封装
///-------------------------------------------------------------------------------------
struct ShzdApiWrap : ShzdApi, wrapper < ShzdApi >
{
virtual void onReceiveTradeInfo(dict data)
{
//以下的try...catch...可以实现捕捉python环境中错误的功能防止C++直接出现原因未知的崩溃
try
{
this->get_override("onReceiveTradeInfo")(data);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onReceiveMarketInfo(dict data)
{
try
{
this->get_override("onReceiveMarketInfo")(data);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
virtual void onReceiveErrorInfo(int errcode, string errmsg)
{
try
{
this->get_override("onReceiveErrorInfo")(errcode, errmsg);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
};
BOOST_PYTHON_MODULE(vnshzd)
{
PyEval_InitThreads(); //导入时运行保证先创建GIL
class_<ShzdApiWrap, boost::noncopyable>("ShzdApi")
.def("release", &ShzdApiWrap::release)
.def("initShZdServer", &ShzdApiWrap::initShZdServer)
.def("registerFront", &ShzdApiWrap::registerFront)
.def("registerMarket", &ShzdApiWrap::registerMarket)
.def("shzdSendInfoToTrade", &ShzdApiWrap::shzdSendInfoToTrade)
.def("shzdSendInfoToMarket", &ShzdApiWrap::shzdSendInfoToMarket)
.def("onReceiveTradeInfo", pure_virtual(&ShzdApiWrap::onReceiveTradeInfo))
.def("onReceiveMarketInfo", pure_virtual(&ShzdApiWrap::onReceiveMarketInfo))
.def("onReceiveErrorInfo", pure_virtual(&ShzdApiWrap::onReceiveErrorInfo))
;
};

View File

@ -0,0 +1,197 @@
//说明部分
//系统
#ifdef WIN32
#include "stdafx.h"
#endif
#include <string>
#include <queue>
#include <vector>
//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/list.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> //任务队列的任务实现
#include <boost/algorithm/string.hpp> //字符串处理功能
//API
#include "ShZdTradeLib.h"
//命名空间
using namespace std;
using namespace boost::python;
using namespace boost;
//常量
#define ONRECEIVETRADEINFO 1
#define ONRECEIVEMARKETINFO 2
#define ONRECEIVEERRORINFO 3
///-------------------------------------------------------------------------------------
///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; //回调函数名称对应的常量
void* task_data; //数据结构指针
string task_errmsg; //错误字符串
int task_errcode; //错误代码
};
///线程安全的队列
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; //返回该任务
}
};
///-------------------------------------------------------------------------------------
///C++ SPI的回调函数方法实现
///-------------------------------------------------------------------------------------
//API的继承实现
class ShzdApi : public IShZdTradeOutLib
{
private:
IShZdTradeInLib *api; //API对象
thread *task_thread; //工作线程指针向python中推送数据
ConcurrentQueue<Task*> task_queue; //任务队列
public:
ShzdApi()
{
function0<void> f = boost::bind(&ShzdApi::processTask, this);
thread t(f);
this->task_thread = &t;
};
~ShzdApi()
{
};
//-------------------------------------------------------------------------------------
//API回调函数
//-------------------------------------------------------------------------------------
virtual int OnReceiveTradeInfo(const CShZdMessage * re);
virtual int OnReceiveMarketInfo(const CShZdMessage * re);
virtual int OnReceiveErrorInfo(int errorCode, const char* re);
//-------------------------------------------------------------------------------------
//task任务
//-------------------------------------------------------------------------------------
void processTask();
void processTradeInfo(Task *task);
void processMarketInfo(Task *task);
void processErrorInfo(Task *task);
//-------------------------------------------------------------------------------------
//data回调函数的数据字典
//error回调函数的错误字典
//id请求id
//last是否为最后返回
//i整数
//-------------------------------------------------------------------------------------
virtual void onReceiveTradeInfo(dict data){};
virtual void onReceiveMarketInfo(dict data){};
virtual void onReceiveErrorInfo(int errcode, string errmsg){};
//-------------------------------------------------------------------------------------
//req:主动函数的请求字典
//-------------------------------------------------------------------------------------
void release();
int initShZdServer();
int registerFront(string address, int port);
int registerMarket(string address, int port);
int shzdSendInfoToTrade(dict data);
int shzdSendInfoToMarket(dict data);
};

View File

@ -0,0 +1,128 @@
# encoding: UTF-8
__author__ = u'用Python的交易员'
# C++和python类型的映射字典
type_dict = {
'int': 'int',
'char': 'string',
'double': 'float',
'short': 'int',
'XTP_EXCHANGE_TYPE': 'int'
}
#----------------------------------------------------------------------
def process_line(line):
"""处理每行"""
# 注释
if line[:3] == '///': # 注释
py_line = process_comment(line)
# 枚举
elif 'enum' in line:
py_line = process_enum(line)
# 常量
elif '#define' in line:
py_line = process_define(line)
# 类型定义
elif 'typedef' in line:
py_line = process_typedef(line)
# 空行
elif line == '\n':
py_line = line
# 其他忽略
else:
py_line = ''
return py_line
#----------------------------------------------------------------------
def process_enum(line):
"""处理枚举"""
content = line.replace('\n', '').split(' ')
type_ = 'int'
keyword = content[1]
py_line = 'typedefDict["%s"] = "%s"\n' % (keyword, type_)
return py_line
#----------------------------------------------------------------------
def process_comment(line):
"""处理注释"""
py_line = line.replace('/', '#')
return py_line
#----------------------------------------------------------------------
def process_typedef(line):
"""处理类型定义"""
content = line.split(' ')
type_ = type_dict[content[1]]
keyword = content[2]
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)
py_line = '%s = %s' %(constant, value)
else:
py_line = ''
return py_line
#----------------------------------------------------------------------
def replaceTabs(f):
"""把Tab用4个空格替代"""
l = []
for line in f:
line.replace('\t', ' ')
l.append(line)
return l
#----------------------------------------------------------------------
def main():
"""主函数"""
fcpp = open('xtp_api_data_type.h','r')
fpy = open('xtp_data_type.py', 'w')
fpy.write('# encoding: UTF-8\n')
fpy.write('\n')
fpy.write('typedefDict = {}\n')
fpy.write('\n')
lcpp = replaceTabs(fcpp)
for n, line in enumerate(lcpp):
py_line = process_line(line)
if py_line:
fpy.write(py_line.decode('gbk').encode('utf-8'))
fcpp.close()
fpy.close()
print u'data_type.py生成过程完成'
if __name__ == '__main__':
main()

View File

@ -0,0 +1,295 @@
# encoding: UTF-8
__author__ = 'CHENXY'
from string import join
from lts_struct import structDict
def processCallBack(line):
orignalLine = line
line = line.replace('\tvirtual 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:
cbArgsTypeList.append(content[0]) # 参数类型列表
cbArgsValueList.append(content[1]) # 参数数据列表
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, 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, int id, bool last)\n'
override_line = '("on' + cbName[2:] + '")(error, id, last);\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('\tvirtual void ', 'void ' + apiName + '::')
funcline = funcline.replace('{};', '')
ftask.write(funcline)
ftask.write('{\n')
ftask.write("\tTask* task = new 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 'RspInfoField' in type_:
ftask.write("\n")
ftask.write("\tif (pRspInfo)\n")
ftask.write("\t{\n")
ftask.write("\t\t" + type_ + ' *task_error = new ' + type_ + '();\n')
ftask.write("\t\t" + '*task_error = ' + cbArgsValueList[i] + ';\n')
ftask.write("\t\ttask->task_error = task_error;\n")
ftask.write("\t}\n")
ftask.write("\n")
else:
ftask.write("\n")
ftask.write("\tif (" + cbArgsValueList[i][1:] + ")\n")
ftask.write("\t{\n")
ftask.write("\t\t" + type_ + ' *task_data = new ' + type_ + '();\n')
ftask.write("\t\t" + '*task_data = ' + cbArgsValueList[i] + ';\n')
ftask.write("\t\ttask->task_data = task_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 'RspInfoField' in type_:
fprocess.write("\t"+ "dict error;\n")
fprocess.write("\tif (task->task_error)\n")
fprocess.write("\t{\n")
fprocess.write("\t\t"+ type_ + ' *task_error = (' + type_ + '*) task->task_error;\n')
struct = structDict[type_]
for key in struct.keys():
fprocess.write("\t\t"+ 'error["' + key + '"] = task_error->' + key + ';\n')
fprocess.write("\t\tdelete task->task_error;\n")
fprocess.write("\t}\n")
fprocess.write("\n")
onArgsList.append('error')
elif type_ in structDict:
fprocess.write("\t"+ "dict data;\n")
fprocess.write("\tif (task->task_data)\n")
fprocess.write("\t{\n")
fprocess.write("\t\t"+ type_ + ' *task_data = (' + type_ + '*) task->task_data;\n')
struct = structDict[type_]
for key in struct.keys():
fprocess.write("\t\t"+ 'data["' + key + '"] = task_data->' + key + ';\n')
fprocess.write("\t\tdelete task->task_data;\n")
fprocess.write("\t}\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('\tdelete task;\n')
fprocess.write("};\n")
fprocess.write("\n")
def processFunction(line):
line = line.replace('\tvirtual 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) > 1:
fcArgsTypeList.append(content[0]) # 参数类型列表
fcArgsValueList.append(content[1]) # 参数数据列表
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 MdApi::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 == '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('SecurityFtdcMdApi.h', 'r')
ftask = open('lts_md_task.cpp', 'w')
fprocess = open('lts_md_process.cpp', 'w')
ffunction = open('lts_md_function.cpp', 'w')
fdefine = open('lts_md_define.cpp', 'w')
fswitch = open('lts_md_switch.cpp', 'w')
fheaderprocess = open('lts_md_header_process.h', 'w')
fheaderon = open('lts_md_header_on.h', 'w')
fheaderfunction = open('lts_md_header_function.h', 'w')
fwrap = open('lts_md_wrap.cpp', 'w')
define_count = 1
for line in fcpp:
if "\tvirtual void On" in line:
processCallBack(line)
elif "\tvirtual int" in line:
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,295 @@
# encoding: UTF-8
__author__ = 'CHENXY'
from string import join
from lts_struct import structDict
def processCallBack(line):
orignalLine = line
line = line.replace('\tvirtual 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:
cbArgsTypeList.append(content[0]) # 参数类型列表
cbArgsValueList.append(content[1]) # 参数数据列表
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, 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, int id, bool last)\n'
override_line = '("on' + cbName[2:] + '")(error, id, last);\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('\tvirtual void ', 'void ' + apiName + '::')
funcline = funcline.replace('{};', '')
ftask.write(funcline)
ftask.write('{\n')
ftask.write("\tTask* task = new 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 'RspInfoField' in type_:
ftask.write("\n")
ftask.write("\tif (pRspInfo)\n")
ftask.write("\t{\n")
ftask.write("\t\t" + type_ + ' *task_error = new ' + type_ + '();\n')
ftask.write("\t\t" + '*task_error = ' + cbArgsValueList[i] + ';\n')
ftask.write("\t\ttask->task_error = task_error;\n")
ftask.write("\t}\n")
ftask.write("\n")
else:
ftask.write("\n")
ftask.write("\tif (" + cbArgsValueList[i][1:] + ")\n")
ftask.write("\t{\n")
ftask.write("\t\t" + type_ + ' *task_data = new ' + type_ + '();\n')
ftask.write("\t\t" + '*task_data = ' + cbArgsValueList[i] + ';\n')
ftask.write("\t\ttask->task_data = task_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 'RspInfoField' in type_:
fprocess.write("\t"+ "dict error;\n")
fprocess.write("\tif (task->task_error)\n")
fprocess.write("\t{\n")
fprocess.write("\t\t"+ type_ + ' *task_error = (' + type_ + '*) task->task_error;\n')
struct = structDict[type_]
for key in struct.keys():
fprocess.write("\t\t"+ 'error["' + key + '"] = task_error->' + key + ';\n')
fprocess.write("\t\tdelete task->task_error;\n")
fprocess.write("\t}\n")
fprocess.write("\n")
onArgsList.append('error')
elif type_ in structDict:
fprocess.write("\t"+ "dict data;\n")
fprocess.write("\tif (task->task_data)\n")
fprocess.write("\t{\n")
fprocess.write("\t\t"+ type_ + ' *task_data = (' + type_ + '*) task->task_data;\n')
struct = structDict[type_]
for key in struct.keys():
fprocess.write("\t\t"+ 'data["' + key + '"] = task_data->' + key + ';\n')
fprocess.write("\t\tdelete task->task_data;\n")
fprocess.write("\t}\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('\tdelete task;\n')
fprocess.write("};\n")
fprocess.write("\n")
def processFunction(line):
line = line.replace('\tvirtual 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) > 1:
fcArgsTypeList.append(content[0]) # 参数类型列表
fcArgsValueList.append(content[1]) # 参数数据列表
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 QryApi::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 == '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 = 'QryApi'
fcpp = open('SecurityFtdcQueryApi.h', 'r')
ftask = open('lts_qry_task.cpp', 'w')
fprocess = open('lts_qry_process.cpp', 'w')
ffunction = open('lts_qry_function.cpp', 'w')
fdefine = open('lts_qry_define.cpp', 'w')
fswitch = open('lts_qry_switch.cpp', 'w')
fheaderprocess = open('lts_qry_header_process.h', 'w')
fheaderon = open('lts_qry_header_on.h', 'w')
fheaderfunction = open('lts_qry_header_function.h', 'w')
fwrap = open('lts_qry_wrap.cpp', 'w')
define_count = 1
for line in fcpp:
if "\tvirtual void On" in line:
processCallBack(line)
elif "\tvirtual int" in line:
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,76 @@
# encoding: UTF-8
__author__ = 'CHENXY'
from xtp_data_type import *
type_dict = {
'uint64_t': 'int',
'uint32_t': 'int',
'int64_t': 'int',
'char': 'string',
'double': 'float'
}
typedefDict.update(type_dict)
def main():
"""主函数"""
fcpp = open('xoms_api_struct.h', 'r')
fpy = open('xtp_struct_oms.py', 'w')
fpy.write('# encoding: UTF-8\n')
fpy.write('\n')
fpy.write('structDict = {}\n')
fpy.write('\n')
for line in 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 ' ' == line[0:4] or '\t' == line[0]:
content = line.split(' ')
content = [k for k in content if k]
print content
typedef = content[0].replace('\t', '')
type_ = typedefDict[typedef]
variable = content[1]
variable = variable.replace(';', "")
variable = variable.replace('\n', "")
if '[' in variable:
k = variable.index('[')
variable = variable[0:k]
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,76 @@
# encoding: UTF-8
__author__ = 'CHENXY'
from xtp_data_type import *
type_dict = {
'uint64_t': 'int',
'uint32_t': 'int',
'int64_t': 'int',
'char': 'string',
'double': 'float'
}
typedefDict.update(type_dict)
def main():
"""主函数"""
fcpp = open('xquote_api_struct.h', 'r')
fpy = open('xtp_struct_quote.py', 'w')
fpy.write('# encoding: UTF-8\n')
fpy.write('\n')
fpy.write('structDict = {}\n')
fpy.write('\n')
for line in 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 ' ' == line[0:4] or '\t' == line[0]:
content = line.split(' ')
content = [k for k in content if k]
print content
typedef = content[0].replace('\t', '')
type_ = typedefDict[typedef]
variable = content[1]
variable = variable.replace(';', "")
variable = variable.replace('\n', "")
if '[' in variable:
k = variable.index('[')
variable = variable[0:k]
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,295 @@
# encoding: UTF-8
__author__ = 'CHENXY'
from string import join
from lts_struct import structDict
def processCallBack(line):
orignalLine = line
line = line.replace('\tvirtual 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:
cbArgsTypeList.append(content[0]) # 参数类型列表
cbArgsValueList.append(content[1]) # 参数数据列表
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, 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, int id, bool last)\n'
override_line = '("on' + cbName[2:] + '")(error, id, last);\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('\tvirtual void ', 'void ' + apiName + '::')
funcline = funcline.replace('{};', '')
ftask.write(funcline)
ftask.write('{\n')
ftask.write("\tTask* task = new 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 'RspInfoField' in type_:
ftask.write("\n")
ftask.write("\tif (pRspInfo)\n")
ftask.write("\t{\n")
ftask.write("\t\t" + type_ + ' *task_error = new ' + type_ + '();\n')
ftask.write("\t\t" + '*task_error = ' + cbArgsValueList[i] + ';\n')
ftask.write("\t\ttask->task_error = task_error;\n")
ftask.write("\t}\n")
ftask.write("\n")
else:
ftask.write("\n")
ftask.write("\tif (" + cbArgsValueList[i][1:] + ")\n")
ftask.write("\t{\n")
ftask.write("\t\t" + type_ + ' *task_data = new ' + type_ + '();\n')
ftask.write("\t\t" + '*task_data = ' + cbArgsValueList[i] + ';\n')
ftask.write("\t\ttask->task_data = task_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 'RspInfoField' in type_:
fprocess.write("\t"+ "dict error;\n")
fprocess.write("\tif (task->task_error)\n")
fprocess.write("\t{\n")
fprocess.write("\t\t"+ type_ + ' *task_error = (' + type_ + '*) task->task_error;\n')
struct = structDict[type_]
for key in struct.keys():
fprocess.write("\t\t"+ 'error["' + key + '"] = task_error->' + key + ';\n')
fprocess.write("\t\tdelete task->task_error;\n")
fprocess.write("\t}\n")
fprocess.write("\n")
onArgsList.append('error')
elif type_ in structDict:
fprocess.write("\t"+ "dict data;\n")
fprocess.write("\tif (task->task_data)\n")
fprocess.write("\t{\n")
fprocess.write("\t\t"+ type_ + ' *task_data = (' + type_ + '*) task->task_data;\n')
struct = structDict[type_]
for key in struct.keys():
fprocess.write("\t\t"+ 'data["' + key + '"] = task_data->' + key + ';\n')
fprocess.write("\t\tdelete task->task_data;\n")
fprocess.write("\t}\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('\tdelete task;\n')
fprocess.write("};\n")
fprocess.write("\n")
def processFunction(line):
line = line.replace('\tvirtual 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) > 1:
fcArgsTypeList.append(content[0]) # 参数类型列表
fcArgsValueList.append(content[1]) # 参数数据列表
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 TdApi::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 == '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 = 'TdApi'
fcpp = open('SecurityFtdcTraderApi.h', 'r')
ftask = open('lts_td_task.cpp', 'w')
fprocess = open('lts_td_process.cpp', 'w')
ffunction = open('lts_td_function.cpp', 'w')
fdefine = open('lts_td_define.cpp', 'w')
fswitch = open('lts_td_switch.cpp', 'w')
fheaderprocess = open('lts_td_header_process.h', 'w')
fheaderon = open('lts_td_header_on.h', 'w')
fheaderfunction = open('lts_td_header_function.h', 'w')
fwrap = open('lts_td_wrap.cpp', 'w')
define_count = 1
for line in fcpp:
if "\tvirtual void On" in line:
processCallBack(line)
elif "\tvirtual int" in line:
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,161 @@
/////////////////////////////////////////////////////////////////////////
///@author 中泰证券股份有限公司
///@file xtp_quote_api_compatible.h
///@brief 定义行情订阅客户端兼容接口
/////////////////////////////////////////////////////////////////////////
#ifndef _XTP_QUOTE_API_COMPATIBLE_H_
#define _XTP_QUOTE_API_COMPATIBLE_H_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "xtp_api_struct.h"
#include "xtp_api_struct_compatible.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 XTP::API::QuoteCompatibleSpi
*
* \brief
*
* \author
* \date 2015
*/
namespace XTP {
namespace API {
class QuoteCompatibleSpi
{
public:
///当客户端与交易后台通信连接断开时该方法被调用。当发生这个情况后API会自动重新连接客户端可不做处理。
///@param nReason 错误原因
/// 0x1001 网络读失败
/// 0x1002 网络写失败
/// 0x2001 接收心跳超时
/// 0x2002 发送心跳失败
/// 0x2003 收到错误报文
virtual void OnFrontDisconnected(int nReason) {};
///错误应答
///@param pRspInfo 错误信息
///@param nRequestID 请求的ID
///@param bIsLast 是否最后一个
virtual void OnRspError(CXTPRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///登出请求响应
///@param pUserLogout 用户登出的参数
///@param pRspInfo 错误信息
///@param nRequestID 请求的ID
///@param bIsLast 是否最后一个
virtual void OnRspUserLogout(CXTPUserLogoutField *pUserLogout, CXTPRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///订阅行情应答
///@param pSpecificInstrument 详细的合约订阅情况
///@param pRspInfo 错误信息
///@param nRequestID 请求的ID
///@param bIsLast 是否最后一个
virtual void OnRspSubMarketData(CXTPSpecificInstrumentField *pSpecificInstrument, CXTPRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///取消订阅行情应答
///@param pSpecificInstrument 详细的合约取消订阅情况
///@param pRspInfo 错误信息
///@param nRequestID 请求的ID
///@param bIsLast 是否最后一个
virtual void OnRspUnSubMarketData(CXTPSpecificInstrumentField *pSpecificInstrument, CXTPRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
///深度行情通知
///@param pDepthMarketData 行情数据
virtual void OnRtnDepthMarketData(CXTPDepthMarketDataField *pDepthMarketData) {};
};
}
}
/*!
* \class XTP::API::QuoteCompatibleApi
*
* \brief
*
* \author
* \date 2015
*/
namespace XTP {
namespace API {
class MD_API_EXPORT QuoteCompatibleApi
{
public:
///创建QuoteApi
///@param pszFlowPath 存贮订阅信息文件的目录,默认为当前目录
///@return 创建出的UserApi
///modify for udp marketdata
static QuoteCompatibleApi *CreateQuoteApi(const char *pszFlowPath = "");
///删除接口对象本身
///@remark 不再使用本接口对象时,调用该函数删除接口对象
virtual void Release() = 0;
///等待接口线程结束运行
///@return 线程退出代码
virtual int Join() = 0;
///获取当前交易日
///@return 获取到的交易日
///@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(QuoteCompatibleSpi *pSpi) = 0;
///订阅行情。
///@param ppInstrumentID 合约ID
///@param nCount 要订阅/退订行情的合约个数
///@param pExchageID 交易所代码
///@remark 可以一次性订阅同一证券交易所的多个合约
virtual int SubscribeMarketData(char *ppInstrumentID[], int nCount, XTP_EXCHANGE_TYPE pExchageID) = 0;
///退订行情。
///@param ppInstrumentID 合约ID
///@param nCount 要订阅/退订行情的合约个数
///@param pExchageID 交易所代码
///@remark 可以一次性取消订阅同一证券交易所的多个合约
virtual int UnSubscribeMarketData(char *ppInstrumentID[], int nCount, XTP_EXCHANGE_TYPE pExchageID) = 0;
///用户登录请求
///@return 登录是否成功“0”表示登录成功非“0”表示登录出错
///@remark 此函数为同步阻塞式,不需要异步等待登录成功,当函数返回即可进行后续操作
virtual int ReqUserLogin(CXTPReqUserLoginField *pReqUserLoginField, int nRequestID) = 0;
///登出请求
///@return 登出是否成功“0”表示登出成功非“0”表示登出出错
virtual int ReqUserLogout(CXTPUserLogoutField *pUserLogout, int nRequestID) = 0;
protected:
~QuoteCompatibleApi() {};
};
}
}
#endif

View File

@ -0,0 +1,258 @@
/*!
* \file xoms_api_struct.h
* \date 2015/10/23 16:45
*
* \author howellxu
* Contact: user@company.com
*
* \brief
*
* TODO: long description
*
* \note
*/
#ifndef _XOMS_API_STRUCT_H_
#define _XOMS_API_STRUCT_H_
#include "xtp_api_data_type.h"
#define XTP_API_TICKER_LEN 13
#define XTP_API_TICKER_NAME_LEN 48
#define XTP_LOCAL_ORDER_LEN 11
#define XTP_ORDER_EXCH_LEN 17
#define XTP_ORDER_RES_LEN 4
#define XTP_SUBPBUID_LEN 7
#define XTP_BRANCH_PBU_LEN 7
#define XTP_SYS_INSTRUMENT_LEN 24
//=====================客户端接口定义=================================
///新订单请求
struct XTPOrderInsertInfo
{
///XTP系统订单ID
uint64_t order_xtp_id;
///报单引用,由客户自定义
uint32_t order_client_id;
///合约代码 客户端请求不带空格
char ticker[XTP_API_TICKER_LEN];
///交易市场
XTP_MARKET_TYPE market;
///价格
double price;
///止损价(保留字段)
double stop_price;
///数量
int64_t quantity;
///报单价格
XTP_PRICE_TYPE price_type;
///买卖方向
XTP_SIDE_TYPE side;
};
///撤单
struct XTPOrderCancel
{
///XTP系统订单ID
uint64_t order_cancel_xtp_id;
///报单操作引用
uint32_t order_cancel_client_id;
///合约代码
char ticker[XTP_API_TICKER_LEN];
///交易市场
XTP_MARKET_TYPE market;
///操作时间
int64_t action_time;
///报单引用
uint32_t order_client_id;
///操作对象订单的序号
uint64_t order_xtp_id;
};
///撤单失败响应消息
struct XTPOrderCancelInfo
{
///撤单XTPID
uint64_t order_cancel_xtp_id;
///原始订单XTPID
uint64_t order_xtp_id;
};
///报单响应结构体
struct XTPOrderInfo
{
///XTP系统订单ID
uint64_t order_xtp_id;
///报单引用,用户自定义
uint32_t order_client_id;
///报单操作引用,用户自定义
uint32_t order_cancel_client_id;
///撤单在XTP系统中的id
uint64_t order_cancel_xtp_id;
///合约代码
char ticker[XTP_API_TICKER_LEN];
///交易市场
XTP_MARKET_TYPE market;
///价格
double price;
///数量
int64_t quantity;
///报单价格条件
XTP_PRICE_TYPE price_type;
///买卖方向
XTP_SIDE_TYPE side;
///今成交数量
int64_t qty_traded;
///剩余数量
int64_t qty_left;
///委托时间
int64_t insert_time;
///最后修改时间
int64_t update_time;
///撤销时间
int64_t cancel_time;
///成交金额
double trade_amount;
///本地报单编号 OMS生成的单号
char order_local_id[XTP_LOCAL_ORDER_LEN];
///报单状态
XTP_ORDER_STATUS_TYPE order_status;
///报单提交状态
XTP_ORDER_SUBMIT_STATUS_TYPE order_submit_status;
///报单类型
TXTPOrderTypeType order_type;
};
///报单成交结构体
struct XTPTradeReport
{
///XTP系统订单ID
uint64_t order_xtp_id;
///报单引用
uint32_t order_client_id;
///合约代码
char ticker[XTP_API_TICKER_LEN];
///交易市场
XTP_MARKET_TYPE market;
///订单号
uint64_t local_order_id;
///成交编号
uint64_t exec_id;
///价格
double price;
///数量
int64_t quantity;
///成交时间
int64_t trade_time;
///成交金额
double trade_amount;
///成交序号 --回报记录号
uint64_t report_index;
///报单编号 --交易所单号
char order_exch_id[XTP_ORDER_EXCH_LEN];
///成交类型 --成交回报中的执行类型
TXTPTradeTypeType trade_type;
///买卖方向
XTP_SIDE_TYPE side;
///交易所交易员代码
char branch_pbu[XTP_BRANCH_PBU_LEN];
};
//////////////////////////////////////////////////////////////////////////
///报单查询
//////////////////////////////////////////////////////////////////////////
///报单查询请求-条件查询
struct XTPQueryOrderReq
{
///证券代码,可以为空,如果为空,则默认查询时间段内的所有成交回报
char ticker[XTP_API_TICKER_LEN];
///格式为YYYYMMDDHHMMSSsss为0则默认当前交易日0点
int64_t begin_time;
///格式为YYYYMMDDHHMMSSsss为0则默认当前时间
int64_t end_time;
};
///报单查询响应结构体
typedef XTPOrderInfo XTPQueryOrderRsp;
//////////////////////////////////////////////////////////////////////////
///成交回报查询
//////////////////////////////////////////////////////////////////////////
///查询成交报告请求-根据执行编号查询(保留字段)
struct XTPQueryReportByExecIdReq
{
///XTP订单系统ID
uint64_t order_xtp_id;
///成交执行编号
uint64_t exec_id;
};
///查询成交回报请求-查询条件
struct XTPQueryTraderReq
{
///证券代码,可以为空,如果为空,则默认查询时间段内的所有成交回报
char ticker[XTP_API_TICKER_LEN];
///开始时间格式为YYYYMMDDHHMMSSsss为0则默认当前交易日0点
int64_t begin_time;
///结束时间格式为YYYYMMDDHHMMSSsss为0则默认当前时间
int64_t end_time;
};
///成交回报查询响应结构体
typedef XTPTradeReport XTPQueryTradeRsp;
//////////////////////////////////////////////////////////////////////////
///账户资金查询响应结构体
//////////////////////////////////////////////////////////////////////////
struct XTPQueryAssetRsp
{
///总资产
double total_asset;
///可用资金
double buying_power;
///证券资产
double security_asset;
///累计买入成交证券占用资金(保留字段)
double fund_buy_amount;
///累计买入成交交易费用(保留字段)
double fund_buy_fee;
///累计卖出成交证券所得资金(保留字段)
double fund_sell_amount;
///累计卖出成交交易费用(保留字段)
double fund_sell_fee;
};
//////////////////////////////////////////////////////////////////////////
///查询股票持仓情况
//////////////////////////////////////////////////////////////////////////
struct XTPQueryStkPositionRsp
{
///证券代码
char ticker[XTP_API_TICKER_LEN];
///证券名称
char ticker_name[XTP_API_TICKER_NAME_LEN];
///当前持仓
int64_t total_qty;
///可用股份数
int64_t sellable_qty;
///持仓成本
double avg_price;
///浮动盈亏
double unrealized_pnl;
};
#endif //_XOMS_API_STRUCT_H_

View File

@ -0,0 +1,160 @@
/////////////////////////////////////////////////////////////////////////
///@author 中泰证券股份有限公司
///@file xquote_api_struct.h
///@brief 定义行情类相关数据结构
/////////////////////////////////////////////////////////////////////////
#ifndef _XQUOTE_API_STRUCT_H_
#define _XQUOTE_API_STRUCT_H_
#include <stdint.h>
#include "xtp_api_data_type.h"
///指定的合约
typedef struct XTPSpecificTickerStruct
{
///交易所代码
XTP_EXCHANGE_TYPE exchange_id;
///合约代码(不包含交易所信息)例如"600000 "
char ticker[XTP_TICKER_LEN];
} XTPST;
///行情
typedef struct XTPMarketDataStruct
{
// 代码
///交易所代码
XTP_EXCHANGE_TYPE exchange_id;
///合约代码(不包含交易所信息)
char ticker[XTP_TICKER_LEN];
// 股票等价格
///最新价
double last_price;
///昨收盘
double pre_close_price;
///今开盘
double open_price;
///最高价
double high_price;
///最低价
double low_price;
///今收盘
double close_price;
// 期货等数据
///昨持仓量(目前未填写)
double pre_open_interest;
///持仓量(目前未填写)
double open_interest;
///上次结算价(目前未填写)
double pre_settlement_price;
///本次结算价(目前未填写)
double settlement_price;
///涨停板价(目前未填写)
double upper_limit_price;
///跌停板价(目前未填写)
double lower_limit_price;
///昨虚实度(目前未填写)
double pre_delta;
///今虚实度(目前未填写)
double curr_delta;
/// 时间类
int64_t data_time;
// 量额数据
///数量
int32_t qty;
///成交金额
double turnover;
///当日均价
double avg_price;
// 买卖盘
///十档申买价
double bid[10];
///十档申卖价
double ask[10];
///十档申买量
int32_t bid_qty[10];
///十档申卖量
int32_t ask_qty[10];
// lts没有包含的数据目前未填写
///成交笔数
int32_t trades_count;
///当前交易状态说明
char ticker_status[8];
///委托买入总量
int32_t total_bid_qty;
///委托卖出总量
int32_t total_ask_qty;
///加权平均委买价格
double ma_bid_price;
///加权平均委卖价格
double ma_ask_price;
///债券加权平均委买价格
double ma_bond_bid_price;
///债券加权平均委卖价格
double ma_bond_ask_price;
///债券到期收益率
double yield_to_maturity;
///ETF净值估值
double iopv;
///ETF申购笔数
int32_t etf_buy_count;
///ETF赎回笔数
int32_t etf_sell_count;
///ETF申购数量
double etf_buy_qty;
///ETF申购金额
double etf_buy_money;
///ETF赎回数量
double etf_sell_qty;
///ETF赎回金额
double etf_sell_money;
///权证执行的总数量
double total_warrant_exec_qty;
///权证跌停价格(元)
double warrant_lower_price;
///权证涨停价格(元)
double warrant_upper_price;
///买入撤单笔数
int32_t cancel_buy_count;
///卖出撤单笔数
int32_t cancel_sell_count;
///买入撤单数量
double cancel_buy_qty;
///卖出撤单数量
double cancel_sell_qty;
///买入撤单金额
double cancel_buy_money;
///卖出撤单金额
double cancel_sell_money;
///买入总笔数
int32_t total_buy_count;
///卖出总笔数
int32_t total_sell_count;
///买入委托成交最大等待时间
int32_t duration_after_buy;
///卖出委托成交最大等待时间
int32_t duration_after_sell;
///买方委托价位数
int32_t num_bid_orders;
///卖方委托价位数
int32_t num_ask_orders;
///成交时间UA3113
int32_t exec_time;
///闭市标志UA103/UA104
char is_market_closed[4];
///合约持仓量UA103
double total_position;
///市盈率1UA103
double pe_ratio1;
///市盈率2UA103
double pe_ratio2;
} XTPMD;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,15 @@
/////////////////////////////////////////////////////////////////////////
///@author 中泰证券股份有限公司
///@file xtp_api_struct.h
///@brief 定义业务数据结构
/////////////////////////////////////////////////////////////////////////
#ifndef _XTP_API_STRUCT_H_
#define _XTP_API_STRUCT_H_
#include "xtp_api_struct_common.h"
#include "xquote_api_struct.h"
#include "xoms_api_struct.h"
#endif // !_XTP_API_STRUCT_H_

View File

@ -0,0 +1,23 @@
/////////////////////////////////////////////////////////////////////////
///@author 中泰证券股份有限公司
///@file xtp_api_struct_common.h
///@brief 定义业务公共数据结构
/////////////////////////////////////////////////////////////////////////
#ifndef _XTP_API_STRUCT_COMMON_H_
#define _XTP_API_STRUCT_COMMON_H_
#include <stdint.h>
#include "xtp_api_data_type.h"
///响应信息
#define XTP_ERR_MSG_LEN 76
typedef struct XTPRspInfoStruct
{
///错误代码
int32_t error_id;
///错误信息
char error_msg[XTP_ERR_MSG_LEN];
} XTPRI;
#endif // !_XTP_API_STRUCT_COMMON_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,158 @@
/////////////////////////////////////////////////////////////////////////
///@author 中泰证券股份有限公司
///@file xtp_quote_api.h
///@brief 定义行情订阅客户端接口
/////////////////////////////////////////////////////////////////////////
#ifndef _XTP_QUOTE_API_H_
#define _XTP_QUOTE_API_H_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "xtp_api_struct.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 XTP::API::QuoteSpi
*
* \brief
*
* \author
* \date 2015
*/
namespace XTP {
namespace API {
class QuoteSpi
{
public:
///当客户端与交易后台通信连接断开时,该方法被调用。
///@remark 保留函数,暂未支持
///@param reason 错误原因
virtual void OnDisconnected(int reason) {};
///错误应答
///@param error_info 错误信息
virtual void OnError(XTPRI *error_info) {};
///订阅行情应答
///@param ticker 详细的合约订阅情况
///@param error_info 订阅合约发生错误时的错误信息
///@param is_last 是否此次订阅的最后一个应答
///@remark 每条订阅的合约均对应一条订阅应答
virtual void OnSubMarketData(XTPST *ticker, XTPRI *error_info, bool is_last) {};
///取消订阅行情应答
///@param ticker 详细的合约取消订阅情况
///@param error_info 错误信息
///@param is_last 是否此次取消订阅的最后一个应答
///@remark 每条取消订阅的合约均对应一条取消订阅应答
virtual void OnUnSubMarketData(XTPST *ticker, XTPRI *error_info, bool is_last) {};
///行情通知
///@param market_data 行情数据
virtual void OnMarketData(XTPMD *market_data) {};
///查询可交易合约应答
///@remark 保留函数,此函数暂未支持
virtual void OnQueryAllTickers() {};
};
}
}
/*!
* \class XTP::API::QuoteApi
*
* \brief
*
* \author
* \date 2015
*/
namespace XTP {
namespace API {
class MD_API_EXPORT QuoteApi
{
public:
///创建QuoteApi
///@param save_file_path (保留字段)存贮订阅信息文件的目录,默认为当前目录
///@return 创建出的UserApi
static QuoteApi *CreateQuoteApi(const char *save_file_path = "");
///删除接口对象本身
///@remark 不再使用本接口对象时,调用该函数删除接口对象
virtual void Release() = 0;
///获取当前交易日
///@return 获取到的交易日
///@remark 只有登录成功后,才能得到正确的交易日
virtual const char *GetTradingDay() = 0;
///注册回调接口
///@param spi 派生自回调接口类的实例
virtual void RegisterSpi(QuoteSpi *spi) = 0;
///订阅行情。
///@return 订阅接口调用是否成功“0”表示接口调用成功非“0”表示接口调用出错
///@param ticker 合约ID数组
///@param count 要订阅/退订行情的合约个数
///@param exchage_id 交易所代码
///@remark 可以一次性订阅同一证券交易所的多个合约
virtual int SubscribeMarketData(char *ticker[], int count, XTP_EXCHANGE_TYPE exchage_id) = 0;
///退订行情。
///@return 取消订阅接口调用是否成功“0”表示接口调用成功非“0”表示接口调用出错
///@param ticker 合约ID数组
///@param count 要订阅/退订行情的合约个数
///@param exchage_id 交易所代码
///@remark 可以一次性取消订阅同一证券交易所的多个合约
virtual int UnSubscribeMarketData(char *ticker[], int count, XTP_EXCHANGE_TYPE exchage_id) = 0;
///用户登录请求
///@return 登录是否成功“0”表示登录成功“-1”表示连接服务器出错“-2”表示已存在连接不允许重复登录如果需要重连请先logout“-3”表示输入有错误
///@param ip 服务器地址
///@param port 服务器端口号
///@param user 登陆用户名
///@param password 登陆密码
///@param sock_type “1”代表TCP“2”代表UDP目前暂时只支持TCP
///@remark 此函数为同步阻塞式,不需要异步等待登录成功,当函数返回即可进行后续操作
virtual int Login(const char* ip, int port, const char* user, const char* password, XTP_PROTOCOL_TYPE sock_type) = 0;
///登出请求
///@return 登出是否成功“0”表示登出成功非“0”表示登出出错
///@remark 此函数为同步阻塞式,不需要异步等待登出,当函数返回即可进行后续操作
virtual int Logout() = 0;
///获取当前交易日可交易合约
///@return 查询是否成功“0”表示查询成功非“0”表示查询不成功
///@param exchage_id 交易所代码
///@remark 此函数暂未支持
virtual int QueryAllTickers(XTP_EXCHANGE_TYPE exchage_id) = 0;
protected:
~QuoteApi() {};
};
}
}
#endif

View File

@ -0,0 +1,262 @@
# encoding: UTF-8
structDict = {}
#新订单请求
XTPOrderInsertInfo = {}
# ///XTP系统订单ID
XTPOrderInsertInfo["order_xtp_id"] = "int"
# ///报单引用,由客户自定义
XTPOrderInsertInfo["order_client_id"] = "int"
# ///合约代码 客户端请求不带空格
XTPOrderInsertInfo["ticker"] = "string"
# ///交易市场
XTPOrderInsertInfo["market"] = "int"
# ///价格
XTPOrderInsertInfo["price"] = "float"
# ///止损价(保留字段)
XTPOrderInsertInfo["stop_price"] = "float"
# ///数量
XTPOrderInsertInfo["quantity"] = "int"
# ///报单价格
XTPOrderInsertInfo["price_type"] = "int"
# ///买卖方向
XTPOrderInsertInfo["side"] = "int"
structDict['XTPOrderInsertInfo'] = XTPOrderInsertInfo
#撤单
XTPOrderCancel = {}
# ///XTP系统订单ID
XTPOrderCancel["order_cancel_xtp_id"] = "int"
# ///报单操作引用
XTPOrderCancel["order_cancel_client_id"] = "int"
# ///合约代码
XTPOrderCancel["ticker"] = "string"
# ///交易市场
XTPOrderCancel["market"] = "int"
# ///操作时间
XTPOrderCancel["action_time"] = "int"
# ///报单引用
XTPOrderCancel["order_client_id"] = "int"
# ///操作对象订单的序号
XTPOrderCancel["order_xtp_id"] = "int"
structDict['XTPOrderCancel'] = XTPOrderCancel
#撤单失败响应消息
XTPOrderCancelInfo = {}
# ///撤单XTPID
XTPOrderCancelInfo["order_cancel_xtp_id"] = "int"
# ///原始订单XTPID
XTPOrderCancelInfo["order_xtp_id"] = "int"
structDict['XTPOrderCancelInfo'] = XTPOrderCancelInfo
#报单响应结构体
XTPOrderInfo = {}
# ///XTP系统订单ID
XTPOrderInfo["order_xtp_id"] = "int"
#报单引用,用户自定义
XTPOrderInfo["order_client_id"] = "int"
# ///报单操作引用,用户自定义
XTPOrderInfo["order_cancel_client_id"] = "int"
# ///撤单在XTP系统中的id
XTPOrderInfo["order_cancel_xtp_id"] = "int"
#合约代码
XTPOrderInfo["ticker"] = "string"
#交易市场
XTPOrderInfo["market"] = "int"
#价格
XTPOrderInfo["price"] = "float"
#数量
XTPOrderInfo["quantity"] = "int"
#报单价格条件
XTPOrderInfo["price_type"] = "int"
#买卖方向
XTPOrderInfo["side"] = "int"
#今成交数量
XTPOrderInfo["qty_traded"] = "int"
#剩余数量
XTPOrderInfo["qty_left"] = "int"
#委托时间
XTPOrderInfo["insert_time"] = "int"
#最后修改时间
XTPOrderInfo["update_time"] = "int"
#撤销时间
XTPOrderInfo["cancel_time"] = "int"
#成交金额
XTPOrderInfo["trade_amount"] = "float"
#本地报单编号 OMS生成的单号
XTPOrderInfo["order_local_id"] = "string"
#报单状态
XTPOrderInfo["order_status"] = "int"
#报单提交状态
XTPOrderInfo["order_submit_status"] = "int"
#报单类型
XTPOrderInfo["order_type"] = "char"
structDict['XTPOrderInfo'] = XTPOrderInfo
#报单成交结构体
XTPTradeReport = {}
# ///XTP系统订单ID
XTPTradeReport["order_xtp_id"] = "int"
# ///报单引用
XTPTradeReport["order_client_id"] = "int"
# ///合约代码
XTPTradeReport["ticker"] = "string"
# ///交易市场
XTPTradeReport["market"] = "int"
# ///订单号
XTPTradeReport["local_order_id"] = "int"
# ///成交编号
XTPTradeReport["exec_id"] = "int"
# ///价格
XTPTradeReport["price"] = "float"
# ///数量
XTPTradeReport["quantity"] = "int"
# ///成交时间
XTPTradeReport["trade_time"] = "int"
# ///成交金额
XTPTradeReport["trade_amount"] = "float"
# ///成交序号 --回报记录号
XTPTradeReport["report_index"] = "int"
# ///报单编号 --交易所单号
XTPTradeReport["order_exch_id"] = "string"
# ///成交类型 --成交回报中的执行类型
XTPTradeReport["trade_type"] = "char"
# ///买卖方向
XTPTradeReport["side"] = "int"
# ///交易所交易员代码
XTPTradeReport["branch_pbu"] = "string"
structDict['XTPTradeReport'] = XTPTradeReport
#///////////////////////////////////////////////////////////////////////
#报单查询
#///////////////////////////////////////////////////////////////////////
#报单查询请求-条件查询
XTPQueryOrderReq = {}
# ///证券代码,可以为空,如果为空,则默认查询时间段内的所有成交回报
XTPQueryOrderReq["ticker"] = "string"
# ///格式为YYYYMMDDHHMMSSsss为0则默认当前交易日0点
XTPQueryOrderReq["begin_time"] = "int"
# ///格式为YYYYMMDDHHMMSSsss为0则默认当前时间
XTPQueryOrderReq["end_time"] = "int"
structDict['XTPQueryOrderReq'] = XTPQueryOrderReq
#报单查询响应结构体
#///////////////////////////////////////////////////////////////////////
#成交回报查询
#///////////////////////////////////////////////////////////////////////
#查询成交报告请求-根据执行编号查询(保留字段)
XTPQueryReportByExecIdReq = {}
# ///XTP订单系统ID
XTPQueryReportByExecIdReq["order_xtp_id"] = "int"
# ///成交执行编号
XTPQueryReportByExecIdReq["exec_id"] = "int"
structDict['XTPQueryReportByExecIdReq'] = XTPQueryReportByExecIdReq
#查询成交回报请求-查询条件
XTPQueryTraderReq = {}
# ///证券代码,可以为空,如果为空,则默认查询时间段内的所有成交回报
XTPQueryTraderReq["ticker"] = "string"
# ///开始时间格式为YYYYMMDDHHMMSSsss为0则默认当前交易日0点
XTPQueryTraderReq["begin_time"] = "int"
# ///结束时间格式为YYYYMMDDHHMMSSsss为0则默认当前时间
XTPQueryTraderReq["end_time"] = "int"
structDict['XTPQueryTraderReq'] = XTPQueryTraderReq
#成交回报查询响应结构体
#///////////////////////////////////////////////////////////////////////
#账户资金查询响应结构体
#///////////////////////////////////////////////////////////////////////
XTPQueryAssetRsp = {}
#总资产
XTPQueryAssetRsp["total_asset"] = "float"
# ///可用资金
XTPQueryAssetRsp["buying_power"] = "float"
#证券资产
XTPQueryAssetRsp["security_asset"] = "float"
# ///累计买入成交证券占用资金(保留字段)
XTPQueryAssetRsp["fund_buy_amount"] = "float"
# ///累计买入成交交易费用(保留字段)
XTPQueryAssetRsp["fund_buy_fee"] = "float"
# ///累计卖出成交证券所得资金(保留字段)
XTPQueryAssetRsp["fund_sell_amount"] = "float"
# ///累计卖出成交交易费用(保留字段)
XTPQueryAssetRsp["fund_sell_fee"] = "float"
structDict['XTPQueryAssetRsp'] = XTPQueryAssetRsp
#///////////////////////////////////////////////////////////////////////
#查询股票持仓情况
#///////////////////////////////////////////////////////////////////////
XTPQueryStkPositionRsp = {}
# ///证券代码
XTPQueryStkPositionRsp["ticker"] = "string"
# ///证券名称
XTPQueryStkPositionRsp["ticker_name"] = "string"
# ///当前持仓
XTPQueryStkPositionRsp["total_qty"] = "int"
# ///可用股份数
XTPQueryStkPositionRsp["sellable_qty"] = "int"
# ///持仓成本
XTPQueryStkPositionRsp["avg_price"] = "float"
# ///浮动盈亏
XTPQueryStkPositionRsp["unrealized_pnl"] = "float"
structDict['XTPQueryStkPositionRsp'] = XTPQueryStkPositionRsp

View File

@ -0,0 +1,20 @@
# encoding: UTF-8
structDict = {}
#//////////////////////////////////////////////////////////////////////
#@author 中泰证券股份有限公司
#@file xquote_api_struct.h
#@brief 定义行情类相关数据结构
#//////////////////////////////////////////////////////////////////////
#指定的合约
struct = {}
# ///交易所代码
struct["exchange_id"] = "int"
# ///合约代码(不包含交易所信息)例如"600000 "

View File

@ -0,0 +1,206 @@
/////////////////////////////////////////////////////////////////////////
///@author 中泰证券股份有限公司
///@file xtp_trader_api.h
///@brief 定义客户端交易接口
/////////////////////////////////////////////////////////////////////////
#ifndef _XTP_TRADER_API_H_
#define _XTP_TRADER_API_H_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "xtp_api_struct.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 XTP::API::TraderSpi
*
* \brief
*
* \author
* \date 2015
*/
namespace XTP {
namespace API {
class TraderSpi
{
public:
///当客户端与交易后台通信连接断开时,该方法被调用。
///@remark 保留函数,暂未支持
///@param reason 错误原因
virtual void OnDisconnected(int reason) {};
///错误应答
///@param error_info 具体的错误代码和错误信息
virtual void OnError(XTPRI *error_info) {};
///报单通知
///@param order_info 订单响应具体信息
///@param error_info 订单被拒绝或者发生错误时错误代码和错误信息
///@remark 每次订单状态更新时,都会被调用
virtual void OnOrderEvent(XTPOrderInfo *order_info, XTPRI *error_info) {};
///成交通知
///@param trade_info 成交回报的具体信息
///@remark 订单有成交发生的时候,会被调用
virtual void OnTradeEvent(XTPTradeReport *trade_info) {};
///撤单出错响应
///@param cancel_info 撤单具体信息包括撤单单和待撤单的order_xtp_id
///@param error_info 撤单被拒绝或者发生错误时错误代码和错误信息
virtual void OnCancelOrderError(XTPOrderCancelInfo *cancel_info, XTPRI *error_info) {};
///请求查询报单响应
///@param order_info 查询到的报单
///@param error_info 错误信息
///@param request_id 此消息响应函数对应的请求ID
///@param is_last 此消息响应函数是否为request_id这条请求所对应的最后一个响应
///@remark 由于支持分时段查询,一个查询请求可能对应多个响应
virtual void OnQueryOrder(XTPQueryOrderRsp *order_info, XTPRI *error_info, int request_id, bool is_last) {};
///请求查询成交响应
///@param trade_info 查询到的成交回报
///@param error_info 错误信息
///@param request_id 此消息响应函数对应的请求ID
///@param is_last 此消息响应函数是否为request_id这条请求所对应的最后一个响应
///@remark 由于支持分时段查询,一个查询请求可能对应多个响应
virtual void OnQueryTrade(XTPQueryTradeRsp *trade_info, XTPRI *error_info, int request_id, bool is_last) {};
///请求查询投资者持仓响应
///@param position 查询到的持仓情况
///@param error_info 错误信息
///@param request_id 此消息响应函数对应的请求ID
///@param is_last 此消息响应函数是否为request_id这条请求所对应的最后一个响应
///@remark 由于用户可能持有多个股票,一个查询请求可能对应多个响应
virtual void OnQueryPosition(XTPQueryStkPositionRsp *position, XTPRI *error_info, int request_id, bool is_last) {};
///请求查询资金账户响应
virtual void OnQueryAsset(XTPQueryAssetRsp *asset, XTPRI *error_info, int request_id, bool is_last) {};
};
}
}
/*!
* \class XTP::API::TraderApi
*
* \brief
*
* \author
* \date 2015
*/
namespace XTP {
namespace API {
class TRADER_API_EXPORT TraderApi
{
public:
///创建TraderApi
///@param save_file_path (保留字段)存贮订阅信息文件的目录,默认为当前目录
///@return 创建出的UserApi
static TraderApi *CreateTraderApi(const char *save_file_path = "");
///删除接口对象本身
///@remark 不再使用本接口对象时,调用该函数删除接口对象
virtual void Release() = 0;
///获取当前交易日
///@return 获取到的交易日
///@remark 只有登录成功后,才能得到正确的交易日
virtual const char *GetTradingDay() = 0;
///注册回调接口
///@param spi 派生自回调接口类的实例
virtual void RegisterSpi(TraderSpi *spi) = 0;
///用户登录请求
///@return 登录是否成功“0”表示登录成功“-1”表示连接服务器出错“-2”表示已存在连接不允许重复登录如果需要重连请先logout
///@param ip 服务器地址
///@param port 服务器端口号
///@param user 登录用户名
///@param password 登录密码
///@param sock_type “1”代表TCP“2”代表UDP目前暂时只支持TCP
///@param client_id 保留字段客户端id用于区分同一用户的不同连接
///@remark 此函数为同步阻塞式,不需要异步等待登录成功,当函数返回即可进行后续操作
virtual int Login(const char* ip, int port, const char* user, const char* password, XTP_PROTOCOL_TYPE sock_type, int client_id = 0) = 0;
///登出请求
///@return 登出是否成功“0”表示登出成功“-1”表示登出失败
virtual int Logout() = 0;
///报单录入请求
///@return 报单在XTP系统中的ID,如果为0表示报单失败用户需要记录下返回的order_xtp_id
///@param order 报单录入信息
virtual uint64_t InsertOrder(XTPOrderInsertInfo *order) = 0;
///报单操作请求
///@return 撤单单在XTP系统中的ID,如果为0表示撤单失败用户需要记录下返回的order_cancel_xtp_id
///@param order_xtp_id 需要撤销的委托单在XTP系统中的ID
virtual uint64_t CancelOrder(const uint64_t order_xtp_id) = 0;
///根据报单ID请求查询报单
///@return 查询是否成功“0”表示成功非“0”表示出错
///@param order_xtp_id 需要查询的报单在xtp系统中的ID
///@param request_id 用于用户定位查询响应的ID由用户自定义
virtual int QueryOrderByXTPID(const uint64_t order_xtp_id, int request_id) = 0;
///请求查询报单
///@return 查询是否成功“0”表示成功非“0”表示出错
///@param query_param 需要查询的订单相关筛选条件
///@param request_id 用于用户定位查询响应的ID由用户自定义
///@remark 该方法支持分时段查询,如果股票代码为空,则默认查询时间段内的所有报单,否则查询时间段内所有跟股票代码相关的报单
virtual int QueryOrders(const XTPQueryOrderReq *query_param, int request_id) = 0;
///根据委托编号请求查询相关成交
///@return 查询是否成功“0”表示成功非“0”表示出错
///@param order_xtp_id 需要查询的委托编号
///@param request_id 用于用户定位查询响应的ID由用户自定义
///@remark 此函数查询出的结果可能对应多个响应
virtual int QueryTradesByXTPID(const uint64_t order_xtp_id, int request_id) = 0;
///请求查询已成交
///@return 查询是否成功“0”表示成功非“0”表示出错
///@param query_param 需要查询的成交回报筛选条件
///@param request_id 用于用户定位查询响应的ID由用户自定义
///@remark 该方法支持分时段查询,如果股票代码为空,则默认查询时间段内的所有成交回报,否则查询时间段内所有跟股票代码相关的成交回报
virtual int QueryTrades(XTPQueryTraderReq *query_param, int request_id) = 0;
///请求查询投资者持仓
///@return 查询是否成功“0”表示成功非“0”表示出错
///@param ticker 需要查询的持仓股票,可以为空
///@param request_id 用于用户定位查询响应的ID由用户自定义
///@remark 该方法如果用户提供了股票代码,则会查询此股票的持仓信息,如果股票代码为空,则默认查询所有持仓信息
virtual int QueryPosition(const char *ticker, int request_id) = 0;
///请求查询资产
///@return 查询是否成功“0”表示成功非“0”表示出错
///@param request_id 用于用户定位查询响应的ID由用户自定义
virtual int QueryAsset(int request_id) = 0;
protected:
~TraderApi() {};
};
}
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

BIN
vn.xtp/xtpapi/libxbaseD.so Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
vn.xtp/xtpapi/xbaseD.dll Normal file

Binary file not shown.

BIN
vn.xtp/xtpapi/xbaseD.lib Normal file

Binary file not shown.

View File

@ -0,0 +1,258 @@
/*!
* \file xoms_api_struct.h
* \date 2015/10/23 16:45
*
* \author howellxu
* Contact: user@company.com
*
* \brief
*
* TODO: long description
*
* \note
*/
#ifndef _XOMS_API_STRUCT_H_
#define _XOMS_API_STRUCT_H_
#include "xtp_api_data_type.h"
#define XTP_API_TICKER_LEN 13
#define XTP_API_TICKER_NAME_LEN 48
#define XTP_LOCAL_ORDER_LEN 11
#define XTP_ORDER_EXCH_LEN 17
#define XTP_ORDER_RES_LEN 4
#define XTP_SUBPBUID_LEN 7
#define XTP_BRANCH_PBU_LEN 7
#define XTP_SYS_INSTRUMENT_LEN 24
//=====================客户端接口定义=================================
///新订单请求
struct XTPOrderInsertInfo
{
///XTP系统订单ID
uint64_t order_xtp_id;
///报单引用,由客户自定义
uint32_t order_client_id;
///合约代码 客户端请求不带空格
char ticker[XTP_API_TICKER_LEN];
///交易市场
XTP_MARKET_TYPE market;
///价格
double price;
///止损价(保留字段)
double stop_price;
///数量
int64_t quantity;
///报单价格
XTP_PRICE_TYPE price_type;
///买卖方向
XTP_SIDE_TYPE side;
};
///撤单
struct XTPOrderCancel
{
///XTP系统订单ID
uint64_t order_cancel_xtp_id;
///报单操作引用
uint32_t order_cancel_client_id;
///合约代码
char ticker[XTP_API_TICKER_LEN];
///交易市场
XTP_MARKET_TYPE market;
///操作时间
int64_t action_time;
///报单引用
uint32_t order_client_id;
///操作对象订单的序号
uint64_t order_xtp_id;
};
///撤单失败响应消息
struct XTPOrderCancelInfo
{
///撤单XTPID
uint64_t order_cancel_xtp_id;
///原始订单XTPID
uint64_t order_xtp_id;
};
///报单响应结构体
struct XTPOrderInfo
{
///XTP系统订单ID
uint64_t order_xtp_id;
///报单引用,用户自定义
uint32_t order_client_id;
///报单操作引用,用户自定义
uint32_t order_cancel_client_id;
///撤单在XTP系统中的id
uint64_t order_cancel_xtp_id;
///合约代码
char ticker[XTP_API_TICKER_LEN];
///交易市场
XTP_MARKET_TYPE market;
///价格
double price;
///数量
int64_t quantity;
///报单价格条件
XTP_PRICE_TYPE price_type;
///买卖方向
XTP_SIDE_TYPE side;
///今成交数量
int64_t qty_traded;
///剩余数量
int64_t qty_left;
///委托时间
int64_t insert_time;
///最后修改时间
int64_t update_time;
///撤销时间
int64_t cancel_time;
///成交金额
double trade_amount;
///本地报单编号 OMS生成的单号
char order_local_id[XTP_LOCAL_ORDER_LEN];
///报单状态
XTP_ORDER_STATUS_TYPE order_status;
///报单提交状态
XTP_ORDER_SUBMIT_STATUS_TYPE order_submit_status;
///报单类型
TXTPOrderTypeType order_type;
};
///报单成交结构体
struct XTPTradeReport
{
///XTP系统订单ID
uint64_t order_xtp_id;
///报单引用
uint32_t order_client_id;
///合约代码
char ticker[XTP_API_TICKER_LEN];
///交易市场
XTP_MARKET_TYPE market;
///订单号
uint64_t local_order_id;
///成交编号
uint64_t exec_id;
///价格
double price;
///数量
int64_t quantity;
///成交时间
int64_t trade_time;
///成交金额
double trade_amount;
///成交序号 --回报记录号
uint64_t report_index;
///报单编号 --交易所单号
char order_exch_id[XTP_ORDER_EXCH_LEN];
///成交类型 --成交回报中的执行类型
TXTPTradeTypeType trade_type;
///买卖方向
XTP_SIDE_TYPE side;
///交易所交易员代码
char branch_pbu[XTP_BRANCH_PBU_LEN];
};
//////////////////////////////////////////////////////////////////////////
///报单查询
//////////////////////////////////////////////////////////////////////////
///报单查询请求-条件查询
struct XTPQueryOrderReq
{
///证券代码,可以为空,如果为空,则默认查询时间段内的所有成交回报
char ticker[XTP_API_TICKER_LEN];
///格式为YYYYMMDDHHMMSSsss为0则默认当前交易日0点
int64_t begin_time;
///格式为YYYYMMDDHHMMSSsss为0则默认当前时间
int64_t end_time;
};
///报单查询响应结构体
typedef XTPOrderInfo XTPQueryOrderRsp;
//////////////////////////////////////////////////////////////////////////
///成交回报查询
//////////////////////////////////////////////////////////////////////////
///查询成交报告请求-根据执行编号查询(保留字段)
struct XTPQueryReportByExecIdReq
{
///XTP订单系统ID
uint64_t order_xtp_id;
///成交执行编号
uint64_t exec_id;
};
///查询成交回报请求-查询条件
struct XTPQueryTraderReq
{
///证券代码,可以为空,如果为空,则默认查询时间段内的所有成交回报
char ticker[XTP_API_TICKER_LEN];
///开始时间格式为YYYYMMDDHHMMSSsss为0则默认当前交易日0点
int64_t begin_time;
///结束时间格式为YYYYMMDDHHMMSSsss为0则默认当前时间
int64_t end_time;
};
///成交回报查询响应结构体
typedef XTPTradeReport XTPQueryTradeRsp;
//////////////////////////////////////////////////////////////////////////
///账户资金查询响应结构体
//////////////////////////////////////////////////////////////////////////
struct XTPQueryAssetRsp
{
///总资产
double total_asset;
///可用资金
double buying_power;
///证券资产
double security_asset;
///累计买入成交证券占用资金(保留字段)
double fund_buy_amount;
///累计买入成交交易费用(保留字段)
double fund_buy_fee;
///累计卖出成交证券所得资金(保留字段)
double fund_sell_amount;
///累计卖出成交交易费用(保留字段)
double fund_sell_fee;
};
//////////////////////////////////////////////////////////////////////////
///查询股票持仓情况
//////////////////////////////////////////////////////////////////////////
struct XTPQueryStkPositionRsp
{
///证券代码
char ticker[XTP_API_TICKER_LEN];
///证券名称
char ticker_name[XTP_API_TICKER_NAME_LEN];
///当前持仓
int64_t total_qty;
///可用股份数
int64_t sellable_qty;
///持仓成本
double avg_price;
///浮动盈亏
double unrealized_pnl;
};
#endif //_XOMS_API_STRUCT_H_

View File

@ -0,0 +1,160 @@
/////////////////////////////////////////////////////////////////////////
///@author 中泰证券股份有限公司
///@file xquote_api_struct.h
///@brief 定义行情类相关数据结构
/////////////////////////////////////////////////////////////////////////
#ifndef _XQUOTE_API_STRUCT_H_
#define _XQUOTE_API_STRUCT_H_
#include <stdint.h>
#include "xtp_api_data_type.h"
///指定的合约
typedef struct XTPSpecificTickerStruct
{
///交易所代码
XTP_EXCHANGE_TYPE exchange_id;
///合约代码(不包含交易所信息)例如"600000 "
char ticker[XTP_TICKER_LEN];
} XTPST;
///行情
typedef struct XTPMarketDataStruct
{
// 代码
///交易所代码
XTP_EXCHANGE_TYPE exchange_id;
///合约代码(不包含交易所信息)
char ticker[XTP_TICKER_LEN];
// 股票等价格
///最新价
double last_price;
///昨收盘
double pre_close_price;
///今开盘
double open_price;
///最高价
double high_price;
///最低价
double low_price;
///今收盘
double close_price;
// 期货等数据
///昨持仓量(目前未填写)
double pre_open_interest;
///持仓量(目前未填写)
double open_interest;
///上次结算价(目前未填写)
double pre_settlement_price;
///本次结算价(目前未填写)
double settlement_price;
///涨停板价(目前未填写)
double upper_limit_price;
///跌停板价(目前未填写)
double lower_limit_price;
///昨虚实度(目前未填写)
double pre_delta;
///今虚实度(目前未填写)
double curr_delta;
/// 时间类
int64_t data_time;
// 量额数据
///数量
int32_t qty;
///成交金额
double turnover;
///当日均价
double avg_price;
// 买卖盘
///十档申买价
double bid[10];
///十档申卖价
double ask[10];
///十档申买量
int32_t bid_qty[10];
///十档申卖量
int32_t ask_qty[10];
// lts没有包含的数据目前未填写
///成交笔数
int32_t trades_count;
///当前交易状态说明
char ticker_status[8];
///委托买入总量
int32_t total_bid_qty;
///委托卖出总量
int32_t total_ask_qty;
///加权平均委买价格
double ma_bid_price;
///加权平均委卖价格
double ma_ask_price;
///债券加权平均委买价格
double ma_bond_bid_price;
///债券加权平均委卖价格
double ma_bond_ask_price;
///债券到期收益率
double yield_to_maturity;
///ETF净值估值
double iopv;
///ETF申购笔数
int32_t etf_buy_count;
///ETF赎回笔数
int32_t etf_sell_count;
///ETF申购数量
double etf_buy_qty;
///ETF申购金额
double etf_buy_money;
///ETF赎回数量
double etf_sell_qty;
///ETF赎回金额
double etf_sell_money;
///权证执行的总数量
double total_warrant_exec_qty;
///权证跌停价格(元)
double warrant_lower_price;
///权证涨停价格(元)
double warrant_upper_price;
///买入撤单笔数
int32_t cancel_buy_count;
///卖出撤单笔数
int32_t cancel_sell_count;
///买入撤单数量
double cancel_buy_qty;
///卖出撤单数量
double cancel_sell_qty;
///买入撤单金额
double cancel_buy_money;
///卖出撤单金额
double cancel_sell_money;
///买入总笔数
int32_t total_buy_count;
///卖出总笔数
int32_t total_sell_count;
///买入委托成交最大等待时间
int32_t duration_after_buy;
///卖出委托成交最大等待时间
int32_t duration_after_sell;
///买方委托价位数
int32_t num_bid_orders;
///卖方委托价位数
int32_t num_ask_orders;
///成交时间UA3113
int32_t exec_time;
///闭市标志UA103/UA104
char is_market_closed[4];
///合约持仓量UA103
double total_position;
///市盈率1UA103
double pe_ratio1;
///市盈率2UA103
double pe_ratio2;
} XTPMD;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,15 @@
/////////////////////////////////////////////////////////////////////////
///@author 中泰证券股份有限公司
///@file xtp_api_struct.h
///@brief 定义业务数据结构
/////////////////////////////////////////////////////////////////////////
#ifndef _XTP_API_STRUCT_H_
#define _XTP_API_STRUCT_H_
#include "xtp_api_struct_common.h"
#include "xquote_api_struct.h"
#include "xoms_api_struct.h"
#endif // !_XTP_API_STRUCT_H_

View File

@ -0,0 +1,23 @@
/////////////////////////////////////////////////////////////////////////
///@author 中泰证券股份有限公司
///@file xtp_api_struct_common.h
///@brief 定义业务公共数据结构
/////////////////////////////////////////////////////////////////////////
#ifndef _XTP_API_STRUCT_COMMON_H_
#define _XTP_API_STRUCT_COMMON_H_
#include <stdint.h>
#include "xtp_api_data_type.h"
///响应信息
#define XTP_ERR_MSG_LEN 76
typedef struct XTPRspInfoStruct
{
///错误代码
int32_t error_id;
///错误信息
char error_msg[XTP_ERR_MSG_LEN];
} XTPRI;
#endif // !_XTP_API_STRUCT_COMMON_H_

View File

@ -0,0 +1,158 @@
/////////////////////////////////////////////////////////////////////////
///@author 中泰证券股份有限公司
///@file xtp_quote_api.h
///@brief 定义行情订阅客户端接口
/////////////////////////////////////////////////////////////////////////
#ifndef _XTP_QUOTE_API_H_
#define _XTP_QUOTE_API_H_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "xtp_api_struct.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 XTP::API::QuoteSpi
*
* \brief
*
* \author
* \date 2015
*/
namespace XTP {
namespace API {
class QuoteSpi
{
public:
///当客户端与交易后台通信连接断开时,该方法被调用。
///@remark 保留函数,暂未支持
///@param reason 错误原因
virtual void OnDisconnected(int reason) {};
///错误应答
///@param error_info 错误信息
virtual void OnError(XTPRI *error_info) {};
///订阅行情应答
///@param ticker 详细的合约订阅情况
///@param error_info 订阅合约发生错误时的错误信息
///@param is_last 是否此次订阅的最后一个应答
///@remark 每条订阅的合约均对应一条订阅应答
virtual void OnSubMarketData(XTPST *ticker, XTPRI *error_info, bool is_last) {};
///取消订阅行情应答
///@param ticker 详细的合约取消订阅情况
///@param error_info 错误信息
///@param is_last 是否此次取消订阅的最后一个应答
///@remark 每条取消订阅的合约均对应一条取消订阅应答
virtual void OnUnSubMarketData(XTPST *ticker, XTPRI *error_info, bool is_last) {};
///行情通知
///@param market_data 行情数据
virtual void OnMarketData(XTPMD *market_data) {};
///查询可交易合约应答
///@remark 保留函数,此函数暂未支持
virtual void OnQueryAllTickers() {};
};
}
}
/*!
* \class XTP::API::QuoteApi
*
* \brief
*
* \author
* \date 2015
*/
namespace XTP {
namespace API {
class MD_API_EXPORT QuoteApi
{
public:
///创建QuoteApi
///@param save_file_path (保留字段)存贮订阅信息文件的目录,默认为当前目录
///@return 创建出的UserApi
static QuoteApi *CreateQuoteApi(const char *save_file_path = "");
///删除接口对象本身
///@remark 不再使用本接口对象时,调用该函数删除接口对象
virtual void Release() = 0;
///获取当前交易日
///@return 获取到的交易日
///@remark 只有登录成功后,才能得到正确的交易日
virtual const char *GetTradingDay() = 0;
///注册回调接口
///@param spi 派生自回调接口类的实例
virtual void RegisterSpi(QuoteSpi *spi) = 0;
///订阅行情。
///@return 订阅接口调用是否成功“0”表示接口调用成功非“0”表示接口调用出错
///@param ticker 合约ID数组
///@param count 要订阅/退订行情的合约个数
///@param exchage_id 交易所代码
///@remark 可以一次性订阅同一证券交易所的多个合约
virtual int SubscribeMarketData(char *ticker[], int count, XTP_EXCHANGE_TYPE exchage_id) = 0;
///退订行情。
///@return 取消订阅接口调用是否成功“0”表示接口调用成功非“0”表示接口调用出错
///@param ticker 合约ID数组
///@param count 要订阅/退订行情的合约个数
///@param exchage_id 交易所代码
///@remark 可以一次性取消订阅同一证券交易所的多个合约
virtual int UnSubscribeMarketData(char *ticker[], int count, XTP_EXCHANGE_TYPE exchage_id) = 0;
///用户登录请求
///@return 登录是否成功“0”表示登录成功“-1”表示连接服务器出错“-2”表示已存在连接不允许重复登录如果需要重连请先logout“-3”表示输入有错误
///@param ip 服务器地址
///@param port 服务器端口号
///@param user 登陆用户名
///@param password 登陆密码
///@param sock_type “1”代表TCP“2”代表UDP目前暂时只支持TCP
///@remark 此函数为同步阻塞式,不需要异步等待登录成功,当函数返回即可进行后续操作
virtual int Login(const char* ip, int port, const char* user, const char* password, XTP_PROTOCOL_TYPE sock_type) = 0;
///登出请求
///@return 登出是否成功“0”表示登出成功非“0”表示登出出错
///@remark 此函数为同步阻塞式,不需要异步等待登出,当函数返回即可进行后续操作
virtual int Logout() = 0;
///获取当前交易日可交易合约
///@return 查询是否成功“0”表示查询成功非“0”表示查询不成功
///@param exchage_id 交易所代码
///@remark 此函数暂未支持
virtual int QueryAllTickers(XTP_EXCHANGE_TYPE exchage_id) = 0;
protected:
~QuoteApi() {};
};
}
}
#endif

View File

@ -0,0 +1,206 @@
/////////////////////////////////////////////////////////////////////////
///@author 中泰证券股份有限公司
///@file xtp_trader_api.h
///@brief 定义客户端交易接口
/////////////////////////////////////////////////////////////////////////
#ifndef _XTP_TRADER_API_H_
#define _XTP_TRADER_API_H_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "xtp_api_struct.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 XTP::API::TraderSpi
*
* \brief
*
* \author
* \date 2015
*/
namespace XTP {
namespace API {
class TraderSpi
{
public:
///当客户端与交易后台通信连接断开时,该方法被调用。
///@remark 保留函数,暂未支持
///@param reason 错误原因
virtual void OnDisconnected(int reason) {};
///错误应答
///@param error_info 具体的错误代码和错误信息
virtual void OnError(XTPRI *error_info) {};
///报单通知
///@param order_info 订单响应具体信息
///@param error_info 订单被拒绝或者发生错误时错误代码和错误信息
///@remark 每次订单状态更新时,都会被调用
virtual void OnOrderEvent(XTPOrderInfo *order_info, XTPRI *error_info) {};
///成交通知
///@param trade_info 成交回报的具体信息
///@remark 订单有成交发生的时候,会被调用
virtual void OnTradeEvent(XTPTradeReport *trade_info) {};
///撤单出错响应
///@param cancel_info 撤单具体信息包括撤单单和待撤单的order_xtp_id
///@param error_info 撤单被拒绝或者发生错误时错误代码和错误信息
virtual void OnCancelOrderError(XTPOrderCancelInfo *cancel_info, XTPRI *error_info) {};
///请求查询报单响应
///@param order_info 查询到的报单
///@param error_info 错误信息
///@param request_id 此消息响应函数对应的请求ID
///@param is_last 此消息响应函数是否为request_id这条请求所对应的最后一个响应
///@remark 由于支持分时段查询,一个查询请求可能对应多个响应
virtual void OnQueryOrder(XTPQueryOrderRsp *order_info, XTPRI *error_info, int request_id, bool is_last) {};
///请求查询成交响应
///@param trade_info 查询到的成交回报
///@param error_info 错误信息
///@param request_id 此消息响应函数对应的请求ID
///@param is_last 此消息响应函数是否为request_id这条请求所对应的最后一个响应
///@remark 由于支持分时段查询,一个查询请求可能对应多个响应
virtual void OnQueryTrade(XTPQueryTradeRsp *trade_info, XTPRI *error_info, int request_id, bool is_last) {};
///请求查询投资者持仓响应
///@param position 查询到的持仓情况
///@param error_info 错误信息
///@param request_id 此消息响应函数对应的请求ID
///@param is_last 此消息响应函数是否为request_id这条请求所对应的最后一个响应
///@remark 由于用户可能持有多个股票,一个查询请求可能对应多个响应
virtual void OnQueryPosition(XTPQueryStkPositionRsp *position, XTPRI *error_info, int request_id, bool is_last) {};
///请求查询资金账户响应
virtual void OnQueryAsset(XTPQueryAssetRsp *asset, XTPRI *error_info, int request_id, bool is_last) {};
};
}
}
/*!
* \class XTP::API::TraderApi
*
* \brief
*
* \author
* \date 2015
*/
namespace XTP {
namespace API {
class TRADER_API_EXPORT TraderApi
{
public:
///创建TraderApi
///@param save_file_path (保留字段)存贮订阅信息文件的目录,默认为当前目录
///@return 创建出的UserApi
static TraderApi *CreateTraderApi(const char *save_file_path = "");
///删除接口对象本身
///@remark 不再使用本接口对象时,调用该函数删除接口对象
virtual void Release() = 0;
///获取当前交易日
///@return 获取到的交易日
///@remark 只有登录成功后,才能得到正确的交易日
virtual const char *GetTradingDay() = 0;
///注册回调接口
///@param spi 派生自回调接口类的实例
virtual void RegisterSpi(TraderSpi *spi) = 0;
///用户登录请求
///@return 登录是否成功“0”表示登录成功“-1”表示连接服务器出错“-2”表示已存在连接不允许重复登录如果需要重连请先logout
///@param ip 服务器地址
///@param port 服务器端口号
///@param user 登录用户名
///@param password 登录密码
///@param sock_type “1”代表TCP“2”代表UDP目前暂时只支持TCP
///@param client_id 保留字段客户端id用于区分同一用户的不同连接
///@remark 此函数为同步阻塞式,不需要异步等待登录成功,当函数返回即可进行后续操作
virtual int Login(const char* ip, int port, const char* user, const char* password, XTP_PROTOCOL_TYPE sock_type, int client_id = 0) = 0;
///登出请求
///@return 登出是否成功“0”表示登出成功“-1”表示登出失败
virtual int Logout() = 0;
///报单录入请求
///@return 报单在XTP系统中的ID,如果为0表示报单失败用户需要记录下返回的order_xtp_id
///@param order 报单录入信息
virtual uint64_t InsertOrder(XTPOrderInsertInfo *order) = 0;
///报单操作请求
///@return 撤单单在XTP系统中的ID,如果为0表示撤单失败用户需要记录下返回的order_cancel_xtp_id
///@param order_xtp_id 需要撤销的委托单在XTP系统中的ID
virtual uint64_t CancelOrder(const uint64_t order_xtp_id) = 0;
///根据报单ID请求查询报单
///@return 查询是否成功“0”表示成功非“0”表示出错
///@param order_xtp_id 需要查询的报单在xtp系统中的ID
///@param request_id 用于用户定位查询响应的ID由用户自定义
virtual int QueryOrderByXTPID(const uint64_t order_xtp_id, int request_id) = 0;
///请求查询报单
///@return 查询是否成功“0”表示成功非“0”表示出错
///@param query_param 需要查询的订单相关筛选条件
///@param request_id 用于用户定位查询响应的ID由用户自定义
///@remark 该方法支持分时段查询,如果股票代码为空,则默认查询时间段内的所有报单,否则查询时间段内所有跟股票代码相关的报单
virtual int QueryOrders(const XTPQueryOrderReq *query_param, int request_id) = 0;
///根据委托编号请求查询相关成交
///@return 查询是否成功“0”表示成功非“0”表示出错
///@param order_xtp_id 需要查询的委托编号
///@param request_id 用于用户定位查询响应的ID由用户自定义
///@remark 此函数查询出的结果可能对应多个响应
virtual int QueryTradesByXTPID(const uint64_t order_xtp_id, int request_id) = 0;
///请求查询已成交
///@return 查询是否成功“0”表示成功非“0”表示出错
///@param query_param 需要查询的成交回报筛选条件
///@param request_id 用于用户定位查询响应的ID由用户自定义
///@remark 该方法支持分时段查询,如果股票代码为空,则默认查询时间段内的所有成交回报,否则查询时间段内所有跟股票代码相关的成交回报
virtual int QueryTrades(XTPQueryTraderReq *query_param, int request_id) = 0;
///请求查询投资者持仓
///@return 查询是否成功“0”表示成功非“0”表示出错
///@param ticker 需要查询的持仓股票,可以为空
///@param request_id 用于用户定位查询响应的ID由用户自定义
///@remark 该方法如果用户提供了股票代码,则会查询此股票的持仓信息,如果股票代码为空,则默认查询所有持仓信息
virtual int QueryPosition(const char *ticker, int request_id) = 0;
///请求查询资产
///@return 查询是否成功“0”表示成功非“0”表示出错
///@param request_id 用于用户定位查询响应的ID由用户自定义
virtual int QueryAsset(int request_id) = 0;
protected:
~TraderApi() {};
};
}
}
#endif

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.