跳转至

02.常见问题答疑

订单立即部分成交后未收到XTF_OS_Queuing的Order消息

如订单发送后,立即部分成交或全部成交,将不会产生“未成交还在队列”的Queuing状态,onOrder直接进入PartTraded或AllTraded状态。

开平标志说明

不通交易所有各自的规则,目前情况如下:

  1. 对于中金所、大商所、广期所,请求填Close 、CloseToday、CloseYesterday时,都转化为Close,交易所默认先平昨后平今;回报返回Close;如果平仓错误,柜台会将客户填入的com_offset_flag再返回给客户。
  2. 对于上期所、能源所时,平今只能用CloseToday,回报返回的是CloseToday;平昨可以使用Close、CloseYesterday,都转化为CloseYesterday,回报中是closeyesterday;如果平仓错误,柜台会将客户填入的com_offset_flag再返回给客户。

在上述规则下,释放仓位时,遵循先成交的仓,先被平的规则。

回报中localOrderID收到负值

  1. 柜台清流启动后的历史报单OrderLocalNo固定为“0xd8888888”
  2. 非本柜台报单OrderLocalNo固定为“0x88888888”
  3. 错误为1172,“请求中的报单编号不存在”时,返回0
  4. 本柜台Monitor管理端平仓的客户端报单编号固定为“0xe8888888”
  5. 其他情况返回订单真实编号

裸协议用户接收ErrRtnOrderAction中的ActionLocalNo收到负值

非本柜台报单产生的回报固定为“0x86666666”

调用API时遇到 /sys/firmware/dmi/tables/smbios_entry_point: Permission denied 或者 /dev/mem: Permission denied 错误,或错误码为2058

根据看穿式监管的要求,投资者登录柜台时需要采集硬件信息,采集的时候需要调用dmidecode,没有赋予API root权限将会遇到该错误,解决方法如下:

  1. 赋予root权限,以sudo的方式运行程序
  2. 使用root用户增加dmidecode的s位,具体命令为chmod +s /usr/sbin/dmidecode,这样就可以用普通用户权限得到看穿式监管需要的信息

以上两种方案均可解决获取权限失败的问题,请用户根据实际情况选择处理。

如使用crontab任务执行,需在执行脚本或计划任务命令中添加export PATH=${PATH}:/usr/sbinsource /etc/profile指定dmidecode命令位置,。

TCP连接后,是否会发送心跳?

如果是初次建立TCP连接,而没有任何其他操作,API不会发送心跳数据。柜台在一段时间后,会断开该TCP连接。

如果用户登录后再登出,此时TCP连接依然保持,且会发送心跳数据。

如何获得合约属于哪个交易所?

首先根据合约ID查询XTFInstrument对象;\ 然后通过XTFInstrument的getExchange()接口,即可获得交易所对象;

示例代码:

C++
1
2
const XTFInstrument *instrument = api->getInstrumentByID(au2212);
const XTFExchange *exchange = instrument->getExchange();

如何获得交易日信息?

Text Only
1
2
首先获得交易所对象指针,对于双交易所随便使用哪个交易所对象都可以;
然后访问交易所对象的tradingDay字段(整数字符串),即可获得交易日信息;

示例代码:

C++
1
2
const XTFExchange *exchange = api->getExchange(0);
printf(Trading Day=%s\n, exchange->tradingDay);

如何获取最后一次报单的本地编号?

报单的本地编号是由用户自身维护的,一般在报单过程中是递增的,以保证编号的唯一性。如果API发生重启,最后一次的本地编号会丢失。API在重新登录柜台后,柜台会把上一次API报单的最后一个本地报单编号,返回给用户。可以通过下面的方法获取:

C++
1
2
XTFAccount *account;
XTFLocalOrderID lastID = account->lastLocalOrderID;

如何获得交易所报单通道号?

  1. 首先获得交易所对象指针,对于双交易所需要按需查询;
  2. 然后通过交易所对象的getChannelCount()查询交易所通道数量;
  3. 最后用getChannel(int pos)接口获得通道号的值;

示例代码:

C++
1
2
3
4
5
const XTFExchange *exchange = api->getExchange(0);
int count = exchange->getChannelCount();
for (int i = 0; i < count; ++i) {
    printf(channel id: %d\n, exchange->getChannel(i);
}

裸协议报单后收不到API回报

  1. 未登录或者登录掉线后的报单将无法收到回报
  2. MessageId错误
  3. clientindex或token错误,可通过以下方法获取

C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
///4.1版本API
void onLogin(errorCode, exchangeCount){
   /// 在登录响应的中获取交易所数目
   m_exchangeCnt = exchangeCount;
   /// 根据交易所数目获取对应交易所的ClientIndex和token数据
   for(i = 0; i < m_exchangeCnt; i++) {
   XTFExchange* pEx = mApi->getExchange(i);
     m_clientIndex = pEx->clientIndex;
     m_clientToken = pEx->clientToken;
   }
}
C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
///3.3版本API
void OnRspUserLogin(pRspUserLogin){
    /// 在登录响应的中获取ClientIndex
    m_clientIndex = pRspUserLogin->ClientIndex; 
    /// 根据ClientIndex获取token信息
    m_token = pTraderApi->GetClientToken(m_clientIndex);
    /// 用户根据实际情况获取自己所有需要的合约序号;
    for() {
      m_instrumentIndex = pTraderApi->GetInstrumentIndex(instrumentID);
    }
    /// 用户也可以调用异步查询接口, 然后在合约序号响应接口中获取自己需要的合约序号;
}

API登录提示错误的资金账号

资金账号填写错误或API更换accountid未重新初始化

获取不到合约涨跌停价时,该合约不支持自成交风控

使用investorid作为accountid登录柜台后,accountid变成investor_1

  1. API登录AccountID不以_结尾的客户账号都识别替换为_1结尾
  2. API登录AccountID以_3、_4、_5结尾的客户账号都识别替换为_2结尾

打开linux操作系统core dump核心转储

打开linux core dump功能后,当客户策略程序运行出现奔溃时,操作系统会将程序的内存、寄存器状态以及相关信息保存到程序目录下的一个文件中,便于后续debug调试与定位出错原因。

Bash
1
2
3
4
5
6
7
8
## 查看是否已打开,输出0为关闭,输出unlimited为打开
$ ulimit -c

## 打开core dump
$ ulimit -c unlimited

## 关闭core dump
$ ulimit -c 0

如果需要重启系统生效,需要在系统文件/etc/security/limits.conf中添加以下内容:

Text Only
1
2
*    hard    core    unlimited
*    soft    core    unlimited

大量回报接收时,出现TCP断链

TCP链接的缓存区大小受内核参数影响,柜台在某些极速场景下,可能会由于客户端接收缓存区不足而导致断链,可以在配置文件中 /etc/sysctl.conf 增加如下配置即可:

Text Only
1
2
3
4
5
net.core.rmem_default = 8388608
net.core.wmem_max=655360000
net.core.rmem_max=873800000
net.ipv4.tcp_rmem =819200 87380000 873800000
net.ipv4.tcp_wmem =409600 65536000 655360000

“3.3 API”的结构体定义和“协议报单”的结构体定义,同名结构体定义有差别(例如“struct CXeleFtdcOrderField”)。使用时,应该以哪边的为准呢?

裸协议报单,用协议报单的结构体定义;API报单,用API头文件里面的定义。

柜台是如何实现仓位组合的,API端如何打开仓位组合功能?

仓位组合实现方法:

  1. 上一交易日的历史仓位,柜台会自动组合;
  2. 日内交易的新开仓位,启用仓位自动组合之后,柜台会将已有的今仓和本次会话中的新开仓位,自动进行组合处理;
  3. 如果日内有多次登录,且最近一次没有启用仓位自动组合,那么上一次登录时,已组合的仓位不再变化,本次会话过程中的新仓,柜台不会自动组合

API打开仓位组合功能方法:

创建API实例后,调用api-enableAutoCombinePosition(true)接口,设置仓位自动组合功能即可。

做市商报价与撤销说明

  1. 报价成功时,会收到Received、Accepted和Queuing三条onQuote(如果交易所RSP乱序则可能不产生Received),同时产生衍生单的onOrder回报;
  2. XELE只支持撤普通报单和报价单,不支持直接撤报价衍生单;
  3. 撤销报价单成功时,不会收到onCancelQuote,对应未成交的衍生单会自动撤销,会收到对应的onCancelOrder;
  4. 撤销报价单失败时,只产生onCancelQuote;
graph TD
双边报价请求[insertQuote]
柜台接收[onQuote=Received]
柜台拒绝[onQuote=Rejected]
双边报价接收[onQuote=Accepted<br>onQuote=Queuing]
单边订单
主动撤单[不会收到onCancelQuote<br>产生各边onCancelOrder=Canceled<br>单边全成交则只有一条onCancelOrder]

双边报价请求--柜台拒绝-->柜台拒绝
柜台接收--交易所拒绝-->柜台拒绝
双边报价请求--柜台接收-->柜台接收
柜台接收--交易所接收-->双边报价接收
双边报价接收-.产生两个单边订单<br>且onOrder/onQuote不保序.->单边订单
双边报价接收--报价撤单或顶单被撤-->主动撤单
graph TD
撤单请求[cancelQuote]
柜台接收[无回调]
撤单拒绝[onCancelQuote=Rejected]
撤单接收[不会收到onCancelQuote<br>产生各边onCancelOrder=Canceled<br>单边全成交则只有一条onCancelOrder]

撤单请求--柜台拒绝-->撤单拒绝
柜台接收--交易所拒绝-->撤单拒绝
撤单请求--柜台接收-->柜台接收
柜台接收--交易所接收-->撤单接收

报价单sysOrderID、localOrderID和衍生单的关系

  1. sysOrderID的关系,报价单是N,报价衍生BID是N+1,报价衍生ASK是N+2;
  2. localOrderID的关系,报价单是M,报价衍生的BID和ASK都是M;

多实例报单问题

API报单时必须使用各自查询出来的合约对象报单。

常见错误:在同一个进程中使用两个账号分别创建实例,若使用API-01查询的合约对象在API-02中报单,会导致API-02收不到回报的问题,因为合约对象中保留了账户信息,柜台直接将回报发送给API-01处理。

郑商所功能使用说明

交易郑商所业务的客户,API需使用1050及之后版本,柜台需升级至Release-004及之后版本;

关于信号处理函数的说明

创建API实例时,如果是首次调用该接口,API默认会注册内部的信号处理函数(Signal Handler)用于调试用途。如果在调用makeXTFApi()之前,APP已经注册了信号处理函数,那么API会覆盖已注册信号处理函数,导致信号无法传递给用户定义的信号处理函数。

可以按照以下方法处理此问题:

  1. 如果API的版本低于4.1.1068版本,可以先调用makeXTFApi()接口,之后再注册用户自己的信号处理函数。调换注册的顺序,可以解决此问题;
  2. 如果API的版本等于或高于4.1.1068版本,除了上面的方法之外,还可以通过在配置文件中增加配置项REGISTER_SIGNAL_ENABLED=false,来关闭makeXTFApi()接口内部自动注册信号函数而导致覆盖的问题。默认API会自动注册内部信号处理函数,此选项需要显式指定为false,才能生效;

onload驱动升级说明

首先,通过onload --version 命令检查当前驱动的版本,当前版本小于7.x或大于7.x时请参考下述步骤进行操作:

1、卸载原驱动(首次安装直接跳过此步骤)

onload_uninstall

2、进入安装脚本目录

cd onload-7.1.3.202/scripts

3、给安装脚本赋执行权限

chmod +x onload install

4、执行安装脚本

./onload_install

5、加载onload

./onload tool reload

6、安装模块

modprobe sfc

提示:升级后也可通过onload --version命令再次检查驱动版本

非本柜台回报处理说明

针对本柜台交易的品种,同一个交易客户如果该品种在主席平仓或其他柜台上报单交易,API会正常推送相关的onOrder和onTrade,回报中的用户本地报单编号固定是0x88888888,交易客户如有需要可根据编号特性自行屏蔽;