示例#1
0
        /// <summary>
        /// Set SymbolProperties entry for a particular market, symbol and security type.
        /// </summary>
        /// <param name="market">Market of the entry</param>
        /// <param name="symbol">Symbol of the entry</param>
        /// <param name="securityType">Type of security for the entry</param>
        /// <param name="properties">The new symbol properties to store</param>
        /// <returns>True if successful</returns>
        public bool SetEntry(string market, string symbol, SecurityType securityType, SymbolProperties properties)
        {
            var key = new SecurityDatabaseKey(market, symbol, securityType);

            _entries[key] = properties;
            return(true);
        }
示例#2
0
        /// <summary>
        /// Gets the entry for the specified market/symbol/security-type
        /// </summary>
        /// <param name="market">The market the exchange resides in, i.e, 'usa', 'fxcm', ect...</param>
        /// <param name="symbol">The particular symbol being traded</param>
        /// <param name="securityType">The security type of the symbol</param>
        /// <returns>The entry matching the specified market/symbol/security-type</returns>
        public virtual Entry GetEntry(string market, string symbol, SecurityType securityType)
        {
            Entry entry;

            // Fall back on the Futures MHDB entry if the FOP lookup failed.
            // Some FOPs have the same symbol properties as their futures counterparts.
            // So, to save ourselves some space, we can fall back on the existing entries
            // so that we don't duplicate the information.
            if (!TryGetEntry(market, symbol, securityType, out entry) &&
                !(securityType == SecurityType.FutureOption && TryGetEntry(market, FuturesOptionsSymbolMappings.MapFromOption(symbol), SecurityType.Future, out entry)))
            {
                var key  = new SecurityDatabaseKey(market, symbol, securityType);
                var keys = string.Join(", ", _entries.Keys);
                Log.Error($"MarketHoursDatabase.GetExchangeHours(): Unable to locate exchange hours for {key}.Available keys: {keys}");

                if (securityType == SecurityType.Future && market == Market.USA)
                {
                    var exception =
                        "Future.Usa market type is no longer supported as we mapped each ticker to its actual exchange. " +
                        "Please find your specific market in the symbol-properties database.";
                    if (SymbolPropertiesDatabase.FromDataFolder().TryGetMarket(symbol, SecurityType.Future, out market))
                    {
                        // let's suggest a market
                        exception += $" Suggested market based on the provided ticker 'Market.{market.ToUpperInvariant()}'.";
                    }

                    throw new ArgumentException(exception);
                }
                // there was nothing that really matched exactly
                throw new ArgumentException($"Unable to locate exchange hours for {key}");
            }

            return(entry);
        }
示例#3
0
        /// <summary>
        /// Gets the entry for the specified market/symbol/security-type
        /// </summary>
        /// <param name="market">The market the exchange resides in, i.e, 'usa', 'fxcm', ect...</param>
        /// <param name="symbol">The particular symbol being traded</param>
        /// <param name="securityType">The security type of the symbol</param>
        /// <returns>The entry matching the specified market/symbol/security-type</returns>
        public virtual Entry GetEntry(string market, string symbol, SecurityType securityType)
        {
            Entry entry;

            if (!TryGetEntry(market, symbol, securityType, out entry))
            {
                var key  = new SecurityDatabaseKey(market, symbol, securityType);
                var keys = string.Join(", ", _entries.Keys);
                Log.Error($"MarketHoursDatabase.GetExchangeHours(): Unable to locate exchange hours for {key}.Available keys: {keys}");

                if (securityType == SecurityType.Future && market == Market.USA)
                {
                    var exception =
                        "Future.Usa market type is no longer supported as we mapped each ticker to its actual exchange. " +
                        "Please find your specific market in the symbol-properties database.";
                    if (SymbolPropertiesDatabase.FromDataFolder().TryGetMarket(symbol, SecurityType.Future, out market))
                    {
                        // let's suggest a market
                        exception += $" Suggested market based on the provided ticker 'Market.{market.ToUpperInvariant()}'.";
                    }

                    throw new ArgumentException(exception);
                }
                // there was nothing that really matched exactly
                throw new ArgumentException($"Unable to locate exchange hours for {key}");
            }

            return(entry);
        }
示例#4
0
        /// <summary>
        /// Gets the symbol properties for the specified market/symbol/security-type
        /// </summary>
        /// <param name="market">The market the exchange resides in, i.e, 'usa', 'fxcm', ect...</param>
        /// <param name="symbol">The particular symbol being traded (Symbol class)</param>
        /// <param name="securityType">The security type of the symbol</param>
        /// <param name="defaultQuoteCurrency">Specifies the quote currency to be used when returning a default instance of an entry is not found in the database</param>
        /// <returns>The symbol properties matching the specified market/symbol/security-type or null if not found</returns>
        /// <remarks>For any derivative options asset that is not for equities, we default to the underlying symbol's properties if no entry is found in the database</remarks>
        public SymbolProperties GetSymbolProperties(string market, Symbol symbol, SecurityType securityType, string defaultQuoteCurrency)
        {
            SymbolProperties symbolProperties;
            var lookupTicker = MarketHoursDatabase.GetDatabaseSymbolKey(symbol);
            var key          = new SecurityDatabaseKey(market, lookupTicker, securityType);

            if (!_entries.TryGetValue(key, out symbolProperties))
            {
                if (symbol != null && symbol.SecurityType == SecurityType.FutureOption)
                {
                    // Default to looking up the underlying symbol's properties and using those instead if there's
                    // no existing entry for the future option.
                    lookupTicker = MarketHoursDatabase.GetDatabaseSymbolKey(symbol.Underlying);
                    key          = new SecurityDatabaseKey(market, lookupTicker, symbol.Underlying.SecurityType);

                    if (_entries.TryGetValue(key, out symbolProperties))
                    {
                        return(symbolProperties);
                    }
                }

                // now check with null symbol key
                if (!_entries.TryGetValue(new SecurityDatabaseKey(market, null, securityType), out symbolProperties))
                {
                    // no properties found, return object with default property values
                    return(SymbolProperties.GetDefault(defaultQuoteCurrency));
                }
            }

            return(symbolProperties);
        }
示例#5
0
        /// <summary>
        /// Creates a new instance of <see cref="SymbolProperties"/> from the specified csv line
        /// </summary>
        /// <param name="line">The csv line to be parsed</param>
        /// <param name="key">The key used to uniquely identify this security</param>
        /// <returns>A new <see cref="SymbolProperties"/> for the specified csv line</returns>
        protected static SymbolProperties FromCsvLine(string line, out SecurityDatabaseKey key)
        {
            var csv = line.Split(',');

            SecurityType securityType;

            if (!csv[2].TryParseSecurityType(out securityType))
            {
                key = null;
                return(null);
            }

            key = new SecurityDatabaseKey(
                market: csv[0],
                symbol: csv[1],
                securityType: securityType);

            return(new SymbolProperties(
                       description: csv[3],
                       quoteCurrency: csv[4],
                       contractMultiplier: csv[5].ToDecimal(),
                       minimumPriceVariation: csv[6].ToDecimalAllowExponent(),
                       lotSize: csv[7].ToDecimal(),
                       marketTicker: csv.Length > 8 ? csv[8] : string.Empty));
        }
示例#6
0
        /// <summary>
        /// Gets the instance of the <see cref="MarketHoursDatabase"/> class produced by reading in the market hours
        /// data found in /Data/market-hours/
        /// </summary>
        /// <param name="dataFolder">Path to the data folder</param>
        /// <returns>A <see cref="MarketHoursDatabase"/> class that represents the data in the market-hours folder</returns>
        public static MarketHoursDatabase FromDataFolder(string dataFolder)
        {
            lock (DataFolderMarketHoursDatabaseLock)
            {
                if (_dataFolderMarketHoursDatabase == null)
                {
                    var path = Path.Combine(dataFolder, "market-hours", "market-hours-database.json");
                    _dataFolderMarketHoursDatabase = FromFile(path);

                    // Add markets not already present
                    Market.Reset();
                    var listing = _dataFolderMarketHoursDatabase.ExchangeHoursListing;
                    int code    = 0;
                    foreach (var item in listing)
                    {
                        SecurityDatabaseKey security = item.Key;
                        string market = security.Market;
                        if (Market.Encode(market) == null)
                        {
                            while (Market.Decode(code) != null)
                            {
                                code++;
                            }

                            // be sure to add a reference to the unknown market, otherwise we won't be able to decode it coming out
                            Market.Add(market, code);
                            code++;
                        }
                    }
                }
            }
            return(_dataFolderMarketHoursDatabase);
        }
示例#7
0
        /// <summary>
        /// Sets the entry for the specified market/symbol/security-type.
        /// This is intended to be used by custom data and other data sources that don't have explicit
        /// entries in market-hours-database.csv. At run time, the algorithm can update the market hours
        /// database via calls to AddData.
        /// </summary>
        /// <param name="market">The market the exchange resides in, i.e, 'usa', 'fxcm', ect...</param>
        /// <param name="symbol">The particular symbol being traded</param>
        /// <param name="securityType">The security type of the symbol</param>
        /// <param name="exchangeHours">The exchange hours for the specified symbol</param>
        /// <param name="dataTimeZone">The time zone of the symbol's raw data. Optional, defaults to the exchange time zone</param>
        /// <returns>The entry matching the specified market/symbol/security-type</returns>
        public virtual Entry SetEntry(string market, string symbol, SecurityType securityType, SecurityExchangeHours exchangeHours, DateTimeZone dataTimeZone = null)
        {
            dataTimeZone = dataTimeZone ?? exchangeHours.TimeZone;
            var key   = new SecurityDatabaseKey(market, symbol, securityType);
            var entry = new Entry(dataTimeZone, exchangeHours);

            _entries[key] = entry;
            return(entry);
        }
示例#8
0
            public override Entry GetEntry(string market, string symbol, SecurityType securityType)
            {
                var key = new SecurityDatabaseKey(market, symbol, securityType);
                var tz  = ContainsKey(key)
                    ? base.GetEntry(market, symbol, securityType).ExchangeHours.TimeZone
                    : DateTimeZone.Utc;

                return(new Entry(tz, SecurityExchangeHours.AlwaysOpen(tz)));
            }
示例#9
0
        /// <summary>
        /// Tries to get the market for the provided symbol/security type
        /// </summary>
        /// <param name="symbol">The particular symbol being traded</param>
        /// <param name="securityType">The security type of the symbol</param>
        /// <param name="market">The market the exchange resides in <see cref="Market"/></param>
        /// <returns>True if market was retrieved, false otherwise</returns>
        public bool TryGetMarket(string symbol, SecurityType securityType, out string market)
        {
            SecurityDatabaseKey result;
            var key = new SecurityDatabaseKey(SecurityDatabaseKey.Wildcard, symbol, securityType);

            if (_keyBySecurityType.TryGetValue(key, out result))
            {
                market = result.Market;
                return(true);
            }

            market = null;
            return(false);
        }
示例#10
0
        /// <summary>
        /// Creates a new instance of <see cref="SymbolProperties"/> from the specified csv line
        /// </summary>
        /// <param name="line">The csv line to be parsed</param>
        /// <param name="key">The key used to uniquely identify this security</param>
        /// <returns>A new <see cref="SymbolProperties"/> for the specified csv line</returns>
        private static SymbolProperties FromCsvLine(string line, out SecurityDatabaseKey key)
        {
            var csv = line.Split(',');

            key = new SecurityDatabaseKey(
                market: csv[0],
                symbol: string.IsNullOrEmpty(csv[1]) ? null : csv[1],
                securityType: (SecurityType)Enum.Parse(typeof(SecurityType), csv[2], true));

            return(new SymbolProperties(
                       description: csv[3],
                       quoteCurrency: csv[4],
                       contractMultiplier: csv[5].ToDecimal(),
                       pipSize: csv[6].ToDecimal()));
        }
示例#11
0
        /// <summary>
        /// Creates a new instance of <see cref="SymbolProperties"/> from the specified csv line
        /// </summary>
        /// <param name="line">The csv line to be parsed</param>
        /// <param name="key">The key used to uniquely identify this security</param>
        /// <returns>A new <see cref="SymbolProperties"/> for the specified csv line</returns>
        private static SymbolProperties FromCsvLine(string line, out SecurityDatabaseKey key)
        {
            var csv = line.Split(',');

            key = new SecurityDatabaseKey(
                market: csv[0],
                symbol: csv[1],
                securityType: (SecurityType)Enum.Parse(typeof(SecurityType), csv[2], true));

            return(new SymbolProperties(
                       description: csv[3],
                       quoteCurrency: csv[4],
                       contractMultiplier: csv[5].ToDecimal(),
                       minimumPriceVariation: csv[6].ToDecimalAllowExponent(),
                       lotSize: csv[7].ToDecimal()));
        }
示例#12
0
        /// <summary>
        /// Gets the symbol properties for the specified market/symbol/security-type
        /// </summary>
        /// <param name="market">The market the exchange resides in, i.e, 'usa', 'fxcm', ect...</param>
        /// <param name="symbol">The particular symbol being traded</param>
        /// <param name="securityType">The security type of the symbol</param>
        /// <param name="defaultQuoteCurrency">Specifies the quote currency to be used when returning a default instance of an entry is not found in the database</param>
        /// <returns>The symbol properties matching the specified market/symbol/security-type or null if not found</returns>
        public SymbolProperties GetSymbolProperties(string market, string symbol, SecurityType securityType, string defaultQuoteCurrency)
        {
            SymbolProperties symbolProperties;
            var key = new SecurityDatabaseKey(market, symbol, securityType);

            if (!_entries.TryGetValue(key, out symbolProperties))
            {
                // now check with null symbol key
                if (!_entries.TryGetValue(new SecurityDatabaseKey(market, null, securityType), out symbolProperties))
                {
                    // no properties found, return object with default property values
                    return(SymbolProperties.GetDefault(defaultQuoteCurrency));
                }
            }

            return(symbolProperties);
        }
示例#13
0
        /// <summary>
        /// Gets the entry for the specified market/symbol/security-type
        /// </summary>
        /// <param name="market">The market the exchange resides in, i.e, 'usa', 'fxcm', ect...</param>
        /// <param name="symbol">The particular symbol being traded</param>
        /// <param name="securityType">The security type of the symbol</param>
        /// <returns>The entry matching the specified market/symbol/security-type</returns>
        public virtual Entry GetEntry(string market, string symbol, SecurityType securityType)
        {
            Entry entry;
            var   key = new SecurityDatabaseKey(market, symbol, securityType);

            if (!_entries.TryGetValue(key, out entry))
            {
                // now check with null symbol key
                if (!_entries.TryGetValue(new SecurityDatabaseKey(market, null, securityType), out entry))
                {
                    var keys = string.Join(", ", _entries.Keys);
                    Log.Error($"MarketHoursDatabase.GetExchangeHours(): Unable to locate exchange hours for {key}.Available keys: {keys}");

                    // there was nothing that really matched exactly... what should we do here?
                    throw new ArgumentException("Unable to locate exchange hours for " + key);
                }
            }

            return(entry);
        }
示例#14
0
        /// <summary>
        /// Gets the symbol properties for the specified market/symbol/security-type
        /// </summary>
        /// <param name="market">The market the exchange resides in, i.e, 'usa', 'fxcm', ect...</param>
        /// <param name="symbol">The particular symbol being traded</param>
        /// <param name="securityType">The security type of the symbol</param>
        /// <returns>The symbol properties matching the specified market/symbol/security-type or null if not found</returns>
        public SymbolProperties GetSymbolProperties(string market, string symbol, SecurityType securityType)
        {
            SymbolProperties symbolProperties;
            var key = new SecurityDatabaseKey(market, symbol, securityType);

            if (!_entries.TryGetValue(key, out symbolProperties))
            {
                // now check with null symbol key
                if (!_entries.TryGetValue(new SecurityDatabaseKey(market, null, securityType), out symbolProperties))
                {
                    // no properties found, return object with default property values
                    return(new SymbolProperties(
                               description: "",
                               quoteCurrency: "USD",
                               contractMultiplier: 1m,
                               pipSize: 0.01m));
                }
            }

            return(symbolProperties);
        }
示例#15
0
        /// <summary>
        /// Gets the entry for the specified market/symbol/security-type
        /// </summary>
        /// <param name="market">The market the exchange resides in, i.e, 'usa', 'fxcm', ect...</param>
        /// <param name="symbol">The particular symbol being traded</param>
        /// <param name="securityType">The security type of the symbol</param>
        /// <param name="overrideTimeZone">Specify this time zone to override the resolved time zone from the market hours database.
        /// This value will also be used as the time zone for SecurityType.Base with no market hours database entry.
        /// If null is specified, no override will be performed. If null is specified, and it's SecurityType.Base, then Utc will be used.</param>
        /// <returns>The entry matching the specified market/symbol/security-type</returns>
        public virtual Entry GetEntry(string market, string symbol, SecurityType securityType, DateTimeZone overrideTimeZone = null)
        {
            Entry entry;
            var   key = new SecurityDatabaseKey(market, symbol, securityType);

            if (!_entries.TryGetValue(key, out entry))
            {
                // now check with null symbol key
                if (!_entries.TryGetValue(new SecurityDatabaseKey(market, null, securityType), out entry))
                {
                    if (securityType == SecurityType.Base)
                    {
                        if (overrideTimeZone == null)
                        {
                            overrideTimeZone = TimeZones.Utc;
                            Log.Error("MarketHoursDatabase.GetExchangeHours(): Custom data no time zone specified, default to UTC. " + key);
                        }
                        // base securities are always open by default and have equal data time zone and exchange time zones
                        return(new Entry(overrideTimeZone, SecurityExchangeHours.AlwaysOpen(overrideTimeZone)));
                    }

                    Log.Error(string.Format("MarketHoursDatabase.GetExchangeHours(): Unable to locate exchange hours for {0}." + "Available keys: {1}", key, string.Join(", ", _entries.Keys)));

                    // there was nothing that really matched exactly... what should we do here?
                    throw new ArgumentException("Unable to locate exchange hours for " + key);
                }

                // perform time zone override if requested, we'll use the same exact local hours
                // and holidays, but we'll express them in a different time zone
                if (overrideTimeZone != null && !entry.ExchangeHours.TimeZone.Equals(overrideTimeZone))
                {
                    return(new Entry(overrideTimeZone, new SecurityExchangeHours(overrideTimeZone, entry.ExchangeHours.Holidays, entry.ExchangeHours.MarketHours, entry.ExchangeHours.EarlyCloses)));
                }
            }

            return(entry);
        }
示例#16
0
        private SymbolPropertiesDatabase(string file)
        {
            var allEntries            = new Dictionary <SecurityDatabaseKey, SymbolProperties>();
            var entriesBySecurityType = new Dictionary <SecurityDatabaseKey, SecurityDatabaseKey>();

            foreach (var keyValuePair in FromCsvFile(file))
            {
                if (allEntries.ContainsKey(keyValuePair.Key))
                {
                    throw new DuplicateNameException($"Encountered duplicate key while processing file: {file}. Key: {keyValuePair.Key}");
                }
                // we wildcard the market, so per security type and symbol we will keep the *first* instance
                // this allows us to fetch deterministically, in O(1), an entry without knowing the market, see 'TryGetMarket()'
                var key = new SecurityDatabaseKey(SecurityDatabaseKey.Wildcard, keyValuePair.Key.Symbol, keyValuePair.Key.SecurityType);
                if (!entriesBySecurityType.ContainsKey(key))
                {
                    entriesBySecurityType[key] = keyValuePair.Key;
                }
                allEntries[keyValuePair.Key] = keyValuePair.Value;
            }

            _entries           = allEntries;
            _keyBySecurityType = entriesBySecurityType;
        }
示例#17
0
 /// <summary>
 /// Determines if the database contains the specified key
 /// </summary>
 /// <param name="key">The key to search for</param>
 /// <returns>True if an entry is found, otherwise false</returns>
 protected bool ContainsKey(SecurityDatabaseKey key)
 {
     return(_entries.ContainsKey(key));
 }
示例#18
0
        /// <summary>
        /// Check whether symbol properties exists for the specified market/symbol/security-type
        /// </summary>
        /// <param name="market">The market the exchange resides in, i.e, 'usa', 'fxcm', ect...</param>
        /// <param name="symbol">The particular symbol being traded</param>
        /// <param name="securityType">The security type of the symbol</param>
        public bool ContainsKey(string market, string symbol, SecurityType securityType)
        {
            var key = new SecurityDatabaseKey(market, symbol, securityType);

            return(_entries.ContainsKey(key));
        }