diff --git a/vnpy/trader/vtEngine.py b/vnpy/trader/vtEngine.py index 58181d83..b3c0482e 100644 --- a/vnpy/trader/vtEngine.py +++ b/vnpy/trader/vtEngine.py @@ -1,5 +1,7 @@ # encoding: UTF-8 +from __future__ import division + import os import shelve import logging @@ -491,7 +493,8 @@ class DataEngine(object): if vtSymbol in self.detailDict: detail = self.detailDict[vtSymbol] else: - detail = PositionDetail(vtSymbol) + contract = self.getContract(vtSymbol) + detail = PositionDetail(vtSymbol, contract) self.detailDict[vtSymbol] = detail # 设置持仓细节的委托转换模式 @@ -647,9 +650,19 @@ class PositionDetail(object): MODE_TDPENALTY = 'tdpenalty' # 平今惩罚 #---------------------------------------------------------------------- - def __init__(self, vtSymbol): + def __init__(self, vtSymbol, contract=None): """Constructor""" self.vtSymbol = vtSymbol + self.symbol = EMPTY_STRING + self.exchange = EMPTY_STRING + self.name = EMPTY_UNICODE + self.size = 1 + + if contract: + self.symbol = contract.symbol + self.exchange = contract.exchange + self.name = contract.name + self.size = contract.size self.longPos = EMPTY_INT self.longYd = EMPTY_INT @@ -657,6 +670,8 @@ class PositionDetail(object): self.longPosFrozen = EMPTY_INT self.longYdFrozen = EMPTY_INT self.longTdFrozen = EMPTY_INT + self.longPnl = EMPTY_FLOAT + self.longPrice = EMPTY_FLOAT self.shortPos = EMPTY_INT self.shortYd = EMPTY_INT @@ -664,6 +679,10 @@ class PositionDetail(object): self.shortPosFrozen = EMPTY_INT self.shortYdFrozen = EMPTY_INT self.shortTdFrozen = EMPTY_INT + self.shortPnl = EMPTY_FLOAT + self.shortPrice = EMPTY_FLOAT + + self.lastPrice = EMPTY_FLOAT self.mode = self.MODE_NORMAL self.exchange = EMPTY_STRING @@ -720,8 +739,10 @@ class PositionDetail(object): self.longYd += self.longTd self.longTd = 0 - # 汇总今昨 + # 汇总 + self.calculatePrice(trade) self.calculatePosition() + self.calculatePnl() #---------------------------------------------------------------------- def updateOrder(self, order): @@ -745,10 +766,14 @@ class PositionDetail(object): self.longPos = pos.position self.longYd = pos.ydPosition self.longTd = self.longPos - self.longYd + self.longPnl = pos.positionProfit + self.longPrice = pos.price elif pos.direction is DIRECTION_SHORT: self.shortPos = pos.position self.shortYd = pos.ydPosition self.shortTd = self.shortPos - self.shortYd + self.shortPnl = pos.positionProfit + self.shortPrice = pos.price #self.output() @@ -772,6 +797,34 @@ class PositionDetail(object): # 计算冻结量 self.calculateFrozen() + + #---------------------------------------------------------------------- + def updateTick(self, tick): + """行情更新""" + self.lastPrice = tick.lastPrice + self.calculatePnl() + + #---------------------------------------------------------------------- + def calculatePnl(self): + """计算持仓盈亏""" + self.longPnl = self.longPos * (self.lastPrice - self.longPrice) * self.size + self.shortPnl = self.shortPos * (self.shortPrice - self.lastPrice) * self.size + + #---------------------------------------------------------------------- + def calculatePrice(self, trade): + """计算持仓均价(基于成交数据)""" + # 只有开仓会影响持仓均价 + if trade.offset == OFFSET_OPEN: + if trade.direction == DIRECTION_LONG: + cost = self.longPrice * self.longPos + cost += trade.volume * trade.price + newPos = self.longPos + trade.volume + self.longPrice = cost / newPos + else: + cost = self.shortPrice * self.shortPos + cost += trade.volume * trade.price + newPos = self.shortPos + trade.volume + self.shortPrice = cost / newPos #---------------------------------------------------------------------- def calculatePosition(self):