예제 #1
0
    def test_create_command_restores_config_map_after_config_stop(self):
        base_strategy = "pure_market_making"
        strategy_config = get_strategy_config_map(base_strategy)
        original_exchange = "bybit"
        strategy_config["exchange"].value = original_exchange

        self.cli_mock_assistant.queue_prompt_reply(base_strategy)  # strategy
        self.cli_mock_assistant.queue_prompt_reply("binance")  # spot connector
        self.cli_mock_assistant.queue_prompt_to_stop_config()  # cancel on trading pair prompt

        self.async_run_with_timeout(self.app.prompt_for_configuration(None))
        strategy_config = get_strategy_config_map(base_strategy)

        self.assertEqual(original_exchange, strategy_config["exchange"].value)
예제 #2
0
    def test_strategy_config_template_complete(self):
        folder = realpath(join(__file__, "../../../../../hummingbot/strategy"))
        # Only include valid directories
        strategies = [
            d for d in listdir(folder)
            if isdir(join(folder, d)) and not d.startswith("__")
        ]
        strategies.sort()

        for strategy in strategies:
            strategy_template_path: str = get_strategy_template_path(strategy)
            strategy_config_map = get_strategy_config_map(strategy)

            with open(strategy_template_path, "r") as template_fd:
                template_data = yaml_parser.load(template_fd)
                template_version = template_data.get("template_version", 0)
                self.assertGreaterEqual(
                    template_version, 1,
                    f"Template version too low at {strategy_template_path}")
                for key in template_data:
                    if key == "template_version":
                        continue
                    self.assertTrue(key in strategy_config_map,
                                    f"{key} not in {strategy}_config_map")

                for key in strategy_config_map:
                    self.assertTrue(key in template_data,
                                    f"{key} not in {strategy_template_path}")
예제 #3
0
    def list_configs(
            self,  # type: HummingbotApplication
    ):
        columns: List[str] = ["Key", "Current Value"]

        global_cvs: List[ConfigVar] = list(
            in_memory_config_map.values()) + list(global_config_map.values())
        global_data: List[List[Any]] = [[
            cv.key,
            len(str(cv.value)) * "*" if cv.is_secure else str(cv.value)
        ] for cv in global_cvs]
        global_df: pd.DataFrame = pd.DataFrame(data=global_data,
                                               columns=columns)
        self._notify("\nglobal configs:")
        self._notify(str(global_df))

        strategy = in_memory_config_map.get("strategy").value
        if strategy:
            strategy_cvs: List[ConfigVar] = get_strategy_config_map(
                strategy).values()
            strategy_data: List[List[Any]] = [[
                cv.key,
                len(str(cv.value)) * "*" if cv.is_secure else str(cv.value)
            ] for cv in strategy_cvs]
            strategy_df: pd.DataFrame = pd.DataFrame(data=strategy_data,
                                                     columns=columns)

            self._notify(f"\n{strategy} strategy configs:")
            self._notify(str(strategy_df))

        self._notify("\n")
예제 #4
0
    async def reset_config_loop(self,  # type: HummingbotApplication
                                key: str = None):
        strategy = in_memory_config_map.get("strategy").value
        strategy_cm = get_strategy_config_map(strategy)

        self.placeholder_mode = True
        self.app.toggle_hide_input()

        if self.strategy:
            choice = await self.app.prompt(prompt=f"Would you like to stop running the {strategy} strategy "
                                                  f"and reconfigure the bot? (y/n) >>> ")
        else:
            choice = await self.app.prompt(prompt=f"Would you like to reconfigure the bot? (y/n) >>> ")

        self.app.change_prompt(prompt=">>> ")
        self.app.toggle_hide_input()
        self.placeholder_mode = False

        if choice.lower() in {"y", "yes"}:
            if self.strategy:
                await self.stop_loop()
            if key is None:
                # Clear original strategy config map
                if strategy_cm:
                    for k in strategy_cm:
                        strategy_cm[k].value = None
                in_memory_config_map.get("strategy").value = None
                in_memory_config_map.get("strategy_file_path").value = None
                self.clear_application_warning()
            self.config(key)
        else:
            self._notify("Aborted.")
예제 #5
0
    async def prompt_for_configuration(self,  # type: HummingbotApplication
                                       file_name):
        self.app.clear_input()
        self.placeholder_mode = True
        self.app.hide_input = True
        required_exchanges.clear()

        strategy_config = ConfigVar(key="strategy",
                                    prompt="What is your market making strategy? >>> ",
                                    validator=validate_strategy)
        await self.prompt_a_config(strategy_config)
        if self.app.to_stop_config:
            self.app.to_stop_config = False
            return
        strategy = strategy_config.value
        config_map = get_strategy_config_map(strategy)
        self._notify(f"Please see https://docs.hummingbot.io/strategies/{strategy.replace('_', '-')}/ "
                     f"while setting up these below configuration.")
        # assign default values and reset those not required
        for config in config_map.values():
            if config.required:
                config.value = config.default
            else:
                config.value = None
        for config in config_map.values():
            if config.prompt_on_new and config.required:
                if not self.app.to_stop_config:
                    await self.prompt_a_config(config)
                else:
                    self.app.to_stop_config = False
                    return
            else:
                config.value = config.default

        # catch a last key binding to stop config, if any
        if self.app.to_stop_config:
            self.app.to_stop_config = False
            return

        if file_name is None:
            file_name = await self.prompt_new_file_name(strategy)
            if self.app.to_stop_config:
                self.app.to_stop_config = False
                self.app.set_text("")
                return
        self.app.change_prompt(prompt=">>> ")
        strategy_path = os.path.join(CONF_FILE_PATH, file_name)
        template = get_strategy_template_path(strategy)
        shutil.copy(template, strategy_path)
        save_to_yml(strategy_path, config_map)
        self.strategy_file_name = file_name
        self.strategy_name = strategy
        # Reload completer here otherwise the new file will not appear
        self.app.input_field.completer = load_completer(self)
        self._notify(f"A new config file {self.strategy_file_name} created.")
        self.placeholder_mode = False
        self.app.hide_input = False
        if await self.status_check_all():
            self._notify("\nEnter \"start\" to start market making.")
예제 #6
0
 def get_all_available_config_keys() -> List[str]:
     all_available_config_keys = list(in_memory_config_map.keys()) + list(
         global_config_map.keys())
     current_strategy: str = in_memory_config_map.get("strategy").value
     strategy_cm: Optional[Dict[str, ConfigVar]] = get_strategy_config_map(
         current_strategy)
     if strategy_cm:
         all_available_config_keys += list(strategy_cm.keys())
     return all_available_config_keys
예제 #7
0
 def get_all_available_config_keys() -> List[str]:
     """
     Returns a list of config keys that are currently relevant, including the ones that are not required.
     """
     all_available_config_keys = list(in_memory_config_map.keys()) + list(global_config_map.keys())
     current_strategy: str = in_memory_config_map.get("strategy").value
     strategy_cm: Optional[Dict[str, ConfigVar]] = get_strategy_config_map(current_strategy)
     if strategy_cm:
         all_available_config_keys += list(strategy_cm.keys())
     return all_available_config_keys
예제 #8
0
    def test_create_command_restores_config_map_after_config_stop_on_new_file_prompt(self):
        base_strategy = "pure_market_making"
        strategy_config = get_strategy_config_map(base_strategy)
        original_exchange = "bybit"
        strategy_config["exchange"].value = original_exchange

        self.cli_mock_assistant.queue_prompt_reply(base_strategy)  # strategy
        self.cli_mock_assistant.queue_prompt_reply("binance")  # spot connector
        self.cli_mock_assistant.queue_prompt_reply("BTC-USDT")  # trading pair
        self.cli_mock_assistant.queue_prompt_reply("1")  # bid spread
        self.cli_mock_assistant.queue_prompt_reply("1")  # ask spread
        self.cli_mock_assistant.queue_prompt_reply("30")  # order refresh time
        self.cli_mock_assistant.queue_prompt_reply("1")  # order amount
        self.cli_mock_assistant.queue_prompt_reply("No")  # ping pong feature
        self.cli_mock_assistant.queue_prompt_to_stop_config()  # cancel on new file prompt

        self.async_run_with_timeout(self.app.prompt_for_configuration(None))
        strategy_config = get_strategy_config_map(base_strategy)

        self.assertEqual(original_exchange, strategy_config["exchange"].value)
예제 #9
0
 def _get_config_var_with_key(key: str) -> ConfigVar:
     current_strategy: str = in_memory_config_map.get("strategy").value
     strategy_cm: Optional[Dict[str, ConfigVar]] = get_strategy_config_map(
         current_strategy)
     if key in in_memory_config_map:
         cv: ConfigVar = in_memory_config_map.get(key)
     elif key in global_config_map:
         cv: ConfigVar = global_config_map.get(key)
     elif strategy_cm is not None and key in strategy_cm:
         cv: ConfigVar = strategy_cm.get(key)
     else:
         raise ValueError(
             f"No config variable associated with key name {key}")
     return cv
예제 #10
0
 def _get_config_var_with_key(key: str) -> ConfigVar:
     """
     Check if key exists in `in_memory_config-map`, `global_config_map`, and `strategy_config_map`.
     If so, return the corresponding ConfigVar for that key
     """
     current_strategy: str = in_memory_config_map.get("strategy").value
     strategy_cm: Optional[Dict[str, ConfigVar]] = get_strategy_config_map(current_strategy)
     if key in in_memory_config_map:
         cv: ConfigVar = in_memory_config_map.get(key)
     elif key in global_config_map:
         cv: ConfigVar = global_config_map.get(key)
     elif strategy_cm is not None and key in strategy_cm:
         cv: ConfigVar = strategy_cm.get(key)
     else:
         raise ValueError(f"No config variable associated with key name {key}")
     return cv
예제 #11
0
    async def _inner_config_loop(self, _keys: List[str], single_key: bool):
        keys = self.key_filter(_keys)
        for key in keys:
            current_strategy: str = in_memory_config_map.get("strategy").value
            strategy_cm: Dict[str, ConfigVar] = get_strategy_config_map(current_strategy)
            if key in in_memory_config_map:
                cv: ConfigVar = in_memory_config_map.get(key)
            elif key in global_config_map:
                cv: ConfigVar = global_config_map.get(key)
            else:
                cv: ConfigVar = strategy_cm.get(key)

            value = await self.config_single_variable(cv, is_single_key=single_key)
            cv.value = parse_cvar_value(cv, value)
            if single_key:
                self._notify(f"\nNew config saved:\n{key}: {str(value)}")
        if not self.config_complete:
            await self._inner_config_loop(self._get_empty_configs(), single_key)
예제 #12
0
        async def inner_loop(_keys: List[str]):
            for key in _keys:
                current_strategy: str = in_memory_config_map.get(
                    "strategy").value
                strategy_cm: Dict[str, ConfigVar] = get_strategy_config_map(
                    current_strategy)
                if key in in_memory_config_map:
                    cv: ConfigVar = in_memory_config_map.get(key)
                elif key in global_config_map:
                    cv: ConfigVar = global_config_map.get(key)
                else:
                    cv: ConfigVar = strategy_cm.get(key)

                value = await single_prompt(cv)
                cv.value = parse_cvar_value(cv, value)
                if single_key:
                    self.app.log(f"\nNew config saved:\n{key}: {str(value)}")
            if not self.config_complete:
                await inner_loop(self._get_empty_configs())
예제 #13
0
    async def prompt_for_configuration(
        self,  # type: HummingbotApplication
        file_name,
    ):
        self.app.clear_input()
        self.placeholder_mode = True
        self.app.hide_input = True
        required_exchanges.clear()

        strategy = await self.get_strategy_name()

        if self.app.to_stop_config:
            return

        config_map = get_strategy_config_map(strategy)
        self.notify(f"Please see https://docs.hummingbot.io/strategies/{strategy.replace('_', '-')}/ "
                    f"while setting up these below configuration.")

        if isinstance(config_map, ClientConfigAdapter):
            await self.prompt_for_model_config(config_map)
            if not self.app.to_stop_config:
                file_name = await self.save_config_to_file(file_name, config_map)
        elif config_map is not None:
            file_name = await self.prompt_for_configuration_legacy(file_name, strategy, config_map)
        else:
            self.app.to_stop_config = True

        if self.app.to_stop_config:
            return

        save_previous_strategy_value(file_name, self.client_config_map)
        self.strategy_file_name = file_name
        self.strategy_name = strategy
        self.strategy_config_map = config_map
        # Reload completer here otherwise the new file will not appear
        self.app.input_field.completer = load_completer(self)
        self.notify(f"A new config file has been created: {self.strategy_file_name}")
        self.placeholder_mode = False
        self.app.hide_input = False

        await self.verify_status()
예제 #14
0
 def strategy_config_map(self):
     if self.strategy_name is not None:
         return get_strategy_config_map(self.strategy_name)
     return None
예제 #15
0
 def test_get_strategy_config_map(self):
     cm = get_strategy_config_map(strategy="avellaneda_market_making")
     self.assertIsInstance(cm.hb_config, AvellanedaMarketMakingConfigMap)
     self.assertFalse(hasattr(cm, "market"))  # uninitialized instance
예제 #16
0
 def missing_configurations(self) -> List[str]:
     missing_globals = missing_required_configs(global_config_map)
     missing_configs = missing_required_configs(get_strategy_config_map(self.strategy_name))
     return missing_globals + missing_configs
예제 #17
0
    async def start_market_making(self, strategy_name: str):
        strategy_cm = get_strategy_config_map(strategy_name)
        if strategy_name == "cross_exchange_market_making":
            maker_market = strategy_cm.get("maker_market").value.lower()
            taker_market = strategy_cm.get("taker_market").value.lower()
            raw_maker_symbol = strategy_cm.get(
                "maker_market_symbol").value.upper()
            raw_taker_symbol = strategy_cm.get(
                "taker_market_symbol").value.upper()
            min_profitability = strategy_cm.get("min_profitability").value
            trade_size_override = strategy_cm.get("trade_size_override").value
            strategy_report_interval = global_config_map.get(
                "strategy_report_interval").value
            limit_order_min_expiration = strategy_cm.get(
                "limit_order_min_expiration").value
            cancel_order_threshold = strategy_cm.get(
                "cancel_order_threshold").value
            active_order_canceling = strategy_cm.get(
                "active_order_canceling").value
            top_depth_tolerance_rules = [(re.compile(re_str), value)
                                         for re_str, value in strategy_cm.get(
                                             "top_depth_tolerance").value]
            top_depth_tolerance = 0.0

            for regex, tolerance_value in top_depth_tolerance_rules:
                if regex.match(raw_maker_symbol) is not None:
                    top_depth_tolerance = tolerance_value

            try:
                maker_assets: Tuple[str, str] = SymbolSplitter.split(
                    maker_market, raw_maker_symbol)
                taker_assets: Tuple[str, str] = SymbolSplitter.split(
                    taker_market, raw_taker_symbol)
            except ValueError as e:
                self.app.log(str(e))
                return

            market_names: List[Tuple[str, List[str]]] = [
                (maker_market, [raw_maker_symbol]),
                (taker_market, [raw_taker_symbol])
            ]
            self._initialize_wallet(
                token_symbols=list(set(maker_assets + taker_assets)))
            self._initialize_markets(market_names)
            self.assets = set(maker_assets + taker_assets)

            self.market_pair = CrossExchangeMarketPair(
                *([self.markets[maker_market], raw_maker_symbol] +
                  list(maker_assets) +
                  [self.markets[taker_market], raw_taker_symbol] +
                  list(taker_assets) + [top_depth_tolerance]))

            strategy_logging_options = (
                CrossExchangeMarketMakingStrategy.OPTION_LOG_CREATE_ORDER
                | CrossExchangeMarketMakingStrategy.OPTION_LOG_ADJUST_ORDER |
                CrossExchangeMarketMakingStrategy.OPTION_LOG_MAKER_ORDER_FILLED
                | CrossExchangeMarketMakingStrategy.OPTION_LOG_REMOVING_ORDER
                | CrossExchangeMarketMakingStrategy.OPTION_LOG_STATUS_REPORT |
                CrossExchangeMarketMakingStrategy.OPTION_LOG_MAKER_ORDER_HEDGED
            )

            self.strategy = CrossExchangeMarketMakingStrategy(
                market_pairs=[self.market_pair],
                min_profitability=min_profitability,
                status_report_interval=strategy_report_interval,
                logging_options=strategy_logging_options,
                trade_size_override=trade_size_override,
                limit_order_min_expiration=limit_order_min_expiration,
                cancel_order_threshold=cancel_order_threshold,
                active_order_canceling=active_order_canceling)

        elif strategy_name == "arbitrage":
            primary_market = strategy_cm.get("primary_market").value.lower()
            secondary_market = strategy_cm.get(
                "secondary_market").value.lower()
            raw_primary_symbol = strategy_cm.get(
                "primary_market_symbol").value.upper()
            raw_secondary_symbol = strategy_cm.get(
                "secondary_market_symbol").value.upper()
            min_profitability = strategy_cm.get("min_profitability").value
            try:
                primary_assets: Tuple[str, str] = SymbolSplitter.split(
                    primary_market, raw_primary_symbol)
                secondary_assets: Tuple[str, str] = SymbolSplitter.split(
                    secondary_market, raw_secondary_symbol)

            except ValueError as e:
                self.app.log(str(e))
                return

            market_names: List[Tuple[str, List[str]]] = [
                (primary_market, [raw_primary_symbol]),
                (secondary_market, [raw_secondary_symbol])
            ]
            self._initialize_wallet(
                token_symbols=list(set(primary_assets + secondary_assets)))
            self._initialize_markets(market_names)
            self.assets = set(primary_assets + secondary_assets)

            self.market_pair = ArbitrageMarketPair(
                *([self.markets[primary_market], raw_primary_symbol] +
                  list(primary_assets) +
                  [self.markets[secondary_market], raw_secondary_symbol] +
                  list(secondary_assets)))

            strategy_logging_options = ArbitrageStrategy.OPTION_LOG_ALL

            self.strategy = ArbitrageStrategy(
                market_pairs=[self.market_pair],
                min_profitability=min_profitability,
                logging_options=strategy_logging_options)

        elif strategy_name == "pure_market_making":
            order_size = strategy_cm.get("order_amount").value
            cancel_order_wait_time = strategy_cm.get(
                "cancel_order_wait_time").value
            bid_place_threshold = strategy_cm.get("bid_place_threshold").value
            ask_place_threshold = strategy_cm.get("ask_place_threshold").value
            maker_market = strategy_cm.get("maker_market").value.lower()
            raw_maker_symbol = strategy_cm.get(
                "maker_market_symbol").value.upper()
            try:
                primary_assets: Tuple[str, str] = SymbolSplitter.split(
                    maker_market, raw_maker_symbol)

            except ValueError as e:
                self.app.log(str(e))
                return

            market_names: List[Tuple[str, List[str]]] = [(maker_market,
                                                          [raw_maker_symbol])]

            self._initialize_wallet(token_symbols=list(set(primary_assets)))
            self._initialize_markets(market_names)
            self.assets = set(primary_assets)

            self.market_pair = PureMarketPair(
                *([self.markets[maker_market], raw_maker_symbol] +
                  list(primary_assets)))
            strategy_logging_options = PureMarketMakingStrategy.OPTION_LOG_ALL

            self.strategy = PureMarketMakingStrategy(
                market_pairs=[self.market_pair],
                order_size=order_size,
                bid_place_threshold=bid_place_threshold,
                ask_place_threshold=ask_place_threshold,
                cancel_order_wait_time=cancel_order_wait_time,
                logging_options=strategy_logging_options)

        elif strategy_name == "discovery":
            try:
                market_1 = strategy_cm.get("primary_market").value.lower()
                market_2 = strategy_cm.get("secondary_market").value.lower()
                target_symbol_1 = list(
                    strategy_cm.get("target_symbol_1").value)
                target_symbol_2 = list(
                    strategy_cm.get("target_symbol_2").value)
                target_profitability = float(
                    strategy_cm.get("target_profitability").value)
                target_amount = float(strategy_cm.get("target_amount").value)
                equivalent_token: List[List[str]] = list(
                    strategy_cm.get("equivalent_tokens").value)

                if not target_symbol_2:
                    target_symbol_2 = SymbolFetcher.get_instance().symbols.get(
                        market_2, [])
                if not target_symbol_1:
                    target_symbol_1 = SymbolFetcher.get_instance().symbols.get(
                        market_1, [])

                market_names: List[Tuple[str, List[str]]] = [
                    (market_1, target_symbol_1), (market_2, target_symbol_2)
                ]

                target_base_quote_1: List[Tuple[str, str]] = [
                    SymbolSplitter.split(market_1, symbol)
                    for symbol in target_symbol_1
                ]
                target_base_quote_2: List[Tuple[str, str]] = [
                    SymbolSplitter.split(market_2, symbol)
                    for symbol in target_symbol_2
                ]

                self._trading_required = False
                self._initialize_wallet(
                    token_symbols=[]
                )  # wallet required only for dex hard dependency
                self._initialize_markets(market_names)
                self.market_pair = DiscoveryMarketPair(*([
                    self.markets[market_1],
                    self.markets[market_1].get_active_exchange_markets
                ] + [
                    self.markets[market_2],
                    self.markets[market_2].get_active_exchange_markets
                ]))
                self.strategy = DiscoveryStrategy(
                    market_pairs=[self.market_pair],
                    target_symbols=target_base_quote_1 + target_base_quote_2,
                    equivalent_token=equivalent_token,
                    target_profitability=target_profitability,
                    target_amount=target_amount)
            except Exception as e:
                self.app.log(str(e))
                self.logger().error("Error initializing strategy.",
                                    exc_info=True)
        else:
            raise NotImplementedError

        try:
            self.clock = Clock(ClockMode.REALTIME)
            if self.wallet is not None:
                self.clock.add_iterator(self.wallet)
            for market in self.markets.values():
                if market is not None:
                    self.clock.add_iterator(market)
            if self.strategy:
                self.clock.add_iterator(self.strategy)
            self.strategy_task: asyncio.Task = asyncio.ensure_future(
                self._run_clock())
            self.app.log(
                f"\n  '{strategy_name}' strategy started.\n"
                f"  You can use the `status` command to query the progress.")

            self.starting_balances = await self.wait_till_ready(
                self.balance_snapshot)
            self.stop_loss_tracker = StopLossTracker(
                self.data_feed, list(self.assets), list(self.markets.values()),
                lambda *args, **kwargs: asyncio.ensure_future(
                    self.stop(*args, **kwargs)))
            await self.wait_till_ready(self.stop_loss_tracker.start)
        except Exception as e:
            self.logger().error(str(e), exc_info=True)
예제 #18
0
    def list(self, obj: str):
        if obj == "wallets":
            wallets = list_wallets()
            if len(wallets) == 0:
                self.app.log(
                    'Wallet not available. Please configure your wallet (Enter "config wallet")'
                )
            else:
                self.app.log('\n'.join(wallets))

        elif obj == "exchanges":
            if len(EXCHANGES) == 0:
                self.app.log("No exchanges available")
            else:
                self.app.log('\n'.join(EXCHANGES))

        elif obj == "configs":
            columns: List[str] = ["Key", "Current Value"]

            global_cvs: List[ConfigVar] = list(
                in_memory_config_map.values()) + list(
                    global_config_map.values())
            global_data: List[List[str, Any]] = [[
                cv.key,
                len(str(cv.value)) * "*" if cv.is_secure else str(cv.value)
            ] for cv in global_cvs]
            global_df: pd.DataFrame = pd.DataFrame(data=global_data,
                                                   columns=columns)
            self.app.log("\nglobal configs:")
            self.app.log(str(global_df))

            strategy = in_memory_config_map.get("strategy").value
            if strategy:
                strategy_cvs: List[ConfigVar] = get_strategy_config_map(
                    strategy).values()
                strategy_data: List[List[str, Any]] = [[
                    cv.key,
                    len(str(cv.value)) * "*" if cv.is_secure else str(cv.value)
                ] for cv in strategy_cvs]
                strategy_df: pd.DataFrame = pd.DataFrame(data=strategy_data,
                                                         columns=columns)

                self.app.log(f"\n{strategy} strategy configs:")
                self.app.log(str(strategy_df))

            self.app.log("\n")

        elif obj == "trades":
            lines = []
            if self.strategy is None:
                self.app.log("No strategy available, cannot show past trades.")
            else:
                if len(self.strategy.trades) > 0:
                    df = Trade.to_pandas(self.strategy.trades)
                    df_lines = str(df).split("\n")
                    lines.extend(["", "  Past trades:"] +
                                 ["    " + line for line in df_lines])
                else:
                    lines.extend(["  No past trades."])
            self.app.log("\n".join(lines))
        else:
            self.help("list")
예제 #19
0
    async def prompt_for_configuration(
            self,  # type: HummingbotApplication
            file_name):
        self.app.clear_input()
        self.placeholder_mode = True
        self.app.hide_input = True
        required_exchanges.clear()

        strategy_config = ConfigVar(
            key="strategy",
            prompt="What is your market making strategy? >>> ",
            validator=validate_strategy)
        await self.prompt_a_config(strategy_config)
        if self.app.to_stop_config:
            self.stop_config()
            return
        strategy = strategy_config.value
        config_map = get_strategy_config_map(strategy)
        config_map_backup = copy.deepcopy(config_map)
        self._notify(
            f"Please see https://docs.hummingbot.io/strategies/{strategy.replace('_', '-')}/ "
            f"while setting up these below configuration.")
        # assign default values and reset those not required
        for config in config_map.values():
            if config.required:
                config.value = config.default
            else:
                config.value = None
        for config in config_map.values():
            if config.prompt_on_new and config.required:
                if not self.app.to_stop_config:
                    await self.prompt_a_config(config)
                else:
                    break
            else:
                config.value = config.default

        if self.app.to_stop_config:
            self.stop_config(config_map, config_map_backup)
            return

        if file_name is None:
            file_name = await self.prompt_new_file_name(strategy)
            if self.app.to_stop_config:
                self.stop_config(config_map, config_map_backup)
                self.app.set_text("")
                return
        self.app.change_prompt(prompt=">>> ")
        strategy_path = os.path.join(CONF_FILE_PATH, file_name)
        template = get_strategy_template_path(strategy)
        shutil.copy(template, strategy_path)
        save_to_yml(strategy_path, config_map)
        self.strategy_file_name = file_name
        self.strategy_name = strategy
        # Reload completer here otherwise the new file will not appear
        self.app.input_field.completer = load_completer(self)
        self._notify(f"A new config file {self.strategy_file_name} created.")
        self.placeholder_mode = False
        self.app.hide_input = False
        try:
            timeout = float(global_config_map["create_command_timeout"].value)
            all_status_go = await asyncio.wait_for(self.status_check_all(),
                                                   timeout)
        except asyncio.TimeoutError:
            self._notify(
                "\nA network error prevented the connection check to complete. See logs for more details."
            )
            self.strategy_file_name = None
            self.strategy_name = None
            raise
        if all_status_go:
            self._notify("\nEnter \"start\" to start market making.")