/// <summary>
        /// Get GetATM options for nearest available expiration.
        /// </summary>
        protected Tuple <OptionContract, OptionContract> GetATM(QCAlgorithmFramework algorithim, Symbol underlyingSymbol, int expiryDistance = 0)
        {
            IOrderedEnumerable <OptionContract> selected = OptionTools.GetOptionsForExpiry(algorithim, underlyingSymbol, expiryDistance);

            if (selected == null)
            {
                return(null);
            }

            var put = selected
                      .Where(o => o.Right == OptionRight.Put &&
                             o.Strike - 0.5m < o.UnderlyingLastPrice)
                      //sort by distance from atm
                      .OrderBy(o => Math.Abs(o.UnderlyingLastPrice - o.Strike)).FirstOrDefault();

            if (put == null)
            {
                return(null);
            }


            var call = selected
                       .Where(o => o.Right == OptionRight.Call &&
                              o.Strike == put.Strike).FirstOrDefault();

            if (call == null)
            {
                return(null);
            }

            return(new Tuple <OptionContract, OptionContract>(call, put));
        }
        /// <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);
        }
        /// <summary>
        /// Get OTM options for nearest available expiration.
        /// </summary>
        protected IOrderedEnumerable <OptionContract> GetOTM(QCAlgorithmFramework algorithim, Symbol underlyingSymbol, OptionRight right, int expiryDistance = 0)
        {
            IOrderedEnumerable <OptionContract> selected = OptionTools.GetOptionsForExpiry(algorithim, underlyingSymbol, expiryDistance);

            if (selected == null)
            {
                return(null);
            }

            return(selected
                   .Where(o => o.Right == right)
                   //check if OTM
                   .Where(o => (right == OptionRight.Put ? o.Strike <o.UnderlyingLastPrice : o.Strike> o.UnderlyingLastPrice))
                   //sort by distance from atm
                   .OrderBy(o => Math.Abs(o.UnderlyingLastPrice - o.Strike)));
        }
Beispiel #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)
        {
            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>());
        }