Пример #1
0
    def _initialize_markets(self, market_names: List[Tuple[str, str]]):
        ethereum_rpc_url = global_config_map.get("ethereum_rpc_url").value
        binance_api_key = global_config_map.get("binance_api_key").value
        binance_api_secret = global_config_map.get("binance_api_secret").value

        for market_name, symbol in market_names:
            market = None
            if market_name == "ddex":
                market = DDEXMarket(wallet=self.wallet,
                                    web3_url=ethereum_rpc_url,
                                    order_book_tracker_data_source_type=OrderBookTrackerDataSourceType.EXCHANGE_API,
                                    symbols=[symbol])

            elif market_name == "binance":
                market = BinanceMarket(web3_url=ethereum_rpc_url,
                                       binance_api_key=binance_api_key,
                                       binance_api_secret=binance_api_secret,
                                       order_book_tracker_data_source_type=OrderBookTrackerDataSourceType.EXCHANGE_API,
                                       symbols=[symbol])

            elif market_name == "radar_relay":
                market = RadarRelayMarket(wallet=self.wallet,
                                          web3_url=ethereum_rpc_url,
                                          symbols=[symbol])

            self.markets[market_name]: MarketBase = market
Пример #2
0
async def main():
    await create_yml_files()
    read_configs_from_yml()

    hb = HummingbotApplication()
    with patch_stdout(log_field=hb.app.log_field):
        init_logging("hummingbot_logs.yml",
                     override_log_level=global_config_map.get("log_level").value)
        tasks: List[Coroutine] = [hb.run()]
        if global_config_map.get("debug_console").value:
            management_port: int = detect_available_port(8211)
            tasks.append(start_management_console(locals(), host="localhost", port=management_port))
        await asyncio.gather(*tasks)
Пример #3
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)
         if key == "wallet":
             wallets = list_wallets()
             if len(wallets) > 0:
                 value = await self._unlock_wallet()
             else:
                 value = await self._create_or_import_wallet()
             logging.getLogger("hummingbot.public_eth_address").info(
                 value)
         elif key == "strategy_file_path":
             value = await self._import_or_create_strategy_config()
         else:
             value = await single_prompt(cv)
         cv.value = parse_cvar_value(cv, value)
     if not self.config_complete:
         await inner_loop(self._get_empty_configs())
Пример #4
0
    def status(self) -> bool:
        if self.config_complete:
            self.app.log(" - Config complete")
        else:
            self.app.log(' x Pending config. Please enter "config" before starting the bot.')
            return False

        eth_node_valid = check_web3(global_config_map.get("ethereum_rpc_url").value)
        if eth_node_valid:
            self.app.log(" - Ethereum node running and current")
        else:
            self.app.log(' x Bad ethereum rpc url. Your node may be syncing. '
                         'Please re-configure by entering "config ethereum_rpc_url"')
            return False

        loading_markets: List[str] = []
        for market_name, market in self.markets.items():
            if not market.ready:
                loading_markets.append(market_name)
        if self.strategy is None:
            return True
        elif len(loading_markets) > 0:
            for loading_market in loading_markets:
                self.app.log(f" x Waiting for {loading_market} market to get ready for trading. "
                             f"Please keep the bot running and try to start again in a few minutes")
            return False
        else:
            self.app.log(" - All markets ready")

        if self.strategy is not None:
            self.app.log("\n" + self.strategy.format_status())

        return False
Пример #5
0
 def _initialize_wallet(self, token_symbols: List[str]):
     ethereum_rpc_url = global_config_map.get("ethereum_rpc_url").value
     erc20_token_addresses = get_erc20_token_addresses(token_symbols)
     self.wallet: Web3Wallet = Web3Wallet(private_key=self.acct.privateKey,
                                          backend_urls=[ethereum_rpc_url],
                                          erc20_token_addresses=erc20_token_addresses,
                                          chain=EthereumChain.MAIN_NET)
Пример #6
0
async def main():
    await create_yml_files()
    init_logging("hummingbot_logs.yml")
    read_configs_from_yml()
    hb = HummingbotApplication()
    hb.acct = unlock_wallet(public_key=WALLET_PUBLIC_KEY,
                            password=WALLET_PASSWORD)

    with patch_stdout(log_field=hb.app.log_field):
        init_logging(
            "hummingbot_logs.yml",
            override_log_level=global_config_map.get("log_level").value)
        logging.getLogger().info("____DEV_MODE__start_directly__")

        in_memory_config_map.get("strategy").value = STRATEGY
        in_memory_config_map.get("strategy").validate(STRATEGY)
        in_memory_config_map.get("strategy_file_path").value = STRATEGY_PATH
        in_memory_config_map.get("strategy_file_path").validate(STRATEGY_PATH)
        global_config_map.get("wallet").value = WALLET_PUBLIC_KEY

        tasks: List[Coroutine] = [hb.run()]
        await asyncio.gather(*tasks)
Пример #7
0
    def status(self) -> bool:
        self.app.log("\n  Preliminary checks:")
        if self.config_complete:
            self.app.log("   - Config check: Config complete")
        else:
            self.app.log(
                '   x Config check: Pending config. Please enter "config" before starting the bot.'
            )
            return False

        eth_node_valid = check_web3(
            global_config_map.get("ethereum_rpc_url").value)
        if eth_node_valid:
            self.app.log("   - Node check: Ethereum node running and current")
        else:
            self.app.log(
                '   x Node check: Bad ethereum rpc url. Your node may be syncing. '
                'Please re-configure by entering "config ethereum_rpc_url"')
            return False

        if self.wallet is not None:
            has_minimum_eth = self.wallet.get_balance("ETH") > 0.01
            if has_minimum_eth:
                self.app.log(
                    "   - Min ETH check: Minimum ETH requirement satisfied")
            else:
                self.app.log(
                    "   x Min ETH check: Not enough ETH in wallet. "
                    "A small amount of Ether is required for sending transactions on Decentralized Exchanges"
                )

        loading_markets: List[str] = []
        for market_name, market in self.markets.items():
            if not market.ready:
                loading_markets.append(market_name)

        if self.strategy is None:
            return True
        elif len(loading_markets) > 0:
            for loading_market in loading_markets:
                self.app.log(
                    f"   x Market check:  Waiting for {loading_market} market to get ready for trading. "
                    f"Please keep the bot running and try to start again in a few minutes"
                )
            return False

        self.app.log("   - Market check: All markets ready")
        self.app.log(self.strategy.format_status() + "\n")
        return True
        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 not self.config_complete:
                await inner_loop(self._get_empty_configs())
    async def _create_or_import_wallet(self):
        choice = await self.app.prompt(prompt=global_config_map.get("wallet").prompt)
        if choice == "import":
            private_key = await self.app.prompt(prompt="Your wallet private key >>> ", is_password=True)
            password = await self.app.prompt(prompt="A password to protect your wallet key >>> ", is_password=True)

            self.acct = import_and_save_wallet(password, private_key)
            self.app.log("Wallet %s imported into hummingbot" % (self.acct.address,))
        elif choice == "create":
            password = await self.app.prompt(prompt="A password to protect your wallet key >>> ", is_password=True)
            self.acct = create_and_save_wallet(password)
            self.app.log("New wallet %s created" % (self.acct.address,))
        else:
            self.app.log('Invalid choice. Please enter "create" or "import".')
            result = await self._create_or_import_wallet()
            return result
        return self.acct.address
Пример #10
0
    def _initialize_markets(self, market_names: List[Tuple[str, str]]):
        ethereum_rpc_url = global_config_map.get("ethereum_rpc_url").value

        for market_name, symbol in market_names:
            if market_name == "ddex" and self.wallet:
                market = DDEXMarket(
                    wallet=self.wallet,
                    web3_url=ethereum_rpc_url,
                    order_book_tracker_data_source_type=
                    OrderBookTrackerDataSourceType.EXCHANGE_API,
                    symbols=[symbol])

            elif market_name == "binance":
                binance_api_key = global_config_map.get(
                    "binance_api_key").value
                binance_api_secret = global_config_map.get(
                    "binance_api_secret").value
                market = BinanceMarket(
                    web3_url=ethereum_rpc_url,
                    binance_api_key=binance_api_key,
                    binance_api_secret=binance_api_secret,
                    order_book_tracker_data_source_type=
                    OrderBookTrackerDataSourceType.EXCHANGE_API,
                    symbols=[symbol])

            elif market_name == "radar_relay" and self.wallet:
                market = RadarRelayMarket(wallet=self.wallet,
                                          web3_url=ethereum_rpc_url,
                                          symbols=[symbol])

            elif market_name == "coinbase_pro":
                coinbase_pro_api_key = global_config_map.get(
                    "coinbase_pro_api_key").value
                coinbase_pro_secret_key = global_config_map.get(
                    "coinbase_pro_secret_key").value
                coinbase_pro_passphrase = global_config_map.get(
                    "coinbase_pro_passphrase").value

                market = CoinbaseProMarket(
                    web3_url=ethereum_rpc_url,
                    coinbase_pro_api_key=coinbase_pro_api_key,
                    coinbase_pro_secret_key=coinbase_pro_secret_key,
                    coinbase_pro_passphrase=coinbase_pro_passphrase,
                    symbols=[symbol])

            else:
                raise ValueError(f"Market name {market_name} is invalid.")

            self.markets[market_name]: MarketBase = market
 async def _cancel_outstanding_orders(self) -> bool:
     on_chain_cancel_on_exit = global_config_map.get("on_chain_cancel_on_exit").value
     success = True
     self.app.log("Cancelling outstanding orders...")
     for market_name, market in self.markets.items():
         # By default, the bot does not cancel orders on exit on Radar Relay, since all open orders will
         # expire in a short window
         if not on_chain_cancel_on_exit and market_name == "radar_relay":
             continue
         cancellation_results = await market.cancel_all(self.KILL_TIMEOUT)
         uncancelled = list(filter(lambda cr: cr.success is False, cancellation_results))
         if len(uncancelled) > 0:
             success = False
             uncancelled_order_ids = list(map(lambda cr: cr.order_id, uncancelled))
             self.app.log("\nFailed to cancel the following orders on %s:\n%s" % (
                 market_name,
                 '\n'.join(uncancelled_order_ids)
             ))
     if success:
         self.app.log("All outstanding orders cancelled.")
     return success
Пример #12
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,
                                     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.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, 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.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)

        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)
            self.clock.add_iterator(self.strategy)
            self.strategy_task: asyncio.Task = asyncio.ensure_future(
                self.clock.run())
            self.app.log(
                f"\n'{strategy_name}' strategy started.\n"
                f"You can use the `status` command to query the progress.")
        except Exception as e:
            self.logger().error(str(e), exc_info=True)