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)); } }
/// <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>()); }
public bool TryGetOptionChain(QCAlgorithmFramework algorithm, Symbol underlyingSymbol, out OptionChain chain) { return(OptionTools.TryGetOptionChain(algorithm, underlyingSymbol, out chain)); }