[Add]增加计算盈亏时、以及计算海龟组合委托数量时,对合约乘数的计算
This commit is contained in:
parent
30ab66928b
commit
7071af22c2
@ -15,6 +15,13 @@ from turtleStrategy import TurtlePortfolio
|
|||||||
DAILY_DB_NAME = 'VnTrader_Daily_Db'
|
DAILY_DB_NAME = 'VnTrader_Daily_Db'
|
||||||
|
|
||||||
|
|
||||||
|
SIZE_DICT = {}
|
||||||
|
PRICETICK_DICT = {}
|
||||||
|
VARIABLE_COMMISSION_DICT = {}
|
||||||
|
FIXED_COMMISSION_DICT = {}
|
||||||
|
SLIPPAGE_DICT = {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
class BacktestingEngine(object):
|
class BacktestingEngine(object):
|
||||||
@ -50,20 +57,21 @@ class BacktestingEngine(object):
|
|||||||
self.endDt = endDt
|
self.endDt = endDt
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def initPortfolio(self, filename):
|
def initPortfolio(self, filename, portfolioValue=10000000):
|
||||||
""""""
|
""""""
|
||||||
with open(filename) as f:
|
with open(filename) as f:
|
||||||
r = DictReader(f)
|
r = DictReader(f)
|
||||||
for d in r:
|
for d in r:
|
||||||
self.vtSymbolList.append(d['vtSymbol'])
|
self.vtSymbolList.append(d['vtSymbol'])
|
||||||
self.sizeDict[d['vtSymbol']] = int(d['size'])
|
|
||||||
self.priceTickDict[d['priceTick']] = float(d['priceTick'])
|
SIZE_DICT[d['vtSymbol']] = int(d['size'])
|
||||||
self.variableCommissionDict[d['vtSymbol']] = float(d['variableCommission'])
|
PRICETICK_DICT[d['vtSymbol']] = float(d['priceTick'])
|
||||||
self.fixedCommissionDict[d['vtSymbol']] = float(d['fixedCommission'])
|
VARIABLE_COMMISSION_DICT[d['vtSymbol']] = float(d['variableCommission'])
|
||||||
self.slippageDict[d['vtSymbol']] = float(d['slippage'])
|
FIXED_COMMISSION_DICT[d['vtSymbol']] = float(d['fixedCommission'])
|
||||||
|
SLIPPAGE_DICT[d['vtSymbol']] = float(d['slippage'])
|
||||||
|
|
||||||
self.portfolio = TurtlePortfolio(self)
|
self.portfolio = TurtlePortfolio(self)
|
||||||
self.portfolio.init(self.vtSymbolList)
|
self.portfolio.init(portfolioValue, self.vtSymbolList, SIZE_DICT)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def loadData(self):
|
def loadData(self):
|
||||||
@ -117,6 +125,11 @@ class BacktestingEngine(object):
|
|||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def sendOrder(self, vtSymbol, direction, offset, price, volume):
|
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)
|
trade = TradeData(vtSymbol, direction, offset, price, volume)
|
||||||
l = self.tradeDict.setdefault(self.currentDt, [])
|
l = self.tradeDict.setdefault(self.currentDt, [])
|
||||||
l.append(trade)
|
l.append(trade)
|
||||||
@ -188,13 +201,14 @@ class DailyResult(object):
|
|||||||
"""计算当日交易盈亏"""
|
"""计算当日交易盈亏"""
|
||||||
for vtSymbol, l in self.tradeDict.items():
|
for vtSymbol, l in self.tradeDict.items():
|
||||||
close = self.closeDict[vtSymbol]
|
close = self.closeDict[vtSymbol]
|
||||||
|
size = SIZE_DICT[vtSymbol]
|
||||||
|
|
||||||
for trade in l:
|
for trade in l:
|
||||||
if trade.direction == DIRECTION_LONG:
|
if trade.direction == DIRECTION_LONG:
|
||||||
side = 1
|
side = 1
|
||||||
else:
|
else:
|
||||||
side = -1
|
side = -1
|
||||||
pnl = (close - trade.price) * trade.volume * side
|
pnl = (close - trade.price) * trade.volume * side * size
|
||||||
self.tradingPnl += pnl
|
self.tradingPnl += pnl
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
@ -203,7 +217,9 @@ class DailyResult(object):
|
|||||||
for vtSymbol, pos in self.posDict.items():
|
for vtSymbol, pos in self.posDict.items():
|
||||||
previousClose = self.previousCloseDict.get(vtSymbol, 0)
|
previousClose = self.previousCloseDict.get(vtSymbol, 0)
|
||||||
close = self.closeDict[vtSymbol]
|
close = self.closeDict[vtSymbol]
|
||||||
pnl = (close - previousClose) * pos
|
size = SIZE_DICT[vtSymbol]
|
||||||
|
|
||||||
|
pnl = (close - previousClose) * pos * size
|
||||||
self.holdingPnl += pnl
|
self.holdingPnl += pnl
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
@ -267,15 +267,23 @@ class TurtlePortfolio(object):
|
|||||||
|
|
||||||
self.signalDict = defaultdict(list)
|
self.signalDict = defaultdict(list)
|
||||||
|
|
||||||
self.posDict = {} # 每个品种的持仓情况
|
self.posDict = {} # 每个品种的持仓情况
|
||||||
self.totalLong = 0 # 总的多头持仓
|
self.totalLong = 0 # 总的多头持仓
|
||||||
self.totalShort = 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:
|
for vtSymbol in vtSymbolList:
|
||||||
signal1 = TurtleSignal(self, vtSymbol, 20, 10, 20, True)
|
signal1 = TurtleSignal(self, vtSymbol, 20, 10, 20, True)
|
||||||
signal2 = TurtleSignal(self, vtSymbol, 55, 20, 20, False)
|
signal2 = TurtleSignal(self, vtSymbol, 55, 20, 20, False)
|
||||||
@ -297,6 +305,16 @@ class TurtlePortfolio(object):
|
|||||||
"""对交易信号进行过滤,符合条件的才发单执行"""
|
"""对交易信号进行过滤,符合条件的才发单执行"""
|
||||||
pos = self.posDict[signal.vtSymbol]
|
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:
|
if offset == OFFSET_OPEN:
|
||||||
# 检查上一次是否为盈利
|
# 检查上一次是否为盈利
|
||||||
@ -348,10 +366,10 @@ class TurtlePortfolio(object):
|
|||||||
else:
|
else:
|
||||||
self.tradingDict.pop(signal.vtSymbol)
|
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:
|
if direction == DIRECTION_LONG:
|
||||||
@ -370,5 +388,5 @@ class TurtlePortfolio(object):
|
|||||||
self.totalShort += pos
|
self.totalShort += pos
|
||||||
|
|
||||||
# 向回测引擎中发单记录
|
# 向回测引擎中发单记录
|
||||||
self.engine.sendOrder(vtSymbol, direction, offset, price, volume)
|
self.engine.sendOrder(vtSymbol, direction, offset, price, volume*unit)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user