예제 #1
0
 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);
 }
예제 #2
0
 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);
 }
예제 #3
0
 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);
 }
예제 #4
0
        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());
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        public void ThrowsOnInvalidFormat()
        {
            const string input = "Equity-[*]";

            Assert.Throws <FormatException>(() =>
            {
                SecurityDatabaseKey.Parse(input);
            }, "expected format");
        }
예제 #9
0
        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);
        }
예제 #10
0
        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);
        }
예제 #11
0
        public void ThrowsOnWildcardSecurityType()
        {
            const string input = "[*]-usa-SPY";

            Assert.Throws <ArgumentException>(() =>
            {
                SecurityDatabaseKey.Parse(input);
            }, "as a SecurityType");
        }
예제 #12
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)));
            }
예제 #13
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;
        }
예제 #14
0
        /// <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));
            }
예제 #16
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;
        }
예제 #17
0
        public void ThrowsOnWildcardSecurityType()
        {
            const string input = "[*]-usa-SPY";

            SecurityDatabaseKey.Parse(input);
        }
예제 #18
0
 public static SymbolProperties TestFromCsvLine(string line, out SecurityDatabaseKey key)
 {
     return(FromCsvLine(line, out key));
 }
예제 #19
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));
                }
            }

            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);
        }
예제 #21
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(), 
                pipSize: csv[6].ToDecimal());
        }
예제 #22
0
 public void DoesNotThrowOnUnknownSecurityType(string key)
 {
     Assert.DoesNotThrow(() => SecurityDatabaseKey.Parse(key));
 }
예제 #23
0
        public void ThrowsOnInvalidFormat()
        {
            const string input = "Equity-[*]";

            SecurityDatabaseKey.Parse(input);
        }