public void GtcTimeInForceOrderDoesNotExpire() { var security = new Equity( SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), new SubscriptionDataConfig( typeof(TradeBar), Symbols.SPY, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, true, true, true ), new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null ); var timeInForce = new GoodTilCanceledTimeInForce(); var order = new LimitOrder(Symbols.SPY, 10, 100, DateTime.UtcNow); Assert.IsFalse(timeInForce.IsOrderExpired(security, order)); var fill1 = new OrderEvent(order.Id, order.Symbol, DateTime.UtcNow, OrderStatus.PartiallyFilled, OrderDirection.Buy, order.LimitPrice, 3, OrderFee.Zero); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill1)); var fill2 = new OrderEvent(order.Id, order.Symbol, DateTime.UtcNow, OrderStatus.Filled, OrderDirection.Buy, order.LimitPrice, 7, OrderFee.Zero); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill2)); }
public void ImmediateFillModelDoesNotUseTicksWhenThereIsNoTickSubscription() { var noon = new DateTime(2014, 6, 24, 12, 0, 0); var timeKeeper = new TimeKeeper(noon.ConvertToUtc(TimeZones.NewYork), new[] { TimeZones.NewYork }); var symbol = Symbol.Create("SPY", SecurityType.Equity, Market.USA); // Minute subscription var config = new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, true, true, false); var security = new Security( SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency), ErrorCurrencyConverter.Instance ); security.SetLocalTimeKeeper(timeKeeper.GetLocalTimeKeeper(TimeZones.NewYork)); security.SetMarketPrice(new IndicatorDataPoint(Symbols.SPY, noon, 101.123m)); // This is the case when a tick is seeded with minute data in an algorithm security.Cache.AddData(new TradeBar(DateTime.MinValue, symbol, 1.0m, 1.0m, 1.0m, 1.0m, 1.0m)); security.Cache.AddData(new Tick(config, "42525000,1000000,100,A,@,0", DateTime.MinValue)); var fillModel = new ImmediateFillModel(); var order = new MarketOrder(symbol, 1000, DateTime.Now); var fill = fillModel.MarketFill(security, order); // The fill model should use the tick.Price Assert.AreEqual(fill.FillPrice, 1.0m); Assert.AreEqual(0, fill.OrderFee); }
public void PerformsLimitFillBuy() { var model = new ImmediateFillModel(); var order = new LimitOrder(Symbols.SPY, 100, 101.5m, Noon); var config = CreateTradeBarConfig(Symbols.SPY); var security = new Security( SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency), ErrorCurrencyConverter.Instance ); security.SetLocalTimeKeeper(TimeKeeper.GetLocalTimeKeeper(TimeZones.NewYork)); security.SetMarketPrice(new IndicatorDataPoint(Symbols.SPY, Noon, 102m)); var fill = model.LimitFill(security, order); Assert.AreEqual(0, fill.FillQuantity); Assert.AreEqual(0, fill.FillPrice); Assert.AreEqual(OrderStatus.None, fill.Status); security.SetMarketPrice(new TradeBar(Noon, Symbols.SPY, 102m, 103m, 101m, 102.3m, 100)); fill = model.LimitFill(security, order); // this fills worst case scenario, so it's at the limit price Assert.AreEqual(order.Quantity, fill.FillQuantity); Assert.AreEqual(Math.Min(order.LimitPrice, security.High), fill.FillPrice); Assert.AreEqual(OrderStatus.Filled, fill.Status); }
public void PerformsLimitFillSell() { var model = new EquityTransactionModel(); var order = new LimitOrder(Symbols.SPY, -100, 101.5m, Noon, type: SecurityType.Equity); var config = CreateTradeBarConfig(); var security = new Security(SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, 1); security.SetLocalTimeKeeper(TimeKeeper.GetLocalTimeKeeper(TimeZones.NewYork)); security.SetMarketPrice(new IndicatorDataPoint(Symbols.SPY, Noon, 101m)); var fill = model.LimitFill(security, order); Assert.AreEqual(0, fill.FillQuantity); Assert.AreEqual(0, fill.FillPrice); Assert.AreEqual(OrderStatus.None, fill.Status); security.SetMarketPrice(new TradeBar(Noon, Symbols.SPY, 102m, 103m, 101m, 102.3m, 100)); fill = model.LimitFill(security, order); // this fills worst case scenario, so it's at the limit price Assert.AreEqual(order.Quantity, fill.FillQuantity); Assert.AreEqual(Math.Max(order.LimitPrice, security.Low), fill.FillPrice); Assert.AreEqual(OrderStatus.Filled, fill.Status); }
public void PerformsMarketFillSell() { var model = new ImmediateFillModel(); var order = new MarketOrder(Symbols.SPY, -100, Noon); var config = CreateTradeBarConfig(Symbols.SPY); var security = new Security( SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency), ErrorCurrencyConverter.Instance ); security.SetLocalTimeKeeper(TimeKeeper.GetLocalTimeKeeper(TimeZones.NewYork)); security.SetMarketPrice(new IndicatorDataPoint(Symbols.SPY, Noon, 101.123m)); var fill = model.Fill(new FillModelParameters( security, order, new MockSubscriptionDataConfigProvider(config))).OrderEvent; Assert.AreEqual(order.Quantity, fill.FillQuantity); Assert.AreEqual(security.Price, fill.FillPrice); Assert.AreEqual(OrderStatus.Filled, fill.Status); }
public void MarketOrderFillWithStalePriceHasWarningMessage() { var model = new ImmediateFillModel(); var order = new MarketOrder(Symbols.SPY, -100, Noon.ConvertToUtc(TimeZones.NewYork).AddMinutes(61)); var config = CreateTradeBarConfig(Symbols.SPY); var security = new Security( SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ); security.SetLocalTimeKeeper(TimeKeeper.GetLocalTimeKeeper(TimeZones.NewYork)); security.SetMarketPrice(new IndicatorDataPoint(Symbols.SPY, Noon, 101.123m)); var fill = model.Fill(new FillModelParameters( security, order, new MockSubscriptionDataConfigProvider(config), Time.OneHour)).OrderEvent; Assert.IsTrue(fill.Message.Contains("Warning: fill at stale price")); }
public void PerformsStopMarketFillSell() { var model = new EquityTransactionModel(); var order = new StopMarketOrder(Symbol, -100, 101.5m, Noon, type: SecurityType.Equity); var config = CreateTradeBarConfig(Symbol); var security = new Security(SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, 1); security.SetLocalTimeKeeper(TimeKeeper.GetLocalTimeKeeper(TimeZones.NewYork)); security.SetMarketPrice(new IndicatorDataPoint(Symbol, Noon, 102m)); var fill = model.StopMarketFill(security, order); Assert.AreEqual(0, fill.FillQuantity); Assert.AreEqual(0, fill.FillPrice); Assert.AreEqual(OrderStatus.None, fill.Status); Assert.AreEqual(OrderStatus.None, order.Status); security.SetMarketPrice(new IndicatorDataPoint(Symbol, Noon, 101m)); fill = model.StopMarketFill(security, order); // this fills worst case scenario, so it's min of asset/stop price Assert.AreEqual(order.Quantity, fill.FillQuantity); Assert.AreEqual(Math.Min(security.Price, order.StopPrice), fill.FillPrice); Assert.AreEqual(OrderStatus.Filled, fill.Status); Assert.AreEqual(OrderStatus.Filled, order.Status); }
public void PerformsStopMarketFillBuy() { var model = new EquityTransactionModel(); var order = new StopMarketOrder(Symbols.SPY, 100, 101.5m, Noon); var config = CreateTradeBarConfig(); var security = new Security(SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency)); security.SetLocalTimeKeeper(TimeKeeper.GetLocalTimeKeeper(TimeZones.NewYork)); security.SetMarketPrice(new IndicatorDataPoint(Symbols.SPY, Noon, 101m)); var fill = model.StopMarketFill(security, order); Assert.AreEqual(0, fill.FillQuantity); Assert.AreEqual(0, fill.FillPrice); Assert.AreEqual(OrderStatus.None, fill.Status); security.SetMarketPrice(new IndicatorDataPoint(Symbols.SPY, Noon, 102.5m)); fill = model.StopMarketFill(security, order); // this fills worst case scenario, so it's min of asset/stop price Assert.AreEqual(order.Quantity, fill.FillQuantity); Assert.AreEqual(Math.Max(security.Price, order.StopPrice), fill.FillPrice); Assert.AreEqual(OrderStatus.Filled, fill.Status); }
public void GetStartTimeForEquityTradeBars(DateTime end, DateTime expectedStart, DateTimeZone dataTimeZone) { var barSize = TimeSpan.FromMinutes(1); var hours = SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(); var start = Time.GetStartTimeForTradeBars(hours, end, barSize, 10, false, dataTimeZone); Assert.AreEqual(expectedStart, start); }
public void GtdSameDayTimeInForceForexOrderAfter5PMExpiresAt5PMNextDay() { // set time to 6:00:00 PM (NY time) var utcTime = new DateTime(2018, 4, 27, 18, 0, 0).ConvertToUtc(TimeZones.NewYork); var security = new Forex( SecurityExchangeHoursTests.CreateForexSecurityExchangeHours(), new Cash(Currencies.USD, 0, 1m), new SubscriptionDataConfig( typeof(QuoteBar), Symbols.EURUSD, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, true, true, true ), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null ); var localTimeKeeper = new LocalTimeKeeper(utcTime, TimeZones.NewYork); security.SetLocalTimeKeeper(localTimeKeeper); var timeInForce = TimeInForce.GoodTilDate(new DateTime(2018, 4, 27)); var orderProperties = new OrderProperties { TimeInForce = timeInForce }; var order = new LimitOrder(Symbols.EURUSD, 10, 100, utcTime, "", orderProperties); Assert.IsFalse(timeInForce.IsOrderExpired(security, order)); var fill1 = new OrderEvent(order.Id, order.Symbol, utcTime, OrderStatus.PartiallyFilled, OrderDirection.Buy, order.LimitPrice, 3, OrderFee.Zero); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill1)); var fill2 = new OrderEvent(order.Id, order.Symbol, utcTime, OrderStatus.Filled, OrderDirection.Buy, order.LimitPrice, 7, OrderFee.Zero); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill2)); // set time to midnight (NY time) localTimeKeeper.UpdateTime(utcTime.AddHours(6)); Assert.IsFalse(timeInForce.IsOrderExpired(security, order)); // set time to 4:59:59 PM next day (NY time) localTimeKeeper.UpdateTime(utcTime.AddHours(23).AddSeconds(-1)); Assert.IsFalse(timeInForce.IsOrderExpired(security, order)); // set time to 5:00:00 PM next day (NY time) localTimeKeeper.UpdateTime(utcTime.AddHours(23)); Assert.IsTrue(timeInForce.IsOrderExpired(security, order)); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill1)); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill2)); }
public void StopLimitOrderDoesNotFillUsingDataBeforeSubmitTime(decimal orderQuantity, decimal stopPrice, decimal limitPrice) { var time = new DateTime(2018, 9, 24, 9, 30, 0); var timeKeeper = new TimeKeeper(time.ConvertToUtc(TimeZones.NewYork), TimeZones.NewYork); var symbol = Symbol.Create("SPY", SecurityType.Equity, Market.USA); var config = new SubscriptionDataConfig(typeof(TradeBar), symbol, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, true, true, false); var security = new Security( SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ); security.SetLocalTimeKeeper(timeKeeper.GetLocalTimeKeeper(TimeZones.NewYork)); var tradeBar = new TradeBar(time, symbol, 290m, 292m, 289m, 291m, 12345); security.SetMarketPrice(tradeBar); time += TimeSpan.FromMinutes(1); timeKeeper.SetUtcDateTime(time.ConvertToUtc(TimeZones.NewYork)); var fillForwardBar = (TradeBar)tradeBar.Clone(true); security.SetMarketPrice(fillForwardBar); var fillModel = new ImmediateFillModel(); var order = new StopLimitOrder(symbol, orderQuantity, stopPrice, limitPrice, time.ConvertToUtc(TimeZones.NewYork)); var fill = fillModel.Fill(new FillModelParameters( security, order, new MockSubscriptionDataConfigProvider(config), Time.OneHour)).OrderEvent; Assert.AreEqual(0, fill.FillQuantity); Assert.AreEqual(0, fill.FillPrice); Assert.AreEqual(OrderStatus.None, fill.Status); time += TimeSpan.FromMinutes(1); timeKeeper.SetUtcDateTime(time.ConvertToUtc(TimeZones.NewYork)); tradeBar = new TradeBar(time, symbol, 290m, 292m, 289m, 291m, 12345); security.SetMarketPrice(tradeBar); fill = fillModel.StopLimitFill(security, order); Assert.AreEqual(orderQuantity, fill.FillQuantity); Assert.AreEqual(limitPrice, fill.FillPrice); Assert.AreEqual(OrderStatus.Filled, fill.Status); Assert.AreEqual(0, fill.OrderFee.Value.Amount); }
public void GetStartTimeForTradeBarsHandlesOverNight() { // 2015.09.01 @ noon var end = new DateTime(2015, 09, 01, 12, 0, 0); var barSize = TimeSpan.FromHours(1); var hours = SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(); var start = Time.GetStartTimeForTradeBars(hours, end, barSize, 7, false); // from noon, back up to 9am (3 hours) then skip night, so from 4pm, back up to noon, 4 more hours Assert.AreEqual(end.AddDays(-1), start); }
public void GtdTimeInForceForexOrderBeforeExpiresAt5PMOnExpiryDate() { // set time to 10:00:00 AM (NY time) var utcTime = new DateTime(2018, 4, 27, 10, 0, 0).ConvertToUtc(TimeZones.NewYork); var security = new Forex( SecurityExchangeHoursTests.CreateForexSecurityExchangeHours(), new Cash(CashBook.AccountCurrency, 0, 1m), new SubscriptionDataConfig(typeof(QuoteBar), Symbols.EURUSD, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, true, true, true), SymbolProperties.GetDefault(CashBook.AccountCurrency)); var localTimeKeeper = new LocalTimeKeeper(utcTime, TimeZones.NewYork); security.SetLocalTimeKeeper(localTimeKeeper); var timeInForce = TimeInForce.GoodTilDate(new DateTime(2018, 5, 1)); var orderProperties = new OrderProperties { TimeInForce = timeInForce }; var order = new LimitOrder(Symbols.EURUSD, 10, 100, utcTime, "", orderProperties); Assert.IsFalse(timeInForce.IsOrderExpired(security, order)); var fill1 = new OrderEvent(order.Id, order.Symbol, utcTime, OrderStatus.PartiallyFilled, OrderDirection.Buy, order.LimitPrice, 3, 0); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill1)); var fill2 = new OrderEvent(order.Id, order.Symbol, utcTime, OrderStatus.Filled, OrderDirection.Buy, order.LimitPrice, 7, 0); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill2)); // April 27th 4:59:59 PM (NY time) localTimeKeeper.UpdateTime(utcTime.AddHours(7).AddSeconds(-1)); Assert.IsFalse(timeInForce.IsOrderExpired(security, order)); // April 27th 5:00:00 PM (NY time) localTimeKeeper.UpdateTime(utcTime.AddHours(7)); Assert.IsFalse(timeInForce.IsOrderExpired(security, order)); // May 1st at 10 AM localTimeKeeper.UpdateTime(utcTime.AddDays(4)); Assert.IsFalse(timeInForce.IsOrderExpired(security, order)); // May 1st 4:59:59 PM (NY time) localTimeKeeper.UpdateTime(utcTime.AddDays(4).AddHours(7).AddSeconds(-1)); Assert.IsFalse(timeInForce.IsOrderExpired(security, order)); // May 1st 5:00:00 PM (NY time) localTimeKeeper.UpdateTime(utcTime.AddDays(4).AddHours(7)); Assert.IsTrue(timeInForce.IsOrderExpired(security, order)); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill1)); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill2)); }
public void GtdTimeInForceEquityOrderExpiresAtMarketCloseOnExpiryDate() { var utcTime = new DateTime(2018, 4, 27, 10, 0, 0).ConvertToUtc(TimeZones.NewYork); var security = new Equity( SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, true, true, true), new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency)); var localTimeKeeper = new LocalTimeKeeper(utcTime, TimeZones.NewYork); security.SetLocalTimeKeeper(localTimeKeeper); var timeInForce = TimeInForce.GoodTilDate(new DateTime(2018, 5, 1)); var orderProperties = new OrderProperties { TimeInForce = timeInForce }; var order = new LimitOrder(Symbols.SPY, 10, 100, utcTime, "", orderProperties); Assert.IsFalse(timeInForce.IsOrderExpired(security, order)); var fill1 = new OrderEvent(order.Id, order.Symbol, utcTime, OrderStatus.PartiallyFilled, OrderDirection.Buy, order.LimitPrice, 3, 0); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill1)); var fill2 = new OrderEvent(order.Id, order.Symbol, utcTime, OrderStatus.Filled, OrderDirection.Buy, order.LimitPrice, 7, 0); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill2)); // April 27th before market close localTimeKeeper.UpdateTime(utcTime.AddHours(6).AddSeconds(-1)); Assert.IsFalse(timeInForce.IsOrderExpired(security, order)); // April 27th at market close localTimeKeeper.UpdateTime(utcTime.AddHours(6)); Assert.IsFalse(timeInForce.IsOrderExpired(security, order)); // May 1st at 10 AM localTimeKeeper.UpdateTime(utcTime.AddDays(4)); Assert.IsFalse(timeInForce.IsOrderExpired(security, order)); // May 1st before market close localTimeKeeper.UpdateTime(utcTime.AddDays(4).AddHours(6).AddSeconds(-1)); Assert.IsFalse(timeInForce.IsOrderExpired(security, order)); // May 1st at market close localTimeKeeper.UpdateTime(utcTime.AddDays(4).AddHours(6)); Assert.IsTrue(timeInForce.IsOrderExpired(security, order)); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill1)); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill2)); }
public void PerformsMarketOnCloseUsingClosingPrice() { var reference = new DateTime(2015, 06, 05, 15, 0, 0); // before market close var model = new ImmediateFillModel(); var order = new MarketOnCloseOrder(Symbols.SPY, 100, reference); var config = CreateTradeBarConfig(Symbols.SPY); var security = new Security( SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ); security.SetLocalTimeKeeper(TimeKeeper.GetLocalTimeKeeper(TimeZones.NewYork)); var time = reference; TimeKeeper.SetUtcDateTime(time.ConvertToUtc(TimeZones.NewYork)); security.SetMarketPrice(new TradeBar(time - config.Increment, Symbols.SPY, 1m, 2m, 0.5m, 1.33m, 100, config.Increment)); var fill = model.Fill(new FillModelParameters( security, order, new MockSubscriptionDataConfigProvider(config), Time.OneHour)).OrderEvent; Assert.AreEqual(0, fill.FillQuantity); // market closes after 60min, so this is just before market Close time = reference.AddMinutes(59); TimeKeeper.SetUtcDateTime(time.ConvertToUtc(TimeZones.NewYork)); security.SetMarketPrice(new TradeBar(time - config.Increment, Symbols.SPY, 1.33m, 2.75m, 1.15m, 1.45m, 100, config.Increment)); fill = model.Fill(new FillModelParameters( security, order, new MockSubscriptionDataConfigProvider(config), Time.OneHour)).OrderEvent; Assert.AreEqual(0, fill.FillQuantity); // market closes time = reference.AddMinutes(60); TimeKeeper.SetUtcDateTime(time.ConvertToUtc(TimeZones.NewYork)); security.SetMarketPrice(new TradeBar(time - config.Increment, Symbols.SPY, 1.45m, 2.0m, 1.1m, 1.40m, 100, config.Increment)); fill = model.MarketOnCloseFill(security, order); Assert.AreEqual(order.Quantity, fill.FillQuantity); Assert.AreEqual(security.Close, fill.FillPrice); }
public void DayTimeInForceEquityOrderExpiresAtMarketClose() { var utcTime = new DateTime(2018, 4, 27, 10, 0, 0).ConvertToUtc(TimeZones.NewYork); var security = new Equity( SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), new SubscriptionDataConfig( typeof(TradeBar), Symbols.SPY, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, true, true, true ), new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null ); var localTimeKeeper = new LocalTimeKeeper(utcTime, TimeZones.NewYork); security.SetLocalTimeKeeper(localTimeKeeper); var timeInForce = TimeInForce.Day; var orderProperties = new OrderProperties { TimeInForce = timeInForce }; var order = new LimitOrder(Symbols.SPY, 10, 100, utcTime, "", orderProperties); Assert.IsFalse(timeInForce.IsOrderExpired(security, order)); var fill1 = new OrderEvent(order.Id, order.Symbol, utcTime, OrderStatus.PartiallyFilled, OrderDirection.Buy, order.LimitPrice, 3, OrderFee.Zero); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill1)); var fill2 = new OrderEvent(order.Id, order.Symbol, utcTime, OrderStatus.Filled, OrderDirection.Buy, order.LimitPrice, 7, OrderFee.Zero); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill2)); localTimeKeeper.UpdateTime(utcTime.AddHours(6).AddSeconds(-1)); Assert.IsFalse(timeInForce.IsOrderExpired(security, order)); localTimeKeeper.UpdateTime(utcTime.AddHours(6)); Assert.IsTrue(timeInForce.IsOrderExpired(security, order)); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill1)); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill2)); }
public void PerformsStopLimitFillSell() { var model = new ImmediateFillModel(); var order = new StopLimitOrder(Symbols.SPY, -100, 101.75m, 101.50m, Noon); var config = CreateTradeBarConfig(Symbols.SPY); var security = new Security( SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ); security.SetLocalTimeKeeper(TimeKeeper.GetLocalTimeKeeper(TimeZones.NewYork)); security.SetMarketPrice(new IndicatorDataPoint(Symbols.SPY, Noon, 102m)); var fill = model.Fill(new FillModelParameters( security, order, new MockSubscriptionDataConfigProvider(config), Time.OneHour)).OrderEvent; Assert.AreEqual(0, fill.FillQuantity); Assert.AreEqual(0, fill.FillPrice); Assert.AreEqual(OrderStatus.None, fill.Status); security.SetMarketPrice(new IndicatorDataPoint(Symbols.SPY, Noon, 101m)); fill = model.Fill(new FillModelParameters( security, order, new MockSubscriptionDataConfigProvider(config), Time.OneHour)).OrderEvent; Assert.AreEqual(0, fill.FillQuantity); Assert.AreEqual(0, fill.FillPrice); Assert.AreEqual(OrderStatus.None, fill.Status); security.SetMarketPrice(new IndicatorDataPoint(Symbols.SPY, Noon, 101.66m)); fill = model.StopLimitFill(security, order); // this fills worst case scenario, so it's at the limit price Assert.AreEqual(order.Quantity, fill.FillQuantity); Assert.AreEqual(security.Low, fill.FillPrice); Assert.AreEqual(OrderStatus.Filled, fill.Status); }
public void PerformsMarketFillSell() { var model = new EquityTransactionModel(); var order = new MarketOrder(Symbols.SPY, -100, Noon); var config = CreateTradeBarConfig(); var security = new Security(SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency)); security.SetLocalTimeKeeper(TimeKeeper.GetLocalTimeKeeper(TimeZones.NewYork)); security.SetMarketPrice(new IndicatorDataPoint(Symbols.SPY, Noon, 101.123m)); var fill = model.MarketFill(security, order); Assert.AreEqual(order.Quantity, fill.FillQuantity); Assert.AreEqual(security.Price, fill.FillPrice); Assert.AreEqual(OrderStatus.Filled, fill.Status); }
public void PerformsMarketFillSell() { var model = new EquityTransactionModel(); var order = new MarketOrder(Symbol, -100, Noon, type: SecurityType.Equity); var config = CreateTradeBarConfig(Symbol); var security = new Security(SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, 1); security.SetLocalTimeKeeper(TimeKeeper.GetLocalTimeKeeper(TimeZones.NewYork)); security.SetMarketPrice(new IndicatorDataPoint(Symbol, Noon, 101.123m)); var fill = model.MarketFill(security, order); Assert.AreEqual(order.Quantity, fill.FillQuantity); Assert.AreEqual(security.Price, fill.FillPrice); Assert.AreEqual(OrderStatus.Filled, fill.Status); }
public void PriceReturnsQuoteBarsIfPresent(OrderDirection orderDirection, decimal expected) { var time = new DateTime(2018, 9, 24, 9, 30, 0); var timeKeeper = new TimeKeeper(time.ConvertToUtc(TimeZones.NewYork), TimeZones.NewYork); var symbol = Symbol.Create("SPY", SecurityType.Equity, Market.USA); var configTradeBar = new SubscriptionDataConfig(typeof(TradeBar), symbol, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, true, true, false); var configQuoteBar = new SubscriptionDataConfig(configTradeBar, typeof(QuoteBar)); var security = new Security( SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), configQuoteBar, new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ); security.SetLocalTimeKeeper(timeKeeper.GetLocalTimeKeeper(TimeZones.NewYork)); var tradeBar = new TradeBar(time, symbol, 290m, 292m, 289m, 291m, 12345); security.SetMarketPrice(tradeBar); var quoteBar = new QuoteBar(time, symbol, new Bar(10, 15, 5, 11), 100, new Bar(20, 25, 15, 21), 100); security.SetMarketPrice(quoteBar); var configProvider = new MockSubscriptionDataConfigProvider(configQuoteBar); configProvider.SubscriptionDataConfigs.Add(configTradeBar); var testFillModel = new TestFillModel(); testFillModel.SetParameters(new FillModelParameters(security, null, configProvider, TimeSpan.FromDays(1))); var result = testFillModel.GetPricesPublic(security, orderDirection); Assert.AreEqual(expected, result.Close); }
public void PerformsMarketOnOpenUsingOpenPrice() { var reference = new DateTime(2015, 06, 05, 9, 0, 0); // before market open var model = new ImmediateFillModel(); var order = new MarketOnOpenOrder(Symbols.SPY, 100, reference); var config = CreateTradeBarConfig(Symbols.SPY); var security = new Security( SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance ); security.SetLocalTimeKeeper(TimeKeeper.GetLocalTimeKeeper(TimeZones.NewYork)); var time = reference; TimeKeeper.SetUtcDateTime(time.ConvertToUtc(TimeZones.NewYork)); security.SetMarketPrice(new TradeBar(time, Symbols.SPY, 1m, 2m, 0.5m, 1.33m, 100)); var fill = model.Fill(new FillModelParameters( security, order, new MockSubscriptionDataConfigProvider(config))).OrderEvent; Assert.AreEqual(0, fill.FillQuantity); // market opens after 30min, so this is just before market open time = reference.AddMinutes(29); TimeKeeper.SetUtcDateTime(time.ConvertToUtc(TimeZones.NewYork)); security.SetMarketPrice(new TradeBar(time, Symbols.SPY, 1.33m, 2.75m, 1.15m, 1.45m, 100)); fill = model.Fill(new FillModelParameters( security, order, new MockSubscriptionDataConfigProvider(config))).OrderEvent; Assert.AreEqual(0, fill.FillQuantity); // market opens after 30min time = reference.AddMinutes(30); TimeKeeper.SetUtcDateTime(time.ConvertToUtc(TimeZones.NewYork)); security.SetMarketPrice(new TradeBar(time, Symbols.SPY, 1.45m, 2.0m, 1.1m, 1.40m, 100)); fill = model.MarketOnOpenFill(security, order); Assert.AreEqual(order.Quantity, fill.FillQuantity); Assert.AreEqual(security.Open, fill.FillPrice); }
public void StopMarketOrderDoesNotFillUsingDataBeforeSubmitTime(decimal orderQuantity, decimal stopPrice) { var time = new DateTime(2018, 9, 24, 9, 30, 0); var timeKeeper = new TimeKeeper(time.ConvertToUtc(TimeZones.NewYork), TimeZones.NewYork); var symbol = Symbol.Create("SPY", SecurityType.Equity, Market.USA); var config = new SubscriptionDataConfig(typeof(TradeBar), symbol, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, true, true, false); var security = new Security(SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency)); security.SetLocalTimeKeeper(timeKeeper.GetLocalTimeKeeper(TimeZones.NewYork)); var tradeBar = new TradeBar(time, symbol, 290m, 292m, 289m, 291m, 12345); security.SetMarketPrice(tradeBar); time += TimeSpan.FromMinutes(1); timeKeeper.SetUtcDateTime(time.ConvertToUtc(TimeZones.NewYork)); var fillForwardBar = (TradeBar)tradeBar.Clone(true); security.SetMarketPrice(fillForwardBar); var fillModel = new ImmediateFillModel(); var order = new StopMarketOrder(symbol, orderQuantity, stopPrice, time.ConvertToUtc(TimeZones.NewYork)); var fill = fillModel.StopMarketFill(security, order); Assert.AreEqual(0, fill.FillQuantity); Assert.AreEqual(0, fill.FillPrice); Assert.AreEqual(OrderStatus.None, fill.Status); time += TimeSpan.FromMinutes(1); timeKeeper.SetUtcDateTime(time.ConvertToUtc(TimeZones.NewYork)); tradeBar = new TradeBar(time, symbol, 290m, 292m, 289m, 291m, 12345); security.SetMarketPrice(tradeBar); fill = fillModel.StopMarketFill(security, order); Assert.AreEqual(orderQuantity, fill.FillQuantity); Assert.AreEqual(stopPrice, fill.FillPrice); Assert.AreEqual(OrderStatus.Filled, fill.Status); Assert.AreEqual(0, fill.OrderFee); }
public void GtcTimeInForceOrderDoesNotExpire() { var handler = new GoodTilCanceledTimeInForceHandler(); var security = new Equity( SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, true, true, true), new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency)); var order = new LimitOrder(Symbols.SPY, 10, 100, DateTime.UtcNow); Assert.IsFalse(handler.IsOrderExpired(security, order)); var fill1 = new OrderEvent(order.Id, order.Symbol, DateTime.UtcNow, OrderStatus.PartiallyFilled, OrderDirection.Buy, order.LimitPrice, 3, 0); Assert.IsTrue(handler.IsFillValid(security, order, fill1)); var fill2 = new OrderEvent(order.Id, order.Symbol, DateTime.UtcNow, OrderStatus.Filled, OrderDirection.Buy, order.LimitPrice, 7, 0); Assert.IsTrue(handler.IsFillValid(security, order, fill2)); }
public void PerformsStopMarketFillBuy() { var model = new ImmediateFillModel(); var order = new StopMarketOrder(Symbols.SPY, 100, 101.5m, Noon); var config = CreateTradeBarConfig(Symbols.SPY); var security = new Security( SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance ); security.SetLocalTimeKeeper(TimeKeeper.GetLocalTimeKeeper(TimeZones.NewYork)); security.SetMarketPrice(new IndicatorDataPoint(Symbols.SPY, Noon, 101m)); var fill = model.Fill(new FillModelParameters( security, order, new MockSubscriptionDataConfigProvider(config), Time.OneHour)).OrderEvent; Assert.AreEqual(0, fill.FillQuantity); Assert.AreEqual(0, fill.FillPrice); Assert.AreEqual(OrderStatus.None, fill.Status); security.SetMarketPrice(new IndicatorDataPoint(Symbols.SPY, Noon, 102.5m)); fill = model.Fill(new FillModelParameters( security, order, new MockSubscriptionDataConfigProvider(config), Time.OneHour)).OrderEvent; // this fills worst case scenario, so it's min of asset/stop price Assert.AreEqual(order.Quantity, fill.FillQuantity); Assert.AreEqual(Math.Max(security.Price, order.StopPrice), fill.FillPrice); Assert.AreEqual(OrderStatus.Filled, fill.Status); }
public void PerformsMarketFillSell() { var model = new EquityFillModel(); var order = new MarketOrder(Symbols.SPY, -100, Noon); var config = CreateQuoteBarConfig(Symbols.SPY); var security = new Security( SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ); security.SetLocalTimeKeeper(TimeKeeper.GetLocalTimeKeeper(TimeZones.NewYork)); security.SetMarketPrice(new IndicatorDataPoint(Symbols.SPY, Noon, 101.123m)); var parameters = new FillModelParameters( security, order, new MockSubscriptionDataConfigProvider(config), Time.OneHour); // IndicatorDataPoint is not market data Assert.Throws <InvalidOperationException>(() => model.Fill(parameters), $"Cannot get bid price to perform fill for {security.Symbol} because no market data subscription were found."); var bidBar = new Bar(101.123m, 101.123m, 101.123m, 101.123m); var askBar = new Bar(101.234m, 101.234m, 101.234m, 101.234m); security.SetMarketPrice(new QuoteBar(Noon, Symbols.SPY, bidBar, 0, askBar, 0)); var fill = model.Fill(parameters).OrderEvent; Assert.AreEqual(order.Quantity, fill.FillQuantity); Assert.AreEqual(bidBar.Close, fill.FillPrice); Assert.AreEqual(OrderStatus.Filled, fill.Status); }
public void ImmediateFillModelUsesPriceForTicksWhenBidAskSpreadsAreNotAvailable() { var noon = new DateTime(2014, 6, 24, 12, 0, 0); var timeKeeper = new TimeKeeper(noon.ConvertToUtc(TimeZones.NewYork), new[] { TimeZones.NewYork }); var symbol = Symbol.Create("SPY", SecurityType.Equity, Market.USA); var config = new SubscriptionDataConfig(typeof(Tick), Symbols.SPY, Resolution.Tick, TimeZones.NewYork, TimeZones.NewYork, true, true, false); var security = new Security( SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ); security.SetLocalTimeKeeper(timeKeeper.GetLocalTimeKeeper(TimeZones.NewYork)); security.SetMarketPrice(new IndicatorDataPoint(Symbols.SPY, noon, 101.123m)); // Add both a tradebar and a tick to the security cache // This is the case when a tick is seeded with minute data in an algorithm security.Cache.AddData(new TradeBar(DateTime.MinValue, symbol, 1.0m, 1.0m, 1.0m, 1.0m, 1.0m)); security.Cache.AddData(new Tick(config, "42525000,1000000,100,A,@,0", DateTime.MinValue)); var fillModel = new ImmediateFillModel(); var order = new MarketOrder(symbol, 1000, DateTime.Now); var fill = fillModel.Fill(new FillModelParameters( security, order, new MockSubscriptionDataConfigProvider(config), Time.OneHour)).OrderEvent; // The fill model should use the tick.Price Assert.AreEqual(fill.FillPrice, 100m); Assert.AreEqual(0, fill.OrderFee.Value.Amount); }
public void PerformsLimitIfTouchedFillSell() { var model = new ImmediateFillModel(); var order = new LimitIfTouchedOrder(Symbols.SPY, -100, 101.5m, 105m, Noon); var configTradeBar = CreateTradeBarConfig(Symbols.SPY); var configQuoteBar = new SubscriptionDataConfig(configTradeBar, typeof(QuoteBar)); var configProvider = new MockSubscriptionDataConfigProvider(configQuoteBar); var security = new Security( SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), configTradeBar, new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ); // Sets price at time zero security.SetLocalTimeKeeper(TimeKeeper.GetLocalTimeKeeper(TimeZones.NewYork)); security.SetMarketPrice(new TradeBar(Noon, Symbols.SPY, 100m, 100m, 90m, 90m, 100)); configProvider.SubscriptionDataConfigs.Add(configTradeBar); var fill = model.Fill(new FillModelParameters( security, order, configProvider, Time.OneHour)).OrderEvent; Assert.AreEqual(0, fill.FillQuantity); Assert.AreEqual(0, fill.FillPrice); Assert.AreEqual(OrderStatus.None, fill.Status); // Time jump => trigger touched but not limit security.SetMarketPrice(new TradeBar(Noon, Symbols.SPY, 102m, 103m, 102m, 102m, 100)); security.SetMarketPrice(new QuoteBar(Noon, Symbols.SPY, new Bar(101m, 102m, 100m, 100m), 100, // Bid bar new Bar(103m, 104m, 102m, 102m), 100) // Ask bar ); Assert.AreEqual(0, fill.FillQuantity); Assert.AreEqual(0, fill.FillPrice); Assert.AreEqual(OrderStatus.None, fill.Status); fill = model.Fill(new FillModelParameters( security, order, configProvider, Time.OneHour)).OrderEvent; Assert.AreEqual(0, fill.FillQuantity); Assert.AreEqual(0, fill.FillPrice); Assert.AreEqual(OrderStatus.None, fill.Status); // Time jump => limit reached, holdings sold security.SetMarketPrice(new TradeBar(Noon, Symbols.SPY, 103m, 108m, 103m, 105m, 100)); security.SetMarketPrice(new QuoteBar(Noon, Symbols.SPY, new Bar(103m, 106m, 103m, 105m), 100, // Bid bar new Bar(103m, 108m, 103m, 105m), 100) // Ask bar ); fill = model.LimitIfTouchedFill(security, order); // this fills worst case scenario Assert.AreEqual(order.Quantity, fill.FillQuantity); Assert.AreEqual(order.LimitPrice, fill.FillPrice); Assert.AreEqual(OrderStatus.Filled, fill.Status); }