我们核心关注一下calculateBacktestingResult这个方法,这个方法中最核心的是一个大循环。
for trade in self.tradeDict.values():
# 复制成交对象,因为下面的开平仓交易配对涉及到对成交数量的修改
# 若不进行复制直接操作,则计算完后所有成交的数量会变成0
trade = copy.copy(trade)
整个循环中,最核心的就是那个tradeDict,这个是一个ordered字典,也就是有序的字典。里面的value是VtTradeDate对象。我们来看一下这个类的实现:
class VtTradeData(VtBaseData):
"""成交数据类"""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
super(VtTradeData, self).__init__()
# 代码编号相关
self.symbol = EMPTY_STRING # 合约代码
self.exchange = EMPTY_STRING # 交易所代码
self.vtSymbol = EMPTY_STRING # 合约在vt系统中的唯一代码,通常是 合约代码.交易所代码
self.tradeID = EMPTY_STRING # 成交编号
self.vtTradeID = EMPTY_STRING # 成交在vt系统中的唯一编号,通常是 Gateway名.成交编号
self.orderID = EMPTY_STRING # 订单编号
self.vtOrderID = EMPTY_STRING # 订单在vt系统中的唯一编号,通常是 Gateway名.订单编号
# 成交相关
self.direction = EMPTY_UNICODE # 成交方向
self.offset = EMPTY_UNICODE # 成交开平仓
self.price = EMPTY_FLOAT # 成交价格
self.volume = EMPTY_INT # 成交数量
self.tradeTime = EMPTY_STRING # 成交时间
那么,很显然,这是在回测成交的过程中被放到这个tradeDict中的。我们去crossLimitOrder方法中看一下。
trade = VtTradeData()
trade.vtSymbol = order.vtSymbol
trade.tradeID = tradeID
trade.vtTradeID = tradeID
trade.orderID = order.orderID
trade.vtOrderID = order.orderID
trade.direction = order.direction
trade.offset = order.offset
# 以买入为例:
# 1.