黄裳 wrote:
请教一个问题,在盘中实时行情之下,行情每跳一下,相应的一分钟线,以及基于一分钟线合成的五分钟,30分钟,以及小时线会跟着跳动吗??也就是随着每一个tick的到来,会自动更新1分钟线。但五分钟以及以后的周期,是不是也是同步更新的??
或者只是一分钟线完成以后,才更新五分钟线?也就是五分钟线每个bar,只更新五次。每一分钟更新一次??
用户CTA策略使用vnpy系统自带的BarGenerator时,假如你创建K线生成器的方法是:
self.bg1 = BarGenerator(self.on_bar,5,self.on_5min_bar)
self.bg2 = BarGenerator(self.on_bar,30,self.on_30min_bar)
那么对tick数据的处理节奏是:
1、用户策略的on_tick()每个tick都会被执行,on_tick()接受tick推送数据,产生1分钟bar,tick数据的时间的分钟数与1分钟bar的分钟数不相同时结束1分钟bar,然后执行on_bar
2、在交易时段内每1分钟都会执行on_tick(),on_bar()接受1分钟bar,利用这些1分钟bar合成出5分钟bar,然后执行on_5min_bar(),利用这些1分钟bar合成出30分钟bar,然后执行on_30min_bar()
3、在交易时段内每5分钟都会执行on_5min_bar(),on_5min_bar()接受5分钟bar,你的策略就可以利用这些5分钟bar进行交易的入场和离场信号。
4、在交易时段内每30分钟都会执行on_30min_bar(),on_30min_bar()接受30分钟bar,你的策略就可以利用这些30分钟bar进行交易的入场和离场信号。
因此,在不是整5分钟的时候,5分钟bar是不会被更新的;在不是整30分钟的时候,30分钟bar是不会被更新的.
远山 wrote:
请问下楼主,怎么不让K线、成交量等图形不要顶着视图的上下边框绘制(如K线视图,最高价最低价都是顶着上下边框绘制的)?一来有些指标绘制会超过视图内所有K线的最低最高价,二来也很不美观。对Qt的图形编程完全是门外汉,看了看代码,暂时没找出修改的地方。
另外,少量K线时,每根K线显示得非常大,按缩放键也不起作用。看代码似乎最小缩放比例跟载入的K线数量有关,如果想让少量K线也能缩放到合适观看的尺寸,需要怎么修改?
你说的让K线、成交量等图形不要顶着视图的上下边框绘制,其实特别容易,只要修改下容纳chart_widget的容器就可以了。研究下Qt5的界面设计就OK了。
K线图的操控在pyQtGraph中有标准的方法,如按住鼠标左键左右拖动,滚轮前后波动等等,自己摸索下吧。
只有日K数据可以进行CTA策略回测吗?
自己做个策略账户,对每个运行策略的交易进行记录进行保存,然后计算盈亏、保证金和手续费进行统计,就可以了.
学与忍 wrote:
我合并到回测界面,用界面测试时,发现k线图的日期要比回测系统的成交组件和委托组件日期慢一天。打开k线图表时会比较卡。
如果K线的数量比较多的话,首次打开的应该是比较慢的。应该是使用合成的K线来显示,比如你使用15分钟的K线来产生信号,那么就直接使用15分钟的K线来显示。回测使用默认的1分钟K线显示,K线数量就会很多,当然觉得卡啦,即使使用其他软件也会觉得卡的。
看看ArrayManager的update_bar()函数的代码就知道了
def update_bar(self, bar: BarData) -> None:
"""
Update new bar data into array manager.
"""
self.count += 1
if not self.inited and self.count >= self.size:
self.inited = True
self.open_array[:-1] = self.open_array[1:]
self.high_array[:-1] = self.high_array[1:]
self.low_array[:-1] = self.low_array[1:]
self.close_array[:-1] = self.close_array[1:]
self.volume_array[:-1] = self.volume_array[1:]
self.open_interest_array[:-1] = self.open_interest_array[1:]
self.open_array[-1] = bar.open_price
self.high_array[-1] = bar.high_price
self.low_array[-1] = bar.low_price
self.close_array[-1] = bar.close_price
self.volume_array[-1] = bar.volume
self.open_interest_array[-1] = bar.open_interest
李贵珍 wrote:
xiaohe wrote:
- 要load_bar完成后(初始化完成后),trading状态才会变为true。
- 可以去engine.py看一下load_bar函数。默认use_database为false,会先去接口拿数据,没有的话会去rqdata找,最后才会去database。
如果数据库中只有两天的数据,load_bar(10) 会不会出问题?
关于这个问题,可以看看这篇帖子:https://www.vnpy.com/forum/topic/4890-fen-xi-yi-xia-pan-zhong-qi-dong-ctace-lue-dai-lai-de-di-yi-gen-he-cheng-kxian-cuo-wu
cczhu wrote:
这个只是当前界面运行中的交易可以显示, 关闭后, 再次打开, 历史委托的reference没法显示了吧,因为没法保存啊
建议:
想办法把包含reference的order和trade保存起来,再次启动vnpy的时候把历史order和trade从文件读取,并且恢复到oms的orders,trades字典里就OK了。
kingmo888 wrote:
直接基于portfolio_manager改造吧,这个是多品种的,构造了指数后从这里多品种来做。
谢谢,一直没有关注portfolio_strategy,原来是这样的,不错!
kingmo888 wrote:
期权合约数现在是个天量啊。tdapi的回调函数又必须刷新合约,没招。
不过我好奇的是楼主在测试2、3这二者的差异,盲猜这难道就是py和c++的效率差别?
不是,是2楼管理员的回答就是答案。
因为使用SimNow的CTP接口连接的时候,在CTP接口初始化的时候,推送的只有期货合约的信息,不含相关期权合约的信息。如果你连接和实际在期货公司的CTP生成接口的时候,在CTP接口初始化的时候,推送的不光有期货合约的信息,还有相关期权合约的信息。而期权合约的数量特别多,
例如一个PTA2101合约,它的期货合约1条就推送完了,而与PTA2101相关的期权合约多达50个,其中包含25个看涨合约和25个看跌合约,每个都要推送到客户端。
所以初始化过程就由原来SimNow的CTP接口连接的3~5秒,猛增到实际在期货公司的CTP生成接口的17到32秒!
这不是vnpy的问题,另外vnpy的CTP接口库也是用C++写成的。
class CtaTemplate(ABC):
... ...
def __init__(
self,
cta_engine: Any,
strategy_name: str,
vt_symbol: str, # 合约代码
setting: dict,
):
用户策略启动后,CTA策略引擎帮助订阅代码为vt_symbol合约的行情,用户策略收到tick推送之后,合成1分钟bar、N分钟bar乃至小时日线的bar。
策略在on_xmin_bar()函数中实现交易信号的计算并且完成交易逻辑。
我们可以知道,策略使用vt_symbol合约的行情指导了对vt_symbol合约的交易。
交易合约是指CTA策略要交易的合约,目前CTA策略里的合约参数就是交易合约,如果是期货的话,我们一般都选择主力合约来交易。
指标合约是指CTA策略用来进行各种指标计算的合约,它可以和要交易的合约相同,也可以不同。可以是交易合约所在品种或者板块的指数,也可以是交易合约所在品种的指数或者主连合约,也可以选择如rqdata中的经过主力合约如rb888,rb999之类的主连合约,这样合约是通过行主力合约间的升水和贴水的方式得到的,没有主连合约那样的在主力合约去换时产生的巨大跳空,更加合理。
要做到这一点,需要修改的类包括:
对send_order等需要需要区分对策略的交易合约发送委托单,
策略初始化时需要同时订阅指标合约和交易合约的行情。
加指标合约参数vt_symbol1,
指标计算时时有指标合约的行情数据进行进行
交易时使用交易合约进行交易
使得在CTA策略在创建时可以输入指标合约
在CTP接口的交易接口的SPI中,有OnRtnOrder和onRtnTrade两个数据接口:
struct CThostFtdcOrderField
{
///经纪公司代码
TThostFtdcBrokerIDType BrokerID;
///投资者代码
TThostFtdcInvestorIDType InvestorID;
///合约代码
TThostFtdcInstrumentIDType InstrumentID;
///报单引用
TThostFtdcOrderRefType OrderRef;
///用户代码
TThostFtdcUserIDType UserID;
///报单价格条件
TThostFtdcOrderPriceTypeType OrderPriceType;
///买卖方向
TThostFtdcDirectionType Direction;
///组合开平标志
TThostFtdcCombOffsetFlagType CombOffsetFlag;
///组合投机套保标志
TThostFtdcCombHedgeFlagType CombHedgeFlag;
///价格
TThostFtdcPriceType LimitPrice;
///数量
TThostFtdcVolumeType VolumeTotalOriginal;
///有效期类型
TThostFtdcTimeConditionType TimeCondition;
///GTD日期
TThostFtdcDateType GTDDate;
///成交量类型
TThostFtdcVolumeConditionType VolumeCondition;
///最小成交量
TThostFtdcVolumeType MinVolume;
///触发条件
TThostFtdcContingentConditionType ContingentCondition;
///止损价
TThostFtdcPriceType StopPrice;
///强平原因
TThostFtdcForceCloseReasonType ForceCloseReason;
///自动挂起标志
TThostFtdcBoolType IsAutoSuspend;
///业务单元
TThostFtdcBusinessUnitType BusinessUnit;
///请求编号
TThostFtdcRequestIDType RequestID;
///本地报单编号
TThostFtdcOrderLocalIDType OrderLocalID;
///交易所代码
TThostFtdcExchangeIDType ExchangeID;
///会员代码
TThostFtdcParticipantIDType ParticipantID;
///客户代码
TThostFtdcClientIDType ClientID;
///合约在交易所的代码
TThostFtdcExchangeInstIDType ExchangeInstID;
///交易所交易员代码
TThostFtdcTraderIDType TraderID;
///安装编号
TThostFtdcInstallIDType InstallID;
///报单提交状态
TThostFtdcOrderSubmitStatusType OrderSubmitStatus;
///报单提示序号
TThostFtdcSequenceNoType NotifySequence;
///交易日
TThostFtdcDateType TradingDay;
///结算编号
TThostFtdcSettlementIDType SettlementID;
///报单编号
TThostFtdcOrderSysIDType OrderSysID;
///报单来源
TThostFtdcOrderSourceType OrderSource;
///报单状态
TThostFtdcOrderStatusType OrderStatus;
///报单类型
TThostFtdcOrderTypeType OrderType;
///今成交数量
TThostFtdcVolumeType VolumeTraded;
///剩余数量
TThostFtdcVolumeType VolumeTotal;
///报单日期
TThostFtdcDateType InsertDate;
///委托时间
TThostFtdcTimeType InsertTime;
///激活时间
TThostFtdcTimeType ActiveTime;
///挂起时间
TThostFtdcTimeType SuspendTime;
///最后修改时间
TThostFtdcTimeType UpdateTime;
///撤销时间
TThostFtdcTimeType CancelTime;
///最后修改交易所交易员代码
TThostFtdcTraderIDType ActiveTraderID;
///结算会员编号
TThostFtdcParticipantIDType ClearingPartID;
///序号
TThostFtdcSequenceNoType SequenceNo;
///前置编号
TThostFtdcFrontIDType FrontID;
///会话编号
TThostFtdcSessionIDType SessionID;
///用户端产品信息
TThostFtdcProductInfoType UserProductInfo;
///状态信息
TThostFtdcErrorMsgType StatusMsg;
///用户强评标志
TThostFtdcBoolType UserForceClose;
///操作用户代码
TThostFtdcUserIDType ActiveUserID;
///经纪公司报单编号
TThostFtdcSequenceNoType BrokerOrderSeq;
///相关报单
TThostFtdcOrderSysIDType RelativeOrderSysID;
///郑商所成交数量
TThostFtdcVolumeType ZCETotalTradedVolume;
///互换单标志
TThostFtdcBoolType IsSwapOrder;
///营业部编号
TThostFtdcBranchIDType BranchID;
///投资单元代码
TThostFtdcInvestUnitIDType InvestUnitID;
///资金账号
TThostFtdcAccountIDType AccountID;
///币种代码
TThostFtdcCurrencyIDType CurrencyID;
///IP地址
TThostFtdcIPAddressType IPAddress;
///Mac地址
TThostFtdcMacAddressType MacAddress;
};
struct CThostFtdcTradeField
{
///经纪公司代码
TThostFtdcBrokerIDType BrokerID;
///投资者代码
TThostFtdcInvestorIDType InvestorID;
///合约代码
TThostFtdcInstrumentIDType InstrumentID;
///报单引用
TThostFtdcOrderRefType OrderRef;
///用户代码
TThostFtdcUserIDType UserID;
///交易所代码
TThostFtdcExchangeIDType ExchangeID;
///成交编号
TThostFtdcTradeIDType TradeID;
///买卖方向
TThostFtdcDirectionType Direction;
///报单编号
TThostFtdcOrderSysIDType OrderSysID;
///会员代码
TThostFtdcParticipantIDType ParticipantID;
///客户代码
TThostFtdcClientIDType ClientID;
///交易角色
TThostFtdcTradingRoleType TradingRole;
///合约在交易所的代码
TThostFtdcExchangeInstIDType ExchangeInstID;
///开平标志
TThostFtdcOffsetFlagType OffsetFlag;
///投机套保标志
TThostFtdcHedgeFlagType HedgeFlag;
///价格
TThostFtdcPriceType Price;
///数量
TThostFtdcVolumeType Volume;
///成交时期
TThostFtdcDateType TradeDate;
///成交时间
TThostFtdcTimeType TradeTime;
///成交类型
TThostFtdcTradeTypeType TradeType;
///成交价来源
TThostFtdcPriceSourceType PriceSource;
///交易所交易员代码
TThostFtdcTraderIDType TraderID;
///本地报单编号
TThostFtdcOrderLocalIDType OrderLocalID;
///结算会员编号
TThostFtdcParticipantIDType ClearingPartID;
///业务单元
TThostFtdcBusinessUnitType BusinessUnit;
///序号
TThostFtdcSequenceNoType SequenceNo;
///交易日
TThostFtdcDateType TradingDay;
///结算编号
TThostFtdcSettlementIDType SettlementID;
///经纪公司报单编号
TThostFtdcSequenceNoType BrokerOrderSeq;
///成交来源
TThostFtdcTradeSourceType TradeSource;
///投资单元代码
TThostFtdcInvestUnitIDType InvestUnitID;
};
CThostFtdcOrderField中的有InsertDate(报单日期)字段和TradingDay(交易日),可是中信建投期货把InsertDate填入交易日,而不是委托单报单之时的日期。
CThostFtdcTradeField中的有TradeDate(成交日期)字段和TradingDay(交易日),可是中信建投期货把TradeDate填入交易日,而不是成交单成交之时的日期。
中信建投期货推荐的软件有数据客户端“金建投”和“快期V2”。
本人使用vnpy进行交易,分别使用金建投和快期V2,登录后看到的持仓信息,同一时间、同一品种、看到的持仓均价和浮动盈亏是不一样的,表现为:
1 金建投软件显示的持仓均价和浮动盈亏是对的
2 快期V2软件显示的持仓均价和浮动盈亏是错误
3 vnpy软件显示的持仓均价和浮动盈亏是错误,而且与快期V2显示结果相同
调试发现,a2101合约,只要是在21:00之后的夜盘交易的记录,委托单的InsertDate和成交单中的TradeDate,均被加上1日或者3日。
现在经过4天左右与中信建投技术人员的交流,他们拒绝承认自己的委托单的InsertDate和成交单中的TradeDate字段错了。
我把从CTP接收到的OrderData和TradeData数据打印给他们,中信建投技术人员说这是第三方表达,不认可vnpy。并且说InsertDate和TradeDate在夜盘的时候就应该是交易日,应该+1或者+3。
现在问题一直没有得到解决。
请问是快期v2和vnpy在CTP接口处理错误了吗,还是中信建投搞错了?
已经开盘了就不要从CTP接口获取主力合约的的开盘价,从米筐接口get_price1分钟的就可以啦,夜盘是日内的第一个bar的open_price,白盘9:00的那一个bar的,无需订阅,简单。
正确的步骤:
0、赋值ctp接口的设置:
ctp_setting = {
"用户名": "xxxxx",
"密码": "*****",
"经纪商代码": "jjjjj",
"交易服务器": "ip:port",
"行情服务器": "ip:port",
"产品名称": "name",
"授权编码": "auth_code",
"产品信息": ""
}
1、创建EventEngine类型的消息引擎event_engine
2、创建MainEngine类型的主引擎main_engine = MainEngine(event_engine)
3、main_engine.add_gateway(CtpGateway)
4、main_engine.connect(ctp_setting, "CTP")
5、创建ScriptEngine类型script_engine = ScriptEngine(main_engine,event_engine)
6、run(script_engine)
ahren wrote:
借鉴您的方法,直接从rqdata抓取主力合约列表以及相关open,close,high等数据,现在要实现高低开提示,需要获取当日open价格,好像rqdata get_price 是获取历史价格,那么怎么获取所有主力合约当日开盘价呢?比如今天是周六,get_latest_trading_date,在通过get_price对于有夜盘的品种无法获取到周五夜盘开盘价格
rqdata的主力合约列表是根据历史日行情比较后得到的,当日行情没有接受是无法得到的,不存在你所说的取主力合约当日open价格的问题。而且在一个月中一个品种的某个合约一旦成为主力合约,即使其后有段时间交易金额或者持仓量不再是最大,也不一定会不再是主力合约了,它会有一定的连续性。具体的可以见米筐的接口文档。
不同的软件或机构对主力合约的选择和延续规则可能不一样,例如文华的主力合约定义规则和米筐的可能是不一样的。但是大致是差不多的。他们的目的就是找到市场中参与方最多的、流动性最好的交易合约。
ahren wrote:
第一步骤,主要函数实现,放在那个文件夹下?
- 第一步骤的主要函数实现可以放在你认为合适的文件夹下,如:vnpy\usertools\myutility.py中
- 在你需要调用这些函数的文件的开头这样引入myutility.py的函数:
from vnpy.usertools.myutility import get_contract_kinds,get_all_dominants
- 然后参照步骤二来使用get_contract_kinds(),get_all_dominants()函数,来获取当前市场正在交易的品种和这些品种中的主力合约。我这里是把它们print了一下,你怎么使用就是另外一回事了。