Esempio n. 1
0
    def crossStopOrder(self):
        """基于最新数据撮合停止单"""
        # 先确定会撮合成交的价格,这里和限价单规则相反
        if self.mode == self.BAR_MODE:
            buyCrossPrice = self.bar.high  # 若买入方向停止单价格低于该价格,则会成交
            sellCrossPrice = self.bar.low  # 若卖出方向限价单价格高于该价格,则会成交
            bestCrossPrice = self.bar.open  # 最优成交价,买入停止单不能低于,卖出停止单不能高于
        else:
            buyCrossPrice = self.tick.lastPrice
            sellCrossPrice = self.tick.lastPrice
            bestCrossPrice = self.tick.lastPrice

        # 遍历停止单字典中的所有停止单
        for stopOrderID, so in self.workingStopOrderDict.items():
            # 判断是否会成交
            buyCross = so.direction == DIRECTION_LONG and so.price <= buyCrossPrice
            sellCross = so.direction == DIRECTION_SHORT and so.price >= sellCrossPrice

            # 如果发生了成交
            if buyCross or sellCross:
                # 推送成交数据
                self.tradeCount += 1  # 成交编号自增1
                tradeID = str(self.tradeCount)
                trade = VtTradeData()
                trade.vtSymbol = so.vtSymbol
                trade.tradeID = tradeID
                trade.vtTradeID = tradeID

                if buyCross:
                    self.strategy.pos += so.volume
                    trade.price = max(bestCrossPrice, so.price)
                else:
                    self.strategy.pos -= so.volume
                    trade.price = min(bestCrossPrice, so.price)

                self.limitOrderCount += 1
                orderID = str(self.limitOrderCount)
                trade.orderID = orderID
                trade.vtOrderID = orderID

                trade.direction = so.direction
                trade.offset = so.offset
                trade.volume = so.volume
                trade.tradeTime = str(self.dt)
                trade.dt = self.dt
                self.strategy.onTrade(trade)

                self.tradeDict[tradeID] = trade

                # 推送委托数据
                so.status = STOPORDER_TRIGGERED

                order = VtOrderData()
                order.vtSymbol = so.vtSymbol
                order.symbol = so.vtSymbol
                order.orderID = orderID
                order.vtOrderID = orderID
                order.direction = so.direction
                order.offset = so.offset
                order.price = so.price
                order.totalVolume = so.volume
                order.tradedVolume = so.volume
                order.status = STATUS_ALLTRADED
                order.orderTime = trade.tradeTime
                self.strategy.onOrder(order)

                self.limitOrderDict[orderID] = order

                # 从字典中删除该限价单
                if stopOrderID in self.workingStopOrderDict:
                    del self.workingStopOrderDict[stopOrderID]
Esempio n. 2
0
 def crossStopOrder(self):
     """基于最新数据撮合停止单"""
     # 先确定会撮合成交的价格,这里和限价单规则相反
     if self.mode == self.BAR_MODE:
         buyCrossPrice = self.bar.high    # 若买入方向停止单价格低于该价格,则会成交
         sellCrossPrice = self.bar.low    # 若卖出方向限价单价格高于该价格,则会成交
     else:
         buyCrossPrice = self.tick.lastPrice
         sellCrossPrice = self.tick.lastPrice
     
     # 遍历停止单字典中的所有停止单
     for stopOrderID, so in self.workingStopOrderDict.items():
         # 判断是否会成交
         buyCross = so.direction==DIRECTION_LONG and so.price<=buyCrossPrice
         sellCross = so.direction==DIRECTION_SHORT and so.price>=sellCrossPrice
         
         # 如果发生了成交
         if buyCross or sellCross:
             # 推送成交数据
             self.tradeCount += 1            # 成交编号自增1
             tradeID = str(self.tradeCount)
             trade = VtTradeData()
             trade.vtSymbol = so.vtSymbol
             trade.tradeID = tradeID
             trade.vtTradeID = tradeID
             
             self.limitOrderCount += 1
             orderID = str(self.limitOrderCount)
             trade.orderID = orderID
             trade.vtOrderID = orderID
             
             trade.direction = so.direction
             trade.offset = so.offset
             trade.price = so.price
             trade.volume = so.volume
             trade.tradeTime = str(self.dt)
             trade.dt = self.dt
             self.strategy.onTrade(trade)
             
             self.tradeDict[tradeID] = trade
             
             # 推送委托数据
             so.status = STOPORDER_TRIGGERED
             
             order = VtOrderData()
             order.vtSymbol = so.vtSymbol
             order.symbol = so.vtSymbol
             order.orderID = orderID
             order.vtOrderID = orderID
             order.direction = so.direction
             order.offset = so.offset
             order.price = so.price
             order.totalVolume = so.volume
             order.tradedVolume = so.volume
             order.status = STATUS_ALLTRADED
             order.orderTime = trade.tradeTime
             self.strategy.onOrder(order)
             
             self.limitOrderDict[orderID] = order
             
             # 从字典中删除该限价单
             del self.workingStopOrderDict[stopOrderID]        
Esempio n. 3
0
    def crossLimitOrder(self):
        """基于最新数据撮合限价单"""
        # 先确定会撮合成交的价格
        if self.mode == self.BAR_MODE:
            buyCrossPrice = self.bar.low  # 若买入方向限价单价格高于该价格,则会成交
            sellCrossPrice = self.bar.high  # 若卖出方向限价单价格低于该价格,则会成交
            buyBestCrossPrice = self.bar.open  # 在当前时间点前发出的买入委托可能的最优成交价
            sellBestCrossPrice = self.bar.open  # 在当前时间点前发出的卖出委托可能的最优成交价
        else:
            buyCrossPrice = self.tick.askPrice1
            sellCrossPrice = self.tick.bidPrice1
            buyBestCrossPrice = self.tick.askPrice1
            sellBestCrossPrice = self.tick.bidPrice1

        # 遍历限价单字典中的所有限价单
        for orderID, order in self.workingLimitOrderDict.items():
            # 判断是否会成交
            buyCross = (order.direction == DIRECTION_LONG
                        and order.price >= buyCrossPrice and buyCrossPrice > 0
                        )  # 国内的tick行情在涨停时askPrice1为0,此时买无法成交

            sellCross = (order.direction == DIRECTION_SHORT
                         and order.price <= sellCrossPrice
                         and sellCrossPrice > 0
                         )  # 国内的tick行情在跌停时bidPrice1为0,此时卖无法成交

            # 如果发生了成交
            if buyCross or sellCross:
                # 推送成交数据
                self.tradeCount += 1  # 成交编号自增1
                tradeID = str(self.tradeCount)
                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. 假设当根K线的OHLC分别为:100, 125, 90, 110
                # 2. 假设在上一根K线结束(也是当前K线开始)的时刻,策略发出的委托为限价105
                # 3. 则在实际中的成交价会是100而不是105,因为委托发出时市场的最优价格是100
                if buyCross:
                    trade.price = min(order.price, buyBestCrossPrice)
                    self.strategy.pos += order.totalVolume
                else:
                    trade.price = max(order.price, sellBestCrossPrice)
                    self.strategy.pos -= order.totalVolume

                trade.volume = order.totalVolume
                trade.tradeTime = str(self.dt)
                trade.dt = self.dt
                self.strategy.onTrade(trade)

                self.tradeDict[tradeID] = trade

                # 推送委托数据
                order.tradedVolume = order.totalVolume
                order.status = STATUS_ALLTRADED
                self.strategy.onOrder(order)

                # 从字典中删除该限价单
                del self.workingLimitOrderDict[orderID]
Esempio n. 4
0
 def crossLimitOrder(self):
     """基于最新数据撮合限价单"""
     # 先确定会撮合成交的价格
     if self.mode == self.BAR_MODE:
         buyCrossPrice = self.bar.low    # 若买入方向限价单价格高于该价格,则会成交
         sellCrossPrice = self.bar.high  # 若卖出方向限价单价格低于该价格,则会成交
         bestCrossPrice = self.bar.open  # 在当前时间点前发出的委托可能的最优成交价
     else:
         buyCrossPrice = self.tick.lastPrice
         sellCrossPrice = self.tick.lastPrice
         bestCrossPrice = self.tick.lastPrice
     
     # 遍历限价单字典中的所有限价单
     for orderID, order in self.workingLimitOrderDict.items():
         # 判断是否会成交
         buyCross = order.direction==DIRECTION_LONG and order.price>=buyCrossPrice
         sellCross = order.direction==DIRECTION_SHORT and order.price<=sellCrossPrice
         
         # 如果发生了成交
         if buyCross or sellCross:
             # 推送成交数据
             self.tradeCount += 1            # 成交编号自增1
             tradeID = str(self.tradeCount)
             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. 假设当根K线的OHLC分别为:100, 125, 90, 110
             # 2. 假设在上一根K线结束(也是当前K线开始)的时刻,策略发出的委托为限价105
             # 3. 则在实际中的成交价会是100而不是105,因为委托发出时市场的最优价格是100
             if buyCross:
                 trade.price = min(order.price, bestCrossPrice)
             else:
                 trade.price = max(order.price, bestCrossPrice)
             
             trade.volume = order.totalVolume
             trade.tradeTime = str(self.dt)
             trade.dt = self.dt
             self.strategy.onTrade(trade)
             
             self.tradeDict[tradeID] = trade
             
             # 推送委托数据
             order.tradedVolume = order.totalVolume
             order.status = STATUS_ALLTRADED
             self.strategy.onOrder(order)
             
             # 从字典中删除该限价单
             del self.workingLimitOrderDict[orderID]
Esempio n. 5
0
    def crossLimitOrder(self):
        """基于最新数据撮合限价单"""
        # 先确定会撮合成交的价格
        if self.mode == self.BAR_MODE:
            buyCrossPrice = self.bar.low  # 若买入方向限价单价格高于该价格,则会成交
            sellCrossPrice = self.bar.high  # 若卖出方向限价单价格低于该价格,则会成交
        else:
            buyCrossPrice = self.tick.lastPrice
            sellCrossPrice = self.tick.lastPrice

        # 遍历限价单字典中的所有限价单
        for orderID, order in self.workingLimitOrderDict.items():
            # 判断是否会成交
            buyCross = order.direction == DIRECTION_LONG and order.price >= buyCrossPrice
            sellCross = order.direction == DIRECTION_SHORT and order.price <= sellCrossPrice

            # 如果发生了成交
            if buyCross or sellCross:
                # 推送成交数据
                self.tradeCount += 1  # 成交编号自增1
                tradeID = str(self.tradeCount)
                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
                trade.price = order.price
                trade.volume = order.totalVolume
                trade.tradeTime = str(self.dt)
                trade.dt = self.dt
                self.strategy.onTrade(trade)

                self.tradeDict[tradeID] = trade

                # 推送委托数据
                order.tradedVolume = order.totalVolume
                order.status = STATUS_ALLTRADED
                self.strategy.onOrder(order)

                # 从字典中删除该限价单
                del self.workingLimitOrderDict[orderID]
    def calculateBacktestingResult(self):
        """
        计算回测结果
        """
        #将交易结果化为dataframe
        tradeResult = []

        def todict(t):
            return t.__dict__

        for symbol in self.tradeDict.keys():
            tradeResult.extend(self.tradeDict[symbol].values())

        tradeResult = map(todict, tradeResult)
        d = pd.DataFrame(tradeResult)
        d = d.sort_values('dt')
        index = pd.Index(np.arange(d.count()[0]))
        d.index = index

        self.output(u'计算回测结果')

        # 首先基于回测后的成交记录,计算每笔交易的盈亏
        self.resultList = []  # 交易结果列表
        longTrade = {}  # 未平仓的多头交易
        shortTrade = {}  # 未平仓的空头交易
        symbolNow = ''  # 当前的交易标的
        for symbol in self.symbols:
            longTrade[symbol] = []
            shortTrade[symbol] = []
        for i in range(d.count()[0]):
            dict_ = d.ix[i].to_dict()
            trade = VtTradeData()
            trade.__dict__ = dict_

            # 这些变量会被较多地引用,故先赋值
            #            if not symbolNow :
            #                symbolNow = trade.vtSymbol
            if symbolNow != trade.vtSymbol:
                symbolNow = trade.vtSymbol
                commission = self.contractInfo[trade.vtSymbol]['commission']
                slippage = self.contractInfo[trade.vtSymbol]['slippage']
                size = self.contractInfo[trade.vtSymbol]['size']
                margin = self.contractInfo[trade.vtSymbol]['margin']
            elif symbolNow == trade.vtSymbol:
                pass

            # 多头交易
            if trade.direction == DIRECTION_LONG:
                # 如果尚无空头交易
                if not shortTrade[symbolNow]:
                    longTrade[symbolNow].append(trade)
                # 当前多头交易为平空
                else:
                    while True:
                        entryTrade = shortTrade[symbolNow][0]
                        exitTrade = trade

                        # 清算开平仓交易
                        closedVolume = min(exitTrade.volume, entryTrade.volume)
                        result = TradingResult(symbolNow, entryTrade.price,
                                               entryTrade.dt, exitTrade.price,
                                               exitTrade.dt, -closedVolume,
                                               commission, slippage, size,
                                               margin)
                        #print BLUEPREFIX + str(result.pnl)
                        #print result.volume
                        self.resultList.append(result)

                        # 计算未清算部分
                        entryTrade.volume -= closedVolume
                        exitTrade.volume -= closedVolume

                        # 如果开仓交易已经全部清算,则从列表中移除
                        if not entryTrade.volume:
                            shortTrade[symbolNow].pop(0)

                        # 如果平仓交易已经全部清算,则退出循环
                        if not exitTrade.volume:
                            break

                        # 如果平仓交易未全部清算,
                        if exitTrade.volume:
                            # 且开仓交易已经全部清算完,则平仓交易剩余的部分
                            # 等于新的反向开仓交易,添加到队列中
                            if not shortTrade[symbolNow]:
                                longTrade[symbolNow].append(exitTrade)
                                break
                            # 如果开仓交易还有剩余,则进入下一轮循环
                            else:
                                pass

            # 空头交易
            else:
                # 如果尚无多头交易
                if not longTrade[symbolNow]:
                    shortTrade[symbolNow].append(trade)
                # 当前空头交易为平多
                else:
                    while True:
                        entryTrade = longTrade[symbolNow][0]
                        exitTrade = trade

                        # 清算开平仓交易
                        closedVolume = min(exitTrade.volume, entryTrade.volume)
                        result = TradingResult(symbolNow, entryTrade.price,
                                               entryTrade.dt, exitTrade.price,
                                               exitTrade.dt, closedVolume,
                                               commission, slippage, size,
                                               margin)
                        #print BLUEPREFIX + str(result.pnl)
                        #print result.volume
                        self.resultList.append(result)

                        # 计算未清算部分
                        entryTrade.volume -= closedVolume
                        exitTrade.volume -= closedVolume

                        # 如果开仓交易已经全部清算,则从列表中移除
                        if not entryTrade.volume:
                            longTrade[symbolNow].pop(0)

                        # 如果平仓交易已经全部清算,则退出循环
                        if not exitTrade.volume:
                            break

                        # 如果平仓交易未全部清算,
                        if exitTrade.volume:
                            # 且开仓交易已经全部清算完,则平仓交易剩余的部分
                            # 等于新的反向开仓交易,添加到队列中
                            if not longTrade[symbolNow]:
                                shortTrade[symbolNow].append(exitTrade)
                                break
                            # 如果开仓交易还有剩余,则进入下一轮循环
                            else:
                                pass

        # 检查是否有交易
        if not self.resultList:
            self.output(u'无交易结果')
            return {}

        #将各标的交易的持仓区间用Series来表示持仓浮盈
        floatProfit = defaultdict(list)  #key为symbol,value是包含sr的list
        df = self.dataframe.set_index(
            'datetime').sort_index().drop_duplicates()
        pnlList = []
        for result in self.resultList:
            symbolDf = df[df.symbol == result.symbol]
            symbolDf = symbolDf[result.entryDt:result.exitDt]  #+ delta]
            symbolDf = symbolDf.drop_duplicates().sort_index()
            sr = (
                symbolDf['close'] - symbolDf.ix[0]['close']
            ) * result.size * self.contractInfo[result.symbol][
                'margin'] * result.volume  #- result.commission #- result.slippage
            floatProfit[result.symbol].append(sr)  #每笔交易区间的资金变化
            pnlList.append(result.pnl)  #每笔交易的利润
#===========================================================================
#print str(result.entryDt) + " =====> " + str(result.exitDt) + " ==========>>>  " + str(result.pnl)

        index = np.unique(df.index)
        capitalSr = pd.Series(0, index=index)
        for lsSymbol in floatProfit.values():
            for floatSr in lsSymbol:
                #print GREENPREFIX + str(floatSr) + "\n\n"
                floatSr = pd.Series(floatSr, index=index)
                floatSr = floatSr.fillna(method='ffill').fillna(0)
                capitalSr += floatSr

        capitalSr = capitalSr.drop_duplicates()
        capitalSr = capitalSr + self.initCapital  #可以看到回测期间的资金变化

        pnlStat = pd.Series(pnlList)  # 盈利序列
        drawdownSr = capitalSr.cummax() - capitalSr  # 回测序列
        #===========================================================================

        # 计算盈亏相关数据
        winningRate = pnlStat[pnlStat > 0].count() / pnlStat.count()  #胜率
        averageWinning = pnlStat[pnlStat > 0].mean()  # 平均每笔盈利
        averageLosing = pnlStat[pnlStat < 0].mean()  # 平均每笔亏损
        profitLossRatio = -averageWinning / averageLosing  # 盈亏比

        #稳健指标计算
        #回归年度回报率
        lenSr = len(capitalSr)
        m, b = np.polyfit(np.arange(lenSr), capitalSr.tolist(),
                          1)  # 对资金曲线进行简单回归
        expectedMonthlyReturn = lenSr * m / b  # 回测收益率
        testInterval = ((capitalSr.index[-1] - capitalSr.index[0]).days / 30.0
                        )  # 测试区间对应的时间长度(月)
        monthlyReturnRatio = expectedMonthlyReturn / testInterval  #月化收益率
        RAR = (1 + monthlyReturnRatio)**12 - 1  # 回归年度回报率

        #稳健风险回报比率
        temp = 0
        maxDrawdownLs = []
        for i in range(1, len(drawdownSr)):
            if drawdownSr[i] == 0:
                tempDrawdown = drawdownSr[temp:i].max()
                if tempDrawdown != 0:
                    maxDrawdownLs.append(tempDrawdown)
                    temp = i

        if len(maxDrawdownLs) >= 5:
            aveDrawdown = np.mean(maxDrawdownLs[-5:])  # 五次最大回测的平均值
        else:
            aveDrawdown = np.mean(maxDrawdownLs)  # 五次最大回测的平均值
        RCube = RAR / aveDrawdown  #稳健风险回报比率

        # 返回回测结果
        d = {}
        d['capital'] = capitalSr[-1] / self.initCapital
        d['maxCapital'] = capitalSr.max()
        d['maxdrawdown'] = (pnlStat.cummax() - pnlStat).max()
        d['maxdrawdownDay'] = drawdownSr.argmax().isoformat()
        d['totalResult'] = pnlStat.count()
        d['pnlList'] = pnlList
        d['capitalSr'] = capitalSr
        d['winningRate'] = winningRate
        d['averageWinning'] = averageWinning
        d['averageLosing'] = averageLosing
        d['profitLossRatio'] = profitLossRatio
        d['floatProfit'] = floatProfit

        d['RAR'] = RAR
        d['RCube'] = RCube

        return d
    def crossLimitOrder(self):
        """基于最新数据撮合限价单"""
        # 先确定会撮合成交的价格
        if self.mode == self.BAR_MODE:
            buyCrossPrice = self.bar.low  # 若买入方向限价单价格高于该价格,则会成交
            sellCrossPrice = self.bar.high  # 若卖出方向限价单价格低于该价格,则会成交
            buyBestCrossPrice = self.bar.open  # 在当前时间点前发出的买入委托可能的最优成交价
            sellBestCrossPrice = self.bar.open  # 在当前时间点前发出的卖出委托可能的最优成交价
        else:
            buyCrossPrice = self.tick.askPrice1
            sellCrossPrice = self.tick.bidPrice1
            buyBestCrossPrice = self.tick.askPrice1
            sellBestCrossPrice = self.tick.bidPrice1

        # 遍历限价单字典中的所有限价单
        for orderID, order in self.workingLimitOrderDict[
                self.bar.symbol].items():
            # 判断是否会成交
            buyCross = order.direction == DIRECTION_LONG and order.price >= buyCrossPrice
            sellCross = order.direction == DIRECTION_SHORT and order.price <= sellCrossPrice

            # 如果发生了成交
            if buyCross or sellCross:
                # 推送成交数据
                self.tradeCount += 1  # 成交编号自增1
                tradeID = str(self.tradeCount)
                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. 假设当根K线的OHLC分别为:100, 125, 90, 110
                # 2. 假设在上一根K线结束(也是当前K线开始)的时刻,策略发出的委托为限价105
                # 3. 则在实际中的成交价会是100而不是105,因为委托发出时市场的最优价格是100
                if buyCross:
                    trade.price = min(order.price, buyBestCrossPrice)
                    stra = self.strategyDict[self.bar.symbol]
                    stra.pos += order.totalVolume
                    #print "a"

                else:
                    trade.price = max(order.price, sellBestCrossPrice)
                    stra = self.strategyDict[self.bar.symbol]
                    stra.pos -= order.totalVolume

                trade.volume = order.totalVolume
                trade.tradeTime = str(self.dt)
                trade.dt = self.dt
                trade.symbol = self.bar.symbol
                stra = self.strategyDict[self.bar.symbol]
                stra.onTrade(trade)
                #print trade.direction

                self.tradeDict[trade.vtSymbol][tradeID] = trade
                '''#在此处更新回测账户'''
                #print REDPREFIX +str(trade.symbol) + "\t"+  "%.1f"%trade.price + "\t" +\
                #        trade.direction + "\t" + trade.offset + "\t" + str(trade.volume)
                self.updateAccount(trade)

                # 推送委托数据
                order.tradedVolume = order.totalVolume
                order.status = STATUS_ALLTRADED

                stra = self.strategyDict[self.bar.symbol]
                stra.onOrder(order)

                # 从字典中删除该限价单
                del self.workingLimitOrderDict[self.bar.symbol][orderID]
Esempio n. 8
0
    def crossLimitOrder(self):
        """基于最新数据撮合限价单"""
        """Check LimitOrder base on newest market data"""

        # 先确定会撮合成交的价格
        if self.mode == self.BAR_MODE:
            buyCrossPrice = self.bar.low  # 若买入方向限价单价格高于该价格,则会成交
            sellCrossPrice = self.bar.high  # 若卖出方向限价单价格低于该价格,则会成交
            buyBestCrossPrice = self.bar.open  # 在当前时间点前发出的买入委托可能的最优成交价
            sellBestCrossPrice = self.bar.open  # 在当前时间点前发出的卖出委托可能的最优成交价
        else:
            buyCrossPrice = self.tick.askPrice1
            sellCrossPrice = self.tick.bidPrice1
            buyBestCrossPrice = self.tick.askPrice1
            sellBestCrossPrice = self.tick.bidPrice1

        # 遍历限价单字典中的所有限价单
        for orderID, order in self.workingLimitOrderDict.items():
            # 判断是否会成交
            buyCross = order.direction == DIRECTION_LONG and order.price >= buyCrossPrice
            sellCross = order.direction == DIRECTION_SHORT and order.price <= sellCrossPrice

            # 如果发生了成交
            # If transaction happens
            if buyCross or sellCross:
                # 推送成交数据
                # Update trade data
                self.tradeCount += 1  # TradeID increase by 1
                tradeID = str(self.tradeCount)
                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

                # Buy as example:
                # 1. Suppose the OHLC of current Bar are 100, 125, 90, 110 (Open = 100)
                # 2. Suppose at the end of last Bar(not the start of current Bar), the price of limit order is 105,
                #    (Last Close = 105)
                # 3. In real trading, the trade price will be 100 instead of 105, because the best market price is 100
                if buyCross:
                    trade.price = min(order.price, buyBestCrossPrice)
                    self.strategy.pos += order.totalVolume
                else:
                    trade.price = max(order.price, sellBestCrossPrice)
                    self.strategy.pos -= order.totalVolume

                trade.volume = order.totalVolume
                trade.tradeTime = str(self.dt)
                trade.dt = self.dt
                self.strategy.onTrade(trade)

                self.tradeDict[tradeID] = trade

                # 推送委托数据
                # Upadte order data
                order.tradedVolume = order.totalVolume
                order.status = STATUS_ALLTRADED
                self.strategy.onOrder(order)

                # 从字典中删除该限价单
                # Remove this order from "working limit order dictionary"
                del self.workingLimitOrderDict[orderID]