# GlTraderFree **Repository Path**: roywang/GlTraderFree ## Basic Information - **Project Name**: GlTraderFree - **Description**: 恒生PB文件下单助手 - **Primary Language**: C++ - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 16 - **Created**: 2019-02-27 - **Last Updated**: 2020-12-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 恒生PB文件下单助手使用与开发指南 ## 软件介绍 为了满足投资者日益增长的程序化交易需求,XX证券公司开发了这款基于恒生PB系统的下单辅助软件。本软件使用SQLite数据库文件作为用户接口,投资者可使用自己的程序化交易软件通过读写SQLite数据库来与本软件交互委托和回报数据。因此,本软件具有轻量级、便捷性等优点。 **开发语言** :C++ **开发环境** :VS2015 + QT5.11 **柜台接口** :恒生PB UFX ### 功能介绍 本软件主要功能是将第三方程序化交易软件写入in.db中的委托和撤单数据报给恒生PB,然后将恒生PB推送的委托回报和成交回报数据写入out.db供第三方软件读取。其架构示意图如下图所示。 ![架构示意图](https://images.gitee.com/uploads/images/2019/0124/122753_95654fd6_96270.png "1.png") 本软件包含以下功能: - 兼容恒生PB账号体系,使用原有的恒生PB账号即可登录本软件进行交易; - 支持沪深股票、基金、债券买卖; - 支持委托和撤单; - 支持查询当天的委托回报和成交数据(仅限通过本软件下达的委托); ### 使用方法 1. 使用VS2015编译并启动软件,在生成的config.ini中输入UFX服务端地址,例如“servers=192.168.0.2:9003”,保存并重启软件。 2. 输入用户名、密码、验证码进行登录。 3. 勾选"开启委托监控",开始监控SQLite委托和撤单表(委托表和撤单表的字段说明详见下一章),一旦发现有新的指令,会立即在"待报委托"页中显示。 4. 勾选要下单的委托,点击"下单"按钮,本软件将把委托发送给恒生PB。如果勾选了"开启快速下单"选项,则用户无需点击"下单"按钮,委托会直接发送到恒生PB中。 5 在"委托查询"和"成交查询"页,可查看委托明细和成交明细(委托明细和成交明细表的字段说明详见下文)。 ### 软件截图 ![登录截图](https://images.gitee.com/uploads/images/2019/0124/130715_ade6bb19_96270.png "2.png") ![主界面截图](https://images.gitee.com/uploads/images/2019/0124/130735_7efe8280_96270.png "3.png") ## 用户接口 ### 接口介绍 本软件使用SQLite数据库作为用户接口。SQLite是一个遵守ACID的轻量级关系型数据库管理系统。用户接口包括in.db和out.db两个数据库文件(保存在本软件的db目录下,实际的文件名为in\_yyyymmdd.db和out\_yyyymmdd.db,其中,yyyymmdd是年月日,例如:in\_20190102.db。为方便表述,本文一律用in.db和out.db代替),其中,in.db包含委托表(tentrust)和撤单表(twithdraw),用户可将委托或撤单指令分别写入这两张表中,本软件会自动读取表中的指令并报送给恒生PB。out.db包含委托明细表(tentrustlist)、成交明细表(tdeallist)和其他一些系统内部表,本软件会把收到的委托回报和成交回报数据插入或更新到这两张表中,用户可定时扫描这两张表中的变化来获取回报数据。数据库文件和数据库表的读写方式如下表所示。 | 数据库文件 | in.db | in.db |out.db |out.db | | --- | --- | --- | --- | --- | | 数据库表 | 委托表tentrust | 撤单表twithdraw | 委托明细表tentrustlist | 成交明细表tdeallist | | 用户程序化交易软件 | 可读写 | 可读写 | 只读 | 只读 | | 本软件 | 只读 | 只读 | 只写更新和插入 | 只写只插入 | 注意: - 务必使用WAL模式打开in.db,以避免多进程读写冲突,方法:打开数据库之后,执行语句PRAGMA journal\_mode=WAL; - 务必使用只读模式打开out.db,以避免多进程读写冲突。 下文将对这些数据库表所详细的介绍。 ### 输入接口 #### 委托表 tentrust 用户程序化交易软件将委托数据写入该表,本软件会定时读取表中的委托。表结构如下。 | 列名 | 名称 | 数据类型 | 插入示例 | 说明 | | --- | --- | --- | --- | --- | | id | 序号 | INTEGER | (空) | 主键,自增序号,无需插入。与tentrustlist表中的id一一对应 | | entrust\_time | 委托时间 | TIMESTAMP | (空) | 自动生成,无需插入 | | batch\_no | 委托批号 | INTEGER, | 1 | 用户自定义 | | account\_code | 账户编号 | TEXT(32), | 00020001 | 账户编号、资产单元编号、组合编号三者至少要传入一项,如资产单元编号或组合编号未传入则取默认资产单元或默认组合。账户编号建议传入,否则将影响性能。 | | asset\_no | 资产单元编号 | TEXT(16), | (空) | | combi\_no | 组合编号 | TEXT(16), | 1 | | market\_no | 交易市场 | TEXT(3), | 1 | 参见:交易市场 market\_no | | stock\_code | 证券代码 | TEXT(16), | 600000 | | | entrust\_direction | 委托方向 | TEXT(4), | 1 | 参见:委托方向 entrust\_direction | | price\_type | 价格类型 | TEXT(1), | 0 | 参见:价格类型 price\_type | | entrust\_price | 委托价格 | DOUBLE, | 10.2 | 单位:元 | | entrust\_amount | 委托数量 | DOUBLE, | 100 | 单位:股 | | ext\_access\_system\_id | 用户交易系统自定义序号 | INTEGER | 223 | 用户可根据该字段与委托明细表、成交明细表中的记录相关联。 | #### 撤单表 twithdraw 用户程序化交易软件将撤单数据写入该表,本软件会定时读取。表结构如下。 | 列名 | 名称 | 数据类型 | 插入示例 | 说明 | | --- | --- | --- | --- | --- | | id | 序号 | INTEGER | (空) | 主键,自增序号,无需插入 | | entrust\_time | 委托时间 | TIMESTAMP | (空) | 自动生成,无需插入 | | entrust\_no | 委托编号 | INTEGER, | 67171 | 恒生PB返回的委托编号。可在委托明细表中获取。 | 注意: - 不支持查询撤单委托的状态。 - 可在委托明细表中查询原委托的撤单结果,包括:待撤、已撤、部撤和撤单失败原因。 - 如果写入的委托编号entrust\_no无效,则该撤单记录将被忽略,仅在软件界面输出错误信息,不会在数据库中输出错误信息。 - 由于网络异常导致委托状态是"未响应"的委托,本软件不会再次发送,此类型委托无法撤单。 ### 输出接口 #### 委托明细表 tentrustlist 在接收到回报数据时(委托状态、成交数量等数据发生变化),本软件会将新的委托信息插入或者更新老的委托数据。表结构如下。 | 列名 | 名称 | 数据类型 | 示例 | 说明 | | --- | --- | --- | --- | --- | | id | 序号 | INTEGER | 1 | 主键,与tentrust表中的id一一对应 | | business\_time | 委托时间 | TIMESTAMP | 2019-01-01 10:30:32 | 格式:yyyy-MM-dd hh:mm:ss | | entrust\_no | 委托序号 | INTEGER | 1 | 用户自定义 | | entrust\_status | 委托状态 | TEXT(1) | 1 | 参见:委托状态 entrust\_status | | account\_code | 账户编号 | TEXT(32) | 00020001 | 与tentrust表中的对应字段一致 | | asset\_no | 资产单元编号 | TEXT(16) | (空) | 与tentrust表中的对应字段一致 | | combi\_no | 组合编号 | TEXT(16) | 1 | 与tentrust表中的对应字段一致 | | market\_no | 交易市场 | TEXT(3) | 1 | 参见:交易市场 market\_no | | stock\_code | 证券代码 | TEXT(16) | 600000 | | | entrust\_direction | 委托方向 | TEXT(4) | 1 | 参见:委托方向 entrust\_direction | | price\_type | 价格类型 | TEXT(1) | 0 | 参见:价格类型 price\_type | | entrust\_price | 委托价格 | DOUBLE | 10.2 | 单元:元 | | entrust\_amount | 委托数量 | DOUBLE | 100 | 单位:股 | | cancel\_deal\_amount | 撤成数量 | DOUBLE | 0 | 0:未撤单或撤单失败;非0:成功撤单的数量,单位:股 | | fail\_cause | 废单原因 | TEXT(256) | (空) | 空:成功;非空:委托或撤单失败的原因 | | ext\_access\_system\_id | 用户交易系统自定义序号 | INTEGER | 223 | 用户可根据该字段与委托明细表、成交明细表中的记录相关联。 | | ext\_system\_id | 外部系统序号 | INTEGER | | 系统内部字段,用户无需关注 | 注意:用户需定期读取该表,以获取委托回报信息。 - 小技巧:用户可在本表中增加"最近更新时间"字段,并添加触发器:当记录被插入或者更新时自动修改该字段的值为当前时间。通过对该字段的筛选,可以获取最近收到回报消息的委托。 #### 成交明细表 tdeallist 在接收到成交回报数据时,本软件会将该数据插入本表(只插入,不更新)。表结构如下。 | 列名 | 名称 | 数据类型 | 示例 | 说明 | | --- | --- | --- | --- | --- | | deal\_time | 成交时间 | TIMESTAMP | 2019-01-01 10:30:32 | 主键,与tentrust表中的id一一对应 | | deal\_no | 成交编号 | INTEGER | 39281 | 格式:yyyy-MM-dd hh:mm:ss | | entrust\_no | 委托序号 | INTEGER | 1 | 可使用该字段与tentrustlist关联 | | entrust\_status | 委托状态 | TEXT(1) | 1 | 参见:委托状态 entrust\_status | | account\_code | 账户编号 | TEXT(32) | 00020001 | 与tentrust表中的对应字段一致 | | asset\_no | 资产单元编号 | TEXT(16) | (空) | 与tentrust表中的对应字段一致 | | combi\_no | 组合编号 | TEXT(16) | 1 | 与tentrust表中的对应字段一致 | | market\_no | 交易市场 | TEXT(3) | 1 | 参见:交易市场 market\_no | | stock\_code | 证券代码 | TEXT(16) | 600000 | | | entrust\_direction | 委托方向 | TEXT(4) | 1 | 参见:委托方向 entrust\_direction | | price\_type | 价格类型 | TEXT(1) | 0 | 参见:价格类型 price\_type | | deal\_price | 成交价格 | DOUBLE | 10.2 | 单元:元 | | deal\_amount | 成交数量 | DOUBLE | 100 | 单位:股 | | deal\_balance | 成交金锷 | DOUBLE | 1020 | 单元:元 | | deal\_fee | 本次费用 | DOUBLE | 5 | 单元:元 | | ext\_access\_system\_id | 用户交易系统自定义序号 | INTEGER | 223 | 用户可根据该字段与委托明细表、成交明细表中的记录相关联。 | 注意:一笔委托可能对应多笔成交数据,委托和成交记录之间可通过entrust\_no进行关联。 ### 数据字典 本章节将列出常用的几个数据字典,完整的数据字典可查看gltrader.db中的tdict表。 #### 交易市场 market\_no | market\_no | 交易市场 | | --- | --- | | 1 | 上交所 | | 2 | 深交所 | #### 委托方向 entrust\_direction | entrust\_direction | 委托方向 | | --- | --- | | 1 | 买入 | | 2 | 卖出 | - 注意:委托方向只支持1、2 #### 价格类型 price\_type | price\_type | 价格类型 | | | --- | --- | --- | | 0 | 限价 | | | a | 五档即成剩撤(上交所市价) | 最优5档即时成交剩余撤销申报,即该申报在对手方实时最优5个价位内以对手方价格为成交价逐次成交,剩余未成交部分自动撤销。 | | b | 五档即成剩转(上交所市价) | 最优5档即时成交剩余转限价申报,即该申报在对手方实时5个最优价位内以对手方价格为成交价逐次成交,剩余未成交部分按本方申报最新成交价转为限价申报;如该申报无成交的,按本方最优报价转为限价申报;如无本方申报的,该申报撤销。 | | A | 五档即成剩撤(深交所市价) | 以对手方价格为成交价,与申报进入交易主机时集中申报簿中对手方最优五个价位的申报队列依次成交,未成交部分自动撤销。 | | C | 即成剩撤(深交所市价) | 以对手方价格为成交价,与申报进入交易主机时集中申报簿中对手方所有申报队列依次成交,未成交部分自动车小。 | | D | 对手方最优(深交所市价) | 以申报进入交易主机时集中申报簿中对手方队列的最优价格为其申报价格。 | | E | 本方最优(深交所市价) | 以申报进入交易主机时集中申报簿中本方队列的最优价格为其申报价格。 | | F | 全额成或撤(FOK市价)(深交所市价) | 以对手方价格为成交价,如与申报进入交易主机时集中申报簿中对手方所有申报队列依次成交能否使其完全成交的,则依次成交,否则申报全部自动撤销。 | #### 委托状态 entrust\_status | entrust\_statues | 委托状态 | | --- | --- | | 0 | 未响应(本软件已将委托指令发送给PB,但如果网络异常导致PB未接收到,则为该状态) | | 1 | 未报 | | 2 | 待报 | | 3 | 正报 | | 4 | 已报 | | 5 | 废单 | | 6 | 部成 | | 7 | 已成 | | 8 | 部撤 | | 9 | 已撤 | | a | 待撤 | #### 数据字典全集 使用SQLite可视化客户端打开本软件同级目录下的gltrader.db,查询tdict表,可看到如下数据: | Dict\_id | Item | Remark | | --- | --- | --- | | 3 | 0 | 未响应 | | 3 | 1 | 未报 | | 3 | 2 | 待报 | | 3 | 3 | 正报 | | 3 | 4 | 已报 | | 3 | 5 | 废单 | | 4 | 1 | 上交所 | | 4 | 2 | 深交所 | 其中,dict\_id是字典类型,取值范围为: | Dict\_id | 表字段 | 中文说明 | | --- | --- | --- | | 1 | account\_type | 账户类型 | | 3 | entrust\_state | 委托状态 | | 4 | market\_no | 交易市场 | | 5 | invest\_type | 投资类型 | | 6 | entrust\_direction | 委托方向 | | 7 | price\_type | 价格类型 | | 8 | position\_flag | 多空标志 | | 9 | instance\_type | 交易实例类型 | | 10 | currency\_code | 币种 | | 11 | account\_category | 资产账户类型 | | 12 | origin\_type | 账户来源 | | 13 | replace\_flag | 现金替代标志 | | 14 | ambusiness\_type\_limits | 业务类别 | | 15 | risk\_type | 风控类别 | | 16 | risk\_operation | 风控触警操作 | | 17 | entrust\_fail\_code | 委托失败代码 | | 18 | option\_type | 期权类型 | | 19 | purchase\_way | 申赎方式 | | 20 | adjust\_mode | 资金调整类型 | | 21 | stock\_type\_limits | 证券类别权限 | | 22 | business\_op\_flag | 业务操作类型 | | 23 | future\_kind\_id | 期货品种序号 | | 24 | bind\_status | 股东指定状态 | ## 软件内部逻辑 ### 启动过程 1. 打开当天的in.db和out.db,如果不存在,则自动创建。 2. 连接恒生PB,进行账号登录。 3. **消息补缺,即接收在本软件关闭期间遗漏的推送信息** 。例如,如果软件异常关闭,可能会接收不到委托回报或成交回报数据,在软件启动后,恒生PB会重新发送这些数据。 4. 从out.db的运行参数表(trunconfig)中读取已经处理过的委托和撤单记录id,从该id的下一个数字开始,定期扫描委托表(tentrust)和撤单表(twithdraw)中的新记录,开始报单。 5. 从in.db读取委托表(tentrust)和撤单表(twithdraw)中的新记录,显示在"待报委托"界面,提示用户手动下单(即使开启了快速委托,也需手动下单)。 ### 委托和回报过程 1. 本软件从委托表(tentrust)读取新的委托指令。 2. 如果设置了 "开启快速下单",则该委托指令会被直接发送给恒生PB;如果没有设置,则在软件界面"待报委托"页中显示该委托,等用户点击"下单"按钮后再发送给恒生PB。如果发送成功,则更新trunconfig中的"当前已处理的委托最大id"为当前委托记录的id值。 3. 在tentrustlist中插入该委托记录,委托编号为零,委托状态为"未响应"。 4. 接收恒生PB应答消息,更新tentrustlist中的委托编号。如果指令错误,例如产品或组合编号无效,则将委托状态更新为"废单",并更新废单原因。 5. 恒生PB完成对委托指令的校验,发送"委托下达"消息,本软件将委托状态更新为"未报"。如果指令错误,例如价格超过涨跌停幅度,则将委托状态更新为"废单",并更新废单原因。 6. 恒生PB将指令成功报送到集中交易柜台,发送"委托确认"消息,本软件将委托状态更新为"已报"。如果集中交易柜台检查委托数据失败,则将委托状态更新为"废单",并更新废单原因。 7. 恒生PB发送"委托成交"消息,本软件将委托状态更新为"已成"或"部成",并在tdeallist中插入成交回报信息。 8. 如果在委托全部成交之前发送撤单指令,则委托状态会变为"待撤",如果撤单指令错误,则委托状态为"撤废";如果撤单成功,则委托状态变为"部撤"或"已撤"。如果委托已经全部成交,则委托状态为"已成",废单原因字段会提示"该委托状态下无法进行撤单"。 ## 注意事项 1. 当网络出现异常时,本软件不会自动重连服务器。因此,如果发现委托状态长时间是"未响应"(从发送委托到接收到应答消息,委托状态是"未响应"),那么需检查网络是否正常,并重启客户端。 2. 本软件会将运行信息写入./log/gltrader.log文件,如果软件报错或出现异常,可在该日志文件中搜索关键字"[WARN]"、"[ERROR]"以获取更详细的错误信息。也可将软件界面截图,连同该日志文件一起提交给我司,以便进一步分析问题原因。 3. 本软件启动过程中会自动读取委托表和撤单表中未处理的委托,不管是否开启了"快速下单",这些委托都需要手动点击"下单"按钮进行下单,不自动下单。对于启动成功后用户写入委托表的委托,"快速下单"选项才会起作用。 4. 如果软件出现错误,例如网络故障、软件内部逻辑错误、数据库操作失败等,界面会给出错误提示和警告音,同时,"快速下单"选项会自动禁用,待错误排除后,请手动启用"快速下单"。 ## 联系方式:thorqq@163.com