Example #1
0
        /// <summary>
        /// removes the level from the specified side's excess level
        /// </summary>
        /// <returns></returns>
        private bool RemoveLevelFromExcess(DepthLevelMap depthLevelMap, DepthLevel[] sideLevels)
        {
            if (depthLevelMap.Any())
            {
                sideLevels.Last().UpdatePrice(depthLevelMap.First().Value.Price);
                sideLevels.Last().UpdateVolume(depthLevelMap.First().Value.AggregatedVolume);
                sideLevels.Last().UpdateOrderCount(depthLevelMap.First().Value.OrderCount);
                sideLevels.Last().ChangeExcessStatus(false);

                depthLevelMap.RemoveLevel(depthLevelMap.First().Value.Price);
                return(true);
            }
            return(false);
        }
Example #2
0
        /// <summary>
        /// Erase the specified level from the Depth Levels
        /// </summary>
        /// <param name="inboundLevel"> </param>
        /// <param name="orderSide"></param>
        /// <returns></returns>
        public bool EraseLevel(DepthLevel inboundLevel, OrderSide orderSide)
        {
            // Specifies the last element with a non-null price in the current side Depthlevel array
            bool isLastLevel = orderSide == OrderSide.Buy ? (
                // If the provided level is the last non-null price level
                inboundLevel == FindLastLevel(_bidLevels) &&
                // If the last non-null price level is the last slot in the array
                FindLastLevel(_bidLevels) == _bidLevels.Last())
                                                             :
                               // If the provided level is the last non-null price level
                               (inboundLevel == FindLastLevel(_askLevels) &&
                               // If the last non-null price level is the last slot in the array
                                FindLastLevel(_askLevels) == _askLevels.Last());

            // If the level lies in the excess levels
            if (inboundLevel.IsExcess)
            {
                switch (orderSide)
                {
                case OrderSide.Buy:
                    _bidExcessLevels.RemoveLevel(inboundLevel.Price);
                    return(true);

                case OrderSide.Sell:
                    _askExcessLevels.RemoveLevel(inboundLevel.Price);
                    return(true);
                }
            }
            // Otherwise, remove the level from the current slot and move all other levels to one slot back
            else
            {
                DepthLevel   lastSideLevel = orderSide == OrderSide.Buy ? _bidLevels.Last() : _askLevels.Last();
                DepthLevel[] sideLevels    = orderSide == OrderSide.Buy ? _bidLevels : _askLevels;

                int backEndLevelIndex = Array.FindIndex(sideLevels, depthLevel => depthLevel == lastSideLevel);
                int inboundLevelIndex = Array.FindIndex(sideLevels, depthLevel => depthLevel == inboundLevel);
                int currentLevelIndex = inboundLevelIndex;

                ++_lastChangeId;

                if (currentLevelIndex >= 0)
                {
                    // Move from the current level to the last
                    while (currentLevelIndex < backEndLevelIndex)
                    {
                        // In the first loop, currentLevelIndex starts from the level which is being removed, inboundLevelIndex
                        // so we make every value null
                        if (currentLevelIndex == inboundLevelIndex)
                        {
                            sideLevels[currentLevelIndex].UpdatePrice(null);
                            sideLevels[currentLevelIndex].UpdateVolume(null);
                            sideLevels[currentLevelIndex].UpdateOrderCount(0);
                            sideLevels[currentLevelIndex].ChangeExcessStatus(false);
                        }
                        sideLevels[currentLevelIndex] = sideLevels[currentLevelIndex + 1];
                        UpdateLevelIndex(sideLevels, currentLevelIndex, currentLevelIndex + 1);
                        sideLevels[currentLevelIndex].LastChange(new ChangeId(_lastChangeId));

                        currentLevelIndex++;
                    }
                    // The last element after the loop is done will be the same as the second last one as the slots have been
                    // shifted back. So we remove this level as this is the duplicate of the level before it
                    sideLevels[currentLevelIndex] = new DepthLevel(null);

                    if (isLastLevel || sideLevels.Last().Price == null || sideLevels.Last().Price.Value == 0)
                    {
                        if (orderSide == OrderSide.Buy &&
                            (isLastLevel || sideLevels.Last().Price == null || sideLevels.Last().Price.Value == 0))
                        {
                            RemoveLevelFromExcess(_bidExcessLevels, _bidLevels);
                        }
                        else if (orderSide == OrderSide.Sell &&
                                 (isLastLevel || sideLevels.Last().Price == null || sideLevels.Last().Price.Value == 0))
                        {
                            RemoveLevelFromExcess(_askExcessLevels, _askLevels);
                        }
                        else
                        {
                            sideLevels[currentLevelIndex].LastChange(new ChangeId(_lastChangeId));
                        }
                    }
                    sideLevels[currentLevelIndex].LastChange(new ChangeId(_lastChangeId));
                    return(true);
                }
            }
            return(false);
        }