forked from QuantConnect/Lean
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathQCAlgorithm.Universe.cs
More file actions
384 lines (353 loc) · 22.3 KB
/
Copy pathQCAlgorithm.Universe.cs
File metadata and controls
384 lines (353 loc) · 22.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
/*
* 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;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.Fundamental;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Securities;
using QuantConnect.Util;
namespace QuantConnect.Algorithm
{
public partial class QCAlgorithm
{
/// <summary>
/// Gets universe manager which holds universes keyed by their symbol
/// </summary>
public UniverseManager UniverseManager
{
get;
private set;
}
/// <summary>
/// Gets the universe settings to be used when adding securities via universe selection
/// </summary>
public UniverseSettings UniverseSettings
{
get;
private set;
}
/// <summary>
/// Gets a helper that provides pre-defined universe defintions, such as top dollar volume
/// </summary>
public UniverseDefinitions Universe
{
get;
private set;
}
/// <summary>
/// Adds the universe to the algorithm
/// </summary>
/// <param name="universe">The universe to be added</param>
public void AddUniverse(Universe universe)
{
UniverseManager.Add(universe.Configuration.Symbol, universe);
}
/// <summary>
/// Creates a new universe and adds it to the algorithm. This will use the default universe settings
/// specified via the <see cref="UniverseSettings"/> property. This universe will use the defaults
/// of SecurityType.Equity, Resolution.Daily, Market.USA, and UniverseSettings
/// </summary>
/// <typeparam name="T">The data type</typeparam>
/// <param name="name">A unique name for this universe</param>
/// <param name="selector">Function delegate that performs selection on the universe data</param>
public void AddUniverse<T>(string name, Func<IEnumerable<T>, IEnumerable<Symbol>> selector)
{
AddUniverse(SecurityType.Equity, name, Resolution.Daily, Market.USA, UniverseSettings, selector);
}
/// <summary>
/// Creates a new universe and adds it to the algorithm. This will use the default universe settings
/// specified via the <see cref="UniverseSettings"/> property. This universe will use the defaults
/// of SecurityType.Equity, Resolution.Daily, Market.USA, and UniverseSettings
/// </summary>
/// <typeparam name="T">The data type</typeparam>
/// <param name="name">A unique name for this universe</param>
/// <param name="selector">Function delegate that performs selection on the universe data</param>
public void AddUniverse<T>(string name, Func<IEnumerable<T>, IEnumerable<string>> selector)
{
AddUniverse(SecurityType.Equity, name, Resolution.Daily, Market.USA, UniverseSettings, selector);
}
/// <summary>
/// Creates a new universe and adds it to the algorithm. This will use the default universe settings
/// specified via the <see cref="UniverseSettings"/> property. This universe will use the defaults
/// of SecurityType.Equity, Resolution.Daily, and Market.USA
/// </summary>
/// <typeparam name="T">The data type</typeparam>
/// <param name="name">A unique name for this universe</param>
/// <param name="universeSettings">The settings used for securities added by this universe</param>
/// <param name="selector">Function delegate that performs selection on the universe data</param>
public void AddUniverse<T>(string name, UniverseSettings universeSettings, Func<IEnumerable<T>, IEnumerable<Symbol>> selector)
{
AddUniverse(SecurityType.Equity, name, Resolution.Daily, Market.USA, universeSettings, selector);
}
/// <summary>
/// Creates a new universe and adds it to the algorithm. This will use the default universe settings
/// specified via the <see cref="UniverseSettings"/> property. This universe will use the defaults
/// of SecurityType.Equity, Resolution.Daily, and Market.USA
/// </summary>
/// <typeparam name="T">The data type</typeparam>
/// <param name="name">A unique name for this universe</param>
/// <param name="universeSettings">The settings used for securities added by this universe</param>
/// <param name="selector">Function delegate that performs selection on the universe data</param>
public void AddUniverse<T>(string name, UniverseSettings universeSettings, Func<IEnumerable<T>, IEnumerable<string>> selector)
{
AddUniverse(SecurityType.Equity, name, Resolution.Daily, Market.USA, universeSettings, selector);
}
/// <summary>
/// Creates a new universe and adds it to the algorithm. This will use the default universe settings
/// specified via the <see cref="UniverseSettings"/> property. This universe will use the defaults
/// of SecurityType.Equity, Market.USA and UniverseSettings
/// </summary>
/// <typeparam name="T">The data type</typeparam>
/// <param name="name">A unique name for this universe</param>
/// <param name="resolution">The epected resolution of the universe data</param>
/// <param name="selector">Function delegate that performs selection on the universe data</param>
public void AddUniverse<T>(string name, Resolution resolution, Func<IEnumerable<T>, IEnumerable<Symbol>> selector)
{
AddUniverse(SecurityType.Equity, name, resolution, Market.USA, UniverseSettings, selector);
}
/// <summary>
/// Creates a new universe and adds it to the algorithm. This will use the default universe settings
/// specified via the <see cref="UniverseSettings"/> property. This universe will use the defaults
/// of SecurityType.Equity, Market.USA and UniverseSettings
/// </summary>
/// <typeparam name="T">The data type</typeparam>
/// <param name="name">A unique name for this universe</param>
/// <param name="resolution">The epected resolution of the universe data</param>
/// <param name="selector">Function delegate that performs selection on the universe data</param>
public void AddUniverse<T>(string name, Resolution resolution, Func<IEnumerable<T>, IEnumerable<string>> selector)
{
AddUniverse(SecurityType.Equity, name, resolution, Market.USA, UniverseSettings, selector);
}
/// <summary>
/// Creates a new universe and adds it to the algorithm. This will use the default universe settings
/// specified via the <see cref="UniverseSettings"/> property. This universe will use the defaults
/// of SecurityType.Equity, and Market.USA
/// </summary>
/// <typeparam name="T">The data type</typeparam>
/// <param name="name">A unique name for this universe</param>
/// <param name="resolution">The epected resolution of the universe data</param>
/// <param name="universeSettings">The settings used for securities added by this universe</param>
/// <param name="selector">Function delegate that performs selection on the universe data</param>
public void AddUniverse<T>(string name, Resolution resolution, UniverseSettings universeSettings, Func<IEnumerable<T>, IEnumerable<Symbol>> selector)
{
AddUniverse(SecurityType.Equity, name, resolution, Market.USA, universeSettings, selector);
}
/// <summary>
/// Creates a new universe and adds it to the algorithm. This will use the default universe settings
/// specified via the <see cref="UniverseSettings"/> property. This universe will use the defaults
/// of SecurityType.Equity, and Market.USA
/// </summary>
/// <typeparam name="T">The data type</typeparam>
/// <param name="name">A unique name for this universe</param>
/// <param name="resolution">The epected resolution of the universe data</param>
/// <param name="universeSettings">The settings used for securities added by this universe</param>
/// <param name="selector">Function delegate that performs selection on the universe data</param>
public void AddUniverse<T>(string name, Resolution resolution, UniverseSettings universeSettings, Func<IEnumerable<T>, IEnumerable<string>> selector)
{
AddUniverse(SecurityType.Equity, name, resolution, Market.USA, universeSettings, selector);
}
/// <summary>
/// Creates a new universe and adds it to the algorithm. This will use the default universe settings
/// specified via the <see cref="UniverseSettings"/> property.
/// </summary>
/// <typeparam name="T">The data type</typeparam>
/// <param name="securityType">The security type the universe produces</param>
/// <param name="name">A unique name for this universe</param>
/// <param name="resolution">The epected resolution of the universe data</param>
/// <param name="market">The market for selected symbols</param>
/// <param name="selector">Function delegate that performs selection on the universe data</param>
public void AddUniverse<T>(SecurityType securityType, string name, Resolution resolution, string market, Func<IEnumerable<T>, IEnumerable<Symbol>> selector)
{
AddUniverse(securityType, name, resolution, market, UniverseSettings, selector);
}
/// <summary>
/// Creates a new universe and adds it to the algorithm. This will use the default universe settings
/// specified via the <see cref="UniverseSettings"/> property.
/// </summary>
/// <typeparam name="T">The data type</typeparam>
/// <param name="securityType">The security type the universe produces</param>
/// <param name="name">A unique name for this universe</param>
/// <param name="resolution">The epected resolution of the universe data</param>
/// <param name="market">The market for selected symbols</param>
/// <param name="selector">Function delegate that performs selection on the universe data</param>
public void AddUniverse<T>(SecurityType securityType, string name, Resolution resolution, string market, Func<IEnumerable<T>, IEnumerable<string>> selector)
{
AddUniverse(securityType, name, resolution, market, UniverseSettings, selector);
}
/// <summary>
/// Creates a new universe and adds it to the algorithm
/// </summary>
/// <typeparam name="T">The data type</typeparam>
/// <param name="securityType">The security type the universe produces</param>
/// <param name="name">A unique name for this universe</param>
/// <param name="resolution">The epected resolution of the universe data</param>
/// <param name="market">The market for selected symbols</param>
/// <param name="universeSettings">The subscription settings to use for newly created subscriptions</param>
/// <param name="selector">Function delegate that performs selection on the universe data</param>
public void AddUniverse<T>(SecurityType securityType, string name, Resolution resolution, string market, UniverseSettings universeSettings, Func<IEnumerable<T>, IEnumerable<Symbol>> selector)
{
var marketHoursDbEntry = MarketHoursDatabase.GetEntry(market, name, securityType);
var dataTimeZone = marketHoursDbEntry.DataTimeZone;
var exchangeTimeZone = marketHoursDbEntry.ExchangeHours.TimeZone;
var symbol = QuantConnect.Symbol.Create(name, securityType, market);
var config = new SubscriptionDataConfig(typeof(T), symbol, resolution, dataTimeZone, exchangeTimeZone, false, false, true, true, isFilteredSubscription: false);
AddUniverse(new FuncUniverse(config, universeSettings, SecurityInitializer, d => selector(d.OfType<T>())));
}
/// <summary>
/// Creates a new universe and adds it to the algorithm
/// </summary>
/// <typeparam name="T">The data type</typeparam>
/// <param name="securityType">The security type the universe produces</param>
/// <param name="name">A unique name for this universe</param>
/// <param name="resolution">The epected resolution of the universe data</param>
/// <param name="market">The market for selected symbols</param>
/// <param name="universeSettings">The subscription settings to use for newly created subscriptions</param>
/// <param name="selector">Function delegate that performs selection on the universe data</param>
public void AddUniverse<T>(SecurityType securityType, string name, Resolution resolution, string market, UniverseSettings universeSettings, Func<IEnumerable<T>, IEnumerable<string>> selector)
{
var marketHoursDbEntry = MarketHoursDatabase.GetEntry(market, name, securityType);
var dataTimeZone = marketHoursDbEntry.DataTimeZone;
var exchangeTimeZone = marketHoursDbEntry.ExchangeHours.TimeZone;
var symbol = QuantConnect.Symbol.Create(name, securityType, market);
var config = new SubscriptionDataConfig(typeof(T), symbol, resolution, dataTimeZone, exchangeTimeZone, false, false, true, true, isFilteredSubscription: false);
AddUniverse(new FuncUniverse(config, universeSettings, SecurityInitializer, d => selector(d.OfType<T>()).Select(x => QuantConnect.Symbol.Create(x, securityType, market))));
}
/// <summary>
/// Creates a new universe and adds it to the algorithm. This is for coarse fundamental US Equity data and
/// will be executed on day changes in the NewYork time zone (<see cref="TimeZones.NewYork"/>
/// </summary>
/// <param name="selector">Defines an initial coarse selection</param>
public void AddUniverse(Func<IEnumerable<CoarseFundamental>, IEnumerable<Symbol>> selector)
{
AddUniverse(new CoarseFundamentalUniverse(UniverseSettings, SecurityInitializer, selector));
}
/// <summary>
/// Creates a new universe and adds it to the algorithm. This is for coarse and fine fundamental US Equity data and
/// will be executed on day changes in the NewYork time zone (<see cref="TimeZones.NewYork"/>
/// </summary>
/// <param name="coarseSelector">Defines an initial coarse selection</param>
/// <param name="fineSelector">Defines a more detailed selection with access to more data</param>
public void AddUniverse(Func<IEnumerable<CoarseFundamental>, IEnumerable<Symbol>> coarseSelector, Func<IEnumerable<FineFundamental>, IEnumerable<Symbol>> fineSelector)
{
var coarse = new CoarseFundamentalUniverse(UniverseSettings, SecurityInitializer, coarseSelector);
AddUniverse(new FineFundamentalFilteredUniverse(coarse, fineSelector));
}
/// <summary>
/// Creates a new universe and adds it to the algorithm. This is for fine fundamental US Equity data and
/// will be executed on day changes in the NewYork time zone (<see cref="TimeZones.NewYork"/>
/// </summary>
/// <param name="universe">The universe to be filtered with fine fundamental selection</param>
/// <param name="fineSelector">Defines a more detailed selection with access to more data</param>
public void AddUniverse(Universe universe, Func<IEnumerable<FineFundamental>, IEnumerable<Symbol>> fineSelector)
{
AddUniverse(new FineFundamentalFilteredUniverse(universe, fineSelector));
}
/// <summary>
/// Creates a new universe and adds it to the algorithm. This can be used to return a list of string
/// symbols retrieved from anywhere and will loads those symbols under the US Equity market.
/// </summary>
/// <param name="name">A unique name for this universe</param>
/// <param name="selector">Function delegate that accepts a DateTime and returns a collection of string symbols</param>
public void AddUniverse(string name, Func<DateTime, IEnumerable<string>> selector)
{
AddUniverse(SecurityType.Equity, name, Resolution.Daily, Market.USA, UniverseSettings, selector);
}
/// <summary>
/// Creates a new universe and adds it to the algorithm. This can be used to return a list of string
/// symbols retrieved from anywhere and will loads those symbols under the US Equity market.
/// </summary>
/// <param name="name">A unique name for this universe</param>
/// <param name="resolution">The resolution this universe should be triggered on</param>
/// <param name="selector">Function delegate that accepts a DateTime and returns a collection of string symbols</param>
public void AddUniverse(string name, Resolution resolution, Func<DateTime, IEnumerable<string>> selector)
{
AddUniverse(SecurityType.Equity, name, resolution, Market.USA, UniverseSettings, selector);
}
/// <summary>
/// Creates a new user defined universe that will fire on the requested resolution during market hours.
/// </summary>
/// <param name="securityType">The security type of the universe</param>
/// <param name="name">A unique name for this universe</param>
/// <param name="resolution">The resolution this universe should be triggered on</param>
/// <param name="market">The market of the universe</param>
/// <param name="universeSettings">The subscription settings used for securities added from this universe</param>
/// <param name="selector">Function delegate that accepts a DateTime and returns a collection of string symbols</param>
public void AddUniverse(SecurityType securityType, string name, Resolution resolution, string market, UniverseSettings universeSettings, Func<DateTime, IEnumerable<string>> selector)
{
var marketHoursDbEntry = MarketHoursDatabase.GetEntry(market, name, securityType);
var dataTimeZone = marketHoursDbEntry.DataTimeZone;
var exchangeTimeZone = marketHoursDbEntry.ExchangeHours.TimeZone;
var symbol = QuantConnect.Symbol.Create(name, securityType, market);
var config = new SubscriptionDataConfig(typeof(CoarseFundamental), symbol, resolution, dataTimeZone, exchangeTimeZone, false, false, true, isFilteredSubscription: false);
AddUniverse(new UserDefinedUniverse(config, universeSettings, SecurityInitializer, resolution.ToTimeSpan(), selector));
}
/// <summary>
/// Adds the security to the user defined universe for the specified
/// </summary>
private void AddToUserDefinedUniverse(Security security)
{
// if we are adding a non-internal security which is also the benchmark, we remove it first
Security existingSecurity;
if (Securities.TryGetValue(security.Symbol, out existingSecurity))
{
if (!security.IsInternalFeed() && existingSecurity.Symbol == _benchmarkSymbol)
{
var securityUniverse = UniverseManager.Select(x => x.Value).OfType<UserDefinedUniverse>().FirstOrDefault(x => x.Members.ContainsKey(security.Symbol));
if (securityUniverse != null)
{
securityUniverse.Remove(security.Symbol);
}
Securities.Remove(security.Symbol);
}
}
Securities.Add(security);
// add this security to the user defined universe
Universe universe;
var subscription = security.Subscriptions.First();
var universeSymbol = UserDefinedUniverse.CreateSymbol(subscription.SecurityType, subscription.Market);
if (!UniverseManager.TryGetValue(universeSymbol, out universe))
{
// create a new universe, these subscription settings don't currently get used
// since universe selection proper is never invoked on this type of universe
var uconfig = new SubscriptionDataConfig(subscription, symbol: universeSymbol, isInternalFeed: true, fillForward: false);
if (security.Type == SecurityType.Base)
{
// set entry in market hours database for the universe subscription to match the custom data
var symbolString = MarketHoursDatabase.GetDatabaseSymbolKey(uconfig.Symbol);
MarketHoursDatabase.SetEntry(uconfig.Market, symbolString, uconfig.SecurityType, security.Exchange.Hours, uconfig.DataTimeZone);
}
universe = new UserDefinedUniverse(uconfig,
new UniverseSettings(security.Resolution, security.Leverage, security.IsFillDataForward, security.IsExtendedMarketHours, TimeSpan.Zero),
SecurityInitializer,
QuantConnect.Time.OneDay,
new List<Symbol> { security.Symbol }
);
UniverseManager.Add(universeSymbol, universe);
}
var userDefinedUniverse = universe as UserDefinedUniverse;
if (userDefinedUniverse != null)
{
userDefinedUniverse.Add(security.Symbol);
}
else
{
// should never happen, someone would need to add a non-user defined universe with this symbol
throw new Exception("Expected universe with symbol '" + universeSymbol.Value + "' to be of type UserDefinedUniverse.");
}
}
}
}