def test_l3_feed():
    book = L3OrderBook(
        instrument_id=TestStubs.audusd_id(),
        price_precision=5,
        size_precision=0,
    )
    # Updates that cause the book to fail integrity checks will be deleted
    # immediately, but we may get also delete later.
    skip_deletes = []
    i = 0
    for i, m in enumerate(TestDataProvider.l3_feed()):  # noqa (B007)
        if m["op"] == "update":
            book.update(order=m["order"])
            try:
                book.check_integrity()
            except AssertionError:
                book.delete(order=m["order"])
                skip_deletes.append(m["order"].id)
        elif m["op"] == "delete" and m["order"].id not in skip_deletes:
            book.delete(order=m["order"])
        book.check_integrity()
    assert i == 100_047
    assert book.best_ask_level().price == 61405.27923706
    assert book.best_ask_level().volume() == 0.12227
    assert book.best_bid_level().price == Price.from_int(61391)
    assert book.best_bid_level().volume() == 1
Exemplo n.º 2
0
    def test_from_int_returns_expected_value(self):
        # Arrange, Act
        price = Price.from_int(100)

        # Assert
        assert str(price) == "100"
        assert price.precision == 0
Exemplo n.º 3
0
def price_to_probability(price: str) -> Price:
    PyCondition.type(price, str, "price", "str")
    PyCondition.positive(float(price), "price")
    price = Price.from_str(price)
    if price in BETFAIR_PRICE_TO_PROBABILITY_MAP:
        return BETFAIR_PRICE_TO_PROBABILITY_MAP[price]
    else:
        # This is likely a trade tick that has been currency adjusted, simply return the nearest price
        value = Price.from_int(1) / price
        bid = BETFAIR_TICK_SCHEME.next_bid_price(value=value)
        ask = BETFAIR_TICK_SCHEME.next_ask_price(value=value)
        if abs(bid - value) < abs(ask - value):
            return bid
        else:
            return ask
Exemplo n.º 4
0
    def test_update_order(self):
        # Arrange
        instrument = IBTestStubs.instrument("AAPL")
        contract_details = IBTestStubs.contract_details("AAPL")
        contract = contract_details.contract
        order = IBTestStubs.create_order()
        self.instrument_setup(instrument=instrument,
                              contract_details=contract_details)
        self.exec_client._ib_insync_orders[
            TestIdStubs.client_order_id()] = Trade(contract=contract,
                                                   order=order)

        # Act
        command = TestCommandStubs.modify_order_command(
            instrument_id=instrument.id,
            price=Price.from_int(10),
            quantity=Quantity.from_str("100"),
        )
        with patch.object(self.exec_client._client, "placeOrder") as mock:
            self.exec_client.modify_order(command=command)

        # Assert
        expected = {
            "contract":
            Contract(
                secType="STK",
                conId=265598,
                symbol="AAPL",
                exchange="SMART",
                primaryExchange="NASDAQ",
                currency="USD",
                localSymbol="AAPL",
                tradingClass="NMS",
            ),
            "order":
            LimitOrder(action="BUY", totalQuantity=100, lmtPrice=10.0),
        }
        name, args, kwargs = mock.mock_calls[0]
        # Can't directly compare kwargs for some reason?
        assert kwargs["contract"] == expected["contract"]
        assert kwargs["order"].action == expected["order"].action
        assert kwargs["order"].totalQuantity == expected["order"].totalQuantity
        assert kwargs["order"].lmtPrice == expected["order"].lmtPrice
Exemplo n.º 5
0
    def test_submit_limit_order_aggressive_multiple_levels(self):
        # Arrange: Prepare market
        self.cache.add_instrument(USDJPY_SIM)

        quote = QuoteTick(
            instrument_id=USDJPY_SIM.id,
            bid=Price.from_str("110.000"),
            ask=Price.from_str("110.010"),
            bid_size=Quantity.from_int(1500000),
            ask_size=Quantity.from_int(1500000),
            ts_event=0,
            ts_init=0,
        )
        self.data_engine.process(quote)
        snapshot = TestDataStubs.order_book_snapshot(
            instrument_id=USDJPY_SIM.id,
            bid_volume=1000,
            ask_volume=1000,
        )
        self.data_engine.process(snapshot)
        self.exchange.process_order_book(snapshot)

        # Create order
        order = self.strategy.order_factory.limit(
            instrument_id=USDJPY_SIM.id,
            order_side=OrderSide.BUY,
            quantity=Quantity.from_int(2000),
            price=Price.from_int(20),
            post_only=False,
        )

        # Act
        self.strategy.submit_order(order)
        self.exchange.process(0)

        # Assert
        assert order.status == OrderStatus.FILLED
        assert order.filled_qty == Decimal("2000.0")  # No slippage
        assert order.avg_px == Decimal("15.33333333333333333333333333")
        assert self.exchange.get_account().balance_total(USD) == Money(
            999999.96, USD)
Exemplo n.º 6
0
    def test_pnl_calculation_from_trading_technologies_example(self):
        # https://www.tradingtechnologies.com/xtrader-help/fix-adapter-reference/pl-calculation-algorithm/understanding-pl-calculations/  # noqa

        # Arrange
        order1 = self.order_factory.market(
            ETHUSDT_BINANCE.id,
            OrderSide.BUY,
            Quantity.from_int(12),
        )

        order2 = self.order_factory.market(
            ETHUSDT_BINANCE.id,
            OrderSide.BUY,
            Quantity.from_int(17),
        )

        order3 = self.order_factory.market(
            ETHUSDT_BINANCE.id,
            OrderSide.SELL,
            Quantity.from_int(9),
        )

        order4 = self.order_factory.market(
            ETHUSDT_BINANCE.id,
            OrderSide.SELL,
            Quantity.from_int(4),
        )

        order5 = self.order_factory.market(
            ETHUSDT_BINANCE.id,
            OrderSide.BUY,
            Quantity.from_int(3),
        )

        # Act
        fill1 = TestStubs.event_order_filled(
            order1,
            instrument=ETHUSDT_BINANCE,
            position_id=PositionId("P-19700101-000000-000-001-1"),
            last_px=Price.from_int(100),
        )

        position = Position(instrument=ETHUSDT_BINANCE, fill=fill1)

        fill2 = TestStubs.event_order_filled(
            order2,
            instrument=ETHUSDT_BINANCE,
            position_id=PositionId("P-19700101-000000-000-001-1"),
            last_px=Price.from_int(99),
        )

        position.apply(fill2)
        self.assertEqual(Quantity.from_int(29), position.quantity)
        self.assertEqual(Money(-0.28830000, USDT), position.realized_pnl)
        self.assertEqual(Decimal("99.41379310344827586206896552"),
                         position.avg_px_open)

        fill3 = TestStubs.event_order_filled(
            order3,
            instrument=ETHUSDT_BINANCE,
            position_id=PositionId("P-19700101-000000-000-001-1"),
            strategy_id=StrategyId("S-001"),
            last_px=Price.from_int(101),
        )

        position.apply(fill3)
        self.assertEqual(Quantity.from_int(20), position.quantity)
        self.assertEqual(Money(13.89666207, USDT), position.realized_pnl)
        self.assertEqual(Decimal("99.41379310344827586206896552"),
                         position.avg_px_open)

        fill4 = TestStubs.event_order_filled(
            order4,
            instrument=ETHUSDT_BINANCE,
            position_id=PositionId("P-19700101-000000-000-001-1"),
            strategy_id=StrategyId("S-001"),
            last_px=Price.from_int(105),
        )

        position.apply(fill4)
        self.assertEqual(Quantity.from_int(16), position.quantity)
        self.assertEqual(Money(36.19948966, USDT), position.realized_pnl)
        self.assertEqual(Decimal("99.41379310344827586206896552"),
                         position.avg_px_open)

        fill5 = TestStubs.event_order_filled(
            order5,
            instrument=ETHUSDT_BINANCE,
            position_id=PositionId("P-19700101-000000-000-001-1"),
            strategy_id=StrategyId("S-001"),
            last_px=Price.from_int(103),
        )

        position.apply(fill5)
        self.assertEqual(Quantity.from_int(19), position.quantity)
        self.assertEqual(Money(36.16858966, USDT), position.realized_pnl)
        self.assertEqual(Decimal("99.98003629764065335753176042"),
                         position.avg_px_open)
        self.assertEqual(
            "Position(LONG 19.00000 ETH/USDT.BINANCE, id=P-19700101-000000-000-001-1)",
            repr(position),
        )
Exemplo n.º 7
0
    (2, 3, 0.02),
    (3, 4, 0.05),
    (4, 6, 0.1),
    (6, 10, 0.2),
    (10, 20, 0.5),
    (20, 30, 1),
    (30, 50, 2),
    (50, 100, 5),
    (100, 1010, 10),
]
BETFAIR_PRICES = list(
    reversed(
        TieredTickScheme(name="betfair_prob",
                         tiers=BETFAIR_PRICE_TIERS).ticks))
BETFAIR_PROBABILITIES = [
    Price(Price.from_int(1) / tick, precision=BETFAIR_PRICE_PRECISION)
    for tick in BETFAIR_PRICES
]
BETFAIR_PRICE_TO_PROBABILITY_MAP = {
    price: prob
    for price, prob in zip(BETFAIR_PRICES, BETFAIR_PROBABILITIES)
}
BETFAIR_PROBABILITY_TO_PRICE_MAP = {
    price: prob
    for price, prob in zip(BETFAIR_PROBABILITIES, BETFAIR_PRICES)
}
MAX_BET_PROB = max(BETFAIR_PROBABILITY_TO_PRICE_MAP)
MIN_BET_PROB = min(BETFAIR_PROBABILITY_TO_PRICE_MAP)

BETFAIR_TICK_SCHEME = TieredTickScheme(
    name="BETFAIR",