Esempio n. 1
0
        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());
        }
Esempio n. 2
0
        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));
        }
Esempio n. 3
0
        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));
        }
Esempio n. 4
0
        internal void IsComplete_OrderPartiallyFilled_ReturnsFalse()
        {
            // Arrange
            var order = new StubOrderBuilder()
                        .WithQuantity(Quantity.Create(100000))
                        .BuildStopMarketOrder();

            var event1 = StubEventMessageProvider.OrderSubmittedEvent(order);
            var event2 = StubEventMessageProvider.OrderAcceptedEvent(order);
            var event3 = StubEventMessageProvider.OrderWorkingEvent(order, order.Price);
            var event4 = StubEventMessageProvider.OrderPartiallyFilledEvent(
                order,
                Quantity.Create(50000),
                Quantity.Create(50000),
                order.Price);

            order.Apply(event1);
            order.Apply(event2);
            order.Apply(event3);
            order.Apply(event4);

            // Act
            var result = order.IsCompleted;

            // Assert
            Assert.True(order.State == OrderState.PartiallyFilled);
            Assert.False(result);
        }
Esempio n. 5
0
        internal void GetSlippage_SellOrderFilledVariousAveragePrices_ReturnsExpectedResult(decimal averagePrice, decimal expectedSlippage)
        {
            // Arrange
            var order = new StubOrderBuilder()
                        .WithOrderSide(OrderSide.Sell)
                        .WithPrice(Price.Create(1.20000m, 5))
                        .BuildStopMarketOrder();

            var event1 = StubEventMessageProvider.OrderSubmittedEvent(order);
            var event2 = StubEventMessageProvider.OrderAcceptedEvent(order);
            var event3 = StubEventMessageProvider.OrderWorkingEvent(order, order.Price);
            var event4 = StubEventMessageProvider.OrderFilledEvent(order, Price.Create(averagePrice, 5));

            order.Apply(event1);
            order.Apply(event2);
            order.Apply(event3);
            order.Apply(event4);

            // Act
            var result = order.Slippage;

            // Assert
            Assert.Equal(OrderState.Filled, order.State);
            Assert.Equal(expectedSlippage, result);
        }
Esempio n. 6
0
        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));
        }
Esempio n. 7
0
        internal void Apply_OrderPartiallyFilled_ReturnsCorrectOrderStatus()
        {
            // Arrange
            var order = new StubOrderBuilder().BuildStopMarketOrder();

            var event1 = StubEventMessageProvider.OrderSubmittedEvent(order);
            var event2 = StubEventMessageProvider.OrderAcceptedEvent(order);
            var event3 = StubEventMessageProvider.OrderWorkingEvent(order, order.Price);
            var event4 = StubEventMessageProvider.OrderPartiallyFilledEvent(
                order,
                order.Quantity,
                Quantity.Create(order.Quantity / 2),
                order.Price);

            // Act
            order.Apply(event1);
            order.Apply(event2);
            order.Apply(event3);
            order.Apply(event4);

            var result = order.State;

            // Assert
            Assert.Equal(OrderState.PartiallyFilled, result);
        }
Esempio n. 8
0
        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());
        }
Esempio n. 9
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));
        }
Esempio n. 10
0
        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);
        }
Esempio n. 11
0
        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);
        }
Esempio n. 12
0
        internal void OnAccountStateEvent_UpdatesAccountSendsToPublisher()
        {
            // Arrange
            var @event = StubEventMessageProvider.AccountStateEvent();

            // Act
            this.engine.Endpoint.SendAsync(@event).Wait();
            this.engine.Endpoint.SendAsync(@event).Wait();
            Task.Delay(100).Wait();  // Buffer to avoid intermittent tests

            // Assert
            Assert.Null(this.engine.UnhandledMessages.FirstOrDefault());
            Assert.Equal(3, this.engine.ProcessedCount);
            Assert.Equal(0, this.engine.CommandCount);
            Assert.Equal(2, this.engine.EventCount);
            Assert.Equal(2, this.receiver.Messages.Count);
        }
Esempio n. 13
0
        internal void Rejected_ParametersValid_ReturnsExpectedResult()
        {
            // Arrange
            var order = new StubOrderBuilder().BuildStopMarketOrder();

            var event1 = StubEventMessageProvider.OrderSubmittedEvent(order);
            var event2 = StubEventMessageProvider.OrderRejectedEvent(order);

            // Act
            order.Apply(event1);
            order.Apply(event2);

            // Assert
            Assert.Equal(3, order.EventCount);
            Assert.Equal(OrderState.Rejected, order.State);
            Assert.Equal(StubZonedDateTime.UnixEpoch(), order.LastEvent.Timestamp);
        }
Esempio n. 14
0
        internal void Test_can_publish_events()
        {
            // Arrange
            const string testAddress = "tcp://127.0.0.1:56601";

            var publisher = new EventPublisher(
                this.container,
                new MsgPackEventSerializer(),
                new BypassCompressor(),
                EncryptionSettings.None(),
                new Label("test-publisher"),
                new Port(56601));

            publisher.Start().Wait();

            var subscriber = new SubscriberSocket(testAddress);

            subscriber.Connect(testAddress);
            subscriber.Subscribe("Event:Trade:TESTER-001");

            Task.Delay(100).Wait(); // Allow socket to subscribe

            var serializer = new MsgPackEventSerializer();
            var order      = new StubOrderBuilder().BuildMarketOrder();
            var rejected   = StubEventMessageProvider.OrderRejectedEvent(order);
            var tradeEvent = new TradeEvent(TraderId.FromString("TESTER-001"), rejected);

            // Act
            publisher.Endpoint.Send(tradeEvent);
            this.Output.WriteLine("Waiting for published events...");

            var topic   = subscriber.ReceiveFrameBytes();
            var message = subscriber.ReceiveFrameBytes();
            var @event  = serializer.Deserialize(message);

            // Assert
            Assert.Equal("Event:Trade:TESTER-001", Encoding.UTF8.GetString(topic));
            Assert.Equal(typeof(OrderRejected), @event.GetType());

            // Tear Down
            subscriber.Disconnect(testAddress);
            subscriber.Dispose();
            publisher.Stop().Wait();
            publisher.Dispose();
        }
Esempio n. 15
0
        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());
        }
Esempio n. 16
0
        internal void Apply_OrderFilled_ReturnsCorrectOrderStatus()
        {
            // Arrange
            var order = new StubOrderBuilder().BuildStopMarketOrder();

            var event1 = StubEventMessageProvider.OrderSubmittedEvent(order);
            var event2 = StubEventMessageProvider.OrderAcceptedEvent(order);
            var event3 = StubEventMessageProvider.OrderWorkingEvent(order, order.Price);
            var event4 = StubEventMessageProvider.OrderFilledEvent(order, order.Price);

            // Act
            order.Apply(event1);
            order.Apply(event2);
            order.Apply(event3);
            order.Apply(event4);

            // Assert
            Assert.Equal(OrderState.Filled, order.State);
        }
Esempio n. 17
0
        internal void IsComplete_OrderWorking_ReturnsFalse()
        {
            // Arrange
            var order = new StubOrderBuilder().BuildStopMarketOrder();

            var event1 = StubEventMessageProvider.OrderSubmittedEvent(order);
            var event2 = StubEventMessageProvider.OrderAcceptedEvent(order);
            var event3 = StubEventMessageProvider.OrderWorkingEvent(order);

            // Act
            order.Apply(event1);
            order.Apply(event2);
            order.Apply(event3);

            var result = order.IsCompleted;

            // Assert
            Assert.False(result);
        }
Esempio n. 18
0
        internal void Working_ParametersValid_ReturnsExpectedResult()
        {
            // Arrange
            var order = new StubOrderBuilder().BuildStopMarketOrder();

            var event1 = StubEventMessageProvider.OrderSubmittedEvent(order);
            var event2 = StubEventMessageProvider.OrderAcceptedEvent(order);
            var event3 = StubEventMessageProvider.OrderWorkingEvent(order, order.Price);

            // Act
            order.Apply(event1);
            order.Apply(event2);
            order.Apply(event3);

            // Assert
            Assert.Equal("BO-123456", order.IdBroker?.Value);
            Assert.Equal(4, order.EventCount);
            Assert.Equal(OrderState.Working, order.State);
            Assert.Equal(StubZonedDateTime.UnixEpoch(), order.LastEvent.Timestamp);
        }
Esempio n. 19
0
        internal void AddPosition_WhenPositionAlreadyExists_ReturnsFailureResult()
        {
            // 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.OrderFilledEvent(order));

            this.database.AddPosition(position);

            // Act
            var result = this.database.AddPosition(position);

            // Assert
            Assert.True(result.IsFailure);
        }
        internal void LoadOrdersCache_WhenOrdersInDatabase_CorrectlyCachesOrders()
        {
            // Arrange
            var order1     = new StubOrderBuilder().EntryOrder("O-123456-1").BuildStopMarketOrder();
            var order2     = new StubOrderBuilder().EntryOrder("O-123456-2").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");

            this.database.AddOrder(order1, traderId, accountId, strategyId, positionId);
            this.database.AddOrder(order2, traderId, accountId, strategyId, positionId);

            order2.Apply(StubEventMessageProvider.OrderSubmittedEvent(order2));
            this.database.UpdateOrder(order2);

            order2.Apply(StubEventMessageProvider.OrderAcceptedEvent(order2));
            this.database.UpdateOrder(order2);

            order2.Apply(StubEventMessageProvider.OrderWorkingEvent(order2));
            this.database.UpdateOrder(order2);

            order2.Apply(StubEventMessageProvider.OrderCancelledEvent(order2));
            this.database.UpdateOrder(order2);

            this.database.ClearCaches();

            // Act
            this.database.LoadOrdersCache();

            // Assert
            Assert.Equal(order1, this.database.GetOrders()[order1.Id]);
            Assert.Equal(order2, this.database.GetOrders()[order2.Id]);
            Assert.Equal(1, this.database.GetOrders()[order1.Id].EventCount);
            Assert.Equal(5, this.database.GetOrders()[order2.Id].EventCount);
            Assert.Equal(OrderState.Initialized, this.database.GetOrders()[order1.Id].State);
            Assert.Equal(OrderState.Cancelled, this.database.GetOrders()[order2.Id].State);
        }