Beispiel #1
0
 public void PlotNetPosition(Slice slice)
 {
     _longHoldingsCount.AddPoint(slice.Time, OptionTools.GetHoldingQuantity(this, _primarySymbol, true, false));
     _shortHoldingsCount.AddPoint(slice.Time, -OptionTools.GetHoldingQuantity(this, _primarySymbol, false, true));
     _longOpenOrdersCount.AddPoint(slice.Time, OptionTools.GetOpenOrderQuantity(this, _primarySymbol, true, false));
     _shortOpenOrdersCount.AddPoint(slice.Time, -OptionTools.GetOpenOrderQuantity(this, _primarySymbol, false, true));
 }
        /// <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)));
        }
        protected virtual List <IPortfolioTarget> IncrementOptionPositions(QCAlgorithmFramework algorithm, Symbol baseSymbol, IEnumerable <OptionHolding> holdings, Insight insight)
        {
            //don't touch anything if there are orders still pending
            if (OptionTools.GetOpenOrderQuantity(algorithm, baseSymbol, true, true) > 0)
            {
                return(null);
            }

            var targets = new List <IPortfolioTarget>();

            holdings.All(p =>
            {
                targets.Add(new PortfolioTarget(p.Symbol, p.Quantity + this.PositionSize));
                return(true);
            });
            return(targets);
        }
        public sealed override List <IPortfolioTarget> OpenTargetsFromInsight(QCAlgorithmFramework algorithm, Symbol baseSymbol, Insight insight)
        {
            var currentHoldings   = GetOptionHoldings(algorithm, baseSymbol);
            var pendingOrderCount = OptionTools.GetOpenOrderQuantity(algorithm, baseSymbol, true, true);

            if (this.PrintPosition)
            {
                algorithm.Log("pending orders: " + pendingOrderCount);
                foreach (var holding in currentHoldings)
                {
                    algorithm.Log("holding: " + holding.Symbol + "\t" + holding.Quantity + "\t" + holding.UnrealizedProfit);
                }
            }

            if (currentHoldings.Count() > 0 ||
                pendingOrderCount > 0)
            {
                this.SanityCheckHoldings(algorithm, currentHoldings);

                if (insight.Direction == InsightDirection.Flat)
                {
                    //create a target to close holdings
                    return(this.LiquidateOptions(algorithm, currentHoldings));
                }
                else
                {
                    //TODO: close pending orders too???
                    var closingTargets = PossiblyCloseCurrentTargets(algorithm, baseSymbol, currentHoldings, insight);
                    if (closingTargets == null || closingTargets.Count > 0)
                    {
                        return(closingTargets);
                    }

                    //if we aren't closing anything, then add to open position
                    return(this.IncrementOptionPositions(algorithm, baseSymbol, currentHoldings, insight));
                }
            }
            else
            {
                return(FindPotentialOptions(algorithm, baseSymbol, insight));
            }
        }
Beispiel #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(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>());
        }
Beispiel #8
0
 public bool TryGetOptionChain(QCAlgorithmFramework algorithm, Symbol underlyingSymbol, out OptionChain chain)
 {
     return(OptionTools.TryGetOptionChain(algorithm, underlyingSymbol, out chain));
 }