增加中信接口

1. 增加中信证券恒生接口vn.cshshlp,以及vn.trader接入cshshlpGateway
2. 更新飞创API的期权相关功能
3. 修复若干bug
4. 移除有问题的加载TB历史数据函数
This commit is contained in:
vn.py 2017-05-12 11:32:03 +08:00
parent 38caf8bf62
commit d455ad58ce
47 changed files with 2637 additions and 200 deletions

Binary file not shown.

View File

@ -0,0 +1,146 @@
[t2sdk]
; 客户端要连接的服务端的IP和端口可以配置一个或多个中间以;分割,连接初始化时,会从这串服务端地址中,随即选择一个作为要建立连接的服务端
;servers=10.23.179.15:20008
;联通请使用这个地址:
;servers=118.192.134.124:20008
;电信请使用这个地址:
servers=124.207.9.124:20008
; 接收缓存的初始大小,单位字节,实际接收到服务端的数据时,可能会扩大(如果需要)
init_recv_buf_size=512
; 每块发送缓存的初始大小,单位字节,该大小也会根据需要动态扩大
init_send_buf_size=512
; 发送队列的大小,该大小不会动态变化,若该配置项很小,且连接发包很频繁,则可能
; 因为发送队列满而造成发送失败
send_queue_size=1000
; lang用于指定T2_SDK错误信息的语言ID2052为简体中文1033为英文
; 默认为2052
lang=2052
; 此配置项请参看“注意事项”
event_count=10
; 许可证文件的路径默认为当前目录下的license.dat。
license_file=(20130403)ZXZQ-TESTsfjrt-ALL-0001_3rd.dat
;第三方许可证密码
license_pwd=999999
; 客户端给服务端发送心跳的间隔时间单位为秒最小值为5秒
; 不配或者配<=0表示不开启客户端心跳
heartbeat_time=5
;t2sdk开发包取本机IP和MAC地址值为1表示t2sdk与服务端建立连接的时候要带上IP和MAC其它任何值都不会带IP和MAC地址信息
addipmac=1
[proxy]
; 可配置采用何种代理配置http/socks4/socks5空表示不采用代理
proxy_type=
; 代理服务器的IP地址
ip=
port=
; 登陆代理服务器的用户名
user_name=guest
password=
[safe]
; 连接的安全模式明文none通信密码pwdSSLssl
; 注意大小写敏感
safe_level=ssl
; 当连接的安全模式为pwd时client_id配置项才生效
client_id=
; 在pwd模式下当client_id为空时comm_pwd为默认的密钥
; 注意当client_id为空时comm_pwd必须和服务端的配置一致方可正常使用目前服务
; 端的配置为888888
comm_pwd=999999
; 当连接的安全模式为ssl时cert_file和cert_pwd配置项才生效
; 证书文件路径
cert_file=s2013.pfx
cert_pwd=999999
; 是否校验服务端,可不配,若不配,默认校验服务端
check_server_cert=

View File

@ -0,0 +1,3 @@
# encoding: UTF-8
from vncshshlp import CsHsHlp

View File

@ -0,0 +1,38 @@
[csapi]
log_path=.\\cslog\
biz_trace=2
; 0: 不记录日志;
; 1: 只记录错误请求参数日志
; 2: 记录所有请求参数日志, 默认值;
; 4: 记录所有请求参数日志并且记录t2sdk的二进制请求包
; 8: 并且记录t2sdk的二进制应答包调试使用。
error_trim = 11
;错误信息格式化0:不处理1:只过滤"表记录"提示11在1的基础上过滤&&后面的参数
;默认为0
update_site=10.1.1.1:21001
;自动升级服务器IP及端口
license_file=csauthor.dat
; CITICs_HsT2Hlp.dll接口许可证文件名称不含路径
[connection]
connect_timeout=10
; 中间件连接超时时间单位S默认时间10s
biz_timeout=15
; 业务请求超时时间单位S默认时间10s
op_site_prefix=
;操作站点前缀默认为空。可以配置长度不超过8个字符的字符串
[func_log]
; 该配置与[biz_trace] 选项两者取大值
; 功能号, 日志标识 1:只记录错误; 2:记录请求数据; 4:记录请求/应答(top2) 8:记录请求/应答数据(完整)
;func_01=331100,4
;func_02=333002,4
;func_03=339306,2
;func_04=333104,4

Binary file not shown.

View File

@ -0,0 +1,141 @@
#ifndef __CITICS_HSHLP_H__
#define __CITICS_HSHLP_H__
#ifdef WIN32
#ifdef CITICS_HSHLP_EXPORTS
#define CITICS_HSHLP_API __declspec(dllexport)
#else
#define CITICS_HSHLP_API __declspec(dllimport)
#endif
#define CITICSSTDCALL __stdcall /* ensure stcall calling convention on NT */
#else
#define CITICS_HSHLP_API
#define CITICSSTDCALL /* leave blank for other systems */
#endif
#define ERROR_MSG_SIZE 512
//////////////////////////////////////////////////////////////////////////
/**
*
* 使
*/
#define BIZCALL_SYNC 0
/**
*
* 使
* QueueGetMsg获取应答结果信息
*/
#define BIZCALL_ASYNC 1
/**
*
*
* QueueGetMsg获取订阅的信息
*/
#define BIZCALL_SUBSCRIBE 3
typedef void *HSHLPCFGHANDLE;
typedef void *HSHLPHANDLE;
typedef void *HSHLPASYNCMSG;
#pragma pack(1)
/* 异步和订阅消息控制信息*/
typedef struct
{
int nFlags; // 位标识信息0x0:正常消息, >0:系统状态消息
int nFuncID; // 异步请求功能号
int nReqNo; // 异步请求接受序号,根据该序号和功能号对请求和应答数据匹配
int nIssueType; // 发布消息类别
int nErrorNo; // 错误代码
HSHLPASYNCMSG HAsyncMsg; // 消息句柄
char szErrorInfo[ERROR_MSG_SIZE+1]; // 错误信息
}MSG_CTRL, *LPMSG_CTRL;
#pragma pack()
#ifdef __cplusplus
extern "C"
{
#endif
// 初始化配置项szConfigFile为空时则按系统默认值初始化hConfig为出参
CITICS_HSHLP_API int CITICSSTDCALL CITICs_HsHlp_InitConfig(HSHLPCFGHANDLE* hConfig, const char* szConfigFile=NULL);
// 加载配置文件项可以加载多个不同的配置文件返回不同的配置句柄。等同于InitConfig
CITICS_HSHLP_API int CITICSSTDCALL CITICs_HsHlp_LoadConfig(HSHLPCFGHANDLE* hConfig, const char* szConfigFile);
// 重置服务器连接地址。格式ip1:port1;ip2:port2;
CITICS_HSHLP_API int CITICSSTDCALL CITICs_HsHlp_ResetServer(HSHLPCFGHANDLE hConfig, const char* szAddr);
// 根据配置句柄,初始化一个连接对象。
CITICS_HSHLP_API int CITICSSTDCALL CITICs_HsHlp_Init(HSHLPHANDLE* HlpHandle, HSHLPCFGHANDLE hConfig);
// 释放连接句柄系统资源
CITICS_HSHLP_API int CITICSSTDCALL CITICs_HsHlp_Exit(HSHLPHANDLE HlpHandle);
// 与服务器建立连接
CITICS_HSHLP_API int CITICSSTDCALL CITICs_HsHlp_ConnectServer(HSHLPHANDLE HlpHandle);
CITICS_HSHLP_API int CITICSSTDCALL CITICs_HsHlp_DisConnect(HSHLPHANDLE HlpHandle);
// 提交业务请求如果szParam参数为NULL则认为是通过SetValue函数设置的请求参数
CITICS_HSHLP_API int CITICSSTDCALL CITICs_HsHlp_BizCallAndCommit(HSHLPHANDLE HlpHandle, int iFuncID, const char* szParam=NULL, int nBizCallType=BIZCALL_SYNC, LPMSG_CTRL lpMsgCtrl=NULL);
// 获取记录行、列数,返回值为行、列数
CITICS_HSHLP_API int CITICSSTDCALL CITICs_HsHlp_GetRowCount(HSHLPHANDLE HlpHandle, LPMSG_CTRL lpMsgCtrl=NULL);
CITICS_HSHLP_API int CITICSSTDCALL CITICs_HsHlp_GetColCount(HSHLPHANDLE HlpHandle, LPMSG_CTRL lpMsgCtrl=NULL);
// 获取字段名称序号以0为基数
CITICS_HSHLP_API int CITICSSTDCALL CITICs_HsHlp_GetColName(HSHLPHANDLE HlpHandle, int iColumn, char* szColName, LPMSG_CTRL lpMsgCtrl=NULL);
// 获取下一行记录第一次调用则首先打开结果集并把第0行作为当前记录行
CITICS_HSHLP_API int CITICSSTDCALL CITICs_HsHlp_GetNextRow(HSHLPHANDLE HlpHandle, LPMSG_CTRL lpMsgCtrl=NULL);
// 根据字段名称,获取字段值
CITICS_HSHLP_API int CITICSSTDCALL CITICs_HsHlp_GetValue(HSHLPHANDLE HlpHandle, const char* szKeyName, char* szValue, LPMSG_CTRL lpMsgCtrl=NULL);
// 根据字段序号获取字段值序号以0为基数
CITICS_HSHLP_API int CITICSSTDCALL CITICs_HsHlp_GetValueByIndex(HSHLPHANDLE HlpHandle, int iColumn, char* szValue, LPMSG_CTRL lpMsgCtrl=NULL);
// 获取当前错误代码和信息
CITICS_HSHLP_API int CITICSSTDCALL CITICs_HsHlp_GetErrorMsg(HSHLPHANDLE HlpHandle, int* piErrorCode, char* szErrorMsg);
/************************************************************************/
// 另一种请求参数设置的方法,一个一个的设置。
// 初始化请求参数
CITICS_HSHLP_API int CITICSSTDCALL CITICs_HsHlp_BeginParam(HSHLPHANDLE HlpHandle);
// 设置每个请求参数字段名称和值
CITICS_HSHLP_API int CITICSSTDCALL CITICs_HsHlp_SetValue(HSHLPHANDLE HlpHandle, const char* szKeyName, const char* szValue);
/************************************************************************/
// 异步请求和消息订阅相关函数
// 获取异步消息队列中的消息数量
CITICS_HSHLP_API int CITICSSTDCALL CITICs_HsHlp_QueueMsgCount(HSHLPHANDLE HlpHandle);
// 从队列中读取一条消息如果队列中没有数据该函数会一直阻塞不返回直到nWaitTime超时时间后才返回。
// nWaitTime: 单位毫秒
// = 0: 立即返回如果队列中有数据则返回Msg且return值为 0否则return值为-5(超时错误)
// =-1: 阻塞直到队列中有数据获取到Msg 才返回。否则将永久阻塞等待。return值为 0
// = 其它值超时时间如果队列中有数据则立即返回否则等待time时间后返回。return值为 -5(超时错误)。
// Return: 0: 队列中有数据且获取消息成功;
// -5: 超时错误,在设定的时间内队列中没有数据。
// 其它错误:
CITICS_HSHLP_API int CITICSSTDCALL CITICs_HsHlp_QueueGetMsg(HSHLPHANDLE HlpHandle, LPMSG_CTRL lpMsgCtrl /*Out*/, int nWaitTime=0);
// 处理完成或者不需要该消息时,应及时删除该消息,否则消息将占用大量内存。
// 如果不删除有可能每次都Get到同一条消息
CITICS_HSHLP_API int CITICSSTDCALL CITICs_HsHlp_QueueEraseMsg(HSHLPHANDLE HlpHandle, LPMSG_CTRL lpMsgCtrl /*In*/);
#ifdef __cplusplus
}
#endif
#endif

Binary file not shown.

View File

@ -0,0 +1,53 @@
[t2sdk]
; 客户端要连接的服务端的IP和端口可以配置一个或多个中间以;分割,连接初始化时,会从这串服务端地址中,随即选择一个作为要建立连接的服务端
servers=114.251.228.136:20008
; 接收缓存的初始大小,单位字节,实际接收到服务端的数据时,可能会扩大(如果需要)
init_recv_buf_size=512
; 每块发送缓存的初始大小,单位字节,该大小也会根据需要动态扩大
init_send_buf_size=512
; 发送队列的大小,该大小不会动态变化,若该配置项很小,且连接发包很频繁,则可能
; 因为发送队列满而造成发送失败
send_queue_size=1000
; lang用于指定T2_SDK错误信息的语言ID2052为简体中文1033为英文
; 默认为2052
lang=2052
; 此配置项请参看“注意事项”
event_count=10
; 许可证文件的路径默认为当前目录下的license.dat。
license_file=./license.dat
[proxy]
; 可配置采用何种代理配置http/socks4/socks5空表示不采用代理
proxy_type=
; 代理服务器的IP地址
ip=
port=
; 登陆代理服务器的用户名
user_name=guest
password=
[safe]
; 连接的安全模式明文none通信密码pwdSSLssl
; 注意大小写敏感
safe_level=none
; 当连接的安全模式为pwd时client_id配置项才生效
client_id=
; 在pwd模式下当client_id为空时comm_pwd为默认的密钥
; 注意当client_id为空时comm_pwd必须和服务端的配置一致方可正常使用目前服务
; 端的配置为888888
comm_pwd=888888
; 当连接的安全模式为ssl时cert_file和cert_pwd配置项才生效
; 证书文件路径
cert_file=xxx.pem
cert_pwd=xxxxxxxx

Binary file not shown.

View File

@ -0,0 +1,20 @@
[t2sdk]
#第三方许可证
license_file=
servers=192.168.94.85:8001
login_name=
init_recv_buf_size=512
init_send_buf_size=512
send_queue_size=1000
#心跳时间
heartbeat_time=10
#接入用户密码
license_pwd=
[safe]
safe_level=ssl
#SSL证书
cert_file=
#SSL证书密码
cert_pwd=

Binary file not shown.

View File

@ -0,0 +1,14 @@
# vn.cshshlp
### 简介
中信证券恒生接口规范的Python封装。
1. 使用时请将该目录下所有的dat、pfx、ini文件复制到vn.trader目录后使用
2. 该封装目前只支持交易接口行情接口请使用中信期货的CTP行情
### API版本
日期2013-09-17
名称Cs_Hshlp
描述中信证券恒生API

BIN
vnpy/api/cshshlp/s2013.pfx Normal file

Binary file not shown.

BIN
vnpy/api/cshshlp/t2sdk.dll Normal file

Binary file not shown.

View File

@ -0,0 +1,20 @@
[t2sdk]
#第三方许可证
license_file=
servers=192.168.94.85:8001
login_name=
init_recv_buf_size=512
init_send_buf_size=512
send_queue_size=1000
#心跳时间
heartbeat_time=10
#接入用户密码
license_pwd=
[safe]
safe_level=ssl
#SSL证书
cert_file=
#SSL证书密码
cert_pwd=

Binary file not shown.

View File

@ -0,0 +1,146 @@
[t2sdk]
; 客户端要连接的服务端的IP和端口可以配置一个或多个中间以;分割,连接初始化时,会从这串服务端地址中,随即选择一个作为要建立连接的服务端
;servers=10.23.179.15:20008
;联通请使用这个地址:
;servers=118.192.134.124:20008
;电信请使用这个地址:
servers=124.207.9.124:20008
; 接收缓存的初始大小,单位字节,实际接收到服务端的数据时,可能会扩大(如果需要)
init_recv_buf_size=512
; 每块发送缓存的初始大小,单位字节,该大小也会根据需要动态扩大
init_send_buf_size=512
; 发送队列的大小,该大小不会动态变化,若该配置项很小,且连接发包很频繁,则可能
; 因为发送队列满而造成发送失败
send_queue_size=1000
; lang用于指定T2_SDK错误信息的语言ID2052为简体中文1033为英文
; 默认为2052
lang=2052
; 此配置项请参看“注意事项”
event_count=10
; 许可证文件的路径默认为当前目录下的license.dat。
license_file=(20130403)ZXZQ-TESTsfjrt-ALL-0001_3rd.dat
;第三方许可证密码
license_pwd=999999
; 客户端给服务端发送心跳的间隔时间单位为秒最小值为5秒
; 不配或者配<=0表示不开启客户端心跳
heartbeat_time=5
;t2sdk开发包取本机IP和MAC地址值为1表示t2sdk与服务端建立连接的时候要带上IP和MAC其它任何值都不会带IP和MAC地址信息
addipmac=1
[proxy]
; 可配置采用何种代理配置http/socks4/socks5空表示不采用代理
proxy_type=
; 代理服务器的IP地址
ip=
port=
; 登陆代理服务器的用户名
user_name=guest
password=
[safe]
; 连接的安全模式明文none通信密码pwdSSLssl
; 注意大小写敏感
safe_level=ssl
; 当连接的安全模式为pwd时client_id配置项才生效
client_id=
; 在pwd模式下当client_id为空时comm_pwd为默认的密钥
; 注意当client_id为空时comm_pwd必须和服务端的配置一致方可正常使用目前服务
; 端的配置为888888
comm_pwd=999999
; 当连接的安全模式为ssl时cert_file和cert_pwd配置项才生效
; 证书文件路径
cert_file=s2013.pfx
cert_pwd=999999
; 是否校验服务端,可不配,若不配,默认校验服务端
check_server_cert=

View File

@ -0,0 +1,38 @@
[csapi]
log_path=.\\cslog\
biz_trace=2
; 0: 不记录日志;
; 1: 只记录错误请求参数日志
; 2: 记录所有请求参数日志, 默认值;
; 4: 记录所有请求参数日志并且记录t2sdk的二进制请求包
; 8: 并且记录t2sdk的二进制应答包调试使用。
error_trim = 11
;错误信息格式化0:不处理1:只过滤"表记录"提示11在1的基础上过滤&&后面的参数
;默认为0
update_site=10.1.1.1:21001
;自动升级服务器IP及端口
license_file=csauthor.dat
; CITICs_HsT2Hlp.dll接口许可证文件名称不含路径
[connection]
connect_timeout=10
; 中间件连接超时时间单位S默认时间10s
biz_timeout=15
; 业务请求超时时间单位S默认时间10s
op_site_prefix=
;操作站点前缀默认为空。可以配置长度不超过8个字符的字符串
[func_log]
; 该配置与[biz_trace] 选项两者取大值
; 功能号, 日志标识 1:只记录错误; 2:记录请求数据; 4:记录请求/应答(top2) 8:记录请求/应答数据(完整)
;func_01=331100,4
;func_02=333002,4
;func_03=339306,2
;func_04=333104,4

View File

@ -0,0 +1,94 @@
# encoding: UTF-8
import sys
from time import sleep
from PyQt4 import QtGui
from vncshshlp import *
branch_no = ''
#----------------------------------------------------------------------
def print_list(l):
""""""
for d in l:
print d
#----------------------------------------------------------------------
def print_dict(d):
"""按照键值打印一个字典"""
for key,value in d.items():
print key + ':' + str(value)
#----------------------------------------------------------------------
def simple_log(func):
"""简单装饰器用于输出函数名"""
def wrapper(*args, **kw):
print '-' * 20
print str(func.__name__)
return func(*args, **kw)
return wrapper
class TestHlp(CsHsHlp):
#----------------------------------------------------------------------
def __init__(self):
""""""
super(TestHlp, self).__init__()
#----------------------------------------------------------------------
@simple_log
def onMsg(self, type_, data, reqNo, errorNo, errorInfo):
""""""
print 'type:', type_
print_list(data)
print 'reqNo:', reqNo
print 'errorNo:', errorNo
print 'errorInfo:', errorInfo
#----------------------------------------------------------------------
def test():
"""测试用"""
api = TestHlp()
# 读取配置文件
i = api.loadConfig("Hsconfig.ini")
if i:
print u'加载配置失败:', i
print u'加载配置成功'
# 初始化
i = api.init()
if i:
print u'初始化失败:', i
print u'初始化成功'
# 连接服务器
i = api.connectServer()
if i:
print u'服务器连接失败:', i
print u'服务器连接成功'
# 登录
print u'尝试登录'
i = api.beginParam()
api.setValue("identity_type", "2")
api.setValue("password_type", "2")
api.setValue("input_content", "1")
api.setValue("op_entrust_way", "5")
api.setValue("password", "")
api.setValue("account_content", "")
i = api.bizCallAndCommit(331100)
print '登录reqNo:', i
print 'done'
raw_input()
if __name__ == '__main__':
test()

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,20 @@
[t2sdk]
#第三方许可证
license_file=
servers=192.168.94.85:8001
login_name=
init_recv_buf_size=512
init_send_buf_size=512
send_queue_size=1000
#心跳时间
heartbeat_time=10
#接入用户密码
license_pwd=
[safe]
safe_level=ssl
#SSL证书
cert_file=
#SSL证书密码
cert_pwd=

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.40629.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vncshshlp", "vncshshlp\vncshshlp.vcxproj", "{982DF24C-BCD1-4F25-BDE8-84ADB719588B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{982DF24C-BCD1-4F25-BDE8-84ADB719588B}.Debug|Win32.ActiveCfg = Debug|Win32
{982DF24C-BCD1-4F25-BDE8-84ADB719588B}.Debug|Win32.Build.0 = Debug|Win32
{982DF24C-BCD1-4F25-BDE8-84ADB719588B}.Release|Win32.ActiveCfg = Release|Win32
{982DF24C-BCD1-4F25-BDE8-84ADB719588B}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,32 @@
========================================================================
动态链接库vncshshlp 项目概述
========================================================================
应用程序向导已为您创建了此 vncshshlp DLL。
本文件概要介绍组成 vncshshlp 应用程序的每个文件的内容。
vncshshlp.vcxproj
这是使用应用程序向导生成的 VC++ 项目的主项目文件,其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
vncshshlp.vcxproj.filters
这是使用“应用程序向导”生成的 VC++ 项目筛选器文件。它包含有关项目文件与筛选器之间的关联信息。在 IDE 中,通过这种关联,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。
vncshshlp.cpp
这是主 DLL 源文件。
此 DLL 在创建时不导出任何符号。因此,生成时不会产生 .lib 文件。如果希望此项目成为其他某个项目的项目依赖项,则需要添加代码以从 DLL 导出某些符号,以便产生一个导出库,或者,也可以在项目“属性页”对话框中的“链接器”文件夹中,将“常规”属性页上的“忽略输入库”属性设置为“是”。
/////////////////////////////////////////////////////////////////////////////
其他标准文件:
StdAfx.h, StdAfx.cpp
这些文件用于生成名为 vncshshlp.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。
/////////////////////////////////////////////////////////////////////////////
其他注释:
应用程序向导使用“TODO:”注释来指示应添加或自定义的源代码部分。
/////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,19 @@
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#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 : 只包括标准包含文件的源文件
// vncshshlp.pch 将作为预编译头
// stdafx.obj 将包含预编译类型信息
#include "stdafx.h"
// TODO: 在 STDAFX.H 中
// 引用任何所需的附加头文件,而不是在此文件中引用

View File

@ -0,0 +1,16 @@
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的信息
// Windows 头文件:
#include <windows.h>
// TODO: 在此处引用程序需要的其他头文件

View File

@ -0,0 +1,8 @@
#pragma once
// 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。
// 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h并将
// WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。
#include <SDKDDKVer.h>

View File

@ -0,0 +1,243 @@
// vncshshlp.cpp : 定义 DLL 应用程序的导出函数。
//
#include "stdafx.h"
#include "vncshshlp.h"
//------------------------------------------------------------------------
//主动函数部分
//------------------------------------------------------------------------
//读取配置文件
int CsHsHlp::loadConfig(string fileName)
{
int i = CITICs_HsHlp_LoadConfig(&this->cfgHandle, fileName.c_str());
return i;
};
//初始化
int CsHsHlp::init()
{
int i = CITICs_HsHlp_Init(&this->handle, this->cfgHandle);
return i;
};
//连接服务器
int CsHsHlp::connectServer()
{
int i = CITICs_HsHlp_ConnectServer(this->handle);
if (this->active == false)
{
this->active = true;
function0<void> f = boost::bind(&CsHsHlp::processMsg, this);
thread t(f);
this->task_thread = &t;
}
return i;
};
//获取错误信息
string CsHsHlp::getErrorMsg()
{
int i;
char msg[512];
CITICs_HsHlp_GetErrorMsg(this->handle, &i, msg);
string errorMsg = msg;
return errorMsg;
};
//初始化发包请求
int CsHsHlp::beginParam()
{
int i = CITICs_HsHlp_BeginParam(this->handle);
return i;
};
//设置发包的参数字段名称和值
int CsHsHlp::setValue(string key, string value)
{
int i = CITICs_HsHlp_SetValue(this->handle, key.c_str(), value.c_str());
return i;
};
//异步发包
int CsHsHlp::bizCallAndCommit(int iFuncID)
{
int i = CITICs_HsHlp_BizCallAndCommit(this->handle, iFuncID, NULL, BIZCALL_ASYNC, NULL);
return i;
};
//订阅
boost::python::list CsHsHlp::subscribeData(int iFuncID)
{
int i = CITICs_HsHlp_BizCallAndCommit(this->handle, iFuncID, NULL, BIZCALL_SUBSCRIBE, NULL);
//订阅为同步调用,读取返回的结果
int row = CITICs_HsHlp_GetRowCount(this->handle); //获取msg行数有多少个回应
int col = CITICs_HsHlp_GetColCount(this->handle); //获取msg列数有哪些字段
char key[64] = { 0 };
char value[512] = { 0 };
boost::python::list data;
for (int i = 0; i < row; i++)
{
if (0 == CITICs_HsHlp_GetNextRow(this->handle))
{
dict d;
for (int j = 0; j < col; j++)
{
CITICs_HsHlp_GetColName(this->handle, j, key);
CITICs_HsHlp_GetValueByIndex(this->handle, j, value);
string str_key = key;
string str_value = value;
d[str_key] = str_value;
}
data.append(d);
}
}
return data;
};
//断开服务器
int CsHsHlp::disconnect()
{
int i = CITICs_HsHlp_DisConnect(this->handle);
return i;
};
//退出
int CsHsHlp::exit()
{
this->active = false;
int i = CITICs_HsHlp_Exit(this->handle);
return i;
};
//------------------------------------------------------------------------
//异步消息处理线程
//------------------------------------------------------------------------
//连续运行的消息处理函数
void CsHsHlp::processMsg()
{
LPMSG_CTRL msgCtrl; //控制信息
int type = 0; //消息类型
int reqNo = 0; //异步请求编号
int errorNo = 0; //错误代码
string errorInfo = ""; //错误信息
int row = 0; //行数
int col = 0; //列数
char key[64] = {0}; //键
char value[512] = {0}; //值
PyGILState_STATE gil_state; //GIL全局锁
//连续运行
while (this->active)
{
//初始化指针
msgCtrl = new MSG_CTRL();
//读取消息
int i = CITICs_HsHlp_QueueGetMsg(this->handle, msgCtrl, -1);
//读取信息
if (msgCtrl->nIssueType)
{
type = msgCtrl->nIssueType;
}
else
{
type = msgCtrl->nFuncID;
}
reqNo = msgCtrl->nReqNo;
errorNo = msgCtrl->nErrorNo;
errorInfo = msgCtrl->szErrorInfo;
row = CITICs_HsHlp_GetRowCount(this->handle, msgCtrl); //获取msg行数有多少个回应
col = CITICs_HsHlp_GetColCount(this->handle, msgCtrl); //获取msg列数有哪些字段
//生成字典并推送到Python中
gil_state = PyGILState_Ensure(); //创建Python对象前先锁定GIL
boost::python::list data;
for (int i = 0; i < row; i++)
{
if (0 == CITICs_HsHlp_GetNextRow(this->handle, msgCtrl))
{
dict d;
for (int j = 0; j < col; j++)
{
CITICs_HsHlp_GetColName(this->handle, j, key, msgCtrl);
CITICs_HsHlp_GetValueByIndex(this->handle, j, value, msgCtrl);
string str_key = key;
string str_value = value;
d[str_key] = str_value;
}
data.append(d);
}
}
this->onMsg(type, data, reqNo, errorNo, errorInfo);
PyGILState_Release(gil_state); //推送Python对象完成后释放GIL
//从队列删除消息
CITICs_HsHlp_QueueEraseMsg(this->handle, msgCtrl);
//删除指针
delete msgCtrl;
}
};
///-------------------------------------------------------------------------------------
///Boost.Python封装
///-------------------------------------------------------------------------------------
struct CsHsHlpWrap : CsHsHlp, wrapper < CsHsHlp >
{
virtual void onMsg(int type, boost::python::list data, int reqNo, int errorNo, string errorInfo)
{
//以下的try...catch...可以实现捕捉python环境中错误的功能防止C++直接出现原因未知的崩溃
try
{
this->get_override("onMsg")(type, data, reqNo, errorNo, errorInfo);
}
catch (error_already_set const &)
{
PyErr_Print();
}
};
};
BOOST_PYTHON_MODULE(vncshshlp)
{
PyEval_InitThreads(); //导入时运行保证先创建GIL
class_<CsHsHlpWrap, boost::noncopyable>("CsHsHlp")
.def("loadConfig", &CsHsHlpWrap::loadConfig)
.def("init", &CsHsHlpWrap::init)
.def("connectServer", &CsHsHlpWrap::connectServer)
.def("getErrorMsg", &CsHsHlpWrap::getErrorMsg)
.def("beginParam", &CsHsHlpWrap::beginParam)
.def("setValue", &CsHsHlpWrap::setValue)
.def("bizCallAndCommit", &CsHsHlpWrap::bizCallAndCommit)
.def("disconnect", &CsHsHlpWrap::disconnect)
.def("exit", &CsHsHlpWrap::exit)
.def("subscribeData", &CsHsHlpWrap::subscribeData)
.def("onMsg", pure_virtual(&CsHsHlpWrap::onMsg))
;
};

View File

@ -0,0 +1,99 @@
//说明部分
//系统
#include "stdafx.h"
#include <string>
#include <queue>
//Boost
#define BOOST_PYTHON_STATIC_LIB
#include <boost/python/module.hpp> //python封装
#include <boost/python/def.hpp> //python封装
#include <boost/python/dict.hpp> //python封装
#include <boost/python/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> //任务队列的任务实现
//API
#include "CITICs_HsT2Hlp.h"
//命名空间
using namespace std;
using namespace boost::python;
using namespace boost;
///-------------------------------------------------------------------------------------
///封装类
///-------------------------------------------------------------------------------------
class CsHsHlp
{
private:
HSHLPCFGHANDLE cfgHandle; //配置指针
HSHLPHANDLE handle; //操作对象指针
thread *task_thread; //工作线程指针向python中推送数据
bool active; //工作状态
public:
CsHsHlp()
{
this->active = false;
};
~CsHsHlp()
{
this->active = false;
};
//------------------------------------------------------------------------
//主动函数部分
//------------------------------------------------------------------------
//读取配置文件
int loadConfig(string fileName);
//初始化
int init();
//连接服务器
int connectServer();
//获取错误信息
string getErrorMsg();
//初始化发包请求
int beginParam();
//设置发包的参数字段名称和值
int setValue(string key, string value);
//发包
int bizCallAndCommit(int iFuncID);
//订阅
boost::python::list subscribeData(int iFuncID);
//断开服务器
int disconnect();
//退出
int exit();
//------------------------------------------------------------------------
//异步消息处理线程
//------------------------------------------------------------------------
//连续运行的消息处理函数
void processMsg();
//------------------------------------------------------------------------
//Python中继承的回调函数
//------------------------------------------------------------------------
//向Python中推送消息的函数
virtual void onMsg(int type, boost::python::list data, int reqNo, int errorNo, string errorInfo) {};
};

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{982DF24C-BCD1-4F25-BDE8-84ADB719588B}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>vncshshlp</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>C:\Users\Administrator\Desktop\vn.cs\vn.cs\hshlp;C:\Users\Administrator\Anaconda2\include;C:\boost_1_62_0;$(IncludePath)</IncludePath>
<ReferencePath>C:\boost_1_62_0\libs;C:\Users\Administrator\Anaconda2\libs;C:\Users\Administrator\Desktop\vn.cs\vn.cs\hshlp;$(ReferencePath)</ReferencePath>
<TargetExt>.pyd</TargetExt>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;VNCSHSHLP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;VNCSHSHLP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>C:\Users\Administrator\Desktop\vn.cs\vn.cs\hshlp;C:\Users\Administrator\Anaconda2\libs;C:\boost_1_62_0\stage\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\hshlp\CITICs_HsT2Hlp.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="vncshshlp.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</PrecompiledHeader>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="vncshshlp.cpp" />
</ItemGroup>
<ItemGroup>
<Library Include="..\..\hshlp\CITICs_HsT2Hlp.lib" />
<Library Include="..\..\hshlp\t2sdk.lib" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\hshlp\CITICs_HsT2Hlp.dll" />
<None Include="..\..\hshlp\t2sdk.dll" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="vncshshlp.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\hshlp\CITICs_HsT2Hlp.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="vncshshlp.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Library Include="..\..\hshlp\CITICs_HsT2Hlp.lib">
<Filter>Resource Files</Filter>
</Library>
<Library Include="..\..\hshlp\t2sdk.lib">
<Filter>Resource Files</Filter>
</Library>
</ItemGroup>
<ItemGroup>
<None Include="..\..\hshlp\CITICs_HsT2Hlp.dll">
<Filter>Resource Files</Filter>
</None>
<None Include="..\..\hshlp\t2sdk.dll">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
</Project>

View File

@ -309,8 +309,6 @@ class HistoryDataEngine(object):
print u'%s下载完成' %symbol
else:
print u'找不到合约%s' %symbol
#----------------------------------------------------------------------
def downloadEquityDailyBarts(self, symbol):
@ -362,7 +360,6 @@ def downloadEquityDailyBarts(self, symbol):
else:
print u'找不到合约%s' %symbol
#----------------------------------------------------------------------
def loadMcCsv(fileName, dbName, symbol):
"""将Multicharts导出的csv格式的历史数据插入到Mongo数据库中"""
@ -431,50 +428,7 @@ def loadTdxCsv(fileName, dbName, symbol):
print bar.date, bar.time
print u'插入完毕,耗时:%s' % (time()-start)
#----------------------------------------------------------------------
def loadTBCsv(fileName, dbName, symbol):
"""将TradeBlazer导出的csv格式的历史数据插入到Mongo数据库中
数据样本
//时间,开盘价,最高价,最低价,收盘价,成交量,持仓量
2017/04/05 09:00,3200,3240,3173,3187,312690,2453850
"""
import csv
start = time()
print u'开始读取CSV文件%s中的数据插入到%s%s' %(fileName, dbName, symbol)
# 锁定集合,并创建索引
client = pymongo.MongoClient(globalSetting['mongoHost'], globalSetting['mongoPort'])
collection = client[dbName][symbol]
collection.ensure_index([('datetime', pymongo.ASCENDING)], unique=True)
# 读取数据和插入到数据库
reader = csv.reader(file(fileName, 'r'))
for d in reader:
if len(d[0]) > 10:
bar = CtaBarData()
bar.vtSymbol = symbol
bar.symbol = symbol
bar.datetime = datetime.strptime(d[0], '%Y/%m/%d %H:%M')
bar.date = bar.datetime.date().strftime('%Y%m%d')
bar.time = bar.datetime.time().strftime('%H:%M:%S')
bar.open = float(d[1])
bar.high = float(d[2])
bar.low = float(d[3])
bar.close = float(d[4])
bar.volume = float(d[5])
bar.openInterest = float(d[6])
flt = {'datetime': bar.datetime}
collection.update_one(flt, {'$set':bar.__dict__}, upsert=True)
print '%s \t %s' % (bar.date, bar.time)
print u'插入完毕,耗时:%s' % (time()-start)
if __name__ == '__main__':
## 简单的测试脚本可以写在这里

View File

@ -23,7 +23,7 @@ for root, subdirs, files in os.walk(path):
# 接口目录名中必须含有Gateway
if 'Gateway' in foldername:
# 模块名称需要上前缀
moduleName = 'gateway.' + foldername
moduleName = 'vnpy.trader.gateway.' + foldername
try:
# 使用importlib动态载入模块并保存到字典中

View File

@ -0,0 +1,11 @@
{
"brokerID": "1000",
"mdAddress": "tcp://203.110.179.217:31213",
"userID": "请联系中信期货申请",
"ctpPassword": "请联系中信期货申请",
"opEntrustWay": "5",
"opStation": "111111111",
"fundAccount": "请联系中信证券申请",
"password": "请联系中信证券申请"
}

View File

@ -0,0 +1,10 @@
# encoding: UTF-8
import vtConstant
from cshshlpGateway import CshshlpGateway as gateway
gatewayName = 'CSHSHLP'
gatewayDisplayName = u'中信期权'
gatewayType = vtConstant.GATEWAYTYPE_EQUITY
gatewayQryEnabled = True

File diff suppressed because it is too large Load Diff

View File

@ -30,9 +30,10 @@ offsetMap = {}
offsetMap[OFFSET_OPEN] = defineDict['DFITC_SPD_OPEN']
offsetMap[OFFSET_CLOSE] = defineDict['DFITC_SPD_CLOSE']
offsetMap[OFFSET_CLOSETODAY] = defineDict['DFITC_SPD_CLOSETODAY']
offsetMap[OFFSET_CLOSEYESTERDAY] = defineDict['DFITC_SPD_CLOSE']
#offsetMap[OFFSET_CLOSEYESTERDAY] = defineDict['DFITC_SPD_CLOSE']
offsetMapReverse = {v:k for k,v in offsetMap.items()}
# 交易所类型映射
exchangeMap = {}
exchangeMap[EXCHANGE_CFFEX] = defineDict['DFITC_EXCHANGE_CFFEX']
@ -42,6 +43,12 @@ exchangeMap[EXCHANGE_DCE] = defineDict['DFITC_EXCHANGE_DCE']
exchangeMap[EXCHANGE_UNKNOWN] = ''
exchangeMapReverse = {v:k for k,v in exchangeMap.items()}
# 合约类型映射
productMap = {}
productMap[PRODUCT_FUTURES] = defineDict["DFITC_COMM_TYPE"]
productMap[PRODUCT_OPTION] = defineDict["DFITC_OPT_TYPE"]
productMapReverse = {v:k for k, v in productMap.items()}
# 委托状态类型映射
orderStatusMap = {}
orderStatusMap[STATUS_ALLTRADED] = defineDict["DFITC_SPD_FILLED"]
@ -128,9 +135,14 @@ class XspeedGateway(VtGateway):
self.tdApi.qryAccount()
#----------------------------------------------------------------------
def qryPosition(self):
def qryFuturesPosition(self):
"""查询持仓"""
self.tdApi.qryPosition()
self.tdApi.qryFuturesPosition()
#----------------------------------------------------------------------
def qryOptionPosition(self):
"""查询期权持仓"""
self.tdApi.qryOptionPosition()
#----------------------------------------------------------------------
def close(self):
@ -145,10 +157,10 @@ class XspeedGateway(VtGateway):
"""初始化连续查询"""
if self.qryEnabled:
# 需要循环的查询函数列表
self.qryFunctionList = [self.qryAccount, self.qryPosition]
self.qryFunctionList = [self.qryAccount, self.qryFuturesPosition, self.qryOptionPosition]
self.qryCount = 0 # 查询触发倒计时
self.qryTrigger = 2 # 查询触发点
self.qryTrigger = 1 # 查询触发点
self.qryNextFunction = 0 # 上次运行的查询函数索引
self.startQuery()
@ -422,8 +434,14 @@ class XspeedTdApi(TdApi):
self.sessionID = EMPTY_INT # 会话编号
self.posDict = {} # 缓存持仓数据的字典
self.optionPosReqID = 0 # 期权持仓查询ID
self.futuresPosReqID = 0 # 期货持仓查询ID
self.optionPosCompleted = False
self.futuresPosCompleted = False
self.orderDict = {} # 缓存委托数据的字典
self.spdOrderDict = {} # 飞创柜台委托号字典
self.contractDict = {} # 缓存合约数据的字典
#----------------------------------------------------------------------
def connect(self, accountID, password, address):
@ -466,13 +484,90 @@ class XspeedTdApi(TdApi):
self.reqQryCustomerCapital(req)
#----------------------------------------------------------------------
def qryPosition(self):
"""查询持仓"""
def qryFuturesPosition(self):
"""查询期货持仓"""
# 清空缓存
self.posDict.clear()
self.reqID += 1
req = {}
req['lRequestID'] = self.reqID
req['accountID'] = self.accountID
req['instrumentType'] = defineDict["DFITC_COMM_TYPE"]
self.reqQryPosition(req)
self.futuresPosReqID = self.reqID
#----------------------------------------------------------------------
def qryOptionPosition(self):
"""查询期权持仓"""
self.posDict.clear()
self.reqID += 1
req = {}
req['lRequestID'] = self.reqID
req['accountID'] = self.accountID
req['instrumentType'] = defineDict["DFITC_OPT_TYPE"]
self.reqQryPosition(req)
self.optionPosReqID = self.reqID
#----------------------------------------------------------------------
def qryContracts(self):
"""查询合约"""
# 查询期货合约代码
self.reqID += 1
req = {}
req['lRequestID'] = self.reqID
req['instrumentType'] = defineDict["DFITC_COMM_TYPE"]
self.reqQryExchangeInstrument(req)
sleep(1)
# 查询期权合约代码
self.reqID += 1
req = {}
req['lRequestID'] = self.reqID
req['instrumentType'] = defineDict["DFITC_OPT_TYPE"]
self.reqQryExchangeInstrument(req)
#----------------------------------------------------------------------
def qryTrade(self):
"""查询成交"""
# 查询成交
self.reqID += 1
req = {}
req['lRequestID'] = self.reqID
req['accountID'] = self.accountID
req['instrumentType'] = defineDict["DFITC_COMM_TYPE"]
self.reqQryMatchInfo(req)
sleep(1)
self.reqID += 1
req = {}
req['lRequestID'] = self.reqID
req['accountID'] = self.accountID
req['instrumentType'] = defineDict["DFITC_OPT_TYPE"]
self.reqQryMatchInfo(req)
#----------------------------------------------------------------------
def qryOrder(self):
"""查询委托"""
# 查询委托
self.reqID += 1
req = {}
req['lRequestID'] = self.reqID
req['accountID'] = self.accountID
req['instrumentType'] = defineDict["DFITC_COMM_TYPE"]
self.reqQryOrderInfo(req)
sleep(1)
self.reqID += 1
req = {}
req['lRequestID'] = self.reqID
req['accountID'] = self.accountID
req['instrumentType'] = defineDict["DFITC_OPT_TYPE"]
self.reqQryOrderInfo(req)
#----------------------------------------------------------------------
def sendOrder(self, orderReq):
@ -499,6 +594,11 @@ class XspeedTdApi(TdApi):
req['minMatchAmount'] = 1 # 最小成交量为1
req['lRequestID'] = self.reqID
# 合约类型获取
contract = self.contractDict.get(orderReq.symbol, None)
if contract:
req['instrumentType'] = productMap.get(contract.productClass, '')
self.reqInsertOrder(req)
# 返回订单号(字符串),便于某些算法进行动态管理
@ -568,11 +668,7 @@ class XspeedTdApi(TdApi):
log.logContent = u'交易服务器登录完成'
self.gateway.onLog(log)
# 查询合约代码
self.reqID += 1
req = {}
req['lRequestID'] = self.reqID
self.reqQryExchangeInstrument(req)
self.qryContracts()
# 否则,推送错误信息
else:
@ -607,6 +703,16 @@ class XspeedTdApi(TdApi):
def onRspInsertOrder(self, data, error) :
"""发单错误(柜台)"""
if error['nErrorID']:
order = VtOrderData()
order.gatewayName = self.gatewayName
order.symbol = error['instrumentID']
order.vtSymbol = order.symbol
order.orderID = str(error['localOrderID'])
order.vtOrderID = '.'.join([self.gatewayName, order.orderID])
order.sessionID = error['sessionID']
order.status = STATUS_REJECTED
self.gateway.onOrder(order)
err = VtErrorData()
err.gatewayName = self.gatewayName
err.errorID = error['nErrorID']
@ -751,43 +857,41 @@ class XspeedTdApi(TdApi):
#----------------------------------------------------------------------
def onRspQryOrderInfo(self, data, error, last) :
"""查询委托回报"""
if not data['localOrderID']:
return
# 更新最大报单编号
newLocalID = data['localOrderID']
self.localID = max(self.localID, int(newLocalID))
self.spdOrderDict[newLocalID] = data['spdOrderID']
# 获取报单数据对象
if newLocalID in self.orderDict:
order = self.orderDict[newLocalID]
else:
order = VtOrderData()
self.orderDict[newLocalID] = order
order.gatewayName = self.gatewayName
# 保存后续不会变化的数据
order.symbol = data['instrumentID']
order.exchange = exchangeMapReverse[data['exchangeID']]
order.vtSymbol = order.symbol
if data['instrumentID']:
# 更新最大报单编号
newLocalID = data['localOrderID']
self.localID = max(self.localID, int(newLocalID))
self.spdOrderDict[newLocalID] = data['spdOrderID']
order.orderID = str(newLocalID)
order.vtOrderID = '.'.join([self.gatewayName, order.orderID])
# 获取报单数据对象
if newLocalID in self.orderDict:
order = self.orderDict[newLocalID]
else:
order = VtOrderData()
self.orderDict[newLocalID] = order
order.gatewayName = self.gatewayName
order.direction = directionMapReverse.get(data['buySellType'], DIRECTION_UNKNOWN)
order.offset = offsetMapReverse.get(data['openClose'], OFFSET_UNKNOWN)
order.price = data['insertPrice']
order.totalVolume = data['orderAmount']
#order.sessionID = data['sessionID']
order.status = orderStatusMapReverse.get(data['orderStatus'], STATUS_UNKNOWN)
order.tradedVolume = data['matchedAmount']
order.orderTime = data['commTime']
# 保存后续不会变化的数据
order.symbol = data['instrumentID']
order.exchange = exchangeMapReverse[data['exchangeID']]
order.vtSymbol = order.symbol
order.orderID = str(newLocalID)
order.vtOrderID = '.'.join([self.gatewayName, order.orderID])
order.direction = directionMapReverse.get(data['buySellType'], DIRECTION_UNKNOWN)
order.offset = offsetMapReverse.get(data['openClose'], OFFSET_UNKNOWN)
order.price = data['insertPrice']
order.totalVolume = data['orderAmount']
#order.sessionID = data['sessionID']
order.status = orderStatusMapReverse.get(data['orderStatus'], STATUS_UNKNOWN)
order.tradedVolume = data['matchedAmount']
order.orderTime = data['commTime']
# 推送
self.gateway.onOrder(copy(order))
# 推送
self.gateway.onOrder(copy(order))
if last:
log = VtLogData()
@ -798,34 +902,35 @@ class XspeedTdApi(TdApi):
#----------------------------------------------------------------------
def onRspQryMatchInfo(self, data, error, last) :
""""""
# 创建报单数据对象
trade = VtTradeData()
trade.gatewayName = self.gatewayName
# 保存代码和报单号
trade.symbol = data['instrumentID']
trade.exchange = exchangeMapReverse.get(data['exchangeID'], EXCHANGE_UNKNOWN)
trade.vtSymbol = trade.symbol #'.'.join([trade.symbol, trade.exchange])
trade.tradeID = data['matchedID']
trade.vtTradeID = '.'.join([self.gatewayName, trade.tradeID])
trade.orderID = str(data['localOrderID'])
trade.vtOrderID = '.'.join([self.gatewayName, trade.orderID])
# 方向
trade.direction = directionMapReverse.get(data['buySellType'], DIRECTION_UNKNOWN)
if data['instrumentID']:
# 创建报单数据对象
trade = VtTradeData()
trade.gatewayName = self.gatewayName
# 开平
trade.offset = offsetMapReverse.get(data['openClose'], OFFSET_UNKNOWN)
# 保存代码和报单号
trade.symbol = data['instrumentID']
trade.exchange = exchangeMapReverse.get(data['exchangeID'], EXCHANGE_UNKNOWN)
trade.vtSymbol = trade.symbol #'.'.join([trade.symbol, trade.exchange])
# 价格、报单量等数值
trade.price = data['matchedPrice']
trade.volume = data['matchedAmount']
trade.tradeTime = data['matchedTime']
# 推送
self.gateway.onTrade(trade)
trade.tradeID = data['matchedID']
trade.vtTradeID = '.'.join([self.gatewayName, trade.tradeID])
trade.orderID = str(data['localOrderID'])
trade.vtOrderID = '.'.join([self.gatewayName, trade.orderID])
# 方向
trade.direction = directionMapReverse.get(data['buySellType'], DIRECTION_UNKNOWN)
# 开平
trade.offset = offsetMapReverse.get(data['openClose'], OFFSET_UNKNOWN)
# 价格、报单量等数值
trade.price = data['matchedPrice']
trade.volume = data['matchedAmount']
trade.tradeTime = data['matchedTime']
# 推送
self.gateway.onTrade(trade)
if last:
log = VtLogData()
@ -836,44 +941,50 @@ class XspeedTdApi(TdApi):
#----------------------------------------------------------------------
def onRspQryPosition(self, data, error, last) :
"""持仓查询回报"""
# 获取缓存字典中的持仓对象,若无则创建并初始化
positionName = '.'.join([data['instrumentID'], str(data['buySellType'])])
if positionName in self.posDict:
pos = self.posDict[positionName]
else:
pos = VtPositionData()
self.posDict[positionName] = pos
pos.gatewayName = self.gatewayName
# 保存代码
pos.symbol = data['instrumentID']
pos.vtSymbol = pos.symbol # 这里因为data中没有ExchangeID这个字段
# 方向
pos.direction = directionMapReverse.get(data['buySellType'], '')
# VT系统持仓名
pos.vtPositionName = '.'.join([pos.vtSymbol, pos.direction])
# 持仓量
if data['positionAmount']:
pos.position = data['positionAmount']
if data['lastAmount']:
pos.ydPosition = data['lastAmount']
# 持仓均价
pos.price = data['positionAvgPrice']
# 推送
newpos = copy(pos)
self.gateway.onPosition(newpos)
# 忽略空数据
if data['instrumentID']:
# 获取缓存字典中的持仓对象,若无则创建并初始化
positionName = '.'.join([data['instrumentID'], str(data['buySellType'])])
if positionName in self.posDict:
pos = self.posDict[positionName]
else:
pos = VtPositionData()
self.posDict[positionName] = pos
pos.gatewayName = self.gatewayName
# 保存代码
pos.symbol = data['instrumentID']
pos.vtSymbol = pos.symbol # 这里因为data中没有ExchangeID这个字段
# 方向
pos.direction = directionMapReverse.get(data['buySellType'], '')
# VT系统持仓名
pos.vtPositionName = '.'.join([pos.vtSymbol, pos.direction])
# 持仓量
if data['positionAmount']:
pos.position = data['positionAmount']
if data['lastAmount']:
pos.ydPosition = data['lastAmount']
# 持仓均价
pos.price = data['positionAvgPrice']
# 查询完成后推送
if last:
for pos in self.posDict.values():
self.gateway.onPosition(pos)
#----------------------------------------------------------------------
def onRspCustomerCapital(self, data, error, last) :
"""资金账户查询回报"""
if not data['accountID']:
return
account = VtAccountData()
account.gatewayName = self.gatewayName
@ -888,7 +999,8 @@ class XspeedTdApi(TdApi):
account.margin = data['margin']
account.closeProfit = data['closeProfitLoss']
account.positionProfit = data['positionProfitLoss']
account.balance = data['todayEquity']
account.balance = data['todayEquity']
account.marketValue = account.balance + data['optMarketValue']
# 推送
self.gateway.onAccount(account)
@ -902,21 +1014,21 @@ class XspeedTdApi(TdApi):
contract.symbol = data['instrumentID']
contract.exchange = exchangeMapReverse.get(data['exchangeID'], EXCHANGE_UNKNOWN)
contract.vtSymbol = contract.symbol #'.'.join([contract.symbol, contract.exchange])
contract.name = data['VarietyName'].decode('GBK') + contract.symbol
if data['VarietyName'] == contract.symbol:
contract.name = data['VarietyName']
else:
contract.name = data['VarietyName'].decode('GBK') + contract.symbol
# 合约数值
contract.size = data['contractMultiplier']
contract.size = int(data['contractMultiplier'])
contract.priceTick = data['minPriceFluctuation']
contract.strikePrice = data['strikePrice']
contract.underlyingSymbol = data['underlying']
contract.expiryDate = data['instrumentMaturity'].replace('.', '')
# 合约类型
if data['instrumentType'] == 0:
contract.productClass = PRODUCT_FUTURES
elif data['instrumentType'] == 1:
contract.productClass = PRODUCT_OPTION
else:
contract.productClass = PRODUCT_UNKNOWN
contract.productClass = productMapReverse.get(data['instrumentType'],
PRODUCT_UNKNOWN)
# 期权类型
if data['optionType'] == 1:
@ -926,26 +1038,17 @@ class XspeedTdApi(TdApi):
# 推送
self.gateway.onContract(contract)
self.contractDict[contract.symbol] = contract
if last:
if last and contract.productClass == PRODUCT_OPTION:
log = VtLogData()
log.gatewayName = self.gatewayName
log.logContent = u'交易合约信息获取完成'
self.gateway.onLog(log)
# 查询委托
self.reqID += 1
req = {}
req['lRequestID'] = self.reqID
req['accountID'] = self.accountID
self.reqQryOrderInfo(req)
# 查询成交
self.reqID += 1
req = {}
req['lRequestID'] = self.reqID
req['accountID'] = self.accountID
self.reqQryMatchInfo(req)
self.qryTrade()
sleep(1)
self.qryOrder()
#----------------------------------------------------------------------
def onRspArbitrageInstrument(self, data, error, last) :

View File

@ -12,7 +12,8 @@ DIRECTION_LONG = u'多'
DIRECTION_SHORT = u''
DIRECTION_UNKNOWN = u'未知'
DIRECTION_NET = u''
DIRECTION_SELL = u'卖出' # IB接口
DIRECTION_SELL = u'卖出' # IB接口
DIRECTION_COVEREDSHORT = u'备兑空' # 证券期权
# 开平常量
OFFSET_NONE = u'无开平'

View File

@ -13,6 +13,7 @@ DIRECTION_SHORT = u'short'
DIRECTION_UNKNOWN = u'unknown'
DIRECTION_NET = u'net'
DIRECTION_SELL = u'sell' # IB接口
DIRECTION_COVEREDSHORT = u'covered short' # 证券期权
# 开平常量
OFFSET_NONE = u'none'

View File

@ -24,8 +24,6 @@ class RmSpinBox(QtWidgets.QSpinBox):
self.setValue(value)
########################################################################
class RmLine(QtWidgets.QFrame):
@ -38,8 +36,6 @@ class RmLine(QtWidgets.QFrame):
self.setFrameShape(self.HLine)
self.setFrameShadow(self.Sunken)
########################################################################
class RmEngineManager(QtWidgets.QWidget):
@ -62,7 +58,7 @@ class RmEngineManager(QtWidgets.QWidget):
self.setWindowTitle(text.RISK_MANAGER)
# 设置界面
self.buttonSwitchEngineStatus = QtGui.QPushButton(text.RISK_MANAGER_STOP)
self.buttonSwitchEngineStatus = QtWidgets.QPushButton(text.RISK_MANAGER_STOP)
self.spinOrderFlowLimit = RmSpinBox(self.rmEngine.orderFlowLimit)
self.spinOrderFlowClear = RmSpinBox(self.rmEngine.orderFlowClear)
@ -71,12 +67,12 @@ class RmEngineManager(QtWidgets.QWidget):
self.spinWorkingOrderLimit = RmSpinBox(self.rmEngine.workingOrderLimit)
self.spinOrderCancelLimit = RmSpinBox(self.rmEngine.orderCancelLimit)
buttonClearOrderFlowCount = QtGui.QPushButton(text.CLEAR_ORDER_FLOW_COUNT)
buttonClearTradeCount = QtGui.QPushButton(text.CLEAR_TOTAL_FILL_COUNT)
buttonSaveSetting = QtGui.QPushButton(text.SAVE_SETTING)
buttonClearOrderFlowCount = QtWidgets.QPushButton(text.CLEAR_ORDER_FLOW_COUNT)
buttonClearTradeCount = QtWidgets.QPushButton(text.CLEAR_TOTAL_FILL_COUNT)
buttonSaveSetting = QtWidgets.QPushButton(text.SAVE_SETTING)
Label = QtGui.QLabel
grid = QtGui.QGridLayout()
Label = QtWidgets.QLabel
grid = QtWidgets.QGridLayout()
grid.addWidget(Label(text.WORKING_STATUS), 0, 0)
grid.addWidget(self.buttonSwitchEngineStatus, 0, 1)
grid.addWidget(RmLine(), 1, 0, 1, 2)
@ -97,13 +93,13 @@ class RmEngineManager(QtWidgets.QWidget):
grid.addWidget(Label(text.CONTRACT_CANCEL_LIMIT), 11, 0)
grid.addWidget(self.spinOrderCancelLimit, 11, 1)
hbox = QtGui.QHBoxLayout()
hbox = QtWidgets.QHBoxLayout()
hbox.addWidget(buttonClearOrderFlowCount)
hbox.addWidget(buttonClearTradeCount)
hbox.addStretch()
hbox.addWidget(buttonSaveSetting)
vbox = QtGui.QVBoxLayout()
vbox = QtWidgets.QVBoxLayout()
vbox.addLayout(grid)
vbox.addLayout(hbox)
self.setLayout(vbox)

View File

@ -101,9 +101,9 @@ class DirectionCell(QtWidgets.QTableWidgetItem):
def setContent(self, text):
"""设置内容"""
if text == DIRECTION_LONG or text == DIRECTION_NET:
self.setForeground(QtWidgets.QColor('red'))
self.setForeground(QtGui.QColor('red'))
elif text == DIRECTION_SHORT:
self.setForeground(QtWidgets.QColor('green'))
self.setForeground(QtGui.QColor('green'))
self.setText(text)
@ -144,8 +144,8 @@ class BidCell(QtWidgets.QTableWidgetItem):
super(BidCell, self).__init__()
self.data = None
self.setForeground(QtWidgets.QColor('black'))
self.setBackground(QtWidgets.QColor(255,174,201))
self.setForeground(QtGui.QColor('black'))
self.setBackground(QtGui.QColor(255,174,201))
if text:
self.setContent(text)
@ -166,8 +166,8 @@ class AskCell(QtWidgets.QTableWidgetItem):
super(AskCell, self).__init__()
self.data = None
self.setForeground(QtWidgets.QColor('black'))
self.setBackground(QtWidgets.QColor(160,255,160))
self.setForeground(QtGui.QColor('black'))
self.setBackground(QtGui.QColor(160,255,160))
if text:
self.setContent(text)
@ -392,7 +392,8 @@ class BasicMonitor(QtWidgets.QTableWidget):
path = QtWidgets.QFileDialog.getSaveFileName(self, vtText.SAVE_DATA, '', 'CSV(*.csv)')
try:
if not path.isEmpty():
#if not path.isEmpty():
if path:
with open(unicode(path), 'wb') as f:
writer = csv.writer(f)
@ -427,7 +428,7 @@ class BasicMonitor(QtWidgets.QTableWidget):
#----------------------------------------------------------------------
def contextMenuEvent(self, event):
"""右键点击事件"""
self.menu.popup(QtWidgets.QCursor.pos())
self.menu.popup(QtGui.QCursor.pos())
########################################################################

View File

@ -160,7 +160,7 @@ class MainWindow(QtWidgets.QMainWindow):
if not displayName:
displayName = gatewayName
displayName = gatewayName
actionName = vtText.CONNECT + displayName
menu.addAction(self.createAction(actionName, connect))

View File

@ -73,7 +73,7 @@ class ClientEngine(object):
#----------------------------------------------------------------------
def sendOrder(self, orderReq, gatewayName):
"""对特定接口发单"""
self.client.sendOrder(orderReq, gatewayName)
return self.client.sendOrder(orderReq, gatewayName)
#----------------------------------------------------------------------
def cancelOrder(self, cancelOrderReq, gatewayName):

View File

@ -85,7 +85,7 @@ class MainEngine(object):
gateway.connect()
# 接口连接后自动执行数据库连接的任务
self.dbConnect()
#self.dbConnect()
#----------------------------------------------------------------------
def subscribe(self, subscribeReq, gatewayName):