public override void onTick(Tick <int> currTick)
        {
            lock (sObject)
            {
                try
                {
                    base.InitComment();

                    if (!this.TestingMode)
                    {
                        spreadAnalyzer.EvaluateSpread(currTick);
                    }

                    if (currTime.Ticks / (TickHistory.tickInOneMinute) == currTick.DateTime.Ticks / (TickHistory.tickInOneMinute))
                    {
                        return;
                    }
                    currTime = currTick.DateTime;

                    foreach (BuyLimitAndWaitParam cparam in customParams)
                    {
                        if (cparam.InitHistoryMinutes > 0)
                        {
                            cparam.historySimulator = new HistorySimulator(cparam, base.TestingMode, new BuyLimitAndWaitStrategy(), this.param, cparam.Symbol, this.Meta);

                            if (TestingMode)
                            {
                                cparam.StartDate = currTick.DateTime.AddMinutes(-cparam.InitHistoryMinutes);
                            }

                            List <string> logString;
                            base.AddComment(cparam.ID, string.Format("Start simulate from {0} to {1}\n", cparam.StartDate.ToShortDateString(), currTick.DateTime.ToShortDateString()));
                            IEnumerable <Order> newOrders = cparam.historySimulator.Init(currTick.DateTime, cparam.StartDate, out logString);
                            if (cparam.historySimulator.IsSuccessful)
                            {
                                base.AddComment(cparam.ID, "Simulation was successful");
                                if (TestingMode)
                                {
                                    Tick <int> currSymbolTick = new Tick <int>();
                                    currSymbolTick.Ask      = Meta.MarketInfo(cparam.Symbol, MarketInfoType.MODE_ASK);
                                    currSymbolTick.Bid      = Meta.MarketInfo(cparam.Symbol, MarketInfoType.MODE_BID);
                                    currSymbolTick.DateTime = currTick.DateTime;
                                    currSymbolTick.volume   = 1;
                                    AddOrders(currSymbolTick, newOrders.Where(p => p.Comment.StartsWith(cparam.IdentityComment)));
                                }
                            }
                            else
                            {
                                base.AddComment(cparam.ID, "History Simulator return error. Init state is not valid.\n");
                            }
                            cparam.InitHistoryMinutes = 0;
                        }
                    }

                    IEnumerable <Order> allBuyOrders  = OrderOperation.GetBuyMarketOrders();
                    IEnumerable <Order> allSellOrders = OrderOperation.GetSellMarketOrders();
                    IEnumerable <Order> allBuyLimitOrders;
                    IEnumerable <Order> allSellLimitOrders;

                    if (!TestingMode)
                    {
                        PositionAggregator pa = new PositionAggregator();

                        foreach (BuyLimitAndWaitParam cparam in customParams)
                        {
                            Tick <int> currSymbolTick = new Tick <int>();
                            currSymbolTick.Ask      = Meta.MarketInfo(cparam.Symbol, MarketInfoType.MODE_ASK);
                            currSymbolTick.Bid      = Meta.MarketInfo(cparam.Symbol, MarketInfoType.MODE_BID);
                            currSymbolTick.DateTime = currTick.DateTime;
                            currSymbolTick.volume   = 1;

                            IEnumerable <Order> requiredOrders = cparam.historySimulator.AddTick(currSymbolTick);
                            //IEnumerable<Order> openedOrders = allBuyOrders.Where(p => p.Comment.StartsWith(cparam.IdentityComment))
                            //    .Union(allSellOrders.Where(p => p.Comment.StartsWith(cparam.IdentityComment)));

                            pa.AddRequrementPosition(requiredOrders);
                            base.AddCommentLine(cparam.Symbol, string.Format("{0} - openPrices={1}, tpPrices={2}",
                                                                             currSymbolTick.DateTime.ToShortTimeString(),
                                                                             String.Join(", ", cparam.historySimulator.LimitOrders.Select(p => p.OpenPrice)),
                                                                             String.Join(", ", cparam.historySimulator.MarketOrders.Select(p => p.TP))
                                                                             ));
                        }

                        foreach (BuyLimitAndWaitParam cparam in customParams)
                        {
                            pa.CheckMinTradeVolumeSize(cparam.Symbol, cparam.MinTradeVolume);
                        }
                        pa.AddCurrentPositions(allBuyOrders);
                        pa.AddCurrentPositions(allSellOrders);

                        foreach (KeyValuePair <string, int> kv in pa.ResultDiff.Where(p => p.Value != 0))
                        {
                            Tick <int> currSymbolTick = new Tick <int>();
                            currSymbolTick.Ask      = Meta.MarketInfo(kv.Key, MarketInfoType.MODE_ASK);
                            currSymbolTick.Bid      = Meta.MarketInfo(kv.Key, MarketInfoType.MODE_BID);
                            currSymbolTick.DateTime = currTick.DateTime;
                            currSymbolTick.volume   = 1;

                            AddComment(string.Format("Adding new order for symbol {0} with volume {1}", kv.Key, kv.Value));
                            Meta.OrderSend(kv.Key, OrderType.Market, kv.Value > 0 ? OrderSide.Buy : OrderSide.Sell, Math.Abs(kv.Value),
                                           kv.Value > 0 ? currSymbolTick.Ask : currSymbolTick.Bid, 0, 0, "");
                        }

                        allBuyOrders  = OrderOperation.GetBuyMarketOrders();
                        allSellOrders = OrderOperation.GetSellMarketOrders();
                        var elem = allBuyOrders.Join(allSellOrders, bO => bO.Symbol, sO => sO.Symbol, (bO, sO) => new { t1 = bO.ID, t2 = sO.ID }).FirstOrDefault();
                        if (elem != null)
                        {
                            AddComment(string.Format("Trying to close by two orders: {0} and {1}.", elem.t1, elem.t2));
                            Meta.OrderCloseBy(elem.t1, elem.t2, 0);
                            AddComment(string.Format("Successfull close by two orders: {0} and {1}.", elem.t1, elem.t2));
                        }
                        return;
                    }


                    BuyLimitAndWaitParam firstParam = customParams[0];

                    RemoveAllLimitWithoutPair(OrderOperation.GetBuyLimitOrders(), OrderOperation.GetSellLimitOrders(),
                                              firstParam, currTick);

                    allBuyLimitOrders  = OrderOperation.GetBuyLimitOrders();
                    allSellLimitOrders = OrderOperation.GetSellLimitOrders();

                    Order minBuyOrder  = null;
                    Order maxSellOrder = null;
                    if (allBuyOrders != null)
                    {
                        minBuyOrder = allBuyOrders
                                      .Where(p => p.Comment.StartsWith(firstParam.IdentityComment))
                                      //.MinElement(p => p.OpenPrice);
                                      .MinElement(p => p.TP);
                    }
                    if (allSellOrders != null)
                    {
                        maxSellOrder = allSellOrders
                                       .Where(p => p.Comment.StartsWith(firstParam.IdentityComment))
                                       //.MaxElement(p => p.OpenPrice);
                                       .MaxElement(p => p.TP);
                    }

                    bool isLimitExist = allSellLimitOrders.Where(p => p.Comment.StartsWith(firstParam.IdentityComment)).Count() != 0 ||
                                        allBuyLimitOrders.Where(p => p.Comment.StartsWith(firstParam.IdentityComment)).Count() != 0;

                    if (this.TestingMode && minBuyOrder != null && !isLimitExist)
                    {
                        RegisterTickToHandle.RegisterBuyLimit((minBuyOrder.TP - 2 * firstParam.TP) - firstParam.OpenOrderShift);
                    }
                    if (this.TestingMode && maxSellOrder != null && !isLimitExist)
                    {
                        RegisterTickToHandle.RegisterSellLimit(firstParam.OpenOrderShift + (maxSellOrder.TP + 2 * firstParam.TP));
                    }

                    if (!isLimitExist &&
                        //(minBuyOrder != null && minBuyOrder.OpenPrice - currSymbolTick.Ask > firstParam.OpenOrderShift
                        //|| maxSellOrder != null && currSymbolTick.Bid - maxSellOrder.OpenPrice > firstParam.OpenOrderShift
                        (minBuyOrder != null && (minBuyOrder.TP - 2 * firstParam.TP) - currTick.Ask >= firstParam.OpenOrderShift ||
                         maxSellOrder != null && currTick.Bid - (maxSellOrder.TP + 2 * firstParam.TP) >= firstParam.OpenOrderShift ||
                         minBuyOrder == null && maxSellOrder == null)
                        )
                    {
                        string comment   = firstParam.NewUniqueComment();
                        int    openPrice = currTick.Ask - firstParam.TP;
                        if (firstParam.OpenMode != OpenMode.OnlySell &&
                            (minBuyOrder == null || (minBuyOrder.TP - 2 * firstParam.TP) - openPrice >= firstParam.OpenOrderShift))
                        {
                            int buyOrderID = Meta.OrderSend(firstParam.Symbol, OrderType.Limit, OrderSide.Buy, firstParam.BasicVolume, openPrice, 0, openPrice + 2 * firstParam.TP, comment);
                            if (buyOrderID <= 0)
                            {
                                Meta.Print(string.Format("Error of adding buy order. Price = {0} Symbol = {1}", openPrice, firstParam.Symbol));
                                Meta.Comment(string.Format("Error of adding buy order. Price = {0} Symbol = {1}", openPrice, firstParam.Symbol));
                                return;
                            }
                            this.RegisterTickToHandle.RegisterBuyStop(openPrice + 2 * firstParam.TP);
                        }

                        openPrice = currTick.Bid + firstParam.TP;
                        if (firstParam.OpenMode != OpenMode.OnlyBuy &&
                            (maxSellOrder == null || openPrice - (maxSellOrder.TP + 2 * firstParam.TP) >= firstParam.OpenOrderShift))
                        {
                            int sellOrderID = Meta.OrderSend(firstParam.Symbol, OrderType.Limit, OrderSide.Sell, firstParam.BasicVolume, openPrice, 0, openPrice - 2 * firstParam.TP, comment);
                            if (sellOrderID <= 0)
                            {
                                Meta.Print(string.Format("Error of adding sell order. Price = {0} Symbol = {1}", openPrice, firstParam.Symbol));
                                Meta.Comment(string.Format("Error of adding sell order. Price = {0} Symbol = {1}", openPrice, firstParam.Symbol));
                            }
                            this.RegisterTickToHandle.RegisterSellStop(openPrice - 2 * firstParam.TP);
                        }
                    }
                }
                catch (HistoryNotAvailableExceptions exc)
                {
                    logger.AddMessage("tick = {0}\r\n {1}", currTick.DateTime.ToLongTimeString(), exc);
                    throw;
                }
                finally
                {
                    ShowComment();
                }
            }
        }