async def show_balances(self):
        total_col_name = f'Total ({RateOracle.global_token_symbol})'
        self._notify("Updating balances, please wait...")
        network_timeout = float(global_config_map["other_commands_timeout"].value)
        try:
            all_ex_bals = await asyncio.wait_for(
                UserBalances.instance().all_balances_all_exchanges(), network_timeout
            )
        except asyncio.TimeoutError:
            self._notify("\nA network error prevented the balances to update. See logs for more details.")
            raise
        all_ex_avai_bals = UserBalances.instance().all_avai_balances_all_exchanges()
        all_ex_limits: Optional[Dict[str, Dict[str, str]]] = global_config_map["balance_asset_limit"].value

        if all_ex_limits is None:
            all_ex_limits = {}

        exchanges_total = 0

        for exchange, bals in all_ex_bals.items():
            self._notify(f"\n{exchange}:")
            df, allocated_total = await self.exchange_balances_extra_df(bals, all_ex_avai_bals.get(exchange, {}))
            if df.empty:
                self._notify("You have no balance on this exchange.")
            else:
                lines = ["    " + line for line in df.to_string(index=False).split("\n")]
                self._notify("\n".join(lines))
                self._notify(f"\n  Total: {RateOracle.global_token_symbol} {PerformanceMetrics.smart_round(df[total_col_name].sum())}    "
                             f"Allocated: {allocated_total / df[total_col_name].sum():.2%}")
                exchanges_total += df[total_col_name].sum()

        self._notify(f"\n\nExchanges Total: {RateOracle.global_token_symbol} {exchanges_total:.0f}    ")

        celo_address = global_config_map["celo_address"].value
        if celo_address is not None:
            try:
                if not CeloCLI.unlocked:
                    await self.validate_n_connect_celo()
                df = await self.celo_balances_df()
                lines = ["    " + line for line in df.to_string(index=False).split("\n")]
                self._notify("\ncelo:")
                self._notify("\n".join(lines))
            except Exception as e:
                self._notify(f"\ncelo CLI Error: {str(e)}")

        eth_address = global_config_map["ethereum_wallet"].value
        if eth_address is not None:
            eth_df = await self.ethereum_balances_df()
            lines = ["    " + line for line in eth_df.to_string(index=False).split("\n")]
            self._notify("\nethereum:")
            self._notify("\n".join(lines))

            # XDAI balances
            xdai_df = await self.xdai_balances_df()
            lines = ["    " + line for line in xdai_df.to_string(index=False).split("\n")]
            self._notify("\nxdai:")
            self._notify("\n".join(lines))
Example #2
0
 async def connection_df(self  # type: HummingbotApplication
                         ):
     columns = [
         "Exchange", "  Keys Added", "  Keys Confirmed",
         "  Connector Status"
     ]
     data = []
     failed_msgs = {}
     network_timeout = float(
         global_config_map["other_commands_timeout"].value)
     try:
         err_msgs = await asyncio.wait_for(
             UserBalances.instance().update_exchanges(reconnect=True),
             network_timeout)
     except asyncio.TimeoutError:
         self._notify(
             "\nA network error prevented the connection table to populate. See logs for more details."
         )
         raise
     for option in sorted(OPTIONS):
         keys_added = "No"
         keys_confirmed = 'No'
         status = get_connector_status(option)
         if option == "ethereum":
             eth_address = global_config_map["ethereum_wallet"].value
             if eth_address is not None and eth_address in Security.private_keys(
             ):
                 keys_added = "Yes"
                 err_msg = UserBalances.validate_ethereum_wallet()
                 if err_msg is not None:
                     failed_msgs[option] = err_msg
                 else:
                     keys_confirmed = 'Yes'
         elif option == "celo":
             celo_address = global_config_map["celo_address"].value
             if celo_address is not None and Security.encrypted_file_exists(
                     "celo_password"):
                 keys_added = "Yes"
                 err_msg = await self.validate_n_connect_celo(True)
                 if err_msg is not None:
                     failed_msgs[option] = err_msg
                 else:
                     keys_confirmed = 'Yes'
         else:
             api_keys = (await Security.api_keys(option)).values()
             if len(api_keys) > 0:
                 keys_added = "Yes"
                 err_msg = err_msgs.get(option)
                 if err_msg is not None:
                     failed_msgs[option] = err_msg
                 else:
                     keys_confirmed = 'Yes'
         data.append([option, keys_added, keys_confirmed, status])
     return pd.DataFrame(data=data, columns=columns), failed_msgs
Example #3
0
 async def asset_ratio_maintenance_prompt(
         self,  # type: HummingbotApplication
         config_map):
     exchange = config_map['exchange'].value
     market = config_map["market"].value
     base, quote = market.split("-")
     balances = await UserBalances.instance().balances(
         exchange, base, quote)
     if balances is None:
         return
     base_ratio = UserBalances.base_amount_ratio(market, balances)
     base_ratio = round(base_ratio, 3)
     quote_ratio = 1 - base_ratio
     base, quote = config_map["market"].value.split("-")
     cvar = ConfigVar(
         key="temp_config",
         prompt=
         f"On {exchange}, you have {balances.get(base, 0):.4f} {base} and "
         f"{balances.get(quote, 0):.4f} {quote}. By market value, "
         f"your current inventory split is {base_ratio:.1%} {base} "
         f"and {quote_ratio:.1%} {quote}."
         f" Would you like to keep this ratio? (Yes/No) >>> ",
         required_if=lambda: True,
         type_str="bool",
         validator=validate_bool)
     await self.prompt_a_config(cvar)
     if cvar.value:
         config_map['inventory_target_base_pct'].value = round(
             base_ratio * Decimal('100'), 1)
     else:
         await self.prompt_a_config(config_map["inventory_target_base_pct"])
     config_map['inventory_skew_enabled'].value = True
Example #4
0
 async def connection_df(self  # type: HummingbotApplication
                         ):
     columns = ["Exchange", "  Keys Added", "  Keys Confirmed"]
     data = []
     failed_msgs = {}
     err_msgs = await UserBalances.instance().update_exchanges(
         reconnect=True)
     for option in sorted(OPTIONS):
         keys_added = "No"
         keys_confirmed = 'No'
         if option == "ethereum":
             eth_address = global_config_map["ethereum_wallet"].value
             if eth_address is not None and eth_address in Security.private_keys(
             ):
                 keys_added = "Yes"
                 err_msg = UserBalances.validate_ethereum_wallet()
                 if err_msg is not None:
                     failed_msgs[option] = err_msg
                 else:
                     keys_confirmed = 'Yes'
         else:
             api_keys = (await Security.api_keys(option)).values()
             if len(api_keys) > 0:
                 keys_added = "Yes"
                 err_msg = err_msgs.get(option)
                 if err_msg is not None:
                     failed_msgs[option] = err_msg
                 else:
                     keys_confirmed = 'Yes'
         data.append([option, keys_added, keys_confirmed])
     return pd.DataFrame(data=data, columns=columns), failed_msgs
 async def get_current_balances(
         self,  # type: HummingbotApplication
         market: str):
     if market in self.markets and self.markets[market].ready:
         return self.markets[market].get_all_balances()
     elif "Paper" in market:
         paper_balances = global_config_map[
             "paper_trade_account_balance"].value
         if paper_balances is None:
             return {}
         return {
             token: Decimal(str(bal))
             for token, bal in paper_balances.items()
         }
     elif "perpetual_finance" == market:
         return await UserBalances.xdai_balances()
     else:
         gateway_eth_connectors = [
             cs.name for cs in CONNECTOR_SETTINGS.values() if
             cs.use_ethereum_wallet and cs.type == ConnectorType.Connector
         ]
         if market in gateway_eth_connectors:
             return await UserBalances.instance().eth_n_erc20_balances()
         else:
             await UserBalances.instance().update_exchange_balance(market)
             return UserBalances.instance().all_balances(market)
Example #6
0
 async def connect_ethereum(self,  # type: HummingbotApplication
                            ):
     self.placeholder_mode = True
     self.app.hide_input = True
     ether_wallet = global_config_map["ethereum_wallet"].value
     to_connect = True
     if ether_wallet is not None:
         answer = await self.app.prompt(prompt=f"Would you like to replace your existing Ethereum wallet "
                                               f"{ether_wallet} (Yes/No)? >>> ")
         if self.app.to_stop_config:
             self.app.to_stop_config = False
             return
         if answer.lower() not in ("yes", "y"):
             to_connect = False
     if to_connect:
         private_key = await self.app.prompt(prompt="Enter your wallet private key >>> ", is_password=True)
         public_address = Security.add_private_key(private_key)
         global_config_map["ethereum_wallet"].value = public_address
         if global_config_map["ethereum_rpc_url"].value is None:
             await self.prompt_a_config(global_config_map["ethereum_rpc_url"])
         if global_config_map["ethereum_rpc_ws_url"].value is None:
             await self.prompt_a_config(global_config_map["ethereum_rpc_ws_url"])
         if self.app.to_stop_config:
             self.app.to_stop_config = False
             return
         save_to_yml(GLOBAL_CONFIG_PATH, global_config_map)
         err_msg = UserBalances.validate_ethereum_wallet()
         if err_msg is None:
             self._notify(f"Wallet {public_address} connected to hummingbot.")
         else:
             self._notify(f"\nError: {err_msg}")
     self.placeholder_mode = False
     self.app.hide_input = False
     self.app.change_prompt(prompt=">>> ")
Example #7
0
 async def show_balances(self):
     self._notify("Updating balances, please wait...")
     df = await self.balances_df()
     lines = [
         "    " + line for line in df.to_string(index=False).split("\n")
     ]
     self._notify("\n".join(lines))
     eth_address = global_config_map["ethereum_wallet"].value
     if eth_address is not None:
         bal = UserBalances.ethereum_balance()
         bal = round(bal, 4)
         self._notify(
             f"Ethereum balance in ...{eth_address[-4:]} wallet: {bal} ETH")
         self._notify(
             f"Note: You may have other ERC 20 tokens in this same address (not shown here)."
         )
     celo_address = global_config_map["celo_address"].value
     if celo_address is not None:
         try:
             if not CeloCLI.unlocked:
                 await self.validate_n_connect_celo()
             bals = CeloCLI.balances()
             self._notify("Celo balances:")
             for token, bal in bals.items():
                 self._notify(
                     f"  {token} - total: {bal.total} locked: {bal.locked}")
         except Exception as e:
             self._notify(f"Celo CLI Error: {str(e)}")
Example #8
0
 async def get_binance_connector(self):
     if self._binance_connector is not None:
         return self._binance_connector
     api_keys = await Security.api_keys("binance")
     if not api_keys:
         return None
     self._binance_connector = UserBalances.connect_market("binance", **api_keys)
     return self._binance_connector
Example #9
0
 async def ethereum_balances_df(
         self,  # type: HummingbotApplication
 ):
     rows = []
     bal = UserBalances.ethereum_balance()
     rows.append({"asset": "ETH", "amount": round(bal, 4)})
     df = pd.DataFrame(data=rows, columns=["asset", "amount"])
     df.sort_values(by=["asset"], inplace=True)
     return df
Example #10
0
    async def show_balances(self):
        self._notify("Updating balances, please wait...")
        all_ex_bals = await UserBalances.instance().all_balances_all_exchanges(
        )
        all_ex_avai_bals = UserBalances.instance(
        ).all_avai_balances_all_exchanges()
        all_ex_limits: Optional[Dict[str, Dict[
            str, str]]] = global_config_map["balance_asset_limit"].value

        if all_ex_limits is None:
            all_ex_limits = {}

        for exchange, bals in all_ex_bals.items():
            self._notify(f"\n{exchange}:")
            # df = await self.exchange_balances_df(bals, all_ex_limits.get(exchange, {}))
            df, allocated_total = await self.exchange_balances_usd_df(
                bals, all_ex_avai_bals.get(exchange, {}))
            if df.empty:
                self._notify("You have no balance on this exchange.")
            else:
                lines = [
                    "    " + line
                    for line in df.to_string(index=False).split("\n")
                ]
                self._notify("\n".join(lines))
                self._notify(
                    f"\n  Total: $ {df['Total ($)'].sum():.0f}    "
                    f"Allocated: {allocated_total / df['Total ($)'].sum():.2%}"
                )

        celo_address = global_config_map["celo_address"].value
        if celo_address is not None:
            try:
                if not CeloCLI.unlocked:
                    await self.validate_n_connect_celo()
                df = await self.celo_balances_df()
                lines = [
                    "    " + line
                    for line in df.to_string(index=False).split("\n")
                ]
                self._notify("\ncelo:")
                self._notify("\n".join(lines))
            except Exception as e:
                self._notify(f"\ncelo CLI Error: {str(e)}")

        eth_address = global_config_map["ethereum_wallet"].value
        if eth_address is not None:
            df = await self.ethereum_balances_df()
            lines = [
                "    " + line for line in df.to_string(index=False).split("\n")
            ]
            self._notify("\nethereum:")
            self._notify("\n".join(lines))
Example #11
0
 async def get_current_balances(self,  # type: HummingbotApplication
                                market: str):
     if market in self.markets and self.markets[market].ready:
         return self.markets[market].get_all_balances()
     elif "Paper" in market:
         paper_balances = self.client_config_map.paper_trade.paper_trade_account_balance
         if paper_balances is None:
             return {}
         return {token: Decimal(str(bal)) for token, bal in paper_balances.items()}
     else:
         await UserBalances.instance().update_exchange_balance(market, self.client_config_map)
         return UserBalances.instance().all_balances(market)
Example #12
0
 async def ethereum_balances_df(self,  # type: HummingbotApplication
                                ):
     rows = []
     if ethereum_required_trading_pairs():
         bals = await UserBalances.eth_n_erc20_balances()
         for token, bal in bals.items():
             rows.append({"Asset": token, "Amount": round(bal, 4)})
     else:
         eth_bal = UserBalances.ethereum_balance()
         rows.append({"Asset": "ETH", "Amount": round(eth_bal, 4)})
     df = pd.DataFrame(data=rows, columns=["Asset", "Amount"])
     df.sort_values(by=["Asset"], inplace=True)
     return df
Example #13
0
 async def connect_exchange(self,  # type: HummingbotApplication
                            exchange):
     self.app.clear_input()
     self.placeholder_mode = True
     self.app.hide_input = True
     if exchange == "kraken":
         self._notify("Reminder: Please ensure your Kraken API Key Nonce Window is at least 10.")
     exchange_configs = [c for c in global_config_map.values()
                         if c.key in settings.CONNECTOR_SETTINGS[exchange].config_keys and c.is_connect_key]
     to_connect = True
     if Security.encrypted_file_exists(exchange_configs[0].key):
         await Security.wait_til_decryption_done()
         api_key_config = [c for c in exchange_configs if "api_key" in c.key]
         if api_key_config:
             api_key_config = api_key_config[0]
             api_key = Security.decrypted_value(api_key_config.key)
             prompt = f"Would you like to replace your existing {exchange} API key {api_key} (Yes/No)? >>> "
         else:
             prompt = f"Would you like to replace your existing {exchange_configs[0].key} (Yes/No)? >>> "
         answer = await self.app.prompt(prompt=prompt)
         if self.app.to_stop_config:
             self.app.to_stop_config = False
             return
         if answer.lower() not in ("yes", "y"):
             to_connect = False
     if to_connect:
         for config in exchange_configs:
             await self.prompt_a_config(config)
             if self.app.to_stop_config:
                 self.app.to_stop_config = False
                 return
             Security.update_secure_config(config.key, config.value)
         api_keys = await Security.api_keys(exchange)
         network_timeout = float(global_config_map["other_commands_timeout"].value)
         try:
             err_msg = await asyncio.wait_for(
                 UserBalances.instance().add_exchange(exchange, **api_keys), network_timeout
             )
         except asyncio.TimeoutError:
             self._notify("\nA network error prevented the connection to complete. See logs for more details.")
             self.placeholder_mode = False
             self.app.hide_input = False
             self.app.change_prompt(prompt=">>> ")
             raise
         if err_msg is None:
             self._notify(f"\nYou are now connected to {exchange}.")
         else:
             self._notify(f"\nError: {err_msg}")
     self.placeholder_mode = False
     self.app.hide_input = False
     self.app.change_prompt(prompt=">>> ")
Example #14
0
 async def show_balances(self):
     self._notify("Updating balances, please wait...")
     df = await self.balances_df()
     lines = [
         "    " + line for line in df.to_string(index=False).split("\n")
     ]
     self._notify("\n".join(lines))
     eth_address = global_config_map["ethereum_wallet"].value
     if eth_address is not None:
         bal = UserBalances.ethereum_balance()
         bal = round(bal, 4)
         self._notify(
             f"Ethereum balance in ...{eth_address[-4:]} wallet: {bal} ETH")
         self._notify(
             f"Note: You may have other ERC 20 tokens in this same address (not shown here)."
         )
Example #15
0
 async def validate_required_connections(self) -> Dict[str, str]:
     invalid_conns = {}
     if self.strategy_name == "celo_arb":
         err_msg = await self.validate_n_connect_celo(True)
         if err_msg is not None:
             invalid_conns["celo"] = err_msg
     if not global_config_map.get("paper_trade_enabled").value:
         await self.update_all_secure_configs()
         connections = await UserBalances.instance().update_exchanges(exchanges=required_exchanges)
         invalid_conns.update({ex: err_msg for ex, err_msg in connections.items()
                               if ex in required_exchanges and err_msg is not None})
         if any(ex in DEXES for ex in required_exchanges):
             err_msg = UserBalances.validate_ethereum_wallet()
             if err_msg is not None:
                 invalid_conns["ethereum"] = err_msg
     return invalid_conns
Example #16
0
    async def get_current_balances(self,  # type: HummingbotApplication
                                   market: str):
        paper_trade_suffix = '_PaperTrade'

        if market in self.markets and self.markets[market].ready:
            return self.markets[market].get_all_balances()
        elif paper_trade_suffix in market:
            return self.markets[market[:-len(paper_trade_suffix)]].get_all_balances()
        elif "perpetual_finance" == market:
            return await UserBalances.xdai_balances()
        else:
            gateway_eth_connectors = [cs.name for cs in CONNECTOR_SETTINGS.values() if cs.use_ethereum_wallet and
                                      cs.type == ConnectorType.Connector]
            if market in gateway_eth_connectors:
                return await UserBalances.instance().eth_n_erc20_balances()
            else:
                await UserBalances.instance().update_exchange_balance(market)
                return UserBalances.instance().all_balances(market)
Example #17
0
 async def validate_required_connections(self) -> Dict[str, str]:
     invalid_conns = {}
     if self.strategy_name == "celo_arb":
         err_msg = await self.validate_n_connect_celo(True)
         if err_msg is not None:
             invalid_conns["celo"] = err_msg
     if not any([
             str(exchange).endswith("paper_trade")
             for exchange in required_exchanges
     ]):
         await self.update_all_secure_configs()
         connections = await UserBalances.instance().update_exchanges(
             exchanges=required_exchanges)
         invalid_conns.update({
             ex: err_msg
             for ex, err_msg in connections.items()
             if ex in required_exchanges and err_msg is not None
         })
         if ethereum_wallet_required():
             err_msg = UserBalances.validate_ethereum_wallet()
             if err_msg is not None:
                 invalid_conns["ethereum"] = err_msg
     return invalid_conns
Example #18
0
    async def show_balances(self  # type: HummingbotApplication
                            ):
        total_col_name = f'Total ({RateOracle.global_token_symbol})'
        sum_not_for_show_name = "sum_not_for_show"
        self.notify("Updating balances, please wait...")
        network_timeout = float(
            self.client_config_map.commands_timeout.other_commands_timeout)
        try:
            all_ex_bals = await asyncio.wait_for(
                UserBalances.instance().all_balances_all_exchanges(
                    self.client_config_map), network_timeout)
        except asyncio.TimeoutError:
            self.notify(
                "\nA network error prevented the balances to update. See logs for more details."
            )
            raise
        all_ex_avai_bals = UserBalances.instance(
        ).all_available_balances_all_exchanges()

        exchanges_total = 0

        for exchange, bals in all_ex_bals.items():
            self.notify(f"\n{exchange}:")
            df, allocated_total = await self.exchange_balances_extra_df(
                exchange, bals, all_ex_avai_bals.get(exchange, {}))
            if df.empty:
                self.notify("You have no balance on this exchange.")
            else:
                lines = [
                    "    " + line
                    for line in df.drop(sum_not_for_show_name, axis=1).
                    to_string(index=False).split("\n")
                ]
                self.notify("\n".join(lines))
                self.notify(
                    f"\n  Total: {RateOracle.global_token_symbol} "
                    f"{PerformanceMetrics.smart_round(df[total_col_name].sum())}"
                )
                allocated_percentage = 0
                if df[sum_not_for_show_name].sum() != Decimal("0"):
                    allocated_percentage = allocated_total / df[
                        sum_not_for_show_name].sum()
                self.notify(f"Allocated: {allocated_percentage:.2%}")
                exchanges_total += df[total_col_name].sum()

        self.notify(
            f"\n\nExchanges Total: {RateOracle.global_token_symbol} {exchanges_total:.0f}    "
        )

        celo_address = CELO_KEYS.celo_address if hasattr(
            CELO_KEYS, "celo_address") else None
        if celo_address is not None:
            try:
                if not CeloCLI.unlocked:
                    await self.validate_n_connect_celo()
                df = await self.celo_balances_df()
                lines = [
                    "    " + line
                    for line in df.to_string(index=False).split("\n")
                ]
                self.notify("\ncelo:")
                self.notify("\n".join(lines))
            except Exception as e:
                self.notify(f"\ncelo CLI Error: {str(e)}")
Example #19
0
    async def start_check(self,  # type: HummingbotApplication
                          log_level: Optional[str] = None,
                          restore: Optional[bool] = False,
                          strategy_file_name: Optional[str] = None):
        if self.strategy_task is not None and not self.strategy_task.done():
            self.notify('The bot is already running - please run "stop" first')
            return

        if settings.required_rate_oracle:
            # If the strategy to run requires using the rate oracle to find FX rates, validate there is a rate for
            # each configured token pair
            if not (await self.confirm_oracle_conversion_rate()):
                self.notify("The strategy failed to start.")
                return

        if strategy_file_name:
            file_name = strategy_file_name.split(".")[0]
            self.strategy_file_name = file_name
            self.strategy_name = file_name
        elif not await self.status_check_all(notify_success=False):
            self.notify("Status checks failed. Start aborted.")
            return
        if self._last_started_strategy_file != self.strategy_file_name:
            init_logging("hummingbot_logs.yml",
                         override_log_level=log_level.upper() if log_level else None,
                         strategy_file_path=self.strategy_file_name)
            self._last_started_strategy_file = self.strategy_file_name

        # If macOS, disable App Nap.
        if platform.system() == "Darwin":
            import appnope
            appnope.nope()

        self._initialize_notifiers()
        try:
            self._initialize_strategy(self.strategy_name)
        except NotImplementedError:
            self.strategy_name = None
            self.strategy_file_name = None
            self.notify("Invalid strategy. Start aborted.")
            raise

        if any([str(exchange).endswith("paper_trade") for exchange in settings.required_exchanges]):
            self.notify("\nPaper Trading Active: All orders are simulated and no real orders are placed.")

        for exchange in settings.required_exchanges:
            connector: str = str(exchange)
            status: str = get_connector_status(connector)
            warning_msg: Optional[str] = warning_messages.get(connector, None)

            # confirm gateway connection
            conn_setting: settings.ConnectorSetting = settings.AllConnectorSettings.get_connector_settings()[connector]
            if conn_setting.uses_gateway_generic_connector():
                connector_details: Dict[str, Any] = conn_setting.conn_init_parameters()
                if connector_details:
                    data: List[List[str]] = [
                        ["chain", connector_details['chain']],
                        ["network", connector_details['network']],
                        ["wallet_address", connector_details['wallet_address']]
                    ]
                    await UserBalances.instance().update_exchange_balance(connector)
                    balances: List[str] = [
                        f"{str(PerformanceMetrics.smart_round(v, 8))} {k}"
                        for k, v in UserBalances.instance().all_balances(connector).items()
                    ]
                    data.append(["balances", ""])
                    for bal in balances:
                        data.append(["", bal])
                    wallet_df: pd.DataFrame = pd.DataFrame(data=data, columns=["", f"{connector} configuration"])
                    self.notify(wallet_df.to_string(index=False))

                    self.app.clear_input()
                    self.placeholder_mode = True
                    use_configuration = await self.app.prompt(prompt="Do you want to continue? (Yes/No) >>> ")
                    self.placeholder_mode = False
                    self.app.change_prompt(prompt=">>> ")

                    if use_configuration in ["N", "n", "No", "no"]:
                        return

                    if use_configuration not in ["Y", "y", "Yes", "yes"]:
                        self.notify("Invalid input. Please execute the `start` command again.")
                        return

            # Display custom warning message for specific connectors
            elif warning_msg is not None:
                self.notify(f"\nConnector status: {status}\n"
                            f"{warning_msg}")

            # Display warning message if the exchange connector has outstanding issues or not working
            elif not status.endswith("GREEN"):
                self.notify(f"\nConnector status: {status}. This connector has one or more issues.\n"
                            "Refer to our Github page for more info: https://github.com/coinalpha/hummingbot")

        self.notify(f"\nStatus check complete. Starting '{self.strategy_name}' strategy...")
        await self.start_market_making(restore)
        # We always start the RateOracle. It is required for PNL calculation.
        RateOracle.get_instance().start()