async def _config_single_key(self, # type: HummingbotApplication key: str): """ Configure a single variable only. Prompt the user to finish all configurations if there are remaining empty configs at the end. """ self._notify("Please follow the prompt to complete configurations: ") self.placeholder_mode = True self.app.toggle_hide_input() try: cv: ConfigVar = self._get_config_var_with_key(key) value = await self.prompt_single_variable(cv, requirement_overwrite=True) cv.value = parse_cvar_value(cv, value) await write_config_to_yml() self._notify(f"\nNew config saved:\n{key}: {str(value)}") if not self.config_complete: choice = await self.app.prompt("Your configuration is incomplete. Would you like to proceed and " "finish all necessary configurations? (y/n) >>> ") if choice.lower() in {"y", "yes"}: self.config() return else: self._notify("Aborted.") except asyncio.TimeoutError: self.logger().error("Prompt timeout") except Exception as err: self.logger().error("Unknown error while writing config. %s" % (err,), exc_info=True) finally: self.app.toggle_hide_input() self.placeholder_mode = False self.app.change_prompt(prompt=">>> ")
async def bounty_config_loop(self, # type: HummingbotApplication ): """ Configuration loop for bounty registration """ self.placeholder_mode = True self.app.toggle_hide_input() self._notify("Starting registration process for liquidity bounties:") try: for key, cvar in liquidity_bounty_config_map.items(): if key == "liquidity_bounty_enabled": await self.print_doc(join(dirname(__file__), "../liquidity_bounty/requirements.txt")) elif key == "agree_to_terms": await self.bounty_print_terms() elif key == "agree_to_data_collection": await self.print_doc(join(dirname(__file__), "../liquidity_bounty/data_collection_policy.txt")) elif key == "eth_address": self._notify("\nYour wallets:") self.list("wallets") value = await self.prompt_single_variable(cvar) cvar.value = parse_cvar_value(cvar, value) if cvar.type == "bool" and cvar.value is False: raise ValueError(f"{cvar.key} is required.") await save_to_yml(LIQUIDITY_BOUNTY_CONFIG_PATH, liquidity_bounty_config_map) except ValueError as e: self._notify(f"Registration aborted: {str(e)}") except Exception as e: self.logger().error(f"Error configuring liquidity bounty: {str(e)}") self.app.change_prompt(prompt=">>> ") self.app.toggle_hide_input() self.placeholder_mode = False
async def prompt_a_config_legacy( self, # type: HummingbotApplication config: ConfigVar, input_value=None, assign_default=True, ): if config.key == "inventory_price": await self.inventory_price_prompt_legacy(self.strategy_config_map, input_value) return if input_value is None: if assign_default: self.app.set_text(parse_config_default_to_text(config)) prompt = await config.get_prompt() input_value = await self.app.prompt(prompt=prompt, is_password=config.is_secure) if self.app.to_stop_config: return value = parse_cvar_value(config, input_value) err_msg = await config.validate(input_value) if err_msg is not None: self.notify(err_msg) config.value = None await self.prompt_a_config_legacy(config) else: config.value = value
def validate_take_if_crossed(value: str) -> Optional[str]: err_msg = validate_bool(value) if err_msg is not None: return err_msg price_source_enabled = perpetual_market_making_config_map["price_source_enabled"].value take_if_crossed = parse_cvar_value(perpetual_market_making_config_map["take_if_crossed"], value) if take_if_crossed and not price_source_enabled: return "You can enable this feature only when external pricing source for mid-market price is used."
def assign_values_advanced_mode_switch(advanced_mode): advanced_mode = parse_cvar_value(pure_market_making_config_map["advanced_mode"], advanced_mode) found_advanced_section = False for cvar in pure_market_making_config_map.values(): if found_advanced_section: if advanced_mode and cvar.value is not None and cvar.default is not None: cvar.value = None if not advanced_mode and cvar.value is None and cvar.default is not None: cvar.value = cvar.default elif cvar == pure_market_making_config_map["advanced_mode"]: found_advanced_section = True
async def _inner_config_loop(self, keys: List[str]): """ Inner loop used by `self._config_loop` that recursively calls itself until all required configs are filled. This enables the bot to detect any newly added requirements as the user fills currently required variables. Use case example: When the user selects a particular market, the API keys related to that market becomes required. :param keys: """ for key in keys: cv: ConfigVar = self._get_config_var_with_key(key) value = await self.prompt_single_variable(cv, requirement_overwrite=False) cv.value = parse_cvar_value(cv, value) if not self.config_complete: await self._inner_config_loop(self._get_empty_configs())
async def prompt_a_config( self, # type: HummingbotApplication config: ConfigVar, input_value=None, assign_default=True): if input_value is None: if assign_default: self.app.set_text(parse_config_default_to_text(config)) input_value = await self.app.prompt(prompt=config.prompt, is_password=config.is_secure) err_msg = config.validate(input_value) if err_msg is not None: self._notify(err_msg) await self.prompt_a_config(config) else: config.value = parse_cvar_value(config, input_value)
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)
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())
def update_oracle_settings(value: str): c_map = cross_exchange_market_making_config_map if not (c_map["use_oracle_conversion_rate"].value is not None and c_map["maker_market_trading_pair"].value is not None and c_map["taker_market_trading_pair"].value is not None): return use_oracle = parse_cvar_value(c_map["use_oracle_conversion_rate"], c_map["use_oracle_conversion_rate"].value) first_base, first_quote = c_map["maker_market_trading_pair"].value.split("-") second_base, second_quote = c_map["taker_market_trading_pair"].value.split("-") if use_oracle and (first_base != second_base or first_quote != second_quote): settings.required_rate_oracle = True settings.rate_oracle_pairs = [] if first_base != second_base: settings.rate_oracle_pairs.append(f"{second_base}-{first_base}") if first_quote != second_quote: settings.rate_oracle_pairs.append(f"{second_quote}-{first_quote}") else: settings.required_rate_oracle = False settings.rate_oracle_pairs = []
async def prompt_answer( self, # type: HummingbotApplication config: ConfigVar, input_value: Optional[str] = None, assign_default: bool = True, ): if input_value is None: if assign_default: self.app.set_text(parse_config_default_to_text(config)) prompt = await config.get_prompt() input_value = await self.app.prompt(prompt=prompt) if self.app.to_stop_config: return config.value = parse_cvar_value(config, input_value) err_msg = await config.validate(input_value) if err_msg is not None: self.notify(err_msg) config.value = None await self.prompt_answer(config)