private void OnQuoteReady(FiveLevelQuote[] quotes, string[] errors)
        {
            if (quotes == null || quotes.Length == 0)
            {
                return;
            }

            lock (_orderLockObj)
            {
                if (_activeOrders.Count == 0)
                {
                    return;
                }
            }

            for (int i = 0; i < quotes.Length; ++i)
            {
                var quote = quotes[i];

                if (quote == null)
                {
                    continue;
                }

                float maxBuyPrice    = quote.BuyPrices.Max();
                float minBuyPrice    = quote.BuyPrices.Min(v => v == 0.0f ? float.MaxValue : v);
                int   totalBuyVolume = ChinaStockHelper.ConvertHandToVolume(quote.BuyVolumesInHand.Sum());

                lock (_orderLockObj)
                {
                    List <StoplossOrder> orders;
                    if (!_activeOrders.TryGetValue(quote.SecurityCode, out orders))
                    {
                        continue;
                    }

                    // duplicate orders to avoid the "orders" object being updated in
                    // SendStoploosOrder function.
                    var duplicatedOrders = orders.ToArray();

                    foreach (var order in duplicatedOrders)
                    {
                        if (ShouldStoploss(quote, maxBuyPrice, minBuyPrice, totalBuyVolume, order))
                        {
                            SendStoplossOrder(order);
                        }
                    }
                }
            }
        }
        private bool ShouldStoploss(FiveLevelQuote quote, float maxBuyPrice, float minBuyPrice, int totalBuyVolume, StoplossOrder order)
        {
            bool shouldStoploss = false;

            if (order.StoplossPrice < minBuyPrice)
            {
                if (totalBuyVolume > order.ExistingVolume)
                {
                }
                else
                {
                    // no solution yet, need to predicate volume.
                    // TODO: predicate volume
                }
            }
            else
            {
                if (order.StoplossPrice >= maxBuyPrice)
                {
                    // need to stop loss immediately.
                    shouldStoploss = true;
                }
                else
                {
                    // order stop loss price is between minBuyPrice and maxBuyPrice
                    // we count the buy volume above stop loss price.
                    int aboveStoplossBuyVolume =
                        ChinaStockHelper.ConvertHandToVolume(
                            Enumerable
                            .Range(0, quote.BuyPrices.Length)
                            .Where(index => quote.BuyPrices[index] >= order.StoplossPrice)
                            .Sum(index => quote.BuyVolumesInHand[index]));

                    if (aboveStoplossBuyVolume <= order.ExistingVolume * 5)
                    {
                        shouldStoploss = true;
                    }
                    else
                    {
                        // there is enough buy volume now, so don't be rush.
                    }
                }
            }

            return(shouldStoploss);
        }