private StockTickTransaction onTick(int seconds, List <StockTickTransaction> data)
        {
            StockTickTransaction tick = new StockTickTransaction();
            int secondsIndex          = DataTimeStampExtension.GetStockSecondsIndex(data[0].TransactionDateTime);

            for (int i = 0; i < data.Count(); i++)
            {
                secondsIndex = DataTimeStampExtension.GetStockSecondsIndex(data[i].TransactionDateTime);
                if (secondsIndex <= seconds)
                {
                    tick = data[i];
                }
                else
                {
                    break;
                }
            }
            return(tick);
        }
        public void computeTWAP(DateTime startDate, DateTime endDate, int totalVolume = 10000000, int newOrderTimeInterval = 15, int oldOrderTimeInterval = 15, int oldOrderFrequency = 10, int newOrderPriceMode = -1, int oldOrderPriceMode = -1, int cancelTimeInterval = 120)
        {
            var tradedays = dateRepo.GetStockTransactionDate(startDate, endDate);

            foreach (var date in tradedays)
            {
                List <StockTickTransaction> data = new List <StockTickTransaction>();
                try
                {
                    data = stockRepo.GetStockTransaction(code, date, date);
                }
                catch (Exception)
                {
                    Console.WriteLine("code:{0},date:{1} No Data!!", code, date);
                }
                if (data.Count() == 0)
                {
                    Console.WriteLine("code:{0},date:{1} No Data!!", code, date);
                    continue;
                }
                double           vol        = getVolatilityMinutly(code, date, 10);
                double           mean       = 0;
                double           marketMean = 0;
                int              seconds    = 0;
                int              dataIndex  = 0;
                int              dataSeconds;
                int              untradeVolume = totalVolume;
                List <OrderBook> orderBook     = new List <OrderBook>();
                List <TradeBook> tradeBook     = new List <TradeBook>();
                //初始化每个周期的挂单量和补单量
                int    period = totalTime / newOrderTimeInterval;
                int    orderVolumePerTimeInterval      = getVolumeOfTimeInterval(untradeVolume, period);
                int    stockNeedToTradePerTimeInterval = untradeVolume / period;
                int    oldOrderVolumePerTimeInterval   = 0;
                int    orderNeedToTrade  = 0;
                int    orderAlreadyTrade = 0;
                int    counting          = 0;
                double lastNewOrderPrice = 0;
                //逐秒进行判断成交以及策略挂单
                for (seconds = 0; seconds <= 14221; seconds++)
                {
                    DateTime time = date.Date + DataTimeStampExtension.GetStockSecondsTimeByIndex(seconds);
                    //获取市场数据部分
                    var lastTick = onTick(seconds, data);
                    if (lastTick.Bid1 == 0)
                    {
                        continue;
                    }
                    counting  += 1;
                    marketMean = (marketMean * (counting - 1) + lastTick.LastPrice) / counting;//计算市场的平均价格
                    //根据最新盘口数据调整orderbook中waitingValume字段
                    modifyOrderBookByTickData(ref orderBook, lastTick);
                    //策略挂单撤单部分
                    double newOrderPrice = getOrderPrice(newOrderPriceMode, lastTick);
                    double oldOrderPrice = getOrderPrice(oldOrderPriceMode, lastTick);
                    if (counting % newOrderTimeInterval == 1)//每个新挂单周期的第1秒进行挂单
                    {
                        orderNeedToTrade = orderNeedToTrade + stockNeedToTradePerTimeInterval;
                        if (orderVolumePerTimeInterval > 0)
                        {
                            orderId += 1;
                            double price = getOrderPrice(newOrderPriceMode, lastTick);
                            placeAnOrder(ref orderBook, lastTick, price, time, orderVolumePerTimeInterval, orderId);
                            lastNewOrderPrice = price;
                        }
                        //如果价格跳涨,单位时间内多挂1倍的单
                        if (lastNewOrderPrice > 0 && (lastTick.Ask1 / lastNewOrderPrice - 1) > 1 * vol * Math.Sqrt(newOrderTimeInterval / 60.0))
                        {
                            orderId += 1;
                            placeAnOrder(ref orderBook, lastTick, lastTick.Ask1, time, orderVolumePerTimeInterval, orderId);
                            lastNewOrderPrice = lastTick.Ask1;
                        }
                    }

                    if (counting % oldOrderTimeInterval == 5)//每个补单周期的第5秒进行补单
                    {
                        int activeOrderNumbers = getActivieOrderNumbers(orderBook);
                        int volumeNow          = (int)(Math.Round((orderNeedToTrade - orderAlreadyTrade - activeOrderNumbers) / 100.0) * 100);
                        volumeNow = Math.Min(oldOrderVolumePerTimeInterval, volumeNow);
                        if (volumeNow > 0)
                        {
                            orderId += 1;
                            double price = getOrderPrice(oldOrderPriceMode, lastTick);
                            placeAnOrder(ref orderBook, lastTick, price, time, volumeNow, orderId);
                        }
                    }


                    if (counting % cancelTimeInterval == 0) //每个撤单周期进行撤单,并计算需要补挂的单子
                    {
                        int activeOrderNumbers = getActivieOrderNumbers(orderBook);
                        cancelDeviateOrders(ref orderBook, lastTick);
                        if (orderAlreadyTrade / Convert.ToDouble(orderNeedToTrade) < tradingRate)
                        {
                            cancelPartialDeviateOrders(ref orderBook, lastTick);
                            activeOrderNumbers = getActivieOrderNumbers(orderBook);
                        }
                        //计算后续补单每次挂单量
                        int oldOrderUntrade = orderNeedToTrade - orderAlreadyTrade - activeOrderNumbers;
                        oldOrderVolumePerTimeInterval = getVolumeOfTimeInterval(oldOrderUntrade, oldOrderFrequency);
                    }
                    //判断成交部分
                    dataSeconds = DataTimeStampExtension.GetStockSecondsIndex(data[dataIndex].TransactionDateTime);
                    if (dataSeconds == seconds)
                    {
                        //根据该tick的盘口数据,进行成交判断
                        transactionSimulation(ref orderBook, ref tradeBook, data[dataIndex]);
                        //根据成交信息更新数据
                        orderAlreadyTrade = getTradedNumbers(tradeBook);
                        untradeVolume     = totalVolume - orderAlreadyTrade;
                        //移到下一个tick的数据
                        if (dataIndex + 1 < data.Count())
                        {
                            dataIndex = dataIndex + 1;
                        }
                    }
                    //输出最后的交易情况
                    if (seconds == 14220)
                    {
                        mean = getTradeAveragePrice(tradeBook);
                        int orderVolume = getOrderBookVolume(orderBook);
                        Console.WriteLine("{0}: 市场均价 {1} 成交均价 {2} 成交量 {3} 需成交 {4} 挂单 {5}", time, marketMean, mean, orderAlreadyTrade, orderNeedToTrade, orderVolume);
                    }
                }
            }
        }