/* * 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.IO; using System.Linq; using QuantConnect.Util; using QuantConnect.Logging; using QuantConnect.Interfaces; using QuantConnect.Configuration; using System.Collections.Generic; using QuantConnect.Data.Auxiliary; namespace QuantConnect.Securities { /// /// Resolves standardized security definitions such as FIGI, CUSIP, ISIN, SEDOL into /// a properly mapped Lean . /// public class SecurityDefinitionSymbolResolver { private List _securityDefinitions; private readonly IMapFileProvider _mapFileProvider; private readonly string _securitiesDefinitionKey; private readonly IDataProvider _dataProvider; /// /// Creates an instance of the symbol resolver /// /// Data provider used to obtain symbol mappings data /// Location to read the securities definition data from public SecurityDefinitionSymbolResolver(IDataProvider dataProvider = null, string securitiesDefinitionKey = null) { _securitiesDefinitionKey = securitiesDefinitionKey ?? Path.Combine(Globals.DataFolder, "symbol-properties", "security-database.csv"); _dataProvider = dataProvider ?? Composer.Instance.GetExportedValueByTypeName( Config.Get("data-provider", "QuantConnect.Lean.Engine.DataFeeds.DefaultDataProvider")); _mapFileProvider = Composer.Instance.GetExportedValueByTypeName(Config.Get("map-file-provider", "LocalDiskMapFileProvider")); _mapFileProvider.Initialize(_dataProvider); } /// /// Converts CUSIP into a Lean /// /// /// The Committee on Uniform Securities Identification Procedures (CUSIP) number of a security /// /// /// The date that the stock was trading at with the CUSIP provided. This is used /// to get the ticker of the symbol on this date. /// /// The Lean Symbol corresponding to the CUSIP number on the trading date provided public Symbol CUSIP(string cusip, DateTime tradingDate) { if (string.IsNullOrWhiteSpace(cusip)) { return null; } return SecurityDefinitionToSymbol( GetSecurityDefinitions().FirstOrDefault(x => x.CUSIP != null && x.CUSIP.Equals(cusip, StringComparison.InvariantCultureIgnoreCase)), tradingDate); } /// /// Converts an asset's composite FIGI into a Lean /// /// /// The composite Financial Instrument Global Identifier (FIGI) of a security /// /// /// The date that the stock was trading at with the composite FIGI provided. This is used /// to get the ticker of the symbol on this date. /// /// The Lean Symbol corresponding to the composite FIGI on the trading date provided public Symbol CompositeFIGI(string compositeFigi, DateTime tradingDate) { if (string.IsNullOrWhiteSpace(compositeFigi)) { return null; } return SecurityDefinitionToSymbol( GetSecurityDefinitions().FirstOrDefault(x => x.CompositeFIGI != null && x.CompositeFIGI.Equals(compositeFigi, StringComparison.InvariantCultureIgnoreCase)), tradingDate); } /// /// Converts SEDOL into a Lean /// /// /// The Stock Exchange Daily Official List (SEDOL) security identifier of a security /// /// /// The date that the stock was trading at with the SEDOL provided. This is used /// to get the ticker of the symbol on this date. /// /// The Lean Symbol corresponding to the SEDOL on the trading date provided public Symbol SEDOL(string sedol, DateTime tradingDate) { if (string.IsNullOrWhiteSpace(sedol)) { return null; } return SecurityDefinitionToSymbol( GetSecurityDefinitions().FirstOrDefault(x => x.SEDOL != null && x.SEDOL.Equals(sedol, StringComparison.InvariantCultureIgnoreCase)), tradingDate); } /// /// Converts ISIN into a Lean /// /// /// The International Securities Identification Number (ISIN) of a security /// /// /// The date that the stock was trading at with the ISIN provided. This is used /// to get the ticker of the symbol on this date. /// /// The Lean Symbol corresponding to the ISIN on the trading date provided public Symbol ISIN(string isin, DateTime tradingDate) { if (string.IsNullOrWhiteSpace(isin)) { return null; } return SecurityDefinitionToSymbol( GetSecurityDefinitions().FirstOrDefault(x => x.ISIN != null && x.ISIN.Equals(isin, StringComparison.InvariantCultureIgnoreCase)), tradingDate); } /// /// Converts a SecurityDefinition to a /// /// Security definition /// /// The date that the stock was being traded. This is used to resolve /// the ticker that the stock was trading under on this date. /// /// Symbol if matching Lean Symbol was found on the trading date, null otherwise private Symbol SecurityDefinitionToSymbol(SecurityDefinition securityDefinition, DateTime tradingDate) { if (securityDefinition == null) { return null; } var mapFileResolver = _mapFileProvider.Get(AuxiliaryDataKey.Create(securityDefinition.SecurityIdentifier)); // Get the first ticker the symbol traded under, and then lookup the // trading date to get the ticker on the trading date. var mapFile = mapFileResolver .ResolveMapFile(securityDefinition.SecurityIdentifier.Symbol, securityDefinition.SecurityIdentifier.Date); // The mapped ticker will be null if the map file is null or there's // no entry found for the given trading date. var mappedTicker = mapFile?.GetMappedSymbol(tradingDate, null); // If we're null, then try again; get the last entry of the map file and use // it as the Symbol we return to the caller. mappedTicker ??= mapFile? .LastOrDefault()? .MappedSymbol; return string.IsNullOrWhiteSpace(mappedTicker) ? null : new Symbol(securityDefinition.SecurityIdentifier, mappedTicker); } /// /// Get's the security definitions using a lazy initialization /// private IEnumerable GetSecurityDefinitions() { if (_securityDefinitions != null) { return _securityDefinitions; } if (!SecurityDefinition.TryRead(_dataProvider, _securitiesDefinitionKey, out _securityDefinitions)) { _securityDefinitions = new List(); Log.Error($"SecurityDefinitionSymbolResolver(): No security definitions data loaded from file: {_securitiesDefinitionKey}"); } return _securityDefinitions; } } }