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; } }
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; } }