目录:
一、数据定义stBase.py
二、价差引擎stEngine.py
三、价差算法stAlgo.py
四、界面定义uiStWidget.py
五、实盘配置ST_setting.json
六、价差交易界面
一、数据定义stBase.py
本文件中定义了价差模块用到的腿类、价差类及方法。
1、类StLeg定义:
以vtSymbol作为腿关键字,定义“实际交易时的比例”、“ 计算价差时的乘数”、“ 对冲时的超价tick”、以及腿的“买价”、“卖价”、 “买量”、 “卖量”;“多仓仓位”、“空仓仓位”、“净持仓”属性。
2、类StSpread定义:
价差名称name作为价差关键字,定义“代码(基于组成腿计算)”,“主动腿”、“被动腿列表”, “所有腿列表”; “价差买价”、 “价差卖价”、 “价差买量”、 “价差卖量”; “时间”; “多仓仓位”、 “空仓仓位”、 “净持仓”属性。
(1)函数initSpread初始化价差:调用函数addActiveLeg加载主动腿,调用函数addPassiveLeg加载被动腿列表;定义价差代码列表,生成“代码(基于组成腿计算)”;该函数在创建价差时调用。
(2)函数calculatePrice计算价差的价格、量:价差的所有腿的量都不为0,则根据腿的买价、卖价及multiplier(计算价差的乘数)计算价差的买价、卖价,multiplier有正负区分,主动腿是正数则被动腿是负数,则“价差 = 主动腿的价格 – 被动腿的价格”;价差的买量、卖量根据腿的量除以腿的ratio通过floor向下取整获得价差的买量、卖量,所有腿计算出价差的买量、卖量取最小值。
(3)函数calculatePos计算持仓:计算价差的持仓,价差的多仓与空仓根据腿的longPos多仓、shortPos空仓除以ratio通过floor向下取整获得;价差的多仓、空仓与腿的多仓、空仓取最小值;价差的净仓位 = 价差多仓 – 价差空仓。价差的多仓、空仓值在平仓时使用到,即只能平成交实际持有的仓位,不能多平。
(4)函数addActiveLeg:添加主动腿
(5)函数addPassiveLeg:添加被动腿
二、价差引擎stEngine.py
本文件中定义了价差模块的“价差数据计算引擎”、“ 价差算法交易引擎”和“价差引擎”三个引擎的属性及对应的全部函数。
1、类StDataEngine(object)价差数据计算引擎:
价差的配置文件是'ST_setting.json'。__init__中引用mainEngine、eventEngine对象;初始腿字典legDict、价差字典spreadDict、标的与价差字典vtSymbolSpreadDict;调用函数registerEvent注册事件。
(1)、函数loadSetting加载配置: 读取文件'ST_setting.json'中配置的价差数据,调用函数createSpread创建价差。
(2)、函数saveSetting保存配置: 保存价差数据到ST_setting.json中,不实现,自定义开发。
(3)、函数createSpread创建价差: 创建不重名的价差,如果ST_setting.json误配置了重名价差,则只会加载第一个,后续的被忽略,不加载。同一个标的vtSymbol只能存在于一个价差中,如果存在不同价差中,则只有第一个价差能被加载,后续的价差不会被加载。 创建主动腿、订阅主动腿;创建全部被动腿、订阅全部被动腿。价差创建成功后添加“发出价差行情更新事件”、“发出价差持仓事件”。
(4)、函数processTickEvent处理行情推送: 如果行情是需要处理的(tick.vtSymbol在腿的字典legDict中),则更新对应腿的买价、卖价、买量、卖量;调用价差对象的函数calculatePrice更新价差价格、发出价差的事件TickEvent。
(5)、函数putSpreadTickEvent发出价差行情更新事件: 根据函数processTickEvent中的vtSymbol的tick变化,调用该函数发出价差行情更新事件。
(6)、函数processTradeEvent处理成交推送: 如果成交的标的vtSymbol在腿字典legDict中,则根据vtSymbol的实际成交数量、成交方向计算腿的实际成交,更新腿持仓的longPos、shortPos和netPos;调用价差对象的函数spread.calculatePos更新价差持仓,推送价差持仓更新。
(7)、函数processPosEvent处理持仓推送: 如果成交的标的vtSymbol在腿字典legDict中,则根据vtSymbol的成交方向更新腿的longPos、shortPos、netPos;调用价差对象的函数spread.calculatePos更新价差持仓,推送价差持仓更新。
(8)、函数putSpreadPosEvent发出价差持仓事件: 在创建价差、价差成交及持仓变化时,调用该函数,发出价差持仓更新,更新界面的“价差持仓”的多仓、空仓、净持仓数据。
(9)、函数registerEvent注册事件: 注册EVENT_TICK、EVENT_TRADE、EVENT_POSITION三个事件,该函数在类StDataEngine的__init__中调用。
(10)、函数subscribeMarketData订阅行情: 获得标的vtSymbol的symbol和exchange后,调用主引擎mainEngine.subscribe函数根据合约对应的接口名称gatewayName向相应接口进行行情订阅。
(11)、函数writeLog发出日志: 在界面“日志信息”位置显示详细日志信息。
(12)、函数getAllSpreads获取所有的价差: 获取价差的详细信息列表,在算法类的函数loadSetting调用,获得价差详细信息列表进行价差的算法配置。
2、类StAlgoEngine(object) 价差算法交易引擎
价差算法的参数值保存在文件‘SpreadTradingAlgo.vt’中。__init__中引用dataEngine、mainEngine、eventEngine对象;初始算法字典algoDict、标的算法字典vtSymbolAlgoDict;调用registerEvent注册事件。
(1)、函数registerEvent注册事件监听: 注册EVENT_SPREADTRADING_TICK、EVENT_SPREADTRADING_POS、EVENT_TRADE、EVENT_ORDER、EVENT_TIMER事件,在类StAlgoEngine的__init__中调用。
(2)、函数processSpreadTickEvent处理价差行情事件: 如果价差的买价、卖价都是0,则直接返回。如果价格不是0,则根据价差名称在算法字典algoDict获得算法信息,调用算法对象algo的函数updateSpreadTick进行价差值比较(即比较当前价差的值与设定价差开平仓的值),符合相应交易条件,则进行买入、卖出,卖空、平空交易业务。
(3)、函数processSpreadPosEvent处理价差持仓事件: 根据价差名称在算法字典algoDict获得算法信息,调用算法对象algo的函数updateSpreadPos进行价差持仓更新,在类StDataEngine的函数processPosEvent中已经实现价差持仓更新,在函数内updateSpreadPos无需再做处理,自定义需求开发。
(4)、函数processTradeEvent处理成交事件: 根据成交的标的vtSymbol在标的与算法字典vtSymbolAlgoDict中找到对应的唯一算法,获得算法信息,调用算法对象algo的函数updateTrade进行订单成交更新处理,在类StDataEngine的函数processTradeEvent中已经实现价差成交更新,在函数内updateTrade无需再做处理,自定义需求开发。
(5)、函数processOrderEvent处理委托事件: 根据成交的标的vtSymbol在标的与算法字典vtSymbolAlgoDict中找到对应的唯一算法,获得算法信息,调用算法对象algo的函数updateOrder进行委托更新。
(6)、函数processTimerEvent处理计时事件: 计时更新,算法行的发单时间到撤单时间的间隔计时。
(7)、函数sendOrder发单: 根据传入的标的vtSymbol获得标的对应的symbol、交易所等信息;传入参数多空、开平、价格及成交数量确定成交时详细信息;固定PRICETYPE_LIMITPRICE限价开单;实际发单价格在传入的价格参数price上根据多空±(payup * contract.priceTick)的差作为实际发单价格;根据标的详细信息进行委托转换确定是否有平今、平昨和平仓惩罚费;如果发单请求在委托转换请求列表中,则循环进行调用mainEngine.sendOrder函数向合约对应接口发单,发单返回的订单编号vtOrderID增加到vtOrderIDList列表中并作为函数返回值。
(8)、函数cancelOrder撤单: 调用函数mainEngine.getOrder确定订单vtOrderID存在,则根据取得的订单信息symbol、exchange、frontID、sessionID、orderID等调用函数mainEngine.cancelOrder向该订单对应接口发送撤销订单。
(9)、函数buy买入、函数sell卖出、函数short卖空、函数cover平空: 这四个函数根据需求被类SniperAlgo的对象的函数“sendLegOrder发送每条腿的委托”调用,这四个函数再分别传多空、开平等参数给函数sendOrder进行发单。
(10)、函数putAlgoEvent发出算法状态更新事件: 算法的状态更新。
(11)、函数writeLog输出日志: 输出在本类中的对应日志信息并在界面的“算法信息”中显示。
(12)、函数saveSetting保存算法配置: 保存算法行的全部参数信息到数据文件'SpreadTradingAlgo.vt'中,文件路径. \vnpy-1.8.1\examples\VnTrader\temp,退出VnTrader时自动保存,但是如果不是通过关闭VnTrader正常退出,例如程序死掉或者通过关闭CMD窗口退出,则不会保存。
(13)、函数loadSetting加载算法配置: 创建算法对象并保存腿代码和算法对象的映射,加载算法行保存在文件'SpreadTradingAlgo.vt'中对应的全部参数信息,并在“价差算法”的表格中显示数据信息。该函数在类“StEngine价差引擎”的函数init中调用。
(14)、函数stopAll停止全部算法: 点击按钮“全部停止”后调用该函数停止全部算法。
(15)、函数startAlgo启动算法: 根据传入的参数spreadName价差名称,在algoDict算法字典中找到对应的算法algo,调用算法algo的函数start启动算法,函数返回算法行的状态。 界面操作:正确设置算法行的参数后,点击‘状态’栏的“已停止”按钮启动该算法行。
(16)、函数stopAlgo停止算法: 根据传入的参数spreadName价差名称,在algoDict算法字典中找到对应的算法algo,调用算法algo的函数stop停止算法,函数返回算法行的状态。 界面操作:点击‘状态’栏的“运行中”按钮停止该算法行。
(17)、函数getAllAlgoParams获取所有算法的参数: 获取所有算法的参数并返回参数列表。
(18)、函数setAlgoBuyPrice设置算法买开价格、setAlgoSellPrice设置算法卖平价格、setAlgoShortPrice设置算法卖开价格、setAlgoCoverPrice设置算法买平价格: 设置对应的算法的买开价格、卖平价格、卖开价格、买平价格,其中“买开价格 < 卖平价格”、“卖开价格 < 买平价格”;‘双向’交易的特殊限制条件“卖平价格 < 卖开价格”,正确设置价格后才能够启动该算法的行。
(19)、函数setAlgoMode设置算法工作模式: 设置算法的交易模式,是做多、做空还是多空都做。
(20)、函数setAlgoMaxOrderSize设置算法单笔委托限制: 算法单笔委托限制,在发出主动腿时计算成交量时从“当前买卖量”、“ 持仓限制 - 净持仓”、“单笔委托限制”中取最小值。
(21)、函数setAlgoMaxPosSize设置算法持仓限制: 算法的最大持仓限制,开仓时价差spread的‘净持仓netPos’要小于‘持仓限制maxPosSize’才开仓,否则不会开仓。
3、类StEngine(object) 价差引擎
__init__中引用mainEngine、eventEngine对象;创建类StDataEngine的对象dataEngine;创建类StAlgoEngine的对象algoEngine。
(1)、函数init初始化: 加载价差对象dataEngine的参数设置;加载价差算法对象algoEngine的参数设置。
(2)、函数stop引擎停止: 在退出主程序时停止价差引擎,保存价差对象dataEngine的参数设置;停止所有算法;保存价差算法对象algoEngine的参数设置。
三、价差算法stAlgo.py
本文件中定义了价差模块的“价差算法交易模板”、“ 狙击算法(市价委托)”两个类的属性及对应的全部函数。
1、类StAlgoTemplate (object) 价差算法交易模板:
__init__中引用算法引擎对象algoEngine、价差对象spread;初始化价差名称spreadName、算法名称algoName、工作状态active、工作模式mode;buyPrice、sellPrice、shortPrice、coverPrice四个算法价格;最大单边持仓量maxPosSize、最大单笔委托量maxOrderSize;
(1)、函数updateSpreadTick价差行情更新、updateSpreadPos价差持仓更新、updateTrade成交更新、updateOrder委托更新、updateTimer计时更新、start启动、stop停止: 以上函数模板中不实现,在算法中实现。
(2)、函数setBuyPrice设置买开的价格、setSellPrice设置卖平的价格、setShortPrice设置卖开的价格、setCoverPrice设置买平的价格、setMode设置算法交易方向、setMaxOrderSize设置最大单笔委托数量、setMaxPosSize设置最大持仓数量: 以上函数设置算法对应的全部参数的值。
(3)、函数putEvent发出算法更新事件: 调用函数algoEngine.putAlgoEvent发出算法更新事件。
(4)、函数writeLog输出算法日志: 调用函数algoEngine.writeLog在界面“算法信息”位置输出算法的日志信息。
(5)、函数getAlgoParams获取算法参数: 获取算法的价差名称、算法名称、买开价格、卖平价格、卖开价格、买平价格,最大单笔委托数量、最大持仓数量、模式的数据,函数返回获得算法全部数据的字典。该函数在类StAlgoEngine的函数saveSetting和getAllAlgoParams中被调用。
(6)、函数setAlgoParams设置算法参数: 设置算法的参数买开价格、卖平价格、卖开价格、买平价格,最大单笔委托数量、最大持仓数量、模式的数据。该函数在类StAlgoEngine的函数loadSetting中被调用,将读取到的价差算法的参数通过该函数获取,为显示在界面“价差算法”使用。
2、类SniperAlgo(StAlgoTemplate) 狙击算法(市价委托):
__init__中定义算法名称、主动腿报价撤单再发前等待的时间、主动腿报价计数、对冲腿对冲撤单再发前的等待时间、被动腿对冲计数;初始化主动腿代码、被动腿代码列表;定义缓存每条腿对象的字典legDict,并加载主动腿数据,通过价差对冲腿列表spread.passiveLegs加载被动腿腿数据;被动腿需要对冲的数量字典hedgingTaskDict、腿订单字典legOrderDict、订单成交字典orderTradedDict;
(1)、函数updateSpreadTick价差行情更新: 该函数在类StAlgoEngine的函数processSpreadTickEvent处理价差行情事件中被调用。 若算法没有启动则直接返回,若当前已有主动腿委托则直接返回不重复进行委托。 算法行允许双向交易、做多交易:
买入:如果“价差的netPos大于等于0” 并且 “netPos 小于最大持仓数量” 并且 “价差的买价askPrice小于等于价差的BuyPrice”,则符合买入开仓条件,调用函数quoteActiveLeg发出主动腿买入开仓。
卖出:如果“价差的netPos大于0” 并且 “价差的卖价bidPrice大于等于价差的SellPrice”,则符合卖出平仓条件,调用函数quoteActiveLeg发出主动腿卖出平仓。 算法行允许双向交易、做空交易:
卖空:如果“价差的netPos小于等于0” 并且 “netPos 大于负的最大持仓数量” 并且 “价差的卖价bidPrice大于等于价差的ShortPrice”,则符合卖出开仓条件,调用函数quoteActiveLeg发出主动腿卖出开仓。
平空:如果“价差的netPos小于0” 并且 “价差的买价askPrice小于等于价差的CoverPrice”,则符合买入平仓条件,调用函数quoteActiveLeg发出主动腿买入平仓。
(2)、函数updateSpreadPos价差持仓更新: 该函数在类StAlgoEngine的函数processSpreadPosEvent处理价差持仓事件中被调用。 自定义开发。
(3)、函数updateTrade成交更新: 该函数在类StAlgoEngine的函数processTradeEvent处理成交事件中被调用。 自定义开发。
(4)、函数updateOrder委托更新: 该函数在类StAlgoEngine的函数processOrderEvent处理委托事件 中被调用。 根据订单返回订单编号、成交量信息,价差是否有新的成交,如果有新的成交,则缓存委托已经成交数量,计算本次成交数量,如果是主动腿,则调用函数newActiveLegTrade新的主动腿成交;如果是被动腿,则调用函数newPassiveLegTrade新的被动腿成交。
处理完成委托,如果订单状态是全部成交,则从委托列表中移除该委托。检查若是被动腿,且已经没有未完成委托,则执行对冲,即如果被动腿有撤单等完成的未成交情况,则需要再次执行一次对冲,对冲数量从对冲任务字典hedgingTaskDict中获得。
(5)、函数updateTimer计时更新: 该函数在类StAlgoEngine的函数processTimerEvent计时更新事件中被调用。 主动腿quoteCount、被动腿hedgeCount的计时报价计数,主动腿quoteCount的计时到达报价间隔后,则对尚未成交的主动腿委托全部撤单,收到撤单回报后清空委托列表(函数updateOrder委托更新中判断如果是撤销或者拒单状态,则从委托列表中删除),则待下次价差更新再发单。
被动腿hedgeCount的计时到达对冲间隔后,则对尚未成交的全部被动腿委托全部撤单,收到撤单回报后清空委托列表(函数updateOrder委托更新中判断如果是撤销或者拒单状态,则从委托列表中删除),如果是被动腿重新再次执行对冲。
(6)、函数checkPrice检查价格: 做多检查:允许多头交易时BuyPrice必须小于SellPrice 做空检查:允许空头交易时ShortPrice必须大于CoverPrice 多空检查:允许双向交易时BuyPrice必须小于CoverPrice;允许双向交易时ShortPrice必须大于SellPrice 以上检查防止价差数值误设置错误导致交易亏损。
(7)、函数start启动: 启动算法并将主动腿quoteCount、被动腿hedgeCount置零,启动算法,同时发出算法启动日志。
(8)、函数stop停止: 如果算法是运行中,则清空腿任务字典hedgingTaskDict,撤销全部订单,停止算法,同时发出算法停止日志。
(9)、函数sendLegOrder发送每条腿的委托: 确定腿要成交的数量及腿的超价tick,如果腿量legVolume大于0(主动腿和被动腿使用legVolume的正负来判断对冲方向,如果是0则不会发送委托),使用腿的买价askPrice作为实际成交价格,如果腿的空仓持仓shortPos大于0,则买入平仓(平空),否则买入开仓(买入); 如果腿量legVolume小于 0,则使用腿的卖价bidPrice作为实际成交价格,如果腿的多仓持仓longPos大于0,则卖出平仓(卖出),否则卖出开仓(卖空)。成交返回的订单列表orderList保存到腿订单字典legOrderDict中。
(10)、函数quoteActiveLeg发出主动腿: 首先计算不带正负号的价差委托量spreadVolume,
买入:委托量在“当前买量askVolume”、“最大持仓减净持仓maxPosSize - spread.netPos”、“最大委托限制maxOrderSize”中取最小值。
平空:有价差空头持仓的情况下,则本次委托最多平完空头,委托量在价差委托量spreadVolume 和shortPos中取最小值。
卖空:委托量在“当前卖量bidVolume”、“最大持仓加净持仓maxPosSize + spread.netPos”、“最大委托限制maxOrderSize”中取最小值。
卖出:有价差多头持仓的情况下,则本次委托最多平完多头,委托量在价差委托量spreadVolume 和longPos中取最小值。 价差委托量spreadVolume加上价差方向(如果是空的方向,则添加负号),根据腿的比例ratio计算出腿的成交量legVolume(此时legVolume则带了方向,在函数sendLegOrder中使用),调用函数sendLegOrder发出新的主动腿狙击单。
(11)、函数hedgePassiveLeg被动腿对冲: 被动腿的vtSymbol如果在对冲任务字典hedgingTaskDict中,如果vtSymbol在腿订单字典legOrderDict中(说明已经发出对冲了),则返回。 根据vtSymbol从对冲任务字典hedgingTaskDict获得被动腿的对冲腿数量legVolume及从腿字典legDict中获得腿信息,调用函数sendLegOrder发出新的被动腿对冲单。
(12)、函数hedgeAllPassiveLegs执行所有被动腿对冲: 循环对冲任务字典hedgingTaskDict中所有被动腿,调用函数hedgePassiveLeg执行对冲。循环完成后,重置被动腿对冲撤单等待计数。
(13)、函数newActiveLegTrade新的主动腿成交: 新的主动腿成交后调用该函数,将主动腿成交带上方向,用来计算被动腿对冲使用。计算主动腿成交后,对应的价差仓位,四舍五入求主动腿成交量对应的价差份数。根据被动腿的比例ratio和主动腿的价差份数spreadVolume计算价差新仓位newHedgingTask(对应的被动腿需要对冲部分),更新对冲任务字典hedgingTaskDict中被动腿的对冲数量,发出全部被动腿对冲委托。
(14)、函数newPassiveLegTrade新的被动腿成交: 如果vtSymbol在对冲任务字典hedgingTaskDict中,计算完成的对冲数量,计算剩余尚未完成的数量,将该数量更新(hedgingTaskDict中vtSymbol对应的数量 – 该数量)到对冲任务字典hedgingTaskDict中。如果已全部完成,则从对冲任务字典hedgingTaskDict中移除该被动腿。
(15)、函数cancelLegOrder撤销某条腿的委托: 根据传入的标的vtSymbol,如果在腿订单字典legOrderDict中,则从字典中获得对应的订单号,如果订单号在订单列表中,则调用函数algoEngine.cancelOrder撤销该订单。
(16)、函数cancelAllOrders撤销全部委托: 循环腿订单字典legOrderDict,根据订单号调用函数algoEngine.cancelOrder撤销该订单。
(17)、函数cancelAllPassiveLegOrders撤销全部被动腿委托: 循环被动腿字典passiveVtSymbols,如果该腿在腿订单字典legOrderDict中,则调用函数cancelLegOrder撤销被动腿委托。确实发出了撤单委托,输出信息“被动腿全撤”。
四、界面定义uiStWidget.py
该文件中定义价差交易界面的全部类及对应的方法。
1、类StTickMonitor (BasicMonitor) 价差行情监控:
__init__中定义价差行情用到的列名称、数据键值使用价差名称;设置事件类型EVENT_SPREADTRADING_TICK,初始化表格及注册事件;
2、类StPosMonitor (BasicMonitor) 价差行情监控:
__init__中定义价差行情用到的列名称、数据键值使用价差名称;设置事件类型EVENT_SPREADTRADING_POS,初始化表格及注册事件;
3、类StLogMonitor (QtWidgets.QTextEdit) 价差行情监控:
__init__中引用对象eventEngine,注册事件;
(1)、函数processLogEvent处理日志事件: 输出日志对应的事件及内容,在价差日志监控中显示。
(2)、函数registerEvent注册事件监听: 注册槽事件processLogEvent,实现在界面上显示日志信息。
4、类StAlgoLogMonitor (BasicMonitor) 价差日志监控:
__init__中定义日志显示用到的列名称;设置事件类型EVENT_SPREADTRADING_ALGOLOG,初始化表格及注册事件;
5、类StBuyPriceSpinBox (QtWidgets.QDoubleSpinBox) BuyPrice定义:
__init__中引用对象algoEngine,定义价差名称变量,设置小数点精度及最小值、最大值范围,初始化valueChanged.connect方法。;
(1)、函数setPrice设置价格: 调用函数algoEngine.setAlgoBuyPrice设置算法行对应的该BuyPrice的价格。
(2)、函数algoActiveChanged算法运行状态改变: 只允许算法停止时修改价格,运行中时不能修改价格,灰色。 类StSellPriceSpinBox、StShortPriceSpinBox、StCoverPriceSpinBox同上。
6、类StMaxPosSizeSpinBox (QtWidgets.QSpinBox) 最大持仓上限:
__init__中引用对象algoEngine,定义价差名称变量,设置最小值、最大值范围,初始化valueChanged.connect方法。;
(1)、函数setSize设置价格: 调用函数algoEngine.setAlgoMaxPosSize设置算法行对应的该最大持仓上限的值。
(2)、函数algoActiveChanged算法运行状态改变: 只允许算法停止时修改值,运行中时不能修改值,灰色。 类StMaxOrderSizeSpinBox最大委托上限与该类相似。
7、类StModeComboBox (QtWidgets.QComboBox) 模式:
__init__中引用对象algoEngine,定义价差名称变量;初始化双向、做多、做空选项,默认双向,初始化currentIndexChanged.connect方法。;
(1)、函数setMode设置模式: 调用函数algoEngine.setAlgoMode设置算法行对应的模式。
(2)、函数algoActiveChanged算法运行状态改变: 只允许算法停止时修改值,运行中时不能修改值,灰色。
8、类StActiveButton(QtWidgets.QPushButton)状态:
__init__中引用对象algoEngine,定义价差名称变量;算法行默认初始已停止,初始化clicked.connect方法。;
(1)、函数buttonClicked改变运行模式: 调用函数stop、start设置算法行是“运行中”还是“已停止”。
(2)、函数stop停止: 调用函数algoEngine.stopAlgo获得算法的运行状态,如果是“运行中”则切换为“已停止”。
(3)、函数start启动: 调用函数algoEngine. startAlgo获得算法的运行状态,如果是“已停止”则切换为“运行中”。
(4)、函数setStarted算法启动: 算法启动,将按钮文字“已停止”修改为“运行中”,标记active为True。
(5)、函数setStopped算法停止: 算法启动,将按钮文字“运行中”修改为“已停止”,标记active为False。
9、类StAlgoManager (QtWidgets. QTableWidget) 价差算法管理组件:
__init__中引用对象algoEngine,定义按钮激活字典buttonActiveDict,初始化函数initUi调用。
(1)、函数initUi初始化表格: 初始化“价差算法”表格用到的全部列、及表格相应属性。
(2)、函数initCells初始化单元格: 调用函数algoEngine.getAllAlgoParams获得算法的全部参数值,初始化参数值。
(3)、函数stopAll停止所有算法: 循环按钮激活字典buttonActiveDict,调用函数stop停止所有算法。
10、类StGroup (QtWidgets. QTableWidget) 集合显示:
__init__中设置表格的Title和对象QtWidgets.QVBoxLayout()的创建及属性设置。
11、类StManager (QtWidgets. QWidget)价差管理:
__init__中引用对象stEngine、stEngine.mainEngine、eventEngine,调用函数initUi初始化界面。
(1)、函数initUi初始化界面: 创建组件及创建相应的按钮,创建集合及设置对应的布局。
(2)、函数show重载显示: 显示窗口并最大化。
(3)、函数init初始化: 调用函数stEngine.init()进行初始化,调用函数algoManager.initCells()进行初始化。
五、实盘配置ST_setting.json
价差交易模块的实盘配置文件,结构如下:
[ { "name": "m.09-12", "activeLeg": { "vtSymbol": "m1809", "ratio": 1, "multiplier": 1.0, "payup": 2 }, "passiveLegs": [ { "vtSymbol": "m1812", "ratio": -1, "multiplier": -1.0, "payup": 2 } ] }, { "name": "IF.09-12", "activeLeg": { "vtSymbol": "IF1809", "ratio": 1, "multiplier": 1.0, "payup": 2 }, "passiveLegs": [ { "vtSymbol": "IF1812", "ratio": -1, "multiplier": -1.0, "payup": 2 } ] } ]
"name"是价差名称,必须唯一,如果重复,则只能加载第一个;"vtSymbol"是合约在系统中的唯一代码,价差中不能有重复,即一个标的只能出现在一个价差中,不能多次出现,多次出现,只会加载这个标的的第一个价差,后续价差都不会再被加载。
主动腿字典"activeLeg"、被动腿列表字典"passiveLegs"的关键字说明: "vtSymbol": 合约在vt系统中的唯一代码,通常是 合约代码.交易所代码; "ratio":实际交易时的比例,主动腿一般是正数则被动腿是负数; "multiplier":主动腿计算价差时的乘数,主动腿一般是正数则被动腿是负数; "payup": 对冲时的超价tick,该数字乘以该标的的最小变动数,正整数;
六、价差交易界面
1、点击“初始化”按钮,加载价差算法对应的数据。
2、点击“全部停止”按钮,停止全部‘运行中’的价差算法。
3、价差交易操作时设定好对应的四个价格以及委托上限、持仓上限、模式,点击 “状态” 列的“已停止”按钮启动对应的算法行,即可进行自动开仓、平仓交易。
价差的买价、卖价与价差算法的四个价格关系如下:
卖价 ≤ BuyPrice:买入;
买价 ≥ SellPrice:卖出;
卖价 ≤ CoverPrice:平空;
买价 ≥ ShortPrice:卖空。