/// <summary> /// Event fired each time the we add/remove securities from the data feed /// </summary> /// <param name="algorithm">The algorithm instance that experienced the change in securities</param> /// <param name="changes">The security additions and removals from the algorithm</param> public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes) { NotifiedSecurityChanges.UpdateCollection(Securities, changes); var symbols = Securities.Select(x => x.Symbol).ToArray(); var history = algorithm.History(symbols, _lookback, _resolution); var vectors = GetPriceVectors(history); if (vectors.LongLength == 0) { algorithm.Debug($"PearsonCorrelationPairsTradingAlphaModel.OnSecuritiesChanged(): The requested historical data does not have series of prices with the same date/time. Please consider increasing the looback period. Current lookback: {_lookback}"); } else { var pearsonMatrix = Correlation.PearsonMatrix(vectors).UpperTriangle(); var maxValue = pearsonMatrix.Enumerate().Where(x => Math.Abs(x) < 1).Max(); if (maxValue >= _minimumCorrelation) { var maxTuple = pearsonMatrix.Find(x => x == maxValue); _bestPair = Tuple.Create(symbols[maxTuple.Item1], symbols[maxTuple.Item2]); } } base.OnSecuritiesChanged(algorithm, changes); }
public IEnumerable <TypedSecurity> ToTypedSecurities() { return(Securities.Select(sec => new TypedSecurity { Type = Type, BoardgroupId = Id, SecId = sec, })); }
private double[][] GetPriceVectors(IEnumerable <Slice> slices) { var symbols = Securities.Select(x => x.Symbol).ToArray(); var timeZones = Securities.ToDictionary(x => x.Symbol, y => y.Exchange.TimeZone); // Special case: daily data and securities from different timezone var isDailyAndMultipleTimeZone = _resolution == Resolution.Daily && timeZones.Values.Distinct().Count() > 1; var bars = new List <BaseData>(); if (isDailyAndMultipleTimeZone) { bars.AddRange(slices .GroupBy(x => x.Time.Date) .Where(x => x.Sum(k => k.Count) == symbols.Length) .SelectMany(x => x.SelectMany(y => y.Values))); } else { bars.AddRange(slices .Where(x => x.Count == symbols.Length) .SelectMany(x => x.Values)); } return(bars .GroupBy(x => x.Symbol) .Select(x => { var array = x.Select(b => Math.Log((double)b.Price)).ToArray(); if (array.Length > 1) { for (var i = array.Length - 1; i > 0; i--) { array[i] = array[i] - array[i - 1]; } array[0] = array[1]; return array; } else { return new double[0]; } }).ToArray()); }
private static async Task LoadStrategies() { var iStrategyTypes = GetIStrategyTypes(); var iStrategyNames = GetIStrategyNames(); var initializeTasks = new List <Task>(); Logger.LogInformation($"Initializing strategies."); foreach (var strategyName in appSettings.strategies) { if (iStrategyNames.Contains(strategyName)) { var strategyType = iStrategyTypes.Where(t => t.Name == strategyName).First(); var strategy = Activator.CreateInstance(strategyType) as IStrategy; var task = Task.Run(async() => { Logger.LogDebug($"Initializing: {strategyName}"); await strategy.Initialize(); }); initializeTasks.Add(task); foreach (var symbol in strategy.Subscriptions) { var security = Securities.GetOrAdd(symbol, new Security(symbol)); security.OnMinuteAggReceived += strategy.OnDataReceived; } } } if (Securities.Count > 0) { Task.WaitAll(initializeTasks.ToArray()); // TODO: No longer outputing the correct information, fix var jsonNames = JsonConvert.SerializeObject(Securities.Select(s => s.Value.GetType().Name)); Logger.LogInformation($"Initialized strategies: {jsonNames}"); } else { Logger.LogError("No strategies found."); await StopAsync(); } }
public void OnEndOfTimeStep() { if (_pendingUniverseAdditions.Count + _pendingUserDefinedUniverseSecurityAdditions.Count == 0) { // no point in looping through everything if there's no pending changes return; } var requiredHistoryRequests = new Dictionary <Security, Resolution>(); // rewrite securities w/ derivatives to be in raw mode lock (_pendingUniverseAdditionsLock) { foreach (var security in Securities.Select(kvp => kvp.Value).Union( _pendingUserDefinedUniverseSecurityAdditions.Select(x => x.Security))) { // check for any derivative securities and mark the underlying as raw if (Securities.Any(skvp => skvp.Key.SecurityType != SecurityType.Base && skvp.Key.HasUnderlyingSymbol(security.Symbol))) { // set data mode raw and default volatility model ConfigureUnderlyingSecurity(security); } var configs = SubscriptionManager.SubscriptionDataConfigService .GetSubscriptionDataConfigs(security.Symbol); if (security.Symbol.HasUnderlying && security.Symbol.SecurityType != SecurityType.Base) { Security underlyingSecurity; var underlyingSymbol = security.Symbol.Underlying; var resolution = configs.GetHighestResolution(); // create the underlying security object if it doesn't already exist if (!Securities.TryGetValue(underlyingSymbol, out underlyingSecurity)) { underlyingSecurity = AddSecurity(underlyingSymbol.SecurityType, underlyingSymbol.Value, resolution, underlyingSymbol.ID.Market, false, 0, configs.IsExtendedMarketHours()); } // set data mode raw and default volatility model ConfigureUnderlyingSecurity(underlyingSecurity); if (LiveMode && underlyingSecurity.GetLastData() == null) { if (requiredHistoryRequests.ContainsKey(underlyingSecurity)) { // lets request the higher resolution var currentResolutionRequest = requiredHistoryRequests[underlyingSecurity]; if (currentResolutionRequest != Resolution.Minute && // Can not be less than Minute resolution < currentResolutionRequest) { requiredHistoryRequests[underlyingSecurity] = (Resolution)Math.Max((int)resolution, (int)Resolution.Minute); } } else { requiredHistoryRequests.Add(underlyingSecurity, (Resolution)Math.Max((int)resolution, (int)Resolution.Minute)); } } // set the underlying security on the derivative -- we do this in two places since it's possible // to do AddOptionContract w/out the underlying already added and normalized properly var derivative = security as IDerivativeSecurity; if (derivative != null) { derivative.Underlying = underlyingSecurity; } } } if (!requiredHistoryRequests.IsNullOrEmpty()) { // Create requests var historyRequests = Enumerable.Empty <HistoryRequest>(); foreach (var byResolution in requiredHistoryRequests.GroupBy(x => x.Value)) { historyRequests = historyRequests.Concat( CreateBarCountHistoryRequests(byResolution.Select(x => x.Key.Symbol), 3, byResolution.Key)); } // Request data var historicLastData = History(historyRequests); historicLastData.PushThrough(x => { var security = requiredHistoryRequests.Keys.FirstOrDefault(y => y.Symbol == x.Symbol); security?.Cache.AddData(x); }); } // add subscriptionDataConfig to their respective user defined universes foreach (var userDefinedUniverseAddition in _pendingUserDefinedUniverseSecurityAdditions) { foreach (var subscriptionDataConfig in userDefinedUniverseAddition.SubscriptionDataConfigs) { userDefinedUniverseAddition.Universe.Add(subscriptionDataConfig); } } // finally add any pending universes, this will make them available to the data feed foreach (var universe in _pendingUniverseAdditions) { UniverseManager.Add(universe.Configuration.Symbol, universe); } _pendingUniverseAdditions.Clear(); _pendingUserDefinedUniverseSecurityAdditions.Clear(); } if (!_rawNormalizationWarningSymbols.IsNullOrEmpty()) { // Log our securities being set to raw price mode Debug($"Warning: The following securities were set to raw price normalization mode to work with options: " + $"{string.Join(", ", _rawNormalizationWarningSymbols.Take(_rawNormalizationWarningSymbolsMaxCount).Select(x => x.Value))}..."); // Set our warning list to null to stop emitting these warnings after its done once _rawNormalizationWarningSymbols = null; } }
/// <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) { Debug($"[{Time}] Warmup: {IsWarmingUp}. Invested: {Portfolio.Invested} {string.Join(",", Securities.Select(pair => $"{pair.Key.Value}:{pair.Value.Price}"))}"); if (IsWarmingUp) { _equityGotTradeBars |= data.Bars.ContainsKey("SPY"); _equityGotQuoteBars |= data.QuoteBars.ContainsKey("SPY"); _cryptoGotTradeBars |= data.Bars.ContainsKey("BTCUSD"); } else { if (!Portfolio.Invested) { AddEquity("AAPL", Resolution.Hour); SetHoldings("BTCUSD", 0.3); } } }
/// <summary> /// Invoked at the end of every time step. This allows the algorithm /// to process events before advancing to the next time step. /// </summary> public void OnEndOfTimeStep() { if (_pendingUniverseAdditions.Count + _pendingUserDefinedUniverseSecurityAdditions.Count == 0) { // no point in looping through everything if there's no pending changes return; } // rewrite securities w/ derivatives to be in raw mode lock (_pendingUniverseAdditionsLock) { foreach (var security in Securities.Select(kvp => kvp.Value).Union(_pendingUserDefinedUniverseSecurityAdditions.Keys)) { // check for any derivative securities and mark the underlying as raw if (Securities.Any(skvp => skvp.Key.HasUnderlyingSymbol(security.Symbol))) { // set data mode raw and default volatility model ConfigureUnderlyingSecurity(security); } if (security.Symbol.HasUnderlying) { Security underlyingSecurity; var underlyingSymbol = security.Symbol.Underlying; // create the underlying security object if it doesn't already exist if (!Securities.TryGetValue(underlyingSymbol, out underlyingSecurity)) { underlyingSecurity = AddSecurity(underlyingSymbol.SecurityType, underlyingSymbol.Value, security.Resolution, underlyingSymbol.ID.Market, false, 0, security.IsExtendedMarketHours); } // set data mode raw and default volatility model ConfigureUnderlyingSecurity(underlyingSecurity); // set the underying security on the derivative -- we do this in two places since it's possible // to do AddOptionContract w/out the underlying already added and normalized properly var derivative = security as IDerivativeSecurity; if (derivative != null) { derivative.Underlying = underlyingSecurity; } } } // add securities to their respective user defined universes foreach (var kvp in _pendingUserDefinedUniverseSecurityAdditions) { var security = kvp.Key; var userDefinedUniverse = kvp.Value; userDefinedUniverse.Add(security.Symbol); } // finally add any pending universes, this will make them available to the data feed foreach (var universe in _pendingUniverseAdditions) { UniverseManager.Add(universe.Configuration.Symbol, universe); } _pendingUniverseAdditions.Clear(); _pendingUserDefinedUniverseSecurityAdditions.Clear(); } }
/// <summary> /// Invoked at the end of every time step. This allows the algorithm /// to process events before advancing to the next time step. /// </summary> public void OnEndOfTimeStep() { if (_pendingUniverseAdditions.Count + _pendingUserDefinedUniverseSecurityAdditions.Count == 0) { // no point in looping through everything if there's no pending changes return; } var requiredHistoryRequests = new Dictionary <Security, Resolution>(); // rewrite securities w/ derivatives to be in raw mode lock (_pendingUniverseAdditionsLock) { foreach (var security in Securities.Select(kvp => kvp.Value).Union(_pendingUserDefinedUniverseSecurityAdditions.Keys)) { // check for any derivative securities and mark the underlying as raw if (Securities.Any(skvp => skvp.Key.HasUnderlyingSymbol(security.Symbol))) { // set data mode raw and default volatility model ConfigureUnderlyingSecurity(security); } if (security.Symbol.HasUnderlying) { Security underlyingSecurity; var underlyingSymbol = security.Symbol.Underlying; // create the underlying security object if it doesn't already exist if (!Securities.TryGetValue(underlyingSymbol, out underlyingSecurity)) { underlyingSecurity = AddSecurity(underlyingSymbol.SecurityType, underlyingSymbol.Value, security.Resolution, underlyingSymbol.ID.Market, false, 0, security.IsExtendedMarketHours); } // set data mode raw and default volatility model ConfigureUnderlyingSecurity(underlyingSecurity); if (LiveMode && underlyingSecurity.GetLastData() == null) { requiredHistoryRequests.Add(underlyingSecurity, (Resolution)Math.Max((int)security.Resolution, (int)Resolution.Minute)); } // set the underlying security on the derivative -- we do this in two places since it's possible // to do AddOptionContract w/out the underlying already added and normalized properly var derivative = security as IDerivativeSecurity; if (derivative != null) { derivative.Underlying = underlyingSecurity; } } } if (!requiredHistoryRequests.IsNullOrEmpty()) { // Create requests var historyRequests = Enumerable.Empty <HistoryRequest>(); foreach (var byResolution in requiredHistoryRequests.GroupBy(x => x.Value)) { historyRequests = historyRequests.Concat( CreateBarCountHistoryRequests(byResolution.Select(x => x.Key.Symbol), 3, byResolution.Key)); } // Request data var historicLastData = History(historyRequests); historicLastData.PushThrough(x => { var security = requiredHistoryRequests.Keys.FirstOrDefault(y => y.Symbol == x.Symbol); security?.Cache.AddData(x); }); } // add securities to their respective user defined universes foreach (var kvp in _pendingUserDefinedUniverseSecurityAdditions) { var security = kvp.Key; var userDefinedUniverse = kvp.Value; userDefinedUniverse.Add(security.Symbol); } // finally add any pending universes, this will make them available to the data feed foreach (var universe in _pendingUniverseAdditions) { UniverseManager.Add(universe.Configuration.Symbol, universe); } _pendingUniverseAdditions.Clear(); _pendingUserDefinedUniverseSecurityAdditions.Clear(); } }