安湖行情系统SDK文档
📚 文档概述
安湖行情服务是基于 FPGA 技术的极速行情接入开发包,专为 Linux 系统设计。我们提供两种接入方式:
- 动态库(.so):适用于动态加载场景
- 静态库(.a):适用于静态链接场景
🎯 适用对象
- FPGA 行情开发人员
- 测试人员
- 运维人员
📋 文档结构
🛠 系统环境配置
基础环境要求
组件 | 要求 | 说明 |
---|---|---|
GCC | 8.5.0+ | 支持C++17特性 |
操作系统 | RedHat RHEL 7.4 x64+ | 推荐最新版本 |
CPU | 6核及以上,高主频 | 推荐高性能CPU |
网络 | SDK与FPGA需在同一网络环境 | 建议使用Solarflare网卡 |
内存 | 8GB+ | 推荐16GB以上 |
🔧 GCC-8.5.0 安装配置
💡 为什么需要GCC 8.5.0+?
行情SDK系统采用了C++11/14/17新特性开发,而RedHat 7默认的GCC 4.8.5不完全支持这些特性。
获取源码
wget https://ftp.gnu.org/gnu/gcc/gcc-8.5.0/gcc-8.5.0.tar.gz
tar xvf gcc-8.5.0.tar.gz
依赖库清单
组件 | 包名 | 最低版本 | 下载/说明 |
---|---|---|---|
m4 | m4-1.4.16-10.el7.x86_64.rpm | - | 下载链接 |
gmp | gmp-6.2.1.tar | 4.2+ | 源码包已提供 |
mpfr | mpfr-4.1.0.tar.bz2 | 2.4+ | 源码包已提供 |
mpc | mpc-1.2.0.tar.gz | 0.8+ | 源码包已提供 |
isl | isl-0.16.1.tar.bz2 | - | 源码包已提供 |
安装方式
📥 在线安装(点击展开)
cd gcc-8.5.0
./contrib/download_prerequisites
make -j$(nproc)
sudo make install
📦 离线安装(点击展开)
- 解压gcc源码目录
- 拷贝
infrastructure.tar.bz2
和upgrade-gcc.sh
至源码目录 - 解压
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"
M4依赖
- 在线安装:
sudo yum install m4
- 离线安装:
rpm -ivh m4-1.4.16-10.el7.x86_64.rpm
- 在线安装:
CMake配置
sudo yum install cmake sudo yum install openssl openssl-devel
CMake升级(需要3.11+)
# 获取最新源码 git clone https://github.com/Kitware/CMake # 编译安装 ./bootstrap && make -j$(nproc) && sudo make install hash -r # 刷新hash表
GCC路径配置
# 方式1: CMake命令行 cmake -DCMAKE_CXX_COMPILER=/usr/local/gcc8/bin/g++ .. # 方式2: CMakeLists.txt set(CMAKE_CXX_COMPILER /usr/local/gcc8/bin/g++)
3.1 依赖库表
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源码编译前需要安装 |
3.2 在线安装
如果系统可以联网, 那么可以直接在 gcc 目录下的执行:
cd gcc-8.5.0
./contrib/download_prerequisites
make -j$(nproc)
sudo make install
离线安装
- 解压 gcc 源码目录
- 拷贝
infrastructure.tar.bz2
和upgrade-gcc.sh
至源码目录 - 解压
infrastructure.tar.bz2
- 执行
upgrade-gcc.sh
📊 行情SDK系统
目录结构
annhoo_md_sdk_demo/
├── bin/ # 可执行文件目录
├── conf/ # 配置文件目录
├── examples/ # 示例代码
├── include/ # 头文件
│ └── annhoo_md_sdk/ # SDK核心头文件
├── lib/ # 库文件
└── src/ # 源代码
💡 重要说明
SDK提供两套日志系统:
- 基于spdlog的日志系统
- 非spdlog的日志系统
⚠️ 注意: 如果您的应用使用spdlog,请选择非spdlog版本的SDK,避免初始化冲突。
4 环境配置
大概编译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++)
5 行情 SDK 系统
以上部分( 2-4 ) 为 sdk 的环境依赖的准备工作, 现在进入 行情SDK系统 部分, 分为:
- 目录结构说明
- 运行环境说明
5.1 目录结构
[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
: 一键停止脚本
Important
需要注意的是,目前sdk自带的日志有两套, 一套是基于spdlog的,另外一套是非spdlog。因为 spdlog 的初始化不能够同时存在于sdk和应用。如果应用也是采用了spdlog作为日志库,那么请使用非spdlog日志的版本
5.2 运行环境说明
- 行情sdk和 FPGA在相同网络环境中的机器上运行,可使用 linux onload(需要solarflare 网卡支持),这样能进一步降低网络延时
- RedHat RHEL 7.4 x64 及以上版本
- 如果 gcc 版本不支持 c++17, 需要对 gcc 升级. 升级步骤前面章节已有相应的详细升级步骤, 并有相应的压缩包提供
- CPU 主频的越高越好,且 cpu核六个以上 (含)
6 行情sdk回调
行情sdk的回调主要包含开发流程, 配置说明和各个接口说明
6.1 开发流程
- 调用
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
注销行情回调, 释放行情回调和行情接口
6.2 配置说明
配置文件目前支持两个格式的配置
- ini
- yaml
缺省的配置文件格式是 ini. 下面以 yaml 格式作为解说. ini 类同.
6.2.1 配置文件
[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, szrecv_np
: 每种行情接收线程所要绑定的cpu核的索引号(-1代表不绑核, >=0 代表说绑定的cpu序列号). 依次为 sh, szdispatch_np
: 分发线程所要绑定的cpu核的索引号(-1代表不绑核, >=0 代表说绑定的cpu序列号)name
: 日志名称level
: 所要输出的日志级别rotate_size
: 日志文件大小, 单位为 Mrotate_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]
6.2.2 sdk 日志配置
目前的 sdk 日志有:
- 调试日志: 1 - debug
- 一般日志: 2 - info
- 警告日志: 3 - warn
- 错误日志: 4 - error
- 致命日志: 5 - fatal(该日志, 程序不正常, 必须停止排查)
- 关闭所有日志: 6 - off
6.2.3 recv_mem_size
该值对应 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
6.2.4 ini 样式
[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
6.3 接口说明
接口函数主要是行情 sdk c++的 API 接口, 主要有
NewMdApi
- 创建行情接口GetMdApiVersion
- 获取 API 版本号RegisterSpi/UnRegisterSpi
- 注册/注销 行情回调SubscribeXXX/UnSubscribeXXX
- 订阅/取消订阅Start
- 启动行情Join
- 等待行情结束
需要注意的是, 以下接口以实际源码为准。
6.3.1 NewMdApi - 创建行情接口
Synopsis
annhoo::IAHMdApi* NewMdApi(const char* config_path);
Parameters
name | data type | description |
---|---|---|
config_path | char* const | 配置文件(yaml格式) |
Return
IAHMdApi pointer
6.3.2 GetMdApiVersion - 获取版本号接口
Synopsis
const char* GetMdApiVersion();
Parameters
void
Return
version: 1.1.2
6.3.3 GetMdApiVersionMore - 获取更多的版本信息
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
6.3.4 RegisterSpi - 注册回调接口
Synopsis
virtual void RegisterSpi(IAHMdSpi* imp) = 0;
Parameters
name | data type | description |
---|---|---|
imp | IAHMdSpi* | 向API注册自定义的回调实现子类的对象 |
Return
void
6.3.5 UnRegisterSpi 取消回调接口
Synopsis
virtual void UnRegisterSpi(IAHMdSpi* imp) = 0;
Parameters
name | data type | description |
---|---|---|
imp | IAHMdSpi* | 向API取消注册的自定义回调实现子类的对象 |
Return
void
6.3.6 SubscribeXXX - 订阅指定的行情列表
Synopsis
virtual int SubscribeIndex(const std::vector<std::string>& securityIDs) = 0;
virtual int SubscribeTick(const std::vector<std::string>& securityIDs) = 0;
virtual int SubscribeSnapshot(const std::vector<std::string>& securityIDs) = 0;
Parameters
name | data type | description |
---|---|---|
securityIDs | const std::vector<std::string>& | 订阅指定的具体行情列表 |
Return
void
6.3.7 Subscribe(XXX)All - 订阅所有行情
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
6.3.8 UnSubscribeXXX - 取消指定的订阅行情列表
Synopsis
virtual int UnSubscribeIndex(const std::vector<std::string>& securityIDs) = 0;
virtual int UnSubscribeTick(const std::vector<std::string>& securityIDs) = 0;
virtual int UnSubscribeSnapshot(const std::vector<std::string>& securityIDs) = 0;
Parameters
name | data type | description |
---|---|---|
securityIDs | const std::vector<std::string>& | 订阅具体的行情列表 |
Return
int
6.3.9 UnSubscribe(XXX)All - 取消所有订阅的行情
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
6.3.10 ExportSubscribeXXXX - 导出订阅列表
Synopsis
virtual void ExportSubscribeAll(std::vector<std::string>& outs) = 0;
virtual void ExportSubscribeIndex(std::vector<std::string>& outs) = 0;
virtual void ExportSubscribeTick(std::vector<std::string>& outs) = 0;
virtual void ExportSubscribeSnapShot(std::vector<std::string>& outs) = 0;
Parameters
name | data type | description |
---|---|---|
outs | std::vector<std::string>& | 导出订阅的具体行情列表 |
Return
void
6.3.11 OnIndexCB - 指数行情快照回调
Synopsis
virtual void OnIndexCB(AHIndex* index)
Parameters
name | data type | description |
---|---|---|
index | AHIndex* | 用户自定义实现的指数行情快照回调 |
Return
void
指数回调的时候, 参数类型为原生指针
AHIndex*
6.3.12 OnTickCB - 逐笔委托和逐笔成交回调
Synopsis
virtual void OnTickCB(AHTick* data, uint16_t type)
Parameters
name | data type | description |
---|---|---|
trade | AHTick* | 用户自定义实现的逐笔委托和逐笔成交回调 |
type | AType | 委托:192, 成交:191 |
Return
void
AHTick 是一个逐笔委托指针和逐笔成交指针的联合体, 后面有 type 标识数据类型
6.3.13 OnSnapshotCB - 集中竞价交易业务行情快照回调
Synopsis
virtual void OnSnapshotCB(AHSnapShot* snapshot)
Parameters
name | data type | description |
---|---|---|
snap_shot | AHSnapshot* | 用户自定义实现的集中竞价交易业务行情快照回调回调 |
Return
void
快照回调的时候, 参数类型为原生指针
AHSnapshot*
6.4 数据结构说明
安湖行情系列产品,对于交易所标准行情数据,采用的是沪深交易所标准,只有对于个别字段考虑到系统的设计要求会有一些特殊处理。
对于传输层细节部分,可参考安湖SDK文档高阶 https://mdsdk.annhoo.cn/structannhoo_1_1_a_h_index.html
6.4.1 数据头定义(AHDataHeader)
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
- 逐笔: 193
6.4.2 指数行情定义(AHIndex)
消息类型:9011 消息长度:100 数据结构:
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; /*!< 最新价, 深市除以1000000后为点, 沪市除以100000后为点 */
int64_t PreCloseIndex; /*!< 前收盘指数, 深市除以1000000后为元, 沪市除以100000后为点 */
int64_t OpenIndex; /*!< 今开盘, 深市除以1000000后为点, 沪市除以100000后为点 */
int64_t HighIndex; /*!< 最高价, 深市除以1000000后为点, 沪市除以100000后为点 */
int64_t LowIndex; /*!< 最低价, 深市除以1000000后为点, 沪市除以100000后为点 */
int64_t CloseIndex; /*!< 今收盘, 深市除以1000000后为点, 沪市除以100000后为点 */
int64_t TotalVolumeTrade; /*!< 成交总量, 深市除以100为股, 沪市除以100000为万手 */
int64_t TotalValueTrade; /*!< 成交总金额, 深市除以10000后为元, 沪市除以10后为元 */
int64_t NumTrades; /*!< 深市成交笔数, 沪市缺失 */
};
模拟深市指数行情数据案例:
key | val |
---|---|
msgtype | 9011 |
ExchangeID | SZ |
MDStreamID | 900 |
OrigTime | 20250331151527000 |
ChannelNo | 10 |
TradingPhaseCode | E |
SecurityID[8] | 399286 |
LastIndex | 3657216600 |
PreCloseIndex | 3672730800 |
OpenIndex | 3646227900 |
HighIndex | 3670504700 |
LowIndex | 3605083100 |
CloseIndex | 0 |
TotalVolumeTrade | 295808684500 |
TotalValueTrade | 453396915374300 |
NumTrades | 2941708 |
区块链50指数(证券代码:399286) 今开盘:3646.2279点,最高价:3670.5047点,最低价:3605.0831点。 成交额:453.396亿 成交量:2958.08 万手(295808 万股) 交易日期:20250331
模拟沪市指数行情数据案例:
key | val |
---|---|
msgtype | 9011 |
ExchangeID | SH |
TradeTime | 20250331151548150 |
SecurityID | 000126 |
LastIndex | 834023420 |
PreCloseIndex | 837773010 |
OpenIndex | 835982400 |
HighIndex | 843495010 |
LowIndex | 830296830 |
CloseIndex | 834023420 |
TotalVolumeTrade | 1193632600000 |
TotalValueTrade | 283089689240 |
消费50指数(证券代码:000126) 今开盘:8359.824点,最高价:8434.9501点,最低价:8302.9683点。 成交额:283.08亿 成交量:1193.6万手 交易日期:20250331
6.4.3 Tick行情定义(AHTick)
随着交易所将逐笔数据合并成tick,客户机房环境可能由于网关的版本原因依然将逐笔委托和逐笔成交进行区分,sdk进行了区分。
namespace AHType {
const uint16_t ENTRUST = 192;
const uint16_t TRADE = 191;
const uint16_t TICK = 193;
}; // namespace AHType
消息类型: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=启动,
OCAL=开市集合竞价, TRAD=连续自动撮合, SUSP=停牌, CCAL=收盘集合竞价, CLOS=闭市,
ENDT=交易结束 */
};
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; /*! 沪市逐笔数量, 实际值除以1000 */
};
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):成交金额(精度为五位) */
};
6.4.4 Tick深市回调数据案例:
深市委托行情数据案例: 消息类型:192
key | val |
---|---|
msgtype | 192 |
ExchangeID | SZ |
MDStreamID | 011 |
ChannelNo | 2034 |
Side | 2 |
OrdType | 2 |
ApplSeqNum | 681543 |
SecurityID[8] | 123226 |
Price | 2299820 |
OrderQty | 6000 |
TransactTime | 20231116095239140 |
委托价格:229.982元,委托数量:60股
深市成交行情数据案例: 消息类型:191
key | val |
---|---|
msgtype | 191 |
ExchangeID | SZ |
MDStreamID | 011 |
ChannelNo | 2014 |
ExecType | F |
ApplSeqNum | 9539107 |
SecurityID[8] | 300682 |
LastPx | 189400 |
LastQty | 10000 |
TransactTime | 20231116095239150 |
BidApplSeqNum | 9535672 |
OfferApplSeqNum | 9539106 |
成交价格:18.94元,成交数量:100股
6.4.5 Tick沪市行情回调数据案例
沪市逐笔行情数据案例: 消息类型:193
key | val |
---|---|
MsgType | 193 |
ExchangeID | SH |
TickBSFlag | B |
Channel | 6 |
Type | T |
BizIndex | 8121272 |
SecurityID | 600455 |
Price | 16630 |
Qty | 100000 |
TickTime | 20240417101502980 |
BuyOrderNo | 5134670 |
SellOrderNo | 5134492 |
TradeMony | 166300000 |
逐笔价格:16.63元,逐笔数量:100股
6.4.6 快照行情定义(AHSnapshot)
消息类型: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]; /*!< 十档申买价, 深市除以1000000后为元, 沪市除以1000后为元 */
int64_t AskPrice[10]; /*!< 十档申卖价, 深市除以1000000后为元, 沪市除以1000后为元 */
int64_t BidVolume[10]; /*!< 十档申买量, 深市除以100, 沪市除以1000 */
int64_t AskVolume[10]; /*!< 十档申卖量, 深市除以100, 沪市除以1000 */
int64_t PrevClosePx; /*!< 昨收价, 深市除以10000后为元, 沪市除以1000后为元 */
int64_t OpenPx; /*!< 今开盘, 深市除以1000000后为元, 沪市除以1000后为元 */
int64_t HighPx; /*!< 最高价, 深市除以1000000后为元, 沪市除以1000后为元 */
int64_t LowPx; /*!< 最低价, 深市除以1000000后为元, 沪市除以1000后为元 */
int64_t LastPx; /*!< 最新价, 深市除以1000000后为元, 沪市除以1000后为元 */
int64_t ClosePx; /*!< 收盘价, 深市缺失, 沪市除以1000后为元 */
int64_t NumTrades; /*!< 成交笔数 */
int64_t TotalVolumeTrade; /*!< 成交总量, 深市除以100, 沪市除以1000 */
int64_t TotalValueTrade; /*!< 成交总金额, 深市除以10000元,沪市除以100000元 */
int64_t TotalBidQty; /*!< 委托买入总量, 深市除以100, 沪市除以1000 */
int64_t WeightedAvgBidPx; /*!< 加权平均委托买入价, 深市除以1000000后为元, 沪市除以1000后为元 */
int64_t TotalOfferQty; /*!< 委托卖出总量, 深市除以100, 沪市除以1000 */
int64_t WeightedAvgOfferPx; /*!< 加权平均委托卖出价, 深市除以1000000后为元, 沪市除以1000后为元 */
int64_t IOPV; /*!< 基金实时参考净值, 深市除以1000000后为元, 沪市除以1000后为元 */
int64_t LPV; /*!< 基金 T-1 日净值, 沪市缺失 */
int64_t UpperLimitPrice; /*!< 涨停价, 深市除以1000000后为元, 沪市缺失 */
int64_t LowerLimitPrice; /*!< 跌停价, 深市除以1000000后为元, 沪市缺失 */
int64_t OpenInterest; /*!< 合约持仓量, 沪市缺失 */
int64_t LastSubPrevClosePrice; /*!< 升跌一, 沪市缺失 */
int64_t LastSubPrevLastPrice; /*!< 升跌二, 沪市缺失 */
};
模拟深市快照行情案例数据:
key | val |
---|---|
MsgType | 111 |
ExchangeID | SZ |
MDStreamID | 010 |
Time | 20220517095024000 |
ChannelNo | 1024 |
TradingPhaseCode | T0 |
SecurityID | 159919 |
BidPrice[0] | 3966000 |
BidPrice[1] | 3964000 |
BidPrice[2] | 3963000 |
BidPrice[3] | 3962000 |
BidPrice[4] | 3961000 |
BidPrice[5] | 3960000 |
BidPrice[6] | 3959000 |
BidPrice[7] | 3958000 |
BidPrice[8] | 3957000 |
BidPrice[9] | 3955000 |
AskPrice[0] | 3968000 |
AskPrice[1] | 3969000 |
AskPrice[2] | 3970000 |
AskPrice[3] | 3971000 |
AskPrice[4] | 3972000 |
AskPrice[5] | 3973000 |
AskPrice[6] | 3974000 |
AskPrice[7] | 3975000 |
AskPrice[8] | 3976000 |
AskPrice[9] | 3977000 |
BidVolume[0] | 170000 |
BidVolume[1] | 63670000 |
BidVolume[2] | 44860000 |
BidVolume[3] | 33040000 |
BidVolume[4] | 5310000 |
BidVolume[5] | 14300000 |
BidVolume[6] | 12430000 |
BidVolume[7] | 12500000 |
BidVolume[8] | 300000 |
BidVolume[9] | 3870000 |
AskVolume[0] | 6190000 |
AskVolume[1] | 9830000 |
AskVolume[2] | 98500000 |
AskVolume[3] | 13110000 |
AskVolume[4] | 18530000 |
AskVolume[5] | 9640000 |
AskVolume[6] | 6170000 |
AskVolume[7] | 6630000 |
AskVolume[8] | 2830000 |
AskVolume[9] | 290000 |
PrevClosePx | 39570 |
OpenPx | 3963000 |
HighPx | 3974000 |
LowPx | 3954000 |
LastPx | 3967000 |
ClosePx | 0 |
NumTrades | 462 |
TotalVolumeTrade | 825910000 |
TotalValueTrade | 327510646000 |
TotalBidQty | 272490000 |
WeightedAvgBidPx | 3937000 |
TotalOfferQty | 340720000 |
WeightedAvgOfferPx | 4011000 |
IOPV | 3970800 |
LPV | 3957900 |
UpperLimitPrice | 4353000 |
LowerLimitPrice | 3561000 |
OpenInterest | 0 |
LastSubPrevClosePrice | 10000 |
LastSubPrevLastPrice | -1000 |
沪深300ETF(证券代码:159919) 今开盘:3.963元,最高价:3.974元,最低价:3.954元,基金实时参考净值:3.9708元。
模拟沪市快照行情案例数据:
key | val |
---|---|
MsgType | 111 |
ExchangeID | SH |
TradeTime | 20240417101503000 |
InstrumentStatus | TR |
TradingPhaseCode | T111 |
SecurityID | 600007 |
BidPrice[0] | 23070 |
BidPrice[1] | 23060 |
BidPrice[2] | 23050 |
BidPrice[3] | 23040 |
BidPrice[4] | 23020 |
BidPrice[5] | 23000 |
BidPrice[6] | 22980 |
BidPrice[7] | 22950 |
BidPrice[8] | 22940 |
BidPrice[9] | 22930 |
AskPrice[0] | 23080 |
AskPrice[1] | 23090 |
AskPrice[2] | 23100 |
AskPrice[3] | 23110 |
AskPrice[4] | 23120 |
AskPrice[5] | 23130 |
AskPrice[6] | 23140 |
AskPrice[7] | 23150 |
AskPrice[8] | 23160 |
AskPrice[9] | 23170 |
BidVolume[0] | 700000 |
BidVolume[1] | 3800000 |
BidVolume[2] | 600000 |
BidVolume[3] | 5400000 |
BidVolume[4] | 200000 |
BidVolume[5] | 500000 |
BidVolume[6] | 2800000 |
BidVolume[7] | 200000 |
BidVolume[8] | 19900000 |
BidVolume[9] | 400000 |
AskVolume[0] | 500000 |
AskVolume[1] | 1000000 |
AskVolume[2] | 2000000 |
AskVolume[3] | 700000 |
AskVolume[4] | 800000 |
AskVolume[5] | 200000 |
AskVolume[6] | 600000 |
AskVolume[7] | 5700000 |
AskVolume[8] | 4200000 |
AskVolume[9] | 200000 |
PrevClosePx | 22730 |
OpenPx | 22520 |
HighPx | 23180 |
LowPx | 22480 |
LastPx | 23080 |
ClosePx | 0 |
NumTrades | 6008 |
TotalVolumeTrade | 1412000000 |
TotalValueTrade | 3223603300000 |
TotalBidQty | 0 |
WeightedAvgBidPx | 22484 |
TotalOfferQty | 261700000 |
WeightedAvgOfferPx | 23644 |
IOPV | 0 |
中国国贸(证券代码:600007) 今开盘:22.52元,最高价:23.18元,最低价:22.48元。
6.5 字典说明
6.5.1 TradingPhaseCode
产品所处的交易阶段代码
深交所:
- 第 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' 表示此产品在当前时段可接受订单申报。无意义填空格
7 其他
yaml格式校验
鉴于yaml语法格式的不熟悉或者误操作,程序提供了对yaml格式检查的工具和开关。我们可以通过环境变量的设置,对yaml文件进行检查。把以下语句添加到启动脚本中。
# yq 的文件路径
export YQ_LINUX_AMD=/home/annhoo/annhoo_md_sdk/tools
8 常见问题
启动异常 请查看启动日志,确定是否是由于版本原因还是硬件驱动问题,详情对照我们的环境说明。或者参考我们的线上文档: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性能 |
3.1.1 | 2025-03-31 | 同步交易所的行情文档,修正数据 |