VeighNa量化社区
你的开源社区量化交易平台
hxxjava's Avatar
Member
离线
419 帖子
声望: 155

CTP 6.6.1 API接口说明中关于TAS介绍的介绍:

TAS介绍

本文旨在介绍CTP API中与TAS(Trading at Settlement, TAS 盘中结算价交易机制)业务相关的内容,具体交易细则请参考交易所官方文档。

1. 报单

接口名称:ReqOrderInsert

1.合约(InstrumentID):填写TAS合约,如对sc1901进行TAS交易,则合约填写sc1911TAS
2.价格(LimitPrice):必须为0。
3.类型(OrderPriceType):只支持限价指令THOST_FTDC_OPT_LimitPrice。

其余字段与标的期货对应字段意义相同(买卖方向、平今平昨、投机套保等字段都需填写)。
TAS开仓,盘中成交后直接计入期货持仓;TAS平仓区分平今/平昨,平对应的期货持仓;平仓的仓位冻结按照标的合约进行冻结。

2. 成交

接口名称:OnRtnTrade

1.交易成交类型(TradeType):为普通成交THOST_FTDC_TRDT_Common。
2.成交价(Price):对于TAS成交,成交价无意义。

3. 持仓

接口名称:OnRspQryInvestorPositionDetail

1.持仓明细新增字段特殊持仓标志(SpecPosiType):标识该明细为tas衍生成交。

接口名称:OnRspQryInvestorPosition

1.持仓汇总新增字段tas持仓手数(TasPosition):记录该汇总中TAS开仓的数量。
2.持仓汇总新增字段tas持仓成本(TasPositionCost):记录该汇总中TAS持仓成本。

tas只有当天有效,不计入昨仓。结算完就变成标的持仓了,不再是tas合约持仓。可以理解成标的合约的昨持仓。

4. 手续费和保证金

开仓保证金和手续费冻结都按照标的合约停板价冻结。
实收保证金率和手续费率都按照标的合约计算。
保证金率和手续费率使用标的合约的费率,通过费率查询接口只能查询到标的合约的费率。

5. 盈亏

计算持仓盈亏的时候,对于(总数量-TAS数量)部分计算持仓盈亏和保证金。对于TAS数量不计算盈亏。

6.合约行情

合约代码、合约状态、买卖方向、报单量、成交量、日期、时间等字段正常发布。其余字段无意义,均为空。
盘中TAS成交量、成交额不计入标的合约的成交量、成交额。

7. 代码示例

void orderinsert()
{
    CThostFtdcInputOrderField t = { 0 };
    strcpy_s(t.BrokerID, "1007");
    strcpy_s(t.InvestorID, "10000001");
    strcpy_s(t.UserID, "10000001");
    t.Direction = THOST_FTDC_D_Sell;
    t.CombOffsetFlag[0] = THOST_FTDC_OF_Open;
    t.CombHedgeFlag[0] = THOST_FTDC_HF_Speculation;
    t.ContingentCondition = THOST_FTDC_CC_Immediately;
    strcpy_s(t.InstrumentID, "sc2006TAS");  //tas合约代码
    t.ForceCloseReason = THOST_FTDC_FCC_NotForceClose;;
    t.LimitPrice = 0;   //价格为0
    t.StopPrice = 0;
    t.OrderPriceType = THOST_FTDC_OPT_LimitPrice;
    t.VolumeCondition = THOST_FTDC_VC_$;
    t.TimeCondition = THOST_FTDC_TC_GFD;
    t.VolumeTotalOriginal = 10;
    m_ptraderapi->ReqOrderInsert(&t, m_requestid++);
}

上期技术的官网上显示,看穿式监管Linux/Windows版本。增加对tas指令的支持,tas功能需要接入的CTP柜台为6.3.19P1及以上版本。包含采集模块和tradeapi。
也就是说从CTP 6.3.19P1 版本开始的API交易支持tas功能了,包括生产版本和评测版本。

http://www.sfit.com.cn/5_2_DocumentDown_2.htm

仕腾 wrote:

看了一下楼主的代码,给了我不少启发。我看楼主代码中用到的是qt原生qtchart的控件,其实qt有不少开源的绘图库,例如qwt,qcustomplot等等,像K线,柱线这些基本的绘图都有提供,我可以看看能不能整合进来。

欢迎改进!

1. 什么是TAS指令?

结算价交易(Trading at Settlement,以下简称TAS)指令,允许交易者在规定交易时段内按照期货合约当日结算价或当日结算价增减若干个最小变动价位申报买卖期货合约。

2. TAS指令撮合原的则是什么?

TAS指令仅可与同一合约的TAS指令撮合成交。在集合竞价采用最大成交量原则进行撮合,在连续竞价交易时段采用价格优先、时间优先原则进行撮合。

3. 为什么要推出TAS指令?

TAS指令已在国际成熟市场得到广泛使用,其本质是为市场提供了一种便捷高效的风险管理工具,从而对促进市场功能发挥、改善市场投资者结构、提升价格影响力等起到积极作用。
对于实体企业,在进行现货贸易点价时,多采用期货合约结算价作为定价基准。在利用期货市场进行风险对冲时,如果没有这个工具,一般要通过盘中多次下单来模拟当日结算价,因此在交易执行方面存在较高的难度,且套保效率较低。
TAS指令可以在规定的交易时段内以结算价或结算价附近的价格进行交易,大大降低了企业围绕结算价交易的不确定性。企业可利用TAS指令更便利、更精准地做好风险管理。
从成熟市场普遍情况看,除了实体企业利用TAS指令进行风险管理,ETF和长期策略基金等机构投资者也运用TAS指令来进行换月移仓交易等,这有效降低了因机构头寸大量变化对市场短期价格的冲击。因此,TAS指令的推出能够促进市场主体有效改善利用结算价进行套保交易的执行效率,吸引境内外多元化市场主体的积极参与,进一步完善投资者结构,有益于市场稳定运行。同时有利于交易者更为便利和广泛地参考中国期货价格,从而提升市场的价格影响力。

黄裳 wrote:

description

求教,这是怎么回事??
NameError: name 'Tuple' is not defined

编译器不认识Tuple

怎么回事呢??

Tuple不是python基本类型,在文件前面前面加入:from typing import Tuple之类的就可以了,

假如您原来使用过SpreadTrading模块,如何排除安装问题?

2.6版本的vnpy在SpreadTrading模块改动也是比较大的,好像是已经可以支持价差的逻辑仓位。并且保持价差设置spread_trading_setting.json、价差策略spread_trading_strategy.json的文件格式已经变了,去掉了spread_trading_advanced.json,同时又增加了一个存价差个腿的持仓的json文件spread_trading_pos.json,所以如果不对这些文件做处理,在执行SpreadTrading模块的时候程序是会崩溃的!
所以干脆把你自己的用户目录下的这几个文件改名或者删除:

spread_trading_setting.json
spread_trading_strategy.json
spread_trading_advanced.json

改名或者删除这三个文件后,重新创建价差,价差策略,然后手动或启动策略自动对价差进行操作就可以了!

假如您原来使用的是MySQL数据库,如何排除安装问题?

  1. 在cmd窗口中登录MYSQL server:
    mysql -uroot -p
    输入密码
    登录mysql server成功后,输入下面的命令删除dbbardata,dbbaroverview和dbtickdata三个表:

    mysql> use vnpy
    mysql> drop table dbbardata;
    mysql> drop table dbbaroverview;
    mysql> drop table dbtickdata;
  2. 其他步骤除了数据库的部分外和 问题解决啦,步骤如下! 相同;

  3. 重新启动vnpy,问题就解决。
  4. 如果你使用的是其他数据库,如:PostreSQL、MongoDB或DolphinDB,方法与此类似。

hill-陆 wrote:

最开始提升 rqdatac not install

pip install rqdatac 然后:
pip install --upgrade vnpy_ctastrategy 也升级了,还是报错。

看看这个:
https://www.vnpy.com/forum/topic/7712-sheng-ji-dao-2-6ban-ben-hou-hui-ce-xia-zai-shu-ju-shi-yu-dao-xia-mian-de-cuo-wu-:

问题解决啦,步骤如下!

(注:本人原来使用的是SQLite数据库。)

1 增加全局设置:

如上图把关于datafeed的
datafeed.name 为 rqdata
datafeed.username 为 米筐用户名称
datafeed.password 为 米筐用户密码
保存设置后退出vnpy软件。

2. 修改数据名称

进入个人目录,修改其中的.trader\database.db,为.trader\database-old.db。系统重新启动的时候会出现创建新的database.db,如果你database-old.db中还有你不能割舍的数据,日后再想办法重新编程序迁移数据。

3. 修改vnpy_ctastrategy\engine.py中第151行,这里有错误,修改如下:

    def query_bar_from_datafeed(
        self, symbol: str, exchange: Exchange, interval: Interval, start: datetime, end: datetime
    ):
        """
        Query bar data from datafeed.
        """
        req = HistoryRequest(
            symbol=symbol,
            exchange=exchange,
            interval=interval,
            start=start,
            end=end
        )
        # data = self.datafeed.query_history(req) # hxxjava
        data = self.datafeed.query_bar_history(req)   
        return data

4. 重新启动vnpy,下面的几个问题就解决了:

  1. 数据管理模块无法下载合约数据的问题
  2. CTA Backtester模块无法下载数据的问题
  3. CTA Strategy模块无法初始化和启动策略的问题

其他模块是否有问题还未可知!

1、命令执行pip install --update vnpy_ctastrategy

仍然不行,问题依旧。

2. 用命令行启动python -m vnstation

启动的时候,报出下面的错误:

qt.network.ssl: QSslSocket: cannot resolve SSL_CTX_set_ciphersuites
qt.network.ssl: QSslSocket: cannot resolve SSL_set_psk_use_session_callback
qt.network.ssl: QSslSocket: cannot call unresolved function SSL_set_psk_use_session_callback
qt.network.ssl: QSslSocket: cannot call unresolved function SSL_set_psk_use_session_callback
qt.network.ssl: QSslSocket: cannot call unresolved function SSL_set_psk_use_session_callback
qt.network.ssl: QSslSocket: cannot call unresolved function SSL_set_psk_use_session_callback
找不到数据服务驱动vnpy_,使用默认的RQData数据服务
js: Uncaught ReferenceError: c is not defined

查找了代码后与系统设置有关。

description

3. 图中三项应该怎么填写?

好像是说设置里面关于datafeed的name、username和password没有填写,
本人已经有米筐的账户,那么这三项应该怎么填写?

1. 升级后进入回测,界面如下:

description

2. 下载数据时遇到下面的错误

11:11:22 初始化CTA回测引擎
11:11:22 策略文件加载完成
11:12:26 ----------------------------------------
11:12:26 rb2201.SHFE-1m开始下载历史数据
11:12:26 数据下载失败,触发异常:
Traceback (most recent call last):
File "D:\ProgramFiles\VnStudio\lib\site-packages\vnpy_ctabacktester\engine.py", line 404, in run_downloading
data = self.datafeed.query_bar_history(req)
File "D:\ProgramFiles\VnStudio\lib\site-packages\vnpy_rqdata\rqdata_datafeed.py", line 164, in query_bar_history
adjust_type="none"
File "D:\ProgramFiles\VnStudio\lib\site-packages\rqdatac\decorators.py", line 150, in wrap
return func(args, **kwargs)
File "D:\ProgramFiles\VnStudio\lib\site-packages\rqdatac\services\get_price.py", line 103, in get_price
order_book_ids, market
File "D:\ProgramFiles\VnStudio\lib\site-packages\rqdatac\services\get_price.py", line 222, in classify_order_book_ids
ins_list = ensure_instruments(order_book_ids, market=market)
File "D:\ProgramFiles\VnStudio\lib\site-packages\rqdatac\validators.py", line 168, in ensure_instruments
all_instruments = _all_instruments_dict(market)
File "D:\ProgramFiles\VnStudio\lib\site-packages\rqdatac\decorators.py", line 129, in wrapper
value = user_function(
args, kwargs)
File "D:\ProgramFiles\VnStudio\lib\site-packages\rqdatac\services\basic.py", line 139, in _all_instruments_dict
ins = _all_cached_instruments_list(market)
File "D:\ProgramFiles\VnStudio\lib\site-packages\rqdatac\decorators.py", line 129, in wrapper
value = user_function(*args,
kwargs)
File "D:\ProgramFiles\VnStudio\lib\site-packages\rqdatac\services\basic.py", line 134, in _all_cached_instruments_list
return _all_instruments_list(market)
File "D:\ProgramFiles\VnStudio\lib\site-packages\rqdatac\services\basic.py", line 112, in _all_instruments_list
ins = [Instrument(i) for i in get_client().execute("all_instruments", market=market)]
File "D:\ProgramFiles\VnStudio\lib\site-packages\rqdatac\client.py", line 31, in execute
raise RuntimeError("rqdatac is not initialized")
RuntimeError: rqdatac is not initialized

3. 好像是说米筐数据没有初始化?

虽然说是整个删除以前的版本,然后重新安装的2.6版本,但是以前的设置一点也没有改变,难道是以前的米筐接口设置不可以在新版本中继续使用了吗?

CTP接口之保证金率手续费率查询中我们已经讲过如何查询保证金率和手续费率,这一篇再详细讲一下根据费率计算相应的保证金,为最终资金权益等的计算做铺垫。

一、保证金计算公式

保证金的计算公式如下:
保证金 = 按手数保证金费*手数+按金额保证金率*金额*手数*合约乘数=(按手数保证金费+按金额保证金率*金额*合约乘数)*手数
按照API中的字段即是:
多头保证金=(LongMarginRatioByVolume + LongMarginRatioByMoney * Price *VolumeMultiple )* Volume
空头保证金类似。
这个公式中按手数保证金费和按金额保证金率可以通过ReqQryInstrumentMarginRate查询得到;合约乘数可以通过ReqQryInstrument查询得到;手数是涉及到计算到的手数。那就只剩下一个问题,用什么金额去计算?

二、保证金价格类型

用什么金额去计算客户的保证金,对于昨仓统一使用昨结算价计算,对于今仓,在期货公司后台是可以设置的。客户也可以通过ReqQryBrokerTradingParams(请求查询经纪公司交易参数)查询得到设置的类型。查询示例如下:

qryField = api.CThostFtdcQryBrokerTradingParamsField()
qryField.BrokerID="8000"
qryField.InvestorID="012345"
qryField.CurrencyID = "CNY"
tradeapi.ReqQryBrokerTradingParams(qryField,0)

在该查询的回调结果中查看MarginPriceType枚举值:

def OnRspQryBrokerTradingParams(self, 
    pBrokerTradingParams: 'CThostFtdcBrokerTradingParamsField', 
    pRspInfo: 'CThostFtdcRspInfoField', 
    nRequestID: 'int', bIsLast: 'bool') -> "void":    
    if pBrokerTradingParams is not None:                            
        print(f"MarginPriceType:{pBrokerTradingParams.MarginPriceType}")

枚举值列表如下:

///昨结算价
#define THOST_FTDC_MPT_PreSettlementPrice '1'
///最新价
#define THOST_FTDC_MPT_SettlementPrice '2'
///成交均价
#define THOST_FTDC_MPT_AveragePrice '3'
///开仓价
#define THOST_FTDC_MPT_OpenPrice '4'

可见计算保证金中用到的价格类型有4种。

下面我们举例说明,设au2106昨结算价为391.74,查询合约得到合约乘数为1000,查询保证金率得到LongMarginRatioByMoney为0.08,LongMarginRatioByVolume为0.0,ShortMarginRatioByMoney为0.08,ShortMarginRatioByVolume为0.0。

三、保证金的计算

01 以昨结算价计算为例

目前simnow即采用昨结算价计算保证金。如果上述查询返回得到参数MarginPriceType为1,则说明CTP后台使用昨结算价计算保证金。
此时假设以396.16报买开1手,未成交,CTP会冻结保证金,账户的可用资金会减少。这时,
冻结保证金=(按手数保证金费+按金额保证金率*昨结算价*合约乘数)*手数=(0.08*391.74*1000)*1=31339.20。
经过一段时间 ,该买开仓以396.16成交,此时客户有1手多头持仓,相应的冻结保证金减少,增加占用保证金。这时,
冻结保证金=0占用保证金=(按手数保证金费+按金额保证金率*昨结算价*合约乘数)*手数=(0.08*391.74*1000)*1=31339.20。
在整个交易日内,au2106合约的行情最新价格上上下下不停变化,这时客户该合约上的持仓盈亏也不断变化,但是这1手占用的保证金因为是用昨结算价计算的,昨结算价不变,占用保证金也不变。
等到第二个交易日,该合约有新的结算价时,占用保证金才发生相应的变化。

02 其他价格类型

如果上述查询返回得到参数MarginPriceType为2,则说明CTP后台是以行情中最新价计算保证金的。
这时冻结保证金和占用保证金均是使用最新 价,而且会随着最新价的更新而动态变化。其他的价格类型也是类似计算,按成交均价算则是按照行情里面的均价更新,按开仓价算则是冻结时用报单价,成交后用成交价计算。
只有在最新价和成交均价这两种情况下今仓的保证金值才会随着行情波动而更新,昨仓的保证金值一直是用昨结算价计算得到,不会改变。

四、保证金计算其他注意项

01 保证金优惠

为了增加资金可用率,交易所都有一定的保证金优惠政策。例如上期所的品种大额单边保证金优惠,是指同一品种内所有的合约按多空分别累计保证金,然后实际只收大额一边的保证金,因为同品种多空有一定风险对冲,同时收两边保证金过于保守。

举例:

客户总资金为200,000,此时au2106多头占用保证金100,000,au2102空头占用保证金80,000,根据品种大单边优惠规则,CTP后台实际算占用保证金为100,000,也就是说客户现在可用资金为200,000-100,000=100,000。
这时客户又成交1手au2104的空头,占用保证金为30,000,总的空头占用保证金为110,000,大于多头的100,000。所以CTP后台实际占用保证金为110,000,客户可用资金为200,000-110,000=90,000。
品种是否采用大额单边保证金算法可以根据查合约ReqQryInstrument请求得到返回中的MaxMarginSideAlgorithm来判断。当下的大额单边保证金占用多少,可以通过ReqQryInvestorProductGroupMargin查询得到。
除了上期所品种内的大额单边保证金优惠外,中金所还有跨品种的大额单边保证金优惠,例如对股指类期货:沪深300股指期货、上证50股指期货和中证500股指期货这三个的跨品种双向持仓,按照交易保证金单边较大者收取交易保证金;对国债类期货也实施跨品种单向大边保证金制度。

大商所郑商所对普通合约还是按照双边收取保证金,但对于标准套利合约只收两个保证金中较高的,大商所盘中申请组合成功也有大边保证金优惠。

02 保证金率调整

保证金率在整个合约存在过程中并不是一直不变,常见的调整保证金情况有:

  • 节假日前为了规避国际市场的风险调整保证金;
  • 单边市出现停板情况时调整保证金;
  • 出现极端风险或市场震荡时调整保证金;
  • 持仓量达到一定数量是交易所调整保证金;
  • 临近交割月调整保证金;
  • 交易所规定的其他情况。

03 市价单保证金计算

对于市价单,在计算保证金冻结时,使用涨跌停价计算,计算占用保证金时,按照价格类型采用相应的价格计算。

保证金率和手续费率都是程序化交易者非常关心的话题,保证金率涉及到开仓时账户资金的冻结和占用,撤单或平仓则会解冻和解占用。手续费率则是真正要付给期货公司的佣金,而且通常开仓,平昨和平今手续费还各有不同。
这里面各种各样的坑,比如有人反应期货公司有的按交易所保证金率收,有的按交易所两倍来收,这样同样的钱在有的期货公司够开2$,而在有的就只能开1手;手续费那更是收的五花八门,各种各样的都有。甚至还有人反应出现过实际收的和开户时说的不一样这种事。
其实这两个费率都是可以通过CTP API直接查询得到的,但这两个查询和其他查询(如查询合约,资金,结算单等)有点不一样,所以本篇单独讲一下。

一、 查询保证金率

官方文档中涉及到保证金率的接口好几个,新手开发看到经常一脸懵逼,不知道究竟哪个才是实际中用到的。这里我们先罗列一下相关的:

//请求查询合约保证金率
def ReqQryInstrumentMarginRate(self, 
    pQryInstrumentMarginRate: 'CThostFtdcQryInstrumentMarginRateField', 
    nRequestID: 'int') -> "int"
//查询合约的返回中会带每条合约的保证金率
def ReqQryInstrument(self, 
    pQryInstrument: 'CThostFtdcQryInstrumentField', 
    nRequestID: 'int') -> "int"
//请求查询交易所保证金率
def ReqQryExchangeMarginRate(self, 
    pQryExchangeMarginRate: 'CThostFtdcQryExchangeMarginRateField', 
    nRequestID: 'int') -> "int"
//请求查询交易所调整保证金率
def ReqQryExchangeMarginRateAdjust(self, 
    pQryExchangeMarginRateAdjust: 'CThostFtdcQryExchangeMarginRateAdjustField',     
    nRequestID: 'int') -> "int"

在实际交易中冻结和占用的计算其实是采用第一个查询函数ReqQryInstrumentMarginRate的返回结果。
而ReqQryInstrument中返回的保证金率通常是交易所保证金率,计算中并不用到。ReqQryExchangeMarginRate和ReqQryExchangeMarginRateAdjust查询得到的是交易所相关的保证金率,这也只在计算中间过程中会用到。
这里我们只讲实际计算中用到的ReqQryInstrumentMarginRate查询,其参数类型为CThostFtdcQryInstrumentMarginRateField,具体字段:

01必填字段

BrokerID //经纪公司代码
InvestorID //投资者代码
HedgeFlag //投机套保标志

前两者开户时可得到,投机套保标志一般投资者填投机就可以。注意这三个字段是一定要填的,不填的话返回值就为空。

02选填字段

InstrumentID //合约代码

如果InstrumentID填空,则返回客户当前持仓对应的合约保证金率,否则返回相应InstrumentID的保证金率。也就是说这个查询和其他查询不一样,如果什么都不填,是不会得到所有的合约保证金率的。
最后给出个查询保证金率的示例:

qryinfofield = api.CThostFtdcQryInstrumentMarginRateField()
qryinfofield.BrokerID='9999'
qryinfofield.InvestorID='000001'
qryinfofield.InstrumentID='rb2007'
qryinfofield.HedgeFlag = api.THOST_FTDC_HF_Speculation
tapi.ReqQryInstrumentMarginRate(qryinfofield,0)

二、 查询手续费率

查手续费的接口也有好几个,罗列如下:

//请求查询合约手续费率
def ReqQryInstrumentCommissionRate(self, 
    pQryInstrumentCommissionRate: 'CThostFtdcQryInstrumentCommissionRateField',     
    nRequestID: 'int') -> "int":
//请求查询报单手续费    
Def ReqQryInstrumentOrderCommRate(self, 
    pQryInstrumentOrderCommRate: 'CThostFtdcQryInstrumentOrderCommRateField',
     nRequestID: 'int') -> "int":    
// 请求查询期权或做市商合约手续费函数这里就不罗列了...

在期货交易中,实际计算用到的只有个前面两个函数,其中第一个查询的是合约的手续费率,第二个查询的是报单申报手续费(就是每报撤一次单子都会收一笔费用),目前来说这是中金所特有的。

也就是说中金所的手续费分为两部分,包括交易手续费和申报费两部分,前者可以通过第一个查询函数查到,后者通过第二个查询函数得到。
两个查询函数的参数类型虽然不一样,但是字段填写方法是一致的,这里我们以ReqQryInstrumentCommissionRate为例讲解,参数类型为CThostFtdcQryInstrumentCommissionRateField,具体字段:

01必填字段

BrokerID //经纪公司代码
InvestorID //投资者代码

02选填字段

InstrumentID //合约代码

如果InstrumentID填空,则返回客户当前持仓对应的合约手续费率,否则返回相应InstrumentID的合约手续费率。和上面查询保证金率的逻辑一样。

查询结果返回值还需要注意几点:

  1. 以开仓为例,查询手续费返回结果中有两项关于开仓的字段:OpenRatioByMoney(开仓手续费率)和OpenRatioByVolume(开仓手续费),这是两种计算手续费的方法。实际计算时的开仓手续费公式为:

手续费 = 成交数量*(成交价*合约乘数*OpenRatioByMoney+OpenRatioByVolume)

  1. 有时查询某合约(例如IF2009)的手续费时,得到的是其对应品种(例如IF)的手续费。这是因为该品种下所有合约的手续费都是一样的,所以就直接将手续费设到品种级别了。
  2. 交易所的手续费率这里查不到,大家可以去交易所官网上看,通常在交易数据/结算参数中。要注意的是大商所手续费中有个短线开平仓的概念,其实就是指今开今平。

最后给出个查询手续费率的示例:

qryinfofield = api.CThostFtdcQryInstrumentCommissionRateField()
qryinfofield.BrokerID='9999'
qryinfofield.InvestorID='000001'
qryinfofield.InstrumentID='rb2007'
tapi.ReqQryInstrumentCommissionRate(qryinfofield,0)

【来自CTP期货期权API接口说明.chm】
CTP交易系统基于安全和性能考虑,在诸多地方有流量控制,其中流量控制又分FTD报文流量控制、报单流量控制、查询流量控制等。而这些流量控制分布在各个不同的地方。此处将会给大家详细介绍。

1.报单流控

报单流控是指用户在本交易系统报单(ReqOrderInsert)、撤单(ReqOrderAction)时每秒内允许的最大笔数。
报单流控限制配置在CTP柜台端【程序化交易频繁报撤单管理】菜单。
如果超过这个限制API会通过OnRspOrderAction提示:“CTP:下单频率限制”。

2.查询流控

查询流控是指用户当前Session在做查询的时候每秒内允许的最大请求笔数。
查询流控配置在交易前置组件上,配置项为【QryFreq】。其中API内置了在途查询流控1笔。
自从穿透式监管版本以后,API在连接交易前置时,会去查询到前置的查询流控设置(该设置配置在front_se组件)。假设前置配置了2笔/秒,那么连接该前置的API每秒只能发# 起2笔查询请求。
但是要注意,不管怎么配置,API都内置了在途流控,在途查询流控为1笔。即,当前这笔查询请求发出后,在未收到响应前,不能发起下一笔查询请求。
在过去,查询流控是内置在API里,1笔每秒,在途1笔。
如果超过交易前置配置的查询流控,则会触发OnRspError,并提示:“CTP:查询未就绪,请稍后重试”
如果超过API内置的在途流控,则查询请求的返回值为-2,表示未处理请求超过许可数。
所有ReqQuery开头查询函数不受流控限制,原因是此类函数都是通过交易核心处理的,不通过查询核心。

3.FTD报文流控

FTD报文流控是指用户当前Session在提交API指令的时候每秒内允许的最大请求笔数。
FTD报文流控配置在交易前置组件上,配置项为【FTDMaxCommFlux】。
FTD报文流控是一种综合性的流控手段,API的所有接口在跟前置交互的时候都是使用FTD协议的报文进行通讯的,因此这就意味着,登录、查询、报单、撤单和报价等等所有请求都在FTD报文流控的限制范围内。
例如如果配置为6,可以简单理解为用户仅能调用6次API请求指令,包括登录、查询、报单撤单等等。
如果超过FTD报文流控,则超过的指令会被缓存到前置,直到下一秒发出。例如用户在一秒内报单10笔,则前6笔会立即发送给核心,而后4笔则会被缓存在前置,到下一秒才发出。因此对于用户程序端的感受就是后4笔报单延迟很大,实则是受到了流控。
注意,FTD报文流控不会有错误信息或错误返回。

4.前置连接数流控

前置连接数流控是指在本交易前置对同一IP每秒允许的最大API连接请求数。
前置连接数流控配置在交易前置组件上,配置项为【ConnectFreq】。
需要注意的是,API连接请求指的是API从init到OnFrontConnected的过程,跟登录无关。可以简单理解为一次init就是一个连接请求。
例如如果配置为20,则一秒内最多有20个session建立跟前置的连接。
如果超过前置连接数流控则会被主动断开连接,触发OnFrontDisconnected。因此用户如果发现自己的程序一连接前置就被断开,则除了版本问题外,有可能是遇到了连接数流控。

5.同一用户最大允许在线会话数

同一用户最大允许在线会话数是指同一个用户(UserID)在本交易系统中同时登录在线的最大允许会话数。
同一用户最大允许在线会话数配置在柜台或交易核心中。
注意,这个会话数针对的是本交易系统,而非单一前置。
如果超过同一用户最大允许在线会话,则会通过OnRspUserLogin返回“CTP:用户在线会话超出上限”的错误。

6.交易所API流控

交易所API流控指通过交易所API发送报单等请求的每秒最大允许数。
交易所API流控的阈值设置在交易所端,由交易所API查询获取,该流控实际控制在交易所API端。
受到交易所流控后会触发OnRtnOrder,报“CTP:交易所每秒发送请求数超过许可数”或者“CTP:交易所未处理请求超过许可数”。

御前侍卫 wrote:

我用的 simnow 仿真系统, 发现策略 在开盘接收到的第一根5分钟K线的时间戳总是错的。以下是日志:
8/27 号的日志:
2021-08-27 08:46:13,713 INFO: CTA策略全部启动
2021-08-27 09:05:00,095 INFO: myhk01: [2021-08-27 07:37:00] ### 收到 on_5min_bar 回调 ###

8/30号的日志:
2021-08-30 08:46:11,493 INFO: CTA策略全部启动
2021-08-30 09:05:00,063 INFO: myhk01: [2021-08-30 07:40:00] ### 收到 on_5min_bar 回调 ###

第一根K线时间戳,开始时间应该是 09:00:00 , 可为什么实际却是 07:37:00 和 07:40:00 呢?
有哪位大佬指点下思路。谢谢

原因:

  1. CTP接口夜间休市会关闭
  2. 如果你没有定时退出的习惯,CTP接口会在次日早晨再次开放,CTP本地API定期重新连接simnow的服务器,CTP连接会重新RESTART(默认的)
  3. 如果早上重启启动了vnpy,并且此时simnow的服务器CTP接口会已经开放,CTP连接立即建立,此时也是RESTART(默认的)
  4. CTP连接立时,客户端MdAPI和TdAPI会重新接受到市场的当前所有的合约信息、 历史委托单(当前交易日的)、历史成绩单(当前交易日的)、当前持仓和账户信息,另外还有就是立即推送客户端的订阅行情,而此时接收到的tick行情的时间,该时间不是上一个交易时间段结束的时间,也不是该合约最后一个tick的时间,而是订阅被接受的时间,当然也有例外,CZCE的合约是本地时间。
  5. 5分钟的bar是用tick合成出来的,如果您不对推送来的tick进行判断和处理,直接使用,那么就会出现有5分钟bar的时间戳为非交易时间段的现象。
  6. 另外,就算上述的原因都没有出现,vnpy当前的BarGenerator也会出现每个交易日的都必然多出1个5分钟bar的情况,因为它没有考虑集合竞价的存在。而集合竞价通常是在每个交易日的前5分钟进行的,开市前1分钟只推送1个开盘tick,这会必然导致每天每个你使用的品种都会多出1个5分钟bar。
  7. 关于bar的合成比较复杂,你可以参考本人的帖子,可能你会发现更多你意想不到的问题:
    如何更有效地利用合约交易状态信息——来看看CTP接口中的脏数据!
    如何更有效地利用合约交易状态信息——交易状态信息管理器。
    如何更有效地利用合约交易状态信息——把集合竞价tick合并到开盘的K线中?

lyl1836 wrote:

description

macd 的 diff, dea 的确是可能超出正负100,这是文华上的截图。

没有时间进一步研究MacdItem的细节,我只是抛砖引玉,目前代码的大体思路是没有问题的,你接着细致点研究下吧。

因为前面的:self.clear price() 已经执行了。

三个原因导致BarData里不需要表示宽度的成员:

1)很多情况下BarData的交易时长是不相等的,有了时间宽度的成员也不能够推导出当前K线的结束时间,也无法推导出下一个K线的开始时间;
2)不同宽带的K线本身就不应该放在一个容器里。不同时间宽度K线的区分可以通过陈放的容器的不同来区分,如5分钟K线放在bars_5min列表,10分钟K线放在bars_10min列表也就可以区分了。
3) 如果增加了,那么每股BarData在存储的时候都必须多出一个时间宽度字段,也是有代价的。由于1)和2)两个原因,时间宽度又不是很有用或者必须,所以不要也罢。

用Python的交易员 wrote:

已经在vnpy_spreadtrading项目中修复

好的,谢谢!!!

© 2015-2022 微信 18391752892
备案服务号:沪ICP备18006526号

沪公网安备 31011502017034号

【用户协议】
【隐私政策】
【免责条款】