20 using System.Collections.Generic;
49 _securities = securities;
64 IEnumerable<IPosition> positions;
65 if (currentPositions.
Count > 0)
68 var positionsToConsiderInNewGroup = impactedGroups.SelectMany(positionGroup => positionGroup.Positions);
69 positions = newPositions.Concat(positionsToConsiderInNewGroup);
73 if (newPositions.Count == 1)
79 positions = newPositions;
82 @group = GetPositionGroups(positions)
83 .Select(positionGroup =>
85 if (positionGroup.Count == 0)
90 if (newPositions.Any(position => positionGroup.TryGetPosition(position.Symbol, out position)))
111 .Where(positionGroup => positionGroup !=
null)
114 return @group !=
null;
126 var groups = GetPositionGroups(positions).ToList();
127 if (groups.Count != 0)
151 if(groups.
Count == 0)
157 var symbolsSet = positions.Where(position => position.Symbol.SecurityType.HasOptions() || position.Symbol.SecurityType.IsOption())
158 .SelectMany(position =>
160 return position.Symbol.HasUnderlying ?
new[] { position.Symbol, position.Symbol.Underlying } :
new[] { position.Symbol };
164 if (symbolsSet.Count == 0)
170 return groups.Where(group => group.Quantity != 0
171 && group.Positions.Any(position1 => symbolsSet.Contains(position1.Symbol)
172 || position1.Symbol.HasUnderlying && position1.Symbol.SecurityType.IsOption() && symbolsSet.Contains(position1.Symbol.Underlying)));
175 private IEnumerable<IPositionGroup> GetPositionGroups(IEnumerable<IPosition> positions)
177 foreach (var positionsByUnderlying
in positions
178 .Where(position => position.Symbol.SecurityType.HasOptions() || position.Symbol.SecurityType.IsOption())
179 .GroupBy(position => position.Symbol.HasUnderlying? position.Symbol.Underlying : position.Symbol)
180 .Select(x => x.ToList()))
182 var optionPosition = positionsByUnderlying.FirstOrDefault(position => position.Symbol.SecurityType.IsOption());
183 if (optionPosition ==
null)
188 var contractMultiplier = (_securities[optionPosition.Symbol].SymbolProperties as
OptionSymbolProperties)?.ContractUnitOfTrade ?? 100;
192 if (optionPositionCollection.Count == 0 && positionsByUnderlying.Count > 0)
199 var matches = _strategyMatcher.MatchOnce(optionPositionCollection);
200 if (matches.Strategies.Count == 0)
205 foreach (var matchedStrategy
in matches.Strategies)
207 var groupQuantity = Math.Abs(matchedStrategy.OptionLegs.Cast<
Leg>().Concat(matchedStrategy.UnderlyingLegs)
208 .Select(leg => leg.Quantity)
209 .GreatestCommonDivisor());
210 var positionsToGroup = matchedStrategy.OptionLegs
211 .Select(optionLeg => (IPosition)
new Position(optionLeg.Symbol, optionLeg.Quantity,
214 Math.Abs(optionLeg.Quantity) / groupQuantity))
215 .Concat(matchedStrategy.UnderlyingLegs.Select(underlyingLeg =>
new Position(underlyingLeg.Symbol,
216 underlyingLeg.Quantity * contractMultiplier,
219 (Math.Abs(underlyingLeg.Quantity) * contractMultiplier / groupQuantity))))
220 .ToDictionary(position => position.Symbol);
222 yield
return new PositionGroup(