class BetfairOrderTest(unittest.TestCase): def setUp(self) -> None: mock_client = mock.Mock(paper_trade=False) self.mock_trade = mock.Mock(client=mock_client, market_id="1.1", selection_id=123, info={}) self.mock_status = mock.Mock() self.mock_order_type = mock.Mock(info={}, size=2.0, liability=2.0) self.order = BetfairOrder(self.mock_trade, "BACK", self.mock_order_type) def test_init(self): self.assertEqual(self.order.EXCHANGE, ExchangeType.BETFAIR) @mock.patch("flumine.order.order.BetfairOrder.placing") def test_place(self, mock_placing): self.order.place(123) mock_placing.assert_called_with() self.assertEqual(self.order.publish_time, 123) @mock.patch( "flumine.order.order.BetfairOrder.size_remaining", new_callable=mock.PropertyMock, ) @mock.patch("flumine.order.order.BetfairOrder.cancelling") def test_cancel(self, mock_cancelling, mock_size_remaining): mock_size_remaining.return_value = 20 self.order.bet_id = 123 self.order.status = OrderStatus.EXECUTABLE with self.assertRaises(OrderUpdateError): self.order.cancel(12) self.mock_order_type.ORDER_TYPE = OrderTypes.LIMIT self.order.cancel(0.01) self.assertEqual(self.order.update_data, {"size_reduction": 0.01}) mock_cancelling.assert_called_with() self.order.cancel() self.assertEqual(self.order.update_data, {"size_reduction": None}) def test_cancel_bet_id(self): self.order.status = OrderStatus.EXECUTABLE with self.assertRaises(OrderUpdateError): self.order.cancel(12) @mock.patch( "flumine.order.order.BetfairOrder.size_remaining", new_callable=mock.PropertyMock, ) @mock.patch("flumine.order.order.BetfairOrder.cancelling") def test_cancel_error_size(self, mock_cancelling, mock_size_remaining): mock_size_remaining.return_value = 20 self.order.status = OrderStatus.EXECUTABLE with self.assertRaises(OrderUpdateError): self.order.cancel(12) self.mock_order_type.ORDER_TYPE = OrderTypes.LIMIT with self.assertRaises(OrderUpdateError): self.order.cancel(21) @mock.patch( "flumine.order.order.BetfairOrder.size_remaining", new_callable=mock.PropertyMock, ) def test_cancel_error(self, mock_size_remaining): mock_size_remaining.return_value = 20 self.mock_order_type.ORDER_TYPE = OrderTypes.LIMIT self.order.status = OrderStatus.PENDING with self.assertRaises(OrderUpdateError): self.order.cancel(12) @mock.patch("flumine.order.order.BetfairOrder.updating") def test_update(self, mock_updating): self.order.bet_id = 123 self.order.status = OrderStatus.EXECUTABLE with self.assertRaises(OrderUpdateError): self.order.update("PERSIST") self.mock_order_type.ORDER_TYPE = OrderTypes.LIMIT self.mock_order_type.persistence_type = "LAPSE" self.order.update("PERSIST") self.assertEqual(self.mock_order_type.persistence_type, "PERSIST") mock_updating.assert_called_with() with self.assertRaises(OrderUpdateError): self.order.update("PERSIST") def test_update_bet_id(self): self.order.status = OrderStatus.EXECUTABLE with self.assertRaises(OrderUpdateError): self.order.update("PERSIST") def test_update_error(self): self.mock_order_type.ORDER_TYPE = OrderTypes.LIMIT self.mock_order_type.persistence_type = "LAPSE" self.order.status = OrderStatus.PENDING with self.assertRaises(OrderUpdateError): self.order.update("PERSIST") @mock.patch("flumine.order.order.BetfairOrder.replacing") def test_replace(self, mock_replacing): self.order.bet_id = 123 self.order.status = OrderStatus.EXECUTABLE with self.assertRaises(OrderUpdateError): self.order.replace(1.01) self.mock_order_type.ORDER_TYPE = OrderTypes.LIMIT self.mock_order_type.price = 2.02 self.order.replace(1.01) self.assertEqual(self.order.update_data, {"new_price": 1.01}) mock_replacing.assert_called_with() with self.assertRaises(OrderUpdateError): self.order.replace(2.02) def test_replace_bet_id(self): self.order.status = OrderStatus.EXECUTABLE with self.assertRaises(OrderUpdateError): self.order.replace(1.01) def test_replace_error(self): self.mock_order_type.ORDER_TYPE = OrderTypes.LIMIT self.order.status = OrderStatus.PENDING with self.assertRaises(OrderUpdateError): self.order.replace(1.52) def test_create_place_instruction(self): self.mock_order_type.ORDER_TYPE = OrderTypes.LIMIT self.assertEqual( self.order.create_place_instruction(), { "customerOrderRef": self.order.customer_order_ref, "handicap": 0, "limitOrder": self.mock_order_type.place_instruction(), "orderType": "LIMIT", "selectionId": self.mock_trade.selection_id, "side": "BACK", }, ) self.mock_order_type.ORDER_TYPE = OrderTypes.LIMIT_ON_CLOSE self.assertEqual( self.order.create_place_instruction(), { "customerOrderRef": self.order.customer_order_ref, "handicap": 0, "limitOnCloseOrder": self.mock_order_type.place_instruction(), "orderType": "LIMIT_ON_CLOSE", "selectionId": self.mock_trade.selection_id, "side": "BACK", }, ) self.mock_order_type.ORDER_TYPE = OrderTypes.MARKET_ON_CLOSE self.assertEqual( self.order.create_place_instruction(), { "customerOrderRef": self.order.customer_order_ref, "handicap": 0, "marketOnCloseOrder": self.mock_order_type.place_instruction(), "orderType": "MARKET_ON_CLOSE", "selectionId": self.mock_trade.selection_id, "side": "BACK", }, ) def test_create_cancel_instruction(self): self.order.update_data = {"size_reduction": 0.02} self.assertEqual(self.order.create_cancel_instruction(), {"sizeReduction": 0.02}) def test_create_update_instruction(self): self.mock_order_type.persistence_type = "PERSIST" self.assertEqual(self.order.create_update_instruction(), {"newPersistenceType": "PERSIST"}) def test_create_replace_instruction(self): self.order.update_data = {"new_price": 2.02} self.assertEqual(self.order.create_replace_instruction(), {"newPrice": 2.02}) def test_average_price_matched(self): self.assertEqual(self.order.average_price_matched, 0) mock_current_order = mock.Mock(average_price_matched=12.3) self.order.responses.current_order = mock_current_order self.assertEqual(self.order.average_price_matched, mock_current_order.average_price_matched) def test_size_matched(self): self.assertEqual(self.order.size_matched, 0) mock_current_order = mock.Mock(size_matched=10) self.order.responses.current_order = mock_current_order self.assertEqual(self.order.size_matched, mock_current_order.size_matched) def test_size_remaining(self): self.mock_order_type.ORDER_TYPE = OrderTypes.LIMIT self.mock_order_type.size = 0 self.assertEqual(self.order.size_remaining, 0) self.mock_order_type.size = 10 mock_current_order = mock.Mock(size_remaining=10) self.order.responses.current_order = mock_current_order self.assertEqual(self.order.size_remaining, mock_current_order.size_remaining) def test_size_remaining_missing(self): self.mock_order_type.ORDER_TYPE = OrderTypes.LIMIT self.mock_order_type.size = 2.51 self.assertEqual(self.order.size_remaining, 2.51) @mock.patch( "flumine.order.order.BetfairOrder.size_matched", new_callable=mock.PropertyMock, ) def test_size_remaining_missing_partial_match(self, mock_size_matched): self.mock_order_type.ORDER_TYPE = OrderTypes.LIMIT mock_size_matched.return_value = 2 self.mock_order_type.size = 10 self.assertEqual(self.order.size_remaining, 8) def test_size_remaining_market_on_close(self): self.mock_order_type.ORDER_TYPE = OrderTypes.MARKET_ON_CLOSE self.mock_order_type.size = ValueError self.order.responses.current_order = None self.assertEqual(self.order.size_remaining, self.mock_order_type.liability) def test_size_cancelled(self): self.assertEqual(self.order.size_cancelled, 0) mock_current_order = mock.Mock(size_cancelled=10) self.order.responses.current_order = mock_current_order self.assertEqual(self.order.size_cancelled, mock_current_order.size_cancelled) def test_size_lapsed(self): self.assertEqual(self.order.size_lapsed, 0) mock_current_order = mock.Mock(size_lapsed=10) self.order.responses.current_order = mock_current_order self.assertEqual(self.order.size_lapsed, mock_current_order.size_lapsed) def test_size_voided(self): self.assertEqual(self.order.size_voided, 0) mock_current_order = mock.Mock(size_voided=10) self.order.responses.current_order = mock_current_order self.assertEqual(self.order.size_voided, mock_current_order.size_voided) def test_info(self): self.order.status_log = [ OrderStatus.PENDING, OrderStatus.EXECUTION_COMPLETE ] self.assertEqual( self.order.info, { "bet_id": None, "handicap": self.order.handicap, "id": self.order.id, "date_time_created": str(self.order.date_time_created), "market_id": self.mock_trade.market_id, "selection_id": self.mock_trade.selection_id, "publish_time": None, "status": None, "status_log": "Pending, Execution complete", "trade": self.mock_trade.info, "order_type": self.mock_order_type.info, "info": { "side": self.order.side, "size_matched": self.order.size_matched, "size_remaining": self.order.size_remaining, "size_cancelled": self.order.size_cancelled, "size_lapsed": self.order.size_lapsed, "size_voided": self.order.size_voided, "average_price_matched": self.order.average_price_matched, }, "customer_order_ref": self.order.customer_order_ref, "simulated": { "profit": 0.0, "piq": 0.0, "matched": [], }, "violation_msg": self.order.violation_msg, "responses": { "date_time_placed": None, "elapsed_seconds_executable": None, }, "runner_status": self.order.runner_status, }, ) def test_json(self): self.assertTrue(isinstance(self.order.json(), str)) def test_set_invalid_sep(self): with self.assertRaises(ValueError): self.order.sep = "@"
class BetfairOrderTest(unittest.TestCase): def setUp(self) -> None: self.mock_trade = mock.Mock() self.mock_status = mock.Mock() self.mock_order_type = mock.Mock() self.order = BetfairOrder(self.mock_trade, "BACK", self.mock_order_type) def test_init(self): self.assertEqual(self.order.EXCHANGE, ExchangeType.BETFAIR) @mock.patch("flumine.order.order.BetfairOrder.placing") def test_place(self, mock_placing): self.order.place(123) mock_placing.assert_called_with() self.assertEqual(self.order.publish_time, 123) @mock.patch( "flumine.order.order.BetfairOrder.size_remaining", new_callable=mock.PropertyMock, ) @mock.patch("flumine.order.order.BetfairOrder.cancelling") def test_cancel(self, mock_cancelling, mock_size_remaining): mock_size_remaining.return_value = 20 self.order.status = OrderStatus.EXECUTABLE with self.assertRaises(OrderUpdateError): self.order.cancel(12) self.mock_order_type.ORDER_TYPE = OrderTypes.LIMIT self.order.cancel(0.01) self.assertEqual(self.order.update_data, {"size_reduction": 0.01}) mock_cancelling.assert_called_with() self.order.cancel() self.assertEqual(self.order.update_data, {"size_reduction": None}) @mock.patch( "flumine.order.order.BetfairOrder.size_remaining", new_callable=mock.PropertyMock, ) @mock.patch("flumine.order.order.BetfairOrder.cancelling") def test_cancel_error_size(self, mock_cancelling, mock_size_remaining): mock_size_remaining.return_value = 20 self.order.status = OrderStatus.EXECUTABLE with self.assertRaises(OrderUpdateError): self.order.cancel(12) self.mock_order_type.ORDER_TYPE = OrderTypes.LIMIT with self.assertRaises(OrderUpdateError): self.order.cancel(21) def test_cancel_error(self): self.mock_order_type.ORDER_TYPE = OrderTypes.LIMIT self.order.status = OrderStatus.PENDING with self.assertRaises(OrderUpdateError): self.order.cancel(12) @mock.patch("flumine.order.order.BetfairOrder.updating") def test_update(self, mock_updating): self.order.status = OrderStatus.EXECUTABLE with self.assertRaises(OrderUpdateError): self.order.update("PERSIST") self.mock_order_type.ORDER_TYPE = OrderTypes.LIMIT self.mock_order_type.persistence_type = "LAPSE" self.order.update("PERSIST") self.assertEqual(self.mock_order_type.persistence_type, "PERSIST") mock_updating.assert_called_with() with self.assertRaises(OrderUpdateError): self.order.update("PERSIST") def test_update_error(self): self.mock_order_type.ORDER_TYPE = OrderTypes.LIMIT self.mock_order_type.persistence_type = "LAPSE" self.order.status = OrderStatus.PENDING with self.assertRaises(OrderUpdateError): self.order.update("PERSIST") @mock.patch("flumine.order.order.BetfairOrder.replacing") def test_replace(self, mock_replacing): self.order.status = OrderStatus.EXECUTABLE with self.assertRaises(OrderUpdateError): self.order.replace(1.01) self.mock_order_type.ORDER_TYPE = OrderTypes.LIMIT self.mock_order_type.price = 2.02 self.order.replace(1.01) self.assertEqual(self.order.update_data, {"new_price": 1.01}) mock_replacing.assert_called_with() with self.assertRaises(OrderUpdateError): self.order.replace(2.02) def test_replace_error(self): self.mock_order_type.ORDER_TYPE = OrderTypes.LIMIT self.order.status = OrderStatus.PENDING with self.assertRaises(OrderUpdateError): self.order.replace(1.52) def test_create_place_instruction(self): self.mock_order_type.ORDER_TYPE = OrderTypes.LIMIT self.assertEqual( self.order.create_place_instruction(), { "customerOrderRef": self.order.customer_order_ref, "handicap": 0, "limitOrder": self.mock_order_type.place_instruction(), "orderType": "LIMIT", "selectionId": self.mock_trade.selection_id, "side": "BACK", }, ) self.mock_order_type.ORDER_TYPE = OrderTypes.LIMIT_ON_CLOSE self.assertEqual( self.order.create_place_instruction(), { "customerOrderRef": self.order.customer_order_ref, "handicap": 0, "limitOnCloseOrder": self.mock_order_type.place_instruction(), "orderType": "LIMIT_ON_CLOSE", "selectionId": self.mock_trade.selection_id, "side": "BACK", }, ) self.mock_order_type.ORDER_TYPE = OrderTypes.MARKET_ON_CLOSE self.assertEqual( self.order.create_place_instruction(), { "customerOrderRef": self.order.customer_order_ref, "handicap": 0, "marketOnCloseOrder": self.mock_order_type.place_instruction(), "orderType": "MARKET_ON_CLOSE", "selectionId": self.mock_trade.selection_id, "side": "BACK", }, ) def test_create_cancel_instruction(self): self.order.update_data = {"size_reduction": 0.02} self.assertEqual(self.order.create_cancel_instruction(), {"sizeReduction": 0.02}) def test_create_update_instruction(self): self.mock_order_type.persistence_type = "PERSIST" self.assertEqual(self.order.create_update_instruction(), {"newPersistenceType": "PERSIST"}) def test_create_replace_instruction(self): self.order.update_data = {"new_price": 2.02} self.assertEqual(self.order.create_replace_instruction(), {"newPrice": 2.02}) def test_average_price_matched(self): self.assertEqual(self.order.average_price_matched, 0) mock_current_order = mock.Mock(average_price_matched=12.3) self.order.responses.current_order = mock_current_order self.assertEqual(self.order.average_price_matched, mock_current_order.average_price_matched) def test_size_matched(self): self.assertEqual(self.order.size_matched, 0) mock_current_order = mock.Mock(size_matched=10) self.order.responses.current_order = mock_current_order self.assertEqual(self.order.size_matched, mock_current_order.size_matched) def test_size_remaining(self): self.assertEqual(self.order.size_remaining, 0) mock_current_order = mock.Mock(size_remaining=10) self.order.responses.current_order = mock_current_order self.assertEqual(self.order.size_remaining, mock_current_order.size_remaining) def test_size_cancelled(self): self.assertEqual(self.order.size_cancelled, 0) mock_current_order = mock.Mock(size_cancelled=10) self.order.responses.current_order = mock_current_order self.assertEqual(self.order.size_cancelled, mock_current_order.size_cancelled) def test_size_lapsed(self): self.assertEqual(self.order.size_lapsed, 0) mock_current_order = mock.Mock(size_lapsed=10) self.order.responses.current_order = mock_current_order self.assertEqual(self.order.size_lapsed, mock_current_order.size_lapsed) def test_size_voided(self): self.assertEqual(self.order.size_voided, 0) mock_current_order = mock.Mock(size_voided=10) self.order.responses.current_order = mock_current_order self.assertEqual(self.order.size_voided, mock_current_order.size_voided) def test_info(self): self.order.status_log = [ OrderStatus.PENDING, OrderStatus.EXECUTION_COMPLETE ] self.assertEqual( self.order.info, { "bet_id": None, "handicap": self.order.handicap, "id": self.order.id, "market_id": self.mock_trade.market_id, "selection_id": self.mock_trade.selection_id, "status": None, "status_log": "Pending, Execution complete", "trade": self.mock_trade.info, "order_type": self.mock_order_type.info, "info": { "side": self.order.side, "size_matched": self.order.size_matched, "size_remaining": self.order.size_remaining, "size_cancelled": self.order.size_cancelled, "size_lapsed": self.order.size_lapsed, "size_voided": self.order.size_voided, "average_price_matched": self.order.average_price_matched, }, "customer_order_ref": self.order.customer_order_ref, }, )