public void MatchesAgainstFullPositionCollection()
        {
            // sort definitions by leg count so that we match more complex definitions first
            var options = OptionStrategyMatcherOptions.ForDefinitions(OptionStrategyDefinitions.AllDefinitions
                                                                      .OrderByDescending(definition => definition.LegCount)
                                                                      );
            var matcher   = new OptionStrategyMatcher(options);
            var positions = OptionPositionCollection.Empty.AddRange(Option.Position(Option.Underlying, +20),
                                                                    Option.Position(Option.Call[100, -4]), Option.Position(Option.Put[105, -4]),
                                                                    Option.Position(Option.Call[105, +4]), Option.Position(Option.Put[110, +4]),
                                                                    Option.Position(Option.Call[110, -3]), Option.Position(Option.Put[115, -3]),
                                                                    Option.Position(Option.Call[115, +3]), Option.Position(Option.Put[120, +3]),
                                                                    Option.Position(Option.Call[120, -5]), Option.Position(Option.Put[125, -5]),
                                                                    Option.Position(Option.Call[124, +5]), Option.Position(Option.Put[130, +5])
                                                                    );

            var match = matcher.MatchOnce(positions);

            foreach (var strategy in match.Strategies)
            {
                Console.WriteLine($"{strategy.Name}");
                foreach (var leg in strategy.OptionLegs)
                {
                    // steal OptionPosition's ToString() implementation
                    Console.Write($"\t{new OptionPosition(leg.Symbol, leg.Quantity)}");
                }
            }
        }
        public void DoesNotDoubleCountPositions()
        {
            // this test aims to verify that match solutions do not reference the same position in multiple matches
            // this behavior is different than the OptionStrategyDefinition.Match, which by design produces all possible
            // matches which permits the same position to appear in different matches, allowing the matcher to pick matches

            // this test aims to verify that we can match the same definition multiple times if positions allows
            // 0: -C110 +C105
            // 1: -C115 +C100
            var positions = OptionPositionCollection.Empty.AddRange(
                Position(Call[110], -1),
                Position(Call[115], -1),
                Position(Call[100]),
                Position(Call[105])
                );

            var matcher = new OptionStrategyMatcher(OptionStrategyMatcherOptions.ForDefinitions(BearCallSpread));
            var matches = matcher.MatchOnce(positions);

            Assert.AreEqual(2, matches.Strategies.Count);
        }
Example #3
0
        public void CoveredCall_MatchesMultipleTimes_ForEachUniqueShortCallContract()
        {
            // CoveredCall
            // 0: +1 underlying lot
            // 1: -1 Call
            // so we should match
            // (4U, -4C100)
            // (3U, -3C110)
            // (5U, -5C120)
            // (9U, -9C130)
            // (20U, -20C140)
            // OptionStrategyDefinition.Match produces ALL possible matches
            var positions = Empty.AddRange(Position(Underlying, +20),
                                           Position(Call[100], -4), Position(Put[105], -4),
                                           Position(Call[105], +4), Position(Put[110], +4),
                                           Position(Call[110], -3), Position(Put[115], -3),
                                           Position(Call[115], +3), Position(Put[120], +3),
                                           Position(Call[120], -5), Position(Put[125], -5),
                                           Position(Call[125], +5), Position(Put[130], +5),
                                           Position(Call[130], -9), Position(Put[135], -9),
                                           Position(Call[140], -21), Position(Put[145], -21)
                                           );

            // force lower strikes to be evaluated first to provide determinism for this test
            var options = OptionStrategyMatcherOptions.ForDefinitions(CoveredCall)
                          .WithPositionEnumerator(new FunctionalOptionPositionCollectionEnumerator(
                                                      pos => pos.OrderBy(p => p.IsUnderlying ? 0 : p.Strike)
                                                      ));

            var matches = CoveredCall.Match(options, positions).ToList();

            Assert.AreEqual(5, matches.Count);
            Assert.AreEqual(1, matches.Count(m => m.Multiplier == 4));
            Assert.AreEqual(1, matches.Count(m => m.Multiplier == 3));
            Assert.AreEqual(1, matches.Count(m => m.Multiplier == 5));
            Assert.AreEqual(1, matches.Count(m => m.Multiplier == 9));
            Assert.AreEqual(1, matches.Count(m => m.Multiplier == 20));
        }
 /// <summary>
 /// Creates a custom option strategy group resolver
 /// </summary>
 /// <param name="strategyMatcherOptions">The option strategy matcher options instance to use</param>
 /// <param name="securities">The algorithms securities</param>
 public OptionStrategyPositionGroupResolver(SecurityManager securities, OptionStrategyMatcherOptions strategyMatcherOptions)
 {
     _securities      = securities;
     _strategyMatcher = new OptionStrategyMatcher(strategyMatcherOptions);
 }
 /// <summary>
 /// Creates the default option strategy group resolver for <see cref="OptionStrategyDefinitions.AllDefinitions"/>
 /// </summary>
 public OptionStrategyPositionGroupResolver(SecurityManager securities)
     : this(securities, OptionStrategyMatcherOptions.ForDefinitions(OptionStrategyDefinitions.AllDefinitions))
 {
 }