Lean  $LEAN_TAG$
NotifiedSecurityChanges.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 using System.Collections.Generic;
20 using QuantConnect.Util;
21 
23 {
24  /// <summary>
25  /// Provides convenience methods for updating collections in responses to securities changed events
26  /// </summary>
27  public static class NotifiedSecurityChanges
28  {
29  /// <summary>
30  /// Adds and removes the security changes to/from the collection
31  /// </summary>
32  /// <param name="securities">The securities collection to be updated with the changes</param>
33  /// <param name="changes">The changes to be applied to the securities collection</param>
34  public static void UpdateCollection(ICollection<Security> securities, SecurityChanges changes)
35  {
36  Update(changes, securities.Add, removed => securities.Remove(removed));
37  }
38 
39  /// <summary>
40  /// Adds and removes the security changes to/from the collection
41  /// </summary>
42  /// <param name="securities">The securities collection to be updated with the changes</param>
43  /// <param name="changes">The changes to be applied to the securities collection</param>
44  /// <param name="valueFactory">Delegate used to create instances of <typeparamref name="TValue"/> from a <see cref="Security"/> object</param>
45  public static void UpdateCollection<TValue>(ICollection<TValue> securities, SecurityChanges changes, Func<Security, TValue> valueFactory)
46  {
47  Update(changes, added => securities.Add(valueFactory(added)), removed => securities.Remove(valueFactory(removed)));
48  }
49 
50  /// <summary>
51  /// Adds and removes the security changes to/from the collection
52  /// </summary>
53  /// <param name="dictionary">The securities collection to be updated with the changes</param>
54  /// <param name="changes">The changes to be applied to the securities collection</param>
55  /// <param name="valueFactory">Factory for creating dictonary values for a key</param>
56  public static void UpdateDictionary<TValue>(
57  IDictionary<Security, TValue> dictionary,
58  SecurityChanges changes,
59  Func<Security, TValue> valueFactory
60  )
61  {
62  UpdateDictionary(dictionary, changes, security => security, valueFactory);
63  }
64 
65  /// <summary>
66  /// Adds and removes the security changes to/from the collection
67  /// </summary>
68  /// <param name="dictionary">The securities collection to be updated with the changes</param>
69  /// <param name="changes">The changes to be applied to the securities collection</param>
70  /// <param name="valueFactory">Factory for creating dictonary values for a key</param>
71  public static void UpdateDictionary<TValue>(
72  IDictionary<Symbol, TValue> dictionary,
73  SecurityChanges changes,
74  Func<Security, TValue> valueFactory
75  )
76  {
77  UpdateDictionary(dictionary, changes, security => security.Symbol, valueFactory);
78  }
79 
80  /// <summary>
81  /// Most generic form of <see cref="UpdateCollection"/>
82  /// </summary>
83  /// <typeparam name="TKey">The dictionary's key type</typeparam>
84  /// <typeparam name="TValue">The dictionary's value type</typeparam>
85  /// <param name="dictionary">The dictionary to update</param>
86  /// <param name="changes">The <seealso cref="SecurityChanges"/> to apply to the dictionary</param>
87  /// <param name="keyFactory">Selector pulling <typeparamref name="TKey"/> from a <seealso cref="Security"/></param>
88  /// <param name="valueFactory">Selector pulling <typeparamref name="TValue"/> from a <seealso cref="Security"/></param>
89  public static void UpdateDictionary<TKey, TValue>(
90  IDictionary<TKey, TValue> dictionary,
91  SecurityChanges changes,
92  Func<Security, TKey> keyFactory,
93  Func<Security, TValue> valueFactory
94  )
95  {
96  Update(changes,
97  added => dictionary.Add(keyFactory(added), valueFactory(added)),
98  removed =>
99  {
100  var key = keyFactory(removed);
101  var entry = dictionary[key];
102  dictionary.Remove(key);
103 
104  // give the entry a chance to clean up after itself
105  var disposable = entry as IDisposable;
106  disposable.DisposeSafely();
107  });
108  }
109 
110  /// <summary>
111  /// Invokes the provided <paramref name="add"/> and <paramref name="remove"/> functions for each
112  /// </summary>
113  /// <param name="changes">The security changes to process</param>
114  /// <param name="add">Function called for each added security</param>
115  /// <param name="remove">Function called for each removed security</param>
116  public static void Update(SecurityChanges changes, Action<Security> add, Action<Security> remove)
117  {
118  foreach (var added in changes.AddedSecurities)
119  {
120  add(added);
121  }
122  foreach (var removed in changes.RemovedSecurities)
123  {
124  remove(removed);
125  }
126  }
127  }
128 }