async def test_account_statement(self):
     with patch.object(BetfairClient,
                       "request",
                       return_value=BetfairResponses.account_details()):
         detail = await self.client.get_account_details()
     with patch.object(
             BetfairClient,
             "request",
             return_value=BetfairResponses.account_funds_no_exposure()):
         funds = await self.client.get_account_funds()
     result = betfair_account_to_account_state(
         account_detail=detail,
         account_funds=funds,
         event_id=self.uuid,
         ts_event=0,
         ts_init=0,
     )
     expected = AccountState(
         account_id=AccountId(issuer="BETFAIR", number="Testy-McTest"),
         account_type=AccountType.CASH,
         base_currency=GBP,
         reported=True,  # reported
         balances=[
             AccountBalance(GBP, Money(1000.0, GBP), Money(0.00, GBP),
                            Money(1000.0, GBP))
         ],
         info={
             "funds": funds,
             "detail": detail
         },
         event_id=self.uuid,
         ts_event=result.ts_event,
         ts_init=result.ts_init,
     )
     assert result == expected
예제 #2
0
 async def test_exception_handling(self):
     with mock_client_request(
             response=BetfairResponses.account_funds_error()):
         with pytest.raises(BetfairAPIError) as ex:
             await self.client.get_account_funds(wallet="not a real walltet"
                                                 )
         assert ex.value.message == "DSC-0018"
예제 #3
0
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
예제 #4
0
    async def test_get_account_details(self):
        with mock_client_request(
                response=BetfairResponses.account_details()) as mock_request:
            account = await self.client.get_account_details()

        assert account["pointsBalance"] == 10
        result = mock_request.call_args.kwargs
        expected = BetfairRequests.account_details()
        assert result == expected
예제 #5
0
    async def test_connect(self):
        self.client.session_token = None
        with mock_client_request(
                response=BetfairResponses.cert_login()) as mock_request:
            await self.client.connect()
            assert self.client.session_token

        result = mock_request.call_args.kwargs
        expected = BetfairRequests.cert_login()
        assert result == expected
예제 #6
0
    async def test_betfair_order_reduces_balance(self):
        # Arrange
        self.client.stream = MagicMock()
        self.exec_engine.start()
        await asyncio.sleep(1)

        balance = self.cache.account_for_venue(self.venue).balances()[GBP]
        order = BetfairTestStubs.make_order(price=Price.from_str("0.5"),
                                            quantity=Quantity.from_int(10))
        self.cache.add_order(order=order, position_id=None)
        mock_betfair_request(self.betfair_client,
                             BetfairResponses.betting_place_order_success())
        command = BetfairTestStubs.submit_order_command(order=order)
        self.client.submit_order(command)
        await asyncio.sleep(0.01)

        # Act
        balance_order = self.cache.account_for_venue(
            BETFAIR_VENUE).balances()[GBP]

        # Cancel the order, balance should return
        command = BetfairTestStubs.cancel_order_command(
            client_order_id=order.client_order_id,
            venue_order_id=order.venue_order_id)
        mock_betfair_request(self.betfair_client,
                             BetfairResponses.betting_cancel_orders_success())
        self.client.cancel_order(command)
        await asyncio.sleep(0.1)
        balance_cancel = self.cache.account_for_venue(
            BETFAIR_VENUE).balances()[GBP]

        # Assert
        assert balance.free == Money(1000.0, GBP)
        assert balance_order.free == Money(990.0, GBP)
        assert balance_cancel.free == Money(1000.0, GBP)

        self.exec_engine.kill()
        await asyncio.sleep(1)
예제 #7
0
    async def test_submit_order_error(self):
        # Arrange
        command = BetfairTestStubs.submit_order_command()
        mock_betfair_request(self.betfair_client, BetfairResponses.betting_place_order_error())

        # Act
        self.client.submit_order(command)
        await asyncio.sleep(0)

        # Assert
        submitted, rejected = self.messages
        assert isinstance(submitted, OrderSubmitted)
        assert isinstance(rejected, OrderRejected)
        assert rejected.reason == "PERMISSION_DENIED: ERROR_IN_ORDER"
예제 #8
0
    async def test_submit_order_success(self):
        # Arrange
        command = BetfairTestStubs.submit_order_command()
        mock_betfair_request(self.betfair_client, BetfairResponses.betting_place_order_success())

        # Act
        self.client.submit_order(command)
        await asyncio.sleep(0)

        # Assert
        submitted, accepted = self.messages
        assert isinstance(submitted, OrderSubmitted)
        assert isinstance(accepted, OrderAccepted)
        assert accepted.venue_order_id == VenueOrderId("228302937743")
예제 #9
0
 async def test_list_market_catalogue(self):
     market_filter = {
         "eventTypeIds": ["7"],
         "marketBettingTypes": ["ODDS"],
     }
     with mock_client_request(
             response=BetfairResponses.betting_list_market_catalogue(
             )) as mock_request:
         catalogue = await self.client.list_market_catalogue(
             filter_=market_filter)
         assert catalogue
     result = mock_request.call_args.kwargs
     expected = BetfairRequests.betting_list_market_catalogue()
     assert result == expected
    async def test_make_instruments(self):
        # Arrange
        list_market_catalogue_data = {
            m["marketId"]: m
            for m in BetfairResponses.betting_list_market_catalogue()["result"]
            if m["eventType"]["name"] == "Basketball"
        }

        # Act
        instruments = [
            instrument for metadata in list_market_catalogue_data.values()
            for instrument in make_instruments(metadata, currency="GBP")
        ]

        # Assert
        assert len(instruments) == 30412
예제 #11
0
    async def test_list_cleared_orders(self):
        with mock_client_request(
                response=BetfairResponses.list_cleared_orders()) as req:
            cleared_orders = await self.client.list_cleared_orders()
            assert len(cleared_orders) == 14

        expected = {
            "id": 1,
            "jsonrpc": "2.0",
            "method": "SportsAPING/v1.0/listClearedOrders",
            "params": {
                "betStatus": "SETTLED",
                "fromRecord": 0
            },
        }
        result = req.call_args.kwargs["json"]
        assert result == expected
예제 #12
0
    async def test_list_current_orders(self):
        with mock_client_request(
                response=BetfairResponses.list_current_orders()) as req:
            current_orders = await self.client.list_current_orders()
            assert len(current_orders) == 4

        expected = {
            "id": 1,
            "jsonrpc": "2.0",
            "method": "SportsAPING/v1.0/listCurrentOrders",
            "params": {
                "fromRecord": 0,
                "orderBy": "BY_PLACE_TIME"
            },
        }
        result = req.call_args.kwargs["json"]
        assert result == expected
예제 #13
0
    async def test_cancel_order_fail(self):
        # Arrange
        order = BetfairTestStubs.make_submitted_order()
        self.cache.add_order(order, position_id=TestIdStubs.position_id())

        command = BetfairTestStubs.cancel_order_command(
            instrument_id=order.instrument_id,
            client_order_id=order.client_order_id,
            venue_order_id=VenueOrderId("228302937743"),
        )
        mock_betfair_request(self.betfair_client, BetfairResponses.betting_cancel_orders_error())

        # Act
        self.client.cancel_order(command)
        await asyncio.sleep(0)

        # Assert
        pending_cancel, cancelled = self.messages
        assert isinstance(pending_cancel, OrderPendingCancel)
        assert isinstance(cancelled, OrderCancelRejected)
예제 #14
0
    async def test_modify_order_error_no_venue_id(self):
        # Arrange
        order = BetfairTestStubs.make_submitted_order()
        self.cache.add_order(order, position_id=TestIdStubs.position_id())

        command = BetfairTestStubs.modify_order_command(
            instrument_id=order.instrument_id,
            client_order_id=order.client_order_id,
            venue_order_id="",
        )
        mock_betfair_request(self.betfair_client, BetfairResponses.betting_replace_orders_success())

        # Act
        self.client.modify_order(command)
        await asyncio.sleep(0)

        # Assert
        pending_update, rejected = self.messages
        assert isinstance(pending_update, OrderPendingUpdate)
        assert isinstance(rejected, OrderModifyRejected)
        assert rejected.reason == "ORDER MISSING VENUE_ORDER_ID"
예제 #15
0
    async def test_replace_orders_multi(self):
        instrument = BetfairTestStubs.betting_instrument()
        update_order_command = BetfairTestStubs.modify_order_command(
            instrument_id=instrument.id,
            client_order_id=ClientOrderId("1628717246480-1.186260932-rpl-0"),
        )
        replace_order = order_update_to_betfair(
            command=update_order_command,
            venue_order_id=VenueOrderId("240718603398"),
            side=OrderSide.BUY,
            instrument=instrument,
        )
        with mock_client_request(
                response=BetfairResponses.betting_replace_orders_success_multi(
                )) as req:
            resp = await self.client.replace_orders(**replace_order)
            assert len(resp["oc"][0]["orc"][0]["uo"]) == 2

        expected = BetfairRequests.betting_replace_order()
        result = req.call_args.kwargs["json"]
        assert result == expected
예제 #16
0
    async def test_modify_order_error_order_doesnt_exist(self):
        # Arrange
        venue_order_id = VenueOrderId("229435133092")
        order = BetfairTestStubs.make_accepted_order(
            venue_order_id=venue_order_id)

        command = BetfairTestStubs.modify_order_command(
            instrument_id=order.instrument_id,
            client_order_id=order.client_order_id,
            venue_order_id=venue_order_id,
        )
        mock_betfair_request(self.betfair_client,
                             BetfairResponses.betting_replace_orders_success())

        # Act
        self.client.modify_order(command)
        await asyncio.sleep(0)

        # Assert
        pending_update, rejected = self.messages
        assert isinstance(pending_update, OrderPendingUpdate)
        assert isinstance(rejected, OrderModifyRejected)
        assert rejected.reason == "ORDER NOT IN CACHE"
예제 #17
0
    async def test_modify_order_success(self):
        # Arrange
        venue_order_id = VenueOrderId("240808576108")
        order = BetfairTestStubs.make_accepted_order(
            venue_order_id=venue_order_id)
        command = BetfairTestStubs.modify_order_command(
            instrument_id=order.instrument_id,
            client_order_id=order.client_order_id,
            venue_order_id=venue_order_id,
        )
        mock_betfair_request(self.betfair_client,
                             BetfairResponses.betting_replace_orders_success())

        # Act
        self.cache.add_order(order, PositionId("1"))
        self.client.modify_order(command)
        await asyncio.sleep(0)

        # Assert
        pending_update, updated = self.messages
        assert isinstance(pending_update, OrderPendingUpdate)
        assert isinstance(updated, OrderUpdated)
        assert updated.price == Price.from_str("0.02000")