public void MarketOrderFillsAtBidAsk(OrderDirection direction) { var symbol = Symbol.Create("EURUSD", SecurityType.Forex, "fxcm"); var exchangeHours = SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork); var quoteCash = new Cash("USD", 1000, 1); var symbolProperties = SymbolProperties.GetDefault("USD"); var security = new Forex(symbol, exchangeHours, quoteCash, symbolProperties); var reference = DateTime.Now; var referenceUtc = reference.ConvertToUtc(TimeZones.NewYork); var timeKeeper = new TimeKeeper(referenceUtc); security.SetLocalTimeKeeper(timeKeeper.GetLocalTimeKeeper(TimeZones.NewYork)); var brokerageModel = new FxcmBrokerageModel(); var fillModel = brokerageModel.GetFillModel(security); const decimal bidPrice = 1.13739m; const decimal askPrice = 1.13746m; security.SetMarketPrice(new Tick(DateTime.Now, symbol, bidPrice, askPrice)); var quantity = direction == OrderDirection.Buy ? 1 : -1; var order = new MarketOrder(symbol, quantity, DateTime.Now); var fill = fillModel.MarketFill(security, order); var expected = direction == OrderDirection.Buy ? askPrice : bidPrice; Assert.AreEqual(expected, fill.FillPrice); }
public void ComputesValueInBaseCurrency() { const int quantity = 100; const decimal conversionRate = 1/100m; var cash = new Cash("JPY", quantity, conversionRate); Assert.AreEqual(quantity*conversionRate, cash.ValueInAccountCurrency); }
public void ConstructorSetsProperties() { const string symbol = "JPY"; const int quantity = 1; const decimal conversionRate = 1.2m; var cash = new Cash(symbol, quantity, conversionRate); Assert.AreEqual(symbol, cash.Symbol); Assert.AreEqual(quantity, cash.Amount); Assert.AreEqual(conversionRate, cash.ConversionRate); }
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, 1m)); 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", new Security(abcConfig, 1m)); cash.EnsureCurrencyDataFeed(securities, subscriptions); Assert.AreEqual(1, subscriptions.Subscriptions.Count(x => x.Symbol == "USDJPY")); Assert.AreEqual(1, securities.Values.Count(x => x.Symbol == "USDJPY")); }
public void UpdateModifiesConversionRateAsInvertedValue() { 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), 1m)); // we need to get subscription index cash.EnsureCurrencyDataFeed(securities, subscriptions, SecurityExchangeHoursProvider.AlwaysOpen); var last = 120m; cash.Update(new Tick(DateTime.Now, Symbols.USDJPY, last, 119.95m, 120.05m)); // jpy is inverted, so compare on the inverse Assert.AreEqual(1 / last, cash.ConversionRate); }
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(Symbols.SPY, new Security(SecurityExchangeHours, subscriptions.Add(Symbols.SPY, Resolution.Minute, TimeZone), 1m)); securities.Add(Symbols.EURUSD, new Security(SecurityExchangeHours, subscriptions.Add(Symbols.EURUSD, minimumResolution, TimeZone), 1m)); cash.EnsureCurrencyDataFeed(securities, subscriptions, SecurityExchangeHoursProvider.AlwaysOpen); Assert.AreEqual(minimumResolution, subscriptions.Subscriptions.Single(x => x.Symbol == Symbols.USDJPY).Resolution); }
/// <summary> /// Temporary convenience constructor /// </summary> protected Security(SubscriptionDataConfig config, Cash quoteCurrency, SymbolProperties symbolProperties, SecurityExchange exchange, SecurityCache cache, ISecurityPortfolioModel portfolioModel, IFillModel fillModel, IFeeModel feeModel, ISlippageModel slippageModel, ISettlementModel settlementModel, IVolatilityModel volatilityModel, ISecurityMarginModel marginModel, ISecurityDataFilter dataFilter ) : this(config.Symbol, quoteCurrency, symbolProperties, exchange, cache, portfolioModel, fillModel, feeModel, slippageModel, settlementModel, volatilityModel, marginModel, dataFilter ) { SubscriptionsBag.Add(config); }
public void ConstructorThrowsOnSymbolTooShort() { var cash = new Cash("s", 0, 0); }
public void ConstructorCapitalizedSymbol() { var cash = new Cash("low", 0, 0); Assert.AreEqual("LOW", cash.Symbol); }
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); 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, MarketHoursDatabase.AlwaysOpen, SymbolPropertiesDatabase.FromDataFolder(), MarketMap, cashBook); var config1 = subscriptions.Subscriptions.Single(x => x.Symbol == Symbols.USDJPY); Assert.IsTrue(config1.IsInternalFeed); cashGBP.EnsureCurrencyDataFeed(securities, subscriptions, MarketHoursDatabase.AlwaysOpen, SymbolPropertiesDatabase.FromDataFolder(), MarketMap, cashBook); 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 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 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(); var securities = new SecurityManager(); securities.Add("ABC", new Security(subscriptions.Add(SecurityType.Equity, "ABC", Resolution.Minute), 1m)); securities.Add("BCD", new Security(subscriptions.Add(SecurityType.Equity, "BCD", minimumResolution), 1m)); cash.EnsureCurrencyDataFeed(securities, subscriptions); Assert.AreEqual(minimumResolution, subscriptions.Subscriptions.Single(x => x.Symbol == "USDJPY").Resolution); }
public void EnsureCurrencyDataFeedMarksIsCurrencyDataFeedForNewSubscriptions() { 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("ABC", new Security(subscriptions.Add(SecurityType.Forex, "ABC", Resolution.Minute), 1m)); cash.EnsureCurrencyDataFeed(securities, subscriptions); var config = subscriptions.Subscriptions.Single(x => x.Symbol == "USDJPY"); Assert.IsTrue(config.IsInternalFeed); }
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", TimeZones.NewYork); var securities = new SecurityManager(TimeKeeper); securities.Add("ABC", new Security(SecurityExchangeHours.AlwaysOpen, 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")); }
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, subscriptions.Add(SecurityType.Forex, "GBPUSD", Resolution.Minute, "fxcm", TimeZone), 1m)); // we need to get subscription index cash.EnsureCurrencyDataFeed(securities, subscriptions, SecurityExchangeHoursProvider.AlwaysOpen); var last = 1.5m; cash.Update(new Tick(DateTime.Now, "GBPUSD", last, last * 1.009m, last * 0.009m)); // jpy is inverted, so compare on the inverse Assert.AreEqual(last, cash.ConversionRate); }
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("USDJPY", new Security(SecurityExchangeHours, subscriptions.Add(SecurityType.Forex, "USDJPY", Resolution.Minute, "fxcm", TimeZone), 1m)); cash.EnsureCurrencyDataFeed(securities, subscriptions, SecurityExchangeHoursProvider.AlwaysOpen); var config = subscriptions.Subscriptions.Single(x => x.Symbol == "USDJPY"); Assert.IsFalse(config.IsInternalFeed); }
/// <summary> /// Construct a new security vehicle based on the user options. /// </summary> public Security(SecurityExchangeHours exchangeHours, SubscriptionDataConfig config, Cash quoteCurrency, SymbolProperties symbolProperties) : this(config, quoteCurrency, symbolProperties, new SecurityExchange(exchangeHours), new SecurityCache(), new SecurityPortfolioModel(), new ImmediateFillModel(), new InteractiveBrokersFeeModel(), new SpreadSlippageModel(), new ImmediateSettlementModel(), Securities.VolatilityModel.Null, new SecurityMarginModel(1m), new SecurityDataFilter(), new SecurityPriceVariationModel()) { }
/// <summary> /// Construct a new security vehicle based on the user options. /// </summary> public Security(SecurityExchangeHours exchangeHours, SubscriptionDataConfig config, Cash quoteCurrency, SymbolProperties symbolProperties) : this(config, quoteCurrency, symbolProperties, new SecurityExchange(exchangeHours), new SecurityCache(), new SecurityPortfolioModel(), new ImmediateFillModel(), new InteractiveBrokersFeeModel(), new SpreadSlippageModel(), new ImmediateSettlementModel(), new SecurityMarginModel(1m), new SecurityDataFilter()) { }
/// <summary> /// Construct a new security vehicle based on the user options. /// </summary> protected Security(SubscriptionDataConfig config, Cash quoteCurrency, SymbolProperties symbolProperties, SecurityExchange exchange, SecurityCache cache, ISecurityPortfolioModel portfolioModel, IFillModel fillModel, IFeeModel feeModel, ISlippageModel slippageModel, ISettlementModel settlementModel, ISecurityMarginModel marginModel, ISecurityDataFilter dataFilter ) { if (symbolProperties == null) { throw new ArgumentNullException("symbolProperties", "Security requires a valid SymbolProperties instance."); } if (symbolProperties.QuoteCurrency != quoteCurrency.Symbol) { throw new ArgumentException("symbolProperties.QuoteCurrency must match the quoteCurrency.Symbol"); } _config = config; QuoteCurrency = quoteCurrency; SymbolProperties = symbolProperties; Cache = cache; Exchange = exchange; DataFilter = dataFilter; PortfolioModel = portfolioModel; MarginModel = marginModel; FillModel = fillModel; FeeModel = feeModel; SlippageModel = slippageModel; SettlementModel = settlementModel; Holdings = new SecurityHolding(this); }
public void UpdateModifiesConversionRateAsInvertedValue() { 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", new Security(subscriptions.Add(SecurityType.Forex, "USDJPY", Resolution.Minute), 1m)); // we need to get subscription index cash.EnsureCurrencyDataFeed(securities, subscriptions); var last = 120m; var data = new Dictionary<int, List<BaseData>>(); data.Add(0, new List<BaseData> { new Tick(DateTime.Now, "USDJPY", last, 119.95m, 120.05m) }); cash.Update(data); // jpy is inverted, so compare on the inverse Assert.AreEqual(1 / last, cash.ConversionRate); }
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(TimeKeeper); 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, MarketHoursDatabase.AlwaysOpen, SymbolPropertiesDatabase.FromDataFolder(), MarketMap, cashBook); var config = subscriptions.Subscriptions.Single(x => x.Symbol == Symbols.USDJPY); Assert.IsFalse(config.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 UpdateModifiesConversionRate() { const int quantity = 100; const decimal conversionRate = 1 / 100m; var cash = new Cash("GBP", quantity, conversionRate); var cashBook = new CashBook(); cashBook.Add("GBP", cash); 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), new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency))); // we need to get subscription index cash.EnsureCurrencyDataFeed(securities, subscriptions, MarketHoursDatabase.AlwaysOpen, SymbolPropertiesDatabase.FromDataFolder(), MarketMap, cashBook); 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); }
/// <summary> /// Construct a new security vehicle based on the user options. /// </summary> protected Security(Symbol symbol, Cash quoteCurrency, SymbolProperties symbolProperties, SecurityExchange exchange, SecurityCache cache, ISecurityPortfolioModel portfolioModel, IFillModel fillModel, IFeeModel feeModel, ISlippageModel slippageModel, ISettlementModel settlementModel, IVolatilityModel volatilityModel, ISecurityMarginModel marginModel, ISecurityDataFilter dataFilter, IPriceVariationModel priceVariationModel ) { if (symbolProperties == null) { throw new ArgumentNullException("symbolProperties", "Security requires a valid SymbolProperties instance."); } if (symbolProperties.QuoteCurrency != quoteCurrency.Symbol) { throw new ArgumentException("symbolProperties.QuoteCurrency must match the quoteCurrency.Symbol"); } _symbol = symbol; SubscriptionsBag = new ConcurrentBag<SubscriptionDataConfig>(); QuoteCurrency = quoteCurrency; SymbolProperties = symbolProperties; IsTradable = true; Cache = cache; Exchange = exchange; DataFilter = dataFilter; PriceVariationModel = priceVariationModel; PortfolioModel = portfolioModel; MarginModel = marginModel; FillModel = fillModel; FeeModel = feeModel; SlippageModel = slippageModel; SettlementModel = settlementModel; VolatilityModel = volatilityModel; Holdings = new SecurityHolding(this); }
public void ConstructorThrowsOnSymbolTooLong() { var cash = new Cash("too long", 0, 0); }
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(Symbols.EURUSD, new Security(SecurityExchangeHours, subscriptions.Add(Symbols.EURUSD, Resolution.Minute, TimeZone), 1m)); cash.EnsureCurrencyDataFeed(securities, subscriptions, SecurityExchangeHoursProvider.AlwaysOpen); var config = subscriptions.Subscriptions.Single(x => x.Symbol == Symbols.USDJPY); Assert.IsTrue(config.IsInternalFeed); }
public void EnsureCurrencyDataFeedAddsSubscriptionThrowsWhenZeroSubscriptionsPresent() { const int quantity = 100; const decimal conversionRate = 1 / 100m; var cash = new Cash("JPY", quantity, conversionRate); var securities = new SecurityManager(); var subscriptions = new SubscriptionManager(); cash.EnsureCurrencyDataFeed(securities, subscriptions); }
/// <summary> /// Construct a new security vehicle based on the user options. /// </summary> public Security(Symbol symbol, SecurityExchangeHours exchangeHours, Cash quoteCurrency, SymbolProperties symbolProperties) : this(symbol, quoteCurrency, symbolProperties, new SecurityExchange(exchangeHours), new SecurityCache(), new SecurityPortfolioModel(), new ImmediateFillModel(), new InteractiveBrokersFeeModel(), new SpreadSlippageModel(), new ImmediateSettlementModel(), Securities.VolatilityModel.Null, new SecurityMarginModel(1m), new SecurityDataFilter() ) { }
public void EnsureCurrencyDataFeedAddsSubscriptionThrowsWhenZeroSubscriptionsPresent() { 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 securities = new SecurityManager(TimeKeeper); var subscriptions = new SubscriptionManager(TimeKeeper); cash.EnsureCurrencyDataFeed(securities, subscriptions, MarketHoursDatabase.AlwaysOpen, SymbolPropertiesDatabase.FromDataFolder(), MarketMap, cashBook); }
public void EnsureCurrencyDataFeedAddsSubscriptionThrowsWhenZeroSubscriptionsPresent() { const int quantity = 100; const decimal conversionRate = 1 / 100m; var cash = new Cash("JPY", quantity, conversionRate); var securities = new SecurityManager(TimeKeeper); var subscriptions = new SubscriptionManager(TimeKeeper); cash.EnsureCurrencyDataFeed(securities, subscriptions, SecurityExchangeHoursProvider.AlwaysOpen); }