Skip to content

Advanced

Locale

Betfair uses slightly different endpoints depending on your country of residence, these can be used by changing the locale on client initialisation:

>>> trading = betfairlightweight.APIClient(
        "username", 
        "password", 
        app_key="app_key", 
        locale="italy"
    )
  • spain
  • italy
  • romania
  • sweden
  • australia

NEMID Login

Danish residents are restricted in how they login due to NemID requirements, this can be handled by replicating the login flow:

import re
import betfairlightweight

trading = betfairlightweight.APIClient("username", "password", app_key="app_key")

resp = trading.session.post(
    url=trading.login_interactive.url,
    data={
        "username": trading.username,
        "password": trading.password,
        "redirectMethod": "POST",
        "product": trading.app_key,
        "url": "https://www.betfair.com",
        "submitForm": True,
    }
)
session_token = re.findall(
    "ssoid=(.*?);", resp.headers["Set-Cookie"]
)
trading.set_session_token(session_token[0])

print(trading.betting.list_event_types())

Session

The client assumes requests is used for the http requests but other clients can be used if required, a session object can be passed to the client:

>>> session = requests.session()
>>> trading = betfairlightweight.APIClient(
        "username", 
        "password", 
        app_key="app_key", 
        session=session,
    )

or on a per requests basis:

>>> trading.betting.list_event_types(
        filter=filters.market_filter(
            text_query='Horse Racing'
        ),
        session=session,
    )

Response

The response object contains the following extra attributes:

>>> response = trading.betting.list_event_types(
        filter=filters.market_filter(
            text_query='Horse Racing'
        ),
        session=session,
    )

Raw data / json response:

>>> response[0]._data
{'eventType': {'id': '7', 'name': 'Horse Racing'}, 'marketCount': 328}

>>> response[0].json()
{"eventType":{"id":"7","name":"Horse Racing"},"marketCount":328}

Elapsed, created and updated time:

>>> response[0].elapsed_time
0.14815688133239746

>>> response[0]._datetime_created
2020-01-27 09:56:32.984387

>>> response[0]._datetime_updated
2020-01-27 09:56:32.984387

Raw requests response object:

>>> response[0]._response
<Response [200]>

Lightweight

In order to return the raw json you can select lightweight on client initialization:

>>> trading = betfairlightweight.APIClient(
        "username", 
        "password", 
        app_key="app_key", 
        certs="/certs", 
        lightweight=True,
    )
>>> trading.login()
{'sessionToken': 'dfgrtegreg===rgrgr', 'loginStatus': 'SUCCESS'}

or on a per request basis:

>>> trading.betting.list_event_types(
        filter=filters.market_filter(
            text_query='Horse Racing'
        ),
        lightweight=True,
    )
[{'eventType': {'id': '7', 'name': 'Horse Racing'}, 'marketCount': 328}]

Hint

Because lightweight means python doesn't need to create objects it can be considerably faster but harder to work with.

Dependencies

By default betfairlightweight will install C and Rust based libraries if your os is either linux or darwin (Mac), due to difficulties in installation Windows users can install them separately:

$ pip install betfairlightweight[speed]

Hint

If using windows it is likely that visual studio will need to be installed as well.

Performance

As detailed above using lightweight mode and the [speed] install improves the performance of bflw however it is possible to further improve the speed of backtesting by setting the following on the Listener:

listener = betfairlightweight.StreamListener(
    max_latency=None,  # ignore latency errors
    output_queue=None,  # use generator rather than a queue (faster)
    lightweight=True,  # lightweight mode is faster
    update_clk=False,  # do not update clk on updates (not required when backtesting)
)

For any further inspiration on speeding up backtesting have a read of the flumine source code, especially patching.py and historicalstream.py