public void ConstructorWithNullSymbolConvertsToWildcard() { var key = new SecurityDatabaseKey(Market.USA, null, SecurityType.Equity); Assert.AreEqual(SecurityType.Equity, key.SecurityType); Assert.AreEqual(Market.USA, key.Market); Assert.AreEqual("[*]", key.Symbol); }
public void ConstructorWithEmptyMarketConvertsToWildcard() { var key = new SecurityDatabaseKey(string.Empty, "SPY", SecurityType.Equity); Assert.AreEqual(SecurityType.Equity, key.SecurityType); Assert.AreEqual("[*]", key.Market); Assert.AreEqual("SPY", key.Symbol); }
public void ConstructorWithNoWildcards() { var key = new SecurityDatabaseKey(Market.USA, "SPY", SecurityType.Equity); Assert.AreEqual(SecurityType.Equity, key.SecurityType); Assert.AreEqual(Market.USA, key.Market); Assert.AreEqual("SPY", key.Symbol); }
public void EqualityMembersAreCaseInsensitive() { var key = new SecurityDatabaseKey("uSa", "SPY", SecurityType.Equity); var key2 = new SecurityDatabaseKey("UsA", "spy", SecurityType.Equity); Assert.AreEqual(key, key2); Assert.AreEqual(key.GetHashCode(), key2.GetHashCode()); }
public void ThrowsOnInvalidFormat() { const string input = "Equity-[*]"; Assert.Throws <FormatException>(() => { SecurityDatabaseKey.Parse(input); }, "expected format"); }
public void ParsesKeyProperly() { const string input = "Equity-usa-SPY"; var key = SecurityDatabaseKey.Parse(input); Assert.AreEqual(SecurityType.Equity, key.SecurityType); Assert.AreEqual(Market.USA, key.Market); Assert.AreEqual("SPY", key.Symbol); }
public void ParsesWildcardMarket() { const string input = "Equity-[*]-SPY"; var key = SecurityDatabaseKey.Parse(input); Assert.AreEqual(SecurityType.Equity, key.SecurityType); Assert.AreEqual("[*]", key.Market); Assert.AreEqual("SPY", key.Symbol); }
public void ThrowsOnWildcardSecurityType() { const string input = "[*]-usa-SPY"; Assert.Throws <ArgumentException>(() => { SecurityDatabaseKey.Parse(input); }, "as a SecurityType"); }
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))); }
/// <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; }
/// <summary> /// Creates a new instance of <see cref="SecurityExchangeHours"/> from the specified csv line and holiday set /// </summary> /// <param name="line">The csv line to be parsed</param> /// <param name="holidaysByMarket">The holidays this exchange isn't open for trading by market</param> /// <param name="key">The key used to uniquely identify these market hours</param> /// <returns>A new <see cref="SecurityExchangeHours"/> for the specified csv line and holidays</returns> private static MarketHoursDatabase.Entry FromCsvLine(string line, IReadOnlyDictionary <string, IEnumerable <DateTime> > holidaysByMarket, out SecurityDatabaseKey key) { var csv = line.Split(','); var marketHours = new List <LocalMarketHours>(7); // timezones can be specified using Tzdb names (America/New_York) or they can // be specified using offsets, UTC-5 var dataTimeZone = ParseTimeZone(csv[0]); var exchangeTimeZone = ParseTimeZone(csv[1]); //var market = csv[2]; //var symbol = csv[3]; //var type = csv[4]; var symbol = string.IsNullOrEmpty(csv[3]) ? null : csv[3]; key = new SecurityDatabaseKey(csv[2], symbol, (SecurityType)Enum.Parse(typeof(SecurityType), csv[4], true)); int csvLength = csv.Length; for (int i = 1; i < 8; i++) // 7 days, so < 8 { // the 4 here is because 4 times per day, ex_open,open,close,ex_close if (4 * i + 4 > csvLength - 1) { break; } var hours = ReadCsvHours(csv, 4 * i + 1, (DayOfWeek)(i - 1)); marketHours.Add(hours); } IEnumerable <DateTime> holidays; if (!holidaysByMarket.TryGetValue(key.Market, out holidays)) { holidays = Enumerable.Empty <DateTime>(); } var earlyCloses = new Dictionary <DateTime, TimeSpan>(); var lateOpens = new Dictionary <DateTime, TimeSpan>(); var exchangeHours = new SecurityExchangeHours(exchangeTimeZone, holidays, marketHours.ToDictionary(x => x.DayOfWeek), earlyCloses, lateOpens); return(new MarketHoursDatabase.Entry(dataTimeZone, exchangeHours)); }
/// <summary> /// Converts this json representation to the <see cref="MarketHoursDatabase"/> type /// </summary> /// <returns>A new instance of the <see cref="MarketHoursDatabase"/> class</returns> public MarketHoursDatabase Convert() { var entries = new Dictionary <SecurityDatabaseKey, MarketHoursDatabase.Entry>(); foreach (var entry in Entries) { try { var key = SecurityDatabaseKey.Parse(entry.Key); entries[key] = entry.Value.Convert(); } catch (Exception err) { Log.Error(err); } } return(new MarketHoursDatabase(entries)); }
/// <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; }
public void ThrowsOnWildcardSecurityType() { const string input = "[*]-usa-SPY"; SecurityDatabaseKey.Parse(input); }
public static SymbolProperties TestFromCsvLine(string line, out SecurityDatabaseKey key) { return(FromCsvLine(line, out key)); }
/// <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)); } } return entry; }
/// <summary> /// Creates a new instance of <see cref="SecurityExchangeHours"/> from the specified csv line and holiday set /// </summary> /// <param name="line">The csv line to be parsed</param> /// <param name="holidaysByMarket">The holidays this exchange isn't open for trading by market</param> /// <param name="key">The key used to uniquely identify these market hours</param> /// <returns>A new <see cref="SecurityExchangeHours"/> for the specified csv line and holidays</returns> private static MarketHoursDatabase.Entry FromCsvLine(string line, IReadOnlyDictionary<string, IEnumerable<DateTime>> holidaysByMarket, out SecurityDatabaseKey key) { var csv = line.Split(','); var marketHours = new List<LocalMarketHours>(7); // timezones can be specified using Tzdb names (America/New_York) or they can // be specified using offsets, UTC-5 var dataTimeZone = ParseTimeZone(csv[0]); var exchangeTimeZone = ParseTimeZone(csv[1]); //var market = csv[2]; //var symbol = csv[3]; //var type = csv[4]; var symbol = string.IsNullOrEmpty(csv[3]) ? null : csv[3]; key = new SecurityDatabaseKey(csv[2], symbol, (SecurityType)Enum.Parse(typeof(SecurityType), csv[4], true)); int csvLength = csv.Length; for (int i = 1; i < 8; i++) // 7 days, so < 8 { // the 4 here is because 4 times per day, ex_open,open,close,ex_close if (4*i + 4 > csvLength - 1) { break; } var hours = ReadCsvHours(csv, 4*i + 1, (DayOfWeek) (i - 1)); marketHours.Add(hours); } IEnumerable<DateTime> holidays; if (!holidaysByMarket.TryGetValue(key.Market, out holidays)) { holidays = Enumerable.Empty<DateTime>(); } var exchangeHours = new SecurityExchangeHours(exchangeTimeZone, holidays, marketHours.ToDictionary(x => x.DayOfWeek)); return new MarketHoursDatabase.Entry(dataTimeZone, exchangeHours); }
/// <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(), pipSize: csv[6].ToDecimal()); }
public void DoesNotThrowOnUnknownSecurityType(string key) { Assert.DoesNotThrow(() => SecurityDatabaseKey.Parse(key)); }
public void ThrowsOnInvalidFormat() { const string input = "Equity-[*]"; SecurityDatabaseKey.Parse(input); }