def test_probability_to_price():
    # Exact match
    assert probability_to_price(0.5, side=OrderSide.BUY) == Price("2.0")
    # Rounding match
    assert probability_to_price(0.499, side=OrderSide.BUY) == Price("2.02")
    assert probability_to_price(0.501, side=OrderSide.BUY) == Price("2.0")
    assert probability_to_price(0.501, side=OrderSide.SELL) == Price("1.99")
Exemple #2
0
 def _determine_fill_price(self, update: Dict, order: Order):
     if "avp" not in update:
         # We don't have any specifics about the fill, assume it was filled at our price
         return update["p"]
     if order.filled_qty == 0:
         # New fill, simply return average price
         return update["avp"]
     else:
         new_price = price_to_probability(str(update["avp"]))
         prev_price = order.avg_px
         if prev_price == new_price:
             # Matched at same price
             return update["avp"]
         else:
             prev_price = probability_to_price(order.avg_px)
             prev_size = order.filled_qty
             new_price = Price.from_str(str(update["avp"]))
             new_size = update["sm"] - prev_size
             total_size = prev_size + new_size
             price = (new_price - ((prev_price * (prev_size / total_size)))) / (
                 new_size / total_size
             )
             self._log.debug(
                 f"Calculating fill price {prev_price=} {prev_size=} {new_price=} {new_size=} == {price=}"
             )
             return price
Exemple #3
0
def order_submit_to_betfair(command: SubmitOrder,
                            instrument: BettingInstrument,
                            customer_ref="1"):
    """ Convert a SubmitOrder command into the data required by betfairlightweight """

    order = command.order  # type: LimitOrder
    return {
        "market_id":
        instrument.market_id,
        # Used to de-dupe orders on betfair server side
        "customer_ref":
        order.client_order_id.value,
        "customer_strategy_ref":
        customer_ref,
        "instructions": [
            place_instruction(
                order_type="LIMIT",
                selection_id=instrument.selection_id,
                side=N2B_SIDE[order.side],
                handicap={"0.0": "0"}.get(instrument.selection_handicap,
                                          instrument.selection_handicap),
                limit_order=limit_order(
                    size=float(order.quantity),
                    price=float(
                        probability_to_price(probability=order.price,
                                             side=order.side)),
                    persistence_type="PERSIST",
                    time_in_force=N2B_TIME_IN_FORCE[order.time_in_force],
                    min_fill_size=0,
                ),
                customer_order_ref=order.client_order_id.value,
            )
        ],
    }
def _probability_to_price(probability: Price, side: OrderSide):
    if side == OrderSide.BUY:
        tick_prob = BETFAIR_TICK_SCHEME.next_bid_price(value=probability)
    elif side == OrderSide.SELL:
        tick_prob = BETFAIR_TICK_SCHEME.next_ask_price(value=probability)
    else:
        raise RuntimeError(f"invalid OrderSide, was {side}")
    return probability_to_price(probability=tick_prob)
def order_submit_to_betfair(command: SubmitOrder,
                            instrument: BettingInstrument):
    """
    Convert a SubmitOrder command into the data required by betfairlightweight
    """

    order = command.order  # type Order
    price = determine_order_price(order)

    return {
        "market_id":
        instrument.market_id,
        # Used to de-dupe orders on betfair server side
        "customer_ref":
        command.id.value.replace("-", ""),
        "customer_strategy_ref":
        command.strategy_id.value[:15],
        "instructions": [
            place_instruction(
                order_type="LIMIT",
                selection_id=instrument.selection_id,
                side=N2B_SIDE[order.side],
                handicap={"0.0": "0"}.get(instrument.selection_handicap,
                                          instrument.selection_handicap),
                limit_order=limit_order(
                    size=float(order.quantity),
                    price=float(
                        probability_to_price(probability=price,
                                             side=order.side)),
                    persistence_type="PERSIST",
                    time_in_force=N2B_TIME_IN_FORCE[order.time_in_force],
                    min_fill_size=0,
                ),
                # Remove the strategy name from customer_order_ref; it has a limited size and we don't control what
                # length the strategy might be or what characters users might append
                customer_order_ref=make_custom_order_ref(
                    client_order_id=order.client_order_id,
                    strategy_id=command.strategy_id,
                ),
            )
        ],
    }
Exemple #6
0
def order_update_to_betfair(
    command: UpdateOrder,
    venue_order_id: VenueOrderId,
    side: OrderSide,
    instrument: BettingInstrument,
):
    """ Convert an UpdateOrder command into the data required by betfairlightweight """
    return {
        "market_id":
        instrument.market_id,
        "customer_ref":
        command.client_order_id.value,
        "instructions": [
            replace_instruction(
                bet_id=venue_order_id.value,
                new_price=float(
                    probability_to_price(probability=command.price,
                                         side=side)),
            )
        ],
    }
Exemple #7
0
 def test_probability_to_price(self, raw_prob, price):
     # Exact match
     prob = self.tick_scheme.next_bid_price(raw_prob)
     assert probability_to_price(prob) == Price.from_str(price)