# 沪深行情 C++ Pro SDK 环境与接口手册 来源:https://doc.annhoo.cn/hushensdk/pro.html 摘要:安湖沪深行情 C++ Pro SDK 技术手册,涵盖 GCC 8.5.0+ 编译环境、依赖安装、行情订阅与回调、数据结构和版本修订记录。 安湖行情服务是 FPGA 极速行情 接入的开发包,支持 linux 系统,以动态库(.so)和静态库 (.a) 两种形式提供给开发者。行情用户可以通过 sdk 的接口文档和 sdk 头文件,轻松实现行情的接入, 并对行情做自定义的回调处理操作。本手册主要分为: 系统环境配置 行情 sdk 系统 行情 sdk 回调 等三部分组成。为 FPGA 行情的开发人员、测试人员和运维人员而提供相应的资料文档. 系统环境配置是指行情sdk系统运行时,所依赖的系统库,软件库等。主要有 gcc-8.5.0+ other tools 由于行情 SDK 系统采用了 c++11/c++14/c++17 新特性开发, 而 redhat 7 内置的 gcc 版本为 4.8.5 。 gcc-8.5.0 是一个较为全面支持 c++17. 建议通过源码安装 gcc,且版本 最低 为 gcc-8.5.0, 可以通过网络下载源码: wget https://ftp.gnu.org/gnu/gcc/gcc-8.5.0/gcc-8.5.0.tar.gz 对上述 gcc 压缩包解压: tar xvf gcc-8.5.0.tar.gz name | package name | download url | description | m4 | m4-1.4.16-10.el7.x86_64.rpm | m4下载 | 编译 gmp 依赖 | gmp | gmp-6.2.1.tar | 源码安装,压缩包已提供(最低版本4.2+) | gcc源码编译前需要安装 | mpfr | mpfr-4.1.0.tar.bz2 | 源码安装,压缩包已提供(最低版本2.4+) | gcc源码编译前需要安装 | mpc | mpc-1.2.0.tar.gz | 源码安装,压缩包已提供(最低版本0.8+) | gcc源码编译前需要安装 | isl | isl-0.16.1.tar.bz2 | 源码安装,压缩包已提供 | gcc源码编译前需要安装 | 如果系统可以联网, 那么可以直接在 gcc 目录下的执行: cd gcc-8.5.0 ./contrib/download_prerequisites make -j$(nproc) sudo make install 其中, m4 通过离线的安装包安装. gmp, mpfr , mpc 和 isl 通过源码编译安装。 如果系统可以联网,可直接在 gcc 目录下的执行: ./contrib/download_prerequisites 即可实现四个依赖的联网安装。另外,以上四个包, 详见压缩在文件 infrastructure.tar.bz2. m4 对应的安装包为 m4-1.4.16-10.el7.x86_64.rpm 如果系统联网不便, 我们也提供了压缩文件: infrastructure.tar.bz2, 该压缩包文件有: gmp-6.2.1.tar.bz2 mpc-1.2.1.tar.gz mpfr-4.1.0.tar.bz2 isl-0.24.tar.bz2 另外还有一个编译脚本 upgrade-gcc.sh 可以一键编译, 步骤如下: 切换到解压后的 gcc 目录下 拷贝 infrastructure.tar.bz2 和 upgrade-gcc.sh 至 gcc 源码目录 解压 infrastructure.tar.bz2 执行 upgrade-gcc.sh 即可 大概编译20-30分钟左右。等编译安装完成后,请执行以下命令行: echo /usr/local/gcc8/lib | sudo tee -a /etc/ld.so.conf echo /usr/local/gcc8/lib64 |sudo tee -a /etc/ld.so.conf sudo ldconfig 如果 gcc 没有安装, 请在线安装 sudo yum group install "Development Tools" 如果编译 gcc 中途出错, 可能需要 m4. 在Redhat7 中, 离线安装包请点击 m4下载地址, 下载后的rpm包为: m4-1.4.16-10.el7.x86_64.rpm , 安装命令: rpm -ivh m4-1.4.16-10.el7.x86_64.rpm. 如果系统支持在线安装, 请执行: yum install m4 即可 如果 cmake 没有安装, 请在线安装 sudo yum install cmake 缺省的 cmake 版本比较低, 需要升级. 版本为 3.11+, 然后请在线安装 sudo yum install openssl openssl-devel 以便对 cmake 进行源码编译升级安装 cmake 最新源码: cmake 源码, 编译安装命令为: ./bootstrap && make -j$(nproc) && sudo make install . 编译后请执行 hash -r 以便所安装的最新版本 cmake 生效 升级安装后的 gcc 版本, 可以在项目的 cmake 参数中指定 gcc 的路径: cmake -DCMAKE_CXX_COMPILER=/usr/local/gcc8/bin/g++ ..(即指向所安装的 gcc 路径). 或者在 CMakeLists.txt 中的 project 前面强行设置: set(CMAKE_CXX_COMPILER /usr/local/gcc8/bin/g++) 以上部分( 2-4 ) 为 sdk 的环境依赖的准备工作, 现在进入 行情SDK系统 部分, 分为: 目录结构说明 运行环境说明 [annhoo_md_sdk_demo] tree -L 3 . ├── bin │ ├── annhoo_md_sdk_demo │ ├── get_version │ └── subscribe ├── CMakeLists.txt ├── conf │ └── config_annhoo_md_sdk.yaml ├── examples │ ├── get_version │ │ ├── CMakeLists.txt │ │ └── get_version.cpp │ └── subscribe │ ├── CMakeLists.txt │ └── subscribe.cpp ├── include │ ├── annhoo_md_sdk │ │ ├── ah_md_api.h │ │ ├── ah_md_common.h │ │ └── ah_md_spi.h │ └── cmdline.h ├── lib │ └── libannhoo_md_sdk.so ├── README.md ├── spdlog_lib │ ├── libannhoo_md_sdk.a │ └── libannhoo_md_sdk.so ├── inner_lib │ ├── libannhoo_md_sdk.a │ └── libannhoo_md_sdk.so ├── src │ ├── ah_md_spi_inl.cpp │ ├── ah_md_spi_inl.h │ └── main.cpp ├── start.sh ├── stop.sh └── tick_bulk_sf └── inner_lib └── libannhoo_md_sdk.so 目录结构详情: bin : demo的二进制 生成目录 bin/annhoo_md_sdk_demo: 二进制可执行文件, 行情可落地文件 bin/get_version: 二进制可执行文件, 可得到sdk的版本信息: 编译时间,commit hash,分支等信息 bin/subscribe: 二进制可执行文件, 演示订阅功能, 所订阅的行情输出到控制台 CMakeLists.txt : demo 的 CMake 文件 conf : sdk 的 配置文件目录 conf/config_annhoo_md_sdk.yaml : sdk配置文件, 为 ymal 格式 include : sdk 所依赖的 头文件目录 include/ah_md_spi.h : 用户需要实现的 行情的四个回调接口文件 include/ah_md_api.h : sdk 的 行情实现接口文件 include/ah_quotes_common.h : sdk 的 行情数据结构文件, 主要定义了四种行情的数据结构和其他数据结构 lib : sdk 的 库文件目录 lib/libannhoo_md_sdk.a : 静态库 文件 lib/libannhoo_md_sdk.so : 动态库 文件 src : demo 源码目录 ah_md_spi_inl.h : 用户自定义实现的 行情的四个回调函数 的头文件 ah_md_spi_inl.cpp : 用户自定义实现的 行情的四个回调函数 的源文件 main.cpp : sdk 调用样例 examples/get_version.cpp : sdk 调用样例源码, 获取版本信息 examples/subscribe.cpp : sdk 调用样例源码, 订阅功能演示 start.sh : 一键启动脚本 stop.sh : 一键停止脚本 重要 需要注意的是,目前sdk自带的日志有两套, 一套是基于spdlog的,另外一套是非spdlog。因为 spdlog 的初始化不能够同时存在于sdk和应用。如果应用也是采用了spdlog作为日志库,那么请使用非spdlog日志的版本 行情sdk和 FPGA在相同网络环境中的机器上运行,可使用 linux onload(需要solarflare 网卡支持),这样能进一步降低网络延时 RedHat RHEL 7.4 x64 及以上版本 如果 gcc 版本不支持 c++17, 需要对 gcc 升级. 升级步骤前面章节已有相应的详细升级步骤, 并有相应的压缩包提供 CPU 主频的越高越好,且 cpu核六个以上 (含) 行情sdk的回调主要包含开发流程, 配置说明和各个接口说明 调用 NewMdApi 创建 IAHMdApi sdk的行情api接口 按照自己的业务从 IAHMdSpi 派生出一个子类,并实现自己关心的回调接口(如委托行情回调 OnTickCB 等),方法可参考 src/ah _md_spi_inl.cpp 和 src/ah_md_spi_inl.h 中的 AHMdSpiInl 实现代码. 调用 IAHMdApi::RegisteAH pi 接口, 把第二步所生成的自定义回调对象注册到 IAHMdApi 中 调用 IAHMdApi::SubscribeXXX 接口订阅所关心的行情数据 调用 IAHMdApi::Start 启动行情服务 调用 IAHMdApi::Join 等待行情服务结束 调用 IAHMdApi::UnRegisterSpi 注销行情回调, 释放行情回调和行情接口 配置文件目前支持两个格式的配置 ini yaml 缺省的配置文件格式是 ini. 下面以 yaml 格式作为解说. ini 类同. [quotes_sdk_demo]$ cat conf/config_annhoo_md_sdk.yaml market: - sh - sz sh: # if tcp was set, all datas come from tcp(just for tcp test) # tcp: # host: 192.168.9.202 # port: 9091 quotes_server: - master - slave master: # host: 224.0.0.1 host: 232.4.102.96 timeout: 99999 try_count: 99999 imr_interface: 192.168.9.202 slave: #host: 224.0.0.1 host: 232.4.102.96 timeout: 99999 try_count: 99999 imr_interface: 192.168.9.202 server: url: 192.168.1.205:8080 ip: 192.168.1.201 port: 8080 mac: b4:2e:99:8f:7d:50 name: yyds pwd: anhoo sz: # if tcp was set, all datas come from tcp(just for tcp test) # tcp: # host: 192.168.9.202 # port: 9091 quotes_server: - master - slave master: host: 232.4.102.98 timeout: 99999 try_count: 99999 imr_interface: 192.168.9.30 slave: host: 232.4.102.98 timeout: 99999 try_count: 99999 imr_interface: 192.168.9.202 server: url: 192.168.1.205 ip: 192.168.1.201 port: 8080 mac: b4:2e:99:8f:7d:50 name: yyds pwd: anhoo # quotes lists quotes_type: - index - snapshot - tick index: port: [22345, 12345] recv_np: [1, 2] # recv udp thread np dispatch_np: 10 # attach cpu index snapshot: port: [22346, 12346] recv_np: [3, 4] # recv udp thread np dispatch_np: 11 # attach cpu index tick: port: [22347, 12347] recv_np: [5, 6] # recv udp thread np dispatch_np: 12 # attach cpu index logger: name: annhoo_md_sdk.log # 0: trace # 1: debug # 2: info # 3: warn # 4: error # 5: fatal # 6: off level: 2 rotate_size: 100 rotate_total: 5 stdout: false system: # solar flare name for sh, sz. interface: [p1p1, p1p1] # if network is normal, interface name should be AH_NONE # interface: [AH_NONE, AH_NONE] # should have root/sudo to increase process permission nice: -20 queue_size: 60000 recv_mem_size: 1234567 market : 市场类别, 其中: sh-上海, sz-深圳 quotes_server : 主备, 此项包含后面的为主备的总述(保留) server : 登录 FPGA 服务器配置, 默认关闭(保留) host : udp 主备的 组播地址(保留) imr_interface : 为多网卡时, 指定接收udp的网口地址. 如果是单网卡, 请保留其值: 0.0.0.0 quotes_type : 行情类别, 当前四种. 如果不需要行情, 可以用 # 注释而不启用(保留) port : 每种行情的监听端口, 端口依次为sh, sz recv_np : 每种行情接收线程所要绑定的cpu核的索引号(-1代表不绑核, >=0 代表说绑定的cpu序列号). 依次为 sh, sz dispatch_np : 分发线程所要绑定的cpu核的索引号(-1代表不绑核, >=0 代表说绑定的cpu序列号) name : 日志名称 level : 所要输出的日志级别 rotate_size : 日志文件大小, 单位为 M rotate_total :日志文件个数 stdout : 日志是否打印屏幕, 需要注意的是,如果sdk采用的是非spdlog日志的 inner_lib 版本,那么此项开关是互斥的,即 打屏幕后不再同时打印日志文件. nice : 是进程优先级, 需要sudo权限, 普通用户请忽略该选项, linux的取值范围为 [-20, 19) queue_size : 缓存队列长度大小, 数越大占的内存越大,队列越大,缓存相对越大。 recv_mem_size : 为 udp 的接收缓存的大小设置(比如配成 67108864 为 64M), 该项依赖于系统所设的缓存值. 此项是非 solar flare 网卡所留,solar flare的用户态版本忽略此项配置。 tick: 含逐笔委托和逐笔成交, 两者要么全订阅要么不订阅. interface: solar flare 网卡的名字,依次为沪市,深市。请填充完整,如果沪深两市用同一个网卡,且sdk同时支持沪深两市,请配置同样的solar flare网卡名。如果是非solar flare, 那么此项需要设置为:[AH_NONE, AH_NONE] 目前的 sdk 日志有: 调试日志: 1 - debug 一般日志: 2 - info 警告日志: 3 - warn 错误日志: 4 - error 致命日志: 5 - fatal(该日志, 程序不正常, 必须停止排查) 关闭所有日志: 6 - off 该值对应 udp 接收缓存的设置. 可以通过如下命令展示系统默认的接收缓存的值: [root@hpserver206 quotes_sdk_demo]# cat /proc/sys/net/core/rmem_default 268435456 行情服务系统配置文件的 recv_mem_size 所设的值, 如果大于等于 /proc/sys/net/core/rmem_default 的 2倍, 则行情服务会以 rmem_default*2 为准. 反之, 则以所设的 recv_mem_size 为准. 建议对 /proc/sys/net/core/rmem_default 进行适当调大, 以减少udp掉包率. 可通过如下命令调整(需要sudo权限) echo 268435456 > /proc/sys/net/core/rmem_default # set to 256M echo 536870912 > /proc/sys/net/core/rmem_max # set to 512M ldconfig 需要注意的是, 此为临时修改, 系统重启后改修改失效. 设置永久值 sudo 权限 编辑 /etc/sysctl.conf 文件 sudo vi /etc/sysctl.conf 在文件的末尾添加以下行: net.core.rmem_default = 268435456 net.core.rmem_max = 536870912 保存并关闭文件 运行以下命令使配置生效: sudo sysctl -p 这将重新加载配置文件并应用更改 如果要启用 yaml, 需要设置环境变量 export AH_LOAD_FILE_FORMAT_YAML=1 或者 export AH_LOAD_FILE_FORMAT=true yaml 和 ini 互斥, 二者之能够二选一 ini 格式启用可以 export AH_LOAD_FILE_FORMAT=0 或者 export AH_LOAD_FILE_FORMAT=false 或者 unset AH_LOAD_FILE_FORMAT [market] markets_type=sz ; 行情推送方式 0-salarflare的组播 1-普通网卡组播 2-tcp recv_type=0 queue_size=600 recv_mem_size=209715200 nice=-20 [sh] #普通网卡使用如下配置 #interface: [AH_NONE, AH_NONE] #solarfare 网卡使用下面配置,p1p1表示 网卡名称 interface=p1p1 auth_url=192.168.9.32 auth_ip=192.168.9.28 auth_port=80 auth_mac=00:0f:53:ad:5d:80 auth_name=EX1714986746948035 auth_pwd=888888 [sh_udp] master_host=232.4.102.96 master_timeout=99999 master_try_count=99999 master_imr_interface=192.168.9.28 slave_host=232.4.102.96 slave_timeout=99999 slave_try_count=99999 slave_imr_interface=192.168.9.28 [sh_index] port=32345 recv_np=1 [sh_snapshot] port=32346 recv_np=3 [sh_tick] port=22347 recv_np=5 ; recv_type=2 [sh_tcp] host=192.168.9.13 port=20068 [sz] #普通网卡使用如下配置 #interface: [AH_NONE, AH_NONE] #solarfare 网卡使用下面配置,p1p1表示 网卡名称 interface=p1p1 auth_url=192.168.9.32 auth_ip=192.168.9.28 auth_port=80 auth_mac=56:82:ab:22:ba:fd auth_name=EX1715047404885022 auth_pwd=888888 [sz_udp] master_host=232.4.102.98 master_timeout=99999 master_timeout=99999 master_imr_interface=192.168.9.28 slave_host=232.4.102.98 slave_timeout=99999 slave_timeout=99999 slave_imr_interface=192.168.9.28 [sz_index] port=22345 recv_np=1 [sz_snapshot] port=22346 recv_np=3 [sz_tick] port=12347 recv_np=5 ; recv_type=2 [sz_tcp] host=192.168.9.15 port=20068 [dispatch] index_np=11 snapshot_np=12 tick_np=13 [logger] name=annhoo_md_sdk.log # 0: trace # 1: debug # 2: info # 3: warn # 4: error # 5: fatal # 6: off level=2 rotate_size=100 rotate_total=5 stdout=false 接口函数主要是行情 sdk c++的 API 接口, 主要有 NewMdApi - 创建行情接口 GetMdApiVersion - 获取 API 版本号 RegisterSpi/UnRegisterSpi - 注册/注销 行情回调 SubscribeXXX/UnSubscribeXXX - 订阅/取消订阅 Start - 启动行情 Join - 等待行情结束 需要主要的是, 以下接口以实际源码为准。 Synopsis annhoo::IAHMdApi* NewMdApi(const char* config_path); Parameters name | data type | description | config_path | char* const | 配置文件(yaml格式) | Return IAHMdApi pointer Synopsis const char* GetMdApiVersion(); Parameters void Return version: 1.1.2 Synopsis const char* GetMdApiVersionMore(); Parameters void Return version: 1.1.2 branch: tick_bulk_sf commit id: ddefcbc1449b2a3f10c88974bb585425ac18cf8c_2023-05-07 10:25:39 +0800 build time: 2023-05-07 10:27:27 build type: RelWithDebInfo Synopsis virtual void RegisterSpi(IAHMdSpi* imp) = 0; Parameters name | data type | description | imp | IAHMdSpi* | 向API注册自定义的回调实现子类的对象 | Return void Synopsis virtual void UnRegisterSpi(IAHMdSpi* imp) = 0; Parameters name | data type | description | imp | IAHMdSpi* | 向API取消注册的自定义回调实现子类的对象 | Return void Synopsis virtual int SubscribeIndex(const std::vector& securityIDs) = 0; virtual int SubscribeTick(const std::vector& securityIDs) = 0; virtual int SubscribeSnapshot(const std::vector& securityIDs) = 0; Parameters name | data type | description | securityIDs | const std::vector& | 订阅指定的具体行情列表 | Return void Synopsis virtual void SubscribeAll(void) = 0; virtual void SubscribeIndexAll(void) = 0; virtual void SubscribeTickAll(void) = 0; virtual void SubscribeSnapshotAll(void) = 0; Parameters void Return void Synopsis virtual int UnSubscribeIndex(const std::vector& securityIDs) = 0; virtual int UnSubscribeTick(const std::vector& securityIDs) = 0; virtual int UnSubscribeSnapshot(const std::vector& securityIDs) = 0; Parameters name | data type | description | securityIDs | const std::vector& | 订阅具体的行情列表 | Return int Synopsis virtual void UnSubscribeAll(void) = 0; virtual void UnSubscribeIndexAll(void) = 0; virtual void UnSubscribeTickAll(void) = 0; virtual void UnSubscribeSnapshotAll(void) = 0; Parameters void Return void Synopsis virtual void ExportSubscribeAll(std::vector& outs) = 0; virtual void ExportSubscribeIndex(std::vector& outs) = 0; virtual void ExportSubscribeTick(std::vector& outs) = 0; virtual void ExportSubscribeSnapShot(std::vector& outs) = 0; Parameters name | data type | description | outs | std::vector& | 导出订阅的具体行情列表 | Return void Synopsis virtual void OnIndexCB(AHIndex* index) Parameters name | data type | description | index | AHIndex* | 用户自定义实现的指数行情快照回调 | Return void 指数回调的时候, 参数类型为原生指针 AHIndex* Synopsis virtual void OnTickCB(AHTick* data, uint16_t type) Parameters name | data type | description | trade | AHTick* | 用户自定义实现的逐笔委托和逐笔成交回调 | type | AType | 委托:192, 成交:191 | Return void AHTick 是一个逐笔委托指针和逐笔成交指针的联合体, 后面有 type 标识数据类型 Synopsis virtual void OnSnapshotCB(AHSnapShot* snapshot) Parameters name | data type | description | snap_shot | AHSnapshot* | 用户自定义实现的集中竞价交易业务行情快照回调回调 | Return void 快照回调的时候, 参数类型为原生指针 AHSnapshot* 安湖行情系列产品,对于交易所标准行情数据,采用的是沪深交易所标准,只有对于个别字段考虑到系统的设计要求会有一些特殊处理。 对于传输层细节部分,可参考安湖SDK文档高阶 https://mdsdk.annhoo.cn/structannhoo_1_1_a_h_index.html struct AHDataHeader { uint16_t MsgType; /*!< Quotes message type: 指数: 9011, 委托: 192, 成交: 191, 快照: 111 */ char ExchangeID[2]; /*!< Exchange identify: SZ or SH */ }; MsgType 详情: 指数: 9011 委托: 192 成交: 191 快照: 111 消息类型:9011 消息长度:106 数据结构: struct AHIndex { AHDataHeader header; /*!< Common header: MsgType: 9011, MsgLength: 100 */ char MDStreamID[4]; /*!< 深市行情类别,沪市缺失 */ union { int64_t OrigTime; /*!< 数据生成时间 */ int64_t TradeTime; /*!< 沪市成交时间 */ }; uint16_t ChannelNo; /*!< 深市频道代码, 沪市缺失 */ char TradingPhaseCode[2]; /*!< 深市产品所处的交易阶段代码, 沪市缺失 */ char SecurityID[8]; /*!< 证券代码, format: 'xxxxxx '(end with two spaces) */ int64_t LastIndex; /*!< 最新价, 深市除以10000后为分, 沪市除以1000后为分 */ int64_t PreCloseIndex; /*!< 前收盘指数, 深市除以10000后为分, 沪市除以1000后为分 */ int64_t OpenIndex; /*!< 今开盘, 深市除以10000后为分, 沪市除以1000后为分 */ int64_t HighIndex; /*!< 最高价, 深市除以10000后为分, 沪市除以1000后为分 */ int64_t LowIndex; /*!< 最低价, 深市除以10000后为分, 沪市除以1000后为分 */ int64_t CloseIndex; /*!< 今收盘, 深市除以10000后为分, 沪市除以1000后为分 */ int64_t TotalVolumeTrade; /*!< 成交总量 */ int64_t TotalValueTrade; /*!< 成交总金额, 深市除以10000后为分, 沪市除以1000后为分 */ int64_t NumTrades; /*!< 深市成交笔数, 沪市缺失 */ }; 模拟数据案例展示: key | val | msgtype | 9011 | ExchangeID | SZ | MDStreamID | 900 | OrigTime | 20220517094612000 | ChannelNo | 10 | TradingPhaseCode | T | SecurityID[8] | 399284 | LastIndex | 2608677400 | PreCloseIndex | 2609506600 | OpenIndex | 2611665800 | HighIndex | 2623839000 | LowIndex | 2604848600 | CloseIndex | 0 | TotalVolumeTrade | 10604617000 | TotalValueTrade | 20248596531300 | NumTrades | 169946 | 消息类型:tick 消息长度:76 数据结构: struct AHTick { AHDataHeader header; /*!< Command header, MsgType: 191/192/193 */ union { char MDStreamID[4]; /*!< 深市的行情类别 */ uint16_t OrderIndex; /*!< 沪市的委托序号,从1开始,按channel连续 */ uint16_t TradeIndex; /*!< 沪市的成交序号,从1开始,按channel连续 */ char TickBSFlag[4]; /*!< 沪市逐笔:逐笔标识。委托:B=买单,S=卖单;产品状态订单:START=启动, OCALL=开市集合竞价, TRADE=连续自动撮合, SUSP=停牌, CCALL=收盘集合竞价, CLOSE=闭市, ENDTR=交易结束 */ }; union { uint16_t ChannelNo; /*!< 深市频道代码 */ uint16_t Channel; /*!< 沪市委托通道。沪市逐笔通道 */ uint16_t TradeChannel; /*!< 沪市成交通道 */ }; union { char Side; /*!< 深市委托时为买卖方向: 1=买, 2=卖, G=借入 F=出借, 深市成交缺失 */ char OrderBSFlag; /*!< 沪市委托时为:B=买单, S=卖单 */ char TradeBSFlag; /*!< 沪市成交为:B=外盘主动买,S=内盘主动卖,N=未知。沪市逐笔此字段已前置,故空 */ }; union { char OrdType; /*!< 深市委托时订单类型时:1=市价,2=限价,U=本方最优 */ char OrderType; /*!< 沪市委托时订单类型时:A=新增委托订单,D=删除委托订单; 沪市成交缺失 */ char ExecType; /*!< 深市成交时订单类型时:4=撤销,F=成交 */ char Type; /*!< 沪市逐笔:A=新增委托订单,D=删除委托订单,S=产品状态订单,T=成交 */ }; union { int64_t ApplSeqNum; /*!< 深市时,消息记录号从 1 开始计数*/ int64_t BizIndex; /*!< 沪市时,业务序列号与竞价逐笔成交消息合并后的连续编号,从 1 开始,按Channel 连续 */ }; char SecurityID[8]; /*!< 证券代码 */ union { int64_t Price; /*!< 深市委托价格, 实际值除以10000。沪市逐笔价格, 实际值除以1000 */ int64_t OrderPrice; /*!< 沪市委托价格, 实际值除以1000 */ int64_t LastPx; /*!< 深市成交价格, 实际值除以10000 */ int64_t TradePrice; /*!< 沪市成交价格, 实际值除以1000 */ }; union { int64_t OrderQty; /*!< 深市委托数量, 除以100 */ int64_t Balance; /*!< 沪市委托数量, 除以1000 */ int64_t LastQty; /*!< 深市成交数量, 实际值除以100 */ int64_t TradeQty; /*!< 沪市成交数量, 实际值除以1000 */ int64_t Qty; /*! 沪市逐笔数量, 实际值除以100 */ }; union { int64_t TransactTime; /*!< 深市委托/成交时间 */ int64_t OrderTime; /*!< 沪市委托时间 */ int64_t TradeTime; /*!< 沪市成交时间 */ int64_t TickTime; /*!< 沪市逐笔订单时间或者成交时间 */ }; union { int64_t OrderNO; /*!< 沪市委托原始订单号 */ int64_t BidApplSeqNum; /*!< 深市成交, 买方委托索引从 1 开始计数,0 表示无对应委托 */ int64_t TradeBuyNo; /*!< 沪市成交, 买方订单号 */ int64_t BuyOrderNo; /*!< 沪市逐笔买方订单 */ }; union { int64_t OfferApplSeqNum; /*!< 深市成交, 卖方委托索引从 1 开始计数,0 表示无对应委托 */ int64_t TradeSellNo; /*!< 沪市成交, 卖方订单号 */ int64_t SellOrderNo; /*!< 沪市逐笔买方订单 */ }; int64_t TradeMoney; /*!< 深市缺失,沪市成交金额, 实际值除以 100000。沪市逐笔:如果市新增委托(Type: A):已成交的委托数量(精度为三位), 如果是成交(Type: T):成交金额(精度为五位) */ }; 深市委托行情数据案例: 消息类型:192 key | val | msgtype | 192 | ExchangeID | SZ | MDStreamID | 011 | ChannelNo | 2013 | Side | 1 | OrdType | 2 | ApplSeqNum | 23293311 | SecurityID[8] | 002256 | Price | 26200 | OrderQty | 90000 | TransactTime | 20220517132752710 | 委托价:2.62元,买入900股 深市成交行情数据案例: 消息类型:191 key | val | msgtype | 191 | ExchangeID | SZ | MDStreamID | 011 | ChannelNo | 2013 | ExecType | F | ApplSeqNum | 23294075 | SecurityID[8] | 003040 | LastPx | 199100 | LastQty | 80000 | TransactTime | 20220517132753170 | BidApplSeqNum | 23294074 | OfferApplSeqNum | 13737530 | 最近委托价为:19.19元,成交量:800股 沪市委托行情数据案例: 消息类型:192 key | val | msgtype | 192 | ExchangeID | SH | OrderIndex | 12585 | Channel | 1 | OrderBSFlag | S | OrderType | D | BizIndex | 16863389 | SecurityID [8] | 688220 | OrderPrice | 66000 | Balance | 1000000 | OrderTime | 20231030135731180 | OrderNO | 10530657 | 最近委托价为:66元,委托数量:1000股 沪市成交行情数据案例: 消息类型:191 key | val | msgtype | 191 | ExchangeID | SH | TradeIndex | 8115 | TradeChannel | 1 | TradeBSFlag | B | OrderType | T | BizIndex | 16863537 | SecurityID | 601898 | TradePrice | 8570 | TradeQty | 200000 | TradeTime | 20231030135731320 | TradeBuyNo | 10532037 | TradeSellNo | 10528285 | TradeMony | 171400000 | 最近委托价为:8.57元,成交数量:200股,成交金额:1714元 消息类型:111 消息长度:514 数据结构: struct AHSnapshot { AHDataHeader header; /*!< Command header, MsgType: 111, MsgType: 514 */ char MDStreamID[4]; /*!< 深市行情类别,沪市缺失 */ union { int64_t OrigTime; /*!< 数据生成时间 */ int64_t TradeTime; /*!< 沪市成交时间 */ }; uint16_t ChannelNo; /*!< 深市频道代码, 沪市缺失 */ char InstrumentStatus[2]; /*!< 沪市当前品种交易状态, 深市缺失 */ char TradingPhaseCode[4]; /*!< 当前产品状态 */ char SecurityID[8]; /*!< 证券代码, format: 'xxxxxx '(end with two spaces) */ int64_t BidPrice[10]; /*!< 十档申买价, 深市除以10000后为分, 沪市除以1000后为分 */ int64_t AskPrice[10]; /*!< 十档申卖价, 深市除以10000后为分, 沪市除以1000后为分 */ int64_t BidVolume[10]; /*!< 十档申买量 */ int64_t AskVolume[10]; /*!< 十档申卖量 */ int64_t PrevClosePx; /*!< 昨收价, 深市除以10000后为分, 沪市除以1000后为分 */ int64_t OpenPx; /*!< 今开盘, 深市除以10000后为分, 沪市除以1000后为分 */ int64_t HighPx; /*!< 最高价, 深市除以10000后为分, 沪市除以1000后为分 */ int64_t LowPx; /*!< 最低价, 深市除以10000后为分, 沪市除以1000后为分 */ int64_t LastPx; /*!< 最新价, 深市除以10000后为分, 沪市除以1000后为分 */ int64_t ClosePx; /*!< 收盘价, 深市缺失, 沪市除以1000后为分 */ int64_t NumTrades; /*!< 成交笔数 */ int64_t TotalVolumeTrade; /*!< 成交总量 */ int64_t TotalValueTrade; /*!< 成交总金额 */ int64_t TotalBidQty; /*!< 委托买入总量 */ int64_t WeightedAvgBidPx; /*!< 加权平均委托买入价, 深市除以10000后为分, 沪市除以1000后为分 */ int64_t TotalOfferQty; /*!< 委托卖出总量 */ int64_t WeightedAvgOfferPx; /*!< 加权平均委托卖出价, 深市除以10000后为分, 沪市除以1000后为分 */ int64_t IOPV; /*!< 基金实时参考净值 */ int64_t LPV; /*!< 基金 T-1 日净值, 沪市缺失 */ int64_t UpperLimitPrice; /*!< 涨停价, 深市除以10000后为分, 沪市缺失 */ int64_t LowerLimitPrice; /*!< 跌停价, 深市除以10000后为分, 沪市缺失 */ int64_t OpenInterest; /*!< 合约持仓量, 沪市缺失 */ int64_t LastSubPrevClosePrice; /*!< 升跌一, 沪市缺失 */ int64_t LastSubPrevLastPrice; /*!< 升跌二, 沪市缺失 */ }; 模拟环境下,案例数据展示: key | val | MsgType | 111 | ExchangeID | SZ | MDStreamID | 010 | Time | 20220517131115000 | ChannelNo | 1012 | TradingPhaseCode | T0 | SecurityID | 300994 | BidPrice[0] | 29960000 | BidPrice[1] | 29950000 | BidPrice[2] | 29940000 | BidPrice[3] | 29920000 | BidPrice[4] | 29910000 | BidPrice[5] | 29900000 | BidPrice[6] | 29870000 | BidPrice[7] | 29850000 | BidPrice[8] | 29800000 | BidPrice[9] | 29740000 | AskPrice[0] | 29990000 | AskPrice[1] | 30000000 | AskPrice[2] | 30010000 | AskPrice[3] | 30040000 | AskPrice[4] | 30050000 | AskPrice[5] | 30060000 | AskPrice[6] | 30080000 | AskPrice[7] | 30100000 | AskPrice[8] | 30120000 | AskPrice[9] | 30170000 | BidVolume[0] | 220000 | BidVolume[1] | 10000 | BidVolume[2] | 30000 | BidVolume[3] | 310000 | BidVolume[4] | 30000 | BidVolume[5] | 10000 | BidVolume[6] | 6170000 | BidVolume[7] | 520000 | BidVolume[8] | 50000 | BidVolume[9] | 40000 | AskVolume[0] | 100000 | AskVolume[1] | 330000 | AskVolume[2] | 320000 | AskVolume[3] | 330000 | AskVolume[4] | 10000 | AskVolume[5] | 10000 | AskVolume[6] | 10000 | AskVolume[7] | 150000 | AskVolume[8] | 10000 | AskVolume[9] | 50000 | PrevClosePx | 297100 | OpenPx | 29300000 | HighPx | 29980000 | LowPx | 28850000 | LastPx | 29980000 | ClosePx | 0 | NumTrades | 4971 | TotalVolumeTrade | 169965300 | TotalValueTrade | 497509300900 | TotalBidQty | 77280000 | WeightedAvgBidPx | 29110000 | TotalOfferQty | 29550000 | WeightedAvgOfferPx | 32070000 | IOPV | 0 | LPV | 0 | UpperLimitPrice | 35650000 | LowerLimitPrice | 23770000 | OpenInterest | 0 | LastSubPrevClosePrice | 270000 | LastSubPrevLastPrice | 30000 | 产品所处的交易阶段代码 深交所: 第 0 位:S=启动(开市前),O=开盘集合竞价,T=连续竞价,B=休市,C=收盘集合竞价,E=已闭市,H=临时停牌,A=盘后交易,V=波动性中断 第 1 位:0=正常状态,1=全天停牌 上交所: 该字段为 8 位字符串,左起每位表示特定的含义,无定义则填空格 第 1 位:‘S’表示启动(开市前)时段,‘C’表示开盘集合竞价时段,‘T’表示连续交易时段,‘E’表示闭市时段,‘P’表示产品停牌,‘M’表示可恢复交易的熔断时段(盘中集合竞价),‘N’表示不可恢复交易的熔断时段(暂停交易至闭市),‘U’表示收盘集合竞价时段。 第 2 位:‘0’表示此产品不可正常交易,‘1’表示此产品可正常交易,无意义填空格。 第 3 位:‘0’表示未上市,‘1’表示已上市。 第 4 位:‘0’表示此产品在当前时段不接受订单申报,‘1’ 表示此产品在当前时段可接受订单申报。无意义填空格 鉴于yaml语法格式的不熟悉或者误操作,程序提供了对yaml格式检查的工具和开关。我们可以通过环境变量的设置,对yaml文件进行检查。把以下语句添加到启动脚本中。 # yq 的文件路径 export YQ_LINUX_AMD=/home/annhoo/annhoo_md_sdk/tools 启动异常 请查看启动日志,确定是否是由于版本原因还是硬件驱动问题,详情对照我们的环境说明。或者参考我们的线上文档:https://doc.annhoo.cn/fund/annhoo_md_sdk.html 如何确定自己的SDK运行模式 当客户使用我们的sdk运行后,启动日志中是有对应的运行日志记录的。如果是采用SF的ef_vi模式接收,在日志中会存在记录:EFVI_mode for tick market之类的数据。 版本 | 日期 | 备注 | 0.0.1 | 2021-10-20 | 初稿 | 0.0.2 | 2021-12-29 | 重构架构和内存管理方式, 添加主备方案 | 0.1.0 | 2022-08-20 | 添加多网卡时的网口绑定, cpu绑定等 | 0.1.1 | 2022-10-10 | 补充案例和说明 | 0.4.0 | 2023-02-01 | tick数据及其接口 | 1.1.2 | 2023-05-13 | 支持solar flare | 1.6.0 | 2023-10-30 | 对原结构体做调整,增加OrderNO,BizIndex等字段 | 2.0.1 | 2024-01-30 | 新增登录校验 | 2.0.2 | 2024-02-29 | 新增tcp模式 | 2.1.0 | 2023-03-29 | 新增配置文件校验和普通网卡 | 2.2.0 | 2023-04-18 | 支持沪市逐笔合并后的tick消息分发处理 | 2.2.1 | 2023-04-27 | 修复登录bug | 2.2.2 | 2023-05-07 | 补充solare flare onload版本信息 | 3.0.0 | 2023-05-27 | 优化系统网络接收性能,超低时延获取行情数据 | 3.1.0 | 2023-06-18 | 增加配置项ini格式,简化配置同时优化sdk性能 |