示例#1
0
        /// <summary>
        /// Updates this alpha model with the latest data from the algorithm.
        /// This is called each time the algorithm receives data for subscribed securities
        /// </summary>
        /// <param name="algorithm">The algorithm instance</param>
        /// <param name="data">The new data available</param>
        /// <returns>The new insights generated</returns>
        public override IEnumerable <Insight> Update(QCAlgorithmFramework algorithm, Slice data)
        {
            var insights = new List <Insight>();

            foreach (var kvp in _symbolDataBySymbol)
            {
                var         symbol = kvp.Key;
                OptionChain chain;
                if (!TryGetOptionChain(algorithm, symbol, out chain))
                {
                    return(insights);
                }
                //compute IV from some ATM options
                decimal iv      = 0;
                var     options = chain.Where((o) => o.UnderlyingLastPrice > o.Strike - STRIKE_SPREAD && o.UnderlyingLastPrice < o.Strike + STRIKE_SPREAD);
                if (options.Count() < 2)
                {
                    algorithm.Log("No options available to compute IV!");
                    return(insights);
                }
                iv = AverageIV(algorithm, options);

                kvp.Value.Update(data.Time, iv);

                var    std           = kvp.Value.STD;
                var    previousState = kvp.Value.State;
                var    previousMag   = kvp.Value.Mag;
                double mag;
                var    state = GetState(std, out mag);

                if ((state != previousState || mag > previousMag) && std.IsReady)
                {
                    var insightPeriod = _resolution.Multiply(_period);

                    switch (state)
                    {
                    case State.Neutral:
                        insights.Add(Insight.Price(symbol, insightPeriod, InsightDirection.Flat));
                        break;

                    case State.TrippedHigh:
                        insights.Add(Insight.Price(symbol, insightPeriod, _inverted ? InsightDirection.Up : InsightDirection.Down, mag));
                        break;

                    case State.TrippedLow:
                        insights.Add(Insight.Price(symbol, insightPeriod, _inverted ? InsightDirection.Down : InsightDirection.Up, mag));
                        break;
                    }

                    kvp.Value.State = state;
                    kvp.Value.Mag   = mag;
                }
            }

            return(insights);
        }
示例#2
0
        /// <summary>
        /// Updates this alpha model with the latest data from the algorithm.
        /// This is called each time the algorithm receives data for subscribed securities
        /// </summary>
        /// <param name="algorithm">The algorithm instance</param>
        /// <param name="data">The new data available</param>
        /// <returns>The new insights generated</returns>
        public override IEnumerable <Insight> Update(QCAlgorithmFramework algorithm, Slice data)
        {
            var insights = new List <Insight>();

            foreach (var kvp in _symbolDataBySymbol)
            {
                var         symbol = kvp.Key;
                OptionChain chain;
                if (!TryGetOptionChain(algorithm, symbol, out chain))
                {
                    return(insights);
                }

                decimal max_pain_strike = FindMaxPain(algorithm, chain);

                if (max_pain_strike <= 0)
                {
                    algorithm.Log("Insufficient data to compute max pain!");
                    return(insights);
                }
                //find the distance of price to the current max pain strike
                decimal max_pain_distance = chain.Underlying.Price - max_pain_strike;
                kvp.Value.Update(data.Time, max_pain_strike, max_pain_distance);

                var    std           = kvp.Value.STD;
                var    previousState = kvp.Value.State;
                var    previousMag   = kvp.Value.Mag;
                double mag;
                var    state = GetState(std, max_pain_distance, out mag); //get the STD (magnitude)

                if ((state != previousState || mag > previousMag) && std.IsReady)
                {
                    var insightPeriod = _resolution.Multiply(_period);

                    switch (state)
                    {
                    case State.Neutral:
                        insights.Add(Insight.Price(symbol, insightPeriod, InsightDirection.Flat));
                        break;

                    case State.TrippedHigh:     //bullish
                        insights.Add(Insight.Price(symbol, insightPeriod, _inverted ? InsightDirection.Down : InsightDirection.Up, mag));
                        break;

                    case State.TrippedLow:     //bearish
                        insights.Add(Insight.Price(symbol, insightPeriod, _inverted ? InsightDirection.Up : InsightDirection.Down, mag));
                        break;
                    }

                    kvp.Value.State = state;
                    kvp.Value.Mag   = mag;
                }
            }

            return(insights);
        }
        /// <summary>
        /// Updates this alpha model with the latest data from the algorithm.
        /// This is called each time the algorithm receives data for subscribed securities
        /// </summary>
        /// <param name="algorithm">The algorithm instance</param>
        /// <param name="data">The new data available</param>
        /// <returns>The new insights generated</returns>
        public override IEnumerable <Insight> Update(QCAlgorithmFramework algorithm, Slice data)
        {
            var insights = new List <Insight>();

            foreach (var kvp in _symbolDataBySymbol)
            {
                var symbol = kvp.Key;
                try
                {
                    var frontOptions = OptionTools.GetOptionsForExpiry(algorithm, symbol, 0);
                    var backOptions  = OptionTools.GetOptionsForExpiry(algorithm, symbol, 1);

                    var frontiv = AverageIV(algorithm, frontOptions);
                    var backiv  = AverageIV(algorithm, backOptions);

                    kvp.Value.Update(data.Time, frontiv, backiv);
                } catch (Exception ex)
                {
                    algorithm.Log("Failed to compute IV!");
                    continue;
                }

                var    std           = kvp.Value.STD;
                var    previousState = kvp.Value.State;
                var    previousMag   = kvp.Value.Mag;
                double mag;
                var    state = GetState(std, out mag);

                if ((state != previousState || mag > previousMag) && std.IsReady)
                {
                    var insightPeriod = _resolution.Multiply(_period);

                    switch (state)
                    {
                    case State.Neutral:
                        insights.Add(Insight.Price(symbol, insightPeriod, InsightDirection.Flat));
                        break;

                    case State.TrippedHigh:
                        insights.Add(Insight.Price(symbol, insightPeriod, _inverted ? InsightDirection.Up : InsightDirection.Down, mag));
                        break;

                    case State.TrippedLow:
                        insights.Add(Insight.Price(symbol, insightPeriod, _inverted ? InsightDirection.Down : InsightDirection.Up, mag));
                        break;
                    }

                    kvp.Value.State = state;
                    kvp.Value.Mag   = mag;
                }
            }

            return(insights);
        }
示例#4
0
        /// <summary>
        /// Updates this alpha model with the latest data from the algorithm.
        /// This is called each time the algorithm receives data for subscribed securities
        /// </summary>
        /// <param name="algorithm">The algorithm instance</param>
        /// <param name="data">The new data available</param>
        /// <returns>The new insights generated</returns>
        public override IEnumerable <Insight> Update(QCAlgorithmFramework algorithm, Slice data)
        {
            var insights = new List <Insight>();

            foreach (var kvp in _symbolDataBySymbol)
            {
                if (!data.ContainsKey(kvp.Key) || data[kvp.Key] == null)
                {
                    continue;
                }

                var symbol = kvp.Key;
                kvp.Value.Update(data[kvp.Key]);

                var std = kvp.Value.STD;
                if (!std.IsReady)
                {
                    continue;
                }

                var    previousState = kvp.Value.State;
                var    previousMag   = kvp.Value.Mag;
                double mag;
                var    state = GetState(kvp.Value.Indicator.Current.Value, std, out mag);

                if ((state != previousState || mag > previousMag) && std.IsReady)
                {
                    var insightPeriod = _resolution.Multiply(_period);

                    switch (state)
                    {
                    case State.Neutral:
                        insights.Add(Insight.Price(symbol, insightPeriod, InsightDirection.Flat));
                        break;

                    case State.TrippedHigh:
                        insights.Add(Insight.Price(symbol, insightPeriod, _inverted ? InsightDirection.Up : InsightDirection.Down, mag));
                        break;

                    case State.TrippedLow:
                        insights.Add(Insight.Price(symbol, insightPeriod, _inverted ? InsightDirection.Down : InsightDirection.Up, mag));
                        break;
                    }

                    kvp.Value.State = state;
                    kvp.Value.Mag   = mag;
                }
            }

            return(insights);
        }
示例#5
0
        /// <summary>
        /// Updates this alpha model with the latest data from the algorithm.
        /// This is called each time the algorithm receives data for subscribed securities
        /// </summary>
        /// <param name="algorithm">The algorithm instance</param>
        /// <param name="data">The new data available</param>
        /// <returns>The new insights generated</returns>
        public override IEnumerable <Insight> Update(QCAlgorithm algorithm, Slice data)
        {
            var insights = new List <Insight>();

            foreach (var symbolData in _symbolDataBySymbol.Values)
            {
                if (symbolData.Fast.IsReady && symbolData.Slow.IsReady)
                {
                    var ratio1        = (double)symbolData.Slow.Current.Value / (double)symbolData.Fast.Current.Value;
                    var ratio2        = (double)symbolData.Fast.Current.Value / (double)symbolData.Slow.Current.Value;
                    var insightPeriod = _resolution.ToTimeSpan().Multiply(_predictionInterval);
                    if (symbolData.FastIsOverSlow)
                    {
                        if (ratio1 > 1.0005)
                        {
                            insights.Add(Insight.Price(
                                             symbolData.Symbol,
                                             _resolution,
                                             _predictionInterval,
                                             InsightDirection.Down,
                                             null, null, null,
                                             ratio1
                                             ));
                        }
                    }
                    else if (symbolData.SlowIsOverFast)
                    {
                        if (ratio2 > 1.0005)
                        {
                            insights.Add(Insight.Price(
                                             symbolData.Symbol,
                                             _resolution,
                                             _predictionInterval,
                                             InsightDirection.Up,
                                             null, null, null,
                                             ratio2
                                             ));
                        }
                    }
                }

                symbolData.FastIsOverSlow = symbolData.Fast > symbolData.Slow;
            }

            return(insights);
        }
示例#6
0
        /// <summary>
        /// Updates this alpha model with the latest data from the algorithm.
        /// This is called each time the algorithm receives data for subscribed securities
        /// </summary>
        /// <param name="algorithm">The algorithm instance</param>
        /// <param name="data">The new data available</param>
        /// <returns>The new insights generated</returns>
        public override IEnumerable <Insight> Update(QCAlgorithmFramework algorithm, Slice data)
        {
            if (data == null || data.OptionChains == null || data.OptionChains.Count() < 1)
            {
                return(new List <Insight>());
            }

            var chainItem = data.OptionChains.First();
            var symbol    = chainItem.Key.Underlying;

            var options = OptionTools.GetOptionsForExpiry(algorithm, symbol, 0);

            var count = options.Where((o) =>
                                      (o.Expiry - data.Time).TotalDays <= _daysOpenBegin &&
                                      (o.Expiry - data.Time).TotalDays >= _daysOpenEnd)
                        .Count();

            if (count > 0)
            {
                return(new List <Insight>()
                {
                    Insight.Price(chainItem.Key.Underlying, TimeSpan.FromDays(1), InsightDirection.Up)
                });
            }

            count = options.Where((o) =>
                                  Math.Abs((o.Expiry - data.Time).TotalDays) <= _daysCloseBegin &&
                                  Math.Abs((o.Expiry - data.Time).TotalDays) >= _daysCloseEnd)
                    .Count();
            if (count > 0)
            {
                return(new List <Insight>()
                {
                    Insight.Price(chainItem.Key.Underlying, TimeSpan.FromDays(1), InsightDirection.Down)
                });
            }

            return(new List <Insight>());
        }
示例#7
0
        /// <summary>
        /// Updates this alpha model with the latest data from the algorithm.
        /// This is called each time the algorithm receives data for subscribed securities
        /// </summary>
        /// <param name="algorithm">The algorithm instance</param>
        /// <param name="data">The new data available</param>
        /// <returns>The new insights generated</returns>
        public override IEnumerable <Insight> Update(QCAlgorithm algorithm, Slice data)
        {
            var insights = new List <Insight>();

            foreach (var symbolData in _symbolDataBySymbol.Values)
            {
                if (symbolData.CanEmit())
                {
                    var direction = InsightDirection.Flat;
                    var magnitude = (double)symbolData.ROC.Current.Value;
                    if (magnitude > 0)
                    {
                        direction = InsightDirection.Up;
                    }
                    if (magnitude < 0)
                    {
                        direction = InsightDirection.Down;
                    }
                    insights.Add(Insight.Price(symbolData.Security.Symbol, _predictionInterval, direction, magnitude, null));
                }
            }
            return(insights);
        }
示例#8
0
        /// <summary>
        /// Updates this alpha model with the latest data from the algorithm.
        /// This is called each time the algorithm receives data for subscribed securities
        /// </summary>
        /// <param name="algorithm">The algorithm instance</param>
        /// <param name="data">The new data available</param>
        /// <returns>The new insights generated</returns>
        public virtual IEnumerable <Insight> Update(QCAlgorithmFramework algorithm, Slice data)
        {
            if (_mean?.IsReady != true)
            {
                return(Enumerable.Empty <Insight>());
            }

            // don't re-emit the same direction
            if (_state != State.LongRatio && _ratio > _upperThreshold)
            {
                _state = State.LongRatio;

                // asset1/asset2 is more than 2 std away from mean, short asset1, long asset2
                var shortAsset1 = Insight.Price(_asset1, TimeSpan.FromMinutes(15), InsightDirection.Down);
                var longAsset2  = Insight.Price(_asset2, TimeSpan.FromMinutes(15), InsightDirection.Up);

                // creates a group id and set the GroupId property on each insight object
                Insight.Group(shortAsset1, longAsset2);
                return(new[] { shortAsset1, longAsset2 });
            }

            // don't re-emit the same direction
            if (_state != State.ShortRatio && _ratio < _lowerThreshold)
            {
                _state = State.ShortRatio;

                // asset1/asset2 is less than 2 std away from mean, long asset1, short asset2
                var longAsset1  = Insight.Price(_asset1, TimeSpan.FromMinutes(15), InsightDirection.Up);
                var shortAsset2 = Insight.Price(_asset2, TimeSpan.FromMinutes(15), InsightDirection.Down);

                // creates a group id and set the GroupId property on each insight object
                Insight.Group(longAsset1, shortAsset2);
                return(new[] { longAsset1, shortAsset2 });
            }

            return(Enumerable.Empty <Insight>());
        }
示例#9
0
        /// <summary>
        /// Updates this alpha model with the latest data from the algorithm.
        /// This is called each time the algorithm receives data for subscribed securities
        /// </summary>
        /// <param name="algorithm">The algorithm instance</param>
        /// <param name="data">The new data available</param>
        /// <returns>The new insights generated</returns>
        public override IEnumerable <Insight> Update(QCAlgorithmFramework algorithm, Slice data)
        {
            var insights = new List <Insight>();

            foreach (var symbolData in _symbolDataBySymbol.Values)
            {
                if (data.ContainsKey(symbolData.Symbol) && symbolData.BB.IsReady)
                {
                    var bar = ((TradeBar)data[symbolData.Symbol]);
                    if (bar == null)
                    {
                        return(insights);
                    }

                    symbolData.Update(bar);

                    var price                  = bar.Price;
                    var insightPeriod          = _resolution.ToTimeSpan().Multiply(_period);
                    InsightDirection?direction = null;

                    if (price <= symbolData.BB.LowerBand.Current.Price)
                    {
                        direction = InsightDirection.Down;
                    }
                    else if (price >= symbolData.BB.UpperBand.Current.Price)
                    {
                        direction = InsightDirection.Up;
                    }
                    else
                    {
                        if (symbolData.LastDirection == InsightDirection.Up)
                        {
                            if (price <= symbolData.BB.MiddleBand.Current.Price)
                            {
                                direction = InsightDirection.Flat;
                            }
                        }
                        if (symbolData.LastDirection == InsightDirection.Down)
                        {
                            if (price >= symbolData.BB.MiddleBand.Current.Price)
                            {
                                direction = InsightDirection.Flat;
                            }
                        }
                    }

                    if (direction != null && direction != symbolData.LastDirection)
                    {
                        symbolData.LastDirection = (InsightDirection)direction;

                        if (direction == InsightDirection.Down)
                        {
                            insights.Add(Insight.Price(symbolData.Symbol, insightPeriod, _inverted ? InsightDirection.Down : InsightDirection.Up));
                        }
                        else if (direction == InsightDirection.Up)
                        {
                            insights.Add(Insight.Price(symbolData.Symbol, insightPeriod, _inverted ? InsightDirection.Up : InsightDirection.Down));
                        }
                        else
                        {
                            insights.Add(Insight.Price(symbolData.Symbol, insightPeriod, InsightDirection.Flat));
                        }
                    }
                }
            }

            return(insights);
        }
示例#10
0
        /// <summary>
        /// Updates this alpha model with the latest data from the algorithm.
        /// This is called each time the algorithm receives data for subscribed securities
        /// </summary>
        /// <param name="algorithm">The algorithm instance</param>
        /// <param name="data">The new data available</param>
        /// <returns>The new insights generated</returns>
        public override IEnumerable <Insight> Update(QCAlgorithmFramework algorithm, Slice data)
        {
            var insights = new List <Insight>();

            foreach (var kvp in _symbolDataBySymbol)
            {
                var         symbol = kvp.Key;
                OptionChain chain;
                if (!TryGetOptionChain(algorithm, symbol, out chain))
                {
                    return(insights);
                }

                decimal calls_iv = 0;
                decimal puts_iv  = 0;
                //compute IV for all reasonable OTM calls
                var options = chain.Where((o) => o.Right == OptionRight.Call && o.UnderlyingLastPrice <o.Strike && o.AskPrice> .15m);
                calls_iv = AverageIV(algorithm, options);
                //compute IV for all reasonable OTM puts
                options = chain.Where((o) => o.Right == OptionRight.Put && o.UnderlyingLastPrice > o.Strike && o.AskPrice > .15m);
                puts_iv = AverageIV(algorithm, options);

                if (calls_iv <= 0 || puts_iv <= 0)
                {
                    algorithm.Log("Insufficient data to compute skew!");
                    return(insights);
                }
                //calls - puts => ratio, +skew bullish, -skew bearish
                decimal iv_ratio = calls_iv - puts_iv;
                kvp.Value.Update(data.Time, iv_ratio);                 //get the STD (magnitude) of skew

                var    std           = kvp.Value.STD;
                var    previousState = kvp.Value.State;
                var    previousMag   = kvp.Value.Mag;
                double mag;
                var    state = GetState(std, iv_ratio, out mag);

                if ((state != previousState || mag > previousMag) && std.IsReady)
                {
                    var insightPeriod = _resolution.Multiply(_period);

                    switch (state)
                    {
                    case State.Neutral:
                        insights.Add(Insight.Price(symbol, insightPeriod, InsightDirection.Flat));
                        break;

                    case State.TrippedHigh:     //bullish
                        insights.Add(Insight.Price(symbol, insightPeriod, _inverted ? InsightDirection.Down : InsightDirection.Up, mag));
                        break;

                    case State.TrippedLow:     //bearish
                        insights.Add(Insight.Price(symbol, insightPeriod, _inverted ? InsightDirection.Up : InsightDirection.Down, mag));
                        break;
                    }

                    kvp.Value.State = state;
                    kvp.Value.Mag   = mag;
                }
            }

            return(insights);
        }
        /// <summary>
        /// Generates a new insight for a given <see cref="OrderEvent"/>.
        /// </summary>
        /// <param name="orderEvent">The <see cref="OrderEvent"/> to create a new
        /// <see cref="Insight"/> from</param>
        /// <param name="securityHolding">The <see cref="SecurityHolding"/> of the
        /// related <see cref="OrderEvent.Symbol"/></param>
        /// <returns></returns>
        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 <see cref="Insight.CloseTimeUtc"/>
            // of the previous insight for the same <see cref="Symbol"/>.
            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);
        }