/// <summary>
        /// Initializes a new instance of the <see cref="PositionManager"/> class
        /// </summary>
        /// <param name="securities">The algorithm's security manager</param>
        public PositionManager(SecurityManager securities)
        {
            _securities   = securities;
            Groups        = PositionGroupCollection.Empty;
            _defaultModel = new SecurityPositionGroupBuyingPowerModel();
            _resolver     = new CompositePositionGroupResolver(new OptionStrategyPositionGroupResolver(securities),
                                                               new SecurityPositionGroupResolver(_defaultModel));

            // we must be notified each time our holdings change, so each time a security is added, we
            // want to bind to its SecurityHolding.QuantityChanged event so we can trigger the resolver

            securities.CollectionChanged += (sender, args) =>
            {
                var items = args.NewItems ?? new List <object>();
                if (args.OldItems != null)
                {
                    foreach (var item in args.OldItems)
                    {
                        items.Add(item);
                    }
                }

                foreach (Security security in items)
                {
                    if (args.Action == NotifyCollectionChangedAction.Add)
                    {
                        security.Holdings.QuantityChanged += HoldingsOnQuantityChanged;
                        if (security.Invested)
                        {
                            // if this security has holdings then we'll need to resolve position groups
                            _requiresGroupResolution = true;
                        }
                    }
                    else if (args.Action == NotifyCollectionChangedAction.Remove)
                    {
                        security.Holdings.QuantityChanged -= HoldingsOnQuantityChanged;
                        if (security.Invested)
                        {
                            // only trigger group resolution if we had holdings in the removed security
                            _requiresGroupResolution = true;
                        }
                    }
                }
            };
        }
 /// <summary>
 /// Inserts the specified <paramref name="resolver"/> into the list of resolvers at the specified index.
 /// </summary>
 /// <param name="resolver">The resolver to be inserted</param>
 /// <param name="index">The zero based index indicating where to insert the resolver, zero inserts to the beginning
 /// of the list making this resolver un first and <see cref="Count"/> inserts the resolver to the end of the list
 /// making this resolver run last</param>
 public void Add(IPositionGroupResolver resolver, int index)
 {
     // insert handles bounds checking
     _resolvers.Insert(index, resolver);
 }
 /// <summary>
 /// Removes the specified <paramref name="resolver"/> from the list of resolvers
 /// </summary>
 /// <param name="resolver">The resolver to be removed</param>
 /// <returns>True if the resolver was removed, false if it wasn't found in the list</returns>
 public bool Remove(IPositionGroupResolver resolver)
 {
     return(_resolvers.Remove(resolver));
 }
 /// <summary>
 /// Adds the specified <paramref name="resolver"/> to the end of the list of resolvers. This resolver will run last.
 /// </summary>
 /// <param name="resolver">The resolver to be added</param>
 public void Add(IPositionGroupResolver resolver)
 {
     _resolvers.Add(resolver);
 }