/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ using System; using System.Collections.Generic; using System.Linq; using QuantConnect.Data; using QuantConnect.Data.UniverseSelection; using QuantConnect.Interfaces; using QuantConnect.Lean.Engine.DataFeeds; using QuantConnect.Logging; namespace QuantConnect.Lean.Engine.Setup { /// /// Base class that provides shared code for /// the implementations /// public static class BaseSetupHandler { /// /// Will first check and add all the required conversion rate securities /// and later will seed an initial value to them. /// /// The algorithm instance /// The universe selection instance public static void SetupCurrencyConversions( IAlgorithm algorithm, UniverseSelection universeSelection) { // this is needed to have non-zero currency conversion rates during warmup // will also set the Cash.ConversionRateSecurity universeSelection.EnsureCurrencyDataFeeds(SecurityChanges.None); // now set conversion rates var cashToUpdate = algorithm.Portfolio.CashBook.Values .Where(x => x.ConversionRateSecurity != null && x.ConversionRate == 0) .ToList(); var historyRequestFactory = new HistoryRequestFactory(algorithm); var historyRequests = new List(); foreach (var cash in cashToUpdate) { // if we already added a history request for this security, skip if (historyRequests.Any(x => x.Symbol == cash.ConversionRateSecurity.Symbol)) { continue; } var configs = algorithm .SubscriptionManager .SubscriptionDataConfigService .GetSubscriptionDataConfigs(cash.ConversionRateSecurity.Symbol); var resolution = configs.GetHighestResolution(); var startTime = historyRequestFactory.GetStartTimeAlgoTz( cash.ConversionRateSecurity.Symbol, 1, resolution, cash.ConversionRateSecurity.Exchange.Hours); var endTime = algorithm.Time.RoundDown(resolution.ToTimeSpan()); // we need to order and select a specific configuration type // so the conversion rate is deterministic var configToUse = configs.OrderBy(x => x.TickType).First(); historyRequests.Add(historyRequestFactory.CreateHistoryRequest( configToUse, startTime, endTime, cash.ConversionRateSecurity.Exchange.Hours, resolution)); } var slices = algorithm.HistoryProvider.GetHistory(historyRequests, algorithm.TimeZone); slices.PushThrough(data => { foreach (var cash in cashToUpdate .Where(x => x.ConversionRateSecurity.Symbol == data.Symbol)) { cash.Update(data); } }); Log.Trace("BaseSetupHandler.SetupCurrencyConversions():" + $"{Environment.NewLine}{algorithm.Portfolio.CashBook}"); } } }