From 7071af22c206d226aba6f9337bfe85673f37afd9 Mon Sep 17 00:00:00 2001 From: "vn.py" Date: Sun, 11 Nov 2018 14:51:46 +0800 Subject: [PATCH] =?UTF-8?q?[Add]=E5=A2=9E=E5=8A=A0=E8=AE=A1=E7=AE=97?= =?UTF-8?q?=E7=9B=88=E4=BA=8F=E6=97=B6=E3=80=81=E4=BB=A5=E5=8F=8A=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E6=B5=B7=E9=BE=9F=E7=BB=84=E5=90=88=E5=A7=94=E6=89=98?= =?UTF-8?q?=E6=95=B0=E9=87=8F=E6=97=B6=EF=BC=8C=E5=AF=B9=E5=90=88=E7=BA=A6?= =?UTF-8?q?=E4=B9=98=E6=95=B0=E7=9A=84=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/TurtleStrategy/turtleEngine.py | 34 +++++++++++++++++------ examples/TurtleStrategy/turtleStrategy.py | 34 +++++++++++++++++------ 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/examples/TurtleStrategy/turtleEngine.py b/examples/TurtleStrategy/turtleEngine.py index ff15d54b..3a87c400 100644 --- a/examples/TurtleStrategy/turtleEngine.py +++ b/examples/TurtleStrategy/turtleEngine.py @@ -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 #---------------------------------------------------------------------- diff --git a/examples/TurtleStrategy/turtleStrategy.py b/examples/TurtleStrategy/turtleStrategy.py index 0bbe14bd..09c274ce 100644 --- a/examples/TurtleStrategy/turtleStrategy.py +++ b/examples/TurtleStrategy/turtleStrategy.py @@ -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) \ No newline at end of file