/*
* 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;
namespace QuantConnect.Securities.Option.StrategyMatcher
{
///
/// Defines the item result type of , containing the number of
/// times the leg definition matched the position () and applicable portion of the position.
///
public struct OptionStrategyLegDefinitionMatch : IEquatable
{
///
/// The number of times the definition is able to match the position. For example,
/// if the definition requires +2 contracts and the algorithm's position has +5
/// contracts, then this multiplier would equal 2.
///
public int Multiplier { get; }
///
/// The position that was successfully matched with the total quantity matched. For example,
/// if the definition requires +2 contracts and this multiplier equals 2, then this position
/// would have a quantity of 4. This may be different than the remaining/total quantity
/// available in the positions collection.
///
public OptionPosition Position { get; }
///
/// Initializes a new instance of the struct
///
/// The number of times the positions matched the leg definition
/// The position that matched the leg definition
public OptionStrategyLegDefinitionMatch(int multiplier, OptionPosition position)
{
Position = position;
Multiplier = multiplier;
}
///
/// Creates the appropriate type of for this matched position
///
/// The multiplier to use for creating the leg data. This multiplier will be
/// the minimum multiplier of all legs within a strategy definition match. Each leg defines its own
/// multiplier which is the max matches for that leg and the strategy definition's multiplier is the
/// min of the individual legs.
public OptionStrategy.LegData CreateOptionStrategyLeg(int multiplier)
{
var quantity = Position.Quantity;
if (Multiplier != multiplier)
{
if (multiplier > Multiplier)
{
throw new ArgumentOutOfRangeException(nameof(multiplier), "Unable to create strategy leg with a larger multiplier than matched.");
}
// back out the unit quantity and scale it up to the requested multiplier
var unit = Position.Quantity / Multiplier;
quantity = unit * multiplier;
}
return Position.IsUnderlying
? (OptionStrategy.LegData) OptionStrategy.UnderlyingLegData.Create(quantity, Position.Symbol)
: OptionStrategy.OptionLegData.Create(quantity, Position.Symbol);
}
///
/// Creates the appropriate for this matched position
///
/// The multiplier to use for creating the OptionPosition. This multiplier will be
/// the minimum multiplier of all legs within a strategy definition match. Each leg defines its own
/// multiplier which is the max matches for that leg and the strategy definition's multiplier is the
/// min of the individual legs.
public OptionPosition CreateOptionPosition(int multiplier)
{
var quantity = Position.Quantity;
if (Multiplier != multiplier)
{
if (multiplier > Multiplier)
{
throw new ArgumentOutOfRangeException(nameof(multiplier), "Unable to create strategy leg with a larger multiplier than matched.");
}
// back out the unit quantity and scale it up to the requested multiplier
var unit = Position.Quantity / Multiplier;
quantity = unit * multiplier;
}
return new OptionPosition(Position.Symbol, quantity);
}
/// Indicates whether the current object is equal to another object of the same type.
/// An object to compare with this object.
/// true if the current object is equal to the parameter; otherwise, false.
public bool Equals(OptionStrategyLegDefinitionMatch other)
{
return Multiplier == other.Multiplier && Position.Equals(other.Position);
}
/// Indicates whether this instance and a specified object are equal.
/// The object to compare with the current instance.
/// true if and this instance are the same type and represent the same value; otherwise, false.
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
return obj is OptionStrategyLegDefinitionMatch && Equals((OptionStrategyLegDefinitionMatch) obj);
}
/// Returns the hash code for this instance.
/// A 32-bit signed integer that is the hash code for this instance.
public override int GetHashCode()
{
unchecked
{
return (Multiplier * 397) ^ Position.GetHashCode();
}
}
/// Returns the fully qualified type name of this instance.
/// The fully qualified type name.
public override string ToString()
{
return $"{Multiplier} Matches|{Position}";
}
///
/// OptionStrategyLegDefinitionMatch == Operator
///
/// True if they are equal
public static bool operator ==(OptionStrategyLegDefinitionMatch left, OptionStrategyLegDefinitionMatch right)
{
return left.Equals(right);
}
///
/// OptionStrategyLegDefinitionMatch != Operator
///
/// True if they are not equal
public static bool operator !=(OptionStrategyLegDefinitionMatch left, OptionStrategyLegDefinitionMatch right)
{
return !left.Equals(right);
}
}
}