[Add]增加计算盈亏时、以及计算海龟组合委托数量时,对合约乘数的计算

This commit is contained in:
vn.py 2018-11-11 14:51:46 +08:00
parent 30ab66928b
commit 7071af22c2
2 changed files with 51 additions and 17 deletions

View File

@ -15,6 +15,13 @@ from turtleStrategy import TurtlePortfolio
DAILY_DB_NAME = 'VnTrader_Daily_Db'
SIZE_DICT = {}
PRICETICK_DICT = {}
VARIABLE_COMMISSION_DICT = {}
FIXED_COMMISSION_DICT = {}
SLIPPAGE_DICT = {}
########################################################################
class BacktestingEngine(object):
@ -50,20 +57,21 @@ class BacktestingEngine(object):
self.endDt = endDt
#----------------------------------------------------------------------
def initPortfolio(self, filename):
def initPortfolio(self, filename, portfolioValue=10000000):
""""""
with open(filename) as f:
r = DictReader(f)
for d in r:
self.vtSymbolList.append(d['vtSymbol'])
self.sizeDict[d['vtSymbol']] = int(d['size'])
self.priceTickDict[d['priceTick']] = float(d['priceTick'])
self.variableCommissionDict[d['vtSymbol']] = float(d['variableCommission'])
self.fixedCommissionDict[d['vtSymbol']] = float(d['fixedCommission'])
self.slippageDict[d['vtSymbol']] = float(d['slippage'])
SIZE_DICT[d['vtSymbol']] = int(d['size'])
PRICETICK_DICT[d['vtSymbol']] = float(d['priceTick'])
VARIABLE_COMMISSION_DICT[d['vtSymbol']] = float(d['variableCommission'])
FIXED_COMMISSION_DICT[d['vtSymbol']] = float(d['fixedCommission'])
SLIPPAGE_DICT[d['vtSymbol']] = float(d['slippage'])
self.portfolio = TurtlePortfolio(self)
self.portfolio.init(self.vtSymbolList)
self.portfolio.init(portfolioValue, self.vtSymbolList, SIZE_DICT)
#----------------------------------------------------------------------
def loadData(self):
@ -117,6 +125,11 @@ class BacktestingEngine(object):
#----------------------------------------------------------------------
def sendOrder(self, vtSymbol, direction, offset, price, volume):
""""""
# 对价格四舍五入
priceTick = PRICETICK_DICT[vtSymbol]
price = int(round(price/priceTick, 0)) * priceTick
# 记录成交数据
trade = TradeData(vtSymbol, direction, offset, price, volume)
l = self.tradeDict.setdefault(self.currentDt, [])
l.append(trade)
@ -188,13 +201,14 @@ class DailyResult(object):
"""计算当日交易盈亏"""
for vtSymbol, l in self.tradeDict.items():
close = self.closeDict[vtSymbol]
size = SIZE_DICT[vtSymbol]
for trade in l:
if trade.direction == DIRECTION_LONG:
side = 1
else:
side = -1
pnl = (close - trade.price) * trade.volume * side
pnl = (close - trade.price) * trade.volume * side * size
self.tradingPnl += pnl
#----------------------------------------------------------------------
@ -203,7 +217,9 @@ class DailyResult(object):
for vtSymbol, pos in self.posDict.items():
previousClose = self.previousCloseDict.get(vtSymbol, 0)
close = self.closeDict[vtSymbol]
pnl = (close - previousClose) * pos
size = SIZE_DICT[vtSymbol]
pnl = (close - previousClose) * pos * size
self.holdingPnl += pnl
#----------------------------------------------------------------------

View File

@ -267,15 +267,23 @@ class TurtlePortfolio(object):
self.signalDict = defaultdict(list)
self.posDict = {} # 每个品种的持仓情况
self.totalLong = 0 # 总的多头持仓
self.totalShort = 0 # 总的空头持仓
self.posDict = {} # 每个品种的持仓情况
self.totalLong = 0 # 总的多头持仓
self.totalShort = 0 # 总的空头持仓
self.tradingDict = {} # 交易中的信号字典
self.tradingDict = {} # 交易中的信号字典
self.sizeDict = {} # 合约大小字典
self.unitDict = {} # 按照波动幅度计算的委托量单位字典
self.portfolioValue = 0 # 组合市值
#----------------------------------------------------------------------
def init(self, vtSymbolList):
def init(self, portfolioValue, vtSymbolList, sizeDict):
""""""
self.portfolioValue = portfolioValue
self.sizeDict = sizeDict
for vtSymbol in vtSymbolList:
signal1 = TurtleSignal(self, vtSymbol, 20, 10, 20, True)
signal2 = TurtleSignal(self, vtSymbol, 55, 20, 20, False)
@ -297,6 +305,16 @@ class TurtlePortfolio(object):
"""对交易信号进行过滤,符合条件的才发单执行"""
pos = self.posDict[signal.vtSymbol]
# 如果当前无仓位,则重新根据波动幅度计算委托量单位
if not pos:
size = self.sizeDict[signal.vtSymbol]
riskValue = self.portfolioValue * 0.01
unit = riskValue / (signal.atrVolatility * size)
unit = int(round(unit, 0))
self.unitDict[signal.vtSymbol] = unit
else:
unit = self.unitDict[signal.vtSymbol]
# 开仓
if offset == OFFSET_OPEN:
# 检查上一次是否为盈利
@ -348,10 +366,10 @@ class TurtlePortfolio(object):
else:
self.tradingDict.pop(signal.vtSymbol)
self.sendOrder(signal.vtSymbol, direction, offset, price, volume)
self.sendOrder(signal.vtSymbol, direction, offset, price, volume, unit)
#----------------------------------------------------------------------
def sendOrder(self, vtSymbol, direction, offset, price, volume):
def sendOrder(self, vtSymbol, direction, offset, price, volume, unit):
""""""
# 计算合约持仓
if direction == DIRECTION_LONG:
@ -370,5 +388,5 @@ class TurtlePortfolio(object):
self.totalShort += pos
# 向回测引擎中发单记录
self.engine.sendOrder(vtSymbol, direction, offset, price, volume)
self.engine.sendOrder(vtSymbol, direction, offset, price, volume*unit)