예제 #1
0
        internal void Ingest_MultipleTicksDifferentSymbols_CorrectlyAddsTicksToRepository()
        {
            // Arrange
            var audusd = StubInstrumentProvider.AUDUSD();
            var eurusd = StubInstrumentProvider.EURUSD();

            this.repository.Update(audusd);
            this.repository.Update(eurusd);

            var tick1 = StubQuoteTickProvider.Create(audusd.Symbol);
            var tick2 = StubQuoteTickProvider.Create(audusd.Symbol, StubZonedDateTime.UnixEpoch() + Duration.FromDays(1));
            var tick3 = StubQuoteTickProvider.Create(audusd.Symbol, StubZonedDateTime.UnixEpoch() + Duration.FromDays(2));
            var tick4 = StubQuoteTickProvider.Create(eurusd.Symbol, StubZonedDateTime.UnixEpoch());
            var tick5 = StubQuoteTickProvider.Create(eurusd.Symbol, StubZonedDateTime.UnixEpoch() + Duration.FromDays(1));

            // Act
            this.repository.Ingest(tick1);
            this.repository.Ingest(tick2);
            this.repository.Ingest(tick3);
            this.repository.Ingest(tick4);
            this.repository.Ingest(tick5);

            // Assert
            // TODO: System.InvalidCastException : Specified cast is not valid. (inside StackExchange.Redis)
            // Assert.Equal(3, this.repository.TicksCount(audusd.Symbol));
            // Assert.Equal(2, this.repository.TicksCount(eurusd.Symbol));
        }
예제 #2
0
        internal void GivenTickMessage_WithSubscriber_PublishesMessage()
        {
            // Arrange
            var symbol = new Symbol("AUDUSD", new Venue("FXCM"));

            var subscriber = new SubscriberSocket(TestAddress);

            subscriber.Connect(TestAddress);
            subscriber.Subscribe($"Quote:{symbol.Value}");

            Task.Delay(100).Wait();  // Allow subscribers to connect

            var tick = StubQuoteTickProvider.Create(symbol);

            // Act
            this.publisher.Endpoint.SendAsync(tick).Wait();

            var topic   = subscriber.ReceiveFrameBytes();
            var message = subscriber.ReceiveFrameBytes();

            // Assert
            Assert.Equal(1, this.publisher.SentCount);
            Assert.Equal("Quote:AUDUSD.FXCM", Encoding.UTF8.GetString(topic));
            Assert.Equal(tick.ToSerializableString(), Encoding.UTF8.GetString(message));

            // Tear Down
            subscriber.Disconnect(TestAddress);
            subscriber.Dispose();
            this.publisher.Stop().Wait();
            this.publisher.Dispose();
        }
예제 #3
0
        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));
        }
예제 #4
0
        internal void GivenData_WhenNoSubscribers_DoesNothing()
        {
            // Arrange
            var tick = StubQuoteTickProvider.Create(new Symbol("AUD/USD", new Venue("FXCM")));

            // Act
            this.dataBus.PostData(tick);
            this.dataBus.PostData(tick);
            this.dataBus.PostData(tick);
            this.dataBus.Stop().Wait();
            this.dataBus.StopData().Wait();

            // Assert
            Assert.Equal(0, this.dataBus.Subscriptions.Count);
        }
예제 #5
0
        [Fact] internal void Ingest_WithValidTick_AddsTickToRepository()
        {
            // Arrange
            var audusd = StubInstrumentProvider.AUDUSD();
            var tick   = StubQuoteTickProvider.Create(audusd.Symbol);

            this.repository.Update(audusd);

            // Act
            this.repository.Ingest(tick);

            // Assert
            // TODO: System.InvalidCastException : Specified cast is not valid. (inside StackExchange.Redis)
            // Assert.True(this.repository.TicksExist(audusd.Symbol));
            // Assert.Equal(1, this.repository.TicksCount(audusd.Symbol));
        }
예제 #6
0
        internal void GivenData_WhenSubscribers_SendsDataToSubscriber()
        {
            // Arrange
            var receiver2 = new MockComponent(this.container, "2");

            receiver2.RegisterHandler <Tick>(receiver2.OnMessage);

            var subscribe1 = new Subscribe <Type>(
                typeof(Tick),
                this.receiver.Mailbox,
                Guid.NewGuid(),
                StubZonedDateTime.UnixEpoch());

            var subscribe2 = new Subscribe <Type>(
                typeof(Tick),
                receiver2.Mailbox,
                Guid.NewGuid(),
                StubZonedDateTime.UnixEpoch());

            var tick1 = StubQuoteTickProvider.Create(new Symbol("AUD/USD", new Venue("FXCM")));
            var tick2 = StubQuoteTickProvider.Create(new Symbol("AUD/USD", new Venue("FXCM")), StubZonedDateTime.UnixEpoch() + Duration.FromSeconds(1));
            var tick3 = StubQuoteTickProvider.Create(new Symbol("AUD/USD", new Venue("FXCM")), StubZonedDateTime.UnixEpoch() + Duration.FromSeconds(2));

            // Act
            this.dataBus.Endpoint.SendAsync(subscribe1).Wait();
            this.dataBus.Endpoint.SendAsync(subscribe2).Wait();
            Task.Delay(100).Wait(); // Allow subscriptions

            this.dataBus.PostData(tick1);
            this.dataBus.PostData(tick2);
            this.dataBus.PostData(tick3);

            this.dataBus.Stop().Wait();
            this.dataBus.StopData().Wait();
            this.receiver.Stop().Wait();
            receiver2.Stop().Wait();

            // Assert
            Assert.Contains(tick1, this.receiver.Messages);
            Assert.Contains(tick2, this.receiver.Messages);
            Assert.Contains(tick3, this.receiver.Messages);
            Assert.Contains(tick1, receiver2.Messages);
            Assert.Contains(tick2, receiver2.Messages);
            Assert.Contains(tick3, receiver2.Messages);
            Assert.Equal(3, this.receiver.Messages.Count);
            Assert.Equal(3, receiver2.Messages.Count);
        }
예제 #7
0
        internal void GetTicks_WithOneTick_ReturnsCorrectTick()
        {
            // Arrange
            var audusd = StubInstrumentProvider.AUDUSD();

            this.repository.Update(audusd);

            var tick1 = StubQuoteTickProvider.Create(audusd.Symbol);

            this.repository.Ingest(tick1);

            // Act
            // var result = this.repository.GetTicks(audusd.Symbol, null, null, null);

            // Assert
            // TODO: System.InvalidCastException : Specified cast is not valid. (inside StackExchange.Redis)
            // Assert.Equal(1, this.repository.TicksCount(audusd.Symbol));
            // Assert.Single(result);
            // Assert.Equal(tick1, result[0]);
        }
예제 #8
0
        internal void GetTicks_WithToDateTime_ReturnsTickInRange()
        {
            // Arrange
            var audusd = StubInstrumentProvider.AUDUSD();

            this.repository.Update(audusd);

            var tick1 = StubQuoteTickProvider.Create(audusd.Symbol);
            var tick2 = StubQuoteTickProvider.Create(audusd.Symbol, StubZonedDateTime.UnixEpoch() + Duration.FromMilliseconds(1000));

            this.repository.Ingest(tick1);
            this.repository.Ingest(tick2);

            // Act
            // var result = this.repository.GetTicks(audusd.Symbol, null, StubZonedDateTime.UnixEpoch(), null);

            // Assert
            // TODO: System.InvalidCastException : Specified cast is not valid. (inside StackExchange.Redis)
            // Assert.Equal(2, this.repository.TicksCount(audusd.Symbol));
            // Assert.Single(result);
            // Assert.Equal(tick1, result[0]);
        }