def process_market_book(self, market, market_book): for runner in market_book.runners: if runner.last_price_traded < 2: lay = get_price(runner.ex.available_to_lay, 0) trade = Trade( market_book.market_id, runner.selection_id, runner.handicap, self, ) order = trade.create_order( side="LAY", order_type=LimitOrder(lay, 2.00), ) self.place_order(market, order)
def process_market_book(self, market, market_book): # process marketBook object for runner in market_book.runners: if (runner.status == "ACTIVE" and runner.last_price_traded and runner.selection_id == 11982403): trade = Trade( market_id=market_book.market_id, selection_id=runner.selection_id, handicap=runner.handicap, strategy=self, ) order = trade.create_order(side="LAY", order_type=LimitOrder(price=1.01, size=2.00)) self.place_order(market, order)
def test_selection_exposure_voided(self): mock_strategy = mock.Mock() mock_trade = mock.Mock(strategy=mock_strategy) mock_order = mock.Mock( trade=mock_trade, lookup=(self.blotter.market_id, 123, 0), side="BACK", order_type=LimitOrder(price=5, size=10.0), status=OrderStatus.VIOLATION, ) self.blotter._orders = {"12345": mock_order} self.assertEqual( self.blotter.selection_exposure(mock_strategy, mock_order.lookup), 0, )
def test_get_exposures_with_exclusion(self): mock_strategy = mock.Mock() mock_trade = mock.Mock(strategy=mock_strategy) mock_order = mock.Mock( trade=mock_trade, lookup=(self.blotter.market_id, 123, 0), side="BACK", average_price_matched=5.6, size_matched=2.0, size_remaining=0.0, order_type=LimitOrder(price=5.6, size=2.0), ) mock_order_excluded = mock.Mock( trade=mock_trade, lookup=(self.blotter.market_id, 123, 0), side="BACK", average_price_matched=5.6, size_matched=2.0, size_remaining=0.0, order_type=LimitOrder(price=5.6, size=2.0), ) self.blotter["12345"] = mock_order self.blotter["67890"] = mock_order_excluded self.assertEqual( self.blotter.get_exposures(mock_strategy, mock_order.lookup, exclusion=mock_order_excluded), { "matched_profit_if_lose": -2.0, "matched_profit_if_win": 9.2, "worst_possible_profit_on_lose": -2.0, "worst_possible_profit_on_win": 9.2, "worst_potential_unmatched_profit_if_lose": 0.0, "worst_potential_unmatched_profit_if_win": 0.0, }, )
def test_selection_exposure(self): mock_strategy = mock.Mock() mock_trade = mock.Mock(strategy=mock_strategy) mock_order = mock.Mock( trade=mock_trade, lookup=(self.blotter.market_id, 123, 0), side="BACK", average_price_matched=5.6, size_matched=2.0, size_remaining=0.0, order_type=LimitOrder(price=5.6, size=2.0), ) self.blotter["12345"] = mock_order self.assertEqual( self.blotter.selection_exposure(mock_strategy, mock_order.lookup), 2.0, )
def process_market_book(self, market, market_book): with market.transaction() as t: for runner in market_book.runners: if runner.status == "ACTIVE": runner_context = self.get_runner_context( market.market_id, runner.selection_id) if runner_context.trade_count == 0: trade = Trade( market_book.market_id, runner.selection_id, runner.handicap, self, ) order = trade.create_order( side="BACK", order_type=LimitOrder(1000, 2.00), ) t.place_order(order)
def test_selection_exposure_from_unmatched_lay(self): mock_strategy = mock.Mock() mock_trade = mock.Mock(strategy=mock_strategy) mock_order = mock.Mock( trade=mock_trade, lookup=(self.blotter.market_id, 123, 0), side="LAY", average_price_matched=5.6, size_matched=2.0, size_remaining=2.0, order_type=LimitOrder(price=6, size=4.0), ) self.blotter["12345"] = mock_order # On the win side, we have -2.0 * (5.6-1.0) -2.0 * (6.0-1.0) = -19.2 # On the lose side, we have 2.0 from size_matched self.assertEqual( self.blotter.selection_exposure(mock_strategy, mock_order.lookup), 19.2, )
class LimitOrderTest(unittest.TestCase): def setUp(self) -> None: self.order_type = LimitOrder(1.01, 2, "PERSIST", "YES", 34.5, "NO", 2) def test_init(self): self.assertEqual(self.order_type.EXCHANGE, ExchangeType.BETFAIR) self.assertEqual(self.order_type.ORDER_TYPE, OrderTypes.LIMIT) self.assertEqual(self.order_type.price, 1.01) self.assertEqual(self.order_type.size, 2) self.assertEqual(self.order_type.persistence_type, "PERSIST") self.assertEqual(self.order_type.time_in_force, "YES") self.assertEqual(self.order_type.min_fill_size, 34.5) self.assertEqual(self.order_type.bet_target_type, "NO") self.assertEqual(self.order_type.bet_target_size, 2) def test_place_instruction(self): self.assertEqual( self.order_type.place_instruction(), { "betTargetSize": 2, "betTargetType": "NO", "minFillSize": 34.5, "persistenceType": "PERSIST", "price": 1.01, "size": 2, "timeInForce": "YES", }, ) def test_info(self): self.assertEqual( self.order_type.info, { "bet_target_size": 2, "bet_target_type": "NO", "min_fill_size": 34.5, "order_type": "Limit", "persistence_type": "PERSIST", "price": 1.01, "size": 2, "time_in_force": "YES", }, )
def process_market_book(self, market, market_book): with market.transaction(client=self.context["client"]) as t: for runner in market_book.runners: if runner.status == "ACTIVE": back = get_price(runner.ex.available_to_back, 0) runner_context = self.get_runner_context( market.market_id, runner.selection_id) if runner_context.trade_count == 0: trade = Trade( market_book.market_id, runner.selection_id, runner.handicap, self, ) order = trade.create_order( side="BACK", order_type=LimitOrder(back, 2.00), ) t.place_order(order)
def test_selection_exposure_from_unmatched_back(self): mock_strategy = mock.Mock() mock_trade = mock.Mock(strategy=mock_strategy) mock_order = mock.Mock( trade=mock_trade, lookup=(self.blotter.market_id, 123, 0), side="BACK", average_price_matched=5.6, size_matched=2.0, size_remaining=2.0, order_type=LimitOrder(price=6, size=4.0), ) self.blotter._orders = {"12345": mock_order} # On the win side, we have 2.0 * (5.6-1.0) = 9.2 # On the lose side, we have -2.0-2.0=-4.0 self.assertEqual( self.blotter.selection_exposure(mock_strategy, mock_order.lookup), 4.0, )
def process_market_book(self, market, market_book): seconds_since_start = (market_book.publish_time_epoch - market.context["start_time"]) / 1e3 # get price dict from market context if "price" not in market.context: market.context["price"] = defaultdict(list) price_dict = market.context["price"] for runner in market_book.runners: # store latest prices/sizes back_price = get_price(runner.ex.available_to_back, 0) back_size = get_size(runner.ex.available_to_back, 0) if back_price: price_dict[runner.selection_id].append( (market_book.publish_time_epoch, back_price, back_size)) # check trigger if trigger(price_dict[runner.selection_id]): runner_context = self.get_runner_context( market.market_id, runner.selection_id, runner.handicap) if runner_context.live_trade_count == 0: # back at current best back price back = get_price(runner.ex.available_to_back, 0) if back is None: continue # create trade trade = Trade( market_book.market_id, runner.selection_id, runner.handicap, self, ) # create order order = trade.create_order( side="BACK", order_type=LimitOrder(back, self.context["stake"]), notes=OrderedDict( seconds_since_start=round(seconds_since_start, 2), back_size=back_size, ), ) # place order for execution market.place_order(order)
def test_get_exposures_voided(self): mock_strategy = mock.Mock() mock_trade = mock.Mock(strategy=mock_strategy) mock_order = mock.Mock( trade=mock_trade, lookup=(self.blotter.market_id, 123, 0), side="BACK", order_type=LimitOrder(price=5, size=10.0), status=OrderStatus.VIOLATION, ) self.blotter["12345"] = mock_order self.assertEqual( self.blotter.get_exposures(mock_strategy, mock_order.lookup), { "matched_profit_if_lose": 0.0, "matched_profit_if_win": 0.0, "worst_possible_profit_on_lose": 0.0, "worst_possible_profit_on_win": 0.0, "worst_potential_unmatched_profit_if_lose": 0.0, "worst_potential_unmatched_profit_if_win": 0.0, }, )
def process_market_book(self, market, market_book): # get lowest price runner prices = [(r.selection_id, r.last_price_traded) for r in market_book.runners if r.status == "ACTIVE" and r.last_price_traded] if not prices: return prices.sort(key=lambda tup: tup[1]) selection_id = prices[0][0] if prices[0][1] > 3: return # calculate market underround for later analysis underround = _calculate_underround(market_book.runners) for runner in market_book.runners: if runner.selection_id == selection_id: runner_context = self.get_runner_context( market.market_id, runner.selection_id, runner.handicap) if runner_context.live_trade_count == 0: # lay at current best lay price lay = get_price(runner.ex.available_to_lay, 0) # create trade trade = Trade( market_book.market_id, runner.selection_id, runner.handicap, self, ) # create order order = trade.create_order( side="LAY", order_type=LimitOrder(lay, self.context["stake"]), notes=OrderedDict(underround=round(underround, 4)), ) # place order for execution market.place_order(order)
def process_market_book(self, market, market_book): # get context selections = self.context["selections"] for selection in selections: if market_book.market_id == selection["market_id"]: for runner in market_book.runners: runner_context = self.get_runner_context( market.market_id, runner.selection_id, runner.handicap) if runner_context.trade_count > 0: continue if (runner.status == "ACTIVE" and runner.selection_id == selection["selection_id"]): trade = Trade( market_id=market_book.market_id, selection_id=runner.selection_id, handicap=runner.handicap, strategy=self, ) order = trade.create_order( side=selection["side"], order_type=LimitOrder(price=1.01, size=selection["liability"]), ) market.place_order(order)
def setUp(self) -> None: self.order_type = LimitOrder(1.01, 2, "PERSIST", "YES", 34.5, "NO", 2)