Exemple #1
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"]
        prices.sort(key=lambda tup: tup[1])
        selection_id = prices[0][0]

        if prices[0][1] > 3:
            return

        for runner in market_book.runners:
            if runner.selection_id == selection_id:
                # lay at current best lay price
                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, self.context["stake"]),
                )
                self.place_order(market, order)
Exemple #2
0
 def setUp(self) -> None:
     logging.disable(logging.CRITICAL)
     mock_client = mock.Mock(paper_trade=False)
     self.mock_strategy = mock.Mock(client=mock_client)
     self.notes = collections.OrderedDict({"trigger": 123})
     self.trade = Trade(
         "1.234",
         567,
         1.0,
         self.mock_strategy,
         self.notes,
         12,
         34,
     )
Exemple #3
0
 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)
Exemple #4
0
 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)
Exemple #5
0
 def process_market_book(self, market, market_book):
     for runner in market_book.runners:
         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="LAY", order_type=MarketOnCloseOrder(100.00),
             )
             self.place_order(market, order)
Exemple #6
0
 def setUp(self) -> None:
     logging.disable(logging.CRITICAL)
     self.mock_strategy = mock.Mock()
     self.mock_fill_kill = mock.Mock()
     self.mock_offset = mock.Mock()
     self.mock_green = mock.Mock()
     self.notes = collections.OrderedDict({"trigger": 123})
     self.trade = Trade(
         "1.234",
         567,
         1.0,
         self.mock_strategy,
         self.notes,
         self.mock_fill_kill,
         self.mock_offset,
         self.mock_green,
     )
Exemple #7
0
 def _create_order_from_current(self, client, current_order, market):
     strategy_name_hash = current_order.customer_order_ref[:
                                                           STRATEGY_NAME_HASH_LENGTH]
     order_id = current_order.customer_order_ref[STRATEGY_NAME_HASH_LENGTH +
                                                 1:]
     # get strategy
     strategy = self.flumine.strategies.hashes.get(strategy_name_hash)
     if strategy is None:
         logger.warning(
             "OrdersMiddleware: Strategy not available to create order {0}".
             format(order_id),
             extra={
                 "bet_id": current_order.bet_id,
                 "market_id": current_order.market_id,
                 "customer_strategy_ref":
                 current_order.customer_strategy_ref,
                 "customer_order_ref": current_order.customer_order_ref,
                 "strategy_name": str(strategy),
                 "client_username": client.username,
             },
         )
         return
     # add trade/order
     trade = Trade(
         market.market_id,
         current_order.selection_id,
         current_order.handicap,
         strategy,
     )
     order = trade.create_order_from_current(client, current_order,
                                             order_id)
     market.blotter[order.id] = order
     runner_context = strategy.get_runner_context(*order.lookup)
     runner_context.place(trade.id)
     logger.info(
         "OrdersMiddleware: New order trade created",
         extra={
             "bet_id": current_order.bet_id,
             "market_id": current_order.market_id,
             "customer_strategy_ref": current_order.customer_strategy_ref,
             "customer_order_ref": current_order.customer_order_ref,
             "strategy_name": str(strategy),
             "client_username": client.username,
         },
     )
     return order
Exemple #8
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 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)
Exemple #10
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)
Exemple #11
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)
Exemple #12
0
 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)
Exemple #13
0
class TradeTest(unittest.TestCase):
    def setUp(self) -> None:
        logging.disable(logging.CRITICAL)
        mock_client = mock.Mock(paper_trade=False)
        self.mock_strategy = mock.Mock(client=mock_client)
        self.mock_fill_kill = mock.Mock()
        self.mock_offset = mock.Mock()
        self.mock_green = mock.Mock()
        self.notes = collections.OrderedDict({"trigger": 123})
        self.trade = Trade(
            "1.234",
            567,
            1.0,
            self.mock_strategy,
            self.notes,
            self.mock_fill_kill,
            self.mock_offset,
            self.mock_green,
            12,
            34,
        )

    def test_init(self):
        self.assertEqual(self.trade.market_id, "1.234")
        self.assertEqual(self.trade.selection_id, 567)
        self.assertEqual(self.trade.handicap, 1.0)
        self.assertEqual(self.trade.strategy, self.mock_strategy)
        self.assertEqual(self.trade.notes, self.notes)
        self.assertEqual(self.trade.fill_kill, self.mock_fill_kill)
        self.assertEqual(self.trade.offset, self.mock_offset)
        self.assertEqual(self.trade.green, self.mock_green)
        self.assertEqual(self.trade.status_log, [])
        self.assertEqual(self.trade.orders, [])
        self.assertEqual(self.trade.offset_orders, [])
        self.assertIsNotNone(self.trade.date_time_created)
        self.assertIsNone(self.trade.date_time_complete)
        self.assertIsNone(self.trade.market_notes)
        self.assertEqual(self.trade.place_reset_seconds, 12)
        self.assertEqual(self.trade.reset_seconds, 34)

    @mock.patch("flumine.order.trade.get_market_notes")
    def test_update_market_notes(self, mock_get_market_notes):
        mock_market = mock.Mock()
        self.trade.update_market_notes(mock_market)
        self.assertEqual(self.trade.market_notes, mock_get_market_notes())

    def test__update_status(self):
        self.trade._update_status(TradeStatus.COMPLETE)
        self.assertEqual(self.trade.status_log, [TradeStatus.COMPLETE])
        self.assertEqual(self.trade.status, TradeStatus.COMPLETE)

    @mock.patch("flumine.order.trade.Trade._update_status")
    def test_complete_trade(self, mock__update_status):
        self.trade.complete_trade()
        mock__update_status.assert_called_with(TradeStatus.COMPLETE)
        runner_context = self.mock_strategy.get_runner_context(
            self.trade.market_id, self.trade.selection_id, self.trade.handicap
        )
        runner_context.reset.assert_called_with()
        self.assertIsNotNone(self.trade.date_time_complete)

    def test_complete(self):
        self.assertTrue(self.trade.complete)
        mock_order = mock.Mock(complete=False)
        self.trade.orders.append(mock_order)
        self.assertFalse(self.trade.complete)

    def test_trade_complete_offset(self):
        self.trade.offset_orders = [1]
        self.assertFalse(self.trade.complete)

    def test_trade_complete_replace_order(self):
        self.assertTrue(self.trade.complete)
        mock_order = mock.Mock(complete=True)
        self.trade.status = TradeStatus.COMPLETE
        self.trade.orders.append(mock_order)
        self.assertFalse(self.trade.complete)

    def test_create_order(self):
        mock_order_type = mock.Mock()
        mock_order_type.EXCHANGE = "SYM"
        mock_order = mock.Mock()
        mock_order.EXCHANGE = "SYM"
        self.trade.create_order("BACK", mock_order_type, handicap=1, order=mock_order)
        self.assertEqual(self.trade.orders, [mock_order()])

    def test_create_order_error(self):
        mock_order_type = mock.Mock()
        mock_order_type.EXCHANGE = "SYM"
        mock_order = mock.Mock()
        mock_order.EXCHANGE = "MYS"
        with self.assertRaises(OrderError):
            self.trade.create_order(
                "BACK", mock_order_type, handicap=1, order=mock_order
            )

    def test_create_order_replacement(self):
        mock_order = mock.Mock()
        replacement_order = self.trade.create_order_replacement(mock_order, 12)
        self.assertEqual(self.trade.orders, [replacement_order])

    def test_create_order_from_current_limit(self):
        mock_current_order = mock.Mock()
        mock_current_order.order_type = "LIMIT"
        order = self.trade.create_order_from_current(mock_current_order, "12345")
        self.assertEqual(order.bet_id, mock_current_order.bet_id)
        self.assertEqual(order.id, "12345")
        self.assertEqual(self.trade.orders, [order])

    def test_create_order_from_current_limit_on_close(self):
        mock_current_order = mock.Mock()
        mock_current_order.order_type = "LIMIT_ON_CLOSE"
        order = self.trade.create_order_from_current(mock_current_order, "12345")
        self.assertEqual(order.bet_id, mock_current_order.bet_id)
        self.assertEqual(order.id, "12345")
        self.assertEqual(self.trade.orders, [order])

    def test_create_order_from_current_market_on_close(self):
        mock_current_order = mock.Mock()
        mock_current_order.order_type = "MARKET_ON_CLOSE"
        order = self.trade.create_order_from_current(mock_current_order, "12345")
        self.assertEqual(order.bet_id, mock_current_order.bet_id)
        self.assertEqual(order.id, "12345")
        self.assertEqual(self.trade.orders, [order])

    def test_create_order_from_current_unknown(self):
        mock_current_order = mock.Mock()
        mock_current_order.order_type = "BE"
        with self.assertRaises(NotImplementedError):
            self.trade.create_order_from_current(mock_current_order, "12345")

    def test_client(self):
        self.assertEqual(self.trade.client, self.mock_strategy.client)

    def test_notes_str(self):
        self.trade.notes = collections.OrderedDict({"1": 1, 2: "2", 3: 3, 4: "four"})
        # self.assertEqual(self.trade.notes_str, "1,2,3,four")
        self.trade.notes = collections.OrderedDict()
        self.assertEqual(self.trade.notes_str, "")

    def test_info(self):
        self.assertEqual(
            self.trade.info,
            {
                "id": self.trade.id,
                "orders": [],
                "status": TradeStatus.LIVE,
                "strategy": self.mock_strategy,
                "notes": "123",
                "market_notes": None,
            },
        )

    @mock.patch("flumine.order.trade.Trade._update_status")
    def test_enter_exit(self, mock__update_status):
        with self.trade:
            mock__update_status.assert_called_with(TradeStatus.PENDING)
        mock__update_status.assert_called_with(TradeStatus.LIVE)

    @mock.patch("flumine.order.trade.Trade._update_status")
    def test_enter_error(self, mock__update_status):
        with self.assertRaises(ValueError):
            with self.trade:
                raise ValueError()
        mock__update_status.assert_called_with(TradeStatus.PENDING)
Exemple #14
0
class TradeTest(unittest.TestCase):
    def setUp(self) -> None:
        logging.disable(logging.CRITICAL)
        mock_client = mock.Mock(paper_trade=False)
        self.mock_strategy = mock.Mock(client=mock_client)
        self.notes = collections.OrderedDict({"trigger": 123})
        self.trade = Trade(
            "1.234",
            567,
            1.0,
            self.mock_strategy,
            self.notes,
            12,
            34,
        )

    def test_init(self):
        self.assertEqual(self.trade.market_id, "1.234")
        self.assertEqual(self.trade.selection_id, 567)
        self.assertEqual(self.trade.handicap, 1.0)
        self.assertEqual(self.trade.strategy, self.mock_strategy)
        self.assertEqual(self.trade.notes, self.notes)
        self.assertEqual(self.trade.status_log, [])
        self.assertEqual(self.trade.orders, [])
        self.assertEqual(self.trade.offset_orders, [])
        self.assertIsNotNone(self.trade.date_time_created)
        self.assertIsNone(self.trade.date_time_complete)
        self.assertIsNone(self.trade.market_notes)
        self.assertEqual(self.trade.place_reset_seconds, 12)
        self.assertEqual(self.trade.reset_seconds, 34)

    @mock.patch("flumine.order.trade.Trade.complete_trade")
    @mock.patch(
        "flumine.order.trade.Trade.complete",
        new_callable=mock.PropertyMock,
        return_value=True,
    )
    def test__update_status(self, mock_complete, mock_complete_trade):
        self.trade._update_status(TradeStatus.COMPLETE)
        self.assertEqual(self.trade.status_log, [TradeStatus.COMPLETE])
        self.assertEqual(self.trade.status, TradeStatus.COMPLETE)
        mock_complete_trade.assert_called()

    @mock.patch("flumine.order.trade.Trade._update_status")
    def test_complete_trade(self, mock__update_status):
        self.trade.complete_trade()
        mock__update_status.assert_called_with(TradeStatus.COMPLETE)
        runner_context = self.mock_strategy.get_runner_context(
            self.trade.market_id, self.trade.selection_id, self.trade.handicap
        )
        runner_context.reset.assert_called_with(self.trade.id)
        self.assertIsNotNone(self.trade.date_time_complete)

    def test_complete(self):
        self.assertTrue(self.trade.complete)
        mock_order = mock.Mock(complete=False)
        self.trade.orders.append(mock_order)
        self.assertFalse(self.trade.complete)

    def test_trade_complete_offset(self):
        self.trade.offset_orders = [mock.Mock(complete=False)]
        self.assertFalse(self.trade.complete)
        self.trade.offset_orders = [mock.Mock(complete=True)]
        self.assertTrue(self.trade.complete)

    def test_trade_complete_replace_order(self):
        self.assertTrue(self.trade.complete)
        mock_order = mock.Mock(complete=True)
        self.trade.status = TradeStatus.COMPLETE
        self.trade.orders.append(mock_order)
        self.assertFalse(self.trade.complete)

    def test_create_order(self):
        mock_order_type = mock.Mock(EXCHANGE="SYM")
        mock_order = mock.Mock(EXCHANGE="SYM")
        self.trade.create_order(
            "BACK", mock_order_type, order=mock_order, sep="-", context={1: 2}
        )
        mock_order.assert_called_with(
            trade=self.trade,
            side="BACK",
            order_type=mock_order_type,
            handicap=self.trade.handicap,
            sep="-",
            context={1: 2},
            notes=None,
        )
        self.assertEqual(self.trade.orders, [mock_order()])

    def test_create_order_error(self):
        mock_order_type = mock.Mock(EXCHANGE="SYM")
        mock_order = mock.Mock(EXCHANGE="MYS")
        with self.assertRaises(OrderError):
            self.trade.create_order("BACK", mock_order_type, order=mock_order)

    def test_create_order_replacement(self):
        mock_order = mock.Mock(sep="-")
        replacement_order = self.trade.create_order_replacement(mock_order, 12, 2.00)
        self.assertEqual(self.trade.orders, [replacement_order])
        self.assertEqual(replacement_order.trade, self.trade)
        self.assertEqual(replacement_order.side, mock_order.side)
        self.assertEqual(replacement_order.order_type.price, 12)
        self.assertEqual(replacement_order.order_type.size, 2.00)
        self.assertEqual(
            replacement_order.order_type.persistence_type,
            mock_order.order_type.persistence_type,
        )
        self.assertEqual(replacement_order.handicap, mock_order.handicap)
        self.assertEqual(replacement_order.sep, mock_order.sep)
        self.assertEqual(replacement_order.context, mock_order.context)
        self.assertEqual(replacement_order.notes, mock_order.notes)
        self.assertEqual(replacement_order.client, mock_order.client)

    def test_create_order_from_current_limit(self):
        mock_client = mock.Mock()
        mock_current_order = mock.Mock(
            order_type="LIMIT", placed_date=12, matched_date=None, cancelled_date=34
        )
        order = self.trade.create_order_from_current(
            mock_client, mock_current_order, "12345"
        )
        self.assertEqual(order.bet_id, mock_current_order.bet_id)
        self.assertEqual(order.id, "12345")
        self.assertEqual(order.client, mock_client)
        self.assertEqual(self.trade.orders, [order])
        self.assertEqual(order.date_time_created, 12)
        self.assertEqual(order.date_time_execution_complete, 34)

    def test_create_order_from_current_limit_on_close(self):
        mock_client = mock.Mock()
        mock_current_order = mock.Mock(order_type="LIMIT_ON_CLOSE")
        order = self.trade.create_order_from_current(
            mock_client, mock_current_order, "12345"
        )
        self.assertEqual(order.bet_id, mock_current_order.bet_id)
        self.assertEqual(order.id, "12345")
        self.assertEqual(order.client, mock_client)
        self.assertEqual(self.trade.orders, [order])

    def test_create_order_from_current_market_on_close(self):
        mock_client = mock.Mock()
        mock_current_order = mock.Mock(order_type="MARKET_ON_CLOSE")
        order = self.trade.create_order_from_current(
            mock_client, mock_current_order, "12345"
        )
        self.assertEqual(order.bet_id, mock_current_order.bet_id)
        self.assertEqual(order.id, "12345")
        self.assertEqual(order.client, mock_client)
        self.assertEqual(self.trade.orders, [order])

    def test_create_order_from_current_unknown(self):
        mock_client = mock.Mock()
        mock_current_order = mock.Mock(order_type="BE")
        with self.assertRaises(NotImplementedError):
            self.trade.create_order_from_current(
                mock_client, mock_current_order, "12345"
            )

    def test_notes_str(self):
        self.trade.notes = collections.OrderedDict({"1": 1, 2: "2", 3: 3, 4: "four"})
        self.assertEqual(self.trade.notes_str, "1,2,3,four")
        self.trade.notes = collections.OrderedDict()
        self.assertEqual(self.trade.notes_str, "")

    def test_info(self):
        self.trade.status_log = [TradeStatus.PENDING, TradeStatus.COMPLETE]
        self.assertEqual(
            self.trade.info,
            {
                "id": str(self.trade.id),
                "orders": [],
                "offset_orders": [],
                "place_reset_seconds": 12,
                "reset_seconds": 34,
                "strategy": str(self.mock_strategy),
                "notes": "123",
                "market_notes": None,
                "status": "Live",
                "status_log": "Pending, Complete",
            },
        )

    @mock.patch("flumine.order.trade.Trade._update_status")
    def test_enter_exit(self, mock__update_status):
        with self.trade:
            mock__update_status.assert_called_with(TradeStatus.PENDING)
        mock__update_status.assert_called_with(TradeStatus.LIVE)

    @mock.patch("flumine.order.trade.Trade._update_status")
    def test_enter_error(self, mock__update_status):
        with self.assertRaises(ValueError):
            with self.trade:
                raise ValueError()
        mock__update_status.assert_called_with(TradeStatus.PENDING)