/*
* 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();
}
}
}