Skip to content

Commit

Permalink
Merge pull request #252 from CoinAlpha/feat/amm_migration_script
Browse files Browse the repository at this point in the history
Feat/amm migration script & in-flight config disable
  • Loading branch information
petioptrv committed Jun 9, 2022
2 parents b2f3991 + 203d8a0 commit b409311
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 31 deletions.
7 changes: 5 additions & 2 deletions hummingbot/client/command/config_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,15 +220,18 @@ async def _config_single_key(self, # type: HummingbotApplication
):
await self._config_single_key_legacy(key, input_value)
else:
if input_value is None:
self.notify("Please follow the prompt to complete configurations: ")
client_config_key = key in self.client_config_map.config_paths()
if client_config_key:
config_map = self.client_config_map
file_path = CLIENT_CONFIG_PATH
elif self.strategy is not None:
self.notify("Configuring the strategy while it is running is not currently supported.")
return
else:
config_map = self.strategy_config_map
file_path = STRATEGIES_CONF_DIR_PATH / self.strategy_file_name
if input_value is None:
self.notify("Please follow the prompt to complete configurations: ")
if key == "inventory_target_base_pct":
await self.asset_ratio_maintenance_prompt(config_map, input_value)
elif key == "inventory_price":
Expand Down
115 changes: 89 additions & 26 deletions hummingbot/client/config/conf_migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
from hummingbot.client.config.config_helpers import ClientConfigAdapter, save_to_yml
from hummingbot.client.config.security import Security
from hummingbot.client.settings import CLIENT_CONFIG_PATH, CONF_DIR_PATH, STRATEGIES_CONF_DIR_PATH
from hummingbot.strategy.avellaneda_market_making.avellaneda_market_making_config_map_pydantic import (
AvellanedaMarketMakingConfigMap,
)
from hummingbot.strategy.cross_exchange_market_making.cross_exchange_market_making_config_map_pydantic import (
CrossExchangeMarketMakingConfigMap,
)
Expand All @@ -36,6 +39,7 @@
encrypted_conf_postfix = ".json"
conf_dir_path = CONF_DIR_PATH
strategies_conf_dir_path = STRATEGIES_CONF_DIR_PATH
celo_address = None


def migrate_configs(secrets_manager: BaseSecretsManager) -> List[str]:
Expand Down Expand Up @@ -86,6 +90,8 @@ def backup_existing_dir() -> List[str]:


def migrate_global_config() -> List[str]:
global celo_address

logging.getLogger().info("\nMigrating the global config...")
global_config_path = CONF_DIR_PATH / "conf_global.yml"
errors = []
Expand All @@ -94,11 +100,16 @@ def migrate_global_config() -> List[str]:
data = yaml.safe_load(f)
del data["template_version"]
client_config_map = ClientConfigAdapter(ClientConfigMap())
migrate_global_config_modes(client_config_map, data)
_migrate_global_config_modes(client_config_map, data)
"kraken_api_tier" in data and data.pop("kraken_api_tier")
"key_file_path" in data and data.pop("key_file_path")
celo_address = data.get("celo_address")
if celo_address is not None:
data.pop("celo_address")
keys = list(data.keys())
for key in keys:
if key in client_config_map.keys():
migrate_global_config_field(client_config_map, data, key)
_migrate_global_config_field(client_config_map, data, key)
for key in data:
logging.getLogger().warning(f"Global ConfigVar {key} was not migrated.")
errors.extend(client_config_map.validate_model())
Expand All @@ -112,7 +123,7 @@ def migrate_global_config() -> List[str]:
return errors


def migrate_global_config_modes(client_config_map: ClientConfigAdapter, data: Dict):
def _migrate_global_config_modes(client_config_map: ClientConfigAdapter, data: Dict):
client_config_map: Union[ClientConfigAdapter, ClientConfigMap] = client_config_map # for IDE autocomplete

kill_switch_enabled = data.pop("kill_switch_enabled")
Expand All @@ -122,10 +133,10 @@ def migrate_global_config_modes(client_config_map: ClientConfigAdapter, data: Di
else:
client_config_map.kill_switch_mode = KillSwitchDisabledMode()

migrate_global_config_field(
_migrate_global_config_field(
client_config_map.paper_trade, data, "paper_trade_exchanges"
)
migrate_global_config_field(
_migrate_global_config_field(
client_config_map.paper_trade, data, "paper_trade_account_balance"
)

Expand Down Expand Up @@ -165,10 +176,10 @@ def migrate_global_config_modes(client_config_map: ClientConfigAdapter, data: Di
else:
client_config_map.pmm_script_mode = PMMScriptDisabledMode()

migrate_global_config_field(
_migrate_global_config_field(
client_config_map.gateway, data, "gateway_api_host"
)
migrate_global_config_field(
_migrate_global_config_field(
client_config_map.gateway, data, "gateway_api_port"
)

Expand All @@ -181,33 +192,33 @@ def migrate_global_config_modes(client_config_map: ClientConfigAdapter, data: Di
else:
client_config_map.anonymized_metrics_mode = AnonymizedMetricsDisabledMode()

migrate_global_config_field(
_migrate_global_config_field(
client_config_map.global_token, data, "global_token", "global_token_name"
)
migrate_global_config_field(
_migrate_global_config_field(
client_config_map.global_token, data, "global_token_symbol"
)

migrate_global_config_field(
_migrate_global_config_field(
client_config_map.commands_timeout, data, "create_command_timeout"
)
migrate_global_config_field(
_migrate_global_config_field(
client_config_map.commands_timeout, data, "other_commands_timeout"
)

color_map: Union[ClientConfigAdapter, ColorConfigMap] = client_config_map.color
migrate_global_config_field(color_map, data, "top-pane", "top_pane")
migrate_global_config_field(color_map, data, "bottom-pane", "bottom_pane")
migrate_global_config_field(color_map, data, "output-pane", "output_pane")
migrate_global_config_field(color_map, data, "input-pane", "input_pane")
migrate_global_config_field(color_map, data, "logs-pane", "logs_pane")
migrate_global_config_field(color_map, data, "terminal-primary", "terminal_primary")
migrate_global_config_field(color_map, data, "primary-label", "primary_label")
migrate_global_config_field(color_map, data, "secondary-label", "secondary_label")
migrate_global_config_field(color_map, data, "success-label", "success_label")
migrate_global_config_field(color_map, data, "warning-label", "warning_label")
migrate_global_config_field(color_map, data, "info-label", "info_label")
migrate_global_config_field(color_map, data, "error-label", "error_label")
_migrate_global_config_field(color_map, data, "top-pane", "top_pane")
_migrate_global_config_field(color_map, data, "bottom-pane", "bottom_pane")
_migrate_global_config_field(color_map, data, "output-pane", "output_pane")
_migrate_global_config_field(color_map, data, "input-pane", "input_pane")
_migrate_global_config_field(color_map, data, "logs-pane", "logs_pane")
_migrate_global_config_field(color_map, data, "terminal-primary", "terminal_primary")
_migrate_global_config_field(color_map, data, "primary-label", "primary_label")
_migrate_global_config_field(color_map, data, "secondary-label", "secondary_label")
_migrate_global_config_field(color_map, data, "success-label", "success_label")
_migrate_global_config_field(color_map, data, "warning-label", "warning_label")
_migrate_global_config_field(color_map, data, "info-label", "info_label")
_migrate_global_config_field(color_map, data, "error-label", "error_label")

balance_asset_limit = data.pop("balance_asset_limit")
if balance_asset_limit is not None:
Expand All @@ -223,7 +234,7 @@ def migrate_global_config_modes(client_config_map: ClientConfigAdapter, data: Di
client_config_map.balance_asset_limit = balance_asset_limit


def migrate_global_config_field(
def _migrate_global_config_field(
cm: ClientConfigAdapter, global_config_data: Dict[str, Any], attr: str, cm_attr: Optional[str] = None
):
value = global_config_data.pop(attr)
Expand All @@ -242,12 +253,60 @@ def migrate_strategy_confs_paths():
if "strategy" in conf and _has_connector_field(conf):
new_path = strategies_conf_dir_path / child.name
child.rename(new_path)
if conf["strategy"] == "cross_exchange_market_making":
if conf["strategy"] == "avellaneda_market_making":
errors.extend(migrate_amm_confs(conf, new_path))
elif conf["strategy"] == "cross_exchange_market_making":
errors.extend(migrate_xemm_confs(conf, new_path))
logging.getLogger().info(f"Migrated conf for {conf['strategy']}")
return errors


def migrate_amm_confs(conf, new_path) -> List[str]:
execution_timeframe = conf.pop("execution_timeframe")
if execution_timeframe == "infinite":
conf["execution_timeframe_mode"] = {}
conf.pop("start_time")
conf.pop("end_time")
elif execution_timeframe == "from_date_to_date":
conf["execution_timeframe_mode"] = {
"start_datetime": conf.pop("start_time"),
"end_datetime": conf.pop("end_time"),
}
else:
assert execution_timeframe == "daily_between_times"
conf["execution_timeframe_mode"] = {
"start_time": conf.pop("start_time"),
"end_time": conf.pop("end_time"),
}
order_levels = int(conf.pop("order_levels"))
if order_levels == 1:
conf["order_levels_mode"] = {}
conf.pop("level_distances")
else:
conf["order_levels_mode"] = {
"order_levels": order_levels,
"level_distances": conf.pop("level_distances")
}
hanging_orders_enabled = conf.pop("hanging_orders_enabled")
if not hanging_orders_enabled:
conf["hanging_orders_mode"] = {}
conf.pop("hanging_orders_cancel_pct")
else:
conf["hanging_orders_mode"] = {
"hanging_orders_cancel_pct": conf.pop("hanging_orders_cancel_pct")
}
if "template_version" in conf:
conf.pop("template_version")
try:
config_map = ClientConfigAdapter(AvellanedaMarketMakingConfigMap(**conf))
save_to_yml(new_path, config_map)
errors = []
except Exception as e:
logging.getLogger().error(str(e))
errors = [str(e)]
return errors


def migrate_xemm_confs(conf, new_path) -> List[str]:
if "active_order_canceling" in conf:
if conf["active_order_canceling"]:
Expand Down Expand Up @@ -316,8 +375,9 @@ def migrate_connector_confs(secrets_manager: BaseSecretsManager):
if connector_dir.name.startswith("_") or connector_dir.name in connector_exceptions:
continue
try:
suffix = "data_types" if connector_dir.name == "celo" else "utils"
util_module_path: str = (
f"hummingbot.connector.{type_dir.name}.{connector_dir.name}.{connector_dir.name}_utils"
f"hummingbot.connector.{type_dir.name}.{connector_dir.name}.{connector_dir.name}_{suffix}"
)
util_module = importlib.import_module(util_module_path)
config_keys = getattr(util_module, "KEYS", None)
Expand All @@ -340,6 +400,9 @@ def _maybe_migrate_encrypted_confs(config_keys: BaseConnectorConfigMap) -> List[
missing_fields = []
for el in cm.traverse():
if el.client_field_data is not None:
if el.attr == "celo_address" and celo_address is not None:
cm.setattr_no_validation(el.attr, celo_address)
continue
key_path = conf_dir_path / f"{encrypted_conf_prefix}{el.attr}{encrypted_conf_postfix}"
if key_path.exists():
with open(key_path, 'r') as f:
Expand Down
3 changes: 1 addition & 2 deletions hummingbot/client/config/config_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"""

import time

from datetime import datetime
from decimal import Decimal
from typing import Optional
Expand Down Expand Up @@ -34,7 +33,7 @@ def validate_connector(value: str) -> Optional[str]:
Restrict valid derivatives to the connector file names
"""
from hummingbot.client.settings import AllConnectorSettings
if value not in AllConnectorSettings.get_connector_settings():
if value not in AllConnectorSettings.get_connector_settings() and value != "celo":
return f"Invalid connector, please choose value from {AllConnectorSettings.get_connector_settings().keys()}"


Expand Down
4 changes: 3 additions & 1 deletion hummingbot/client/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,9 @@ def update_connector_config_keys(cls, new_config_keys: "BaseConnectorConfigMap")

@classmethod
def get_exchange_names(cls) -> Set[str]:
return {cs.name for cs in cls.all_connector_settings.values() if cs.type is ConnectorType.Exchange}
return {
cs.name for cs in cls.all_connector_settings.values() if cs.type is ConnectorType.Exchange
}.union(set(PAPER_TRADE_EXCHANGES))

@classmethod
def get_derivative_names(cls) -> Set[str]:
Expand Down

0 comments on commit b409311

Please sign in to comment.