internal void UpdatePosition_WhenPositionOpen_CorrectlyUpdatesIndexes() { // Arrange var order = new StubOrderBuilder().BuildMarketOrder(); var traderId = TraderId.FromString("TESTER-000"); var accountId = AccountId.FromString("NAUTILUS-000-SIMULATED"); var strategyId = new StrategyId("SCALPER", "001"); var positionId = new PositionId("P-123456"); this.database.AddOrder(order, traderId, accountId, strategyId, positionId); var position = new Position(positionId, StubEventMessageProvider.OrderPartiallyFilledEvent( order, Quantity.Create(50000), Quantity.Create(50000))); this.database.AddPosition(position); // Act position.Apply(StubEventMessageProvider.OrderFilledEvent(order)); this.database.UpdatePosition(position); // Assert Assert.Equal(position, this.database.GetPosition(positionId)); Assert.Contains(position.Id, this.database.GetPositions()); Assert.Contains(position.Id, this.database.GetPositions(traderId)); Assert.Contains(position.Id, this.database.GetPositions(traderId, strategyId)); Assert.Contains(position.Id, this.database.GetPositionsOpen()); Assert.Contains(position.Id, this.database.GetPositionsOpen(traderId)); Assert.Contains(position.Id, this.database.GetPositionsOpen(traderId, strategyId)); Assert.Contains(position.Id, this.database.GetPositionIds()); Assert.Contains(position.Id, this.database.GetPositionOpenIds()); Assert.DoesNotContain(position.Id, this.database.GetPositionClosedIds()); }
internal void CanSerializeAndDeserialize_OrderFilledEvents() { // Arrange var order = new StubOrderBuilder() .WithQuantity(Quantity.Create(100000)) .BuildStopLimitOrder(); var filled = new OrderFilled( AccountId.FromString("FXCM-02851908-DEMO"), order.Id, new ExecutionId("E123456"), new PositionIdBroker("P123456"), order.Symbol, order.OrderSide, order.Quantity, Price.Create(2m, 1), Currency.USD, StubZonedDateTime.UnixEpoch(), Guid.NewGuid(), StubZonedDateTime.UnixEpoch()); // Act var packed = this.serializer.Serialize(filled); var unpacked = (OrderFilled)this.serializer.Deserialize(packed); // Assert Assert.Equal(filled, unpacked); this.Output.WriteLine(Convert.ToBase64String(packed)); }
internal void OnSubmitOrderCommand_WhenCommandValid_OperatesDatabaseAndSendsToGateway() { // Arrange var order = new StubOrderBuilder().EntryOrder("O-123456").BuildMarketOrder(); var traderId = TraderId.FromString("TESTER-000"); var accountId = AccountId.FromString("NAUTILUS-000-SIMULATED"); var positionId = new PositionId("P-123456"); var strategyId = new StrategyId("SCALPER", "001"); var command = new SubmitOrder( traderId, accountId, strategyId, positionId, order, Guid.NewGuid(), StubZonedDateTime.UnixEpoch()); // Act this.engine.Endpoint.SendAsync(command).Wait(); Task.Delay(100).Wait(); // Buffer to avoid intermittent tests // Assert Assert.Null(this.engine.UnhandledMessages.FirstOrDefault()); Assert.Equal(2, this.engine.ProcessedCount); Assert.Equal(1, this.engine.CommandCount); Assert.Single(this.tradingGateway.CalledMethods); Assert.Single(this.tradingGateway.ReceivedObjects); Assert.Equal("SubmitOrder", this.tradingGateway.CalledMethods[0]); Assert.Equal(order, this.tradingGateway.ReceivedObjects[0]); }
internal void GetOrdersCompleted_WhenDoesNotExistInCache_ReturnsEmptyDictionary() { // Arrange var order = new StubOrderBuilder().EntryOrder("O-123456").BuildMarketOrder(); var traderId = TraderId.FromString("TESTER-000"); var accountId = AccountId.FromString("NAUTILUS-000-SIMULATED"); var positionId = new PositionId("P-123456"); var strategyId = new StrategyId("SCALPER", "001"); this.database.AddOrder(order, traderId, accountId, strategyId, positionId); order.Apply(StubEventMessageProvider.OrderSubmittedEvent(order)); this.database.UpdateOrder(order); order.Apply(StubEventMessageProvider.OrderRejectedEvent(order)); this.database.UpdateOrder(order); // Act this.database.ClearCaches(); // Assert Assert.Empty(this.database.GetOrders()); Assert.Empty(this.database.GetOrders(traderId)); Assert.Empty(this.database.GetOrders(traderId, strategyId)); Assert.Empty(this.database.GetOrdersWorking()); Assert.Empty(this.database.GetOrdersWorking(traderId)); Assert.Empty(this.database.GetOrdersWorking(traderId, strategyId)); Assert.Empty(this.database.GetOrdersCompleted()); Assert.Empty(this.database.GetOrdersCompleted(traderId)); Assert.Empty(this.database.GetOrdersCompleted(traderId, strategyId)); }
internal void UpdateOrder_WhenOrderCompleted_CorrectlyUpdatesIndexes() { // Arrange var order = new StubOrderBuilder().EntryOrder("O-123456").BuildMarketOrder(); var traderId = TraderId.FromString("TESTER-000"); var accountId = AccountId.FromString("NAUTILUS-000-SIMULATED"); var positionId = new PositionId("P-123456"); var strategyId = new StrategyId("SCALPER", "001"); this.database.AddOrder(order, traderId, accountId, strategyId, positionId); order.Apply(StubEventMessageProvider.OrderSubmittedEvent(order)); this.database.UpdateOrder(order); order.Apply(StubEventMessageProvider.OrderRejectedEvent(order)); // Act this.database.UpdateOrder(order); // Assert Assert.Contains(order.Id, this.database.GetOrderIds()); Assert.Contains(order.Id, this.database.GetOrderIds(traderId)); Assert.Contains(order.Id, this.database.GetOrderIds(traderId, strategyId)); Assert.Contains(order.Id, this.database.GetOrderCompletedIds()); Assert.Contains(order.Id, this.database.GetOrderCompletedIds(traderId)); Assert.Contains(order.Id, this.database.GetOrderCompletedIds(traderId, strategyId)); Assert.DoesNotContain(order.Id, this.database.GetOrderWorkingIds()); Assert.Contains(order.Id, this.database.GetOrders(traderId)); Assert.Contains(order.Id, this.database.GetOrders(traderId, strategyId)); Assert.Contains(order.Id, this.database.GetOrdersCompleted(traderId)); Assert.Contains(order.Id, this.database.GetOrdersCompleted(traderId, strategyId)); }
internal void AddBracketOrder_WithNoTakeProfit_CorrectlyAddsOrdersWithIndexes() { // Arrange var bracketOrder = StubBracketOrderProvider.Create(false); var traderId = TraderId.FromString("TESTER-000"); var accountId = AccountId.FromString("NAUTILUS-000-SIMULATED"); var positionId = new PositionId("P-123456"); var strategyId = new StrategyId("SCALPER", "001"); // Act this.database.AddBracketOrder(bracketOrder, traderId, accountId, strategyId, positionId); // Assert Assert.Equal(bracketOrder.Entry, this.database.GetOrder(bracketOrder.Entry.Id)); Assert.Equal(bracketOrder.StopLoss, this.database.GetOrder(bracketOrder.StopLoss.Id)); Assert.Equal(positionId, this.database.GetPositionId(bracketOrder.Entry.Id)); Assert.Equal(positionId, this.database.GetPositionId(bracketOrder.StopLoss.Id)); Assert.Equal(traderId, this.database.GetTraderId(bracketOrder.Entry.Id)); Assert.Equal(traderId, this.database.GetTraderId(bracketOrder.StopLoss.Id)); Assert.Equal(2, this.database.GetOrders().Count); Assert.Equal(2, this.database.GetOrders(traderId).Count); Assert.Equal(2, this.database.GetOrders(traderId, strategyId).Count); Assert.Contains(bracketOrder.Entry.Id, this.database.GetOrderIds()); Assert.Contains(bracketOrder.Entry.Id, this.database.GetOrders()); Assert.Contains(bracketOrder.Entry.Id, this.database.GetOrders(traderId)); Assert.Contains(bracketOrder.Entry.Id, this.database.GetOrders(traderId, strategyId)); Assert.DoesNotContain(bracketOrder.Entry.Id, this.database.GetOrderWorkingIds()); Assert.DoesNotContain(bracketOrder.Entry.Id, this.database.GetOrderCompletedIds()); Assert.DoesNotContain(bracketOrder.Entry.Id, this.database.GetOrdersWorking()); Assert.DoesNotContain(bracketOrder.Entry.Id, this.database.GetOrdersCompleted()); Assert.Contains(bracketOrder.StopLoss.Id, this.database.GetOrderIds()); Assert.Contains(bracketOrder.StopLoss.Id, this.database.GetOrders()); Assert.Contains(bracketOrder.StopLoss.Id, this.database.GetOrders(traderId)); Assert.Contains(bracketOrder.StopLoss.Id, this.database.GetOrders(traderId, strategyId)); }
public static OrderPartiallyFilled OrderPartiallyFilledEvent( Order order, Quantity filledQuantity, Quantity leavesQuantity, Price?averagePrice = null) { if (averagePrice is null) { averagePrice = Price.Create(1.00000m); } return(new OrderPartiallyFilled( AccountId.FromString("FXCM-02851908-DEMO"), order.Id, new ExecutionId("None"), new PositionIdBroker("None"), order.Symbol, order.OrderSide, filledQuantity, leavesQuantity, averagePrice, Currency.USD, StubZonedDateTime.UnixEpoch() + Period.FromMinutes(1).ToDuration(), Guid.NewGuid(), StubZonedDateTime.UnixEpoch())); }
internal void AddOrder_WithNoOrdersInDatabase_CorrectlyAddsOrderWithIndexes() { // Arrange var order = new StubOrderBuilder().EntryOrder("O-123456").BuildMarketOrder(); var traderId = TraderId.FromString("TESTER-000"); var accountId = AccountId.FromString("NAUTILUS-000-SIMULATED"); var positionId = new PositionId("P-123456"); var strategyId = new StrategyId("SCALPER", "001"); // Act this.database.AddOrder(order, traderId, accountId, strategyId, positionId); // Assert Assert.Equal(order, this.database.GetOrder(order.Id)); Assert.Equal(positionId, this.database.GetPositionId(order.Id)); Assert.Equal(traderId, this.database.GetTraderId(order.Id)); Assert.Single(this.database.GetOrders()); Assert.Single(this.database.GetOrders(traderId)); Assert.Single(this.database.GetOrders(traderId, strategyId)); Assert.Contains(order.Id, this.database.GetOrders()); Assert.Contains(order.Id, this.database.GetOrders(traderId)); Assert.Contains(order.Id, this.database.GetOrders(traderId, strategyId)); Assert.Contains(traderId, this.database.GetTraderIds()); Assert.Contains(accountId, this.database.GetAccountIds()); Assert.Contains(strategyId, this.database.GetStrategyIds(traderId)); }
internal void OnOrderPartiallyFilledEvent_UpdatesOrderSendsToPublisher() { // Arrange var order = new StubOrderBuilder().EntryOrder("O-123456").BuildMarketOrder(); var traderId = TraderId.FromString("TESTER-000"); var accountId = AccountId.FromString("NAUTILUS-000-SIMULATED"); var positionId = new PositionId("P-123456"); var strategyId = new StrategyId("SCALPER", "001"); var submitOrder = new SubmitOrder( traderId, accountId, strategyId, positionId, order, Guid.NewGuid(), StubZonedDateTime.UnixEpoch()); // Act this.engine.Endpoint.SendAsync(submitOrder).Wait(); this.engine.Endpoint.SendAsync(StubEventMessageProvider.OrderAcceptedEvent(order)).Wait(); this.engine.Endpoint.SendAsync(StubEventMessageProvider.OrderPartiallyFilledEvent( order, Quantity.Create(50000), Quantity.Create(50000))).Wait(); Task.Delay(100).Wait(); // Buffer to avoid intermittent tests // Assert Assert.Null(this.engine.UnhandledMessages.FirstOrDefault()); Assert.Equal(4, this.engine.ProcessedCount); Assert.Equal(1, this.engine.CommandCount); Assert.Equal(2, this.engine.EventCount); Assert.Equal(3, this.receiver.Messages.Count); Assert.Equal(OrderState.PartiallyFilled, order.State); }
internal void OnOrderFilledEvent_WithNoPosition_OpensPosition() { // Arrange var order = new StubOrderBuilder().EntryOrder("O-123456").BuildMarketOrder(); var traderId = TraderId.FromString("TESTER-000"); var accountId = AccountId.FromString("NAUTILUS-000-SIMULATED"); var positionId = new PositionId("P-123456"); var strategyId = new StrategyId("SCALPER", "001"); var submitOrder = new SubmitOrder( traderId, accountId, strategyId, positionId, order, Guid.NewGuid(), StubZonedDateTime.UnixEpoch()); // Act this.engine.Endpoint.SendAsync(submitOrder).Wait(); this.engine.Endpoint.SendAsync(StubEventMessageProvider.OrderSubmittedEvent(order)).Wait(); this.engine.Endpoint.SendAsync(StubEventMessageProvider.OrderAcceptedEvent(order)).Wait(); this.engine.Endpoint.SendAsync(StubEventMessageProvider.OrderFilledEvent(order)).Wait(); Task.Delay(100).Wait(); // Buffer to avoid intermittent tests // Assert Assert.Single(this.database.GetPositions()); }
internal void OnModifyOrderCommand_WhenNoOrderExists_DoesNotSendToGateway() { // Arrange var order = new StubOrderBuilder().EntryOrder("O-123456").BuildMarketOrder(); var traderId = TraderId.FromString("TESTER-000"); var accountId = AccountId.FromString("NAUTILUS-000-SIMULATED"); var modify = new ModifyOrder( traderId, accountId, order.Id, order.Quantity, Price.Create(1.00010m, 5), Guid.NewGuid(), StubZonedDateTime.UnixEpoch()); // Act this.engine.Endpoint.SendAsync(modify); Task.Delay(100).Wait(); // Buffer to avoid intermittent tests // Assert Assert.Null(this.engine.UnhandledMessages.FirstOrDefault()); Assert.Equal(2, this.engine.ProcessedCount); Assert.Equal(1, this.engine.CommandCount); Assert.Equal(0, this.engine.EventCount); Assert.Empty(this.tradingGateway.CalledMethods); Assert.Empty(this.tradingGateway.ReceivedObjects); Assert.Empty(this.receiver.Messages); }
internal void GetPositionsOpen_WhenNotPositionsInCache_ReturnsEmptyDictionary() { // Arrange var order = new StubOrderBuilder().BuildMarketOrder(); var traderId = TraderId.FromString("TESTER-000"); var accountId = AccountId.FromString("NAUTILUS-000-SIMULATED"); var strategyId = new StrategyId("SCALPER", "001"); var positionId = new PositionId("P-123456"); this.database.AddOrder(order, traderId, accountId, strategyId, positionId); var position = new Position(positionId, StubEventMessageProvider.OrderPartiallyFilledEvent( order, Quantity.Create(50000), Quantity.Create(50000))); this.database.AddPosition(position); position.Apply(StubEventMessageProvider.OrderFilledEvent(order)); this.database.UpdatePosition(position); // Act this.database.ClearCaches(); // Assert Assert.Empty(this.database.GetPositionsOpen()); Assert.Empty(this.database.GetPositionsOpen(traderId)); Assert.Empty(this.database.GetPositionsOpen(traderId, strategyId)); }
internal void GetPositionsClosed_WhenNotPositionsInCache_ReturnsEmptyDictionary() { // Arrange var order1 = new StubOrderBuilder() .WithOrderId("O-123456-1") .BuildMarketOrder(); var order2 = new StubOrderBuilder() .WithOrderId("O-123456-2") .WithOrderSide(OrderSide.Sell) .BuildMarketOrder(); var traderId = TraderId.FromString("TESTER-000"); var accountId = AccountId.FromString("NAUTILUS-000-SIMULATED"); var strategyId = new StrategyId("SCALPER", "001"); var positionId = new PositionId("P-123456"); this.database.AddOrder(order1, traderId, accountId, strategyId, positionId); this.database.AddOrder(order2, traderId, accountId, strategyId, positionId); var position = new Position(positionId, StubEventMessageProvider.OrderFilledEvent(order1)); this.database.AddPosition(position); position.Apply(StubEventMessageProvider.OrderFilledEvent(order2)); this.database.UpdatePosition(position); // Act this.database.ClearCaches(); // Assert Assert.Empty(this.database.GetPositionsClosed()); Assert.Empty(this.database.GetPositionsClosed(traderId)); Assert.Empty(this.database.GetPositionsClosed(traderId, strategyId)); }
internal void CanSerializeAndDeserialize_OrderWorkingWithExpireTimeEvents() { // Arrange var order = new StubOrderBuilder() .WithTimeInForce(TimeInForce.GTD) .WithExpireTime(StubZonedDateTime.UnixEpoch() + Duration.FromMinutes(1)) .BuildStopMarketOrder(); var working = new OrderWorking( AccountId.FromString("FXCM-02851908-DEMO"), order.Id, new OrderIdBroker("B" + order.Id.Value), order.Symbol, order.OrderSide, order.OrderType, order.Quantity, order.Price, order.TimeInForce, order.ExpireTime, StubZonedDateTime.UnixEpoch(), Guid.NewGuid(), StubZonedDateTime.UnixEpoch()); // Act var packed = this.serializer.Serialize(working); var unpacked = (OrderWorking)this.serializer.Deserialize(packed); // Assert Assert.Equal(working, unpacked); this.Output.WriteLine(Convert.ToBase64String(packed)); }
public static OrderSubmitted OrderSubmittedEvent(Order order) { return(new OrderSubmitted( AccountId.FromString("FXCM-02851908-DEMO"), order.Id, StubZonedDateTime.UnixEpoch(), Guid.NewGuid(), StubZonedDateTime.UnixEpoch())); }
public static OrderAccepted OrderAcceptedEvent(Order order) { return(new OrderAccepted( AccountId.FromString("FXCM-02851908-DEMO"), order.Id, new OrderIdBroker("B" + order.Id.Value), StubZonedDateTime.UnixEpoch(), Guid.NewGuid(), StubZonedDateTime.UnixEpoch())); }
internal void ApplyEvents_OrderFilledFromShortPositionToLong_ReturnsCorrectMarketPositionAndQuantity() { // Arrange var orderFill1 = new OrderFilled( AccountId.FromString("FXCM-02851908-DEMO"), new OrderId("O-123456"), new ExecutionId("E-123456"), new PositionIdBroker("ET-123456"), new Symbol("AUDUSD", new Venue("FXCM")), OrderSide.Sell, Quantity.Create(1000000), Price.Create(1.00000m, 5), Currency.USD, StubZonedDateTime.UnixEpoch(), Guid.NewGuid(), StubZonedDateTime.UnixEpoch()); var position = new Position(new PositionId("P-123456"), orderFill1); var orderFill2 = new OrderFilled( AccountId.FromString("FXCM-02851908-DEMO"), new OrderId("O-123457"), new ExecutionId("E-123456"), new PositionIdBroker("ET-123456"), position.Symbol, OrderSide.Buy, Quantity.Create(500000), Price.Create(1.00001m, 5), Currency.USD, StubZonedDateTime.UnixEpoch(), Guid.NewGuid(), StubZonedDateTime.UnixEpoch()); var orderFill3 = new OrderFilled( AccountId.FromString("FXCM-02851908-DEMO"), new OrderId("O-123458"), new ExecutionId("E-123456"), new PositionIdBroker("ET-123456"), position.Symbol, OrderSide.Buy, Quantity.Create(1000000), Price.Create(1.00000m, 5), Currency.USD, StubZonedDateTime.UnixEpoch(), Guid.NewGuid(), StubZonedDateTime.UnixEpoch()); // Act position.Apply(orderFill2); position.Apply(orderFill3); // Assert Assert.Equal(MarketPosition.Long, position.MarketPosition); Assert.Equal(Quantity.Create(500000), position.Quantity); }
internal void OnModifyOrderCommand_WhenOrderAlreadyBeingModified_DoesNotSendToGateway() { // Arrange var order = new StubOrderBuilder().EntryOrder("O-123456").BuildStopMarketOrder(); var traderId = TraderId.FromString("TESTER-000"); var accountId = AccountId.FromString("NAUTILUS-000-SIMULATED"); var positionId = new PositionId("P-123456"); var strategyId = new StrategyId("SCALPER", "001"); var submit = new SubmitOrder( traderId, accountId, strategyId, positionId, order, Guid.NewGuid(), StubZonedDateTime.UnixEpoch()); var modify1 = new ModifyOrder( traderId, accountId, order.Id, order.Quantity, Price.Create(1.00010m, 5), Guid.NewGuid(), StubZonedDateTime.UnixEpoch()); var modify2 = new ModifyOrder( traderId, accountId, order.Id, order.Quantity, Price.Create(1.00010m, 5), Guid.NewGuid(), StubZonedDateTime.UnixEpoch()); // Act this.engine.Endpoint.SendAsync(submit).Wait(); this.engine.Endpoint.SendAsync(StubEventMessageProvider.OrderAcceptedEvent(order)).Wait(); this.engine.Endpoint.SendAsync(StubEventMessageProvider.OrderWorkingEvent(order)).Wait(); this.engine.Endpoint.SendAsync(modify1).Wait(); this.engine.Endpoint.SendAsync(modify2).Wait(); Task.Delay(100).Wait(); // Buffer to avoid intermittent tests // Assert Assert.Null(this.engine.UnhandledMessages.FirstOrDefault()); Assert.Equal(6, this.engine.ProcessedCount); Assert.Equal(3, this.engine.CommandCount); Assert.Equal(2, this.engine.EventCount); Assert.Equal(2, this.tradingGateway.CalledMethods.Count); Assert.Equal(2, this.tradingGateway.ReceivedObjects.Count); Assert.Equal("SubmitOrder", this.tradingGateway.CalledMethods[0]); Assert.Equal("ModifyOrder", this.tradingGateway.CalledMethods[1]); Assert.Equal(3, this.receiver.Messages.Count); }
public static OrderCancelReject OrderCancelRejectEvent(Order order) { return(new OrderCancelReject( AccountId.FromString("FXCM-02851908-DEMO"), order.Id, StubZonedDateTime.UnixEpoch(), "None", "TEST", Guid.NewGuid(), StubZonedDateTime.UnixEpoch())); }
public static OrderModified OrderModifiedEvent(Order order, Price newPrice) { return(new OrderModified( AccountId.FromString("FXCM-02851908-DEMO"), order.Id, new OrderIdBroker("B" + order.Id.Value), order.Quantity, newPrice, StubZonedDateTime.UnixEpoch(), Guid.NewGuid(), StubZonedDateTime.UnixEpoch())); }
internal void ApplyEvents_MultipleFillsInOpenDirection_ReturnsCorrectValues() { // Arrange var orderFill1 = new OrderFilled( AccountId.FromString("FXCM-02851908-DEMO"), new OrderId("O-123456"), new ExecutionId("E-123456"), new PositionIdBroker("ET-123456"), new Symbol("AUDUSD", new Venue("FXCM")), OrderSide.Sell, Quantity.Create(100000), Price.Create(1.00000m, 5), Currency.USD, StubZonedDateTime.UnixEpoch(), Guid.NewGuid(), StubZonedDateTime.UnixEpoch()); var orderFill2 = new OrderFilled( AccountId.FromString("FXCM-02851908-DEMO"), new OrderId("O-1234561"), new ExecutionId("E-1234561"), new PositionIdBroker("ET-123456"), new Symbol("AUDUSD", new Venue("FXCM")), OrderSide.Sell, Quantity.Create(100000), Price.Create(1.00001m, 5), Currency.USD, StubZonedDateTime.UnixEpoch(), Guid.NewGuid(), StubZonedDateTime.UnixEpoch()); var position = new Position(new PositionId("P-123456"), orderFill1); var tick = StubQuoteTickProvider.Create(new Symbol("AUDUSD", new Venue("FXCM"))); // Act position.Apply(orderFill2); // Assert Assert.Equal(1.000005m, position.AverageOpenPrice); Assert.Equal(MarketPosition.Short, position.MarketPosition); Assert.Equal(Quantity.Create(200000), position.Quantity); Assert.Equal(decimal.Zero, position.RealizedPoints); Assert.Equal(0, position.RealizedReturn); Assert.Equal(Money.Zero(position.BaseCurrency), position.RealizedPnl); Assert.Equal(0.199945m, position.UnrealizedPoints(tick)); Assert.Equal(0.19994400027999865, position.UnrealizedReturn(tick)); Assert.Equal(Money.Create(39989m, position.BaseCurrency), position.UnrealizedPnl(tick)); Assert.Equal(0.199945m, position.TotalPoints(tick)); Assert.Equal(0.19994400027999865, position.TotalReturn(tick)); Assert.Equal(Money.Create(39989m, position.BaseCurrency), position.TotalPnl(tick)); }
internal void Position_OrderFilledSellCase_ReturnsCorrectValues() { // Arrange var orderFill = new OrderFilled( AccountId.FromString("FXCM-02851908-DEMO"), new OrderId("O-123456"), new ExecutionId("E-123456"), new PositionIdBroker("ET-123456"), new Symbol("AUD/USD", new Venue("FXCM")), OrderSide.Sell, Quantity.Create(1000), Price.Create(2000m, 2), Currency.USD, StubZonedDateTime.UnixEpoch(), Guid.NewGuid(), StubZonedDateTime.UnixEpoch()); // Act var position = new Position(new PositionId("P-123456"), orderFill); // Assert Assert.Equal(new Symbol("AUD/USD", new Venue("FXCM")), position.Symbol); Assert.Equal(new OrderId("O-123456"), position.FromOrderId); Assert.Equal(new OrderId("O-123456"), position.LastOrderId); Assert.Equal(new ExecutionId("E-123456"), position.LastExecutionId); Assert.Equal(new PositionIdBroker("ET-123456"), position.IdBroker); Assert.Equal(new OrderId("O-123456"), position.GetOrderIds()[0]); Assert.Equal(new ExecutionId("E-123456"), position.GetExecutionIds()[0]); Assert.Equal(2000, position.AverageOpenPrice); Assert.Null(position.AverageClosePrice); Assert.Null(position.ClosedTime); Assert.Null(position.OpenDuration); Assert.Equal(OrderSide.Sell, position.EntryDirection); Assert.Equal(Quantity.Create(1000), position.Quantity); Assert.Equal(Quantity.Create(1000), position.PeakQuantity); Assert.Equal(MarketPosition.Short, position.MarketPosition); Assert.Equal(StubZonedDateTime.UnixEpoch(), position.OpenedTime); Assert.Equal(1, position.EventCount); Assert.Equal(orderFill, position.LastEvent); Assert.Equal(0m, position.RealizedPoints); Assert.Equal(0, position.RealizedReturn); Assert.Equal(Money.Zero(position.BaseCurrency), position.RealizedPnl); Assert.True(position.IsOpen); Assert.True(position.IsShort); Assert.False(position.IsClosed); Assert.False(position.IsLong); Assert.Equal(StubZonedDateTime.UnixEpoch(), position.LastUpdated); Assert.Equal(orderFill, position.LastEvent); Assert.Equal(orderFill, position.InitialEvent); }
public static AccountStateEvent AccountStateEvent(string accountId = "FXCM-123456789-SIMULATED") { return(new AccountStateEvent( AccountId.FromString(accountId), Currency.USD, Money.Create(100000, Currency.USD), Money.Create(100000, Currency.USD), Money.Zero(Currency.USD), Money.Zero(Currency.USD), Money.Zero(Currency.USD), decimal.Zero, string.Empty, Guid.NewGuid(), StubZonedDateTime.UnixEpoch())); }
internal void ApplyEvents_OrderFilledFromAlreadyShort_ReturnsCorrectMarketPositionAndQuantity() { // Arrange var orderFill11 = new OrderFilled( AccountId.FromString("FXCM-02851908-DEMO"), new OrderId("O-123456"), new ExecutionId("E-123456"), new PositionIdBroker("ET-123456"), new Symbol("AUD/USD", new Venue("FXCM")), OrderSide.Sell, Quantity.Create(5000), Price.Create(1.00000m, 5), Currency.USD, StubZonedDateTime.UnixEpoch(), Guid.NewGuid(), StubZonedDateTime.UnixEpoch()); var position = new Position(new PositionId("P-123456"), orderFill11); var orderFill2 = new OrderFilled( AccountId.FromString("FXCM-02851908-DEMO"), new OrderId("O-123456"), new ExecutionId("E-123456"), new PositionIdBroker("ET-123456"), position.Symbol, OrderSide.Buy, Quantity.Create(5000), Price.Create(1.00000m, 5), Currency.USD, StubZonedDateTime.UnixEpoch() + Duration.FromMinutes(1), Guid.NewGuid(), StubZonedDateTime.UnixEpoch()); // Act position.Apply(orderFill2); // Assert Assert.Equal(MarketPosition.Flat, position.MarketPosition); Assert.Equal(Duration.FromMinutes(1), position.OpenDuration); Assert.Equal(Quantity.Create(0), position.Quantity); Assert.Equal(orderFill2, position.LastEvent); Assert.True(position.IsClosed); Assert.False(position.IsOpen); Assert.False(position.IsShort); Assert.False(position.IsLong); }
internal void AddOrder_WhenOrderAlreadyExists_ReturnsFailureResult() { // Arrange var order = new StubOrderBuilder().EntryOrder("O-123456").BuildMarketOrder(); var traderId = TraderId.FromString("TESTER-000"); var accountId = AccountId.FromString("NAUTILUS-000-SIMULATED"); var positionId = new PositionId("P-123456"); var strategyId = new StrategyId("SCALPER", "001"); this.database.AddOrder(order, traderId, accountId, strategyId, positionId); // Act var result = this.database.AddOrder(order, traderId, accountId, strategyId, positionId); // Assert Assert.True(result.IsFailure); }
internal void ClearCaches_WithOrderInCaches_CorrectlyClearsCache() { // Arrange var order = new StubOrderBuilder().EntryOrder("O-123456").BuildMarketOrder(); var traderId = TraderId.FromString("TESTER-000"); var accountId = AccountId.FromString("NAUTILUS-000-SIMULATED"); var positionId = new PositionId("P-123456"); var strategyId = new StrategyId("SCALPER", "001"); this.database.AddOrder(order, traderId, accountId, strategyId, positionId); // Act this.database.ClearCaches(); // Assert Assert.Null(this.database.GetOrder(order.Id)); }
internal void AddBracketOrder_WhenStopLossOrderAlreadyExists_ReturnsFailureResult() { // Arrange var bracketOrder = StubBracketOrderProvider.Create(); var traderId = TraderId.FromString("TESTER-000"); var accountId = AccountId.FromString("NAUTILUS-000-SIMULATED"); var positionId = new PositionId("P-123456"); var strategyId = new StrategyId("SCALPER", "001"); this.database.AddOrder(bracketOrder.StopLoss, traderId, accountId, strategyId, positionId); // Act var result = this.database.AddBracketOrder(bracketOrder, traderId, accountId, strategyId, positionId); // Assert Assert.True(result.IsFailure); }
internal void UpdatePosition_WhenMultipleOrdersForPositionLeavingPositionOpen_CorrectlyUpdatesIndexes() { // Arrange var order1 = new StubOrderBuilder() .WithOrderId("O-123456-1") .BuildMarketOrder(); var order2 = new StubOrderBuilder() .WithOrderId("O-123456-2") .BuildMarketOrder(); var order3 = new StubOrderBuilder() .WithOrderId("O-123456-3") .BuildMarketOrder(); var traderId = TraderId.FromString("TESTER-000"); var accountId = AccountId.FromString("NAUTILUS-000-SIMULATED"); var strategyId = new StrategyId("SCALPER", "001"); var positionId = new PositionId("P-123456"); this.database.AddOrder(order1, traderId, accountId, strategyId, positionId); this.database.AddOrder(order2, traderId, accountId, strategyId, positionId); this.database.AddOrder(order3, traderId, accountId, strategyId, positionId); var position = new Position(positionId, StubEventMessageProvider.OrderFilledEvent(order1)); this.database.AddPosition(position); position.Apply(StubEventMessageProvider.OrderFilledEvent(order2)); this.database.UpdatePosition(position); // Act position.Apply(StubEventMessageProvider.OrderFilledEvent(order3)); this.database.UpdatePosition(position); // Assert Assert.Equal(position, this.database.GetPosition(positionId)); Assert.Contains(position.Id, this.database.GetPositionsOpen()); Assert.Contains(position.Id, this.database.GetPositionsOpen(traderId)); Assert.Contains(position.Id, this.database.GetPositionsOpen(traderId, strategyId)); Assert.Contains(position.Id, this.database.GetPositionIds()); Assert.Contains(position.Id, this.database.GetPositionOpenIds()); Assert.DoesNotContain(position.Id, this.database.GetPositionClosedIds()); }
internal void CanSerializeAndDeserialize_OrderExpiredEvents() { // Arrange var order = new StubOrderBuilder().BuildStopMarketOrder(); var expired = new OrderExpired( AccountId.FromString("FXCM-02851908-DEMO"), order.Id, StubZonedDateTime.UnixEpoch(), Guid.NewGuid(), StubZonedDateTime.UnixEpoch()); // Act var packed = this.serializer.Serialize(expired); var unpacked = (OrderExpired)this.serializer.Deserialize(packed); // Assert Assert.Equal(expired, unpacked); this.Output.WriteLine(Convert.ToBase64String(packed)); }
internal void GetOrders_WhenDoesNotExistInCache_ReturnsEmptyDictionary() { // Arrange var order = new StubOrderBuilder().EntryOrder("O-123456").BuildMarketOrder(); var traderId = TraderId.FromString("TESTER-000"); var accountId = AccountId.FromString("NAUTILUS-000-SIMULATED"); var positionId = new PositionId("P-123456"); var strategyId = new StrategyId("SCALPER", "001"); this.database.AddOrder(order, traderId, accountId, strategyId, positionId); // Act this.database.ClearCaches(); // Assert Assert.Empty(this.database.GetOrders()); Assert.Empty(this.database.GetOrders(traderId)); Assert.Empty(this.database.GetOrders(traderId, strategyId)); }