Lean  $LEAN_TAG$
OptionStrategyLegDefinitionMatch.cs
1 /*
2  * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
3  * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14 */
15 
16 using System;
17 
19 {
20  /// <summary>
21  /// Defines the item result type of <see cref="OptionStrategyLegDefinition.Match"/>, containing the number of
22  /// times the leg definition matched the position (<see cref="Multiplier"/>) and applicable portion of the position.
23  /// </summary>
24  public struct OptionStrategyLegDefinitionMatch : IEquatable<OptionStrategyLegDefinitionMatch>
25  {
26  /// <summary>
27  /// The number of times the definition is able to match the position. For example,
28  /// if the definition requires +2 contracts and the algorithm's position has +5
29  /// contracts, then this multiplier would equal 2.
30  /// </summary>
31  public int Multiplier { get; }
32 
33  /// <summary>
34  /// The position that was successfully matched with the total quantity matched. For example,
35  /// if the definition requires +2 contracts and this multiplier equals 2, then this position
36  /// would have a quantity of 4. This may be different than the remaining/total quantity
37  /// available in the positions collection.
38  /// </summary>
39  public OptionPosition Position { get; }
40 
41  /// <summary>
42  /// Initializes a new instance of the <see cref="OptionStrategyLegDefinitionMatch"/> struct
43  /// </summary>
44  /// <param name="multiplier">The number of times the positions matched the leg definition</param>
45  /// <param name="position">The position that matched the leg definition</param>
46  public OptionStrategyLegDefinitionMatch(int multiplier, OptionPosition position)
47  {
48  Position = position;
49  Multiplier = multiplier;
50  }
51 
52  /// <summary>
53  /// Creates the appropriate type of <see cref="OptionStrategy.LegData"/> for this matched position
54  /// </summary>
55  /// <param name="multiplier">The multiplier to use for creating the leg data. This multiplier will be
56  /// the minimum multiplier of all legs within a strategy definition match. Each leg defines its own
57  /// multiplier which is the max matches for that leg and the strategy definition's multiplier is the
58  /// min of the individual legs.</param>
60  {
61  var quantity = Position.Quantity;
62  if (Multiplier != multiplier)
63  {
64  if (multiplier > Multiplier)
65  {
66  throw new ArgumentOutOfRangeException(nameof(multiplier), "Unable to create strategy leg with a larger multiplier than matched.");
67  }
68 
69  // back out the unit quantity and scale it up to the requested multiplier
70  var unit = Position.Quantity / Multiplier;
71  quantity = unit * multiplier;
72  }
73 
74  return Position.IsUnderlying
77  }
78 
79  /// <summary>
80  /// Creates the appropriate <see cref="OptionPosition"/> for this matched position
81  /// </summary>
82  /// <param name="multiplier">The multiplier to use for creating the OptionPosition. This multiplier will be
83  /// the minimum multiplier of all legs within a strategy definition match. Each leg defines its own
84  /// multiplier which is the max matches for that leg and the strategy definition's multiplier is the
85  /// min of the individual legs.</param>
86  public OptionPosition CreateOptionPosition(int multiplier)
87  {
88  var quantity = Position.Quantity;
89  if (Multiplier != multiplier)
90  {
91  if (multiplier > Multiplier)
92  {
93  throw new ArgumentOutOfRangeException(nameof(multiplier), "Unable to create strategy leg with a larger multiplier than matched.");
94  }
95 
96  // back out the unit quantity and scale it up to the requested multiplier
97  var unit = Position.Quantity / Multiplier;
98  quantity = unit * multiplier;
99  }
100 
101  return new OptionPosition(Position.Symbol, quantity);
102  }
103 
104  /// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
105  /// <param name="other">An object to compare with this object.</param>
106  /// <returns>true if the current object is equal to the <paramref name="other" /> parameter; otherwise, false.</returns>
108  {
109  return Multiplier == other.Multiplier && Position.Equals(other.Position);
110  }
111 
112  /// <summary>Indicates whether this instance and a specified object are equal.</summary>
113  /// <param name="obj">The object to compare with the current instance. </param>
114  /// <returns>true if <paramref name="obj" /> and this instance are the same type and represent the same value; otherwise, false. </returns>
115  public override bool Equals(object obj)
116  {
117  if (ReferenceEquals(null, obj))
118  {
119  return false;
120  }
121 
123  }
124 
125  /// <summary>Returns the hash code for this instance.</summary>
126  /// <returns>A 32-bit signed integer that is the hash code for this instance.</returns>
127  public override int GetHashCode()
128  {
129  unchecked
130  {
131  return (Multiplier * 397) ^ Position.GetHashCode();
132  }
133  }
134 
135  /// <summary>Returns the fully qualified type name of this instance.</summary>
136  /// <returns>The fully qualified type name.</returns>
137  public override string ToString()
138  {
139  return $"{Multiplier} Matches|{Position}";
140  }
141 
142  /// <summary>
143  /// OptionStrategyLegDefinitionMatch == Operator
144  /// </summary>
145  /// <returns>True if they are equal</returns>
147  {
148  return left.Equals(right);
149  }
150 
151  /// <summary>
152  /// OptionStrategyLegDefinitionMatch != Operator
153  /// </summary>
154  /// <returns>True if they are not equal</returns>
156  {
157  return !left.Equals(right);
158  }
159  }
160 }