public override void OnData(Slice slice) { try { HandleSplits(slice); if (!_rebalanceMeter.IsDue(Time) || slice.Count() == 0 || !IsAllowedToTrade(slice)) { return; } if (!ActiveSecurities.Any()) { return; } SendEmailNotification("Begin OnData()"); UpdateIndicatorOpen(slice); SetTargetCounts(); var insights = GetInsights(slice).ToArray(); EmitInsights(insights); Rebalance(insights); _rebalanceMeter.Update(Time); SendEmailNotification("End OnData()"); } catch (Exception e) { var msg = $"Exception: OnData: {e.Message}, {e.StackTrace}"; Log(msg); SendEmailNotification(msg); } }
/// <summary> /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here. /// </summary> /// <param name="data">Slice object keyed by symbol containing the stock data</param> public override void OnData(Slice data) { if (!Portfolio.Invested) { SetHoldings("SPY", 1); } if (Time.Day == 11) { return; } if (!ActiveSecurities.ContainsKey("AIG")) { var aig = AddEquity("AIG", Resolution.Minute); var ticket = MarketOrder("AIG", 1); if (ticket.Status != OrderStatus.Invalid) { throw new Exception("Expected order to always be invalid because there is no data yet!"); } } else { RemoveSecurity("AIG"); } }
private IEnumerable <Insight> GetInsights(Slice slice) { try { var candidateLongs = RankSymbols(ActiveSecurities .Where(x => x.Value.IsTradable && slice.ContainsKey(x.Key) && _longCandidates.Contains(x.Key) && _indicators.ContainsKey(x.Key) && _indicators[x.Key].IsReady && _indicators[x.Key].Momentum > MinLongMomentum && !_indicators[x.Key].ExcludedBySma && !_indicators[x.Key].ExcludedBySpread && (slice[x.Key] as BaseData).Price >= MinPrice) .Select(x => x.Key)) .ToList(); var holdingRanks = Portfolio .Where(x => x.Value.Invested) .ToDictionary( x => x.Key, x => candidateLongs.FindIndex(y => y == x.Key)); var rankThreshold = 2.5 * NumLong; var toSell = holdingRanks .Where(x => x.Value <0 || x.Value> rankThreshold) .Select(x => x.Key); var toHold = holdingRanks.Keys.Except(toSell); var toBuy = candidateLongs .Where(x => !toHold.Contains(x)) .OrderByDescending(x => _indicators[x].Momentum) .Take(NumLong - toHold.Count()); var toOwn = toBuy .Union(toHold) .Select(x => new Insight( x, RebalancePeriod, InsightType.Price, InsightDirection.Up)); return(toOwn); } catch (Exception e) { var msg = $"Exception: GetInsights: {e.Message}, {e.StackTrace}"; Log(msg); SendEmailNotification(msg); throw; } }
public override void OnData(Slice data) { if (!Portfolio.Invested && Transactions.GetOpenOrders().Count == 0) { var aapl = QuantConnect.Symbol.Create("AAPL", SecurityType.Equity, Market.USA); SetHoldings(aapl, 0.5); } foreach (var customSymbol in _customSymbols) { if (!ActiveSecurities.ContainsKey(customSymbol.Underlying)) { throw new Exception($"Custom data underlying ({customSymbol.Underlying}) Symbol was not found in active securities"); } } }
private void Rebalance(Insight[] insights) { var shortCount = insights.Count(x => x.Direction == InsightDirection.Down); var longTargets = insights .Where(x => x.Direction == InsightDirection.Up) .Select(x => PortfolioTarget.Percent(this, x.Symbol, 1.0m / (_targetLongCount + shortCount))); var shortTargets = insights .Where(x => x.Direction == InsightDirection.Down) .Select(x => PortfolioTarget.Percent(this, x.Symbol, -1.0m / (NumLong + NumShort))); var targets = longTargets.Union(shortTargets); Plot("targetCounts", "longs", longTargets.Count()); Plot("targetCounts", "shorts", shortTargets.Count()); Plot("targetCounts", "active", ActiveSecurities.Count()); new SmartImmediateExecutionModel().Execute(this, targets.ToArray()); var targetsStr = targets.Any() ? string.Join(",", targets.Select(x => x.Symbol.Value).OrderBy(x => x)) : "nothing"; Log(targetsStr); SendEmailNotification($"We have positions in: {targetsStr}"); }
private IEnumerable <Insight> GetInsights(Slice slice) { try { var insights = new List <Insight>(); var stoStatuses = _stos.ToDictionary( x => x.Key, x => StoStatus(x.Key)); var macdStatuses = _macdHistograms.ToDictionary( x => x.Key, x => MacdStatus(x.Key)); //***** //var aSymbol = _stos.Keys.Single(x => x.Value == "AAPL"); //var sto = _stos[aSymbol]; //var strElements = Enumerable.Range(0, sto.Count) // .Select(x => $"{x}({sto[x].Value})"); //var str = string.Join(", ", strElements); //Log(str); //var momentumCount = ActiveSecurities // .Where(x => x.Value.IsTradable // && slice.ContainsKey(x.Key) // && MomentumDirection(x.Key) == InsightDirection.Up) // .Count(); //var stoHistogram = ActiveSecurities // .Where(x => x.Value.IsTradable // && slice.ContainsKey(x.Key) // && stoStatuses[x.Key].Direction == InsightDirection.Up) // .Select(x => x.Key) // .GroupBy(x => stoStatuses[x].DaysPastSignal) // .Select(x => new { Days = x.Key, Count = x.Count() }) // .OrderBy(x => x.Count) // .Select(x => $"{x.Days}({x.Count})"); //var macdHistogram = ActiveSecurities // .Where(x => x.Value.IsTradable // && slice.ContainsKey(x.Key) // && macdStatuses[x.Key].Direction == InsightDirection.Up) // .Select(x => x.Key) // .GroupBy(x => macdStatuses[x].DaysPastSignal) // .Select(x => new { Days = x.Key, Count = x.Count() }) // .OrderBy(x => x.Count) // .Select(x => $"{x.Days}({x.Count})"); //Log($"momentumCount={momentumCount}, stos[{string.Join(",", stoHistogram)}], macds[{string.Join(",", macdHistogram)}]"); ////////// //var aSto = _stos[sym][0].Value; //Log($"{Time}: sto[{sym.Value}]={aSto}"); var momentumCount = ActiveSecurities .Where(x => x.Value.IsTradable && slice.ContainsKey(x.Key) && MomentumDirection(x.Key, slice) == InsightDirection.Up) .Count(); var stoCount = ActiveSecurities .Where(x => x.Value.IsTradable && slice.ContainsKey(x.Key) && stoStatuses[x.Key].Direction == InsightDirection.Up) .Count(); var macdCount = ActiveSecurities .Where(x => x.Value.IsTradable && slice.ContainsKey(x.Key) && macdStatuses[x.Key].Direction == InsightDirection.Up) .Count(); Log($"{Time}: momCount={momentumCount}, stoCount={stoCount}, macdCount={macdCount}"); //***** insights.AddRange(ActiveSecurities .Where(x => x.Value.IsTradable && slice.ContainsKey(x.Key) && MomentumDirection(x.Key, slice) == InsightDirection.Up && stoStatuses[x.Key].Direction == InsightDirection.Up && macdStatuses[x.Key].Direction == InsightDirection.Up && macdStatuses[x.Key].DaysPastSignal < stoStatuses[x.Key].DaysPastSignal) .Take(NumLongShort) .Select(x => new Insight( x.Value.Symbol, RebalancePeriod, InsightType.Price, InsightDirection.Up))); insights.AddRange(ActiveSecurities .Where(x => x.Value.IsTradable && slice.ContainsKey(x.Key) && MomentumDirection(x.Key, slice) == InsightDirection.Down && stoStatuses[x.Key].Direction == InsightDirection.Down && macdStatuses[x.Key].Direction == InsightDirection.Down && macdStatuses[x.Key].DaysPastSignal < stoStatuses[x.Key].DaysPastSignal) .Take(NumLongShort) .Select(x => new Insight( x.Value.Symbol, RebalancePeriod, InsightType.Price, InsightDirection.Down))); return(insights); } catch (Exception e) { Log($"Exception: GetInsights: {e.Message}"); throw; } }