public void EnsureCurrencyDataFeedChecksSecurityChangesForSecurity() { const int quantity = 100; const decimal conversionRate = 1 / 100m; var cash = new Cash("JPY", quantity, conversionRate); var cashBook = new CashBook(); cashBook.Add("JPY", cash); var subscriptions = new SubscriptionManager(); subscriptions.SetDataManager(new DataManagerStub(TimeKeeper)); var abcConfig = subscriptions.Add(Symbols.SPY, Resolution.Minute, TimeZone, TimeZone); var securities = new SecurityManager(TimeKeeper); securities.Add( Symbols.SPY, new Security( SecurityExchangeHours, abcConfig, new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency), ErrorCurrencyConverter.Instance ) ); var usdjpy = new Security(Symbols.USDJPY, SecurityExchangeHours, new Cash("JPY", 0, 0), SymbolProperties.GetDefault("JPY"), ErrorCurrencyConverter.Instance); var changes = new SecurityChanges(new[] { usdjpy }, Enumerable.Empty <Security>()); var addedSecurity = cash.EnsureCurrencyDataFeed(securities, subscriptions, AlwaysOpenMarketHoursDatabase, SymbolPropertiesDatabase.FromDataFolder(), MarketMap, cashBook, changes); // the security exists in SecurityChanges so it is NOT added to the security manager or subscriptions // this security will be added by the algorithm manager Assert.IsNull(addedSecurity); }
public void UpdateModifiesConversionRate() { const int quantity = 100; const decimal conversionRate = 1 / 100m; var cash = new Cash("GBP", quantity, conversionRate); var subscriptions = new SubscriptionManager(TimeKeeper); var securities = new SecurityManager(TimeKeeper); securities.Add("GBPUSD", new Security(SecurityExchangeHours.AlwaysOpen, subscriptions.Add(SecurityType.Forex, "GBPUSD", Resolution.Minute, "fxcm", TimeZones.NewYork), 1m)); // we need to get subscription index cash.EnsureCurrencyDataFeed(securities, subscriptions, SecurityExchangeHoursProvider.AlwaysOpen); var last = 1.5m; var data = new Dictionary <int, List <BaseData> >(); data.Add(0, new List <BaseData> { new Tick(DateTime.Now, "GBPUSD", last, last * 1.009m, last * 0.009m) }); cash.Update(data); // jpy is inverted, so compare on the inverse Assert.AreEqual(last, cash.ConversionRate); }
public void EnsureInternalCurrencyDataFeedsForNonUsdQuoteCurrencyGetAdded() { const int quantity = 100; const decimal conversionRate = 1 / 100m; var cashJPY = new Cash("JPY", quantity, conversionRate); var cashGBP = new Cash("GBP", quantity, conversionRate); var cashBook = new CashBook(); cashBook.Add("JPY", cashJPY); cashBook.Add("GBP", cashGBP); var symbol = Symbol.Create("GBPJPY", SecurityType.Forex, Market.FXCM); var subscriptions = new SubscriptionManager(TimeKeeper, new DataManagerStub()); var securities = new SecurityManager(TimeKeeper); securities.Add(symbol, new Security(SecurityExchangeHours, subscriptions.Add(symbol, Resolution.Minute, TimeZone, TimeZone), new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency))); cashJPY.EnsureCurrencyDataFeed(securities, subscriptions, AlwaysOpenMarketHoursDatabase, SymbolPropertiesDatabase.FromDataFolder(), MarketMap, cashBook, SecurityChanges.None); var config1 = subscriptions.Subscriptions.Single(x => x.Symbol == Symbols.USDJPY); Assert.IsTrue(config1.IsInternalFeed); cashGBP.EnsureCurrencyDataFeed(securities, subscriptions, AlwaysOpenMarketHoursDatabase, SymbolPropertiesDatabase.FromDataFolder(), MarketMap, cashBook, SecurityChanges.None); var config2 = subscriptions.Subscriptions.Single(x => x.Symbol == Symbols.GBPUSD); Assert.IsTrue(config2.IsInternalFeed); }
public void EnsureCurrencyDataFeedsAddsSubscriptionAtMinimumResolution() { const int quantity = 100; const decimal conversionRate = 1 / 100m; const Resolution minimumResolution = Resolution.Second; var cash = new Cash("JPY", quantity, conversionRate); var subscriptions = new SubscriptionManager(TimeKeeper); var securities = new SecurityManager(TimeKeeper); securities.Add("ABC", new Security(SecurityExchangeHours.AlwaysOpen, subscriptions.Add(SecurityType.Equity, "ABC", Resolution.Minute, "usa", TimeZones.NewYork), 1m)); securities.Add("BCD", new Security(SecurityExchangeHours.AlwaysOpen, subscriptions.Add(SecurityType.Forex, "BCD", minimumResolution, "fxcm", TimeZones.NewYork), 1m)); cash.EnsureCurrencyDataFeed(securities, subscriptions, SecurityExchangeHoursProvider.AlwaysOpen); Assert.AreEqual(minimumResolution, subscriptions.Subscriptions.Single(x => x.Symbol == "USDJPY").Resolution); }
public void EnsureCurrencyDataFeedAddsSubscription() { const int quantity = 100; const decimal conversionRate = 1 / 100m; var cash = new Cash("JPY", quantity, conversionRate); var cashBook = new CashBook(); cashBook.Add("JPY", cash); var subscriptions = new SubscriptionManager(); var dataManager = new DataManagerStub(TimeKeeper); subscriptions.SetDataManager(dataManager); var abcConfig = subscriptions.Add(Symbols.SPY, Resolution.Minute, TimeZone, TimeZone); var securities = new SecurityManager(TimeKeeper); securities.Add( Symbols.SPY, new Security( SecurityExchangeHours, abcConfig, new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(cashBook.AccountCurrency), cashBook, RegisteredSecurityDataTypesProvider.Null, new SecurityCache())); cash.EnsureCurrencyDataFeed(securities, subscriptions, MarketMap, SecurityChanges.None, dataManager.SecurityService, cashBook.AccountCurrency); Assert.AreEqual(1, subscriptions.SubscriptionDataConfigService.GetSubscriptionDataConfigs(Symbols.USDJPY, includeInternalConfigs: true).Count); Assert.AreEqual(1, securities.Values.Count(x => x.Symbol == Symbols.USDJPY)); }
public void EnsureCurrencyDataFeedDoesNotMarkIsCurrencyDataFeedForExistantSubscriptions() { const int quantity = 100; const decimal conversionRate = 1 / 100m; var cash = new Cash("JPY", quantity, conversionRate); var cashBook = new CashBook(); cashBook.Add("JPY", cash); var subscriptions = new SubscriptionManager(); var dataManager = new DataManagerStub(TimeKeeper); subscriptions.SetDataManager(dataManager); var securities = new SecurityManager(TimeKeeper); securities.Add( Symbols.USDJPY, new Security( SecurityExchangeHours, subscriptions.Add(Symbols.USDJPY, Resolution.Minute, TimeZone, TimeZone), new Cash(cashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(cashBook.AccountCurrency), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ) ); cash.EnsureCurrencyDataFeed(securities, subscriptions, MarketMap, SecurityChanges.None, dataManager.SecurityService, cashBook.AccountCurrency); var config = subscriptions.Subscriptions.Single(x => x.Symbol == Symbols.USDJPY); Assert.IsFalse(config.IsInternalFeed); }
public void EnsureCurrencyDataFeedChecksSecurityChangesForSecurity() { const int quantity = 100; const decimal conversionRate = 1 / 100m; var cash = new Cash("JPY", quantity, conversionRate); var cashBook = new CashBook(); cashBook.Add("JPY", cash); var subscriptions = new SubscriptionManager(); var dataManager = new DataManagerStub(TimeKeeper); subscriptions.SetDataManager(dataManager); var abcConfig = subscriptions.Add(Symbols.SPY, Resolution.Minute, TimeZone, TimeZone); var securities = new SecurityManager(TimeKeeper); securities.Add( Symbols.SPY, new Security( SecurityExchangeHours, abcConfig, new Cash(cashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(cashBook.AccountCurrency), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ) ); var usdjpy = new Security(Symbols.USDJPY, SecurityExchangeHours, new Cash("JPY", 0, 0), SymbolProperties.GetDefault("JPY"), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache()); var changes = SecurityChangesTests.CreateNonInternal(new[] { usdjpy }, Enumerable.Empty <Security>()); var addedSecurities = cash.EnsureCurrencyDataFeed(securities, subscriptions, MarketMap, changes, dataManager.SecurityService, cashBook.AccountCurrency); // the security exists in SecurityChanges so it is NOT added to the security manager or subscriptions // this security will be added by the algorithm manager Assert.True(addedSecurities == null || addedSecurities.Count == 0); }
/// <summary> /// Ensures that we have a data feed to conver this currency into the base currency. /// This will add a subscription at the lowest resolution if one is not found. /// </summary> /// <param name="subscriptions">The subscription manager used for searching and adding subscriptions</param> /// <param name="securities"></param> public void EnsureCurrencyDataFeed(SubscriptionManager subscriptions, SecurityManager securities) { if (Symbol == CashBook.BaseCurrency) { _isBaseCurrency = true; ConversionRate = 1.0m; return; } if (subscriptions.Count == 0) { throw new InvalidOperationException("Unable to add cash when no subscriptions are present. Please add subscriptions in the Initialize() method."); } // we require a subscription that converts this into the base currency string normal = Symbol + CashBook.BaseCurrency; string invert = CashBook.BaseCurrency + Symbol; for (int i = 0; i < subscriptions.Subscriptions.Count; i++) { var config = subscriptions.Subscriptions[i]; if (config.Security != SecurityType.Forex) { continue; } if (config.Symbol == normal) { _config = config; return; } if (config.Symbol == invert) { _config = config; _invertRealTimePrice = true; return; } } // if we've made it here we didn't find a subscription, so we'll need to add one var currencyPairs = Forex.Forex.CurrencyPairs; var minimumResolution = subscriptions.Subscriptions.Min(x => x.Resolution); var objectType = minimumResolution == Resolution.Tick ? typeof(Tick) : typeof(TradeBar); var isTradeBar = objectType == typeof(TradeBar); foreach (var symbol in currencyPairs) { if (symbol == normal || symbol == invert) { _invertRealTimePrice = symbol == invert; // set this as an internal feed so that the data doesn't get sent into the algorithm's OnData events _config = subscriptions.Add(objectType, SecurityType.Forex, symbol, minimumResolution, true, false, isTradeBar, isTradeBar, true); securities.Add(symbol, _config, 1m, false); return; } } // if this still hasn't been set then it's an error condition throw new ArgumentException(string.Format("In order to maintain cash in {0} you are required to add a subscription for Forex pair {0}{1} or {1}{0}", Symbol, CashBook.BaseCurrency)); }
public void EnsureCurrencyDataFeedsAddsSubscriptionAtMinimumResolution() { const int quantity = 100; const decimal conversionRate = 1 / 100m; const Resolution minimumResolution = Resolution.Second; var cash = new Cash("JPY", quantity, conversionRate); var cashBook = new CashBook(); cashBook.Add("JPY", cash); var subscriptions = new SubscriptionManager(); var dataManager = new DataManagerStub(TimeKeeper); subscriptions.SetDataManager(dataManager); var securities = new SecurityManager(TimeKeeper); securities.Add( Symbols.SPY, new Security( SecurityExchangeHours, subscriptions.Add(Symbols.SPY, Resolution.Minute, TimeZone, TimeZone), new Cash(cashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(cashBook.AccountCurrency), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ) ); securities.Add( Symbols.EURUSD, new Security( SecurityExchangeHours, subscriptions.Add(Symbols.EURUSD, minimumResolution, TimeZone, TimeZone), new Cash(cashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(cashBook.AccountCurrency), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ) ); cash.EnsureCurrencyDataFeed(securities, subscriptions, MarketMap, SecurityChanges.None, dataManager.SecurityService, cashBook.AccountCurrency); Assert.AreEqual(minimumResolution, subscriptions.SubscriptionDataConfigService.GetSubscriptionDataConfigs(Symbols.USDJPY, includeInternalConfigs: true).Single().Resolution); }
public void NonUsdAccountCurrencyCurrencyDataFeedsGetAdded(string accountCurrency, string quoteCurrency, string baseCurrency, string quoteCurrencySymbol, string baseCurrencySymbol, SecurityType securityType, string market) { var quoteCash = new Cash(quoteCurrency, 100, 1); var baseCash = new Cash(baseCurrency, 100, 1); var cashBook = new CashBook { { quoteCurrency, quoteCash }, { baseCurrency, baseCash } }; var symbol = Symbol.Create(baseCurrency + quoteCurrency, securityType, market); var subscriptions = new SubscriptionManager(); var dataManager = new DataManagerStub(TimeKeeper); subscriptions.SetDataManager(dataManager); var securities = new SecurityManager(TimeKeeper) { { symbol, new Security( SecurityExchangeHours, subscriptions.Add(symbol, Resolution.Minute, TimeZone, TimeZone), new Cash(cashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(cashBook.AccountCurrency), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ) } }; var symbol1 = quoteCash.EnsureCurrencyDataFeed(securities, subscriptions, MarketMap, SecurityChanges.None, dataManager.SecurityService, accountCurrency); Assert.IsNotNull(symbol1); Assert.AreEqual(quoteCurrencySymbol, symbol1.Symbol.Value); var symbol2 = baseCash.EnsureCurrencyDataFeed(securities, subscriptions, MarketMap, SecurityChanges.None, dataManager.SecurityService, accountCurrency); Assert.IsNotNull(symbol2); Assert.AreEqual(baseCurrencySymbol, symbol2.Symbol.Value); }
public void EnsureCurrencyDataFeedsAddsSubscriptionAtMinimumResolution() { const int quantity = 100; const decimal conversionRate = 1 / 100m; const Resolution minimumResolution = Resolution.Second; var cash = new Cash("JPY", quantity, conversionRate); var cashBook = new CashBook(); cashBook.Add("JPY", cash); var subscriptions = new SubscriptionManager(TimeKeeper); var securities = new SecurityManager(TimeKeeper); securities.Add(Symbols.SPY, new Security(SecurityExchangeHours, subscriptions.Add(Symbols.SPY, Resolution.Minute, TimeZone, TimeZone), new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency))); securities.Add(Symbols.EURUSD, new Security(SecurityExchangeHours, subscriptions.Add(Symbols.EURUSD, minimumResolution, TimeZone, TimeZone), new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency))); cash.EnsureCurrencyDataFeed(securities, subscriptions, MarketHoursDatabase.AlwaysOpen, SymbolPropertiesDatabase.FromDataFolder(), MarketMap, cashBook); Assert.AreEqual(minimumResolution, subscriptions.Subscriptions.Single(x => x.Symbol == Symbols.USDJPY).Resolution); }
public void TestCashFills() { // this test asserts the portfolio behaves according to the Test_Cash algo, see TestData\CashTestingStrategy.csv // also "https://www.dropbox.com/s/oiliumoyqqj1ovl/2013-cash.csv?dl=1" const string fillsFile = "TestData\\test_cash_fills.xml"; const string equityFile = "TestData\\test_cash_equity.xml"; var fills = XDocument.Load(fillsFile).Descendants("OrderEvent").Select(x => new OrderEvent( x.Get <int>("OrderId"), SymbolMap[x.Get <string>("Symbol")], DateTime.MinValue, x.Get <OrderStatus>("Status"), x.Get <int>("FillQuantity") < 0 ? OrderDirection.Sell : x.Get <int>("FillQuantity") > 0 ? OrderDirection.Buy : OrderDirection.Hold, x.Get <decimal>("FillPrice"), x.Get <int>("FillQuantity"), 0m) ).ToList(); var equity = XDocument.Load(equityFile).Descendants("decimal") .Select(x => decimal.Parse(x.Value, CultureInfo.InvariantCulture)) .ToList(); Assert.AreEqual(fills.Count + 1, equity.Count); // we're going to process fills and very our equity after each fill var subscriptions = new SubscriptionManager(TimeKeeper); var securities = new SecurityManager(TimeKeeper); var security = new Security(SecurityExchangeHours, subscriptions.Add(CASH, Resolution.Daily, TimeZones.NewYork, TimeZones.NewYork), new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency)); security.SetLeverage(10m); securities.Add(CASH, security); var transactions = new SecurityTransactionManager(securities); var portfolio = new SecurityPortfolioManager(securities, transactions); portfolio.SetCash(equity[0]); for (int i = 0; i < fills.Count; i++) { // before processing the fill we must deduct the cost var fill = fills[i]; var time = DateTime.Today.AddDays(i); TimeKeeper.SetUtcDateTime(time.ConvertToUtc(TimeZones.NewYork)); // the value of 'CASH' increments for each fill, the original test algo did this monthly // the time doesn't really matter though security.SetMarketPrice(new IndicatorDataPoint(CASH, time, i + 1)); portfolio.ProcessFill(fill); Assert.AreEqual(equity[i + 1], portfolio.TotalPortfolioValue, "Failed on " + i); } }
public void EnsureCurrencyDataFeedsForNonUsdQuoteCurrencyDoNotGetAddedToSymbolCache() { SymbolCache.Clear(); const int quantity = 100; const decimal conversionRate = 1 / 100m; var cashJPY = new Cash("JPY", quantity, conversionRate); var cashGBP = new Cash("GBP", quantity, conversionRate); var cashBook = new CashBook(); cashBook.Add("JPY", cashJPY); cashBook.Add("GBP", cashGBP); var symbol = Symbol.Create("GBPJPY", SecurityType.Forex, Market.FXCM); var subscriptions = new SubscriptionManager(); var dataManager = new DataManagerStub(TimeKeeper); subscriptions.SetDataManager(dataManager); var securities = new SecurityManager(TimeKeeper); securities.Add( symbol, new Security( SecurityExchangeHours, subscriptions.Add(symbol, Resolution.Minute, TimeZone, TimeZone), new Cash(cashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(cashBook.AccountCurrency), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ) ); Assert.IsNotNull( cashGBP.EnsureCurrencyDataFeed( securities, subscriptions, MarketMap, SecurityChanges.None, dataManager.SecurityService, cashBook.AccountCurrency)); Assert.IsNotNull( cashJPY.EnsureCurrencyDataFeed(securities, subscriptions, MarketMap, SecurityChanges.None, dataManager.SecurityService, cashBook.AccountCurrency)); Assert.IsFalse(SymbolCache.TryGetSymbol("USDJPY", out symbol)); Assert.IsFalse(SymbolCache.TryGetSymbol("GBPUSD", out symbol)); }
/// <summary> /// AddData<typeparam name="T"/> a new user defined data source, requiring only the minimum config options. /// </summary> /// <param name="symbol">Key/Symbol for data</param> /// <param name="resolution">Resolution of the Data Required</param> /// <param name="fillDataForward">When no data available on a tradebar, return the last data that was generated</param> /// <param name="leverage">Custom leverage per security</param> /// <remarks>Generic type T must implement base data</remarks> public void AddData <T>(string symbol, Resolution resolution, bool fillDataForward, decimal leverage = 1.0m) { if (_locked) { return; } //Add this to the data-feed subscriptions SubscriptionManager.Add(typeof(T), SecurityType.Base, symbol, resolution, fillDataForward, extendedMarketHours: true); //Add this new generic data as a tradeable security: Securities.Add(symbol, SecurityType.Base, resolution, fillDataForward, leverage, extendedMarketHours: true, isDynamicallyLoadedData: true); }
/// <summary> /// Add a new user defined data source, requiring only the minimum config options: /// </summary> /// <param name="type">typeof(Type) data</param> /// <param name="symbol">Key/Symbol for data</param> public void AddData <T>(string symbol, Resolution resolution = Resolution.Second) { if (!_locked) { //Add this to the data-feed subscriptions SubscriptionManager.Add(typeof(T), SecurityType.Base, symbol, resolution, fillDataForward: false, extendedMarketHours: true); //Add this new generic data as a tradeable security: // Defaults:extended market hours" = true because we want events 24 hours, // fillforward = false because only want to trigger when there's new custom data. // leverage = 1 because no leverage on nonmarket data? Securities.Add(symbol, SecurityType.Base, resolution, fillDataForward: false, leverage: 1, extendedMarketHours: true, useQuantConnectData: false); } }
public void TestCashFills() { // this test asserts the portfolio behaves according to the Test_Cash algo, see TestData\CashTestingStrategy.csv // also "https://www.dropbox.com/s/oiliumoyqqj1ovl/2013-cash.csv?dl=1" const string fillsFile = "TestData\\test_cash_fills.xml"; const string equityFile = "TestData\\test_cash_equity.xml"; var fills = XDocument.Load(fillsFile).Descendants("OrderEvent").Select(x => new OrderEvent( x.Get <int>("OrderId"), x.Get <string>("Symbol"), x.Get <OrderStatus>("Status"), x.Get <decimal>("FillPrice"), x.Get <int>("FillQuantity")) ).ToList(); var equity = XDocument.Load(equityFile).Descendants("decimal") .Select(x => decimal.Parse(x.Value, CultureInfo.InvariantCulture)) .ToList(); Assert.AreEqual(fills.Count + 1, equity.Count); // we're going to process fills and very our equity after each fill var subscriptions = new SubscriptionManager(TimeKeeper); var securities = new SecurityManager(TimeKeeper); securities.Add("CASH", new Security(SecurityExchangeHours.AlwaysOpen, subscriptions.Add(SecurityType.Base, "CASH", Resolution.Daily, "usa", TimeZones.NewYork), leverage: 10)); var transactions = new SecurityTransactionManager(securities); var portfolio = new SecurityPortfolioManager(securities, transactions); portfolio.SetCash(equity[0]); for (int i = 0; i < fills.Count; i++) { // before processing the fill we must deduct the cost var fill = fills[i]; var time = DateTime.Today.AddDays(i); // the value of 'CASH' increments for each fill, the original test algo did this monthly // the time doesn't really matter though var updateData = new Dictionary <int, List <BaseData> >(); updateData.Add(0, new List <BaseData> { new IndicatorDataPoint("CASH", time, i + 1) }); securities.Update(time, updateData); portfolio.ProcessFill(fill); Assert.AreEqual(equity[i + 1], portfolio.TotalPortfolioValue, "Failed on " + i); } }
public void EnsureCurrencyDataFeedAddsSubscription() { const int quantity = 100; const decimal conversionRate = 1 / 100m; var cash = new Cash("JPY", quantity, conversionRate); var subscriptions = new SubscriptionManager(TimeKeeper); var abcConfig = subscriptions.Add(SecurityType.Equity, "ABC", Resolution.Minute, "fxcm", TimeZone); var securities = new SecurityManager(TimeKeeper); securities.Add("ABC", new Security(SecurityExchangeHours, abcConfig, 1m)); cash.EnsureCurrencyDataFeed(securities, subscriptions, SecurityExchangeHoursProvider.AlwaysOpen); Assert.AreEqual(1, subscriptions.Subscriptions.Count(x => x.Symbol == "USDJPY")); Assert.AreEqual(1, securities.Values.Count(x => x.Symbol == "USDJPY")); }
/// <summary> /// AddData<typeparam name="T"/> a new user defined data source, requiring only the minimum config options. /// </summary> /// <param name="symbol">Key/Symbol for data</param> /// <param name="resolution">Resolution of the Data Required</param> /// <param name="fillDataForward">When no data available on a tradebar, return the last data that was generated</param> /// <param name="leverage">Custom leverage per security</param> /// <param name="isTradeBar">Set to true if this data has Open, High, Low, and Close properties</param> /// <param name="hasVolume">Set to true if this data has a Volume property</param> /// <remarks>Generic type T must implement base data</remarks> public void AddData <T>(string symbol, Resolution resolution, bool fillDataForward, decimal leverage = 1.0m, bool isTradeBar = false, bool hasVolume = false) { if (_locked) { return; } symbol = symbol.ToUpper(); //Add this to the data-feed subscriptions var config = SubscriptionManager.Add(typeof(T), SecurityType.Base, symbol, resolution, fillDataForward, extendedMarketHours: true, isTradeBar: isTradeBar, hasVolume: hasVolume); //Add this new generic data as a tradeable security: Securities.Add(symbol, config, leverage, isDynamicallyLoadedData: true); }
public void EnsureCurrencyDataFeedAddsSubscription() { const int quantity = 100; const decimal conversionRate = 1 / 100m; var cash = new Cash("JPY", quantity, conversionRate); var subscriptions = new SubscriptionManager(TimeKeeper); var abcConfig = subscriptions.Add(Symbols.SPY, Resolution.Minute, TimeZone, TimeZone); var securities = new SecurityManager(TimeKeeper); securities.Add(Symbols.SPY, new Security(SecurityExchangeHours, abcConfig)); cash.EnsureCurrencyDataFeed(securities, subscriptions, MarketHoursDatabase.AlwaysOpen); Assert.AreEqual(1, subscriptions.Subscriptions.Count(x => x.Symbol == Symbols.USDJPY)); Assert.AreEqual(1, securities.Values.Count(x => x.Symbol == Symbols.USDJPY)); }
public void EnsureCurrencyDataFeedAddsSubscription() { const int quantity = 100; const decimal conversionRate = 1 / 100m; var cash = new Cash("JPY", quantity, conversionRate); var subscriptions = new SubscriptionManager(); var abcConfig = subscriptions.Add(SecurityType.Equity, "ABC", Resolution.Minute); var securities = new SecurityManager(); securities.Add("ABC", abcConfig); cash.EnsureCurrencyDataFeed(subscriptions, securities); Assert.AreEqual(1, subscriptions.Subscriptions.Count(x => x.Symbol == "USDJPY")); Assert.AreEqual(1, securities.Values.Count(x => x.Symbol == "USDJPY")); }
public void EnsureCurrencyDataFeedDoesNotMarkIsCurrencyDataFeedForExistantSubscriptions() { const int quantity = 100; const decimal conversionRate = 1 / 100m; var cash = new Cash("JPY", quantity, conversionRate); var subscriptions = new SubscriptionManager(); var securities = new SecurityManager(); securities.Add("USDJPY", subscriptions.Add(SecurityType.Forex, "USDJPY", Resolution.Minute)); cash.EnsureCurrencyDataFeed(subscriptions, securities); var config = subscriptions.Subscriptions.Single(x => x.Symbol == "USDJPY"); Assert.IsFalse(config.IsInternalFeed); }
public void EnsureCurrencyDataFeedMarksIsCurrencyDataFeedForNewSubscriptions() { const int quantity = 100; const decimal conversionRate = 1 / 100m; var cash = new Cash("JPY", quantity, conversionRate); var subscriptions = new SubscriptionManager(TimeKeeper); var securities = new SecurityManager(TimeKeeper); securities.Add("ABC", new Security(SecurityExchangeHours, subscriptions.Add(SecurityType.Forex, "ABC", Resolution.Minute, "fxcm", TimeZone), 1m)); cash.EnsureCurrencyDataFeed(securities, subscriptions, SecurityExchangeHoursProvider.AlwaysOpen); var config = subscriptions.Subscriptions.Single(x => x.Symbol == "USDJPY"); Assert.IsTrue(config.IsInternalFeed); }
public void EnsureCurrencyDataFeedDoesNotMarkIsCurrencyDataFeedForExistantSubscriptions() { const int quantity = 100; const decimal conversionRate = 1 / 100m; var cash = new Cash("JPY", quantity, conversionRate); var subscriptions = new SubscriptionManager(TimeKeeper); var securities = new SecurityManager(TimeKeeper); securities.Add(Symbols.USDJPY, new Security(SecurityExchangeHours, subscriptions.Add(Symbols.USDJPY, Resolution.Minute, TimeZone, TimeZone))); cash.EnsureCurrencyDataFeed(securities, subscriptions, MarketHoursDatabase.AlwaysOpen); var config = subscriptions.Subscriptions.Single(x => x.Symbol == Symbols.USDJPY); Assert.IsFalse(config.IsInternalFeed); }
public void EnsureCurrencyDataFeedAddsSubscription() { const int quantity = 100; const decimal conversionRate = 1 / 100m; var cash = new Cash("JPY", quantity, conversionRate); var cashBook = new CashBook(); cashBook.Add("JPY", cash); var subscriptions = new SubscriptionManager(AlgorithmSettings, TimeKeeper); var abcConfig = subscriptions.Add(Symbols.SPY, Resolution.Minute, TimeZone, TimeZone); var securities = new SecurityManager(TimeKeeper); securities.Add(Symbols.SPY, new Security(SecurityExchangeHours, abcConfig, new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency))); cash.EnsureCurrencyDataFeed(securities, subscriptions, AlwaysOpenMarketHoursDatabase, SymbolPropertiesDatabase.FromDataFolder(), MarketMap, cashBook); Assert.AreEqual(1, subscriptions.Subscriptions.Count(x => x.Symbol == Symbols.USDJPY)); Assert.AreEqual(1, securities.Values.Count(x => x.Symbol == Symbols.USDJPY)); }
/// <summary> /// AddData<typeparam name="T"/> a new user defined data source, requiring only the minimum config options. /// </summary> /// <param name="symbol">Key/Symbol for data</param> /// <param name="resolution">Resolution of the Data Required</param> /// <param name="timeZone">Specifies the time zone of the raw data</param> /// <param name="fillDataForward">When no data available on a tradebar, return the last data that was generated</param> /// <param name="leverage">Custom leverage per security</param> /// <remarks>Generic type T must implement base data</remarks> public void AddData <T>(Symbol symbol, Resolution resolution, DateTimeZone timeZone, bool fillDataForward = false, decimal leverage = 1.0m) where T : BaseData, new() { if (_locked) { return; } //Add this to the data-feed subscriptions var config = SubscriptionManager.Add(typeof(T), SecurityType.Base, symbol, resolution, "usa", timeZone, true, fillDataForward, true, false); var exchangeHours = _exchangeHoursProvider.GetExchangeHours(config); //Add this new generic data as a tradeable security: var security = new Security(exchangeHours, config, leverage); Securities.Add(symbol, security); }
/// <summary> /// AddData<typeparam name="T"/> a new user defined data source, requiring only the minimum config options. /// </summary> /// <param name="symbol">Key/Symbol for data</param> /// <param name="resolution">Resolution of the Data Required</param> /// <param name="fillDataForward">When no data available on a tradebar, return the last data that was generated</param> /// <param name="leverage">Custom leverage per security</param> /// <param name="isTradeBar">Set to true if this data has Open, High, Low, and Close properties</param> /// <param name="hasVolume">Set to true if this data has a Volume property</param> /// <remarks>Generic type T must implement base data</remarks> public void AddData <T>(string symbol, Resolution resolution, bool fillDataForward, decimal leverage = 1.0m, bool isTradeBar = false, bool hasVolume = false) { if (_locked) { return; } symbol = symbol.ToUpper(); //Add this to the data-feed subscriptions var config = SubscriptionManager.Add(typeof(T), SecurityType.Base, symbol, resolution, "usa", TimeZones.NewYork, fillDataForward, true, isTradeBar, hasVolume, false); var exchangeHours = _exchangeHoursProvider.GetExchangeHours(config); //Add this new generic data as a tradeable security: var security = new Security(exchangeHours, config, leverage, true); Securities.Add(symbol, security); }
public void EnsureCurrencyDataFeedDoesNotMarkIsCurrencyDataFeedForExistantSubscriptions() { const int quantity = 100; const decimal conversionRate = 1 / 100m; var cash = new Cash("JPY", quantity, conversionRate); var cashBook = new CashBook(); cashBook.Add("JPY", cash); var subscriptions = new SubscriptionManager(AlgorithmSettings, TimeKeeper, new DataManagerStub()); var securities = new SecurityManager(TimeKeeper); securities.Add(Symbols.USDJPY, new Security(SecurityExchangeHours, subscriptions.Add(Symbols.USDJPY, Resolution.Minute, TimeZone, TimeZone), new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency))); cash.EnsureCurrencyDataFeed(securities, subscriptions, AlwaysOpenMarketHoursDatabase, SymbolPropertiesDatabase.FromDataFolder(), MarketMap, cashBook, SecurityChanges.None); var config = subscriptions.Subscriptions.Single(x => x.Symbol == Symbols.USDJPY); Assert.IsFalse(config.IsInternalFeed); }
public void EnsureCurrencyDataFeedMarksIsCurrencyDataFeedForNewSubscriptions() { const int quantity = 100; const decimal conversionRate = 1 / 100m; var cash = new Cash("JPY", quantity, conversionRate); var cashBook = new CashBook(); cashBook.Add("JPY", cash); var subscriptions = new SubscriptionManager(TimeKeeper); var securities = new SecurityManager(TimeKeeper); securities.Add(Symbols.EURUSD, new Security(SecurityExchangeHours, subscriptions.Add(Symbols.EURUSD, Resolution.Minute, TimeZone, TimeZone), new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency))); cash.EnsureCurrencyDataFeed(securities, subscriptions, MarketHoursDatabase.AlwaysOpen, SymbolPropertiesDatabase.FromDataFolder(), MarketMap, cashBook); var config = subscriptions.Subscriptions.Single(x => x.Symbol == Symbols.USDJPY); Assert.IsTrue(config.IsInternalFeed); }
public void EnsureInternalCurrencyDataFeedsForNonUsdQuoteCurrencyGetAdded() { const int quantity = 100; const decimal conversionRate = 1 / 100m; var cashJPY = new Cash("JPY", quantity, conversionRate); var cashGBP = new Cash("GBP", quantity, conversionRate); var cashBook = new CashBook(); cashBook.Add("JPY", cashJPY); cashBook.Add("GBP", cashGBP); var symbol = Symbol.Create("GBPJPY", SecurityType.Forex, Market.FXCM); var subscriptions = new SubscriptionManager(); var dataManager = new DataManagerStub(TimeKeeper); subscriptions.SetDataManager(dataManager); var securities = new SecurityManager(TimeKeeper); securities.Add( symbol, new Security( SecurityExchangeHours, subscriptions.Add(symbol, Resolution.Minute, TimeZone, TimeZone), new Cash(cashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(cashBook.AccountCurrency), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ) ); cashJPY.EnsureCurrencyDataFeed(securities, subscriptions, MarketMap, SecurityChanges.None, dataManager.SecurityService, cashBook.AccountCurrency); var config1 = subscriptions.Subscriptions.Single(x => x.Symbol == Symbols.USDJPY); Assert.IsTrue(config1.IsInternalFeed); cashGBP.EnsureCurrencyDataFeed(securities, subscriptions, MarketMap, SecurityChanges.None, dataManager.SecurityService, cashBook.AccountCurrency); var config2 = subscriptions.Subscriptions.Single(x => x.Symbol == Symbols.GBPUSD); Assert.IsTrue(config2.IsInternalFeed); }
public void UpdateModifiesConversionRate() { const int quantity = 100; const decimal conversionRate = 1 / 100m; var cash = new Cash("GBP", quantity, conversionRate); var subscriptions = new SubscriptionManager(TimeKeeper); var securities = new SecurityManager(TimeKeeper); securities.Add(Symbols.GBPUSD, new Security(SecurityExchangeHours, subscriptions.Add(Symbols.GBPUSD, Resolution.Minute, TimeZone, TimeZone))); // we need to get subscription index cash.EnsureCurrencyDataFeed(securities, subscriptions, MarketHoursDatabase.AlwaysOpen); var last = 1.5m; cash.Update(new Tick(DateTime.Now, Symbols.GBPUSD, last, last * 1.009m, last * 0.009m)); // jpy is inverted, so compare on the inverse Assert.AreEqual(last, cash.ConversionRate); }