def test_handle_trade_tick_when_volume_at_threshold_sends_bar_to_handler(
            self):
        # Arrange
        bar_store = ObjectStorer()
        handler = bar_store.store
        instrument = AUDUSD_SIM
        bar_spec = BarSpecification(10000, BarAggregation.VOLUME,
                                    PriceType.LAST)
        bar_type = BarType(instrument.id, bar_spec)
        aggregator = VolumeBarAggregator(
            instrument,
            bar_type,
            handler,
            Logger(TestClock()),
        )

        tick1 = TradeTick(
            instrument_id=instrument.id,
            price=Price.from_str("1.00001"),
            size=Quantity.from_int(3000),
            aggressor_side=AggressorSide.BUY,
            trade_id=TradeId("123456"),
            ts_event=0,
            ts_init=0,
        )

        tick2 = TradeTick(
            instrument_id=instrument.id,
            price=Price.from_str("1.00002"),
            size=Quantity.from_int(4000),
            aggressor_side=AggressorSide.BUY,
            trade_id=TradeId("123457"),
            ts_event=0,
            ts_init=0,
        )

        tick3 = TradeTick(
            instrument_id=instrument.id,
            price=Price.from_str("1.00000"),
            size=Quantity.from_int(3000),
            aggressor_side=AggressorSide.BUY,
            trade_id=TradeId("123458"),
            ts_event=0,
            ts_init=0,
        )

        # Act
        aggregator.handle_trade_tick(tick1)
        aggregator.handle_trade_tick(tick2)
        aggregator.handle_trade_tick(tick3)

        # Assert
        assert len(bar_store.get_store()) == 1
        assert bar_store.get_store()[0].open == Price.from_str("1.00001")
        assert bar_store.get_store()[0].high == Price.from_str("1.00002")
        assert bar_store.get_store()[0].low == Price.from_str("1.00000")
        assert bar_store.get_store()[0].close == Price.from_str("1.00000")
        assert bar_store.get_store()[0].volume == Quantity.from_int(10000)
Beispiel #2
0
    def test_position_filled_with_buy_order_returns_expected_attributes(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        fill = TestEventStubs.order_filled(
            order,
            instrument=AUDUSD_SIM,
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S-001"),
            last_px=Price.from_str("1.00001"),
        )

        last = Price.from_str("1.00050")

        # Act
        position = Position(instrument=AUDUSD_SIM, fill=fill)

        # Assert
        assert position.symbol == AUDUSD_SIM.id.symbol
        assert position.venue == AUDUSD_SIM.id.venue
        assert not position.is_opposite_side(fill.order_side)
        assert not position != position  # Equality operator test
        assert position.from_order == ClientOrderId(
            "O-19700101-000000-000-001-1")
        assert position.quantity == Quantity.from_int(100000)
        assert position.peak_qty == Quantity.from_int(100000)
        assert position.entry == OrderSide.BUY
        assert position.side == PositionSide.LONG
        assert position.ts_opened == 0
        assert position.duration_ns == 0
        assert position.avg_px_open == Decimal("1.00001")
        assert position.event_count == 1
        assert position.client_order_ids == [order.client_order_id]
        assert position.venue_order_ids == [VenueOrderId("1")]
        assert position.trade_ids == [TradeId("E-19700101-000000-000-001-1")]
        assert position.last_trade_id == TradeId("E-19700101-000000-000-001-1")
        assert position.id == PositionId("P-123456")
        assert len(position.events) == 1
        assert position.is_long
        assert not position.is_short
        assert position.is_open
        assert not position.is_closed
        assert position.realized_points == 0
        assert position.realized_return == 0
        assert position.realized_pnl == Money(-2.00, USD)
        assert position.unrealized_pnl(last) == Money(49.00, USD)
        assert position.total_pnl(last) == Money(47.00, USD)
        assert position.commissions() == [Money(2.00, USD)]
        assert repr(
            position) == "Position(LONG 100_000 AUD/USD.SIM, id=P-123456)"
Beispiel #3
0
    def test_position_partial_fills_with_sell_order_returns_expected_attributes(
            self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.SELL,
            Quantity.from_int(100000),
        )

        fill1 = TestEventStubs.order_filled(
            order,
            instrument=AUDUSD_SIM,
            trade_id=TradeId("1"),
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S-001"),
            last_px=Price.from_str("1.00001"),
            last_qty=Quantity.from_int(50000),
        )

        fill2 = TestEventStubs.order_filled(
            order,
            instrument=AUDUSD_SIM,
            trade_id=TradeId("2"),
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S-001"),
            last_px=Price.from_str("1.00002"),
            last_qty=Quantity.from_int(50000),
        )

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

        last = Price.from_str("1.00050")

        # Act
        position.apply(fill2)

        # Assert
        assert position.quantity == Quantity.from_int(100000)
        assert position.side == PositionSide.SHORT
        assert position.ts_opened == 0
        assert position.avg_px_open == Decimal("1.000015")
        assert position.event_count == 2
        assert not position.is_long
        assert position.is_short
        assert position.is_open
        assert not position.is_closed
        assert position.realized_points == 0
        assert position.realized_return == 0
        assert position.realized_pnl == Money(-4.00, USD)
        assert position.unrealized_pnl(last) == Money(-48.50, USD)
        assert position.total_pnl(last) == Money(-52.50, USD)
        assert position.commissions() == [Money(4.00, USD)]
        assert repr(
            position) == "Position(SHORT 100_000 AUD/USD.SIM, id=P-123456)"
def nautilus_objects() -> List[Any]:
    """A list of nautilus instances for testing serialization"""
    instrument = TestInstrumentProvider.default_fx_ccy("AUD/USD")
    position_id = PositionId("P-001")
    buy = TestExecStubs.limit_order()
    buy_submitted, buy_accepted, buy_filled = _make_order_events(
        buy,
        instrument=instrument,
        position_id=position_id,
        trade_id=TradeId("BUY"),
    )
    sell = TestExecStubs.limit_order(order_side=OrderSide.SELL)
    _, _, sell_filled = _make_order_events(
        sell,
        instrument=instrument,
        position_id=position_id,
        trade_id=TradeId("SELL"),
    )
    open_position = Position(instrument=instrument, fill=buy_filled)
    closed_position = Position(instrument=instrument, fill=buy_filled)
    closed_position.apply(sell_filled)

    return [
        TestDataStubs.ticker(),
        TestDataStubs.quote_tick_5decimal(),
        TestDataStubs.trade_tick_5decimal(),
        TestDataStubs.bar_5decimal(),
        TestDataStubs.venue_status_update(),
        TestDataStubs.instrument_status_update(),
        TestEventStubs.component_state_changed(),
        TestEventStubs.trading_state_changed(),
        TestEventStubs.betting_account_state(),
        TestEventStubs.cash_account_state(),
        TestEventStubs.margin_account_state(),
        # ORDERS
        TestEventStubs.order_accepted(buy),
        TestEventStubs.order_rejected(buy),
        TestEventStubs.order_pending_update(buy_accepted),
        TestEventStubs.order_pending_cancel(buy_accepted),
        TestEventStubs.order_filled(
            order=buy,
            instrument=instrument,
            position_id=open_position.id,
        ),
        TestEventStubs.order_canceled(buy_accepted),
        TestEventStubs.order_expired(buy),
        TestEventStubs.order_triggered(buy),
        # POSITIONS
        TestEventStubs.position_opened(open_position),
        TestEventStubs.position_changed(open_position),
        TestEventStubs.position_closed(closed_position),
    ]
    def test_add_trade_reports(self):
        report_id1 = UUID4()
        mass_status = ExecutionMassStatus(
            client_id=ClientId("IB"),
            account_id=AccountId("IB", "U123456789"),
            venue=Venue("IDEALPRO"),
            report_id=report_id1,
            ts_init=0,
        )

        report_id2 = UUID4()
        report1 = TradeReport(
            account_id=AccountId("IB", "U123456789"),
            instrument_id=AUDUSD_IDEALPRO,
            client_order_id=ClientOrderId("O-123456789"),
            venue_order_id=VenueOrderId("1"),
            venue_position_id=PositionId("2"),
            trade_id=TradeId("3"),
            order_side=OrderSide.BUY,
            last_qty=Quantity.from_int(100),
            last_px=Price.from_str("100.50"),
            commission=Money("4.50", USD),
            liquidity_side=LiquiditySide.TAKER,
            report_id=report_id2,
            ts_event=0,
            ts_init=0,
        )

        report_id3 = UUID4()
        report2 = TradeReport(
            account_id=AccountId("IB", "U123456789"),
            instrument_id=AUDUSD_IDEALPRO,
            client_order_id=ClientOrderId("O-123456790"),
            venue_order_id=VenueOrderId("1"),
            venue_position_id=PositionId("2"),
            trade_id=TradeId("4"),
            order_side=OrderSide.BUY,
            last_qty=Quantity.from_int(100),
            last_px=Price.from_str("100.60"),
            commission=Money("4.50", USD),
            liquidity_side=LiquiditySide.TAKER,
            report_id=report_id3,
            ts_event=0,
            ts_init=0,
        )

        # Act
        mass_status.add_trade_reports([report1, report2])

        # Assert
        assert mass_status.trade_reports()[VenueOrderId("1")] == [report1, report2]
Beispiel #6
0
    def test_passive_fill_on_trade_tick(self):
        # Arrange: Prepare market
        # Market is 10 @ 15
        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)

        order = self.strategy.order_factory.limit(
            instrument_id=USDJPY_SIM.id,
            order_side=OrderSide.SELL,
            quantity=Quantity.from_int(2000),
            price=Price.from_str("14"),
            post_only=False,
        )
        self.strategy.submit_order(order)

        # Act
        tick1 = TradeTick(
            instrument_id=USDJPY_SIM.id,
            price=Price.from_str("14.0"),
            size=Quantity.from_int(1000),
            aggressor_side=AggressorSide.SELL,
            trade_id=TradeId("123456789"),
            ts_event=0,
            ts_init=0,
        )
        self.exchange.process_tick(tick1)

        # Assert
        assert order.status == OrderStatus.PARTIALLY_FILLED
        assert order.filled_qty == Quantity.from_int(1000.0)  # No slippage
        assert order.avg_px == Decimal("14.0")
Beispiel #7
0
    async def test_subscribe_trade_ticks(self, monkeypatch):
        handler = []
        self.msgbus.subscribe(
            topic="data.trades.BINANCE.ETHUSDT",
            handler=handler.append,
        )

        # Act
        self.data_client.subscribe_trade_ticks(ETHUSDT_BINANCE.id)

        raw_trade = pkgutil.get_data(
            package="tests.integration_tests.adapters.binance.resources.ws_messages",
            resource="ws_spot_trade.json",
        )

        # Assert
        self.data_client._handle_ws_message(raw_trade)
        await asyncio.sleep(1)

        assert self.data_engine.data_count == 1
        assert len(handler) == 1  # <-- handler received tick
        assert handler[0] == TradeTick(
            instrument_id=ETHUSDT_BINANCE.id,
            price=Price.from_str("4149.74000000"),
            size=Quantity.from_str("0.43870000"),
            aggressor_side=AggressorSide.SELL,
            trade_id=TradeId("705291099"),
            ts_event=1639351062243000064,
            ts_init=handler[0].ts_init,
        )
Beispiel #8
0
def parse_trade_report_http(
    account_id: AccountId,
    instrument_id: InstrumentId,
    data: BinanceFuturesAccountTrade,
    report_id: UUID4,
    ts_init: int,
) -> TradeReport:
    return TradeReport(
        account_id=account_id,
        instrument_id=instrument_id,
        venue_order_id=VenueOrderId(str(data.orderId)),
        venue_position_id=PositionId(
            f"{instrument_id}-{data.positionSide.value}"),
        trade_id=TradeId(str(data.id)),
        order_side=OrderSide[data.side.value],
        last_qty=Quantity.from_str(data.qty),
        last_px=Price.from_str(data.price),
        commission=Money(data.commission,
                         Currency.from_str(data.commissionAsset)),
        liquidity_side=LiquiditySide.MAKER
        if data.maker else LiquiditySide.TAKER,
        report_id=report_id,
        ts_event=millis_to_nanos(data.time),
        ts_init=ts_init,
    )
    def test_handle_trade_tick_when_value_below_threshold_updates(self):
        # Arrange
        bar_store = ObjectStorer()
        handler = bar_store.store
        instrument_id = TestIdStubs.audusd_id()
        bar_spec = BarSpecification(100000, BarAggregation.VALUE,
                                    PriceType.LAST)
        bar_type = BarType(instrument_id, bar_spec)
        aggregator = ValueBarAggregator(
            AUDUSD_SIM,
            bar_type,
            handler,
            Logger(TestClock()),
        )

        tick1 = TradeTick(
            instrument_id=AUDUSD_SIM.id,
            price=Price.from_str("15000.00"),
            size=Quantity.from_str("3.5"),
            aggressor_side=AggressorSide.BUY,
            trade_id=TradeId("123456"),
            ts_event=0,
            ts_init=0,
        )

        # Act
        aggregator.handle_trade_tick(tick1)

        # Assert
        assert len(bar_store.get_store()) == 0
        assert aggregator.get_cumulative_value() == Decimal("52500.000")
Beispiel #10
0
    def test_data_catalog_instrument_ids_correctly_unmapped(self):
        # Arrange
        catalog = DataCatalog.from_env()
        instrument = TestInstrumentProvider.default_fx_ccy("AUD/USD",
                                                           venue=Venue("SIM"))
        trade_tick = TradeTick(
            instrument_id=instrument.id,
            price=Price.from_str("2.0"),
            size=Quantity.from_int(10),
            aggressor_side=AggressorSide.UNKNOWN,
            trade_id=TradeId("1"),
            ts_event=0,
            ts_init=0,
        )
        write_objects(catalog=catalog, chunk=[instrument, trade_tick])

        # Act
        instrument = catalog.instruments(instrument_ids=["AUD/USD.SIM"],
                                         as_nautilus=True)[0]
        trade_tick = catalog.trade_ticks(instrument_ids=["AUD/USD.SIM"],
                                         as_nautilus=True)[0]

        # Assert
        assert instrument.id.value == "AUD/USD.SIM"
        assert trade_tick.instrument_id.value == "AUD/USD.SIM"
async def generate_trades_list(
        self,
        venue_order_id: VenueOrderId,
        symbol: Symbol,
        since: datetime = None  # type: ignore
) -> List[TradeReport]:
    filled = self.client().betting.list_cleared_orders(
        bet_ids=[venue_order_id], )
    if not filled["clearedOrders"]:
        self._log.warn(f"Found no existing order for {venue_order_id}")
        return []
    fill = filled["clearedOrders"][0]
    ts_event = int(pd.Timestamp(fill["lastMatchedDate"]).to_datetime64())
    return [
        TradeReport(
            client_order_id=self.
            venue_order_id_to_client_order_id[venue_order_id],
            venue_order_id=VenueOrderId(fill["betId"]),
            venue_position_id=None,  # Can be None
            trade_id=TradeId(fill["lastMatchedDate"]),
            last_qty=Quantity.from_str(str(
                fill["sizeSettled"])),  # TODO: Incorrect precision?
            last_px=Price.from_str(str(
                fill["priceMatched"])),  # TODO: Incorrect precision?
            commission=None,  # Can be None
            liquidity_side=LiquiditySide.NONE,
            ts_event=ts_event,
            ts_init=ts_event,
        )
    ]
    def test_handle_trade_tick_when_volume_below_threshold_updates(self):
        # Arrange
        bar_store = ObjectStorer()
        handler = bar_store.store
        instrument = AUDUSD_SIM
        bar_spec = BarSpecification(10000, BarAggregation.VOLUME,
                                    PriceType.LAST)
        bar_type = BarType(instrument.id, bar_spec)
        aggregator = VolumeBarAggregator(
            instrument,
            bar_type,
            handler,
            Logger(TestClock()),
        )

        tick1 = TradeTick(
            instrument_id=instrument.id,
            price=Price.from_str("1.00001"),
            size=Quantity.from_int(1),
            aggressor_side=AggressorSide.BUY,
            trade_id=TradeId("123456"),
            ts_event=0,
            ts_init=0,
        )

        # Act
        aggregator.handle_trade_tick(tick1)

        # Assert
        assert len(bar_store.get_store()) == 0
Beispiel #13
0
    def test_to_dict_returns_expected_dict(self):
        # Arrange
        tick = TradeTick(
            instrument_id=AUDUSD_SIM.id,
            price=Price.from_str("1.00000"),
            size=Quantity.from_int(10000),
            aggressor_side=AggressorSide.BUY,
            trade_id=TradeId("123456789"),
            ts_event=0,
            ts_init=0,
        )

        # Act
        result = TradeTick.to_dict(tick)

        # Assert
        assert result == {
            "type": "TradeTick",
            "instrument_id": "AUD/USD.SIM",
            "price": "1.00000",
            "size": "10000",
            "aggressor_side": "BUY",
            "trade_id": "123456789",
            "ts_event": 0,
            "ts_init": 0,
        }
    def test_instantiate_trade_report(self):
        # Arrange, Act
        report_id = UUID4()
        report = TradeReport(
            account_id=AccountId("SIM", "001"),
            instrument_id=AUDUSD_IDEALPRO,
            client_order_id=ClientOrderId("O-123456789"),
            venue_order_id=VenueOrderId("1"),
            venue_position_id=PositionId("2"),
            trade_id=TradeId("3"),
            order_side=OrderSide.BUY,
            last_qty=Quantity.from_int(10000000),
            last_px=Price.from_str("100.50"),
            commission=Money("4.50", USD),
            liquidity_side=LiquiditySide.TAKER,
            report_id=report_id,
            ts_event=0,
            ts_init=0,
        )

        # Assert
        assert (
            str(report)
            == f"TradeReport(account_id=SIM-001, instrument_id=AUD/USD.IDEALPRO, client_order_id=O-123456789, venue_order_id=1, venue_position_id=2, trade_id=3, order_side=BUY, last_qty=10_000_000, last_px=100.50, commission=4.50 USD, liquidity_side=TAKER, report_id={report_id}, ts_event=0, ts_init=0)"  # noqa
        )
        assert (
            repr(report)
            == f"TradeReport(account_id=SIM-001, instrument_id=AUD/USD.IDEALPRO, client_order_id=O-123456789, venue_order_id=1, venue_position_id=2, trade_id=3, order_side=BUY, last_qty=10_000_000, last_px=100.50, commission=4.50 USD, liquidity_side=TAKER, report_id={report_id}, ts_event=0, ts_init=0)"  # noqa
        )
Beispiel #15
0
    def test_serialize_and_deserialize_order_filled_events(self):
        # Arrange
        event = OrderFilled(
            self.trader_id,
            self.strategy_id,
            self.account_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            VenueOrderId("1"),
            TradeId("E123456"),
            PositionId("T123456"),
            OrderSide.SELL,
            OrderType.MARKET,
            Quantity(100000, precision=0),
            Price(1.00000, precision=5),
            AUDUSD_SIM.quote_currency,
            Money(0, USD),
            LiquiditySide.TAKER,
            UUID4(),
            0,
            0,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event
Beispiel #16
0
def parse_trade_tick_http(instrument_id: InstrumentId, msg: Dict,
                          ts_init: int) -> TradeTick:
    return TradeTick(
        instrument_id=instrument_id,
        price=Price.from_str(msg["price"]),
        size=Quantity.from_str(msg["qty"]),
        aggressor_side=AggressorSide.SELL
        if msg["isBuyerMaker"] else AggressorSide.BUY,
        trade_id=TradeId(str(msg["id"])),
        ts_event=millis_to_nanos(msg["time"]),
        ts_init=ts_init,
    )
    async def test_reconcile_state_no_cached_with_partially_filled_order_and_trade(
            self):
        # Arrange
        venue_order_id = VenueOrderId("1")
        order_report = OrderStatusReport(
            account_id=self.account_id,
            instrument_id=AUDUSD_SIM.id,
            client_order_id=ClientOrderId("O-123456"),
            venue_order_id=venue_order_id,
            order_side=OrderSide.BUY,
            order_type=OrderType.LIMIT,
            time_in_force=TimeInForce.GTC,
            order_status=OrderStatus.PARTIALLY_FILLED,
            price=Price.from_str("1.00000"),
            quantity=Quantity.from_int(10_000),
            filled_qty=Quantity.from_int(5_000),
            avg_px=Decimal("1.00000"),
            post_only=True,
            report_id=UUID4(),
            ts_accepted=0,
            ts_triggered=0,
            ts_last=0,
            ts_init=0,
        )

        trade_report = TradeReport(
            account_id=self.account_id,
            instrument_id=AUDUSD_SIM.id,
            client_order_id=ClientOrderId("O-123456"),
            venue_order_id=venue_order_id,
            venue_position_id=None,
            trade_id=TradeId("1"),
            order_side=OrderSide.BUY,
            last_qty=Quantity.from_int(5_000),
            last_px=Price.from_str("1.00000"),
            commission=Money(0, USD),
            liquidity_side=LiquiditySide.MAKER,
            report_id=UUID4(),
            ts_event=0,
            ts_init=0,
        )

        self.client.add_order_status_report(order_report)
        self.client.add_trade_reports(venue_order_id, [trade_report])

        # Act
        result = await self.exec_engine.reconcile_state()

        # Assert
        assert result
        assert len(self.cache.orders()) == 1
        assert self.cache.orders()[0].status == OrderStatus.PARTIALLY_FILLED
Beispiel #18
0
def create_trade_id(uo: Dict) -> TradeId:
    data: bytes = orjson.dumps((
        uo["id"],
        uo["p"],
        uo["s"],
        uo["side"],
        uo["pt"],
        uo["ot"],
        uo["pd"],
        uo.get("md"),
        uo.get("avp"),
        uo.get("sm"),
    ))
    return TradeId(hashlib.sha1(data).hexdigest())  # noqa (S303 insecure SHA1)
Beispiel #19
0
def parse_trade_tick_ws(
    instrument_id: InstrumentId,
    data: BinanceTradeData,
    ts_init: int,
) -> TradeTick:
    return TradeTick(
        instrument_id=instrument_id,
        price=Price.from_str(data.p),
        size=Quantity.from_str(data.q),
        aggressor_side=AggressorSide.SELL if data.m else AggressorSide.BUY,
        trade_id=TradeId(str(data.t)),
        ts_event=millis_to_nanos(data.T),
        ts_init=ts_init,
    )
Beispiel #20
0
 def parse_line(d):
     if "status" in d:
         return {}
     elif "close_price" in d:
         # return {'timestamp': d['remote_timestamp'], "close_price": d['close_price']}
         return {}
     if "trade" in d:
         ts = millis_to_nanos(
             pd.Timestamp(d["remote_timestamp"]).timestamp())
         return {
             "timestamp":
             d["remote_timestamp"],
             "op":
             "trade",
             "trade":
             TradeTick(
                 instrument_id=InstrumentId(Symbol("TEST"),
                                            Venue("BETFAIR")),
                 price=Price(d["trade"]["price"], 4),
                 size=Quantity(d["trade"]["volume"], 4),
                 aggressor_side=d["trade"]["side"],
                 trade_id=TradeId(d["trade"]["trade_id"]),
                 ts_event=ts,
                 ts_init=ts,
             ),
         }
     elif "level" in d and d["level"]["orders"][0]["volume"] == 0:
         op = "delete"
     else:
         op = "update"
     order_like = d["level"]["orders"][0] if op != "trade" else d[
         "trade"]
     return {
         "timestamp":
         d["remote_timestamp"],
         "op":
         op,
         "order":
         Order(
             price=Price(order_like["price"], precision=6),
             size=Quantity(abs(order_like["volume"]), precision=4),
             # Betting sides are reversed
             side={
                 2: OrderSide.BUY,
                 1: OrderSide.SELL
             }[order_like["side"]],
             id=str(order_like["order_id"]),
         ),
     }
Beispiel #21
0
 def trade_tick_3decimal(
     instrument_id=None,
     price=None,
     aggressor_side=None,
     quantity=None,
 ) -> TradeTick:
     return TradeTick(
         instrument_id=instrument_id or TestIdStubs.usdjpy_id(),
         price=price or Price.from_str("1.001"),
         size=quantity or Quantity.from_int(100000),
         aggressor_side=aggressor_side or AggressorSide.BUY,
         trade_id=TradeId("123456"),
         ts_event=0,
         ts_init=0,
     )
Beispiel #22
0
    def _handle_fills(self, instrument: Instrument, data: Dict[str,
                                                               Any]) -> None:
        if data["type"] != "order":
            self._log.error(f"Fill not for order, {data}")
            return

        # Parse identifiers
        venue_order_id = VenueOrderId(str(data["orderId"]))
        client_order_id = self._order_ids.get(venue_order_id)
        if client_order_id is None:
            client_order_id = ClientOrderId(str(uuid.uuid4()))
            # TODO(cs): WIP
            # triggers = await self._http_client.get_trigger_order_triggers(venue_order_id.value)
            #
            # for trigger in triggers:
            #     client_order_id = self._open_triggers.get(trigger)
            #     if client_order_id is not None:
            #         break
            # if client_order_id is None:
            #     client_order_id = ClientOrderId(str(uuid.uuid4()))

        # Fetch strategy ID
        strategy_id: StrategyId = self._cache.strategy_id_for_order(
            client_order_id)
        if strategy_id is None:
            self._generate_external_trade_report(instrument, data)
            return

        self.generate_order_filled(
            strategy_id=strategy_id,
            instrument_id=instrument.id,
            client_order_id=client_order_id,
            venue_order_id=venue_order_id,
            venue_position_id=None,  # NETTING accounts
            trade_id=TradeId(str(data["id"])),  # Trade ID
            order_side=OrderSideParser.from_str_py(data["side"].upper()),
            order_type=self._order_types[venue_order_id],
            last_qty=Quantity(data["size"], instrument.size_precision),
            last_px=Price(data["price"], instrument.price_precision),
            quote_currency=instrument.quote_currency,
            commission=Money(data["fee"],
                             Currency.from_str(data["feeCurrency"])),
            liquidity_side=LiquiditySide.MAKER
            if data["liquidity"] == "maker" else LiquiditySide.TAKER,
            ts_event=pd.to_datetime(data["time"], utc=True).to_datetime64(),
        )
        if not self._calculated_account:
            self._loop.create_task(self._update_account_state())
Beispiel #23
0
    def test_hash_str_and_repr(self):
        # Arrange
        tick = TradeTick(
            instrument_id=AUDUSD_SIM.id,
            price=Price.from_str("1.00000"),
            size=Quantity.from_int(50000),
            aggressor_side=AggressorSide.BUY,
            trade_id=TradeId("123456789"),
            ts_event=0,
            ts_init=0,
        )

        # Act, Assert
        assert isinstance(hash(tick), int)
        assert str(tick) == "AUD/USD.SIM,1.00000,50000,BUY,123456789,0"
        assert repr(tick) == "TradeTick(AUD/USD.SIM,1.00000,50000,BUY,123456789,0)"
Beispiel #24
0
    def test_from_dict_returns_expected_tick(self):
        # Arrange
        tick = TradeTick(
            instrument_id=AUDUSD_SIM.id,
            price=Price.from_str("1.00000"),
            size=Quantity.from_int(10000),
            aggressor_side=AggressorSide.BUY,
            trade_id=TradeId("123456789"),
            ts_event=0,
            ts_init=0,
        )

        # Act
        result = TradeTick.from_dict(TradeTick.to_dict(tick))

        # Assert
        assert tick == result
    def test_process(self):
        # Arrange
        instrument = TestInstrumentProvider.btcusdt_binance()
        wrangler = TradeTickDataWrangler(instrument=instrument)
        path = os.path.join(PACKAGE_ROOT, "data", "tardis_trades.csv")
        data = TardisTradeDataLoader.load(path)

        # Act
        ticks = wrangler.process(data)

        # Assert
        assert len(ticks) == 9999
        assert ticks[0].price == Price.from_str("9682.00")
        assert ticks[0].size == Quantity.from_str("0.132000")
        assert ticks[0].aggressor_side == AggressorSide.BUY
        assert ticks[0].trade_id == TradeId("42377944")
        assert ticks[0].ts_event == 1582329602418379008
        assert ticks[0].ts_init == 1582329602418379008
    def test_process(self):
        # Arrange
        ethusdt = TestInstrumentProvider.ethusdt_binance()
        wrangler = TradeTickDataWrangler(instrument=ethusdt)
        provider = TestDataProvider()

        # Act
        ticks = wrangler.process(
            provider.read_csv_ticks("binance-ethusdt-trades.csv")[:100])

        # Assert
        assert len(ticks) == 100
        assert ticks[0].price == Price.from_str("423.760")
        assert ticks[0].size == Quantity.from_str("2.67900")
        assert ticks[0].aggressor_side == AggressorSide.SELL
        assert ticks[0].trade_id == TradeId("148568980")
        assert ticks[0].ts_event == 1597399200223000064
        assert ticks[0].ts_init == 1597399200223000064
Beispiel #27
0
def parse_trade_ticks_ws(
    instrument: Instrument,
    data: List[Dict[str, Any]],
    ts_init: int,
) -> List[TradeTick]:
    ticks: List[TradeTick] = []
    for trade in data:
        tick: TradeTick = TradeTick(
            instrument_id=instrument.id,
            price=Price(trade["price"], instrument.price_precision),
            size=Quantity(trade["size"], instrument.size_precision),
            aggressor_side=AggressorSide.BUY
            if trade["side"] == "buy" else AggressorSide.SELL,
            trade_id=TradeId(str(trade["id"])),
            ts_event=pd.to_datetime(trade["time"], utc=True).to_datetime64(),
            ts_init=ts_init,
        )
        ticks.append(tick)

    return ticks
Beispiel #28
0
def parse_trade_report(
    account_id: AccountId,
    instrument: Instrument,
    data: Dict[str, Any],
    report_id: UUID4,
    ts_init: int,
) -> TradeReport:
    return TradeReport(
        account_id=account_id,
        instrument_id=instrument.id,
        venue_order_id=VenueOrderId(str(data["orderId"])),
        trade_id=TradeId(str(data["tradeId"])),
        order_side=OrderSide.BUY if data["side"] == "buy" else OrderSide.SELL,
        last_qty=instrument.make_qty(data["size"]),
        last_px=instrument.make_price(data["price"]),
        commission=Money(data["fee"], Currency.from_str(data["feeCurrency"])),
        liquidity_side=LiquiditySide.TAKER
        if data["liquidity"] == "taker" else LiquiditySide.MAKER,
        report_id=report_id,
        ts_event=int(pd.to_datetime(data["time"], utc=True).to_datetime64()),
        ts_init=ts_init,
    )
Beispiel #29
0
def parse_trade_report_http(
    account_id: AccountId,
    instrument_id: InstrumentId,
    data: Dict[str, Any],
    report_id: UUID4,
    ts_init: int,
) -> TradeReport:
    return TradeReport(
        account_id=account_id,
        instrument_id=instrument_id,
        venue_order_id=VenueOrderId(str(data["orderId"])),
        trade_id=TradeId(str(data["id"])),
        order_side=OrderSide.BUY if data["isBuyer"] else OrderSide.SELL,
        last_qty=Quantity.from_str(data["qty"]),
        last_px=Price.from_str(data["price"]),
        commission=Money(data["commission"],
                         Currency.from_str(data["commissionAsset"])),
        liquidity_side=LiquiditySide.MAKER
        if data["isMaker"] else LiquiditySide.TAKER,
        report_id=report_id,
        ts_event=millis_to_nanos(data["time"]),
        ts_init=ts_init,
    )
def _handle_market_trades(
    runner,
    instrument,
    ts_event,
    ts_init,
):
    trade_ticks = []
    for price, volume in runner.get("trd", []):
        if volume == 0:
            continue
        # Betfair doesn't publish trade ids, so we make our own
        # TODO - should we use clk here for ID instead of the hash?
        trade_id = hash_json(data=(ts_event, price, volume))
        tick = TradeTick(
            instrument_id=instrument.id,
            price=price_to_probability(str(price)),
            size=Quantity(volume, precision=4),
            aggressor_side=AggressorSide.UNKNOWN,
            trade_id=TradeId(trade_id),
            ts_event=ts_event,
            ts_init=ts_init,
        )
        trade_ticks.append(tick)
    return trade_ticks