# Buggy code
async def start_update_loop(self):
    error = None
    try:
        time_frames = self.evaluator_task_manager_by_time_frame_by_symbol.keys()

        # sort time frames to update them in order of accuracy
        time_frames = TimeFrameManager.sort_time_frames(time_frames)

        if time_frames and self.symbols:
            self.in_backtesting = self._init_backtesting_if_necessary(time_frames)

            # init refreshed_times at 0 for each time frame
            self.refreshed_times = {
                key: {symbol: 0 for symbol in self.symbols} for key in time_frames
            }

            # init last refresh times at 0 for each time frame
            self.time_frame_last_update = {
                key: {symbol: 0 for symbol in self.symbols} for key in time_frames
            }

            while self.keep_running:
                try:
                    await self._trigger_update(time_frames)
                except Exception as e:
                    self.logger.error(f"exception when triggering update: {e}")
                    self.logger.exception(e)
        else:
            self.logger.warning("no time frames to monitor, going to sleep.")

    except Exception as e:
        self.logger.exception(e)
        if self.watcher is not None:
            error = e

    finally:
        if (
            self.in_backtesting
            and self.symbols is not None
            and not self.exchange.get_exchange()
            .get_backtesting()
            .get_is_finished(self.symbols)
        ):
            if error is None:
                error = "backtesting did not finish properly."
            if self.watcher is not None:
                self.watcher.set_error(error)
            self.logger.error(error)


# Traceback (concurrent.futures._base.CancelledError)
Traceback (most recent call last):
File "/home/herklos/dev/Drakkars/OctoBot/evaluator/Updaters/global_price_updater.py", line 163, in _refresh_time_frame_data
await self._refresh_data(time_frame, symbol, notify=notify)
File "/home/herklos/dev/Drakkars/OctoBot/evaluator/Updaters/global_price_updater.py", line 177, in _refresh_data
return_list=False))
File "/home/herklos/dev/Drakkars/OctoBot/trading/exchanges/exchange_dispatcher.py", line 89, in get_symbol_prices
await self.exchange.get_symbol_prices(symbol=symbol, time_frame=time_frame, limit=limit)
File "/home/herklos/dev/Drakkars/OctoBot/trading/exchanges/rest_exchanges/rest_exchange.py", line 126, in get_symbol_prices
candles = await self.client.fetch_ohlcv(symbol, time_frame.value)
File "/home/herklos/.local/lib/python3.7/site-packages/ccxt/async_support/binance.py", line 503, in fetch_ohlcv
response = await self.publicGetKlines(self.extend(request, params))
File "/home/herklos/.local/lib/python3.7/site-packages/ccxt/async_support/binance.py", line 1114, in request
response = await self.fetch2(path, api, method, params, headers, body)
File "/home/herklos/.local/lib/python3.7/site-packages/ccxt/async_support/base/exchange.py", line 113, in fetch2
await self.throttle()
concurrent.futures._base.CancelledError
2019-01-19 19:05:51,432 ERROR    GlobalPriceUpdater    when refreshing data for time frame TimeFrames.FOUR_HOURS:
2019-01-19 19:05:51,432 ERROR    GlobalPriceUpdater
Traceback (most recent call last):
File "/usr/lib/python3.7/asyncio/runners.py", line 43, in run
return loop.run_until_complete(main)
File "/usr/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
return future.result()
concurrent.futures._base.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/herklos/dev/Drakkars/OctoBot/evaluator/Updaters/global_price_updater.py", line 163, in _refresh_time_frame_data
await self._refresh_data(time_frame, symbol, notify=notify)
File "/home/herklos/dev/Drakkars/OctoBot/evaluator/Updaters/global_price_updater.py", line 177, in _refresh_data
return_list=False))
File "/home/herklos/dev/Drakkars/OctoBot/trading/exchanges/exchange_dispatcher.py", line 89, in get_symbol_prices
await self.exchange.get_symbol_prices(symbol=symbol, time_frame=time_frame, limit=limit)
File "/home/herklos/dev/Drakkars/OctoBot/trading/exchanges/rest_exchanges/rest_exchange.py", line 126, in get_symbol_prices
candles = await self.client.fetch_ohlcv(symbol, time_frame.value)
File "/home/herklos/.local/lib/python3.7/site-packages/ccxt/async_support/binance.py", line 503, in fetch_ohlcv
response = await self.publicGetKlines(self.extend(request, params))
File "/home/herklos/.local/lib/python3.7/site-packages/ccxt/async_support/binance.py", line 1114, in request
response = await self.fetch2(path, api, method, params, headers, body)
File "/home/herklos/.local/lib/python3.7/site-packages/ccxt/async_support/base/exchange.py", line 113, in fetch2
await self.throttle()
concurrent.futures._base.CancelledError

# Fixed code
async def start_update_loop(self):
    error = None
    try:
        time_frames = self.evaluator_task_manager_by_time_frame_by_symbol.keys()

        # sort time frames to update them in order of accuracy
        time_frames = TimeFrameManager.sort_time_frames(time_frames)

        if time_frames and self.symbols:
            self.in_backtesting = self._init_backtesting_if_necessary(time_frames)

            # init refreshed_times at 0 for each time frame
            self.refreshed_times = {
                key: {symbol: 0 for symbol in self.symbols} for key in time_frames
            }

            # init last refresh times at 0 for each time frame
            self.time_frame_last_update = {
                key: {symbol: 0 for symbol in self.symbols} for key in time_frames
            }

            while self.keep_running:
                try:
                    await self._trigger_update(time_frames)
                except CancelledError:
                    self.logger.info("Update tasks cancelled.")
                except Exception as e:
                    self.logger.error(f"exception when triggering update: {e}")
                    self.logger.exception(e)
        else:
            self.logger.warning("no time frames to monitor, going to sleep.")

    except Exception as e:
        self.logger.exception(e)
        if self.watcher is not None:
            error = e

    finally:
        if (
            self.in_backtesting
            and self.symbols is not None
            and not self.exchange.get_exchange()
            .get_backtesting()
            .get_is_finished(self.symbols)
        ):
            if error is None:
                error = "backtesting did not finish properly."
            if self.watcher is not None:
                self.watcher.set_error(error)
            self.logger.error(error)