增加实时结算2,支持对锁单。
This commit is contained in:
parent
e907dacaa1
commit
7792ef4ccf
@ -22,6 +22,7 @@ from eventEngine import *
|
|||||||
import MySQLdb
|
import MySQLdb
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import cPickle
|
import cPickle
|
||||||
import csv
|
import csv
|
||||||
import logging
|
import logging
|
||||||
@ -105,7 +106,9 @@ class BacktestingEngine(object):
|
|||||||
|
|
||||||
self.tradeCount = 0 # 成交编号
|
self.tradeCount = 0 # 成交编号
|
||||||
self.tradeDict = OrderedDict() # 成交字典
|
self.tradeDict = OrderedDict() # 成交字典
|
||||||
|
self.longPosition = [] # 多单持仓
|
||||||
|
self.shortPosition = [] # 空单持仓
|
||||||
|
|
||||||
self.logList = [] # 日志记录
|
self.logList = [] # 日志记录
|
||||||
|
|
||||||
# 当前最新数据,用于模拟成交用
|
# 当前最新数据,用于模拟成交用
|
||||||
@ -960,14 +963,17 @@ class BacktestingEngine(object):
|
|||||||
leg2_shortSymbol = leg2_shortSymbol.group(1)
|
leg2_shortSymbol = leg2_shortSymbol.group(1)
|
||||||
|
|
||||||
# E:\Ticks\ZJ\2015\201505\TF
|
# E:\Ticks\ZJ\2015\201505\TF
|
||||||
leg1File = u'{0}\\{1}\\{2}\\{3}\\{4}\\{5}.txt' \
|
leg1File = os.path.abspath(os.path.join(leg1MainPath, testday.strftime('%Y'),testday.strftime('%Y%m'),leg1_shortSymbol,testday.strftime('%m%d'),'{0}.txt'.format(leg1Symbol)))
|
||||||
.format(leg1MainPath, testday.strftime('%Y'),testday.strftime('%Y%m'), leg1_shortSymbol, testday.strftime('%m%d'), leg1Symbol)
|
#leg1File = u'{0}\\{1}\\{2}\\{3}\\{4}\\{5}.txt' \
|
||||||
|
# .format(leg1MainPath, testday.strftime('%Y'),testday.strftime('%Y%m'), leg1_shortSymbol, testday.strftime('%m%d'), leg1Symbol)
|
||||||
if not os.path.isfile(leg1File):
|
if not os.path.isfile(leg1File):
|
||||||
self.writeCtaLog(u'{0}文件不存在'.format(leg1File))
|
self.writeCtaLog(u'{0}文件不存在'.format(leg1File))
|
||||||
return
|
return
|
||||||
|
|
||||||
leg2File = u'{0}\\{1}\\{2}\\{3}\\{4}\\{5}.txt' \
|
leg2File=os.path.abspath(os.path.join(leg2MainPath, testday.strftime('%Y'), testday.strftime('%Y%m'), leg2_shortSymbol,
|
||||||
.format(leg2MainPath, testday.strftime('%Y'), testday.strftime('%Y%m'), leg2_shortSymbol, testday.strftime('%m%d'), leg2Symbol)
|
testday.strftime('%m%d'), '{0}.txt'.format(leg2Symbol)))
|
||||||
|
#leg2File = u'{0}\\{1}\\{2}\\{3}\\{4}\\{5}.txt' \
|
||||||
|
# .format(leg2MainPath, testday.strftime('%Y'), testday.strftime('%Y%m'), leg2_shortSymbol, testday.strftime('%m%d'), leg2Symbol)
|
||||||
if not os.path.isfile(leg2File):
|
if not os.path.isfile(leg2File):
|
||||||
self.writeCtaLog(u'{0}文件不存在'.format(leg2File))
|
self.writeCtaLog(u'{0}文件不存在'.format(leg2File))
|
||||||
return
|
return
|
||||||
@ -1608,9 +1614,9 @@ class BacktestingEngine(object):
|
|||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
self.writeCtaError(u'{0}:{1}'.format(Exception, ex))
|
self.writeCtaError(u'{0}:{1}'.format(Exception, ex))
|
||||||
|
|
||||||
# 实时计算模式
|
# 实时计算模式
|
||||||
if self.calculateMode == self.REALTIME_MODE:
|
if self.calculateMode == self.REALTIME_MODE:
|
||||||
self.realtimeCalculate()
|
self.realtimeCalculate2()
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def crossStopOrder(self):
|
def crossStopOrder(self):
|
||||||
@ -1687,9 +1693,9 @@ class BacktestingEngine(object):
|
|||||||
if stopOrderID in self.workingStopOrderDict:
|
if stopOrderID in self.workingStopOrderDict:
|
||||||
del self.workingStopOrderDict[stopOrderID]
|
del self.workingStopOrderDict[stopOrderID]
|
||||||
|
|
||||||
# 若采用实时计算净值
|
# 若采用实时计算净值
|
||||||
if self.calculateMode == self.REALTIME_MODE:
|
if self.calculateMode == self.REALTIME_MODE:
|
||||||
self.realtimeCalculate()
|
self.realtimeCalculate2()
|
||||||
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
@ -1729,6 +1735,9 @@ class BacktestingEngine(object):
|
|||||||
def realtimeCalculate(self):
|
def realtimeCalculate(self):
|
||||||
"""实时计算交易结果"""
|
"""实时计算交易结果"""
|
||||||
|
|
||||||
|
if len(self.tradeDict) < 1:
|
||||||
|
return
|
||||||
|
|
||||||
resultDict = OrderedDict() # 交易结果记录
|
resultDict = OrderedDict() # 交易结果记录
|
||||||
|
|
||||||
longTrade = [] # 未平仓的多头交易
|
longTrade = [] # 未平仓的多头交易
|
||||||
@ -2146,6 +2155,416 @@ class BacktestingEngine(object):
|
|||||||
self.avaliable = self.capital - occupyMoney
|
self.avaliable = self.capital - occupyMoney
|
||||||
self.percent = round(float(occupyMoney * 100 / self.capital), 2)
|
self.percent = round(float(occupyMoney * 100 / self.capital), 2)
|
||||||
|
|
||||||
|
def realtimeCalculate2(self):
|
||||||
|
"""实时计算交易结果2
|
||||||
|
支持多空仓位并存"""
|
||||||
|
|
||||||
|
if len(self.tradeDict) <1:
|
||||||
|
return
|
||||||
|
|
||||||
|
tradeids = self.tradeDict.keys()
|
||||||
|
|
||||||
|
resultDict = OrderedDict() # 交易结果记录
|
||||||
|
|
||||||
|
longTrade = [] # 未平仓的多头交易
|
||||||
|
shortTrade = [] # 未平仓的空头交易
|
||||||
|
longid = EMPTY_STRING
|
||||||
|
shortid = EMPTY_STRING
|
||||||
|
|
||||||
|
no_match_shortTrade = False
|
||||||
|
no_match_longTrade = False
|
||||||
|
|
||||||
|
# 对交易记录逐一处理
|
||||||
|
for tradeid in tradeids:
|
||||||
|
try:
|
||||||
|
trade = self.tradeDict[tradeid]
|
||||||
|
except:
|
||||||
|
self.output(u'没有{0}的成交单'.format(tradeid))
|
||||||
|
continue
|
||||||
|
|
||||||
|
# buy trade
|
||||||
|
if trade.direction == DIRECTION_LONG and trade.offset == OFFSET_OPEN:
|
||||||
|
self.output(u'{0}多开:{1},{2}'.format(trade.vtSymbol, trade.volume, trade.price))
|
||||||
|
self.writeCtaLog(u'{0}多开:{1},{2}'.format(trade.vtSymbol, trade.volume, trade.price))
|
||||||
|
self.longPosition.append(trade)
|
||||||
|
del self.tradeDict[tradeid]
|
||||||
|
|
||||||
|
# cover trade,
|
||||||
|
elif trade.direction == DIRECTION_LONG and trade.offset == OFFSET_CLOSE:
|
||||||
|
|
||||||
|
gId = trade.tradeID # 交易组(多个平仓数为一组)
|
||||||
|
gr = None # 组合的交易结果
|
||||||
|
|
||||||
|
coverVolume = trade.volume
|
||||||
|
|
||||||
|
while coverVolume > 0:
|
||||||
|
if len(self.shortPosition) == 0:
|
||||||
|
self.writeCtaError(u'异常!没有开空仓的数据')
|
||||||
|
break
|
||||||
|
pop_indexs = [i for i, val in enumerate(self.shortPosition) if val.vtSymbol == trade.vtSymbol]
|
||||||
|
if len(pop_indexs) < 1:
|
||||||
|
self.writeCtaError(u'异常,没有对应symbol:{0}的空单持仓'.format(trade.vtSymbol))
|
||||||
|
break
|
||||||
|
|
||||||
|
pop_index = pop_indexs[0]
|
||||||
|
# 从未平仓的空头交易
|
||||||
|
entryTrade = self.shortPosition.pop(pop_index)
|
||||||
|
|
||||||
|
# 开空volume,不大于平仓volume
|
||||||
|
if coverVolume >= entryTrade.volume:
|
||||||
|
self.writeCtaLog(u'coverVolume:{0} >= entryTrade.volume:{1}'.format(coverVolume, entryTrade.volume))
|
||||||
|
coverVolume = coverVolume - entryTrade.volume
|
||||||
|
|
||||||
|
self.output(u'{0}空平:{1},{2}'.format(entryTrade.vtSymbol, entryTrade.volume, trade.price))
|
||||||
|
self.writeCtaLog(u'{0}空平:{1},{2}'.format(entryTrade.vtSymbol, entryTrade.volume, trade.price))
|
||||||
|
|
||||||
|
result = TradingResult(entryPrice=entryTrade.price,
|
||||||
|
entryDt=entryTrade.dt,
|
||||||
|
exitPrice=trade.price,
|
||||||
|
exitDt=trade.dt,
|
||||||
|
volume=-entryTrade.volume,
|
||||||
|
rate=self.rate,
|
||||||
|
slippage=self.slippage,
|
||||||
|
size=self.size,
|
||||||
|
groupId=gId,
|
||||||
|
fixcommission=self.fixCommission)
|
||||||
|
|
||||||
|
t = {}
|
||||||
|
t['vtSymbol'] = entryTrade.vtSymbol
|
||||||
|
t['OpenTime'] = entryTrade.tradeTime
|
||||||
|
t['OpenPrice'] = entryTrade.price
|
||||||
|
t['Direction'] = u'Short'
|
||||||
|
t['CloseTime'] = trade.tradeTime
|
||||||
|
t['ClosePrice'] = trade.price
|
||||||
|
t['Volume'] = entryTrade.volume
|
||||||
|
t['Profit'] = result.pnl
|
||||||
|
self.exportTradeList.append(t)
|
||||||
|
|
||||||
|
msg = u'Gid:{0} {1}[{2}:开空tid={3}:{4}]-[{5}.平空tid={6},{7},vol:{8}],净盈亏:{9}'\
|
||||||
|
.format(gId, entryTrade.vtSymbol, entryTrade.tradeTime, shortid, entryTrade.price,
|
||||||
|
trade.tradeTime, tradeid, trade.price,
|
||||||
|
entryTrade.volume, result.pnl)
|
||||||
|
self.output(msg)
|
||||||
|
|
||||||
|
self.writeCtaLog(msg)
|
||||||
|
|
||||||
|
if type(gr) == type(None):
|
||||||
|
if coverVolume > 0:
|
||||||
|
# 属于组合
|
||||||
|
gr = copy.deepcopy(result)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# 不属于组合
|
||||||
|
resultDict[entryTrade.dt] = result
|
||||||
|
|
||||||
|
# 删除平空交易单,
|
||||||
|
del self.tradeDict[trade.tradeID]
|
||||||
|
|
||||||
|
else:
|
||||||
|
# 更新组合的数据
|
||||||
|
gr.turnover = gr.turnover + result.turnover
|
||||||
|
gr.commission = gr.commission + result.commission
|
||||||
|
gr.slippage = gr.slippage + result.slippage
|
||||||
|
gr.pnl = gr.pnl + result.pnl
|
||||||
|
|
||||||
|
# 所有仓位平完
|
||||||
|
if coverVolume == 0:
|
||||||
|
gr.volume = trade.volume
|
||||||
|
resultDict[entryTrade.dt] = gr
|
||||||
|
# 删除平空交易单,
|
||||||
|
del self.tradeDict[trade.tradeID]
|
||||||
|
|
||||||
|
# 开空volume,大于平仓volume,需要更新减少tradeDict的数量。
|
||||||
|
else:
|
||||||
|
self.writeCtaLog(u'Short volume:{0} > Cover volume:{1},需要更新减少tradeDict的数量。'.format(entryTrade.volume,coverVolume))
|
||||||
|
shortVolume = entryTrade.volume - coverVolume
|
||||||
|
|
||||||
|
result = TradingResult(entryPrice=entryTrade.price,
|
||||||
|
entryDt=entryTrade.dt,
|
||||||
|
exitPrice=trade.price,
|
||||||
|
exitDt=trade.dt,
|
||||||
|
volume=-coverVolume,
|
||||||
|
rate=self.rate,
|
||||||
|
slippage=self.slippage,
|
||||||
|
size=self.size,
|
||||||
|
groupId=gId,
|
||||||
|
fixcommission=self.fixCommission)
|
||||||
|
|
||||||
|
t = {}
|
||||||
|
t['vtSymbol'] = entryTrade.vtSymbol
|
||||||
|
t['OpenTime'] = entryTrade.tradeTime
|
||||||
|
t['OpenPrice'] = entryTrade.price
|
||||||
|
t['Direction'] = u'Short'
|
||||||
|
t['CloseTime'] = trade.tradeTime
|
||||||
|
t['ClosePrice'] = trade.price
|
||||||
|
t['Volume'] = coverVolume
|
||||||
|
t['Profit'] = result.pnl
|
||||||
|
self.exportTradeList.append(t)
|
||||||
|
|
||||||
|
msg = u'Gid:{0} {1}[{2}:开空tid={3}:{4}]-[{5}.平空tid={6},{7},vol:{8}],净盈亏:{9}'\
|
||||||
|
.format(gId, entryTrade.vtSymbol, entryTrade.tradeTime, shortid, entryTrade.price,
|
||||||
|
trade.tradeTime, tradeid, trade.price,
|
||||||
|
coverVolume, result.pnl)
|
||||||
|
self.output(msg)
|
||||||
|
self.writeCtaLog(msg)
|
||||||
|
|
||||||
|
# 更新(减少)开仓单的volume,重新推进开仓单列表中
|
||||||
|
entryTrade.volume = shortVolume
|
||||||
|
self.shortPosition.append(entryTrade)
|
||||||
|
|
||||||
|
coverVolume = 0
|
||||||
|
|
||||||
|
if type(gr) == type(None):
|
||||||
|
resultDict[entryTrade.dt] = result
|
||||||
|
|
||||||
|
else:
|
||||||
|
# 更新组合的数据
|
||||||
|
gr.turnover = gr.turnover + result.turnover
|
||||||
|
gr.commission = gr.commission + result.commission
|
||||||
|
gr.slippage = gr.slippage + result.slippage
|
||||||
|
gr.pnl = gr.pnl + result.pnl
|
||||||
|
gr.volume = trade.volume
|
||||||
|
resultDict[entryTrade.dt] = gr
|
||||||
|
|
||||||
|
# 删除平空交易单,
|
||||||
|
del self.tradeDict[trade.tradeID]
|
||||||
|
|
||||||
|
if type(gr) != type(None):
|
||||||
|
self.writeCtaLog(u'组合净盈亏:{0}'.format(gr.pnl))
|
||||||
|
|
||||||
|
self.writeCtaLog(u'-------------')
|
||||||
|
|
||||||
|
# Short Trade
|
||||||
|
elif trade.direction == DIRECTION_SHORT and trade.offset == OFFSET_OPEN:
|
||||||
|
|
||||||
|
self.output(u'{0}空开:{1},{2}'.format(trade.vtSymbol, trade.volume, trade.price))
|
||||||
|
self.writeCtaLog(u'{0}空开:{1},{2}'.format(trade.vtSymbol, trade.volume, trade.price))
|
||||||
|
self.shortPosition.append(trade)
|
||||||
|
del self.tradeDict[trade.tradeID]
|
||||||
|
continue
|
||||||
|
|
||||||
|
# sell trade
|
||||||
|
elif trade.direction == DIRECTION_SHORT and trade.offset == OFFSET_CLOSE:
|
||||||
|
gId = trade.tradeID # 交易组(多个平仓数为一组) s
|
||||||
|
gr = None # 组合的交易结果
|
||||||
|
|
||||||
|
sellVolume = trade.volume
|
||||||
|
|
||||||
|
while sellVolume > 0:
|
||||||
|
if len(self.longPosition) == 0:
|
||||||
|
self.writeCtaError(u'异常,没有开多单')
|
||||||
|
break
|
||||||
|
|
||||||
|
pop_indexs = [i for i, val in enumerate(self.longPosition) if val.vtSymbol == trade.vtSymbol]
|
||||||
|
if len(pop_indexs) < 1:
|
||||||
|
self.writeCtaError(u'没有对应的symbol{0}开多仓数据,'.format(trade.vtSymbol))
|
||||||
|
break
|
||||||
|
|
||||||
|
pop_index = pop_indexs[0]
|
||||||
|
|
||||||
|
entryTrade = self.longPosition.pop(pop_index)
|
||||||
|
|
||||||
|
# 开多volume,不大于平仓volume
|
||||||
|
if sellVolume >= entryTrade.volume:
|
||||||
|
self.writeCtaLog(u'{0}Sell Volume:{1} >= Entry Volume:{2}'.format(entryTrade.vtSymbol, sellVolume, entryTrade.volume))
|
||||||
|
sellVolume = sellVolume - entryTrade.volume
|
||||||
|
self.output(u'{0}多平:{1},{2}'.format(entryTrade.vtSymbol, entryTrade.volume, trade.price))
|
||||||
|
self.writeCtaLog(u'{0}多平:{1},{2}'.format(entryTrade.vtSymbol, entryTrade.volume, trade.price))
|
||||||
|
|
||||||
|
result = TradingResult(entryPrice=entryTrade.price,
|
||||||
|
entryDt=entryTrade.dt,
|
||||||
|
exitPrice=trade.price,
|
||||||
|
exitDt=trade.dt,
|
||||||
|
volume=entryTrade.volume,
|
||||||
|
rate=self.rate,
|
||||||
|
slippage=self.slippage,
|
||||||
|
size=self.size,
|
||||||
|
groupId=gId,
|
||||||
|
fixcommission=self.fixCommission)
|
||||||
|
|
||||||
|
t = {}
|
||||||
|
t['vtSymbol'] = entryTrade.vtSymbol
|
||||||
|
t['OpenTime'] = entryTrade.tradeTime
|
||||||
|
t['OpenPrice'] = entryTrade.price
|
||||||
|
t['Direction'] = u'Long'
|
||||||
|
t['CloseTime'] = trade.tradeTime
|
||||||
|
t['ClosePrice'] = trade.price
|
||||||
|
t['Volume'] = entryTrade.volume
|
||||||
|
t['Profit'] = result.pnl
|
||||||
|
self.exportTradeList.append(t)
|
||||||
|
|
||||||
|
msg = u'Gid:{0} {1}[{2}:开多tid={3}:{4}]-[{5}.平多tid={6},{7},vol:{8}],净盈亏:{9}'\
|
||||||
|
.format(gId, entryTrade.vtSymbol,
|
||||||
|
entryTrade.tradeTime, longid, entryTrade.price,
|
||||||
|
trade.tradeTime, tradeid, trade.price,
|
||||||
|
entryTrade.volume, result.pnl)
|
||||||
|
self.output(msg)
|
||||||
|
self.writeCtaLog(msg)
|
||||||
|
|
||||||
|
if type(gr) == type(None):
|
||||||
|
if sellVolume > 0:
|
||||||
|
# 属于组合
|
||||||
|
gr = copy.deepcopy(result)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# 不属于组合
|
||||||
|
resultDict[entryTrade.dt] = result
|
||||||
|
|
||||||
|
# 删除平多交易单,
|
||||||
|
del self.tradeDict[trade.tradeID]
|
||||||
|
|
||||||
|
else:
|
||||||
|
# 更新组合的数据
|
||||||
|
gr.turnover = gr.turnover + result.turnover
|
||||||
|
gr.commission = gr.commission + result.commission
|
||||||
|
gr.slippage = gr.slippage + result.slippage
|
||||||
|
gr.pnl = gr.pnl + result.pnl
|
||||||
|
|
||||||
|
if sellVolume == 0:
|
||||||
|
gr.volume = trade.volume
|
||||||
|
resultDict[entryTrade.dt] = gr
|
||||||
|
# 删除平多交易单,
|
||||||
|
del self.tradeDict[trade.tradeID]
|
||||||
|
|
||||||
|
# 开多volume,大于平仓volume,需要更新减少tradeDict的数量。
|
||||||
|
else:
|
||||||
|
longVolume = entryTrade.volume -sellVolume
|
||||||
|
self.writeCtaLog(u'Long Volume:{0} > sell Volume:{1}'.format(entryTrade.volume,sellVolume))
|
||||||
|
|
||||||
|
result = TradingResult(entryPrice=entryTrade.price,
|
||||||
|
entryDt=entryTrade.dt,
|
||||||
|
exitPrice=trade.price,
|
||||||
|
exitDt=trade.dt,
|
||||||
|
volume=sellVolume,
|
||||||
|
rate=self.rate,
|
||||||
|
slippage=self.slippage,
|
||||||
|
size=self.size,
|
||||||
|
groupId=gId,
|
||||||
|
fixcommission=self.fixCommission)
|
||||||
|
|
||||||
|
t = {}
|
||||||
|
t['vtSymbol'] = entryTrade.vtSymbol
|
||||||
|
t['OpenTime'] = entryTrade.tradeTime
|
||||||
|
t['OpenPrice'] = entryTrade.price
|
||||||
|
t['Direction'] = u'Long'
|
||||||
|
t['CloseTime'] = trade.tradeTime
|
||||||
|
t['ClosePrice'] = trade.price
|
||||||
|
t['Volume'] = sellVolume
|
||||||
|
t['Profit'] = result.pnl
|
||||||
|
self.exportTradeList.append(t)
|
||||||
|
|
||||||
|
self.writeCtaLog(u'Gid:{0} {1}[{2}:开多tid={3}:{4}]-[{5}.平多tid={6},{7},vol:{8}],净盈亏:{9}'
|
||||||
|
.format(gId, entryTrade.vtSymbol,entryTrade.tradeTime, longid, entryTrade.price,
|
||||||
|
trade.tradeTime, tradeid, trade.price,
|
||||||
|
sellVolume, result.pnl))
|
||||||
|
|
||||||
|
# 减少开多volume,重新推进多单持仓列表中
|
||||||
|
entryTrade.volume = longVolume
|
||||||
|
self.longPosition.append(entryTrade)
|
||||||
|
|
||||||
|
sellVolume = 0
|
||||||
|
|
||||||
|
if type(gr) == type(None):
|
||||||
|
resultDict[entryTrade.dt] = result
|
||||||
|
|
||||||
|
else:
|
||||||
|
# 更新组合的数据
|
||||||
|
gr.turnover = gr.turnover + result.turnover
|
||||||
|
gr.commission = gr.commission + result.commission
|
||||||
|
gr.slippage = gr.slippage + result.slippage
|
||||||
|
gr.pnl = gr.pnl + result.pnl
|
||||||
|
gr.volume = trade.volume
|
||||||
|
resultDict[entryTrade.dt] = gr
|
||||||
|
|
||||||
|
# 删除平多交易单,
|
||||||
|
del self.tradeDict[trade.tradeID]
|
||||||
|
|
||||||
|
if type(gr) != type(None):
|
||||||
|
self.writeCtaLog(u'组合净盈亏:{0}'.format(gr.pnl))
|
||||||
|
|
||||||
|
self.writeCtaLog(u'-------------')
|
||||||
|
|
||||||
|
# 计算仓位比例
|
||||||
|
occupyMoney = EMPTY_FLOAT
|
||||||
|
occupyLongVolume = EMPTY_INT
|
||||||
|
occupyShortVolume = EMPTY_INT
|
||||||
|
longPos = {}
|
||||||
|
shortPos = {}
|
||||||
|
if len(self.longPosition) > 0:
|
||||||
|
for t in self.longPosition:
|
||||||
|
occupyMoney += t.price * abs(t.volume) * self.size * self.margin_rate
|
||||||
|
occupyLongVolume += abs(t.volume)
|
||||||
|
if t.vtSymbol in longPos:
|
||||||
|
longPos[t.vtSymbol] += abs(t.volume)
|
||||||
|
else:
|
||||||
|
longPos[t.vtSymbol] = abs(t.volume)
|
||||||
|
|
||||||
|
if len(self.shortPosition) > 0:
|
||||||
|
for t in self.shortPosition:
|
||||||
|
occupyMoney += t.price * abs(t.volume) * self.size * self.margin_rate
|
||||||
|
occupyShortVolume += (t.volume)
|
||||||
|
if t.vtSymbol in shortPos:
|
||||||
|
shortPos[t.vtSymbol] += abs(t.volume)
|
||||||
|
else:
|
||||||
|
shortPos[t.vtSymbol] = abs(t.volume)
|
||||||
|
|
||||||
|
self.output(u'L:{0}|{1},S:{2}|{3}'.format(occupyLongVolume, str(longPos), occupyShortVolume, str(shortPos)))
|
||||||
|
self.writeCtaLog(u'L:{0}|{1},S:{2}|{3}'.format(occupyLongVolume, str(longPos), occupyShortVolume, str(shortPos)))
|
||||||
|
# 最大持仓
|
||||||
|
self.maxVolume = max(self.maxVolume, occupyLongVolume + occupyShortVolume)
|
||||||
|
|
||||||
|
self.avaliable = self.capital - occupyMoney
|
||||||
|
self.percent = round(float(occupyMoney * 100 / self.capital), 2)
|
||||||
|
|
||||||
|
# 检查是否有平交易
|
||||||
|
if not resultDict:
|
||||||
|
|
||||||
|
msg = u''
|
||||||
|
if len(self.longPosition) > 0:
|
||||||
|
msg += u'持多仓{0},'.format( str(longPos))
|
||||||
|
|
||||||
|
if len(self.shortPosition) > 0:
|
||||||
|
msg += u'持空仓{0},'.format(str(shortPos))
|
||||||
|
|
||||||
|
msg += u'资金占用:{0},仓位:{1}%%'.format(occupyMoney, self.percent)
|
||||||
|
self.output(msg)
|
||||||
|
self.writeCtaLog(msg)
|
||||||
|
return
|
||||||
|
|
||||||
|
# 对交易结果汇总统计
|
||||||
|
for time, result in resultDict.items():
|
||||||
|
|
||||||
|
if result.pnl > 0:
|
||||||
|
self.winningResult += 1
|
||||||
|
self.totalWinning += result.pnl
|
||||||
|
else:
|
||||||
|
self.losingResult += 1
|
||||||
|
self.totalLosing += result.pnl
|
||||||
|
self.capital += result.pnl
|
||||||
|
self.maxCapital = max(self.capital, self.maxCapital)
|
||||||
|
#self.maxVolume = max(self.maxVolume, result.volume)
|
||||||
|
drawdown = self.capital - self.maxCapital
|
||||||
|
drawdownRate = round(float(drawdown*100/self.maxCapital),4)
|
||||||
|
|
||||||
|
self.pnlList.append(result.pnl)
|
||||||
|
self.timeList.append(time)
|
||||||
|
self.capitalList.append(self.capital)
|
||||||
|
self.drawdownList.append(drawdown)
|
||||||
|
self.drawdownRateList.append(drawdownRate)
|
||||||
|
|
||||||
|
self.totalResult += 1
|
||||||
|
self.totalTurnover += result.turnover
|
||||||
|
self.totalCommission += result.commission
|
||||||
|
self.totalSlippage += result.slippage
|
||||||
|
|
||||||
|
self.output(u'[{5}],{6} Vol:{0},盈亏:{1},回撤:{2}/{3},权益:{4}'.
|
||||||
|
format(abs(result.volume), result.pnl, drawdown,
|
||||||
|
drawdownRate, self.capital, result.groupId, time))
|
||||||
|
|
||||||
|
# 重新计算一次avaliable
|
||||||
|
self.avaliable = self.capital - occupyMoney
|
||||||
|
self.percent = round(float(occupyMoney * 100 / self.capital), 2)
|
||||||
|
|
||||||
def savingDailyData(self, d, c, m):
|
def savingDailyData(self, d, c, m):
|
||||||
"""保存每日数据"""
|
"""保存每日数据"""
|
||||||
dict = {}
|
dict = {}
|
||||||
|
Loading…
Reference in New Issue
Block a user