Files
quantconnect--lean/Engine/DataFeeds/Enumerators/AuxiliaryDataEnumerator.cs
Martin Molinero 1370ae666a Address reviews
2019-06-13 20:33:22 -03:00

175 lines
6.3 KiB
C#

/*
* 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;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.Auxiliary;
namespace QuantConnect.Lean.Engine.DataFeeds.Enumerators
{
/// <summary>
/// Auxiliary data enumerator that will, initialize and call the <see cref="ITradableDateEventProvider.GetEvents"/>
/// implementation each time there is a new tradable day for every <see cref="ITradableDateEventProvider"/>
/// provided.
/// </summary>
public class AuxiliaryDataEnumerator : IEnumerator<BaseData>
{
private readonly Queue<BaseData> _auxiliaryData;
private bool _initialized;
/// <summary>
/// Creates a new instance
/// </summary>
/// <param name="config">The <see cref="SubscriptionDataConfig"/></param>
/// <param name="factorFile">The factor file to use</param>
/// <param name="mapFile">The <see cref="MapFile"/> to use</param>
/// <param name="tradableDateEventProviders">The tradable dates event providers</param>
/// <param name="tradableDayNotifier">Tradable dates provider</param>
/// <param name="includeAuxiliaryData">True to emit auxiliary data</param>
public AuxiliaryDataEnumerator(
SubscriptionDataConfig config,
Lazy<FactorFile> factorFile,
Lazy<MapFile> mapFile,
ITradableDateEventProvider []tradableDateEventProviders,
ITradableDatesNotifier tradableDayNotifier,
bool includeAuxiliaryData)
{
_auxiliaryData = new Queue<BaseData>();
tradableDayNotifier.NewTradableDate += (sender, eventArgs) =>
{
if (!_initialized)
{
Initialize(config, factorFile, mapFile, tradableDateEventProviders);
}
foreach (var tradableDateEventProvider in tradableDateEventProviders)
{
// Call implementation
// and materialize list since we need symbol changes applied to the config
// regardless of the includeAuxiliaryData argument
var newEvents = tradableDateEventProvider.GetEvents(eventArgs).ToList();
if (includeAuxiliaryData)
{
foreach (var newEvent in newEvents)
{
_auxiliaryData.Enqueue(newEvent);
}
}
}
};
}
/// <summary>
/// Late initialization so it is performed in the data feed stack
/// and not in the algorithm thread
/// </summary>
private void Initialize(SubscriptionDataConfig config,
Lazy<FactorFile> factorFile,
Lazy<MapFile> mapFile,
ITradableDateEventProvider[] tradableDateEventProviders)
{
foreach (var tradableDateEventProvider in tradableDateEventProviders)
{
tradableDateEventProvider.Initialize(
config,
factorFile?.Value,
mapFile?.Value);
}
_initialized = true;
}
/// <summary>
/// Advances the enumerator to the next element.
/// </summary>
/// <returns>Always true</returns>
public virtual bool MoveNext()
{
Current = _auxiliaryData.Any() ? _auxiliaryData.Dequeue() : null;
return true;
}
/// <summary>
/// Dispose of the Stream Reader and close out the source stream and file connections.
/// </summary>
public void Dispose()
{
}
/// <summary>
/// Reset the IEnumeration
/// </summary>
/// <remarks>Not used</remarks>
public void Reset()
{
throw new NotImplementedException("Reset method not implemented. Assumes loop will only be used once.");
}
object IEnumerator.Current => Current;
/// <summary>
/// Last read BaseData object from this type and source
/// </summary>
public BaseData Current
{
get;
private set;
}
/// <summary>
/// Un-normalizes the PreviousUnderlyingData.Value
/// </summary>
public static decimal GetRawClose(decimal price, SubscriptionDataConfig config)
{
return GetRawValue(price, config.SumOfDividends, config.PriceScaleFactor, config.DataNormalizationMode);
}
/// <summary>
/// Un-normalizes a price
/// </summary>
private static decimal GetRawValue(decimal price,
decimal sumOfDividends,
decimal priceScaleFactor,
DataNormalizationMode dataNormalizationMode)
{
switch (dataNormalizationMode)
{
case DataNormalizationMode.Raw:
break;
case DataNormalizationMode.SplitAdjusted:
case DataNormalizationMode.Adjusted:
// we need to 'unscale' the price
price = price / priceScaleFactor;
break;
case DataNormalizationMode.TotalReturn:
// we need to remove the dividends since we've been accumulating them in the price
price = (price - sumOfDividends) / priceScaleFactor;
break;
default:
throw new ArgumentOutOfRangeException();
}
return price;
}
}
}