Exemplo n.º 1
0
    def test_to_dict_returns_expected_dict(self):
        # Arrange
        tick = QuoteTick(
            instrument_id=AUDUSD_SIM.id,
            bid=Price.from_str("1.00000"),
            ask=Price.from_str("1.00001"),
            bid_size=Quantity.from_int(1),
            ask_size=Quantity.from_int(1),
            ts_event=0,
            ts_init=0,
        )

        # Act
        result = QuoteTick.to_dict(tick)
        print(result)
        # Assert
        assert result == {
            "type": "QuoteTick",
            "instrument_id": "AUD/USD.SIM",
            "bid": "1.00000",
            "ask": "1.00001",
            "bid_size": "1",
            "ask_size": "1",
            "ts_event": 0,
            "ts_init": 0,
        }
    def test_update_correctly_updates_analyzer(self):
        # Arrange
        analyzer = SpreadAnalyzer(AUDUSD_SIM.id, 1000)
        tick1 = QuoteTick(
            instrument_id=AUDUSD_SIM.id,
            bid=Price.from_str("0.80000"),
            ask=Price.from_str("0.80010"),
            bid_size=Quantity.from_int(1),
            ask_size=Quantity.from_int(1),
            ts_event=0,
            ts_init=0,
        )

        tick2 = QuoteTick(
            instrument_id=AUDUSD_SIM.id,
            bid=Price.from_str("0.80002"),
            ask=Price.from_str("0.80008"),
            bid_size=Quantity.from_int(1),
            ask_size=Quantity.from_int(1),
            ts_event=0,
            ts_init=0,
        )

        # Act
        analyzer.handle_quote_tick(tick1)
        analyzer.handle_quote_tick(tick2)

        # Assert
        assert analyzer.current == pytest.approx(6e-05)
        assert analyzer.average == pytest.approx(8e-05)
Exemplo n.º 3
0
    def test_handle_quote_tick(self):
        # Arrange
        indicator = BidAskMinMax(self.instrument_id, timedelta(minutes=5))

        # Act
        indicator.handle_quote_tick(
            QuoteTick(
                instrument_id=self.instrument_id,
                bid=Price.from_str("1.0"),
                ask=Price.from_str("2.0"),
                bid_size=Quantity.from_int(1),
                ask_size=Quantity.from_int(1),
                ts_event=0,
                ts_init=0,
            ))
        # 5 min later (still in the window)
        indicator.handle_quote_tick(
            QuoteTick(
                instrument_id=self.instrument_id,
                bid=Price.from_str("0.9"),
                ask=Price.from_str("2.1"),
                bid_size=Quantity.from_int(1),
                ask_size=Quantity.from_int(1),
                ts_event=3e11,
                ts_init=3e11,
            ))

        # Assert
        assert indicator.bids.min_price == Price.from_str("0.9")
        assert indicator.bids.max_price == Price.from_str("1.0")
        assert indicator.asks.min_price == Price.from_str("2.1")
        assert indicator.asks.max_price == Price.from_str("2.1")
    def test_handle_quote_tick_when_value_beyond_threshold_sends_bar_to_handler(
            self):
        # Arrange
        bar_store = ObjectStorer()
        handler = bar_store.store
        instrument_id = TestStubs.audusd_id()
        bar_spec = BarSpecification(100000, BarAggregation.VALUE,
                                    PriceType.BID)
        bar_type = BarType(instrument_id, bar_spec)
        aggregator = ValueBarAggregator(
            AUDUSD_SIM,
            bar_type,
            handler,
            Logger(TestClock()),
        )

        tick1 = QuoteTick(
            instrument_id=AUDUSD_SIM.id,
            bid=Price.from_str("1.00001"),
            ask=Price.from_str("1.00004"),
            bid_size=Quantity.from_int(20000),
            ask_size=Quantity.from_int(20000),
            ts_event=0,
            ts_init=0,
        )

        tick2 = QuoteTick(
            instrument_id=AUDUSD_SIM.id,
            bid=Price.from_str("1.00002"),
            ask=Price.from_str("1.00005"),
            bid_size=Quantity.from_int(60000),
            ask_size=Quantity.from_int(20000),
            ts_event=0,
            ts_init=0,
        )

        tick3 = QuoteTick(
            instrument_id=AUDUSD_SIM.id,
            bid=Price.from_str("1.00000"),
            ask=Price.from_str("1.00003"),
            bid_size=Quantity.from_int(30500),
            ask_size=Quantity.from_int(20000),
            ts_event=0,
            ts_init=0,
        )

        # Act
        aggregator.handle_quote_tick(tick1)
        aggregator.handle_quote_tick(tick2)
        aggregator.handle_quote_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_str("99999")
        assert aggregator.get_cumulative_value() == Decimal("10501.400")
    def test_update_timed_with_test_clock_sends_single_bar_to_handler(self):
        # Arrange
        clock = TestClock()
        bar_store = ObjectStorer()
        handler = bar_store.store
        instrument_id = TestStubs.audusd_id()
        bar_spec = BarSpecification(1, BarAggregation.MINUTE, PriceType.MID)
        bar_type = BarType(instrument_id, bar_spec)
        aggregator = TimeBarAggregator(
            AUDUSD_SIM,
            bar_type,
            handler,
            TestClock(),
            Logger(clock),
        )

        tick1 = QuoteTick(
            instrument_id=AUDUSD_SIM.id,
            bid=Price.from_str("1.00001"),
            ask=Price.from_str("1.00004"),
            bid_size=Quantity.from_int(1),
            ask_size=Quantity.from_int(1),
            ts_event=0,
            ts_init=0,
        )

        tick2 = QuoteTick(
            instrument_id=AUDUSD_SIM.id,
            bid=Price.from_str("1.00002"),
            ask=Price.from_str("1.00005"),
            bid_size=Quantity.from_int(1),
            ask_size=Quantity.from_int(1),
            ts_event=0,
            ts_init=0,
        )

        tick3 = QuoteTick(
            instrument_id=AUDUSD_SIM.id,
            bid=Price.from_str("1.00000"),
            ask=Price.from_str("1.00003"),
            bid_size=Quantity.from_int(1),
            ask_size=Quantity.from_int(1),
            ts_event=2 * 60 * 1_000_000_000,  # 2 minutes in nanoseconds
            ts_init=2 * 60 * 1_000_000_000,  # 2 minutes in nanoseconds
        )

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

        # Assert
        assert len(bar_store.get_store()) == 1
        assert Price.from_str("1.000025") == bar_store.get_store()[0].open
        assert Price.from_str("1.000035") == bar_store.get_store()[0].high
        assert Price.from_str("1.000025") == bar_store.get_store()[0].low
        assert Price.from_str("1.000035") == bar_store.get_store()[0].close
        assert Quantity.from_int(2) == bar_store.get_store()[0].volume
        assert 60_000_000_000 == bar_store.get_store()[0].ts_init
    def test_handle_quote_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.BID)
        bar_type = BarType(instrument.id, bar_spec)
        aggregator = VolumeBarAggregator(
            instrument,
            bar_type,
            handler,
            Logger(TestClock()),
        )

        tick1 = QuoteTick(
            instrument_id=instrument.id,
            bid=Price.from_str("1.00001"),
            ask=Price.from_str("1.00004"),
            bid_size=Quantity.from_int(3000),
            ask_size=Quantity.from_int(2000),
            ts_event=0,
            ts_init=0,
        )

        tick2 = QuoteTick(
            instrument_id=instrument.id,
            bid=Price.from_str("1.00002"),
            ask=Price.from_str("1.00005"),
            bid_size=Quantity.from_int(4000),
            ask_size=Quantity.from_int(2000),
            ts_event=0,
            ts_init=0,
        )

        tick3 = QuoteTick(
            instrument_id=instrument.id,
            bid=Price.from_str("1.00000"),
            ask=Price.from_str("1.00003"),
            bid_size=Quantity.from_int(3000),
            ask_size=Quantity.from_int(2000),
            ts_event=0,
            ts_init=0,
        )

        # Act
        aggregator.handle_quote_tick(tick1)
        aggregator.handle_quote_tick(tick2)
        aggregator.handle_quote_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)
Exemplo n.º 7
0
    def test_partial_fill_bracket_tp_updates_sl_order(self):
        # Arrange: Prepare market
        tick1 = QuoteTick(
            instrument_id=ETHUSD_FTX.id,
            bid=ETHUSD_FTX.make_price(3090.2),
            ask=ETHUSD_FTX.make_price(3090.5),
            bid_size=ETHUSD_FTX.make_qty(15.100),
            ask_size=ETHUSD_FTX.make_qty(15.100),
            ts_event=0,
            ts_init=0,
        )

        self.data_engine.process(tick1)
        self.exchange.process_tick(tick1)

        bracket = self.strategy.order_factory.bracket_limit(
            instrument_id=ETHUSD_FTX.id,
            order_side=OrderSide.BUY,
            quantity=ETHUSD_FTX.make_qty(10.000),
            entry=ETHUSD_FTX.make_price(3100.0),
            stop_loss=ETHUSD_FTX.make_price(3050.0),
            take_profit=ETHUSD_FTX.make_price(3150.0),
        )

        en = bracket.orders[0]
        sl = bracket.orders[1]
        tp = bracket.orders[2]

        self.strategy.submit_order_list(bracket)
        self.exchange.process(0)

        # Act
        tick2 = QuoteTick(
            instrument_id=ETHUSD_FTX.id,
            bid=ETHUSD_FTX.make_price(3150.0),
            ask=ETHUSD_FTX.make_price(3151.0),
            bid_size=ETHUSD_FTX.make_qty(5.000),
            ask_size=ETHUSD_FTX.make_qty(5.1000),
            ts_event=0,
            ts_init=0,
        )

        self.exchange.process_tick(tick2)

        # Assert
        assert en.status == OrderStatus.FILLED
        assert sl.status == OrderStatus.ACCEPTED
        assert tp.status == OrderStatus.PARTIALLY_FILLED
        assert sl.quantity == Quantity.from_int(5)
        assert tp.leaves_qty == Quantity.from_int(5)
        assert tp.quantity == Quantity.from_int(10)
        assert len(self.exchange.get_open_orders()) == 2
        assert len(self.exchange.cache.positions_open()) == 1
Exemplo n.º 8
0
    def test_extract_volume_with_invalid_price_raises_value_error(self):
        # Arrange
        tick = QuoteTick(
            instrument_id=AUDUSD_SIM.id,
            bid=Price.from_str("1.00000"),
            ask=Price.from_str("1.00001"),
            bid_size=Quantity.from_int(1),
            ask_size=Quantity.from_int(1),
            ts_event=0,
            ts_init=0,
        )

        # Act, Assert
        with pytest.raises(ValueError):
            tick.extract_volume(0)
    def test_handle_quote_tick_when_value_below_threshold_updates(self):
        # Arrange
        bar_store = ObjectStorer()
        handler = bar_store.store
        instrument_id = TestStubs.audusd_id()
        bar_spec = BarSpecification(100000, BarAggregation.VALUE,
                                    PriceType.BID)
        bar_type = BarType(instrument_id, bar_spec)
        aggregator = ValueBarAggregator(
            AUDUSD_SIM,
            bar_type,
            handler,
            Logger(TestClock()),
        )

        tick1 = QuoteTick(
            instrument_id=AUDUSD_SIM.id,
            bid=Price.from_str("1.00001"),
            ask=Price.from_str("1.00004"),
            bid_size=Quantity.from_int(3000),
            ask_size=Quantity.from_int(2000),
            ts_event=0,
            ts_init=0,
        )

        # Act
        aggregator.handle_quote_tick(tick1)

        # Assert
        assert len(bar_store.get_store()) == 0
        assert aggregator.get_cumulative_value() == Decimal("3000.03000")
Exemplo n.º 10
0
    def test_submit_bracket_limit_buy_has_sl_tp_pending(self):
        # Arrange: Prepare market
        tick = QuoteTick(
            instrument_id=ETHUSD_FTX.id,
            bid=ETHUSD_FTX.make_price(3090.2),
            ask=ETHUSD_FTX.make_price(3090.5),
            bid_size=ETHUSD_FTX.make_qty(15.100),
            ask_size=ETHUSD_FTX.make_qty(15.100),
            ts_event=0,
            ts_init=0,
        )

        self.data_engine.process(tick)
        self.exchange.process_tick(tick)

        bracket = self.strategy.order_factory.bracket_limit(
            instrument_id=ETHUSD_FTX.id,
            order_side=OrderSide.BUY,
            quantity=ETHUSD_FTX.make_qty(10.000),
            entry=ETHUSD_FTX.make_price(3090.0),
            stop_loss=ETHUSD_FTX.make_price(3050.0),
            take_profit=ETHUSD_FTX.make_price(3150.0),
        )

        # Act
        self.strategy.submit_order_list(bracket)
        self.exchange.process(0)
        #
        # # Assert
        assert bracket.orders[0].status == OrderStatus.ACCEPTED
        assert bracket.orders[1].status == OrderStatus.SUBMITTED
        assert bracket.orders[2].status == OrderStatus.SUBMITTED
Exemplo n.º 11
0
    def test_partition_key_correctly_remapped(self):
        # Arrange
        instrument = TestInstrumentProvider.default_fx_ccy("AUD/USD")
        tick = QuoteTick(
            instrument_id=instrument.id,
            bid=Price(10, 1),
            ask=Price(11, 1),
            bid_size=Quantity(10, 1),
            ask_size=Quantity(10, 1),
            ts_init=0,
            ts_event=0,
        )
        tables = dicts_to_dataframes(split_and_serialize([tick]))
        write_tables(catalog=self.catalog, tables=tables)

        # Act
        df = self.catalog.quote_ticks()

        # Assert
        assert len(df) == 1
        assert self.fs.isdir(
            "/root/data/quote_tick.parquet/instrument_id=AUD-USD.SIM/")
        # Ensure we "unmap" the keys that we write the partition filenames as;
        # this instrument_id should be AUD/USD not AUD-USD
        assert df.iloc[0]["instrument_id"] == instrument.id.value
    def test_handle_quote_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.BID)
        bar_type = BarType(instrument.id, bar_spec)
        aggregator = VolumeBarAggregator(
            instrument,
            bar_type,
            handler,
            Logger(TestClock()),
        )

        tick1 = QuoteTick(
            instrument_id=instrument.id,
            bid=Price.from_str("1.00001"),
            ask=Price.from_str("1.00004"),
            bid_size=Quantity.from_int(3000),
            ask_size=Quantity.from_int(2000),
            ts_event=0,
            ts_init=0,
        )

        # Act
        aggregator.handle_quote_tick(tick1)

        # Assert
        assert len(bar_store.get_store()) == 0
Exemplo n.º 13
0
    async def test_subscribe_quote_ticks(self, monkeypatch):
        handler = []
        self.msgbus.subscribe(
            topic="data.quotes.BINANCE.ETHUSDT",
            handler=handler.append,
        )

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

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

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

        assert self.data_engine.data_count == 1
        assert len(handler) == 1  # <-- handler received tick
        assert handler[0] == QuoteTick(
            instrument_id=ETHUSDT_BINANCE.id,
            bid=Price.from_str("4507.24000000"),
            ask=Price.from_str("4507.25000000"),
            bid_size=Quantity.from_str("2.35950000"),
            ask_size=Quantity.from_str("2.84570000"),
            ts_event=handler[0].ts_init,  # TODO: WIP
            ts_init=handler[0].ts_init,
        )
Exemplo n.º 14
0
    def test_submit_bracket_limit_sell_fills_then_triggers_sl_and_tp(self):
        # Arrange: Prepare market
        tick = QuoteTick(
            instrument_id=ETHUSD_FTX.id,
            bid=ETHUSD_FTX.make_price(3090.2),
            ask=ETHUSD_FTX.make_price(3090.5),
            bid_size=ETHUSD_FTX.make_qty(15.100),
            ask_size=ETHUSD_FTX.make_qty(15.100),
            ts_event=0,
            ts_init=0,
        )

        self.data_engine.process(tick)
        self.exchange.process_tick(tick)

        bracket = self.strategy.order_factory.bracket_limit(
            instrument_id=ETHUSD_FTX.id,
            order_side=OrderSide.SELL,
            quantity=ETHUSD_FTX.make_qty(10.000),
            entry=ETHUSD_FTX.make_price(3050.0),
            stop_loss=ETHUSD_FTX.make_price(3150.0),
            take_profit=ETHUSD_FTX.make_price(3000.0),
        )

        # Act
        self.strategy.submit_order_list(bracket)
        self.exchange.process(0)

        # Assert
        assert bracket.orders[0].status == OrderStatus.FILLED
        assert bracket.orders[1].status == OrderStatus.ACCEPTED
        assert bracket.orders[2].status == OrderStatus.ACCEPTED
        assert len(self.exchange.get_open_orders()) == 2
        assert bracket.orders[1] in self.exchange.get_open_orders()
        assert bracket.orders[2] in self.exchange.get_open_orders()
Exemplo n.º 15
0
    def test_from_dict_returns_expected_tick(self):
        # Arrange
        tick = QuoteTick(
            instrument_id=AUDUSD_SIM.id,
            bid=Price.from_str("1.00000"),
            ask=Price.from_str("1.00001"),
            bid_size=Quantity.from_int(1),
            ask_size=Quantity.from_int(1),
            ts_event=0,
            ts_init=0,
        )

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

        # Assert
        assert tick == result
Exemplo n.º 16
0
    def test_filling_bracket_tp_cancels_sl_order(self):
        # Arrange: Prepare market
        tick1 = QuoteTick(
            instrument_id=ETHUSD_FTX.id,
            bid=ETHUSD_FTX.make_price(3090.2),
            ask=ETHUSD_FTX.make_price(3090.5),
            bid_size=ETHUSD_FTX.make_qty(15.100),
            ask_size=ETHUSD_FTX.make_qty(15.100),
            ts_event=0,
            ts_init=0,
        )

        self.data_engine.process(tick1)
        self.exchange.process_tick(tick1)

        bracket = self.strategy.order_factory.bracket_limit(
            instrument_id=ETHUSD_FTX.id,
            order_side=OrderSide.BUY,
            quantity=ETHUSD_FTX.make_qty(10.000),
            entry=ETHUSD_FTX.make_price(3100.0),
            stop_loss=ETHUSD_FTX.make_price(3050.0),
            take_profit=ETHUSD_FTX.make_price(3150.0),
        )

        self.strategy.submit_order_list(bracket)
        self.exchange.process(0)

        # Act
        tick2 = QuoteTick(
            instrument_id=ETHUSD_FTX.id,
            bid=ETHUSD_FTX.make_price(3150.0),
            ask=ETHUSD_FTX.make_price(3151.0),
            bid_size=ETHUSD_FTX.make_qty(10.000),
            ask_size=ETHUSD_FTX.make_qty(10.000),
            ts_event=0,
            ts_init=0,
        )

        self.exchange.process_tick(tick2)

        # Assert
        assert bracket.orders[0].status == OrderStatus.FILLED
        assert bracket.orders[1].status == OrderStatus.CANCELED
        assert bracket.orders[2].status == OrderStatus.FILLED
        assert len(self.exchange.get_open_orders()) == 0
        assert len(self.exchange.cache.positions_open()) == 0
Exemplo n.º 17
0
def parse_quote_tick_ws(instrument_id: InstrumentId, msg: Dict,
                        ts_init: int) -> QuoteTick:
    return QuoteTick(
        instrument_id=instrument_id,
        bid=Price.from_str(msg["b"]),
        ask=Price.from_str(msg["a"]),
        bid_size=Quantity.from_str(msg["B"]),
        ask_size=Quantity.from_str(msg["B"]),
        ts_event=ts_init,
        ts_init=ts_init,
    )
Exemplo n.º 18
0
    def test_extract_price_with_various_price_types_returns_expected_values(self):
        # Arrange
        tick = QuoteTick(
            instrument_id=AUDUSD_SIM.id,
            bid=Price.from_str("1.00000"),
            ask=Price.from_str("1.00001"),
            bid_size=Quantity.from_int(1),
            ask_size=Quantity.from_int(1),
            ts_event=0,
            ts_init=0,
        )

        # Act
        result1 = tick.extract_price(PriceType.ASK)
        result2 = tick.extract_price(PriceType.MID)
        result3 = tick.extract_price(PriceType.BID)

        # Assert
        assert result1 == Price.from_str("1.00001")
        assert result2 == Price.from_str("1.000005")
        assert result3 == Price.from_str("1.00000")
Exemplo n.º 19
0
    def handle_quote_tick(self, tick: QuoteTick):
        """
        Update the indicator with the given quote tick.

        Parameters
        ----------
        tick : QuoteTick
            The update tick to handle.

        """
        PyCondition.not_none(tick, "tick")

        self.update_raw(tick.extract_price(self.price_type).as_double())
Exemplo n.º 20
0
    def test_partially_filling_position_updates_bracket_ocos(self):
        # Arrange: Prepare market
        tick1 = QuoteTick(
            instrument_id=ETHUSD_FTX.id,
            bid=ETHUSD_FTX.make_price(3090.2),
            ask=ETHUSD_FTX.make_price(3090.5),
            bid_size=ETHUSD_FTX.make_qty(15.100),
            ask_size=ETHUSD_FTX.make_qty(15.100),
            ts_event=0,
            ts_init=0,
        )

        self.data_engine.process(tick1)
        self.exchange.process_tick(tick1)

        bracket = self.strategy.order_factory.bracket_market(
            instrument_id=ETHUSD_FTX.id,
            order_side=OrderSide.BUY,
            quantity=ETHUSD_FTX.make_qty(10.000),
            stop_loss=ETHUSD_FTX.make_price(3050.0),
            take_profit=ETHUSD_FTX.make_price(3150.0),
        )

        en = bracket.orders[0]
        sl = bracket.orders[1]
        tp = bracket.orders[2]

        self.strategy.submit_order_list(bracket)
        self.exchange.process(0)

        # Act
        reduce_order = self.strategy.order_factory.market(
            instrument_id=ETHUSD_FTX.id,
            order_side=OrderSide.SELL,
            quantity=ETHUSD_FTX.make_qty(5.000),
        )
        self.strategy.submit_order(
            reduce_order,
            position_id=self.cache.position_for_order(en.client_order_id).id,
        )
        self.exchange.process(0)

        # Assert
        assert en.status == OrderStatus.FILLED
        assert sl.status == OrderStatus.ACCEPTED
        assert tp.status == OrderStatus.ACCEPTED
        assert sl.quantity == ETHUSD_FTX.make_qty(5.000)
        assert tp.quantity == ETHUSD_FTX.make_qty(5.000)
        assert len(self.exchange.get_open_orders()) == 2
        assert len(self.exchange.cache.positions_open()) == 1
Exemplo n.º 21
0
def parse_quote_tick_ws(
    instrument: Instrument,
    data: Dict[str, Any],
    ts_init: int,
) -> QuoteTick:
    return QuoteTick(
        instrument_id=instrument.id,
        bid=Price(data["bid"], instrument.price_precision),
        ask=Price(data["ask"], instrument.price_precision),
        bid_size=Quantity(data["bidSize"], instrument.size_precision),
        ask_size=Quantity(data["askSize"], instrument.size_precision),
        ts_event=secs_to_nanos(data["time"]),
        ts_init=ts_init,
    )
Exemplo n.º 22
0
 def quote_tick_5decimal(
     instrument_id=None,
     bid=None,
     ask=None,
 ) -> QuoteTick:
     return QuoteTick(
         instrument_id=instrument_id or TestIdStubs.audusd_id(),
         bid=bid or Price.from_str("1.00001"),
         ask=ask or Price.from_str("1.00003"),
         bid_size=Quantity.from_int(1_000_000),
         ask_size=Quantity.from_int(1_000_000),
         ts_event=0,
         ts_init=0,
     )
Exemplo n.º 23
0
 def parse_csv_tick(df, instrument_id):
     yield instrument
     for r in df.values:
         ts = secs_to_nanos(pd.Timestamp(r[0]).timestamp())
         tick = QuoteTick(
             instrument_id=instrument_id,
             bid=Price.from_str(str(r[1])),
             ask=Price.from_str(str(r[2])),
             bid_size=Quantity.from_int(1_000_000),
             ask_size=Quantity.from_int(1_000_000),
             ts_event=ts,
             ts_init=ts,
         )
         yield tick
Exemplo n.º 24
0
def parse_quote_tick_ws(
    instrument_id: InstrumentId,
    data: BinanceQuoteData,
    ts_init: int,
) -> QuoteTick:
    return QuoteTick(
        instrument_id=instrument_id,
        bid=Price.from_str(data.b),
        ask=Price.from_str(data.a),
        bid_size=Quantity.from_str(data.B),
        ask_size=Quantity.from_str(data.A),
        ts_event=ts_init,
        ts_init=ts_init,
    )
 def test_update_with_incorrect_tick_raises_exception(self):
     # Arrange
     analyzer = SpreadAnalyzer(AUDUSD_SIM.id, 1000)
     tick = QuoteTick(
         instrument_id=USDJPY_SIM.id,
         bid=Price.from_str("117.80000"),
         ask=Price.from_str("117.80010"),
         bid_size=Quantity.from_int(1),
         ask_size=Quantity.from_int(1),
         ts_event=0,
         ts_init=0,
     )
     # Act, Assert
     with pytest.raises(ValueError):
         analyzer.handle_quote_tick(tick)
Exemplo n.º 26
0
    def test_tick_hash_str_and_repr(self):
        # Arrange
        tick = QuoteTick(
            instrument_id=AUDUSD_SIM.id,
            bid=Price.from_str("1.00000"),
            ask=Price.from_str("1.00001"),
            bid_size=Quantity.from_int(1),
            ask_size=Quantity.from_int(1),
            ts_event=0,
            ts_init=0,
        )

        # Act, Assert
        assert isinstance(hash(tick), int)
        assert str(tick) == "AUD/USD.SIM,1.00000,1.00001,1,1,0"
        assert repr(tick) == "QuoteTick(AUD/USD.SIM,1.00000,1.00001,1,1,0)"
Exemplo n.º 27
0
 def quote_tick_3decimal(
     instrument_id=None,
     bid=None,
     ask=None,
     bid_volume=None,
     ask_volume=None,
 ) -> QuoteTick:
     return QuoteTick(
         instrument_id=instrument_id or TestIdStubs.usdjpy_id(),
         bid=bid or Price.from_str("90.002"),
         ask=ask or Price.from_str("90.005"),
         bid_size=bid_volume or Quantity.from_int(1_000_000),
         ask_size=ask_volume or Quantity.from_int(1_000_000),
         ts_event=0,
         ts_init=0,
     )
Exemplo n.º 28
0
def parse_historic_quote_ticks(historic_ticks: List[HistoricalTickBidAsk],
                               instrument_id: InstrumentId) -> List[QuoteTick]:
    trades = []
    for tick in historic_ticks:
        ts_init = dt_to_unix_nanos(tick.time)
        quote_tick = QuoteTick(
            instrument_id=instrument_id,
            bid=Price.from_str(str(tick.priceBid)),
            bid_size=Quantity.from_str(str(tick.sizeBid)),
            ask=Price.from_str(str(tick.priceAsk)),
            ask_size=Quantity.from_str(str(tick.sizeAsk)),
            ts_init=ts_init,
            ts_event=ts_init,
        )
        trades.append(quote_tick)

    return trades
Exemplo n.º 29
0
 def _on_quote_tick_update(self, tick: Ticker, contract: Contract):
     instrument_id = self._instrument_provider.contract_id_to_instrument_id[
         contract.conId]
     ts_event = dt_to_unix_nanos(tick.time)
     ts_init = self._clock.timestamp_ns()
     quote_tick = QuoteTick(
         instrument_id=instrument_id,
         bid=Price.from_str(str(tick.bid)) if tick.bid else None,
         bid_size=Quantity.from_str(str(tick.bidSize))
         if tick.bidSize else None,
         ask=Price.from_str(str(tick.ask)) if tick.ask else None,
         ask_size=Quantity.from_str(str(tick.askSize))
         if tick.askSize else None,
         ts_event=ts_event,
         ts_init=ts_init,
     )
     self._handle_data(quote_tick)
Exemplo n.º 30
0
    def test_closing_position_cancels_bracket_ocos(self):
        # Arrange: Prepare market
        tick1 = QuoteTick(
            instrument_id=ETHUSD_FTX.id,
            bid=ETHUSD_FTX.make_price(3090.2),
            ask=ETHUSD_FTX.make_price(3090.5),
            bid_size=ETHUSD_FTX.make_qty(15.100),
            ask_size=ETHUSD_FTX.make_qty(15.100),
            ts_event=0,
            ts_init=0,
        )

        self.data_engine.process(tick1)
        self.exchange.process_tick(tick1)

        bracket = self.strategy.order_factory.bracket_market(
            instrument_id=ETHUSD_FTX.id,
            order_side=OrderSide.BUY,
            quantity=ETHUSD_FTX.make_qty(10.000),
            stop_loss=ETHUSD_FTX.make_price(3050.0),
            take_profit=ETHUSD_FTX.make_price(3150.0),
        )

        en = bracket.orders[0]
        sl = bracket.orders[1]
        tp = bracket.orders[2]

        self.strategy.submit_order_list(bracket)
        self.exchange.process(0)

        # Act
        self.strategy.flatten_position(
            self.strategy.cache.position(en.position_id))
        self.exchange.process(0)

        # Assert
        assert en.status == OrderStatus.FILLED
        assert sl.status == OrderStatus.CANCELED
        assert tp.status == OrderStatus.CANCELED
        assert len(self.exchange.get_open_orders()) == 0
        assert len(self.exchange.cache.positions_open()) == 0