def __init__(self): self.ev_loop: asyncio.BaseEventLoop = asyncio.get_event_loop() self.parser: ThrowingArgumentParser = load_parser(self) self.app = HummingbotCLI( input_handler=self._handle_command, bindings=load_key_bindings(self), completer=load_completer(self)) self.acct: Optional[LocalAccount] = None self.markets: Dict[str, MarketBase] = {} self.wallet: Optional[Web3Wallet] = None self.strategy_task: Optional[asyncio.Task] = None self.strategy: Optional[StrategyBase] = None self.market_pair: Optional[CrossExchangeMarketPair] = None self.market_trading_pair_tuples: List[MarketTradingPairTuple] = [] self.clock: Optional[Clock] = None self.init_time: int = int(time.time() * 1e3) self.start_time: Optional[int] = None self.assets: Optional[Set[str]] = set() self.starting_balances = {} self.placeholder_mode = False self.log_queue_listener: Optional[logging.handlers.QueueListener] = None self.reporting_module: Optional[ReportAggregator] = None self.data_feed: Optional[DataFeedBase] = None self.notifiers: List[NotifierBase] = [] self.kill_switch: Optional[KillSwitch] = None self.liquidity_bounty: Optional[LiquidityBounty] = None self._initialize_liquidity_bounty() self._app_warnings: Deque[ApplicationWarning] = deque() self._trading_required: bool = True self.trade_fill_db: SQLConnectionManager = SQLConnectionManager.get_trade_fills_instance() self.markets_recorder: Optional[MarketsRecorder] = None
def __init__(self): self.ev_loop: asyncio.BaseEventLoop = asyncio.get_event_loop() self.parser: ThrowingArgumentParser = load_parser(self) self.app = HummingbotCLI(input_handler=self._handle_command, bindings=load_key_bindings(self), completer=load_completer(self)) self.acct: Optional[LocalAccount] = None self.markets: Dict[str, MarketBase] = {} self.wallet: Optional[Web3Wallet] = None self.strategy_task: Optional[asyncio.Task] = None self.strategy: Optional[CrossExchangeMarketMakingStrategy] = None self.market_pair: Optional[CrossExchangeMarketPair] = None self.clock: Optional[Clock] = None self.assets: Optional[Set[str]] = set() self.starting_balances = {} self.placeholder_mode = False self.log_queue_listener: Optional[ logging.handlers.QueueListener] = None self.reporting_module: Optional[ReportAggregator] = None self.data_feed: Optional[DataFeedBase] = None self.stop_loss_tracker: Optional[StopLossTracker] = None self._app_warnings: Deque[ApplicationWarning] = deque() self._trading_required: bool = True
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.")
async def update_gateway_config_key_list(self): try: config_list: List[str] = [] config_dict: Dict[str, Any] = await self._fetch_gateway_configs() build_config_namespace_keys(config_list, config_dict) self.gateway_config_keys = config_list self._app.app.input_field.completer = load_completer(self._app) except Exception: self.logger().error( "Error fetching gateway configs. Please check that Gateway service is online. ", exc_info=True)
def __init__(self, client_config_map: Optional[ClientConfigAdapter] = None): self.client_config_map: Union[ClientConfigMap, ClientConfigAdapter] = ( # type-hint enables IDE auto-complete client_config_map or load_client_config_map_from_file() ) # This is to start fetching trading pairs for auto-complete TradingPairFetcher.get_instance(self.client_config_map) self.ev_loop: asyncio.AbstractEventLoop = asyncio.get_event_loop() self.markets: Dict[str, ExchangeBase] = {} # strategy file name and name get assigned value after import or create command self._strategy_file_name: Optional[str] = None self.strategy_name: Optional[str] = None self._strategy_config_map: Optional[BaseStrategyConfigMap] = None self.strategy_task: Optional[asyncio.Task] = None self.strategy: Optional[StrategyBase] = None self.market_pair: Optional[CrossExchangeMarketPair] = None self.market_trading_pair_tuples: List[MarketTradingPairTuple] = [] self.clock: Optional[Clock] = None self.market_trading_pairs_map = {} self.token_list = {} self.init_time: float = time.time() self.start_time: Optional[int] = None self.placeholder_mode = False self.log_queue_listener: Optional[logging.handlers.QueueListener] = None self.data_feed: Optional[DataFeedBase] = None self.notifiers: List[NotifierBase] = [] self.kill_switch: Optional[KillSwitch] = None self._app_warnings: Deque[ApplicationWarning] = deque() self._trading_required: bool = True self._last_started_strategy_file: Optional[str] = None self.trade_fill_db: Optional[SQLConnectionManager] = None self.markets_recorder: Optional[MarketsRecorder] = None self._pmm_script_iterator = None self._binance_connector = None self._shared_client = None # gateway variables and monitor self._gateway_monitor = GatewayStatusMonitor(self) command_tabs = self.init_command_tabs() self.parser: ThrowingArgumentParser = load_parser(self, command_tabs) self.app = HummingbotCLI( self.client_config_map, input_handler=self._handle_command, bindings=load_key_bindings(self), completer=load_completer(self), command_tabs=command_tabs ) self._init_gateway_monitor()
def __init__(self): # This is to start fetching trading pairs for auto-complete TradingPairFetcher.get_instance() self.ev_loop: asyncio.BaseEventLoop = asyncio.get_event_loop() # # Enable main thread debug mode to make sure Callbacks taking longer than 50ms are logged. # self.ev_loop.set_debug(True) # self.ev_loop.slow_callback_duration = 0.001 # 1ms self.parser: ThrowingArgumentParser = load_parser(self) self.app = HummingbotCLI(input_handler=self._handle_command, bindings=load_key_bindings(self), completer=load_completer(self)) self.markets: Dict[str, ExchangeBase] = {} self.wallet: Optional[Web3Wallet] = None # strategy file name and name get assigned value after import or create command self._strategy_file_name: str = None self.strategy_name: str = None self.strategy_task: Optional[asyncio.Task] = None self.strategy: Optional[StrategyBase] = None self.market_pair: Optional[CrossExchangeMarketPair] = None self.market_trading_pair_tuples: List[MarketTradingPairTuple] = [] self.clock: Optional[Clock] = None self.market_trading_pairs_map = {} self.token_list = {} self.init_time: float = time.time() self.start_time: Optional[int] = None self.assets: Optional[Set[str]] = set() self.placeholder_mode = False self.log_queue_listener: Optional[ logging.handlers.QueueListener] = None self.data_feed: Optional[DataFeedBase] = None self.notifiers: List[NotifierBase] = [] self.kill_switch: Optional[KillSwitch] = None self._app_warnings: Deque[ApplicationWarning] = deque() self._trading_required: bool = True self._last_started_strategy_file: Optional[str] = None self.trade_fill_db: Optional[SQLConnectionManager] = None self.markets_recorder: Optional[MarketsRecorder] = None self._script_iterator = None self._binance_connector = None
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()
def __init__(self): self.ev_loop: asyncio.BaseEventLoop = asyncio.get_event_loop() self.parser: ThrowingArgumentParser = load_parser(self) self.app = HummingbotCLI(input_handler=self._handle_command, bindings=load_key_bindings(self), completer=load_completer(self)) self.markets: Dict[str, ExchangeBase] = {} self.wallet: Optional[Web3Wallet] = None # strategy file name and name get assigned value after import or create command self.strategy_file_name: str = None self.strategy_name: str = None self.strategy_task: Optional[asyncio.Task] = None self.strategy: Optional[StrategyBase] = None self.market_pair: Optional[CrossExchangeMarketPair] = None self.market_trading_pair_tuples: List[MarketTradingPairTuple] = [] self.clock: Optional[Clock] = None self.init_time: int = int(time.time() * 1e3) self.start_time: Optional[int] = None self.assets: Optional[Set[str]] = set() self.starting_balances = {} self.placeholder_mode = False self.log_queue_listener: Optional[ logging.handlers.QueueListener] = None self.data_feed: Optional[DataFeedBase] = None self.notifiers: List[NotifierBase] = [] self.kill_switch: Optional[KillSwitch] = None self._app_warnings: Deque[ApplicationWarning] = deque() self._trading_required: bool = True self.trade_fill_db: SQLConnectionManager = SQLConnectionManager.get_trade_fills_instance( ) self.markets_recorder: Optional[MarketsRecorder] = None self._script_iterator = None # This is to start fetching trading pairs for auto-complete TradingPairFetcher.get_instance()
async def _gateway_connect( self, # type: HummingbotApplication connector: str = None ): with begin_placeholder_mode(self): gateway_connections_conf: List[Dict[str, str]] = GatewayConnectionSetting.load() if connector is None: if len(gateway_connections_conf) < 1: self.notify("No existing connection.\n") else: connector_df: pd.DataFrame = build_connector_display(gateway_connections_conf) self.notify(connector_df.to_string(index=False)) else: # get available networks connector_configs: Dict[str, Any] = await GatewayHttpClient.get_instance().get_connectors() connector_config: List[Dict[str, Any]] = [ d for d in connector_configs["connectors"] if d["name"] == connector ] if len(connector_config) < 1: self.notify(f"No available blockchain networks available for the connector '{connector}'.") return available_networks: List[Dict[str, Any]] = connector_config[0]["available_networks"] trading_type: str = connector_config[0]["trading_type"][0] # ask user to select a chain. Automatically select if there is only one. chains: List[str] = [d['chain'] for d in available_networks] chain: str if len(chains) == 1: chain = chains[0] else: # chains as options while True: chain = await self.app.prompt( prompt=f"Which chain do you want {connector} to connect to?({', '.join(chains)}) >>> " ) if self.app.to_stop_config: self.app.to_stop_config = False return if chain in GATEWAY_CONNECTORS: break self.notify(f"{chain} chain not supported.\n") # ask user to select a network. Automatically select if there is only one. networks: List[str] = list( itertools.chain.from_iterable([d['networks'] for d in available_networks if d['chain'] == chain]) ) network: str if len(networks) == 1: network = networks[0] else: while True: self.app.input_field.completer.set_gateway_networks(networks) network = await self.app.prompt( prompt=f"Which network do you want {connector} to connect to? ({', '.join(networks)}) >>> " ) if self.app.to_stop_config: return if network in networks: break self.notify("Error: Invalid network") # get wallets for the selected chain wallets_response: List[Dict[str, Any]] = await GatewayHttpClient.get_instance().get_wallets() matching_wallets: List[Dict[str, Any]] = [w for w in wallets_response if w["chain"] == chain] wallets: List[str] if len(matching_wallets) < 1: wallets = [] else: wallets = matching_wallets[0]['walletAddresses'] # if the user has no wallet, ask them to select one if len(wallets) < 1: self.app.clear_input() self.placeholder_mode = True wallet_private_key = await self.app.prompt( prompt=f"Enter your {chain}-{network} wallet private key >>> ", is_password=True ) self.app.clear_input() if self.app.to_stop_config: return response: Dict[str, Any] = await GatewayHttpClient.get_instance().add_wallet( chain, network, wallet_private_key ) wallet_address: str = response["address"] # the user has a wallet. Ask if they want to use it or create a new one. else: # print table while True: use_existing_wallet: str = await self.app.prompt( prompt=f"Do you want to connect to {chain}-{network} with one of your existing wallets on " f"Gateway? (Yes/No) >>> " ) if self.app.to_stop_config: return if use_existing_wallet in ["Y", "y", "Yes", "yes", "N", "n", "No", "no"]: break self.notify("Invalid input. Please try again or exit config [CTRL + x].\n") self.app.clear_input() # they use an existing wallet if use_existing_wallet is not None and use_existing_wallet in ["Y", "y", "Yes", "yes"]: native_token: str = native_tokens[chain] wallet_table: List[Dict[str, Any]] = [] for w in wallets: balances: Dict[str, Any] = await GatewayHttpClient.get_instance().get_balances( chain, network, w, [native_token] ) wallet_table.append({"balance": balances['balances'][native_token], "address": w}) wallet_df: pd.DataFrame = build_wallet_display(native_token, wallet_table) self.notify(wallet_df.to_string(index=False)) self.app.input_field.completer.set_list_gateway_wallets_parameters(wallets_response, chain) while True: wallet_address: str = await self.app.prompt(prompt="Select a gateway wallet >>> ") if self.app.to_stop_config: return if wallet_address in wallets: self.notify(f"You have selected {wallet_address}") break self.notify("Error: Invalid wallet address") # they want to create a new wallet even though they have other ones else: while True: try: wallet_private_key: str = await self.app.prompt( prompt=f"Enter your {chain}-{network} wallet private key >>> ", is_password=True ) self.app.clear_input() if self.app.to_stop_config: return response: Dict[str, Any] = await GatewayHttpClient.get_instance().add_wallet( chain, network, wallet_private_key ) wallet_address = response["address"] break except Exception: self.notify("Error adding wallet. Check private key.\n") self.app.clear_input() # write wallets to Gateway connectors settings. GatewayConnectionSetting.upsert_connector_spec(connector, chain, network, trading_type, wallet_address) self.notify(f"The {connector} connector now uses wallet {wallet_address} on {chain}-{network}") # update AllConnectorSettings and fee overrides. AllConnectorSettings.create_connector_settings() AllConnectorSettings.initialize_paper_trade_settings(global_config_map.get("paper_trade_exchanges").value) await refresh_trade_fees_config() # Reload completer here to include newly added gateway connectors self.app.input_field.completer = load_completer(self)
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.")