/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Linq; using System.Collections; using System.Collections.Generic; namespace QuantConnect.Securities.Positions { /// /// Provides a collection type for aimed at providing indexing for /// common operations required by the resolver implementations. /// public class PositionCollection : IEnumerable { private Dictionary _positions; /// Gets the number of elements in the collection. /// The number of elements in the collection. public int Count => _positions.Count; /// /// Initializes a new instance of the class /// /// The positions to include in this collection public PositionCollection(Dictionary positions) { _positions = positions; } /// /// Initializes a new instance of the class /// /// The positions to include in this collection public PositionCollection(IEnumerable positions) : this(positions.ToDictionary(p => p.Symbol)) { } /// /// Removes the quantities in the provided groups from this position collection. /// This should be called following has resolved /// position groups in order to update the collection of positions for the next resolver, /// if one exists. /// /// The resolved position groups /// public void Remove(IEnumerable groups) { foreach (var group in groups) { foreach (var position in group.Positions) { IPosition existing; if (!_positions.TryGetValue(position.Symbol, out existing)) { throw new InvalidOperationException($"Position with symbol {position.Symbol} not found."); } var resultingPosition = existing.Deduct(position.Quantity); // directly remove positions hows quantity is 0 if(resultingPosition.Quantity == 0) { _positions.Remove(position.Symbol); } else { _positions[position.Symbol] = resultingPosition; } } } } /// /// Clears this collection of all positions /// public void Clear() { _positions.Clear(); } /// /// Attempts to retrieve the position with the specified symbol from this collection /// /// The symbol /// The position /// True if the position is found, otherwise false public bool TryGetPosition(Symbol symbol, out IPosition position) { return _positions.TryGetValue(symbol, out position); } /// Returns an enumerator that iterates through the collection. /// An enumerator that can be used to iterate through the collection. public IEnumerator GetEnumerator() { return _positions.Values.GetEnumerator(); } /// Returns an enumerator that iterates through a collection. /// An object that can be used to iterate through the collection. IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } }