Beispiel #1
0
 def setUp(self):
     self.market = mock.Mock()
     self.market.blotter = Blotter("market_id")
     self.mock_flumine = mock.Mock()
     self.mock_flumine.markets.markets = {"market_id": self.market}
     self.trading_control = StrategyExposure(self.mock_flumine)
Beispiel #2
0
class TestStrategyExposure(unittest.TestCase):
    def setUp(self):
        self.market = mock.Mock()
        self.market.blotter = Blotter("market_id")
        self.mock_flumine = mock.Mock()
        self.mock_flumine.markets.markets = {"market_id": self.market}
        self.trading_control = StrategyExposure(self.mock_flumine)

    def test_init(self):
        self.assertEqual(self.trading_control.NAME, "STRATEGY_EXPOSURE")
        self.assertEqual(self.trading_control.flumine, self.mock_flumine)

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_strategy_validate_order(self, mock_on_error):
        mock_order = mock.Mock(market_id="market_id", lookup=(1, 2, 3))
        mock_order.trade.strategy.validate_order.return_value = True
        mock_runner_context = mock.Mock()
        mock_order.trade.strategy.get_runner_context.return_value = mock_runner_context
        self.trading_control._validate(mock_order, OrderPackageType.PLACE)

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_strategy_validate_order_error(self, mock_on_error):
        mock_order = mock.Mock(market_id="market_id", lookup=(1, 2, 3))
        mock_order.trade.strategy.validate_order.return_value = False
        mock_runner_context = mock.Mock()
        mock_order.trade.strategy.get_runner_context.return_value = mock_runner_context
        self.trading_control._validate(mock_order, OrderPackageType.PLACE)
        mock_on_error.assert_called_with(
            mock_order,
            mock_order.violation_msg,
        )

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_limit(self, mock_on_error):
        mock_order = mock.Mock(market_id="market_id", lookup=(1, 2, 3))
        mock_order.trade.strategy.max_order_exposure = 10
        mock_order.trade.strategy.max_selection_exposure = 100
        mock_order.order_type.ORDER_TYPE = OrderTypes.LIMIT
        mock_order.side = "BACK"
        mock_order.order_type.size = 12.0
        self.trading_control._validate(mock_order, OrderPackageType.PLACE)
        mock_on_error.assert_called_with(
            mock_order,
            "Order exposure (12.0) is greater than strategy.max_order_exposure (10)",
        )

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_limit_with_multiple_strategies_succeeds(
            self, mock_on_error):
        """
        The 2 orders would exceed selection_exposure limits if they were for the same strategy. But they are
        for different strategies. Assert that they do not cause a validation failure.
        """
        strategy = mock.Mock()
        strategy.max_order_exposure = 10
        strategy.max_selection_exposure = 10

        order1 = mock.Mock(market_id="market_id", lookup=(1, 2, 3))
        order1.trade.strategy.max_order_exposure = 10
        order1.trade.strategy.max_selection_exposure = 10
        order1.order_type.ORDER_TYPE = OrderTypes.LIMIT
        order1.side = "BACK"
        order1.order_type.price = 2.0
        order1.order_type.size = 9.0
        order1.size_remaining = 9.0
        order1.average_price_matched = 0.0
        order1.size_matched = 0

        order2 = mock.Mock(lookup=(1, 2, 3))
        order2.trade.strategy.max_order_exposure = 10
        order2.trade.strategy.max_selection_exposure = 10
        order2.trade.strategy = strategy
        order2.order_type.ORDER_TYPE = OrderTypes.LIMIT
        order2.side = "BACK"
        order2.order_type.price = 3.0
        order2.order_type.size = 9.0
        order2.size_remaining = 5.0
        order2.average_price_matched = 0.0
        order2.size_matched = 0

        self.market.blotter._orders = {"order1": order1, "order2": order2}

        self.trading_control._validate(order1, OrderPackageType.PLACE)
        mock_on_error.assert_not_called()

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_limit_with_multiple_strategies_fails(
            self, mock_on_error):
        """
        The 2 orders are from the same strategy. And are each less than strategy.max_order_exposure.
        However, in combination, they exceed strategy.max_selection_exposure.
        """
        strategy = mock.Mock()
        strategy.max_order_exposure = 10
        strategy.max_selection_exposure = 10

        order1 = mock.Mock(market_id="market_id", lookup=(1, 2, 3))
        order1.trade.strategy = strategy
        order1.order_type.ORDER_TYPE = OrderTypes.LIMIT
        order1.side = "BACK"
        order1.order_type.price = 2.0
        order1.order_type.size = 9.0
        order1.size_remaining = 9.0
        order1.average_price_matched = 0.0
        order1.size_matched = 0

        order2 = mock.Mock(lookup=(1, 2, 3))
        order2.trade.strategy = strategy
        order2.order_type.ORDER_TYPE = OrderTypes.LIMIT
        order2.side = "BACK"
        order2.order_type.price = 3.0
        order2.order_type.size = 9.0
        order2.size_remaining = 5.0
        order2.average_price_matched = 0.0
        order2.size_matched = 0

        self.market.blotter["order2"] = order2

        self.trading_control._validate(order1, OrderPackageType.PLACE)
        self.assertEqual(1, mock_on_error.call_count)
        mock_on_error.assert_called_with(
            order1,
            "Potential selection exposure (14.00) is greater than strategy.max_selection_exposure (10)",
        )

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_limit_on_close(self, mock_on_error):
        mock_order = mock.Mock(market_id="market_id", lookup=(1, 2, 3))
        mock_order.trade.strategy.max_order_exposure = 10
        mock_order.trade.strategy.max_selection_exposure = 100
        mock_order.order_type.ORDER_TYPE = OrderTypes.LIMIT_ON_CLOSE
        mock_order.side = "BACK"
        mock_order.order_type.liability = 12
        self.trading_control._validate(mock_order, OrderPackageType.PLACE)
        mock_on_error.assert_called_with(
            mock_order,
            "Order exposure (12) is greater than strategy.max_order_exposure (10)",
        )

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_market_on_close(self, mock_on_error):
        mock_market = mock.Mock()
        mock_market.blotter.selection_exposure.return_value = 10.0
        self.mock_flumine.markets.markets = {"1.234": mock_market}

        mock_order = mock.Mock(market_id="1.234", lookup=(1, 2, 3))
        mock_order.trade.strategy.max_order_exposure = 10
        mock_order.trade.strategy.max_selection_exposure = 100
        mock_order.order_type.ORDER_TYPE = OrderTypes.MARKET_ON_CLOSE
        mock_order.side = "BACK"
        mock_order.order_type.liability = 12
        self.trading_control._validate(mock_order, OrderPackageType.PLACE)
        mock_on_error.assert_called_with(
            mock_order,
            "Order exposure (12) is greater than strategy.max_order_exposure (10)",
        )

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_selection(self, mock_on_error):
        mock_market = mock.Mock()
        mock_market.blotter.selection_exposure.return_value = 12.0
        self.mock_flumine.markets.markets = {"1.234": mock_market}
        mock_order = mock.Mock(market_id="1.234", lookup=(1, 2, 3), side="LAY")
        mock_order.trade.strategy.max_order_exposure = 10
        mock_order.trade.strategy.max_selection_exposure = 10
        mock_order.order_type.ORDER_TYPE = OrderTypes.LIMIT
        mock_order.order_type.size = 12.0
        mock_order.order_type.price = 1.01
        mock_market.blotter._live_orders = [mock_order]
        self.trading_control._validate(mock_order, OrderPackageType.PLACE)
        mock_on_error.assert_called_with(
            mock_order,
            "Potential selection exposure (12.12) is greater than strategy.max_selection_exposure (10)",
        )
Beispiel #3
0
class TestStrategyExposure(unittest.TestCase):
    def setUp(self):
        self.market = mock.Mock()
        self.market.blotter = Blotter("market_id")
        self.mock_flumine = mock.Mock()
        self.mock_flumine.markets.markets = {"market_id": self.market}
        self.trading_control = StrategyExposure(self.mock_flumine)

    def test_init(self):
        self.assertEqual(self.trading_control.NAME, "STRATEGY_EXPOSURE")
        self.assertEqual(self.trading_control.flumine, self.mock_flumine)

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_strategy_validate_order(self, mock_on_error):
        mock_order = mock.Mock(market_id="market_id", lookup=(1, 2, 3))
        mock_order.trade.strategy.validate_order.return_value = True
        mock_runner_context = mock.Mock()
        mock_order.trade.strategy.get_runner_context.return_value = mock_runner_context
        self.trading_control._validate(mock_order, OrderPackageType.PLACE)

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_strategy_validate_order_error(self, mock_on_error):
        mock_order = mock.Mock(market_id="market_id", lookup=(1, 2, 3))
        mock_order.trade.strategy.validate_order.return_value = False
        mock_runner_context = mock.Mock()
        mock_order.trade.strategy.get_runner_context.return_value = mock_runner_context
        self.trading_control._validate(mock_order, OrderPackageType.PLACE)
        mock_on_error.assert_called_with(
            mock_order,
            mock_order.violation_msg,
        )

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_limit(self, mock_on_error):
        mock_order = mock.Mock(market_id="market_id", lookup=(1, 2, 3))
        mock_order.trade.strategy.max_order_exposure = 10
        mock_order.trade.strategy.max_selection_exposure = 100
        mock_order.order_type.ORDER_TYPE = OrderTypes.LIMIT
        mock_order.side = "BACK"
        mock_order.order_type.size = 12.0
        self.trading_control._validate(mock_order, OrderPackageType.PLACE)
        mock_on_error.assert_called_with(
            mock_order,
            "Order exposure (12.0) is greater than strategy.max_order_exposure (10)",
        )

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_limit_target(self, mock_on_error):
        mock_order = mock.Mock(market_id="market_id", lookup=(1, 2, 3))
        mock_order.trade.strategy.max_order_exposure = 10
        mock_order.trade.strategy.max_selection_exposure = 100
        mock_order.order_type.ORDER_TYPE = OrderTypes.LIMIT
        mock_order.side = "BACK"
        mock_order.order_type.size = None
        mock_order.order_type.bet_target_size = 12.0
        self.trading_control._validate(mock_order, OrderPackageType.PLACE)
        mock_on_error.assert_called_with(
            mock_order,
            "Order exposure (12.0) is greater than strategy.max_order_exposure (10)",
        )

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_limit_with_multiple_strategies_succeeds(
            self, mock_on_error):
        """
        The 2 orders would exceed selection_exposure limits if they were for the same strategy. But they are
        for different strategies. Assert that they do not cause a validation failure.
        """
        strategy = mock.Mock()
        strategy.max_order_exposure = 10
        strategy.max_selection_exposure = 10

        order1 = mock.Mock(market_id="market_id", lookup=(1, 2, 3))
        order1.trade.strategy.max_order_exposure = 10
        order1.trade.strategy.max_selection_exposure = 10
        order1.order_type.ORDER_TYPE = OrderTypes.LIMIT
        order1.side = "BACK"
        order1.order_type.price = 2.0
        order1.order_type.size = 9.0
        order1.size_remaining = 9.0
        order1.average_price_matched = 0.0
        order1.size_matched = 0

        order2 = mock.Mock(lookup=(1, 2, 3))
        order2.trade.strategy.max_order_exposure = 10
        order2.trade.strategy.max_selection_exposure = 10
        order2.trade.strategy = strategy
        order2.order_type.ORDER_TYPE = OrderTypes.LIMIT
        order2.side = "BACK"
        order2.order_type.price = 3.0
        order2.order_type.size = 9.0
        order2.size_remaining = 5.0
        order2.average_price_matched = 0.0
        order2.size_matched = 0

        self.market.blotter._orders = {"order1": order1, "order2": order2}

        self.trading_control._validate(order1, OrderPackageType.PLACE)
        mock_on_error.assert_not_called()

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_limit_with_multiple_strategies_fails(
            self, mock_on_error):
        """
        The 2 orders are from the same strategy. And are each less than strategy.max_order_exposure.
        However, in combination, they exceed strategy.max_selection_exposure.
        """
        strategy = mock.Mock()
        strategy.max_order_exposure = 10
        strategy.max_selection_exposure = 10

        order1 = mock.Mock(
            market_id="market_id",
            lookup=(1, 2, 3),
            side="BACK",
            size_remaining=9.0,
            average_price_matched=0.0,
            size_matched=0,
            status=OrderStatus.EXECUTABLE,
            complete=False,
        )
        order1.trade.strategy = strategy
        order1.order_type.ORDER_TYPE = OrderTypes.LIMIT
        order1.order_type.price = 2.0
        order1.order_type.size = 9.0

        order2 = mock.Mock(
            lookup=(1, 2, 3),
            side="BACK",
            size_remaining=5.0,
            average_price_matched=0.0,
            size_matched=0,
            status=OrderStatus.EXECUTABLE,
            complete=False,
        )
        order2.trade.strategy = strategy
        order2.order_type.ORDER_TYPE = OrderTypes.LIMIT
        order2.order_type.price = 3.0
        order2.order_type.size = 9.0

        self.market.blotter["order2"] = order2

        self.trading_control._validate(order1, OrderPackageType.PLACE)
        self.assertEqual(1, mock_on_error.call_count)
        mock_on_error.assert_called_with(
            order1,
            "Potential selection exposure (14.00) is greater than strategy.max_selection_exposure (10)",
        )

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_limit_on_close(self, mock_on_error):
        mock_order = mock.Mock(market_id="market_id", lookup=(1, 2, 3))
        mock_order.trade.strategy.max_order_exposure = 10
        mock_order.trade.strategy.max_selection_exposure = 100
        mock_order.order_type.ORDER_TYPE = OrderTypes.LIMIT_ON_CLOSE
        mock_order.side = "BACK"
        mock_order.order_type.liability = 12
        self.trading_control._validate(mock_order, OrderPackageType.PLACE)
        mock_on_error.assert_called_with(
            mock_order,
            "Order exposure (12) is greater than strategy.max_order_exposure (10)",
        )

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_market_on_close(self, mock_on_error):
        mock_market = mock.Mock()
        mock_market.blotter.selection_exposure.return_value = 10.0
        self.mock_flumine.markets.markets = {"1.234": mock_market}

        mock_order = mock.Mock(market_id="1.234", lookup=(1, 2, 3))
        mock_order.trade.strategy.max_order_exposure = 10
        mock_order.trade.strategy.max_selection_exposure = 100
        mock_order.order_type.ORDER_TYPE = OrderTypes.MARKET_ON_CLOSE
        mock_order.side = "BACK"
        mock_order.order_type.liability = 12
        self.trading_control._validate(mock_order, OrderPackageType.PLACE)
        mock_on_error.assert_called_with(
            mock_order,
            "Order exposure (12) is greater than strategy.max_order_exposure (10)",
        )

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_selection(self, mock_on_error):
        mock_market = mock.Mock()
        mock_market.blotter.get_exposures.return_value = {
            "worst_possible_profit_on_win": -12.0
        }
        self.mock_flumine.markets.markets = {"1.234": mock_market}
        mock_order = mock.Mock(market_id="1.234", lookup=(1, 2, 3), side="LAY")
        mock_order.trade.strategy.max_order_exposure = 10
        mock_order.trade.strategy.max_selection_exposure = 10
        mock_order.order_type.ORDER_TYPE = OrderTypes.LIMIT
        mock_order.order_type.size = 12.0
        mock_order.order_type.price = 1.01
        mock_market.blotter._live_orders = [mock_order]
        self.trading_control._validate(mock_order, OrderPackageType.PLACE)
        mock_on_error.assert_called_with(
            mock_order,
            "Potential selection exposure (12.12) is greater than strategy.max_selection_exposure (10)",
        )

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_selection2a(self, mock_on_error):
        """
        test_validate_selection2a expects an error, as it attempts to place a lay bet with a £36 potential
        loss, which is more than the £10 max_selection_exposure
        """
        mock_market = mock.Mock()
        mock_market.blotter = Blotter(market_id="1.234")
        self.mock_flumine.markets.markets = {"1.234": mock_market}

        mock_strategy = mock.Mock()
        mock_strategy.max_order_exposure = 100
        mock_strategy.max_selection_exposure = 10

        mock_trade = mock.Mock()
        mock_trade.strategy = mock_strategy

        mock_order = mock.Mock(market_id="1.234", lookup=(1, 2, 3), side="LAY")
        mock_order.trade = mock_trade
        mock_order.order_type.ORDER_TYPE = OrderTypes.LIMIT
        mock_order.order_type.size = 9.0
        mock_order.order_type.price = 5.0

        self.trading_control._validate(mock_order, OrderPackageType.PLACE)
        mock_on_error.assert_called_with(
            mock_order,
            "Potential selection exposure (36.00) is greater than strategy.max_selection_exposure (10)",
        )

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_selection2b(self, mock_on_error):
        """
        test_validate_selection2b expects no error.
        Unlike test_validate_selection2a, the blotter contains an existing order. The order that it attempts
        to validate hedges the existing order, and reduces the total exposure.
        """
        mock_market = mock.Mock()
        mock_market.blotter = Blotter(market_id="1.234")

        self.mock_flumine.markets.markets = {"1.234": mock_market}

        mock_strategy = mock.Mock()
        mock_strategy.max_order_exposure = 100
        mock_strategy.max_selection_exposure = 10

        mock_trade = mock.Mock()
        mock_trade.strategy = mock_strategy

        existing_matched_order = mock.Mock(market_id="1.234",
                                           lookup=(1, 2, 3),
                                           side="BACK")
        existing_matched_order.trade = mock_trade
        existing_matched_order.order_type.ORDER_TYPE = OrderTypes.LIMIT
        existing_matched_order.size_matched = 9.0
        existing_matched_order.average_price_matched = 6.0
        existing_matched_order.size_remaining = 0.0

        mock_order = mock.Mock(market_id="1.234", lookup=(1, 2, 3), side="LAY")
        mock_order.trade = mock_trade
        mock_order.order_type.ORDER_TYPE = OrderTypes.LIMIT
        mock_order.order_type.size = 9.0
        mock_order.order_type.price = 5.0

        mock_market.blotter["existing_order"] = existing_matched_order

        self.trading_control._validate(mock_order, OrderPackageType.PLACE)
        mock_on_error.assert_not_called()

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_replace(self, mock_on_error):
        """
        Check that validating a REPLACE order does not lead to double counting of exposures.

        In this test, max_selection_exposure is 10.0, and the potential liability on the order is £9.
        If exposures are double counted, the validation would fail.
        If exposures aren't double counted, then the validation will succeed
        """
        strategy = mock.Mock()
        strategy.max_order_exposure = 10
        strategy.max_selection_exposure = 10

        order1 = mock.Mock(
            market_id="market_id",
            lookup=(1, 2, 3),
            selection_id=1234,
            side="BACK",
            average_price_matched=0.0,
            size_matched=0,
            handicap=0,
            status=OrderStatus.EXECUTABLE,
            complete=False,
        )
        order1.trade.strategy = strategy
        order1.order_type.ORDER_TYPE = OrderTypes.LIMIT
        order1.order_type.price = 2.0
        order1.order_type.size = 9.0
        order1.size_remaining = 9.0

        self.market.blotter._strategy_selection_orders = {
            (strategy, 2, 3): [order1]
        }

        # Show that the exposures aren't double counted when REPLACE is used
        self.trading_control._validate(order1, OrderPackageType.REPLACE)
        mock_on_error.assert_not_called()

        # Just to be sure, check that the validation fails if we try to validate order1 as a PLACE
        self.trading_control._validate(order1, OrderPackageType.PLACE)
        mock_on_error.assert_called_once()
class TestStrategyExposure(unittest.TestCase):
    def setUp(self):
        self.market = mock.Mock()
        self.market.blotter = Blotter("market_id")
        self.mock_flumine = mock.Mock()
        self.mock_flumine.markets.markets = {"market_id": self.market}
        self.trading_control = StrategyExposure(self.mock_flumine)

    def test_init(self):
        self.assertEqual(self.trading_control.NAME, "STRATEGY_EXPOSURE")
        self.assertEqual(self.trading_control.flumine, self.mock_flumine)

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_limit(self, mock_on_error):
        order = mock.Mock()
        order.trade.strategy.max_order_exposure = 10
        order.trade.strategy.max_selection_exposure = 100
        order.order_type.ORDER_TYPE = OrderTypes.LIMIT
        order.side = "BACK"
        order.order_type.size = 12.0
        order_package = mock.Mock()
        order_package.package_type = OrderPackageType.PLACE
        order_package.market_id = "market_id"
        order_package.__iter__ = mock.Mock(return_value=iter([order]))
        self.trading_control._validate(order_package)
        mock_on_error.assert_called_with(
            order,
            "Order exposure (12.0) is greater than strategy.max_order_strategy (10)",
        )

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_limit_with_multiple_strategies_succeeds(
            self, mock_on_error):
        """
        The 2 orders would exceed selection_exposure limits if they were for the same strategy. But they are
        for different strategies. Assert that they do not cause a validation failure.
        """

        strategy = mock.Mock()
        strategy.max_order_exposure = 10
        strategy.max_selection_exposure = 10

        order1 = mock.Mock()
        order1.trade.strategy.max_order_exposure = 10
        order1.trade.strategy.max_selection_exposure = 10
        order1.order_type.ORDER_TYPE = OrderTypes.LIMIT
        order1.side = "BACK"
        order1.order_type.price = 2.0
        order1.order_type.size = 9.0
        order1.size_remaining = 9.0
        order1.lookup = "lookup"
        order1.average_price_matched = 0.0
        order1.size_matched = 0

        order2 = mock.Mock()
        order2.trade.strategy.max_order_exposure = 10
        order2.trade.strategy.max_selection_exposure = 10
        order2.trade.strategy = strategy
        order2.order_type.ORDER_TYPE = OrderTypes.LIMIT
        order2.side = "BACK"
        order2.order_type.price = 3.0
        order2.order_type.size = 9.0
        order2.size_remaining = 5.0
        order2.lookup = "lookup"
        order2.average_price_matched = 0.0
        order2.size_matched = 0

        self.market.blotter._orders = {"order1": order1, "order2": order2}

        order_package = mock.Mock()
        order_package.package_type = OrderPackageType.PLACE
        order_package.market_id = "market_id"
        order_package.__iter__ = mock.Mock(return_value=iter([order1, order2]))
        self.trading_control._validate(order_package)

        mock_on_error.assert_not_called()

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_limit_with_multiple_strategies_fails(
            self, mock_on_error):
        """
        The 2 orders are from the same strategy. And are each less than strategy.max_order_exposure.
        However, in combination, they exceed strategy.max_selection_exposure.
        """
        strategy = mock.Mock()
        strategy.max_order_exposure = 10
        strategy.max_selection_exposure = 10

        order1 = mock.Mock()
        order1.trade.strategy = strategy
        order1.order_type.ORDER_TYPE = OrderTypes.LIMIT
        order1.side = "BACK"
        order1.order_type.price = 2.0
        order1.order_type.size = 9.0
        order1.size_remaining = 9.0
        order1.lookup = "lookup"
        order1.average_price_matched = 0.0
        order1.size_matched = 0

        order2 = mock.Mock()
        order2.trade.strategy = strategy
        order2.order_type.ORDER_TYPE = OrderTypes.LIMIT
        order2.side = "BACK"
        order2.order_type.price = 3.0
        order2.order_type.size = 9.0
        order2.size_remaining = 5.0
        order2.lookup = "lookup"
        order2.average_price_matched = 0.0
        order2.size_matched = 0

        self.market.blotter._orders = {"order1": order1, "order2": order2}

        order_package = mock.Mock()
        order_package.package_type = OrderPackageType.PLACE
        order_package.market_id = "market_id"
        order_package.__iter__ = mock.Mock(return_value=iter([order1, order2]))
        self.trading_control._validate(order_package)

        self.assertEqual(2, mock_on_error.call_count)
        # This asserts the 2nd call, using order2
        mock_on_error.assert_called_with(
            order2,
            "Potential selection exposure (14.0) is greater than strategy.max_selection_exposure (10)",
        )

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_limit_on_close(self, mock_on_error):
        order = mock.Mock()
        order.trade.strategy.max_order_exposure = 10
        order.trade.strategy.max_selection_exposure = 100
        order.order_type.ORDER_TYPE = OrderTypes.LIMIT_ON_CLOSE
        order.side = "BACK"
        order.order_type.liability = 12
        order_package = mock.Mock()
        order_package.package_type = OrderPackageType.PLACE
        order_package.market_id = "market_id"
        order_package.__iter__ = mock.Mock(return_value=iter([order]))
        self.trading_control._validate(order_package)
        mock_on_error.assert_called_with(
            order,
            "Order exposure (12) is greater than strategy.max_order_strategy (10)",
        )

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_market_on_close(self, mock_on_error):

        mock_market = mock.Mock()
        mock_market.blotter.selection_exposure.return_value = 10.0
        self.mock_flumine.markets.markets = {"1.234": mock_market}

        order = mock.Mock()
        order.trade.strategy.max_order_exposure = 10
        order.trade.strategy.max_selection_exposure = 100
        order.order_type.ORDER_TYPE = OrderTypes.MARKET_ON_CLOSE
        order.side = "BACK"
        order.order_type.liability = 12
        order_package = mock.Mock()
        order_package.market_id = "1.234"
        order_package.package_type = OrderPackageType.PLACE
        order_package.__iter__ = mock.Mock(return_value=iter([order]))
        self.trading_control._validate(order_package)
        mock_on_error.assert_called_with(
            order,
            "Order exposure (12) is greater than strategy.max_order_strategy (10)",
        )

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_selection(self, mock_on_error):
        mock_market = mock.Mock()
        mock_market.blotter.selection_exposure.return_value = 12.0
        self.mock_flumine.markets.markets = {"1.234": mock_market}

        order = mock.Mock()
        order.trade.strategy.max_order_exposure = 10
        order.trade.strategy.max_selection_exposure = 10
        order_package = mock.Mock()
        order_package.market_id = "1.234"
        order_package.package_type = OrderPackageType.PLACE
        order_package.__iter__ = mock.Mock(return_value=iter([order]))

        mock_market.blotter._live_orders = [order]

        self.trading_control._validate(order_package)
        mock_on_error.assert_called_with(
            order,
            "Potential selection exposure (12.0) is greater than strategy.max_selection_exposure (10)",
        )
Beispiel #5
0
 def setUp(self):
     self.mock_flumine = mock.Mock()
     self.trading_control = StrategyExposure(self.mock_flumine)
Beispiel #6
0
class TestStrategyExposure(unittest.TestCase):
    def setUp(self):
        self.mock_flumine = mock.Mock()
        self.trading_control = StrategyExposure(self.mock_flumine)

    def test_init(self):
        self.assertEqual(self.trading_control.NAME, "STRATEGY_EXPOSURE")
        self.assertEqual(self.trading_control.flumine, self.mock_flumine)

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_limit(self, mock_on_error):
        order = mock.Mock()
        order.trade.strategy.max_order_exposure = 10
        order.order_type.ORDER_TYPE = OrderTypes.LIMIT
        order.side = "BACK"
        order.order_type.size = 12
        order_package = mock.Mock()
        order_package.package_type = OrderPackageType.PLACE
        order_package.__iter__ = mock.Mock(return_value=iter([order]))
        self.trading_control._validate(order_package)
        mock_on_error.assert_called_with(
            order,
            "Order exposure (12) is greater than strategy.max_order_strategy (10)",
        )

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_limit_on_close(self, mock_on_error):
        order = mock.Mock()
        order.trade.strategy.max_order_exposure = 10
        order.order_type.ORDER_TYPE = OrderTypes.LIMIT_ON_CLOSE
        order.side = "BACK"
        order.order_type.liability = 12
        order_package = mock.Mock()
        order_package.package_type = OrderPackageType.PLACE
        order_package.__iter__ = mock.Mock(return_value=iter([order]))
        self.trading_control._validate(order_package)
        mock_on_error.assert_called_with(
            order,
            "Order exposure (12) is greater than strategy.max_order_strategy (10)",
        )

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_market_on_close(self, mock_on_error):
        order = mock.Mock()
        order.trade.strategy.max_order_exposure = 10
        order.order_type.ORDER_TYPE = OrderTypes.MARKET_ON_CLOSE
        order.side = "BACK"
        order.order_type.liability = 12
        order_package = mock.Mock()
        order_package.package_type = OrderPackageType.PLACE
        order_package.__iter__ = mock.Mock(return_value=iter([order]))
        self.trading_control._validate(order_package)
        mock_on_error.assert_called_with(
            order,
            "Order exposure (12) is greater than strategy.max_order_strategy (10)",
        )

    @mock.patch("flumine.controls.tradingcontrols.StrategyExposure._on_error")
    def test_validate_selection(self, mock_on_error):
        mock_market = mock.Mock()
        mock_market.blotter.selection_exposure.return_value = -10
        self.mock_flumine.markets.markets = {"1.234": mock_market}

        order = mock.Mock()
        order.trade.strategy.max_order_exposure = 10
        order.trade.strategy.max_selection_exposure = 10
        order.order_type.ORDER_TYPE = OrderTypes.LIMIT
        order.side = "BACK"
        order.order_type.size = 2
        order_package = mock.Mock()
        order_package.market_id = "1.234"
        order_package.package_type = OrderPackageType.PLACE
        order_package.__iter__ = mock.Mock(return_value=iter([order]))

        self.trading_control._validate(order_package)
        mock_on_error.assert_called_with(
            order,
            "Potential selection exposure (-12) is greater than strategy.max_selection_exposure (10)",
        )