Repository: liampauling/flumine
Pull request #365 (2021-01-11 14:17:41)

correctly handle BSP orders that are removed (runner removal after BSP)
note that lay BSP orders round down the size (no idea why)


Patch:
diff --git a/HISTORY.rst b/HISTORY.rst
index 0b1d16c..da0f330 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -3,6 +3,13 @@
 Release History
 ---------------
 
+1.15.3 (2021-01-11)
++++++++++++++++++++
+
+**Bug Fixes**
+
+- Correctly handle runner removal / order void for LimitOnClose/MarketOnClose orders
+
 1.15.2 (2021-01-11)
 +++++++++++++++++++
 
diff --git a/flumine/__version__.py b/flumine/__version__.py
index 3a2f232..ee306f4 100644
--- a/flumine/__version__.py
+++ b/flumine/__version__.py
@@ -1,6 +1,6 @@
 __title__ = "flumine"
 __description__ = "Betfair trading framework"
 __url__ = "https://github.com/liampauling/flumine"
-__version__ = "1.15.2"
+__version__ = "1.15.3"
 __author__ = "Liam Pauling"
 __license__ = "MIT"
diff --git a/flumine/markets/middleware.py b/flumine/markets/middleware.py
index bc29d51..a73c780 100644
--- a/flumine/markets/middleware.py
+++ b/flumine/markets/middleware.py
@@ -2,7 +2,7 @@ import logging
 from collections import defaultdict
 from betfairlightweight.resources.bettingresources import RunnerBook
 
-from ..order.order import OrderStatus
+from ..order.order import OrderStatus, OrderTypes
 from ..utils import get_price, wap
 
 logger = logging.getLogger(__name__)
@@ -90,7 +90,10 @@ class SimulatedMiddleware(Middleware):
                     order.simulated.size_matched = 0
                     order.simulated.average_price_matched = 0
                     order.simulated.matched = []
-                    order.simulated.size_voided = order.order_type.size
+                    if order.order_type.ORDER_TYPE == OrderTypes.LIMIT:
+                        order.simulated.size_voided = order.order_type.size
+                    else:
+                        order.simulated.size_voided = order.order_type.liability
                     logger.warning(
                         "Order voided on non runner {0}".format(order.selection_id),
                         extra=order.info,


Test patch:
diff --git a/flumine/backtest/simulated.py b/flumine/backtest/simulated.py
index 5843f06..2c4af90 100644
--- a/flumine/backtest/simulated.py
+++ b/flumine/backtest/simulated.py
@@ -235,7 +235,9 @@ class Simulated:
                     if actual_sp > _order_type.price:
                         self.order.execution_complete()
                         return
-                    size = round(_order_type.liability / (actual_sp - 1), 2)
+                    size = round(
+                        _order_type.liability / (actual_sp - 1), 2
+                    )  # todo round 2dp down
             elif _order_type.ORDER_TYPE == OrderTypes.MARKET_ON_CLOSE:
                 if self.side == "BACK":
                     size = _order_type.liability
diff --git a/tests/test_middleware.py b/tests/test_middleware.py
index 3e83f88..9d3d649 100644
--- a/tests/test_middleware.py
+++ b/tests/test_middleware.py
@@ -6,6 +6,7 @@ from flumine.markets.middleware import (
     SimulatedMiddleware,
     RunnerAnalytics,
     OrderStatus,
+    OrderTypes,
     WIN_MINIMUM_ADJUSTMENT_FACTOR,
     PLACE_MINIMUM_ADJUSTMENT_FACTOR,
 )
@@ -120,6 +121,7 @@ class SimulatedMiddlewareTest(unittest.TestCase):
             lookup=("1.23", 12345, 0), simulated=mock_simulated, info={}
         )
         mock_order.order_type.size = 10
+        mock_order.order_type.ORDER_TYPE = OrderTypes.LIMIT
         mock_market = mock.Mock(market_id="1.23", blotter=[mock_order])
         self.middleware._process_runner_removal(mock_market, 12345, 0, 16.2)
         self.assertEqual(mock_order.simulated.size_matched, 0)