# Buggy code
def stop_threads(self):
    # Notify stopping
    if self.config[CONFIG_NOTIFICATION_INSTANCE].enabled(
        CONFIG_NOTIFICATION_GLOBAL_INFO
    ):
        # To be improved with a full async implementation
        # To be done : "asyncio.run" --> replaced by a simple await
        # PR discussion : https://github.com/Drakkar-Software/OctoBot/pull/563#discussion_r248088266
        asyncio.run(
            self.config[CONFIG_NOTIFICATION_INSTANCE].notify_with_all(
                NOTIFICATION_STOPPING_MESSAGE
            )
        )

    self.logger.info("Stopping threads ...")

    if self.main_task_group:
        self.main_task_group.cancel()

    for thread in self.dispatchers_list:
        thread.stop()

    # stop services
    for service_instance in ServiceCreator.get_service_instances(self.config):
        try:
            service_instance.stop()
        except Exception as e:
            raise e

    # stop exchanges threads
    for exchange in self.exchanges_list.values():
        exchange.stop()

    self.logger.info("Threads stopped.")


# 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
def stop_threads(self):
    stop_coroutines = []
    # Notify stopping
    if self.config[CONFIG_NOTIFICATION_INSTANCE].enabled(
        CONFIG_NOTIFICATION_GLOBAL_INFO
    ):
        # To be improved with a full async implementation
        # To be done : "asyncio.run" --> replaced by a simple await
        # PR discussion : https://github.com/Drakkar-Software/OctoBot/pull/563#discussion_r248088266
        stop_coroutines.append(
            self.config[CONFIG_NOTIFICATION_INSTANCE].notify_with_all(
                NOTIFICATION_STOPPING_MESSAGE
            )
        )

    self.logger.info("Stopping threads ...")

    if self.main_task_group:
        self.main_task_group.cancel()

    for thread in self.dispatchers_list:
        thread.stop()

    # stop services
    for service_instance in ServiceCreator.get_service_instances(self.config):
        try:
            service_instance.stop()
        except Exception as e:
            raise e

    # stop exchanges threads
    for exchange in self.exchanges_list.values():
        stop_coroutines.append(exchange.stop())

    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    asyncio.run(get_gather_wrapper(stop_coroutines))

    self.logger.info("Threads stopped.")