Lean  $LEAN_TAG$
PortfolioState.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 
17 using System;
18 using System.Linq;
19 using Newtonsoft.Json;
20 using QuantConnect.Logging;
22 using System.Collections.Generic;
23 
25 {
26  /// <summary>
27  /// Snapshot of an algorithms portfolio state
28  /// </summary>
29  public class PortfolioState
30  {
31  /// <summary>
32  /// Utc time this portfolio snapshot was taken
33  /// </summary>
34  public DateTime Time { get; set; }
35 
36  /// <summary>
37  /// The current total portfolio value
38  /// </summary>
39  public decimal TotalPortfolioValue { get; set; }
40 
41  /// <summary>
42  /// The margin used
43  /// </summary>
44  public decimal TotalMarginUsed { get; set; }
45 
46  /// <summary>
47  /// The different positions groups
48  /// </summary>
49  [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
50  public List<PositionGroupState> PositionGroups { get; set; }
51 
52  /// <summary>
53  /// Gets the cash book that keeps track of all currency holdings (only settled cash)
54  /// </summary>
55  [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
56  public Dictionary<string, Cash> CashBook { get; set; }
57 
58  /// <summary>
59  /// Gets the cash book that keeps track of all currency holdings (only unsettled cash)
60  /// </summary>
61  [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
62  public Dictionary<string, Cash> UnsettledCashBook { get; set; }
63 
64  /// <summary>
65  /// Helper method to create the portfolio state snapshot
66  /// </summary>
67  public static PortfolioState Create(SecurityPortfolioManager portfolioManager, DateTime utcNow, decimal currentPortfolioValue)
68  {
69  try
70  {
71  var totalMarginUsed = 0m;
72  var positionGroups = new List<PositionGroupState>(portfolioManager.Positions.Groups.Count);
73  foreach (var group in portfolioManager.Positions.Groups)
74  {
75  var buyingPowerForPositionGroup = group.BuyingPowerModel.GetReservedBuyingPowerForPositionGroup(portfolioManager, group);
76 
77  var positionGroupState = new PositionGroupState
78  {
79  MarginUsed = buyingPowerForPositionGroup,
80  Positions = group.Positions.ToList()
81  };
82  if (currentPortfolioValue != 0)
83  {
84  positionGroupState.PortfolioValuePercentage = (buyingPowerForPositionGroup / currentPortfolioValue).RoundToSignificantDigits(4);
85  }
86 
87  positionGroups.Add(positionGroupState);
88  totalMarginUsed += buyingPowerForPositionGroup;
89  }
90 
91  var result = new PortfolioState
92  {
93  Time = utcNow,
94  TotalPortfolioValue = currentPortfolioValue,
95  TotalMarginUsed = totalMarginUsed,
96  CashBook = portfolioManager.CashBook.Where(pair => pair.Value.Amount != 0).ToDictionary(pair => pair.Key, pair => pair.Value)
97  };
98 
99  var unsettledCashBook = portfolioManager.UnsettledCashBook
100  .Where(pair => pair.Value.Amount != 0)
101  .ToDictionary(pair => pair.Key, pair => pair.Value);
102  if (positionGroups.Count > 0)
103  {
104  result.PositionGroups = positionGroups;
105  }
106  if (unsettledCashBook.Count > 0)
107  {
108  result.UnsettledCashBook = unsettledCashBook;
109  }
110  return result;
111  }
112  catch (Exception e)
113  {
114  Log.Error(e);
115  return null;
116  }
117  }
118  }
119 
120  /// <summary>
121  /// Snapshot of a position group state
122  /// </summary>
123  public class PositionGroupState
124  {
125  /// <summary>
126  /// Name of this position group
127  /// </summary>
128  [JsonIgnore]
129  public string Name { get; set; }
130 
131  /// <summary>
132  /// Currently margin used
133  /// </summary>
134  public decimal MarginUsed { get; set; }
135 
136  /// <summary>
137  /// The margin used by this position in relation to the total portfolio value
138  /// </summary>
139  public decimal PortfolioValuePercentage { get; set; }
140 
141  /// <summary>
142  /// The positions which compose this group
143  /// </summary>
144  public List<IPosition> Positions { get; set; }
145  }
146 }