Files
quantconnect--lean/ToolBox/TickAggregator.cs
T
Ricardo Andrés Marino Rojas 4e56af487c
Python Virtual Environments / build (push) Has been cancelled
Benchmarks / build (push) Has been cancelled
Build & Test Lean / build (push) Has been cancelled
Regression Tests / build (push) Has been cancelled
Research Regression Tests / build (push) Has been cancelled
Fix bug in RandomDataGenerator for Option data at Minute resolution (#7237)
* Fix the bug and add unit tests
- The bug was raised by different conditions.

First, the tick created in tick generator for Open Interest was not of type Open Interest.

Second, TickAggregator.cs was made to use daily resolution for OpenInterest always.

Third, the RandomValueGenerator, generated a random friday as expiration date for the option created but this one needed first two underlying data points, so if the expiration date was before the start date plus 3 days, RandomDataGenerator just generated OpenInterest data for the option.

* Add docs
2023-05-11 12:54:45 -03:00

181 lines
6.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.Consolidators;
using QuantConnect.Data.Market;
using QuantConnect.Util;
namespace QuantConnect.ToolBox
{
/// <summary>
/// Class that uses consolidators to aggregate tick data data
/// </summary>
public abstract class TickAggregator
{
protected TickAggregator(Resolution resolution, TickType tickType)
{
TickType = tickType;
Resolution = resolution;
}
/// <summary>
/// Gets the tick type of the consolidator
/// </summary>
public TickType TickType { get; protected set; }
/// <summary>
/// The consolidator used to aggregate data from
/// higher resolutions to data in lower resolutions
/// </summary>
public IDataConsolidator Consolidator { get; protected set; }
/// <summary>
/// The consolidated data
/// </summary>
public List<BaseData> Consolidated { get; protected set; }
/// <summary>
/// The resolution that the data is being aggregated into
/// </summary>
public Resolution Resolution { get; }
/// <summary>
/// Updates the consolidator with the specified bar.
/// </summary>
/// <param name="data">The latest data observation.</param>
public virtual void Update(BaseData data)
{
Consolidator.Update(data);
}
/// <summary>
/// Return all the consolidated data as well as the
/// bar the consolidator is currently working on
/// </summary>
public List<BaseData> Flush()
{
var data = new List<BaseData>(Consolidated);
if (Consolidator.WorkingData != null)
{
data.Add(Consolidator.WorkingData as BaseData);
}
return data;
}
/// <summary>
/// Creates the correct <see cref="TickAggregator"/> instances for the specified tick types and resolution.
/// <see cref="QuantConnect.TickType.OpenInterest"/> will ignore <paramref name="resolution"/> and use <see cref="QuantConnect.Resolution.Daily"/>
/// </summary>
public static IEnumerable<TickAggregator> ForTickTypes(SecurityType securityType, Resolution resolution, params TickType[] tickTypes)
{
if (resolution == Resolution.Tick)
{
foreach (var tickType in tickTypes.Where(t => LeanData.IsValidConfiguration(securityType, resolution, t)))
{
// OI is special
if (tickType == TickType.OpenInterest)
{
yield return new OpenInterestTickAggregator(resolution);
continue;
}
yield return new IdentityTickAggregator(tickType);
}
yield break;
}
foreach (var tickType in tickTypes.Where(t => LeanData.IsValidConfiguration(securityType, resolution, t)))
{
switch (tickType)
{
case TickType.Trade:
yield return new TradeTickAggregator(resolution);
break;
case TickType.Quote:
yield return new QuoteTickAggregator(resolution);
break;
case TickType.OpenInterest:
yield return new OpenInterestTickAggregator(resolution);
break;
default:
throw new ArgumentOutOfRangeException(nameof(tickType), tickType, null);
}
}
}
}
/// <summary>
/// Use <see cref="TickQuoteBarConsolidator"/> to consolidate quote ticks into a specified resolution
/// </summary>
public class QuoteTickAggregator : TickAggregator
{
public QuoteTickAggregator(Resolution resolution)
: base(resolution, TickType.Quote)
{
Consolidated = new List<BaseData>();
Consolidator = new TickQuoteBarConsolidator(resolution.ToTimeSpan());
Consolidator.DataConsolidated += (sender, consolidated) =>
{
Consolidated.Add(consolidated as QuoteBar);
};
}
}
/// <summary>
/// Use <see cref="TickQuoteBarConsolidator"/> to consolidate trade ticks into a specified resolution
/// </summary>
public class TradeTickAggregator : TickAggregator
{
public TradeTickAggregator(Resolution resolution)
: base(resolution, TickType.Trade)
{
Consolidated = new List<BaseData>();
Consolidator = new TickConsolidator(resolution.ToTimeSpan());
Consolidator.DataConsolidated += (sender, consolidated) =>
{
Consolidated.Add(consolidated as TradeBar);
};
}
}
/// <summary>
/// Use <see cref="OpenInterestConsolidator"/> to consolidate open interest ticks into a specified resolution
/// </summary>
public class OpenInterestTickAggregator : TickAggregator
{
public OpenInterestTickAggregator(Resolution resolution)
: base(resolution, TickType.OpenInterest)
{
Consolidated = new List<BaseData>();
Consolidator = new OpenInterestConsolidator(resolution.ToTimeSpan());
Consolidator.DataConsolidated += (sender, consolidated) =>
{
Consolidated.Add(consolidated as OpenInterest);
};
}
}
/// <summary>
/// Use <see cref="IdentityDataConsolidator{T}"/> to yield ticks unmodified into the consolidated data collection
/// </summary>
public class IdentityTickAggregator : TickAggregator
{
public IdentityTickAggregator(TickType tickType)
: base(Resolution.Tick, tickType)
{
Consolidated = new List<BaseData>();
Consolidator = FilteredIdentityDataConsolidator.ForTickType(tickType);
Consolidator.DataConsolidated += (sender, consolidated) =>
{
Consolidated.Add(consolidated as Tick);
};
}
}
}