Lean  $LEAN_TAG$
OptionPortfolioModel.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 QuantConnect.Logging;
17 using QuantConnect.Orders;
18 using static QuantConnect.StringExtensions;
19 
21 {
22  /// <summary>
23  /// Provides an implementation of <see cref="ISecurityPortfolioModel"/> for options that supports
24  /// default fills as well as option exercising.
25  /// </summary>
27  {
28  /// <summary>
29  /// Performs application of an OrderEvent to the portfolio
30  /// </summary>
31  /// <param name="portfolio">The algorithm's portfolio</param>
32  /// <param name="security">Option security</param>
33  /// <param name="fill">The order event fill object to be applied</param>
34  public override void ProcessFill(SecurityPortfolioManager portfolio, Security security, OrderEvent fill)
35  {
36  var order = portfolio.Transactions.GetOrderById(fill.OrderId);
37  if (order == null)
38  {
39  Log.Error(Invariant($"OptionPortfolioModel.ProcessFill(): Unable to locate Order with id {fill.OrderId}"));
40  return;
41  }
42 
43  if (order.Type == OrderType.OptionExercise)
44  {
45  ProcessExerciseFill(portfolio, security, order, fill);
46  }
47  else
48  {
49  // we delegate the call to the base class (default behavior)
50  base.ProcessFill(portfolio, security, fill);
51  }
52  }
53 
54  /// <summary>
55  /// Processes exercise/assignment event to the portfolio
56  /// </summary>
57  /// <param name="portfolio">The algorithm's portfolio</param>
58  /// <param name="security">Option security</param>
59  /// <param name="order">The order object to be applied</param>
60  /// <param name="fill">The order event fill object to be applied</param>
61  public void ProcessExerciseFill(SecurityPortfolioManager portfolio, Security security, Order order, OrderEvent fill)
62  {
63  var exerciseOrder = (OptionExerciseOrder)order;
64  var option = (Option)portfolio.Securities[exerciseOrder.Symbol];
65  var underlying = option.Underlying;
66  var cashQuote = option.QuoteCurrency;
67  var optionQuantity = order.Quantity;
68  var processSecurity = portfolio.Securities[fill.Symbol];
69 
70  // depending on option settlement terms we either add underlying to the account or add cash equivalent
71  // we then remove the exercised contracts from our option position
72  switch (option.ExerciseSettlement)
73  {
74  case SettlementType.PhysicalDelivery:
75 
76  base.ProcessFill(portfolio, processSecurity, fill);
77  break;
78 
79  case SettlementType.Cash:
80 
81  var cashQuantity = -option.GetIntrinsicValue(underlying.Close) * option.ContractUnitOfTrade * optionQuantity;
82 
83  // we add cash equivalent to portfolio
84  option.SettlementModel.ApplyFunds(new ApplyFundsSettlementModelParameters(portfolio, option, fill.UtcTime, new CashAmount(cashQuantity, cashQuote.Symbol), fill));
85 
86  base.ProcessFill(portfolio, processSecurity, fill);
87  break;
88  }
89  }
90  }
91 }