chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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 Python.Runtime;
|
||||
using QuantConnect.Interfaces;
|
||||
using System.Collections.Generic;
|
||||
using QuantConnect.Util;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Alphas.Analysis
|
||||
{
|
||||
/// <summary>
|
||||
/// Encapsulates the storage of insights.
|
||||
/// </summary>
|
||||
public class InsightManager : InsightCollection
|
||||
{
|
||||
private readonly IAlgorithm _algorithm;
|
||||
private IInsightScoreFunction _insightScoreFunction;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance
|
||||
/// </summary>
|
||||
/// <param name="algorithm">The associated algorithm instance</param>
|
||||
public InsightManager(IAlgorithm algorithm)
|
||||
{
|
||||
_algorithm = algorithm;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process a new time step handling insights scoring
|
||||
/// </summary>
|
||||
/// <param name="utcNow">The current utc time</param>
|
||||
public void Step(DateTime utcNow)
|
||||
{
|
||||
_insightScoreFunction?.Score(this, utcNow);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the insight score function to use
|
||||
/// </summary>
|
||||
/// <param name="insightScoreFunction">Model that scores insights</param>
|
||||
public void SetInsightScoreFunction(IInsightScoreFunction insightScoreFunction)
|
||||
{
|
||||
_insightScoreFunction = insightScoreFunction;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the insight score function to use
|
||||
/// </summary>
|
||||
/// <param name="insightScoreFunction">Model that scores insights</param>
|
||||
public void SetInsightScoreFunction(PyObject insightScoreFunction)
|
||||
{
|
||||
_insightScoreFunction = PythonUtil.CreateInstanceOrWrapper<IInsightScoreFunction>(
|
||||
insightScoreFunction,
|
||||
py => new InsightScoreFunctionPythonWrapper(py)
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Expire the insights of the given symbols
|
||||
/// </summary>
|
||||
/// <param name="symbols">Symbol we want to expire insights for</param>
|
||||
public void Expire(IEnumerable<Symbol> symbols)
|
||||
{
|
||||
if (symbols == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var symbol in symbols)
|
||||
{
|
||||
if (TryGetValue(symbol, out var insights))
|
||||
{
|
||||
Expire(insights);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancel the insights of the given symbols
|
||||
/// </summary>
|
||||
/// <param name="symbols">Symbol we want to cancel insights for</param>
|
||||
public void Cancel(IEnumerable<Symbol> symbols)
|
||||
{
|
||||
Expire(symbols);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Expire the given insights
|
||||
/// </summary>
|
||||
/// <param name="insights">Insights to expire</param>
|
||||
public void Expire(IEnumerable<Insight> insights)
|
||||
{
|
||||
if (insights == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var currentUtcTime = _algorithm.UtcTime;
|
||||
foreach (var insight in insights)
|
||||
{
|
||||
insight.Expire(currentUtcTime);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancel the given insights
|
||||
/// </summary>
|
||||
/// <param name="insights">Insights to cancel</param>
|
||||
public void Cancel(IEnumerable<Insight> insights)
|
||||
{
|
||||
Expire(insights);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Alphas
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a collection of insights that were generated at the same time step
|
||||
/// </summary>
|
||||
public class GeneratedInsightsCollection
|
||||
{
|
||||
/// <summary>
|
||||
/// The utc date time the insights were generated
|
||||
/// </summary>
|
||||
public DateTime DateTimeUtc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The generated insights
|
||||
/// </summary>
|
||||
public Insight[] Insights { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GeneratedInsightsCollection"/> class
|
||||
/// </summary>
|
||||
/// <param name="dateTimeUtc">The utc date time the sinals were generated</param>
|
||||
/// <param name="insights">The generated insights</param>
|
||||
public GeneratedInsightsCollection(DateTime dateTimeUtc, Insight[] insights)
|
||||
{
|
||||
DateTimeUtc = dateTimeUtc;
|
||||
Insights = insights;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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 QuantConnect.Algorithm.Framework.Alphas.Analysis;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Alphas
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstraction in charge of scoring insights
|
||||
/// </summary>
|
||||
public interface IInsightScoreFunction
|
||||
{
|
||||
/// <summary>
|
||||
/// Method to evaluate and score insights for each time step
|
||||
/// </summary>
|
||||
void Score(InsightManager insightManager, DateTime utcTime);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,747 @@
|
||||
/*
|
||||
* 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 Newtonsoft.Json;
|
||||
using QuantConnect.Algorithm.Framework.Alphas.Serialization;
|
||||
using QuantConnect.Interfaces;
|
||||
using QuantConnect.Securities;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Alphas
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a alpha prediction for a single symbol generated by the algorithm
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Serialization of this type is delegated to the <see cref="InsightJsonConverter"/> which uses the <see cref="SerializedInsight"/> as a model.
|
||||
/// </remarks>
|
||||
[JsonConverter(typeof(InsightJsonConverter))]
|
||||
public class Insight
|
||||
{
|
||||
private readonly IPeriodSpecification _periodSpecification;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique identifier for this insight
|
||||
/// </summary>
|
||||
public Guid Id { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the group id this insight belongs to, null if not in a group
|
||||
/// </summary>
|
||||
public Guid? GroupId { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets an identifier for the source model that generated this insight.
|
||||
/// </summary>
|
||||
public string SourceModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the utc time this insight was generated
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The algorithm framework handles setting this value appropriately.
|
||||
/// If providing custom <see cref="Insight"/> implementation, be sure
|
||||
/// to set this value to algorithm.UtcTime when the insight is generated.
|
||||
/// </remarks>
|
||||
public DateTime GeneratedTimeUtc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the insight's prediction end time. This is the time when this
|
||||
/// insight prediction is expected to be fulfilled. This time takes into
|
||||
/// account market hours, weekends, as well as the symbol's data resolution
|
||||
/// </summary>
|
||||
public DateTime CloseTimeUtc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the symbol this insight is for
|
||||
/// </summary>
|
||||
public Symbol Symbol { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of insight, for example, price insight or volatility insight
|
||||
/// </summary>
|
||||
public InsightType Type { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the initial reference value this insight is predicting against. The value is dependent on the specified <see cref="InsightType"/>
|
||||
/// </summary>
|
||||
public decimal ReferenceValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the final reference value, used for scoring, this insight is predicting against. The value is dependent on the specified <see cref="InsightType"/>
|
||||
/// </summary>
|
||||
public decimal ReferenceValueFinal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the predicted direction, down, flat or up
|
||||
/// </summary>
|
||||
public InsightDirection Direction { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the period over which this insight is expected to come to fruition
|
||||
/// </summary>
|
||||
public TimeSpan Period { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the predicted percent change in the insight type (price/volatility)
|
||||
/// </summary>
|
||||
public double? Magnitude { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the confidence in this insight
|
||||
/// </summary>
|
||||
public double? Confidence { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the portfolio weight of this insight
|
||||
/// </summary>
|
||||
public double? Weight { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the most recent scores for this insight
|
||||
/// </summary>
|
||||
public InsightScore Score { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the estimated value of this insight in the account currency
|
||||
/// </summary>
|
||||
public decimal EstimatedValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The insight's tag containing additional information
|
||||
/// </summary>
|
||||
public string Tag { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether or not this insight is considered expired at the specified <paramref name="utcTime"/>
|
||||
/// </summary>
|
||||
/// <param name="utcTime">The algorithm's current time in UTC. See <see cref="IAlgorithm.UtcTime"/></param>
|
||||
/// <returns>True if this insight is expired, false otherwise</returns>
|
||||
public bool IsExpired(DateTime utcTime)
|
||||
{
|
||||
return CloseTimeUtc < utcTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether or not this insight is considered active at the specified <paramref name="utcTime"/>
|
||||
/// </summary>
|
||||
/// <param name="utcTime">The algorithm's current time in UTC. See <see cref="IAlgorithm.UtcTime"/></param>
|
||||
/// <returns>True if this insight is active, false otherwise</returns>
|
||||
public bool IsActive(DateTime utcTime)
|
||||
{
|
||||
return !IsExpired(utcTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Expire this insight
|
||||
/// </summary>
|
||||
/// <param name="utcTime">The algorithm's current time in UTC. See <see cref="IAlgorithm.UtcTime"/></param>
|
||||
public void Expire(DateTime utcTime)
|
||||
{
|
||||
if (IsActive(utcTime))
|
||||
{
|
||||
CloseTimeUtc = utcTime.Add(-Time.OneSecond);
|
||||
Period = CloseTimeUtc - GeneratedTimeUtc;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancel this insight
|
||||
/// </summary>
|
||||
/// <param name="utcTime">The algorithm's current time in UTC. See <see cref="IAlgorithm.UtcTime"/></param>
|
||||
public void Cancel(DateTime utcTime)
|
||||
{
|
||||
Expire(utcTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Insight"/> class
|
||||
/// </summary>
|
||||
/// <param name="symbol">The symbol this insight is for</param>
|
||||
/// <param name="period">The period over which the prediction will come true</param>
|
||||
/// <param name="type">The type of insight, price/volatility</param>
|
||||
/// <param name="direction">The predicted direction</param>
|
||||
/// <param name="tag">The insight's tag containing additional information</param>
|
||||
public Insight(Symbol symbol, TimeSpan period, InsightType type, InsightDirection direction, string tag = "")
|
||||
: this(symbol, period, type, direction, null, null, null, null, tag)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Insight"/> class
|
||||
/// </summary>
|
||||
/// <param name="symbol">The symbol this insight is for</param>
|
||||
/// <param name="period">The period over which the prediction will come true</param>
|
||||
/// <param name="type">The type of insight, price/volatility</param>
|
||||
/// <param name="direction">The predicted direction</param>
|
||||
/// <param name="magnitude">The predicted magnitude as a percentage change</param>
|
||||
/// <param name="confidence">The confidence in this insight</param>
|
||||
/// <param name="sourceModel">An identifier defining the model that generated this insight</param>
|
||||
/// <param name="weight">The portfolio weight of this insight</param>
|
||||
/// <param name="tag">The insight's tag containing additional information</param>
|
||||
public Insight(Symbol symbol, TimeSpan period, InsightType type, InsightDirection direction, double? magnitude, double? confidence, string sourceModel = null, double? weight = null, string tag = "")
|
||||
{
|
||||
Id = Guid.NewGuid();
|
||||
Score = new InsightScore();
|
||||
SourceModel = sourceModel;
|
||||
|
||||
Symbol = symbol;
|
||||
Type = type;
|
||||
Direction = direction;
|
||||
Period = period;
|
||||
|
||||
// Optional
|
||||
Magnitude = magnitude;
|
||||
Confidence = confidence;
|
||||
Weight = weight;
|
||||
Tag = tag;
|
||||
|
||||
_periodSpecification = new TimeSpanPeriodSpecification(period);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Insight"/> class
|
||||
/// </summary>
|
||||
/// <param name="symbol">The symbol this insight is for</param>
|
||||
/// <param name="expiryFunc">Func that defines the expiry time</param>
|
||||
/// <param name="type">The type of insight, price/volatility</param>
|
||||
/// <param name="direction">The predicted direction</param>
|
||||
/// <param name="tag">The insight's tag containing additional information</param>
|
||||
public Insight(Symbol symbol, Func<DateTime, DateTime> expiryFunc, InsightType type, InsightDirection direction, string tag = "")
|
||||
: this(symbol, expiryFunc, type, direction, null, null, null, null, tag)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Insight"/> class
|
||||
/// </summary>
|
||||
/// <param name="symbol">The symbol this insight is for</param>
|
||||
/// <param name="expiryFunc">Func that defines the expiry time</param>
|
||||
/// <param name="type">The type of insight, price/volatility</param>
|
||||
/// <param name="direction">The predicted direction</param>
|
||||
/// <param name="magnitude">The predicted magnitude as a percentage change</param>
|
||||
/// <param name="confidence">The confidence in this insight</param>
|
||||
/// <param name="sourceModel">An identifier defining the model that generated this insight</param>
|
||||
/// <param name="weight">The portfolio weight of this insight</param>
|
||||
/// <param name="tag">The insight's tag containing additional information</param>
|
||||
public Insight(Symbol symbol, Func<DateTime, DateTime> expiryFunc, InsightType type, InsightDirection direction, double? magnitude, double? confidence, string sourceModel = null, double? weight = null, string tag = "")
|
||||
: this(symbol, new FuncPeriodSpecification(expiryFunc), type, direction, magnitude, confidence, sourceModel, weight, tag)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Insight"/> class.
|
||||
/// This constructor is provided mostly for testing purposes. When running inside an algorithm,
|
||||
/// the generated and close times are set based on the algorithm's time.
|
||||
/// </summary>
|
||||
/// <param name="generatedTimeUtc">The time this insight was generated in utc</param>
|
||||
/// <param name="symbol">The symbol this insight is for</param>
|
||||
/// <param name="period">The period over which the prediction will come true</param>
|
||||
/// <param name="type">The type of insight, price/volatility</param>
|
||||
/// <param name="direction">The predicted direction</param>
|
||||
/// <param name="magnitude">The predicted magnitude as a percentage change</param>
|
||||
/// <param name="confidence">The confidence in this insight</param>
|
||||
/// <param name="sourceModel">An identifier defining the model that generated this insight</param>
|
||||
/// <param name="weight">The portfolio weight of this insight</param>
|
||||
/// <param name="tag">The insight's tag containing additional information</param>
|
||||
public Insight(DateTime generatedTimeUtc, Symbol symbol, TimeSpan period, InsightType type, InsightDirection direction, double? magnitude, double? confidence, string sourceModel = null, double? weight = null, string tag = "")
|
||||
: this(symbol, period, type, direction, magnitude, confidence, sourceModel, weight, tag)
|
||||
{
|
||||
GeneratedTimeUtc = generatedTimeUtc;
|
||||
CloseTimeUtc = generatedTimeUtc + period;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Private constructor used to keep track of how a user defined the insight period.
|
||||
/// </summary>
|
||||
/// <param name="symbol">The symbol this insight is for</param>
|
||||
/// <param name="periodSpec">A specification defining how the insight's period was defined, via time span, via resolution/barcount, via close time</param>
|
||||
/// <param name="type">The type of insight, price/volatility</param>
|
||||
/// <param name="direction">The predicted direction</param>
|
||||
/// <param name="magnitude">The predicted magnitude as a percentage change</param>
|
||||
/// <param name="confidence">The confidence in this insight</param>
|
||||
/// <param name="sourceModel">An identifier defining the model that generated this insight</param>
|
||||
/// <param name="weight">The portfolio weight of this insight</param>
|
||||
/// <param name="tag">The insight's tag containing additional information</param>
|
||||
private Insight(Symbol symbol, IPeriodSpecification periodSpec, InsightType type, InsightDirection direction, double? magnitude, double? confidence, string sourceModel = null, double? weight = null, string tag = "")
|
||||
{
|
||||
Id = Guid.NewGuid();
|
||||
Score = new InsightScore();
|
||||
SourceModel = sourceModel;
|
||||
|
||||
Symbol = symbol;
|
||||
Type = type;
|
||||
Direction = direction;
|
||||
|
||||
// Optional
|
||||
Magnitude = magnitude;
|
||||
Confidence = confidence;
|
||||
Weight = weight;
|
||||
Tag = tag;
|
||||
|
||||
_periodSpecification = periodSpec;
|
||||
|
||||
// keep existing behavior of Insight.Price such that we set the period immediately
|
||||
var period = (periodSpec as TimeSpanPeriodSpecification)?.Period;
|
||||
if (period != null)
|
||||
{
|
||||
Period = period.Value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the insight period and close times if they have not already been set.
|
||||
/// </summary>
|
||||
/// <param name="exchangeHours">The insight's security exchange hours</param>
|
||||
public void SetPeriodAndCloseTime(SecurityExchangeHours exchangeHours)
|
||||
{
|
||||
if (GeneratedTimeUtc == default(DateTime))
|
||||
{
|
||||
throw new InvalidOperationException(Messages.Insight.GeneratedTimeUtcNotSet(this));
|
||||
}
|
||||
|
||||
_periodSpecification.SetPeriodAndCloseTime(this, exchangeHours);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a deep clone of this insight instance
|
||||
/// </summary>
|
||||
/// <returns>A new insight with identical values, but new instances</returns>
|
||||
public virtual Insight Clone()
|
||||
{
|
||||
return new Insight(Symbol, Period, Type, Direction, Magnitude, Confidence, weight: Weight, tag: Tag)
|
||||
{
|
||||
GeneratedTimeUtc = GeneratedTimeUtc,
|
||||
CloseTimeUtc = CloseTimeUtc,
|
||||
Score = Score,
|
||||
Id = Id,
|
||||
EstimatedValue = EstimatedValue,
|
||||
ReferenceValue = ReferenceValue,
|
||||
ReferenceValueFinal = ReferenceValueFinal,
|
||||
SourceModel = SourceModel,
|
||||
GroupId = GroupId
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new insight for predicting the percent change in price over the specified period
|
||||
/// </summary>
|
||||
/// <param name="symbol">The symbol this insight is for</param>
|
||||
/// <param name="resolution">The resolution used to define the insight's period and also used to determine the insight's close time</param>
|
||||
/// <param name="barCount">The number of resolution time steps to make in market hours to compute the insight's closing time</param>
|
||||
/// <param name="direction">The predicted direction</param>
|
||||
/// <param name="magnitude">The predicted magnitude as a percent change</param>
|
||||
/// <param name="confidence">The confidence in this insight</param>
|
||||
/// <param name="sourceModel">The model generating this insight</param>
|
||||
/// <param name="weight">The portfolio weight of this insight</param>
|
||||
/// <param name="tag">The insight's tag containing additional information</param>
|
||||
/// <returns>A new insight object for the specified parameters</returns>
|
||||
public static Insight Price(Symbol symbol, Resolution resolution, int barCount, InsightDirection direction, double? magnitude = null, double? confidence = null, string sourceModel = null, double? weight = null, string tag = "")
|
||||
{
|
||||
if (barCount < 1)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(barCount), Messages.Insight.InvalidBarCount);
|
||||
}
|
||||
|
||||
var spec = new ResolutionBarCountPeriodSpecification(resolution, barCount);
|
||||
return new Insight(symbol, spec, InsightType.Price, direction, magnitude, confidence, sourceModel, weight, tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new insight for predicting the percent change in price over the specified period
|
||||
/// </summary>
|
||||
/// <param name="symbol">The symbol this insight is for</param>
|
||||
/// <param name="closeTimeLocal">The insight's closing time in the security's exchange time zone</param>
|
||||
/// <param name="direction">The predicted direction</param>
|
||||
/// <param name="magnitude">The predicted magnitude as a percent change</param>
|
||||
/// <param name="confidence">The confidence in this insight</param>
|
||||
/// <param name="sourceModel">The model generating this insight</param>
|
||||
/// <param name="weight">The portfolio weight of this insight</param>
|
||||
/// <param name="tag">The insight's tag containing additional information</param>
|
||||
/// <returns>A new insight object for the specified parameters</returns>
|
||||
public static Insight Price(Symbol symbol, DateTime closeTimeLocal, InsightDirection direction, double? magnitude = null, double? confidence = null, string sourceModel = null, double? weight = null, string tag = "")
|
||||
{
|
||||
var spec = closeTimeLocal == Time.EndOfTime ? (IPeriodSpecification)
|
||||
new EndOfTimeCloseTimePeriodSpecification() : new CloseTimePeriodSpecification(closeTimeLocal);
|
||||
return new Insight(symbol, spec, InsightType.Price, direction, magnitude, confidence, sourceModel, weight, tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new insight for predicting the percent change in price over the specified period
|
||||
/// </summary>
|
||||
/// <param name="symbol">The symbol this insight is for</param>
|
||||
/// <param name="period">The period over which the prediction will come true</param>
|
||||
/// <param name="direction">The predicted direction</param>
|
||||
/// <param name="magnitude">The predicted magnitude as a percent change</param>
|
||||
/// <param name="confidence">The confidence in this insight</param>
|
||||
/// <param name="sourceModel">The model generating this insight</param>
|
||||
/// <param name="weight">The portfolio weight of this insight</param>
|
||||
/// <param name="tag">The insight's tag containing additional information</param>
|
||||
/// <returns>A new insight object for the specified parameters</returns>
|
||||
public static Insight Price(Symbol symbol, TimeSpan period, InsightDirection direction, double? magnitude = null, double? confidence = null, string sourceModel = null, double? weight = null, string tag = "")
|
||||
{
|
||||
if (period < Time.OneSecond)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(period), Messages.Insight.InvalidPeriod);
|
||||
}
|
||||
|
||||
var spec = period == Time.EndOfTimeTimeSpan ? (IPeriodSpecification)
|
||||
new EndOfTimeCloseTimePeriodSpecification() : new TimeSpanPeriodSpecification(period);
|
||||
return new Insight(symbol, spec, InsightType.Price, direction, magnitude, confidence, sourceModel, weight, tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new insight for predicting the percent change in price over the specified period
|
||||
/// </summary>
|
||||
/// <param name="symbol">The symbol this insight is for</param>
|
||||
/// <param name="expiryFunc">Func that defines the expiry time</param>
|
||||
/// <param name="direction">The predicted direction</param>
|
||||
/// <param name="magnitude">The predicted magnitude as a percent change</param>
|
||||
/// <param name="confidence">The confidence in this insight</param>
|
||||
/// <param name="sourceModel">The model generating this insight</param>
|
||||
/// <param name="weight">The portfolio weight of this insight</param>
|
||||
/// <param name="tag">The insight's tag containing additional information</param>
|
||||
/// <returns>A new insight object for the specified parameters</returns>
|
||||
public static Insight Price(Symbol symbol, Func<DateTime, DateTime> expiryFunc, InsightDirection direction, double? magnitude = null, double? confidence = null, string sourceModel = null, double? weight = null, string tag = "")
|
||||
{
|
||||
return new Insight(symbol, expiryFunc, InsightType.Price, direction, magnitude, confidence, sourceModel, weight, tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new, unique group id and sets it on each insight
|
||||
/// </summary>
|
||||
/// <param name="insights">The insights to be grouped</param>
|
||||
public static IEnumerable<Insight> Group(params Insight[] insights)
|
||||
{
|
||||
if (insights == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(insights));
|
||||
}
|
||||
|
||||
var groupId = Guid.NewGuid();
|
||||
foreach (var insight in insights)
|
||||
{
|
||||
if (insight.GroupId.HasValue)
|
||||
{
|
||||
throw new InvalidOperationException(Messages.Insight.InsightAlreadyAssignedToAGroup(insight));
|
||||
}
|
||||
|
||||
insight.GroupId = groupId;
|
||||
}
|
||||
return insights;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new, unique group id and sets it on each insight
|
||||
/// </summary>
|
||||
/// <param name="insight">The insight to be grouped</param>
|
||||
public static IEnumerable<Insight> Group(Insight insight) => Group(new[] {insight});
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Insight"/> object from the specified serialized form
|
||||
/// </summary>
|
||||
/// <param name="serializedInsight">The insight DTO</param>
|
||||
/// <returns>A new insight containing the information specified</returns>
|
||||
public static Insight FromSerializedInsight(SerializedInsight serializedInsight)
|
||||
{
|
||||
var sid = SecurityIdentifier.Parse(serializedInsight.Symbol);
|
||||
var insight = new Insight(
|
||||
Time.UnixTimeStampToDateTime(serializedInsight.CreatedTime),
|
||||
new Symbol(sid, serializedInsight.Ticker ?? sid.Symbol),
|
||||
TimeSpan.FromSeconds(serializedInsight.Period),
|
||||
serializedInsight.Type,
|
||||
serializedInsight.Direction,
|
||||
serializedInsight.Magnitude,
|
||||
serializedInsight.Confidence,
|
||||
serializedInsight.SourceModel,
|
||||
serializedInsight.Weight,
|
||||
serializedInsight.Tag
|
||||
)
|
||||
{
|
||||
Id = Guid.Parse(serializedInsight.Id),
|
||||
CloseTimeUtc = Time.UnixTimeStampToDateTime(serializedInsight.CloseTime),
|
||||
EstimatedValue = serializedInsight.EstimatedValue,
|
||||
ReferenceValue = serializedInsight.ReferenceValue,
|
||||
ReferenceValueFinal = serializedInsight.ReferenceValueFinal,
|
||||
GroupId = string.IsNullOrEmpty(serializedInsight.GroupId) ? (Guid?) null : Guid.Parse(serializedInsight.GroupId)
|
||||
};
|
||||
|
||||
// only set score values if non-zero or if they're the final scores
|
||||
if (serializedInsight.ScoreIsFinal)
|
||||
{
|
||||
insight.Score.SetScore(InsightScoreType.Magnitude, serializedInsight.ScoreMagnitude, insight.CloseTimeUtc);
|
||||
insight.Score.SetScore(InsightScoreType.Direction, serializedInsight.ScoreDirection, insight.CloseTimeUtc);
|
||||
insight.Score.Finalize(insight.CloseTimeUtc);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (serializedInsight.ScoreMagnitude != 0)
|
||||
{
|
||||
insight.Score.SetScore(InsightScoreType.Magnitude, serializedInsight.ScoreMagnitude, insight.CloseTimeUtc);
|
||||
}
|
||||
|
||||
if (serializedInsight.ScoreDirection != 0)
|
||||
{
|
||||
insight.Score.SetScore(InsightScoreType.Direction, serializedInsight.ScoreDirection, insight.CloseTimeUtc);
|
||||
}
|
||||
}
|
||||
|
||||
return insight;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the insight closing time from the given generated time, resolution and bar count.
|
||||
/// This will step through market hours using the given resolution, respecting holidays, early closes, weekends, etc..
|
||||
/// </summary>
|
||||
/// <param name="exchangeHours">The exchange hours of the insight's security</param>
|
||||
/// <param name="generatedTimeUtc">The insight's generated time in utc</param>
|
||||
/// <param name="resolution">The resolution used to 'step-through' market hours to compute a reasonable close time</param>
|
||||
/// <param name="barCount">The number of resolution steps to take</param>
|
||||
/// <returns>The insight's closing time in utc</returns>
|
||||
public static DateTime ComputeCloseTime(SecurityExchangeHours exchangeHours, DateTime generatedTimeUtc, Resolution resolution, int barCount)
|
||||
{
|
||||
if (barCount < 1)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(barCount), Messages.Insight.InvalidBarCount);
|
||||
}
|
||||
|
||||
// remap ticks to seconds
|
||||
resolution = resolution == Resolution.Tick ? Resolution.Second : resolution;
|
||||
if (resolution == Resolution.Hour)
|
||||
{
|
||||
// remap hours to minutes to avoid complications w/ stepping through
|
||||
// for example 9->10 is an hour step but market opens at 9:30
|
||||
barCount *= 60;
|
||||
resolution = Resolution.Minute;
|
||||
}
|
||||
|
||||
var barSize = resolution.ToTimeSpan();
|
||||
var startTimeLocal = generatedTimeUtc.ConvertFromUtc(exchangeHours.TimeZone);
|
||||
var closeTimeLocal = Time.GetEndTimeForTradeBars(exchangeHours, startTimeLocal, barSize, barCount, false);
|
||||
return closeTimeLocal.ConvertToUtc(exchangeHours.TimeZone);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// computs the insight closing time from the given generated time and period
|
||||
/// </summary>
|
||||
/// <param name="exchangeHours">The exchange hours of the insight's security</param>
|
||||
/// <param name="generatedTimeUtc">The insight's generated time in utc</param>
|
||||
/// <param name="period">The insight's period</param>
|
||||
/// <returns>The insight's closing time in utc</returns>
|
||||
public static DateTime ComputeCloseTime(SecurityExchangeHours exchangeHours, DateTime generatedTimeUtc, TimeSpan period)
|
||||
{
|
||||
if (period < Time.OneSecond)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(period), Messages.Insight.InvalidPeriod);
|
||||
}
|
||||
|
||||
var barSize = period.ToHigherResolutionEquivalent(false);
|
||||
// remap ticks to seconds
|
||||
barSize = barSize == Resolution.Tick ? Resolution.Second : barSize;
|
||||
// remap hours to minutes to avoid complications w/ stepping through, for example 9->10 is an hour step but market opens at 9:30
|
||||
barSize = barSize == Resolution.Hour ? Resolution.Minute : barSize;
|
||||
var barCount = (int)(period.Ticks / barSize.ToTimeSpan().Ticks);
|
||||
var closeTimeUtc = ComputeCloseTime(exchangeHours, generatedTimeUtc, barSize, barCount);
|
||||
if (closeTimeUtc == generatedTimeUtc)
|
||||
{
|
||||
return ComputeCloseTime(exchangeHours, generatedTimeUtc, Resolution.Second, 1);
|
||||
}
|
||||
|
||||
var totalPeriodUsed = barSize.ToTimeSpan().Multiply(barCount);
|
||||
if (totalPeriodUsed != period)
|
||||
{
|
||||
var delta = period - totalPeriodUsed;
|
||||
|
||||
// interpret the remainder as fractional trading days
|
||||
if (barSize == Resolution.Daily)
|
||||
{
|
||||
var percentOfDay = delta.Ticks / (double) Time.OneDay.Ticks;
|
||||
delta = exchangeHours.RegularMarketDuration.Multiply(percentOfDay);
|
||||
}
|
||||
|
||||
if (delta != TimeSpan.Zero)
|
||||
{
|
||||
// continue stepping forward using minute resolution for the remainder
|
||||
barCount = (int) (delta.Ticks / Time.OneMinute.Ticks);
|
||||
if (barCount > 0)
|
||||
{
|
||||
closeTimeUtc = ComputeCloseTime(exchangeHours, closeTimeUtc, Resolution.Minute, barCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return closeTimeUtc;
|
||||
}
|
||||
|
||||
/// <summary>Returns a string that represents the current object.</summary>
|
||||
/// <returns>A string that represents the current object.</returns>
|
||||
/// <filterpriority>2</filterpriority>
|
||||
public override string ToString()
|
||||
{
|
||||
return Messages.Insight.ToString(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a short string that represents the current object.
|
||||
/// </summary>
|
||||
/// <returns>A string that represents the current object.</returns>
|
||||
public string ShortToString()
|
||||
{
|
||||
return Messages.Insight.ShortToString(this);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Distinguishes between the different ways an insight's period/close times can be specified
|
||||
/// This was really only required since we can't properly acces certain data from within a static
|
||||
/// context (such as Insight.Price) or from within a constructor w/out requiring the users to properly
|
||||
/// fetch the required data and supply it as an argument.
|
||||
/// </summary>
|
||||
private interface IPeriodSpecification
|
||||
{
|
||||
void SetPeriodAndCloseTime(Insight insight, SecurityExchangeHours exchangeHours);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// User defined the insight's period using a time span
|
||||
/// </summary>
|
||||
private class TimeSpanPeriodSpecification : IPeriodSpecification
|
||||
{
|
||||
public readonly TimeSpan Period;
|
||||
|
||||
public TimeSpanPeriodSpecification(TimeSpan period)
|
||||
{
|
||||
if (period == TimeSpan.Zero)
|
||||
{
|
||||
period = Time.OneSecond;
|
||||
}
|
||||
|
||||
Period = period;
|
||||
}
|
||||
|
||||
public void SetPeriodAndCloseTime(Insight insight, SecurityExchangeHours exchangeHours)
|
||||
{
|
||||
insight.Period = Period;
|
||||
insight.CloseTimeUtc = ComputeCloseTime(exchangeHours, insight.GeneratedTimeUtc, Period);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// User defined insight's period using a resolution and bar count
|
||||
/// </summary>
|
||||
private class ResolutionBarCountPeriodSpecification : IPeriodSpecification
|
||||
{
|
||||
public readonly Resolution Resolution;
|
||||
public readonly int BarCount;
|
||||
|
||||
public ResolutionBarCountPeriodSpecification(Resolution resolution, int barCount)
|
||||
{
|
||||
if (resolution == Resolution.Tick)
|
||||
{
|
||||
resolution = Resolution.Second;
|
||||
}
|
||||
|
||||
if (resolution == Resolution.Hour)
|
||||
{
|
||||
// remap hours to minutes to avoid errors w/ half hours, for example, 9:30 open
|
||||
barCount *= 60;
|
||||
resolution = Resolution.Minute;
|
||||
}
|
||||
|
||||
Resolution = resolution;
|
||||
BarCount = barCount;
|
||||
}
|
||||
|
||||
public void SetPeriodAndCloseTime(Insight insight, SecurityExchangeHours exchangeHours)
|
||||
{
|
||||
insight.CloseTimeUtc = ComputeCloseTime(exchangeHours, insight.GeneratedTimeUtc, Resolution, BarCount);
|
||||
insight.Period = insight.CloseTimeUtc - insight.GeneratedTimeUtc;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// User defined the insight's local closing time
|
||||
/// </summary>
|
||||
private class CloseTimePeriodSpecification : IPeriodSpecification
|
||||
{
|
||||
public readonly DateTime CloseTimeLocal;
|
||||
|
||||
public CloseTimePeriodSpecification(DateTime closeTimeLocal)
|
||||
{
|
||||
CloseTimeLocal = closeTimeLocal;
|
||||
}
|
||||
|
||||
public void SetPeriodAndCloseTime(Insight insight, SecurityExchangeHours exchangeHours)
|
||||
{
|
||||
// Prevent close time to be defined to a date/time in closed market
|
||||
var closeTimeLocal = exchangeHours.IsOpen(CloseTimeLocal, false)
|
||||
? CloseTimeLocal
|
||||
: exchangeHours.GetNextMarketOpen(CloseTimeLocal, false);
|
||||
|
||||
insight.CloseTimeUtc = closeTimeLocal.ConvertToUtc(exchangeHours.TimeZone);
|
||||
|
||||
if (insight.GeneratedTimeUtc > insight.CloseTimeUtc)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(closeTimeLocal), $"Insight closeTimeLocal must not be in the past.");
|
||||
}
|
||||
|
||||
insight.Period = insight.CloseTimeUtc - insight.GeneratedTimeUtc;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Special case for insights which close time is defined by a function
|
||||
/// and want insights to expiry with calendar rules
|
||||
/// </summary>
|
||||
private class FuncPeriodSpecification : IPeriodSpecification
|
||||
{
|
||||
public readonly Func<DateTime, DateTime> _expiryFunc;
|
||||
|
||||
public FuncPeriodSpecification(Func<DateTime, DateTime> expiryFunc)
|
||||
{
|
||||
_expiryFunc = expiryFunc;
|
||||
}
|
||||
|
||||
public void SetPeriodAndCloseTime(Insight insight, SecurityExchangeHours exchangeHours)
|
||||
{
|
||||
var closeTimeLocal = insight.GeneratedTimeUtc.ConvertFromUtc(exchangeHours.TimeZone);
|
||||
closeTimeLocal = _expiryFunc(closeTimeLocal);
|
||||
|
||||
// Prevent close time to be defined to a date/time in closed market
|
||||
if (!exchangeHours.IsOpen(closeTimeLocal, false))
|
||||
{
|
||||
closeTimeLocal = exchangeHours.GetNextMarketOpen(closeTimeLocal, false);
|
||||
}
|
||||
|
||||
insight.CloseTimeUtc = closeTimeLocal.ConvertToUtc(exchangeHours.TimeZone);
|
||||
insight.Period = insight.CloseTimeUtc - insight.GeneratedTimeUtc;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Special case for insights where we do not know whats the
|
||||
/// <see cref="Period"/> or <see cref="CloseTimeUtc"/>.
|
||||
/// </summary>
|
||||
private class EndOfTimeCloseTimePeriodSpecification : IPeriodSpecification
|
||||
{
|
||||
public void SetPeriodAndCloseTime(Insight insight, SecurityExchangeHours exchangeHours)
|
||||
{
|
||||
insight.Period = Time.EndOfTimeTimeSpan;
|
||||
insight.CloseTimeUtc = Time.EndOfTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,395 @@
|
||||
/*
|
||||
* 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.Linq;
|
||||
using Python.Runtime;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Alphas
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a collection for managing insights. This type provides collection access semantics
|
||||
/// as well as dictionary access semantics through TryGetValue, ContainsKey, and this[symbol]
|
||||
/// </summary>
|
||||
public class InsightCollection : IEnumerable<Insight>
|
||||
{
|
||||
private int _totalInsightCount;
|
||||
private int _openInsightCount;
|
||||
private readonly List<Insight> _insightsComplete = new();
|
||||
private readonly Dictionary<Symbol, List<Insight>> _insights = new();
|
||||
|
||||
/// <summary>
|
||||
/// The open insight count
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_insights)
|
||||
{
|
||||
return _openInsightCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The total insight count
|
||||
/// </summary>
|
||||
public int TotalCount
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_insights)
|
||||
{
|
||||
return _totalInsightCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1" />.</summary>
|
||||
/// <param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
|
||||
/// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1" /> is read-only.</exception>
|
||||
public void Add(Insight item)
|
||||
{
|
||||
lock (_insights)
|
||||
{
|
||||
_openInsightCount++;
|
||||
_totalInsightCount++;
|
||||
|
||||
_insightsComplete.Add(item);
|
||||
|
||||
if (!_insights.TryGetValue(item.Symbol, out var existingInsights))
|
||||
{
|
||||
_insights[item.Symbol] = existingInsights = new();
|
||||
}
|
||||
existingInsights.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds each item in the specified enumerable of insights to this collection
|
||||
/// </summary>
|
||||
/// <param name="insights">The insights to add to this collection</param>
|
||||
public void AddRange(IEnumerable<Insight> insights)
|
||||
{
|
||||
foreach (var insight in insights)
|
||||
{
|
||||
Add(insight);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Determines whether the <see cref="T:System.Collections.Generic.ICollection`1" /> contains a specific value.</summary>
|
||||
/// <returns>true if <paramref name="item" /> is found in the <see cref="T:System.Collections.Generic.ICollection`1" />; otherwise, false.</returns>
|
||||
/// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
|
||||
public bool Contains(Insight item)
|
||||
{
|
||||
lock(_insights)
|
||||
{
|
||||
return _insights.TryGetValue(item.Symbol, out var symbolInsights)
|
||||
&& symbolInsights.Contains(item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether insights exist in this collection for the specified symbol
|
||||
/// </summary>
|
||||
/// <param name="symbol">The symbol key</param>
|
||||
/// <returns>True if there are insights for the symbol in this collection</returns>
|
||||
public bool ContainsKey(Symbol symbol)
|
||||
{
|
||||
lock (_insights)
|
||||
{
|
||||
return _insights.TryGetValue(symbol, out var symbolInsights)
|
||||
&& symbolInsights.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.ICollection`1" />.</summary>
|
||||
/// <returns>true if <paramref name="item" /> was successfully removed from the <see cref="T:System.Collections.Generic.ICollection`1" />; otherwise, false. This method also returns false if <paramref name="item" /> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1" />.</returns>
|
||||
/// <param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
|
||||
/// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1" /> is read-only.</exception>
|
||||
public bool Remove(Insight item)
|
||||
{
|
||||
lock (_insights)
|
||||
{
|
||||
if (_insights.TryGetValue(item.Symbol, out var symbolInsights))
|
||||
{
|
||||
if (symbolInsights.Remove(item))
|
||||
{
|
||||
_openInsightCount--;
|
||||
|
||||
// remove empty list from dictionary
|
||||
if (symbolInsights.Count == 0)
|
||||
{
|
||||
_insights.Remove(item.Symbol);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dictionary accessor returns a list of insights for the specified symbol
|
||||
/// </summary>
|
||||
/// <param name="symbol">The symbol key</param>
|
||||
/// <returns>List of insights for the symbol</returns>
|
||||
public List<Insight> this[Symbol symbol]
|
||||
{
|
||||
get
|
||||
{
|
||||
lock(_insights)
|
||||
{
|
||||
return _insights[symbol]?.ToList();
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
lock (_insights)
|
||||
{
|
||||
if (_insights.TryGetValue(symbol, out var existingInsights))
|
||||
{
|
||||
_openInsightCount -= existingInsights?.Count ?? 0;
|
||||
}
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
_openInsightCount += value.Count;
|
||||
_totalInsightCount += value.Count;
|
||||
}
|
||||
_insights[symbol] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get the list of insights with the specified symbol key
|
||||
/// </summary>
|
||||
/// <param name="symbol">The symbol key</param>
|
||||
/// <param name="insights">The insights for the specified symbol, or null if not found</param>
|
||||
/// <returns>True if insights for the specified symbol were found, false otherwise</returns>
|
||||
public bool TryGetValue(Symbol symbol, out List<Insight> insights)
|
||||
{
|
||||
lock (_insights)
|
||||
{
|
||||
var result = _insights.TryGetValue(symbol, out insights);
|
||||
if (result)
|
||||
{
|
||||
// for thread safety we need to return a copy of the collection
|
||||
insights = insights.ToList();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Returns an enumerator that iterates through the collection.</summary>
|
||||
/// <returns>A <see cref="T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection.</returns>
|
||||
/// <filterpriority>1</filterpriority>
|
||||
public IEnumerator<Insight> GetEnumerator()
|
||||
{
|
||||
lock (_insights)
|
||||
{
|
||||
return _insights.SelectMany(kvp => kvp.Value).ToList().GetEnumerator();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Returns an enumerator that iterates through a collection.</summary>
|
||||
/// <returns>An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.</returns>
|
||||
/// <filterpriority>2</filterpriority>
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the symbol and its insights
|
||||
/// </summary>
|
||||
/// <param name="symbols">List of symbols that will be removed</param>
|
||||
public void Clear(Symbol[] symbols)
|
||||
{
|
||||
lock (_insights)
|
||||
{
|
||||
foreach (var symbol in symbols)
|
||||
{
|
||||
if (_insights.Remove(symbol, out var existingInsights))
|
||||
{
|
||||
_openInsightCount -= existingInsights.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the next expiry time UTC
|
||||
/// </summary>
|
||||
public DateTime? GetNextExpiryTime()
|
||||
{
|
||||
lock(_insights)
|
||||
{
|
||||
if (_openInsightCount == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// we can't store expiration time because it can change
|
||||
return _insights.Min(x => x.Value.Min(i => i.CloseTimeUtc));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last generated active insight
|
||||
/// </summary>
|
||||
/// <returns>Collection of insights that are active</returns>
|
||||
public ICollection<Insight> GetActiveInsights(DateTime utcTime)
|
||||
{
|
||||
var activeInsights = new List<Insight>();
|
||||
lock (_insights)
|
||||
{
|
||||
foreach (var kvp in _insights)
|
||||
{
|
||||
foreach (var insight in kvp.Value)
|
||||
{
|
||||
if (insight.IsActive(utcTime))
|
||||
{
|
||||
activeInsights.Add(insight);
|
||||
}
|
||||
}
|
||||
}
|
||||
return activeInsights;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if there are active insights for a given symbol and time
|
||||
/// </summary>
|
||||
/// <param name="symbol">The symbol key</param>
|
||||
/// <param name="utcTime">Time that determines whether the insight has expired</param>
|
||||
/// <returns></returns>
|
||||
public bool HasActiveInsights(Symbol symbol, DateTime utcTime)
|
||||
{
|
||||
lock (_insights)
|
||||
{
|
||||
if(_insights.TryGetValue(symbol, out var existingInsights))
|
||||
{
|
||||
return existingInsights.Any(i => i.IsActive(utcTime));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove all expired insights from the collection and retuns them
|
||||
/// </summary>
|
||||
/// <param name="utcTime">Time that determines whether the insight has expired</param>
|
||||
/// <returns>Expired insights that were removed</returns>
|
||||
public ICollection<Insight> RemoveExpiredInsights(DateTime utcTime)
|
||||
{
|
||||
var removedInsights = new List<Insight>();
|
||||
lock (_insights)
|
||||
{
|
||||
foreach (var kvp in _insights)
|
||||
{
|
||||
foreach (var insight in kvp.Value)
|
||||
{
|
||||
if (insight.IsExpired(utcTime))
|
||||
{
|
||||
removedInsights.Add(insight);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (var insight in removedInsights)
|
||||
{
|
||||
Remove(insight);
|
||||
}
|
||||
}
|
||||
return removedInsights;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will remove insights from the complete insight collection
|
||||
/// </summary>
|
||||
/// <param name="filter">The function that will determine which insight to remove</param>
|
||||
public void RemoveInsights(Func<Insight, bool> filter)
|
||||
{
|
||||
lock (_insights)
|
||||
{
|
||||
_insightsComplete.RemoveAll(insight => filter(insight));
|
||||
|
||||
// for consistentcy remove from open insights just in case
|
||||
List<Insight> insightsToRemove = null;
|
||||
foreach (var insights in _insights.Values)
|
||||
{
|
||||
foreach (var insight in insights)
|
||||
{
|
||||
if (filter(insight))
|
||||
{
|
||||
insightsToRemove ??= new ();
|
||||
insightsToRemove.Add(insight);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(insightsToRemove != null)
|
||||
{
|
||||
foreach (var insight in insightsToRemove)
|
||||
{
|
||||
Remove(insight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will return insights from the complete insight collection
|
||||
/// </summary>
|
||||
/// <param name="filter">The function that will determine which insight to return</param>
|
||||
/// <returns>A new list containing the selected insights</returns>
|
||||
public List<Insight> GetInsights(Func<Insight, bool> filter = null)
|
||||
{
|
||||
lock (_insights)
|
||||
{
|
||||
if(filter == null)
|
||||
{
|
||||
return _insightsComplete.ToList();
|
||||
}
|
||||
return _insightsComplete.Where(filter).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will return insights from the complete insight collection
|
||||
/// </summary>
|
||||
/// <param name="filter">The function that will determine which insight to return</param>
|
||||
/// <returns>A new list containing the selected insights</returns>
|
||||
public List<Insight> GetInsights(PyObject filter)
|
||||
{
|
||||
Func<Insight, bool> convertedFilter;
|
||||
if (filter.TrySafeAs(out convertedFilter))
|
||||
{
|
||||
return GetInsights(convertedFilter);
|
||||
}
|
||||
else
|
||||
{
|
||||
using (Py.GIL())
|
||||
{
|
||||
throw new ArgumentException($"InsightCollection.GetInsights: {filter.Repr()} is not a valid argument.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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 Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Alphas
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies the predicted direction for a insight (price/volatility)
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter), true)]
|
||||
public enum InsightDirection
|
||||
{
|
||||
/// <summary>
|
||||
/// The value will go down (-1)
|
||||
/// </summary>
|
||||
Down = -1,
|
||||
|
||||
/// <summary>
|
||||
/// The value will stay flat (0)
|
||||
/// </summary>
|
||||
Flat = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The value will go up (1)
|
||||
/// </summary>
|
||||
Up = 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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 Newtonsoft.Json;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Alphas
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the scores given to a particular insight
|
||||
/// </summary>
|
||||
public class InsightScore
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the time these scores were last updated
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public DateTime UpdatedTimeUtc { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the direction score
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public double Direction { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the magnitude score
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public double Magnitude { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether or not this is the insight's final score
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public bool IsFinalScore { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new, default instance of the <see cref="InsightScore"/> class
|
||||
/// </summary>
|
||||
public InsightScore()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="InsightScore"/> class
|
||||
/// </summary>
|
||||
/// <param name="direction">The insight direction score</param>
|
||||
/// <param name="magnitude">The insight percent change score</param>
|
||||
/// <param name="updatedTimeUtc">The algorithm utc time these scores were computed</param>
|
||||
public InsightScore(double direction, double magnitude, DateTime updatedTimeUtc)
|
||||
{
|
||||
Direction = direction;
|
||||
Magnitude = magnitude;
|
||||
UpdatedTimeUtc = updatedTimeUtc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the specified score type with the value
|
||||
/// </summary>
|
||||
/// <param name="type">The score type to be set, Direction/Magnitude</param>
|
||||
/// <param name="value">The new value for the score</param>
|
||||
/// <param name="algorithmUtcTime">The algorithm's utc time at which time the new score was computed</param>
|
||||
public void SetScore(InsightScoreType type, double value, DateTime algorithmUtcTime)
|
||||
{
|
||||
if (IsFinalScore) return;
|
||||
|
||||
UpdatedTimeUtc = algorithmUtcTime;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case InsightScoreType.Direction:
|
||||
Direction = Math.Max(0, Math.Min(1, value));
|
||||
break;
|
||||
|
||||
case InsightScoreType.Magnitude:
|
||||
Magnitude = Math.Max(0, Math.Min(1, value));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(type), type, null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Marks the score as finalized, preventing any further updates.
|
||||
/// </summary>
|
||||
/// <param name="algorithmUtcTime">The algorithm's utc time at which time these scores were finalized</param>
|
||||
public void Finalize(DateTime algorithmUtcTime)
|
||||
{
|
||||
IsFinalScore = true;
|
||||
UpdatedTimeUtc = algorithmUtcTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the specified score
|
||||
/// </summary>
|
||||
/// <param name="type">The type of score to get, Direction/Magnitude</param>
|
||||
/// <returns>The requested score</returns>
|
||||
public double GetScore(InsightScoreType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case InsightScoreType.Direction:
|
||||
return Direction;
|
||||
|
||||
case InsightScoreType.Magnitude:
|
||||
return Magnitude;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(type), type, null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Returns a string that represents the current object.</summary>
|
||||
/// <returns>A string that represents the current object.</returns>
|
||||
/// <filterpriority>2</filterpriority>
|
||||
public override string ToString()
|
||||
{
|
||||
return Messages.InsightScore.ToString(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 Python.Runtime;
|
||||
using QuantConnect.Algorithm.Framework.Alphas.Analysis;
|
||||
using QuantConnect.Python;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Alphas
|
||||
{
|
||||
/// <summary>
|
||||
/// A python implementation insight evaluator wrapper
|
||||
/// </summary>
|
||||
public class InsightScoreFunctionPythonWrapper : BasePythonWrapper<IInsightScoreFunction>, IInsightScoreFunction
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new python wrapper instance
|
||||
/// </summary>
|
||||
/// <param name="insightEvaluator">The python instance to wrap</param>
|
||||
public InsightScoreFunctionPythonWrapper(PyObject insightEvaluator)
|
||||
: base(insightEvaluator)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to evaluate and score insights for each time step
|
||||
/// </summary>
|
||||
public void Score(InsightManager insightManager, DateTime utcTime)
|
||||
{
|
||||
InvokeMethod(nameof(Score), insightManager, utcTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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 Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Alphas
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a specific type of score for a insight
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter), true)]
|
||||
public enum InsightScoreType
|
||||
{
|
||||
/// <summary>
|
||||
/// Directional accuracy (0)
|
||||
/// </summary>
|
||||
Direction,
|
||||
|
||||
/// <summary>
|
||||
/// Magnitude accuracy (1)
|
||||
/// </summary>
|
||||
Magnitude
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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 Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Alphas
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies the type of insight
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter), true)]
|
||||
public enum InsightType
|
||||
{
|
||||
/// <summary>
|
||||
/// The insight is for a security's price (0)
|
||||
/// </summary>
|
||||
Price,
|
||||
|
||||
/// <summary>
|
||||
/// The insight is for a security's price volatility (1)
|
||||
/// </summary>
|
||||
Volatility
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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 QuantConnect.Util;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Alphas.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines how insights should be serialized to json
|
||||
/// </summary>
|
||||
public class InsightJsonConverter : TypeChangeJsonConverter<Insight, SerializedInsight>
|
||||
{
|
||||
/// <summary>
|
||||
/// Convert the input value to a value to be serialized
|
||||
/// </summary>
|
||||
/// <param name="value">The input value to be converted before serialization</param>
|
||||
/// <returns>A new instance of TResult that is to be serialized</returns>
|
||||
protected override SerializedInsight Convert(Insight value)
|
||||
{
|
||||
return new SerializedInsight(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the input value to be deserialized
|
||||
/// </summary>
|
||||
/// <param name="value">The deserialized value that needs to be converted to T</param>
|
||||
/// <returns>The converted value</returns>
|
||||
protected override Insight Convert(SerializedInsight value)
|
||||
{
|
||||
return Insight.FromSerializedInsight(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* 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 Newtonsoft.Json;
|
||||
using QuantConnect.Util;
|
||||
using System;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Alphas.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// DTO used for serializing an insight that was just generated by an algorithm.
|
||||
/// This type does not contain any of the analysis dependent fields, such as scores
|
||||
/// and estimated value
|
||||
/// </summary>
|
||||
public class SerializedInsight
|
||||
{
|
||||
private double _createdTime;
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="Insight.Id"/>
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="Insight.GroupId"/>
|
||||
/// </summary>
|
||||
public string GroupId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="Insight.SourceModel"/>
|
||||
/// </summary>
|
||||
public string SourceModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Pass-through for <see cref="CreatedTime"/>
|
||||
/// </summary>
|
||||
[Obsolete("Deprecated as of 2020-01-23. Please use the `CreatedTime` property instead.")]
|
||||
public double GeneratedTime
|
||||
{
|
||||
get { return _createdTime; }
|
||||
set { _createdTime = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="Insight.GeneratedTimeUtc"/>
|
||||
/// </summary>
|
||||
public double CreatedTime
|
||||
{
|
||||
get { return _createdTime; }
|
||||
set { _createdTime = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="Insight.CloseTimeUtc"/>
|
||||
/// </summary>
|
||||
public double CloseTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="Insight.Symbol"/>
|
||||
/// The symbol's security identifier string
|
||||
/// </summary>
|
||||
public string Symbol { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="Insight.Symbol"/>
|
||||
/// The symbol's ticker at the generated time
|
||||
/// </summary>
|
||||
public string Ticker { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="Insight.Type"/>
|
||||
/// </summary>
|
||||
public InsightType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="Insight.ReferenceValue"/>
|
||||
/// </summary>
|
||||
[JsonProperty("reference")]
|
||||
public decimal ReferenceValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="Insight.ReferenceValueFinal"/>
|
||||
/// </summary>
|
||||
public decimal ReferenceValueFinal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="Insight.Direction"/>
|
||||
/// </summary>
|
||||
public InsightDirection Direction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="Insight.Period"/>
|
||||
/// </summary>
|
||||
public double Period { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="Insight.Magnitude"/>
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(JsonRoundingConverter))]
|
||||
public double? Magnitude { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="Insight.Confidence"/>
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(JsonRoundingConverter))]
|
||||
public double? Confidence { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="Insight.Weight"/>
|
||||
/// </summary>
|
||||
public double? Weight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="InsightScore.IsFinalScore"/>
|
||||
/// </summary>
|
||||
public bool ScoreIsFinal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="InsightScore.Magnitude"/>
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(JsonRoundingConverter))]
|
||||
public double ScoreMagnitude { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="InsightScore.Direction"/>
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(JsonRoundingConverter))]
|
||||
public double ScoreDirection { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="Insight.EstimatedValue"/>
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(JsonRoundingConverter))]
|
||||
public decimal EstimatedValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="Insight.Tag"/>
|
||||
/// </summary>
|
||||
public string Tag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new default instance of the <see cref="SerializedInsight"/> class
|
||||
/// </summary>
|
||||
public SerializedInsight()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SerializedInsight "/> class by copying the specified insight
|
||||
/// </summary>
|
||||
/// <param name="insight">The insight to copy</param>
|
||||
public SerializedInsight(Insight insight)
|
||||
{
|
||||
Id = insight.Id.ToStringInvariant("N");
|
||||
SourceModel = insight.SourceModel;
|
||||
GroupId = insight.GroupId?.ToStringInvariant("N");
|
||||
CreatedTime = Time.DateTimeToUnixTimeStamp(insight.GeneratedTimeUtc);
|
||||
CloseTime = Time.DateTimeToUnixTimeStamp(insight.CloseTimeUtc);
|
||||
Symbol = insight.Symbol.ID.ToString();
|
||||
Ticker = insight.Symbol.Value;
|
||||
Type = insight.Type;
|
||||
ReferenceValue = insight.ReferenceValue;
|
||||
ReferenceValueFinal = insight.ReferenceValueFinal;
|
||||
Direction = insight.Direction;
|
||||
Period = insight.Period.TotalSeconds;
|
||||
Magnitude = insight.Magnitude;
|
||||
Confidence = insight.Confidence;
|
||||
ScoreIsFinal = insight.Score.IsFinalScore;
|
||||
ScoreMagnitude = insight.Score.Magnitude;
|
||||
ScoreDirection = insight.Score.Direction;
|
||||
EstimatedValue = insight.EstimatedValue;
|
||||
Weight = insight.Weight;
|
||||
Tag = insight.Tag;
|
||||
}
|
||||
|
||||
#region BackwardsCompatibility
|
||||
[JsonProperty("group-id")]
|
||||
string OldGroupId
|
||||
{
|
||||
set
|
||||
{
|
||||
GroupId = value;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("source-model")]
|
||||
string OldSourceModel
|
||||
{
|
||||
set
|
||||
{
|
||||
SourceModel = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pass-through for <see cref="CreatedTime"/>
|
||||
/// </summary>
|
||||
[JsonProperty("generated-time")]
|
||||
double OldGeneratedTime
|
||||
{
|
||||
set
|
||||
{
|
||||
GeneratedTime = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="Insight.GeneratedTimeUtc"/>
|
||||
/// </summary>
|
||||
[JsonProperty("created-time")]
|
||||
public double OldCreatedTime
|
||||
{
|
||||
set
|
||||
{
|
||||
CreatedTime = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="Insight.CloseTimeUtc"/>
|
||||
/// </summary>
|
||||
[JsonProperty("close-time")]
|
||||
public double OldCloseTime
|
||||
{
|
||||
set
|
||||
{
|
||||
CloseTime = value;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("reference-final")]
|
||||
decimal OldReferenceValueFinal
|
||||
{
|
||||
set
|
||||
{
|
||||
ReferenceValueFinal = value;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("score-final")]
|
||||
bool OldScoreIsFinal
|
||||
{
|
||||
set
|
||||
{
|
||||
ScoreIsFinal = value;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("score-magnitude")]
|
||||
[JsonConverter(typeof(JsonRoundingConverter))]
|
||||
double OldScoreMagnitude
|
||||
{
|
||||
set
|
||||
{
|
||||
ScoreMagnitude = value;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("score-direction")]
|
||||
[JsonConverter(typeof(JsonRoundingConverter))]
|
||||
double OldScoreDirection
|
||||
{
|
||||
set
|
||||
{
|
||||
ScoreDirection = value;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("estimated-value")]
|
||||
[JsonConverter(typeof(JsonRoundingConverter))]
|
||||
decimal OldEstimatedValue
|
||||
{
|
||||
set
|
||||
{
|
||||
EstimatedValue = value;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user