Repository: liampauling/flumine
Pull request #174 (2020-05-26 08:25:16)

refactor and bugfix to handle positive exposure


Patch:
diff --git a/HISTORY.rst b/HISTORY.rst
index 10a7e2d..22511f9 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -3,46 +3,6 @@
 Release History
 ---------------
 
-1.6.0 (2020-06-01)
-+++++++++++++++++++
-
-**Improvements**
-
-- #175 Update/Replace simulated handling
-- Trade context manager added
-
-**Bug Fixes**
-
-- BetfairExecution replace bugfix
-
-1.5.7 (2020-06-01)
-+++++++++++++++++++
-
-**Bug Fixes**
-
-- Sentry uses name in extra so do not override.
-
-1.5.6 (2020-06-01)
-+++++++++++++++++++
-
-**Improvements**
-
-- #186 Error handling when calling strategy functions
-- Start delay bumped on workers and name changed
-- Minor typos / cleanups
-
-1.5.5 (2020-05-29)
-+++++++++++++++++++
-
-**Improvements**
-
-- Missing Middleware inheritance
-- get_sp added
-
-**Bug Fixes**
-
-- MarketCatalogue missing from Market when logged
-
 1.5.4 (2020-05-22)
 +++++++++++++++++++
 
diff --git a/flumine/__version__.py b/flumine/__version__.py
index 8698451..9e02207 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.6.0"
+__version__ = "1.5.4"
 __author__ = "Liam Pauling"
 __license__ = "MIT"
diff --git a/flumine/baseflumine.py b/flumine/baseflumine.py
index fa526df..8dfd155 100644
--- a/flumine/baseflumine.py
+++ b/flumine/baseflumine.py
@@ -17,7 +17,7 @@ from .order.process import process_current_orders
 from .controls.clientcontrols import BaseControl, MaxOrderCount
 from .controls.tradingcontrols import OrderValidation, StrategyExposure
 from .controls.loggingcontrols import LoggingControl
-from . import config, utils
+from . import config
 
 
 logger = logging.getLogger(__name__)
@@ -122,10 +122,8 @@ class BaseFlumine:
                 middleware(market)  # todo err handling?
 
             for strategy in self.strategies:
-                if utils.call_check_market(strategy.check_market, market, market_book):
-                    utils.call_process_market_book(
-                        strategy.process_market_book, market, market_book
-                    )
+                if strategy.check_market(market, market_book):
+                    strategy.process_market_book(market, market_book)
 
             self._process_market_orders(market)
 
@@ -166,13 +164,11 @@ class BaseFlumine:
             market = self.markets.markets.get(market_catalogue.market_id)
             if market:
                 if market.market_catalogue is None:
-                    market.market_catalogue = market_catalogue
                     self.log_control(events.MarketEvent(market))
                     logger.info(
                         "Updated marketCatalogue for {0}".format(market.market_id)
                     )
-                else:
-                    market.market_catalogue = market_catalogue
+                market.market_catalogue = market_catalogue
 
     def _process_current_orders(self, event: events.CurrentOrdersEvent) -> None:
         process_current_orders(self.markets, self.strategies, event)  # update state
diff --git a/flumine/config.py b/flumine/config.py
index 122ba06..b202c36 100644
--- a/flumine/config.py
+++ b/flumine/config.py
@@ -10,5 +10,3 @@ hostname = socket.gethostname()[
 process_id = os.getpid()  # process id of app
 
 current_time = None  # used for backtesting
-
-raise_errors = False  # used for call_check_market / call_process_market_book
diff --git a/flumine/execution/betfairexecution.py b/flumine/execution/betfairexecution.py
index c1335f9..327899f 100644
--- a/flumine/execution/betfairexecution.py
+++ b/flumine/execution/betfairexecution.py
@@ -23,17 +23,14 @@ class BetfairExecution(BaseExecution):
             for (order, instruction_report) in zip(
                 order_package, response.place_instruction_reports
             ):
-                with order.trade:
-                    self._order_logger(
-                        order, instruction_report, OrderPackageType.PLACE
-                    )
-                    if instruction_report.status == "SUCCESS":
-                        order.executable()
-                    elif instruction_report.status == "FAILURE":
-                        order.lapsed()  # todo correct?
-                    elif instruction_report.status == "TIMEOUT":
-                        # https://docs.developer.betfair.com/display/1smk3cen4v3lu3yomq5qye0ni/Betting+Enums#BettingEnums-ExecutionReportStatus
-                        pass
+                self._order_logger(order, instruction_report, OrderPackageType.PLACE)
+                if instruction_report.status == "SUCCESS":
+                    order.executable()
+                elif instruction_report.status == "FAILURE":
+                    order.lapsed()  # todo correct?
+                elif instruction_report.status == "TIMEOUT":
+                    # https://docs.developer.betfair.com/display/1smk3cen4v3lu3yomq5qye0ni/Betting+Enums#BettingEnums-ExecutionReportStatus
+                    pass
 
     def place(self, order_package: OrderPackageType, session: requests.Session):
         return order_package.client.betting_client.betting.place_orders(
@@ -55,26 +52,22 @@ class BetfairExecution(BaseExecution):
             for instruction_report in response.cancel_instruction_reports:
                 # get order (can't rely on the order they are returned)
                 order = order_lookup.pop(instruction_report.instruction.bet_id)
-                with order.trade:
-                    self._order_logger(
-                        order, instruction_report, OrderPackageType.CANCEL
-                    )
-                    if instruction_report.status == "SUCCESS":
-                        if (
-                            instruction_report.size_cancelled == order.size_remaining
-                        ):  # todo what if?
-                            order.execution_complete()
-                        else:
-                            order.executable()
-                    elif instruction_report.status == "FAILURE":
-                        order.executable()
-                    elif instruction_report.status == "TIMEOUT":
+                self._order_logger(order, instruction_report, OrderPackageType.CANCEL)
+                if instruction_report.status == "SUCCESS":
+                    if (
+                        instruction_report.size_cancelled == order.size_remaining
+                    ):  # todo what if?
+                        order.execution_complete()
+                    else:
                         order.executable()
+                elif instruction_report.status == "FAILURE":
+                    order.executable()
+                elif instruction_report.status == "TIMEOUT":
+                    order.executable()
 
             # reset any not returned so that they can be picked back up
             for order in order_lookup.values():
-                with order.trade:
-                    order.executable()
+                order.executable()
 
     def cancel(self, order_package: OrderPackageType, session: requests.Session):
         # temp copy to prevent an empty list of instructions sent
@@ -99,16 +92,13 @@ class BetfairExecution(BaseExecution):
             for (order, instruction_report) in zip(
                 order_package, response.update_instruction_reports
             ):
-                with order.trade:
-                    self._order_logger(
-                        order, instruction_report, OrderPackageType.UPDATE
-                    )
-                    if instruction_report.status == "SUCCESS":
-                        order.executable()
-                    elif instruction_report.status == "FAILURE":
-                        order.executable()
-                    elif instruction_report.status == "TIMEOUT":
-                        order.executable()
+                self._order_logger(order, instruction_report, OrderPackageType.UPDATE)
+                if instruction_report.status == "SUCCESS":
+                    order.executable()
+                elif instruction_report.status == "FAILURE":
+                    order.executable()
+                elif instruction_report.status == "TIMEOUT":
+                    order.executable()
 
     def update(self, order_package: OrderPackageType, session: requests.Session):
         return order_package.client.betting_client.betting.update_orders(
@@ -126,54 +116,36 @@ class BetfairExecution(BaseExecution):
             for (order, instruction_report) in zip(
                 order_package, response.replace_instruction_reports
             ):
-                with order.trade:
-                    # process cancel response
-                    if (
-                        instruction_report.cancel_instruction_reports.status
-                        == "SUCCESS"
-                    ):
-                        self._order_logger(
-                            order,
-                            instruction_report.cancel_instruction_reports,
-                            OrderPackageType.CANCEL,
-                        )
-                        order.execution_complete()
-                    elif (
-                        instruction_report.cancel_instruction_reports.status
-                        == "FAILURE"
-                    ):
-                        order.executable()
-                    elif (
-                        instruction_report.cancel_instruction_reports.status
-                        == "TIMEOUT"
-                    ):
-                        order.executable()
+                # process cancel response
+                if instruction_report.cancel_instruction_reports.status == "SUCCESS":
+                    self._order_logger(
+                        order,
+                        instruction_report.cancel_instruction_reports,
+                        OrderPackageType.CANCEL,
+                    )
+                    order.execution_complete()
+                elif instruction_report.cancel_instruction_reports.status == "FAILURE":
+                    order.executable()
+                elif instruction_report.cancel_instruction_reports.status == "TIMEOUT":
+                    order.executable()
 
-                    # process place response
-                    if instruction_report.place_instruction_reports.status == "SUCCESS":
-                        # create new order
-                        replacement_order = order.trade.create_order_replacement(
-                            order,
-                            instruction_report.place_instruction_reports.instruction.limit_order.price,
-                        )
-                        self._order_logger(
-                            replacement_order,
-                            instruction_report.place_instruction_reports,
-                            OrderPackageType.REPLACE,
-                        )
-                        # add to blotter
-                        order_package.market.place_order(
-                            replacement_order, execute=False
-                        )
-                        replacement_order.executable()
-                    elif (
-                        instruction_report.place_instruction_reports.status == "FAILURE"
-                    ):
-                        pass  # todo
-                    elif (
-                        instruction_report.place_instruction_reports.status == "TIMEOUT"
-                    ):
-                        pass  # todo
+                # process place response
+                if instruction_report.place_instruction_reports.status == "SUCCESS":
+                    # create new order
+                    replacement_order = order.trade.create_order_replacement(order)
+                    self._order_logger(
+                        replacement_order,
+                        instruction_report.place_instruction_reports,
+                        OrderPackageType.REPLACE,
+                    )
+                    # add to blotter
+                    market = self.markets.markets[order.market_id]
+                    market.place_order(replacement_order, execute=False)
+                    replacement_order.executable()
+                elif instruction_report.place_instruction_reports.status == "FAILURE":
+                    pass  # todo
+                elif instruction_report.place_instruction_reports.status == "TIMEOUT":
+                    pass  # todo
 
     def replace(self, order_package: OrderPackageType, session: requests.Session):
         return order_package.client.betting_client.betting.replace_orders(
diff --git a/flumine/execution/simulatedexecution.py b/flumine/execution/simulatedexecution.py
index dd997c3..387002e 100644
--- a/flumine/execution/simulatedexecution.py
+++ b/flumine/execution/simulatedexecution.py
@@ -40,18 +40,15 @@ class SimulatedExecution(BaseExecution):
         #     time.sleep(order_package.bet_delay + self.PLACE_LATENCY)
         market_book = order_package.market.market_book
         for order, instruction in zip(order_package, order_package.place_instructions):
-            with order.trade:
-                self._bet_id += 1
-                simulated_response = order.simulated.place(
-                    market_book, instruction, self._bet_id
-                )
-                self._order_logger(
-                    order, simulated_response, order_package.package_type
-                )
-                if simulated_response.status == "SUCCESS":
-                    order.executable()
-                elif simulated_response.status == "FAILURE":
-                    order.lapsed()
+            self._bet_id += 1
+            simulated_response = order.simulated.place(
+                market_book, instruction, self._bet_id
+            )
+            self._order_logger(order, simulated_response, order_package.package_type)
+            if simulated_response.status == "SUCCESS":
+                order.executable()
+            elif simulated_response.status == "FAILURE":
+                order.lapsed()
 
     def execute_cancel(
         self, order_package, http_session: Optional[requests.Session]
@@ -59,71 +56,19 @@ class SimulatedExecution(BaseExecution):
         # todo if order_package.client.paper_trade:
         #     time.sleep(self.CANCEL_LATENCY)
         for order in order_package:
-            with order.trade:
-                simulated_response = order.simulated.cancel()
-                self._order_logger(
-                    order, simulated_response, order_package.package_type
-                )
-                if simulated_response.status == "SUCCESS":
-                    order.execution_complete()
-                elif simulated_response.status == "FAILURE":
-                    order.executable()
+            simulated_response = order.simulated.cancel()
+            self._order_logger(order, simulated_response, order_package.package_type)
+            if simulated_response.status == "SUCCESS":
+                order.execution_complete()
+            elif simulated_response.status == "FAILURE":
+                order.executable()
 
     def execute_update(
         self, order_package, http_session: Optional[requests.Session]
     ) -> None:
-        # todo if order_package.client.paper_trade:
-        #     time.sleep(self.UPDATE_LATENCY)
-        for order, instruction in zip(order_package, order_package.update_instructions):
-            with order.trade:
-                simulated_response = order.simulated.update(instruction)
-                self._order_logger(
-                    order, simulated_response, order_package.package_type
-                )
-                if simulated_response.status == "SUCCESS":
-                    order.executable()
-                elif simulated_response.status == "FAILURE":
-                    order.executable()
+        raise NotImplementedError
 
     def execute_replace(
         self, order_package, http_session: Optional[requests.Session]
     ) -> None:
-        # todo if order_package.client.paper_trade:
-        #     time.sleep(self.REPLACE_LATENCY)
-        market_book = order_package.market.market_book
-        for order, instruction in zip(
-            order_package, order_package.replace_instructions
-        ):
-            with order.trade:
-                # cancel current order
-                cancel_instruction_report = order.simulated.cancel()
-                if cancel_instruction_report.status == "SUCCESS":
-                    order.execution_complete()
-                elif cancel_instruction_report.status == "FAILURE":
-                    order.executable()  # todo do not carry out replace
-                else:
-                    order.lapsed()  # todo do not carry out replace
-                self._order_logger(
-                    order, cancel_instruction_report, OrderPackageType.CANCEL,
-                )
-
-                # place new order
-                self._bet_id += 1
-                replacement_order = order.trade.create_order_replacement(
-                    order, instruction.get("newPrice")
-                )
-                place_instruction_report = replacement_order.simulated.place(
-                    market_book, instruction, self._bet_id
-                )
-                if place_instruction_report.status == "SUCCESS":
-                    self._order_logger(
-                        replacement_order,
-                        place_instruction_report,
-                        order_package.package_type,
-                    )
-                    # add to blotter
-                    market = order_package.market
-                    market.place_order(replacement_order, execute=False)
-                    replacement_order.executable()
-                elif place_instruction_report.status == "FAILURE":
-                    order.executable()
+        raise NotImplementedError
diff --git a/flumine/flumine.py b/flumine/flumine.py
index 9902be5..9fb5af0 100644
--- a/flumine/flumine.py
+++ b/flumine/flumine.py
@@ -54,14 +54,17 @@ class Flumine(BaseFlumine):
 
     def _add_default_workers(self):
         self.add_worker(
-            worker.BackgroundWorker(self, function=worker.keep_alive, interval=1200)
+            worker.BackgroundWorker(
+                self, function=worker.keep_alive, interval=1200, name="keep_alive",
+            )
         )
         self.add_worker(
             worker.BackgroundWorker(
                 self,
                 function=worker.poll_account_balance,
                 interval=60,
-                start_delay=10,  # wait for login
+                start_delay=5,  # wait for login
+                name="poll_account_balance",
             )
         )
         self.add_worker(
@@ -69,7 +72,8 @@ class Flumine(BaseFlumine):
                 self,
                 function=worker.poll_market_catalogue,
                 interval=60,
-                start_delay=10,  # wait for streams to populate
+                start_delay=5,  # wait for streams to populate
+                name="poll_market_catalogue",
             )
         )
         self.add_worker(
@@ -77,7 +81,7 @@ class Flumine(BaseFlumine):
                 self,
                 function=worker.poll_cleared_orders,
                 interval=10,  # restart
-                start_delay=10,  # wait for login
+                name="poll_cleared_orders",
             )
         )
 
diff --git a/flumine/markets/blotter.py b/flumine/markets/blotter.py
index 9bdd639..dabf424 100644
--- a/flumine/markets/blotter.py
+++ b/flumine/markets/blotter.py
@@ -72,10 +72,7 @@ class Blotter:
     @property
     def live_orders(self) -> bool:
         for order in self._orders.values():
-            if (
-                order.status == OrderStatus.EXECUTABLE
-                or order.trade.trade_complete is False
-            ):
+            if order.status == OrderStatus.EXECUTABLE:
                 return True
         return False
 
@@ -92,7 +89,9 @@ class Blotter:
 
     def selection_exposure(self, strategy, lookup: tuple) -> float:
         """Returns strategy/selection exposure,
-        max value is 0
+        can be positive or negative.
+            positive = profit on selection
+            negative = exposure on selection
         """
         mb, ml = [], []  # (price, size)
         for order in self:
diff --git a/flumine/markets/middleware.py b/flumine/markets/middleware.py
index de95269..fb01511 100644
--- a/flumine/markets/middleware.py
+++ b/flumine/markets/middleware.py
@@ -1,6 +1,6 @@
 import logging
 from collections import defaultdict
-from betfairlightweight.resources.bettingresources import RunnerBook
+from betfairlightweight.resources.bettingresources import MarketBook, RunnerBook
 
 from ..order.order import OrderStatus
 
@@ -12,7 +12,7 @@ class Middleware:
         raise NotImplementedError
 
 
-class SimulatedMiddleware(Middleware):
+class SimulatedMiddleware:
     """
     Calculates matched amounts per runner
     to be used in simulated matching.
diff --git a/flumine/order/process.py b/flumine/order/process.py
index 404ec77..d524cb6 100644
--- a/flumine/order/process.py
+++ b/flumine/order/process.py
@@ -59,8 +59,10 @@ def process_current_order(order: BaseOrder):
         elif order.size_remaining == 0:
             order.execution_complete()
 
-    if order.trade.trade_complete:
-        order.trade.complete()
+    if order.status == OrderStatus.EXECUTION_COMPLETE:
+        if order.trade.status == TradeStatus.LIVE:
+            if not order.trade.offset_orders:
+                order.trade.complete()
 
 
 def create_order_from_current(markets: Markets, strategies: Strategies, current_order):
diff --git a/flumine/order/trade.py b/flumine/order/trade.py
index 29a4bb1..79e2000 100644
--- a/flumine/order/trade.py
+++ b/flumine/order/trade.py
@@ -6,7 +6,7 @@ from typing import Union, Type
 from betfairlightweight.resources.bettingresources import CurrentOrder
 
 from ..strategy.strategy import BaseStrategy
-from .order import BetfairOrder, OrderStatus
+from .order import BetfairOrder
 from .ordertype import LimitOrder, LimitOnCloseOrder, MarketOnCloseOrder
 from ..exceptions import OrderError
 
@@ -14,7 +14,6 @@ logger = logging.getLogger(__name__)
 
 
 class TradeStatus(Enum):
-    PENDING = "Pending"  # pending exchange processing
     LIVE = "Live"
     COMPLETE = "Complete"
 
@@ -63,17 +62,6 @@ class Trade:
         )
         runner_context.reset()  # todo race condition?
 
-    @property
-    def trade_complete(self) -> bool:
-        if self.status != TradeStatus.LIVE:
-            return False
-        if self.offset_orders:
-            return False
-        for order in self.orders:
-            if order.status != OrderStatus.EXECUTION_COMPLETE:
-                return False
-        return True
-
     def create_order(
         self,
         side: str,
@@ -89,13 +77,11 @@ class Trade:
         self.orders.append(order)
         return order
 
-    def create_order_replacement(
-        self, order: BetfairOrder, new_price: float
-    ) -> BetfairOrder:
+    def create_order_replacement(self, order: BetfairOrder) -> BetfairOrder:
         """Create new order due to replace
         execution"""
         order_type = LimitOrder(
-            price=new_price,
+            price=order.update_data["new_price"],
             size=order.order_type.size,
             persistence_type=order.order_type.persistence_type,
         )
@@ -140,13 +126,3 @@ class Trade:
             "orders": [o.id for o in self.orders],
             "notes": self.notes_str,
         }
-
-    def __enter__(self):
-        # todo raise error if already pending?
-        self._update_status(TradeStatus.PENDING)
-
-    def __exit__(self, exc_type, exc_val, exc_tb):
-        if exc_tb is None:
-            self._update_status(TradeStatus.LIVE)
-        else:
-            logger.critical("Trade error in %s" % self.id, exc_info=True)
diff --git a/flumine/streams/orderstream.py b/flumine/streams/orderstream.py
index 5e65888..f228e43 100644
--- a/flumine/streams/orderstream.py
+++ b/flumine/streams/orderstream.py
@@ -33,12 +33,12 @@ class OrderStream(BaseStream):
             )
             self._stream.start()
         except BetfairError:
-            logger.error("OrderStream run error", exc_info=True)
+            logger.error("MarketStream run error", exc_info=True)
             raise
         except Exception:
-            logger.critical("OrderStream run error", exc_info=True)
+            logger.critical("MarketStream run error", exc_info=True)
             raise
-        logger.info("Stopped OrderStream {0}".format(self.stream_id))
+        logger.info("Stopped MarketStream {0}".format(self.stream_id))
 
     def handle_output(self) -> None:
         """Handles output from stream.
diff --git a/flumine/utils.py b/flumine/utils.py
index 869cd6b..83bb5fa 100644
--- a/flumine/utils.py
+++ b/flumine/utils.py
@@ -1,12 +1,8 @@
 import uuid
 import logging
 import hashlib
-from typing import Optional, Tuple, Callable
+from typing import Optional, Tuple
 from decimal import Decimal
-from betfairlightweight.resources.bettingresources import RunnerBook
-
-from . import config
-from .exceptions import FlumineException
 
 logger = logging.getLogger(__name__)
 
@@ -96,17 +92,6 @@ def get_size(data: list, level: int) -> Optional[float]:
         return
 
 
-def get_sp(runner: RunnerBook) -> Optional[float]:
-    if isinstance(runner.sp, list):
-        return
-    elif runner.sp is None:
-        return
-    elif runner.sp.actual_sp == "NaN":
-        return
-    else:
-        return runner.sp.actual_sp
-
-
 def price_ticks_away(price: float, n_ticks: int) -> float:
     try:
         price_index = PRICES.index(as_dec(price))
@@ -123,11 +108,12 @@ def calculate_exposure(mb: list, ml: list) -> int:
     of (price, size)
     """
     back_exp = sum(-i[1] for i in mb)
-    back_profit = sum(i[0] * i[1] for i in mb)
+    back_profit = sum((i[0] - 1) * i[1] for i in mb)
     lay_exp = sum((i[0] - 1) * -i[1] for i in ml)
-    if lay_exp:
-        lay_exp += back_profit
-    return min(round(back_exp + lay_exp, 2), 0)  # returns negative int
+    lay_profit = sum(i[1] for i in ml)
+    _win = back_profit + lay_exp
+    _lose = lay_profit + back_exp
+    return round(min(_win, _lose), 2)
 
 
 # todo LRU cache?
@@ -142,44 +128,3 @@ def wap(matched: list) -> Tuple[float, float]:
         return 0, 0
     else:
         return round(b, 2), round(a / b, 2)
-
-
-def call_check_market(strategy_check_market: Callable, market, market_book) -> bool:
-    try:
-        return strategy_check_market(market, market_book)
-    except FlumineException as e:
-        logger.error(
-            "FlumineException %s in strategy_check_market %s %s"
-            % (e, strategy_check_market, market.market_id),
-            exc_info=True,
-        )
-    except Exception as e:
-        logger.critical(
-            "Unknown error %s in strategy_check_market %s %s"
-            % (e, strategy_check_market, market.market_id),
-            exc_info=True,
-        )
-        if config.raise_errors:
-            raise
-    return False
-
-
-def call_process_market_book(
-    strategy_process_market_book: Callable, market, market_book
-) -> None:
-    try:
-        strategy_process_market_book(market, market_book)
-    except FlumineException as e:
-        logger.error(
-            "FlumineException %s in strategy_process_market_book %s %s"
-            % (e, strategy_process_market_book, market.market_id),
-            exc_info=True,
-        )
-    except Exception as e:
-        logger.critical(
-            "Unknown error %s in strategy_process_market_book %s %s"
-            % (e, strategy_process_market_book, market.market_id),
-            exc_info=True,
-        )
-        if config.raise_errors:
-            raise
diff --git a/flumine/worker.py b/flumine/worker.py
index 2e3e893..10473ab 100644
--- a/flumine/worker.py
+++ b/flumine/worker.py
@@ -1,7 +1,7 @@
 import time
 import threading
 import logging
-from typing import Callable
+import queue
 from betfairlightweight import BetfairError, filters
 
 from . import config
@@ -15,17 +15,15 @@ class BackgroundWorker(threading.Thread):
     def __init__(
         self,
         flumine,
-        function: Callable,
+        function,
         interval: int,
         func_args: tuple = None,
         func_kwargs: dict = None,
         start_delay: int = 0,
         context: dict = None,
-        name: str = None,
         **kwargs
     ):
-        name = name or function.__name__
-        threading.Thread.__init__(self, daemon=True, name=name, **kwargs)
+        threading.Thread.__init__(self, daemon=True, **kwargs)
         self.flumine = flumine
         self.function = function
         self.interval = interval


Test patch:
diff --git a/flumine/backtest/backtest.py b/flumine/backtest/backtest.py
index 2c7fdd3..223304d 100644
--- a/flumine/backtest/backtest.py
+++ b/flumine/backtest/backtest.py
@@ -3,7 +3,7 @@ import datetime
 
 from ..baseflumine import BaseFlumine
 from ..events import events
-from .. import config, utils
+from .. import config
 from ..clients import ExchangeType
 from ..exceptions import RunError
 from .utils import PendingPackages
@@ -87,10 +87,8 @@ class FlumineBacktest(BaseFlumine):
                 middleware(market)  # todo err handling?
 
             for strategy in self.strategies:
-                if utils.call_check_market(strategy.check_market, market, market_book):
-                    utils.call_process_market_book(
-                        strategy.process_market_book, market, market_book
-                    )
+                if strategy.check_market(market, market_book):
+                    strategy.process_market_book(market, market_book)
 
             # process current orders
             blotter = market.blotter
diff --git a/flumine/backtest/simulated.py b/flumine/backtest/simulated.py
index 05e296d..6e9c877 100644
--- a/flumine/backtest/simulated.py
+++ b/flumine/backtest/simulated.py
@@ -1,11 +1,7 @@
 import datetime
 from betfairlightweight.resources.bettingresources import MarketBook, RunnerBook
 
-from .utils import (
-    SimulatedPlaceResponse,
-    SimulatedCancelResponse,
-    SimulatedUpdateResponse,
-)
+from .utils import SimulatedPlaceResponse, SimulatedCancelResponse
 from ..utils import get_price, wap
 from ..order.ordertype import OrderTypes
 from .. import config
@@ -102,20 +98,13 @@ class Simulated:
                 status="FAILURE", error_code="BET_ACTION_ERROR",  # todo ?
             )
 
-    def update(self, instruction: dict):
+    def update(self):
         # simulates updateOrder request->update->response
-        if (
-            self.order.order_type.ORDER_TYPE == OrderTypes.LIMIT
-            and self.size_remaining > 0
-        ):
-            self.order.order_type.persistence_type = instruction.get(
-                "newPersistenceType"
-            )
-            return SimulatedUpdateResponse(status="SUCCESS")
-        else:
-            return SimulatedCancelResponse(
-                status="FAILURE", error_code="BET_ACTION_ERROR",
-            )
+        pass
+
+    def replace(self):
+        # simulates replaceOrder request->cancel/matching->response
+        pass
 
     def _get_runner(self, market_book: MarketBook) -> RunnerBook:
         runner_dict = {
diff --git a/flumine/backtest/utils.py b/flumine/backtest/utils.py
index bc5befe..9aa475c 100644
--- a/flumine/backtest/utils.py
+++ b/flumine/backtest/utils.py
@@ -42,11 +42,3 @@ class SimulatedCancelResponse:
         self.size_cancelled = size_cancelled
         self.cancelled_date = cancelled_date
         self.error_code = error_code
-
-
-class SimulatedUpdateResponse:
-    def __init__(
-        self, status: str = None, error_code: str = None,
-    ):
-        self.status = status
-        self.error_code = error_code
diff --git a/tests/test_blotter.py b/tests/test_blotter.py
index 33a1659..e639885 100644
--- a/tests/test_blotter.py
+++ b/tests/test_blotter.py
@@ -75,14 +75,6 @@ class BlotterTest(unittest.TestCase):
         self.blotter._orders = {"12345": mock_order}
         self.assertTrue(self.blotter.live_orders)
 
-    def test_live_orders_trade(self):
-        self.assertFalse(self.blotter.live_orders)
-        mock_order = mock.Mock()
-        mock_order.trade.trade_complete = False
-        mock_order.status = OrderStatus.EXECUTION_COMPLETE
-        self.blotter._orders = {"12345": mock_order}
-        self.assertTrue(self.blotter.live_orders)
-
     def test_process_closed_market(self):
         mock_market_book = mock.Mock()
         mock_runner = mock.Mock(selection_id=123, handicap=0.0)
diff --git a/tests/test_execution.py b/tests/test_execution.py
index 83842e0..98f2263 100644
--- a/tests/test_execution.py
+++ b/tests/test_execution.py
@@ -1,12 +1,11 @@
 import unittest
 from unittest import mock
-from unittest.mock import call
 
-from flumine.clients.clients import ExchangeType
-from flumine.exceptions import OrderExecutionError
 from flumine.execution.baseexecution import BaseExecution, OrderPackageType
 from flumine.execution.betfairexecution import BetfairExecution
 from flumine.execution.simulatedexecution import SimulatedExecution
+from flumine.clients.clients import ExchangeType
+from flumine.exceptions import OrderExecutionError
 
 
 class BaseExecutionTest(unittest.TestCase):
@@ -142,8 +141,6 @@ class BetfairExecutionTest(unittest.TestCase):
     ):
         mock_session = mock.Mock()
         mock_order = mock.Mock()
-        mock_order.trade.__enter__ = mock.Mock()
-        mock_order.trade.__exit__ = mock.Mock()
         mock_order_package = mock.Mock()
         mock_order_package.__iter__ = mock.Mock(return_value=iter([mock_order]))
         mock_order_package.info = {}
@@ -160,8 +157,6 @@ class BetfairExecutionTest(unittest.TestCase):
             mock_order, mock_instruction_report, OrderPackageType.PLACE
         )
         mock_order.executable.assert_called_with()
-        mock_order.trade.__enter__.assert_called_with()
-        mock_order.trade.__exit__.assert_called_with(None, None, None)
 
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution._order_logger")
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution.place")
@@ -171,8 +166,6 @@ class BetfairExecutionTest(unittest.TestCase):
     ):
         mock_session = mock.Mock()
         mock_order = mock.Mock()
-        mock_order.trade.__enter__ = mock.Mock()
-        mock_order.trade.__exit__ = mock.Mock()
         mock_order_package = mock.Mock()
         mock_order_package.__iter__ = mock.Mock(return_value=iter([mock_order]))
         mock_order_package.info = {}
@@ -189,8 +182,6 @@ class BetfairExecutionTest(unittest.TestCase):
             mock_order, mock_instruction_report, OrderPackageType.PLACE
         )
         mock_order.lapsed.assert_called_with()
-        mock_order.trade.__enter__.assert_called_with()
-        mock_order.trade.__exit__.assert_called_with(None, None, None)
 
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution._order_logger")
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution.place")
@@ -200,8 +191,6 @@ class BetfairExecutionTest(unittest.TestCase):
     ):
         mock_session = mock.Mock()
         mock_order = mock.Mock()
-        mock_order.trade.__enter__ = mock.Mock()
-        mock_order.trade.__exit__ = mock.Mock()
         mock_order_package = mock.Mock()
         mock_order_package.__iter__ = mock.Mock(return_value=iter([mock_order]))
         mock_order_package.info = {}
@@ -218,8 +207,6 @@ class BetfairExecutionTest(unittest.TestCase):
             mock_order, mock_instruction_report, OrderPackageType.PLACE
         )
         # mock_order.lapsed.assert_called_with()
-        mock_order.trade.__enter__.assert_called_with()
-        mock_order.trade.__exit__.assert_called_with(None, None, None)
 
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution.place")
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution._execution_helper")
@@ -249,8 +236,6 @@ class BetfairExecutionTest(unittest.TestCase):
     ):
         mock_session = mock.Mock()
         mock_order = mock.Mock()
-        mock_order.trade.__enter__ = mock.Mock()
-        mock_order.trade.__exit__ = mock.Mock()
         mock_order.bet_id = 123
         mock_order.size_remaining = 2
         mock_order_package = mock.Mock()
@@ -271,8 +256,6 @@ class BetfairExecutionTest(unittest.TestCase):
             mock_order, mock_instruction_report, OrderPackageType.CANCEL
         )
         mock_order.execution_complete.assert_called_with()
-        mock_order.trade.__enter__.assert_called_with()
-        mock_order.trade.__exit__.assert_called_with(None, None, None)
 
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution._order_logger")
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution.cancel")
@@ -282,8 +265,6 @@ class BetfairExecutionTest(unittest.TestCase):
     ):
         mock_session = mock.Mock()
         mock_order = mock.Mock()
-        mock_order.trade.__enter__ = mock.Mock()
-        mock_order.trade.__exit__ = mock.Mock()
         mock_order.bet_id = 123
         mock_order.size_remaining = 2
         mock_order_package = mock.Mock()
@@ -304,8 +285,6 @@ class BetfairExecutionTest(unittest.TestCase):
             mock_order, mock_instruction_report, OrderPackageType.CANCEL
         )
         mock_order.executable.assert_called_with()
-        mock_order.trade.__enter__.assert_called_with()
-        mock_order.trade.__exit__.assert_called_with(None, None, None)
 
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution._order_logger")
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution.cancel")
@@ -315,8 +294,6 @@ class BetfairExecutionTest(unittest.TestCase):
     ):
         mock_session = mock.Mock()
         mock_order = mock.Mock()
-        mock_order.trade.__enter__ = mock.Mock()
-        mock_order.trade.__exit__ = mock.Mock()
         mock_order.bet_id = 123
         mock_order_package = mock.Mock()
         mock_order_package.__iter__ = mock.Mock(return_value=iter([mock_order]))
@@ -335,8 +312,6 @@ class BetfairExecutionTest(unittest.TestCase):
             mock_order, mock_instruction_report, OrderPackageType.CANCEL
         )
         mock_order.executable.assert_called_with()
-        mock_order.trade.__enter__.assert_called_with()
-        mock_order.trade.__exit__.assert_called_with(None, None, None)
 
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution._order_logger")
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution.cancel")
@@ -346,8 +321,6 @@ class BetfairExecutionTest(unittest.TestCase):
     ):
         mock_session = mock.Mock()
         mock_order = mock.Mock()
-        mock_order.trade.__enter__ = mock.Mock()
-        mock_order.trade.__exit__ = mock.Mock()
         mock_order.bet_id = 123
         mock_order_package = mock.Mock()
         mock_order_package.__iter__ = mock.Mock(return_value=iter([mock_order]))
@@ -366,8 +339,6 @@ class BetfairExecutionTest(unittest.TestCase):
             mock_order, mock_instruction_report, OrderPackageType.CANCEL
         )
         mock_order.executable.assert_called_with()
-        mock_order.trade.__enter__.assert_called_with()
-        mock_order.trade.__exit__.assert_called_with(None, None, None)
 
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution._order_logger")
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution.cancel")
@@ -377,8 +348,6 @@ class BetfairExecutionTest(unittest.TestCase):
     ):
         mock_session = mock.Mock()
         mock_order = mock.Mock()
-        mock_order.trade.__enter__ = mock.Mock()
-        mock_order.trade.__exit__ = mock.Mock()
         mock_order.bet_id = 123
         mock_order_package = mock.Mock()
         mock_order_package.__iter__ = mock.Mock(return_value=iter([mock_order]))
@@ -391,8 +360,6 @@ class BetfairExecutionTest(unittest.TestCase):
             mock_cancel, mock_order_package, mock_session
         )
         mock_order.executable.assert_called_with()
-        mock_order.trade.__enter__.assert_called_with()
-        mock_order.trade.__exit__.assert_called_with(None, None, None)
 
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution.cancel")
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution._execution_helper")
@@ -431,8 +398,6 @@ class BetfairExecutionTest(unittest.TestCase):
     ):
         mock_session = mock.Mock()
         mock_order = mock.Mock()
-        mock_order.trade.__enter__ = mock.Mock()
-        mock_order.trade.__exit__ = mock.Mock()
         mock_order.bet_id = 123
         mock_order_package = mock.Mock()
         mock_order_package.__iter__ = mock.Mock(return_value=iter([mock_order]))
@@ -450,8 +415,6 @@ class BetfairExecutionTest(unittest.TestCase):
             mock_order, mock_instruction_report, OrderPackageType.UPDATE
         )
         mock_order.executable.assert_called_with()
-        mock_order.trade.__enter__.assert_called_with()
-        mock_order.trade.__exit__.assert_called_with(None, None, None)
 
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution._order_logger")
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution.update")
@@ -461,8 +424,6 @@ class BetfairExecutionTest(unittest.TestCase):
     ):
         mock_session = mock.Mock()
         mock_order = mock.Mock()
-        mock_order.trade.__enter__ = mock.Mock()
-        mock_order.trade.__exit__ = mock.Mock()
         mock_order.bet_id = 123
         mock_order_package = mock.Mock()
         mock_order_package.__iter__ = mock.Mock(return_value=iter([mock_order]))
@@ -480,8 +441,6 @@ class BetfairExecutionTest(unittest.TestCase):
             mock_order, mock_instruction_report, OrderPackageType.UPDATE
         )
         mock_order.executable.assert_called_with()
-        mock_order.trade.__enter__.assert_called_with()
-        mock_order.trade.__exit__.assert_called_with(None, None, None)
 
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution._order_logger")
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution.update")
@@ -491,8 +450,6 @@ class BetfairExecutionTest(unittest.TestCase):
     ):
         mock_session = mock.Mock()
         mock_order = mock.Mock()
-        mock_order.trade.__enter__ = mock.Mock()
-        mock_order.trade.__exit__ = mock.Mock()
         mock_order.bet_id = 123
         mock_order_package = mock.Mock()
         mock_order_package.__iter__ = mock.Mock(return_value=iter([mock_order]))
@@ -510,8 +467,6 @@ class BetfairExecutionTest(unittest.TestCase):
             mock_order, mock_instruction_report, OrderPackageType.UPDATE
         )
         mock_order.executable.assert_called_with()
-        mock_order.trade.__enter__.assert_called_with()
-        mock_order.trade.__exit__.assert_called_with(None, None, None)
 
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution.update")
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution._execution_helper")
@@ -539,10 +494,10 @@ class BetfairExecutionTest(unittest.TestCase):
     def test_execute_replace_success(
         self, mock__execution_helper, mock_replace, mock__order_logger
     ):
+        mock_market = mock.Mock()
+        self.mock_flumine.markets.markets = {"1.234": mock_market}
         mock_session = mock.Mock()
         mock_order = mock.Mock()
-        mock_order.trade.__enter__ = mock.Mock()
-        mock_order.trade.__exit__ = mock.Mock()
         mock_order.market_id = "1.234"
         mock_order.bet_id = 123
         mock_order_package = mock.Mock()
@@ -565,16 +520,15 @@ class BetfairExecutionTest(unittest.TestCase):
 
         replacement_order = mock_order.trade.create_order_replacement()
         replacement_order.executable.assert_called_with()
-        mock_order_package.market.place_order.assert_called_with(
-            replacement_order, execute=False
-        )
+        mock_market.place_order.assert_called_with(replacement_order, execute=False)
         mock__order_logger.assert_called_with(
             replacement_order,
             mock_instruction_report.place_instruction_reports,
             OrderPackageType.REPLACE,
         )
-        mock_order.trade.__enter__.assert_called_with()
-        mock_order.trade.__exit__.assert_called_with(None, None, None)
+
+    # def test_execute_replace_failure(self):
+    #     pass
 
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution.replace")
     @mock.patch("flumine.execution.betfairexecution.BetfairExecution._execution_helper")
@@ -653,8 +607,6 @@ class SimulatedExecutionTest(unittest.TestCase):
     @mock.patch("flumine.execution.simulatedexecution.SimulatedExecution._order_logger")
     def test_execute_place_success(self, mock__order_logger):
         mock_order = mock.Mock()
-        mock_order.trade.__enter__ = mock.Mock()
-        mock_order.trade.__exit__ = mock.Mock()
         mock_order_package = mock.Mock()
         mock_order_package.__iter__ = mock.Mock(return_value=iter([mock_order]))
         mock_order_package.place_instructions = [1]
@@ -670,14 +622,10 @@ class SimulatedExecutionTest(unittest.TestCase):
             mock_order, mock_sim_resp, mock_order_package.package_type
         )
         mock_order.executable.assert_called_with()
-        mock_order.trade.__enter__.assert_called_with()
-        mock_order.trade.__exit__.assert_called_with(None, None, None)
 
     @mock.patch("flumine.execution.simulatedexecution.SimulatedExecution._order_logger")
     def test_execute_place_failure(self, mock__order_logger):
         mock_order = mock.Mock()
-        mock_order.trade.__enter__ = mock.Mock()
-        mock_order.trade.__exit__ = mock.Mock()
         mock_order_package = mock.Mock()
         mock_order_package.__iter__ = mock.Mock(return_value=iter([mock_order]))
         mock_order_package.place_instructions = [1]
@@ -693,14 +641,10 @@ class SimulatedExecutionTest(unittest.TestCase):
             mock_order, mock_sim_resp, mock_order_package.package_type
         )
         mock_order.lapsed.assert_called_with()
-        mock_order.trade.__enter__.assert_called_with()
-        mock_order.trade.__exit__.assert_called_with(None, None, None)
 
     @mock.patch("flumine.execution.simulatedexecution.SimulatedExecution._order_logger")
     def test_execute_cancel(self, mock__order_logger):
         mock_order = mock.Mock()
-        mock_order.trade.__enter__ = mock.Mock()
-        mock_order.trade.__exit__ = mock.Mock()
         mock_order_package = mock.Mock()
         mock_order_package.__iter__ = mock.Mock(return_value=iter([mock_order]))
         mock_sim_resp = mock.Mock()
@@ -712,14 +656,10 @@ class SimulatedExecutionTest(unittest.TestCase):
             mock_order, mock_sim_resp, mock_order_package.package_type
         )
         mock_order.execution_complete.assert_called_with()
-        mock_order.trade.__enter__.assert_called_with()
-        mock_order.trade.__exit__.assert_called_with(None, None, None)
 
     @mock.patch("flumine.execution.simulatedexecution.SimulatedExecution._order_logger")
     def test_execute_cancel_failure(self, mock__order_logger):
         mock_order = mock.Mock()
-        mock_order.trade.__enter__ = mock.Mock()
-        mock_order.trade.__exit__ = mock.Mock()
         mock_order_package = mock.Mock()
         mock_order_package.__iter__ = mock.Mock(return_value=iter([mock_order]))
         mock_sim_resp = mock.Mock()
@@ -731,123 +671,11 @@ class SimulatedExecutionTest(unittest.TestCase):
             mock_order, mock_sim_resp, mock_order_package.package_type
         )
         mock_order.executable.assert_called_with()
-        mock_order.trade.__enter__.assert_called_with()
-        mock_order.trade.__exit__.assert_called_with(None, None, None)
-
-    @mock.patch("flumine.execution.simulatedexecution.SimulatedExecution._order_logger")
-    def test_execute_update(self, mock__order_logger):
-        mock_order = mock.Mock()
-        mock_order.trade.__enter__ = mock.Mock()
-        mock_order.trade.__exit__ = mock.Mock()
-        mock_order_package = mock.Mock()
-        mock_order_package.__iter__ = mock.Mock(return_value=iter([mock_order]))
-        mock_order_package.update_instructions = ["PERSIST"]
-        mock_order_package.info = {}
-        mock_sim_resp = mock.Mock()
-        mock_sim_resp.status = "SUCCESS"
-        mock_order.simulated.update.return_value = mock_sim_resp
-        self.execution.execute_update(mock_order_package, None)
-        mock_order.simulated.update.assert_called_with("PERSIST")
-        mock__order_logger.assert_called_with(
-            mock_order, mock_sim_resp, mock_order_package.package_type
-        )
-        mock_order.executable.assert_called_with()
-        mock_order.trade.__enter__.assert_called_with()
-        mock_order.trade.__exit__.assert_called_with(None, None, None)
-
-    @mock.patch("flumine.execution.simulatedexecution.SimulatedExecution._order_logger")
-    def test_execute_update_failure(self, mock__order_logger):
-        mock_order = mock.Mock()
-        mock_order.trade.__enter__ = mock.Mock()
-        mock_order.trade.__exit__ = mock.Mock()
-        mock_order_package = mock.Mock()
-        mock_order_package.__iter__ = mock.Mock(return_value=iter([mock_order]))
-        mock_order_package.update_instructions = ["PERSIST"]
-        mock_order_package.info = {}
-        mock_sim_resp = mock.Mock()
-        mock_sim_resp.status = "FAILURE"
-        mock_order.simulated.update.return_value = mock_sim_resp
-        self.execution.execute_update(mock_order_package, None)
-        mock_order.simulated.update.assert_called_with("PERSIST")
-        mock__order_logger.assert_called_with(
-            mock_order, mock_sim_resp, mock_order_package.package_type
-        )
-        mock_order.executable.assert_called_with()
-        mock_order.trade.__enter__.assert_called_with()
-        mock_order.trade.__exit__.assert_called_with(None, None, None)
 
-    @mock.patch("flumine.execution.simulatedexecution.SimulatedExecution._order_logger")
-    def test_execute_replace(self, mock__order_logger):
-        mock_market = mock.Mock()
-        self.mock_flumine.markets.markets = {"1.234": mock_market}
-        mock_order = mock.Mock()
-        mock_order.trade.__enter__ = mock.Mock()
-        mock_order.trade.__exit__ = mock.Mock()
-        mock_order.market_id = "1.234"
-        mock_order_package = mock.Mock()
-        mock_order_package.__iter__ = mock.Mock(return_value=iter([mock_order]))
-        mock_order_package.replace_instructions = [{"newPrice": 2.03}]
-        mock_replacement_order = mock.Mock()
-        mock_replacement_order_package = mock.Mock()
-        mock_replacement_order_package.__iter__ = mock.Mock(
-            return_value=iter([mock_order])
-        )
-        mock_sim_resp = mock.Mock()
-        mock_sim_resp.status = "SUCCESS"
-        mock_order.simulated.cancel.return_value = mock_sim_resp
-        mock_replacement_order.simulated.place.return_value = mock_sim_resp
-        mock_order.trade.create_order_replacement.return_value = mock_replacement_order
-        self.execution.execute_replace(mock_order_package, None)
-        mock_order.simulated.cancel.assert_called_with()
-        mock_replacement_order.simulated.place.assert_called_with(
-            mock_order_package.market.market_book,
-            {"newPrice": 2.03},
-            self.execution._bet_id,
-        )
-        mock__order_logger.assert_has_calls(
-            [
-                call(mock_order, mock_sim_resp, OrderPackageType.CANCEL),
-                call(
-                    mock_replacement_order,
-                    mock_sim_resp,
-                    mock_order_package.package_type,
-                ),
-            ]
-        )
-        mock_order.execution_complete.assert_called_with()
-        mock_replacement_order.executable.assert_called_with()
-        mock_order.trade.__enter__.assert_called_with()
-        mock_order.trade.__exit__.assert_called_with(None, None, None)
+    def test_execute_update(self):
+        with self.assertRaises(NotImplementedError):
+            self.execution.execute_update(None, None)
 
-    @mock.patch("flumine.execution.simulatedexecution.SimulatedExecution._order_logger")
-    def test_execute_replace_failure(self, mock__order_logger):
-        mock_order = mock.Mock()
-        mock_order.trade.__enter__ = mock.Mock()
-        mock_order.trade.__exit__ = mock.Mock()
-        mock_order_package = mock.Mock()
-        mock_order_package.__iter__ = mock.Mock(return_value=iter([mock_order]))
-        mock_order_package.replace_instructions = [{"newPrice": 2.54}]
-        mock_replacement_order = mock.Mock()
-        mock_replacement_order_package = mock.Mock()
-        mock_replacement_order_package.__iter__ = mock.Mock(
-            return_value=iter([mock_order])
-        )
-        mock_sim_resp = mock.Mock()
-        mock_sim_resp.status = "FAILURE"
-        mock_order.simulated.cancel.return_value = mock_sim_resp
-        mock_replacement_order.simulated.place.return_value = mock_sim_resp
-        mock_order.trade.create_order_replacement.return_value = mock_replacement_order
-        self.execution.execute_replace(mock_order_package, None)
-        mock_order.simulated.cancel.assert_called_with()
-        mock_replacement_order.simulated.place.assert_called_with(
-            mock_order_package.market.market_book,
-            {"newPrice": 2.54},
-            self.execution._bet_id,
-        )
-        mock__order_logger.assert_called_with(
-            mock_order, mock_sim_resp, OrderPackageType.CANCEL
-        )
-        mock_order.executable.assert_called_with()
-        mock_replacement_order.executable.assert_not_called()
-        mock_order.trade.__enter__.assert_called_with()
-        mock_order.trade.__exit__.assert_called_with(None, None, None)
+    def test_execute_replace(self):
+        with self.assertRaises(NotImplementedError):
+            self.execution.execute_replace(None, None)
diff --git a/tests/test_simulated.py b/tests/test_simulated.py
index c1a5019..04f5eab 100644
--- a/tests/test_simulated.py
+++ b/tests/test_simulated.py
@@ -158,15 +158,11 @@ class SimulatedTest(unittest.TestCase):
         self.assertEqual(resp.status, "FAILURE")
         self.assertEqual(resp.error_code, "BET_ACTION_ERROR")
 
-    def test_update(self):
-        resp = self.simulated.update({"newPersistenceType": "PERSIST"})
-        self.assertEqual(resp.status, "SUCCESS")
+    # def test_update(self):
+    #     pass
 
-    def test_update_else(self):
-        self.simulated.order.order_type.ORDER_TYPE = OrderTypes.MARKET_ON_CLOSE
-        resp = self.simulated.update({"newPersistenceType": "PERSIST"})
-        self.assertEqual(resp.status, "FAILURE")
-        self.assertEqual(resp.error_code, "BET_ACTION_ERROR")
+    # def test_replace(self):
+    #     pass
 
     def test__get_runner(self):
         mock_market_book = mock.Mock()
diff --git a/tests/test_trade.py b/tests/test_trade.py
index 66c72cc..9226763 100644
--- a/tests/test_trade.py
+++ b/tests/test_trade.py
@@ -1,14 +1,12 @@
-import logging
 import collections
 import unittest
 from unittest import mock
 
-from flumine.order.trade import Trade, OrderError, OrderStatus, TradeStatus
+from flumine.order.trade import Trade, OrderError, TradeStatus
 
 
 class TradeTest(unittest.TestCase):
     def setUp(self) -> None:
-        logging.disable(logging.CRITICAL)
         self.mock_strategy = mock.Mock()
         self.mock_fill_kill = mock.Mock()
         self.mock_offset = mock.Mock()
@@ -55,23 +53,6 @@ class TradeTest(unittest.TestCase):
         )
         runner_context.reset.assert_called_with()
 
-    def test_trade_complete(self):
-        self.assertTrue(self.trade.trade_complete)
-        mock_order = mock.Mock(status=OrderStatus.PENDING)
-        self.trade.orders.append(mock_order)
-        self.assertFalse(self.trade.trade_complete)
-
-    def test_trade_complete_offset(self):
-        self.trade.offset_orders = [1]
-        self.assertFalse(self.trade.trade_complete)
-
-    def test_trade_complete_replace_order(self):
-        self.assertTrue(self.trade.trade_complete)
-        mock_order = mock.Mock(status=OrderStatus.EXECUTION_COMPLETE)
-        self.trade.status = TradeStatus.COMPLETE
-        self.trade.orders.append(mock_order)
-        self.assertFalse(self.trade.trade_complete)
-
     def test_create_order(self):
         mock_order_type = mock.Mock()
         mock_order_type.EXCHANGE = "SYM"
@@ -92,7 +73,8 @@ class TradeTest(unittest.TestCase):
 
     def test_create_order_replacement(self):
         mock_order = mock.Mock()
-        replacement_order = self.trade.create_order_replacement(mock_order, 12)
+        mock_order.update_data = {"new_price": 12}
+        replacement_order = self.trade.create_order_replacement(mock_order)
         self.assertEqual(self.trade.orders, [replacement_order])
 
     def test_create_order_from_current_limit(self):
@@ -132,16 +114,3 @@ class TradeTest(unittest.TestCase):
                 "notes": "123",
             },
         )
-
-    @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)
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 0fae954..ecd6348 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -1,14 +1,10 @@
-import logging
 import unittest
 from unittest import mock
 
-from flumine import utils, FlumineException
+from flumine import utils
 
 
 class UtilsTest(unittest.TestCase):
-    def setUp(self) -> None:
-        logging.disable(logging.CRITICAL)
-
     def test_create_short_uuid(self):
         self.assertTrue(utils.create_short_uuid())
 
@@ -65,18 +61,6 @@ class UtilsTest(unittest.TestCase):
         )
         self.assertIsNone(utils.get_size([], 3))
 
-    def test_get_sp(self):
-        mock_runner = mock.Mock()
-        mock_runner.sp = []
-        self.assertIsNone(utils.get_sp(mock_runner))
-        mock_runner.sp = None
-        self.assertIsNone(utils.get_sp(mock_runner))
-        mock_runner = mock.Mock()
-        mock_runner.sp.actual_sp = "NaN"
-        self.assertIsNone(utils.get_sp(mock_runner))
-        mock_runner.sp.actual_sp = 12.2345
-        self.assertEqual(utils.get_sp(mock_runner), 12.2345)
-
     def test_price_ticks_away(self):
         self.assertEqual(utils.price_ticks_away(1.01, 1), 1.02)
         self.assertEqual(utils.price_ticks_away(1.01, 5), 1.06)
@@ -95,79 +79,19 @@ class UtilsTest(unittest.TestCase):
         self.assertEqual(utils.calculate_exposure([], [(5.6, 2)]), -9.2)
         self.assertEqual(utils.calculate_exposure([], [(5.6, 2), (5.8, 2)]), -18.8)
         self.assertEqual(utils.calculate_exposure([(5.6, 2)], [(5.6, 2)]), 0)
-        self.assertEqual(utils.calculate_exposure([(5.6, 2), (100, 20)], [(5.6, 2)]), 0)
+        self.assertEqual(
+            utils.calculate_exposure([(5.6, 2), (100, 20)], [(5.6, 2)]), -20
+        )
         self.assertEqual(
             utils.calculate_exposure([(5.6, 2), (100, 20)], [(10, 1000)]), -7010.80
         )
         self.assertEqual(utils.calculate_exposure([(10, 2)], [(5, 2)]), 0)
-        self.assertEqual(utils.calculate_exposure([(10, 2)], [(5, 4)]), 0)
+        self.assertEqual(utils.calculate_exposure([(10, 2)], [(5, 4)]), 2)
         self.assertEqual(utils.calculate_exposure([(10, 2)], [(5, 8)]), -14)
 
+        self.assertEqual(utils.calculate_exposure([(5.6, 200)], [(5.6, 100)]), -100)
+
     def test_wap(self):
         self.assertEqual(utils.wap([(1.5, 100), (1.6, 100)]), (200, 1.55))
         self.assertEqual(utils.wap([]), (0, 0))
         self.assertEqual(utils.wap([(1.5, 0)]), (0, 0))
-
-    def test_call_check_market(self):
-        mock_strategy_check = mock.Mock()
-        mock_market = mock.Mock()
-        mock_market_book = mock.Mock()
-        utils.call_check_market(mock_strategy_check, mock_market, mock_market_book)
-        mock_strategy_check.assert_called_with(mock_market, mock_market_book)
-
-    def test_call_check_market_flumine_error(self):
-        mock_strategy_check = mock.Mock(side_effect=FlumineException)
-        mock_market = mock.Mock()
-        mock_market_book = mock.Mock()
-        self.assertFalse(
-            utils.call_check_market(mock_strategy_check, mock_market, mock_market_book)
-        )
-        mock_strategy_check.assert_called_with(mock_market, mock_market_book)
-
-    def test_call_check_market_error(self):
-        mock_strategy_check = mock.Mock(side_effect=ValueError)
-        mock_market = mock.Mock()
-        mock_market_book = mock.Mock()
-        self.assertFalse(
-            utils.call_check_market(mock_strategy_check, mock_market, mock_market_book)
-        )
-        mock_strategy_check.assert_called_with(mock_market, mock_market_book)
-
-    @mock.patch("flumine.utils.config")
-    def test_call_check_market_raise(self, mock_config):
-        mock_config.raise_errors = True
-        mock_strategy_check = mock.Mock(side_effect=ValueError)
-        mock_market = mock.Mock()
-        mock_market_book = mock.Mock()
-        with self.assertRaises(ValueError):
-            utils.call_check_market(mock_strategy_check, mock_market, mock_market_book)
-
-    def test_call_process_market_book(self):
-        mock_strategy = mock.Mock()
-        mock_market = mock.Mock()
-        mock_market_book = mock.Mock()
-        utils.call_process_market_book(mock_strategy, mock_market, mock_market_book)
-        mock_strategy.assert_called_with(mock_market, mock_market_book)
-
-    def test_call_process_market_book_flumine_error(self):
-        mock_strategy = mock.Mock(side_effect=FlumineException)
-        mock_market = mock.Mock()
-        mock_market_book = mock.Mock()
-        utils.call_process_market_book(mock_strategy, mock_market, mock_market_book)
-        mock_strategy.assert_called_with(mock_market, mock_market_book)
-
-    def test_call_process_market_book_error(self):
-        mock_strategy = mock.Mock(side_effect=ZeroDivisionError)
-        mock_market = mock.Mock()
-        mock_market_book = mock.Mock()
-        utils.call_process_market_book(mock_strategy, mock_market, mock_market_book)
-        mock_strategy.assert_called_with(mock_market, mock_market_book)
-
-    @mock.patch("flumine.utils.config")
-    def test_call_process_market_book_raise(self, mock_config):
-        mock_config.raise_errors = True
-        mock_strategy = mock.Mock(side_effect=ZeroDivisionError)
-        mock_market = mock.Mock()
-        mock_market_book = mock.Mock()
-        with self.assertRaises(ZeroDivisionError):
-            utils.call_process_market_book(mock_strategy, mock_market, mock_market_book)
diff --git a/tests/test_worker.py b/tests/test_worker.py
index 1120df8..bab95e7 100644
--- a/tests/test_worker.py
+++ b/tests/test_worker.py
@@ -8,7 +8,7 @@ from flumine import worker
 
 class BackgroundWorkerTest(unittest.TestCase):
     def setUp(self):
-        self.mock_function = mock.Mock(__name__="test")
+        self.mock_function = mock.Mock()
         self.mock_flumine = mock.Mock()
         self.worker = worker.BackgroundWorker(
             self.mock_flumine,
@@ -28,7 +28,6 @@ class BackgroundWorkerTest(unittest.TestCase):
         self.assertEqual(self.worker.func_kwargs, {"hello": "world"})
         self.assertEqual(self.worker.start_delay, 5)
         self.assertEqual(self.worker.context, {1: 2})
-        self.assertEqual(self.worker.name, "test")
 
     # def test_run(self):
     #     self.worker.run()