def test_byte_reader_parser(self):
        def block_parser(block: bytes, instrument_provider):
            for raw in block.split(b"\\n"):
                ts, line = raw.split(b" - ")
                state = {
                    "ts_init":
                    int(pd.Timestamp(ts.decode(), tz="UTC").to_datetime64())
                }
                line = line.strip().replace(b"b'", b"")
                orjson.loads(line)
                for obj in BetfairTestStubs.parse_betfair(
                        line, instrument_provider=instrument_provider):
                    values = obj.to_dict(obj)
                    values["ts_init"] = state["ts_init"]
                    yield obj.from_dict(values)

        provider = BetfairInstrumentProvider.from_instruments(
            [BetfairTestStubs.betting_instrument()])
        block = BetfairDataProvider.badly_formatted_log()
        reader = ByteReader(
            block_parser=partial(block_parser, instrument_provider=provider),
            instrument_provider=provider,
        )

        data = list(reader.parse(block=block))
        result = [pd.Timestamp(d.ts_init).isoformat() for d in data]
        expected = ["2021-06-29T06:03:14.528000"]
        assert result == expected
def instrument_list(mock_load_markets_metadata,
                    loop: asyncio.AbstractEventLoop):
    """Prefill `INSTRUMENTS` cache for tests"""
    global INSTRUMENTS

    # Setup
    logger = LiveLogger(loop=loop,
                        clock=LiveClock(),
                        level_stdout=LogLevel.ERROR)
    client = BetfairTestStubs.betfair_client(loop=loop, logger=logger)
    logger = LiveLogger(loop=loop,
                        clock=LiveClock(),
                        level_stdout=LogLevel.DEBUG)
    instrument_provider = BetfairInstrumentProvider(client=client,
                                                    logger=logger,
                                                    market_filter={})

    # Load instruments
    market_ids = BetfairDataProvider.market_ids()
    catalog = {
        r["marketId"]: r
        for r in BetfairResponses.betting_list_market_catalogue()["result"]
        if r["marketId"] in market_ids
    }
    mock_load_markets_metadata.return_value = catalog
    t = loop.create_task(
        instrument_provider.load_all_async(
            market_filter={"market_id": market_ids}))
    loop.run_until_complete(t)

    # Fill INSTRUMENTS global cache
    INSTRUMENTS.extend(instrument_provider.list_all())
    assert INSTRUMENTS
 def test_betfair_orderbook(self):
     book = L2OrderBook(
         instrument_id=BetfairTestStubs.instrument_id(),
         price_precision=2,
         size_precision=2,
     )
     for update in BetfairDataProvider.raw_market_updates():
         for message in on_market_update(
                 instrument_provider=self.instrument_provider,
                 update=update):
             try:
                 if isinstance(message, OrderBookSnapshot):
                     book.apply_snapshot(message)
                 elif isinstance(message, OrderBookDeltas):
                     book.apply_deltas(message)
                 elif isinstance(message, OrderBookDelta):
                     book.apply_delta(message)
                 elif isinstance(message,
                                 (Ticker, TradeTick, InstrumentStatusUpdate,
                                  InstrumentClosePrice)):
                     pass
                 else:
                     raise NotImplementedError(str(type(message)))
                 book.check_integrity()
             except Exception as ex:
                 print(str(type(ex)) + " " + str(ex))
 def test_instrument_in_play_events(self):
     events = [
         msg for update in BetfairDataProvider.raw_market_updates()
         for msg in on_market_update(
             instrument_provider=self.client.instrument_provider(),
             update=update) if isinstance(msg, InstrumentStatusUpdate)
     ]
     assert len(events) == 14
     result = [ev.status for ev in events]
     expected = [
         InstrumentStatus.PRE_OPEN.value,
         InstrumentStatus.PRE_OPEN.value,
         InstrumentStatus.PRE_OPEN.value,
         InstrumentStatus.PRE_OPEN.value,
         InstrumentStatus.PRE_OPEN.value,
         InstrumentStatus.PRE_OPEN.value,
         InstrumentStatus.PAUSE.value,
         InstrumentStatus.PAUSE.value,
         InstrumentStatus.OPEN.value,
         InstrumentStatus.OPEN.value,
         InstrumentStatus.PAUSE.value,
         InstrumentStatus.PAUSE.value,
         InstrumentStatus.CLOSED.value,
         InstrumentStatus.CLOSED.value,
     ]
     assert result == expected
 def test_instrument_closing_events(self):
     updates = BetfairDataProvider.raw_market_updates()
     messages = on_market_update(
         instrument_provider=self.client.instrument_provider(),
         update=updates[-1],
     )
     assert len(messages) == 4
     assert (
         isinstance(messages[0], InstrumentStatusUpdate)
         and messages[0].status == InstrumentStatus.CLOSED
     )
     assert isinstance(messages[1], InstrumentClosePrice) and messages[1].close_price == 1.0000
     assert (
         isinstance(messages[1], InstrumentClosePrice)
         and messages[1].close_type == InstrumentCloseType.EXPIRED
     )
     assert (
         isinstance(messages[2], InstrumentStatusUpdate)
         and messages[2].status == InstrumentStatus.CLOSED
     )
     assert isinstance(messages[3], InstrumentClosePrice) and messages[3].close_price == 0.0
     assert (
         isinstance(messages[3], InstrumentClosePrice)
         and messages[3].close_type == InstrumentCloseType.EXPIRED
     )
 def test_instrument_opening_events(self):
     updates = BetfairDataProvider.raw_market_updates()
     messages = on_market_update(
         instrument_provider=self.client.instrument_provider(),
         update=updates[0])
     assert len(messages) == 2
     assert (isinstance(messages[0], InstrumentStatusUpdate)
             and messages[0].status == InstrumentStatus.PRE_OPEN)
     assert (isinstance(messages[1], InstrumentStatusUpdate)
             and messages[0].status == InstrumentStatus.PRE_OPEN)
Esempio n. 7
0
    async def test_generate_trades_list(self):
        patch(
            "betfairlightweight.endpoints.betting.Betting.list_cleared_orders",
            return_value=BetfairDataProvider.list_cleared_orders(order_id="226125004209"),
        )
        patch.object(
            self.client,
            "venue_order_id_to_client_order_id",
            {"226125004209": ClientOrderId("1")},
        )

        result = await generate_trades_list(
            self=self.client, venue_order_id="226125004209", symbol=None, since=None
        )
        assert result
Esempio n. 8
0
    def handle(self):
        self.on_connection_message()

        if self.connection_info.get("auth") is None:
            return self.close()

        for n, data in enumerate(BetfairDataProvider.raw_market_updates()):
            line = orjson.dumps(data)
            try:
                print("SERVER [SEND]", line)
                self.wfile.write(line.strip() + b"\r\n")
                time.sleep(0.1)

                if (self.connection_info.get("num_lines") is not None
                        and n > self.connection_info["num_lines"]):
                    return self.close()

            except BrokenPipeError:
                return self.close()
    def setup(self):
        # Fixture Setup
        data_catalog_setup()

        config = BacktestEngineConfig(
            bypass_logging=True,
            run_analysis=False,
        )
        self.engine = BacktestEngine(config=config)

        self.venue = Venue("BETFAIR")

        data = BetfairDataProvider.betfair_feed_parsed(
            market_id="1.166811431.bz2", folder="data/betfair")
        instruments = [d for d in data if isinstance(d, BettingInstrument)]

        for instrument in instruments[:1]:
            trade_ticks = [
                d for d in data if isinstance(d, TradeTick)
                and d.instrument_id == instrument.id
            ]
            order_book_deltas = [
                d for d in data if isinstance(d, OrderBookData)
                and d.instrument_id == instrument.id
            ]
            self.engine.add_instrument(instrument)
            self.engine.add_ticks(trade_ticks)
            self.engine.add_order_book_data(order_book_deltas)
            self.instrument = instrument
        self.engine.add_venue(
            venue=self.venue,
            venue_type=VenueType.EXCHANGE,
            account_type=AccountType.MARGIN,
            base_currency=None,
            oms_type=OMSType.NETTING,
            starting_balances=[Money(10_000, GBP)],
            book_type=BookType.L2_MBP,
        )
Esempio n. 10
0
    def setup(self):
        # Fixture Setup
        self.loop = asyncio.get_event_loop()
        self.loop.set_debug(True)

        self.clock = LiveClock()
        self.uuid_factory = UUIDFactory()

        self.trader_id = TestStubs.trader_id()
        self.uuid = UUID4()
        self.venue = BETFAIR_VENUE
        self.account_id = AccountId(self.venue.value, "001")

        # Setup logging
        self.logger = LiveLogger(loop=self.loop,
                                 clock=self.clock,
                                 level_stdout=LogLevel.ERROR)
        self._log = LoggerAdapter("TestBetfairExecutionClient", self.logger)

        self.msgbus = MessageBus(
            trader_id=self.trader_id,
            clock=self.clock,
            logger=self.logger,
        )

        self.cache = TestStubs.cache()
        self.cache.add_instrument(BetfairTestStubs.betting_instrument())

        self.portfolio = Portfolio(
            msgbus=self.msgbus,
            cache=self.cache,
            clock=self.clock,
            logger=self.logger,
        )

        self.data_engine = LiveDataEngine(
            loop=self.loop,
            msgbus=self.msgbus,
            cache=self.cache,
            clock=self.clock,
            logger=self.logger,
        )

        self.betfair_client = BetfairTestStubs.betfair_client(
            loop=self.loop, logger=self.logger)

        self.instrument_provider = BetfairTestStubs.instrument_provider(
            betfair_client=self.betfair_client)
        # Add a subset of instruments
        instruments = [
            ins for ins in INSTRUMENTS
            if ins.market_id in BetfairDataProvider.market_ids()
        ]
        self.instrument_provider.add_bulk(instruments)

        self.client = BetfairDataClient(
            loop=self.loop,
            client=self.betfair_client,
            msgbus=self.msgbus,
            cache=self.cache,
            clock=self.clock,
            logger=self.logger,
            instrument_provider=self.instrument_provider,
            market_filter={},
        )

        self.data_engine.register_client(self.client)

        # Re-route exec engine messages through `handler`
        self.messages = []

        def handler(x, endpoint):
            self.messages.append(x)
            if endpoint == "execute":
                self.data_engine.execute(x)
            elif endpoint == "process":
                self.data_engine.process(x)
            elif endpoint == "response":
                self.data_engine.response(x)

        self.msgbus.deregister(
            endpoint="DataEngine.execute",
            handler=self.data_engine.execute)  # type: ignore
        self.msgbus.register(
            endpoint="DataEngine.execute",
            handler=partial(handler, endpoint="execute")  # type: ignore
        )

        self.msgbus.deregister(
            endpoint="DataEngine.process",
            handler=self.data_engine.process)  # type: ignore
        self.msgbus.register(
            endpoint="DataEngine.process",
            handler=partial(handler, endpoint="process")  # type: ignore
        )

        self.msgbus.deregister(
            endpoint="DataEngine.response",
            handler=self.data_engine.response)  # type: ignore
        self.msgbus.register(
            endpoint="DataEngine.response",
            handler=partial(handler, endpoint="response")  # type: ignore
        )