diff --git a/betfairutil/__init__.py b/betfairutil/__init__.py index 4a108af..f81c30d 100644 --- a/betfairutil/__init__.py +++ b/betfairutil/__init__.py @@ -1540,6 +1540,37 @@ def calculate_book_percentage( return sum(implied_probabilities) +def calculate_available_volume( + market_book: Union[Dict[str, Any], MarketBook], + side: Side, + max_book_percentage: float, +) -> float: + """ + Calculate the available volume up to a maximum book_percentage value. + + :param market_book: A market book either as a dictionary or betfairlightweight MarketBook object + :param side: Indicate whether to get the available volume on the back or lay side. + :param max_book_percentage: Maximum book_percentage value to use for calculating the volume. + :return: Available total volume. + """ + available_volume = 0 + for depth in itertools.count(): + book_percentage = 0 + size = 0 + for runner in market_book["runners"]: + runner_price_size = get_price_size_by_depth( + runner=runner, side=side, depth=depth + ) + if runner_price_size: + book_percentage += 1.0 / runner_price_size["price"] + size += runner_price_size["size"] + else: + return available_volume + + if book_percentage <= max_book_percentage: + available_volume += size + + def calculate_market_book_diff( current_market_book: Union[Dict[str, Any], MarketBook], previous_market_book: Union[Dict[str, Any], MarketBook], diff --git a/tests/test_non_prices.py b/tests/test_non_prices.py index eebe1af..380efa2 100644 --- a/tests/test_non_prices.py +++ b/tests/test_non_prices.py @@ -13,6 +13,7 @@ from betfairlightweight.resources import RunnerBook from pyrsistent import pmap +from betfairutil import calculate_available_volume from betfairutil import calculate_book_percentage from betfairutil import calculate_market_book_diff from betfairutil import calculate_order_book_imbalance @@ -1119,3 +1120,16 @@ def test_get_first_market_definition_from_prices_file( def test_get_winners_from_prices_file(path_to_prices_file: Path): assert get_winners_from_prices_file(path_to_prices_file) == [] + + +def test_calculate_available_volume(market_book: Dict[str, Any]): + assert calculate_available_volume(market_book, Side.BACK, 1.05) == 2 + + market_book["runners"][0]["ex"]["availableToBack"].append( + {"price": 1.96, "size": 1} + ) + market_book["runners"][1]["ex"]["availableToBack"].append( + {"price": 1.96, "size": 1} + ) + assert calculate_available_volume(market_book, Side.BACK, 1.05) == 4 + assert calculate_available_volume(market_book, Side.BACK, 1.02) == 2