vn.py量化社区
By Traders, For Traders.
Administrator
avatar
加入于:
帖子: 197
声望: 30

作者:viponedream ;来源:维恩的派论坛
 
针对懒人,打算挂上去就不管它,让它自己运行,一个星期,一个月,甚至更久。
目前想到的就是几个地方要改一下,欢迎大家探讨怎样用vnpy来做隔夜。
 
 
一,定时连接CTP我采用的死方法。在uiMainWindow.py中的 updateStatusBar中,增加时间判断,到点了自动重连CTP。

# 计时器,
# 晚上21:00是夜盘时间,提前20分钟连接 CTP
dt = datetime.now()
if dt.hour == 20  or dt.hour == 8:
    if dt.minute == 40  and dt.second == 0:
        self.connectCtp()

 
 
二,历史持仓,即以前的老仓位。策略一开始要不要处理老仓位?目前是不管的,只管策略自己开的那些仓位。

这样中途停机造成问题。所以还是把老仓位一起赋给策略吧。

有人是把历史仓位存在一个文件中。我觉得没什么必要(不是单品种多策略的话)。

直接在策略中onPosition中读取历史持仓了。(要先在ctaEngine中增加一个处理函数,把onPosition推到相应的策略去)

 

def  onPosition(self, pos):
    # 更新仓位,把手动的开平仓同步更新到策略中。这样,就只能一个品种用一个策略了。
    # 有历史仓位则在策略开始时,把历史仓位赋给策略仓位。没有历史仓位则不必。

    if  self.isPrePosHaved  or self.isAlreadyTraded:         # 还没有开过仓,或,还没有获取历史仓位
        return
    elif pos.position != 0:
        if pos.direction == DIRECTION_LONG:
            self.pos = pos.position
        else:
            self.pos = -pos.position
        self.lastEntryPrice = pos.price
        self.isPrePosHaved = True

    print  (u'{0} {1}  历史持仓 {2}  开仓均价 {3}'.format(datetime.now(),  self.vtSymbol,  self.pos,  pos.price   ))
    pass

 
 

三,今仓,昨仓重置。

 

原来的系统是日内的,碰到换日就会出错。所以要重置一下。
这个要修改两个地方。
先在 CtpTdApi的 init 中加上

self.posBufferDict = {}             # 缓存持仓数据的字典
self.symbolExchangeDict = {}        # 保存合约代码和交易所的印射关系
self.symbolSizeDict = {}            # 保存合约代码和合约大小的印射关系
# 加上下面这一行
self.posBufferDictShfe = {}         # 缓存SHFE持仓数据的字典1,是在CTPGATEWAY.PY 修改这个回调。
def onRspQryInvestorPosition(self, data, error, n, last):
    """持仓查询回报"""
#print   datetime.now(),u'持仓回报', data
    # 更新持仓缓存,并获取VT系统中持仓对象的返回值
    exchange = self.symbolExchangeDict.get(data['InstrumentID'], EXCHANGE_UNKNOWN)
    size = self.symbolSizeDict.get(data['InstrumentID'], 1)

    # 获取缓存字典中的持仓缓存,若无则创建并初始化
    positionName = '.'.join([data['InstrumentID'], data['PosiDirection']])

    if exchange == EXCHANGE_SHFE:               #上期所的专门一个 dict
        if positionName in self.posBufferDictShfe:
            posBuffer = self.posBufferDictShfe[positionName]
        else:
            posBuffer = PositionBuffer(data, self.gatewayName)
            self.posBufferDictShfe[positionName] = posBuffer
    else:                                       # 其它交易所
        if positionName in self.posBufferDict:
            posBuffer = self.posBufferDict[positionName]
        else:
            posBuffer = PositionBuffer(data, self.gatewayName)
            self.posBufferDict[positionName] = posBuffer

    # 缓存持仓信息
    if exchange == EXCHANGE_SHFE:
        posBuffer.updateShfeBuffer(data, size)  # 不必 return
        if last:        # 上期所的只有最后一个才全部返回持仓信息
            for positionName in self.posBufferDictShfe:
                pos = self.posBufferDictShfe[positionName].pos
                self.gateway.onPosition(pos)
            self.posBufferDictShfe = {}      # 返回后就重置

    else:           # 其它交易所直接返回
        pos = posBuffer.updateBuffer(data, size)
        self.gateway.onPosition(pos)

 
2,在ctaEngine
增加两个事件处理函数
 

#----------------------------------------------------------------------
def registerEvent(self):
    # 加上以下两个
    self.eventEngine.register(EVENT_POSITION, self.processExchangePositionEvent)
    self.eventEngine.register(EVENT_TIMER, self.onTimer)

    def onTimer(self, event):
        dt = datetime.now()
        if dt.hour == 21 and dt.minute==0  and dt.second==1:       # 夜盘开盘第一时间重置
            self.posBufferDict = {}         # 清空则默认使用平昨

        if self.tickStrategyDict:
            for key in self.tickStrategyDict:
                for strategy in self.tickStrategyDict[key]:
                    strategy.onTimer()
        pass

    def processExchangePositionEvent(self, event):
        pos = event.dict_['data']
        if pos.vtSymbol in self.tickStrategyDict:
            for strategy in self.tickStrategyDict[pos.vtSymbol]:
                if pos.direction == DIRECTION_LONG:
                    strategy.exchangePos = pos.position
                else:
                    strategy.exchangePos = -pos.position
                strategy.onPosition(pos)

 
以上修改,策略已经可以连续跑起来了。强调的是:一个品种只能一个策略,并且只能单方向,不能同时有多和有空。# 涉及到的变量,自己加的。
self.isPrePosHaved self.isAlreadyTraded 自己加在策略上或者ctaTemplate都行。
onTimer()也自己加上的。

Member
avatar
加入于:
帖子: 6
声望: 0

mark

© 2015-2019 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号-3