/* * 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 QuantConnect.Orders; using QuantConnect.Securities; namespace QuantConnect.Algorithm.Framework.Alphas { /// /// Helper class used by classic algorithms to generate new insights based on order fills. /// public class OrderBasedInsightGenerator { /// /// Source model for the insights generated by /// public const string AutoGeneratedSourceModel = "AutoGeneratedInsightFromOrderEvent"; private readonly Dictionary _insights = new Dictionary(); /// /// Generates a new insight for a given . /// /// The to create a new /// from /// The of the /// related /// public Insight GenerateInsightFromFill(OrderEvent orderEvent, SecurityHolding securityHolding) { var desiredFinalQuantity = orderEvent.FillQuantity + securityHolding.Quantity; Insight existingInsight; _insights.TryGetValue(orderEvent.Symbol, out existingInsight); double? confidence; if (// new position securityHolding.Quantity == 0 // closing the entire position || desiredFinalQuantity == 0 // changing market sides || Math.Sign(desiredFinalQuantity) != Math.Sign(securityHolding.Quantity) // increasing the position || Math.Sign(orderEvent.FillQuantity) == Math.Sign(securityHolding.Quantity)) { confidence = 1; } else { // we are reducing the position, so set the confidence based on the original position confidence = (double)(securityHolding.AbsoluteQuantity - orderEvent.AbsoluteFillQuantity) / (double) securityHolding.AbsoluteQuantity; if (existingInsight != null) { // we have to adjust new confidence based on previous confidence = confidence * existingInsight.Confidence; } } var insightDirection = desiredFinalQuantity > 0 ? InsightDirection.Up : desiredFinalQuantity == 0 ? InsightDirection.Flat : InsightDirection.Down; var insight = Insight.Price(orderEvent.Symbol, Time.EndOfTime, insightDirection, null, confidence, AutoGeneratedSourceModel); insight.GeneratedTimeUtc = orderEvent.UtcTime; // When a new insight is generated, will update the // of the previous insight for the same . if (existingInsight != null) { // close the previous insight existingInsight.CloseTimeUtc = insight.GeneratedTimeUtc; _insights.Remove(insight.Symbol); } _insights.Add(insight.Symbol, insight); insight.SetPeriodAndCloseTime(null); return insight; } } }