/// <summary> /// Used to send data updates to algorithm framework models /// </summary> /// <param name="slice">The current data slice</param> public void OnFrameworkData(Slice slice) { if (UtcTime >= UniverseSelection.GetNextRefreshTimeUtc()) { var universes = UniverseSelection.CreateUniverses(this).ToDictionary(u => u.Configuration.Symbol); // remove deselected universes by symbol foreach (var ukvp in UniverseManager) { var universeSymbol = ukvp.Key; var qcUserDefined = UserDefinedUniverse.CreateSymbol(ukvp.Value.SecurityType, ukvp.Value.Market); if (universeSymbol.Equals(qcUserDefined)) { // prevent removal of qc algorithm created user defined universes continue; } Universe universe; if (!universes.TryGetValue(universeSymbol, out universe)) { if (ukvp.Value.DisposeRequested) { UniverseManager.Remove(universeSymbol); } // mark this universe as disposed to remove all child subscriptions ukvp.Value.Dispose(); } } // add newly selected universes foreach (var ukvp in universes) { // note: UniverseManager.Add uses TryAdd, so don't need to worry about duplicates here UniverseManager.Add(ukvp); } } // we only want to run universe selection if there's no data available in the slice if (!slice.HasData) { return; } // insight timestamping handled via InsightsGenerated event handler var insightsEnumerable = Alpha.Update(this, slice); // for performance only call 'ToArray' if not empty enumerable (which is static) var insights = insightsEnumerable == Enumerable.Empty <Insight>() ? new Insight[] { } : insightsEnumerable.ToArray(); // only fire insights generated event if we actually have insights if (insights.Length != 0) { OnInsightsGenerated(insights.Select(InitializeInsightFields)); } ProcessInsights(insights); }
/// <summary> /// Used to send data updates to algorithm framework models /// </summary> /// <param name="slice">The current data slice</param> public void OnFrameworkData(Slice slice) { if (UtcTime >= UniverseSelection.GetNextRefreshTimeUtc()) { var universes = UniverseSelection.CreateUniverses(this).ToDictionary(u => u.Configuration.Symbol); // remove deselected universes by symbol foreach (var ukvp in UniverseManager) { var universeSymbol = ukvp.Key; if (_userAddedUniverses.Contains(universeSymbol)) { // prevent removal of qc algorithm created user defined universes continue; } if (ukvp.Value.DisposeRequested) { // have to remove in the next loop after the universe is marked as disposed, when 'Dispose()' is called it will trigger universe selection // and deselect all symbols, sending the removed security changes, which are picked up by the AlgorithmManager and tags securities // as non tradable as long as they are not active in any universe (uses UniverseManager.ActiveSecurities) // but they will remain tradable if a position is still being hold since they won't be remove from the UniverseManager // but this last part will not happen if we remove the universe from the UniverseManager right away, since it won't be part of 'UniverseManager'. // And we have to remove the universe even if it's present at 'universes' because that one is another New universe that should get added! // 'UniverseManager' will skip duplicate entries getting added. UniverseManager.Remove(universeSymbol); } Universe universe; if (!universes.TryGetValue(universeSymbol, out universe)) { // mark this universe as disposed to remove all child subscriptions ukvp.Value.Dispose(); } } // add newly selected universes foreach (var ukvp in universes) { // note: UniverseManager.Add uses TryAdd, so don't need to worry about duplicates here UniverseManager.Add(ukvp); } } // we only want to run universe selection if there's no data available in the slice if (!slice.HasData) { return; } // insight timestamping handled via InsightsGenerated event handler var insightsEnumerable = Alpha.Update(this, slice); // for performance only call 'ToArray' if not empty enumerable (which is static) var insights = insightsEnumerable == Enumerable.Empty <Insight>() ? new Insight[] { } : insightsEnumerable.ToArray(); // only fire insights generated event if we actually have insights if (insights.Length != 0) { insights = InitializeInsights(insights); OnInsightsGenerated(insights); } ProcessInsights(insights); }
/// <summary> /// Used to send data updates to algorithm framework models /// </summary> /// <param name="slice">The current data slice</param> public sealed override void OnFrameworkData(Slice slice) { if (UtcTime >= UniverseSelection.GetNextRefreshTimeUtc()) { var universes = UniverseSelection.CreateUniverses(this).ToDictionary(u => u.Configuration.Symbol); // remove deselected universes by symbol foreach (var ukvp in UniverseManager) { var universeSymbol = ukvp.Key; var qcUserDefined = UserDefinedUniverse.CreateSymbol(ukvp.Value.SecurityType, ukvp.Value.Market); if (universeSymbol.Equals(qcUserDefined)) { // prevent removal of qc algorithm created user defined universes continue; } Universe universe; if (!universes.TryGetValue(universeSymbol, out universe)) { if (ukvp.Value.DisposeRequested) { UniverseManager.Remove(universeSymbol); } // mark this universe as disposed to remove all child subscriptions ukvp.Value.Dispose(); } } // add newly selected universes foreach (var ukvp in universes) { // note: UniverseManager.Add uses TryAdd, so don't need to worry about duplicates here UniverseManager.Add(ukvp); } } // we only want to run universe selection if there's no data available in the slice if (!slice.HasData) { return; } // insight timestamping handled via InsightsGenerated event handler var insights = Alpha.Update(this, slice).ToArray(); // only fire insights generated event if we actually have insights if (insights.Length != 0) { // debug printing of generated insights if (DebugMode) { Log($"{Time}: ALPHA: {string.Join(" | ", insights.Select(i => i.ToString()).OrderBy(i => i))}"); } OnInsightsGenerated(insights); } // construct portfolio targets from insights var targets = PortfolioConstruction.CreateTargets(this, insights).ToArray(); // set security targets w/ those generated via portfolio construction module foreach (var target in targets) { var security = Securities[target.Symbol]; security.Holdings.Target = target; } if (DebugMode) { // debug printing of generated targets if (targets.Length > 0) { Log($"{Time}: PORTFOLIO: {string.Join(" | ", targets.Select(t => t.ToString()).OrderBy(t => t))}"); } } var riskTargetOverrides = RiskManagement.ManageRisk(this, targets).ToArray(); // override security targets w/ those generated via risk management module foreach (var target in riskTargetOverrides) { var security = Securities[target.Symbol]; security.Holdings.Target = target; } if (DebugMode) { // debug printing of generated risk target overrides if (riskTargetOverrides.Length > 0) { Log($"{Time}: RISK: {string.Join(" | ", riskTargetOverrides.Select(t => t.ToString()).OrderBy(t => t))}"); } } // execute on the targets, overriding targets for symbols w/ risk targets var riskAdjustedTargets = riskTargetOverrides.Concat(targets).DistinctBy(pt => pt.Symbol).ToArray(); if (DebugMode) { // only log adjusted targets if we've performed an adjustment if (riskTargetOverrides.Length > 0) { Log($"{Time}: RISK ADJUSTED TARGETS: {string.Join(" | ", riskAdjustedTargets.Select(t => t.ToString()).OrderBy(t => t))}"); } } Execution.Execute(this, riskAdjustedTargets); }