From 8d95f8bea2f3008cb353abae74be9dd9db6c74ac Mon Sep 17 00:00:00 2001 From: cardosofede Date: Wed, 22 Nov 2023 16:06:41 -0300 Subject: [PATCH] (feat) adapt scripts to use multiple paris --- ...v2_market-making_dman_v1_multiple_pairs.py | 133 ++++++++++++++++ ...v2_market-making_dman_v2_multiple_pairs.py | 142 ++++++++--------- ...v2_market-making_dman_v3_multiple_pairs.py | 144 ++++++++---------- 3 files changed, 263 insertions(+), 156 deletions(-) create mode 100644 hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_dman_v1_multiple_pairs.py diff --git a/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_dman_v1_multiple_pairs.py b/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_dman_v1_multiple_pairs.py new file mode 100644 index 00000000..24189cfc --- /dev/null +++ b/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_dman_v1_multiple_pairs.py @@ -0,0 +1,133 @@ +from decimal import Decimal +from typing import Dict + +from hummingbot.connector.connector_base import ConnectorBase +from hummingbot.core.data_type.common import OrderType, PositionAction, PositionSide +from hummingbot.data_feed.candles_feed.candles_factory import CandlesConfig +from hummingbot.smart_components.controllers.dman_v1 import DManV1, DManV1Config +from hummingbot.smart_components.strategy_frameworks.data_types import ExecutorHandlerStatus, TripleBarrierConf +from hummingbot.smart_components.strategy_frameworks.market_making.market_making_executor_handler import ( + MarketMakingExecutorHandler, +) +from hummingbot.smart_components.utils.distributions import Distributions +from hummingbot.smart_components.utils.order_level_builder import OrderLevelBuilder +from hummingbot.strategy.script_strategy_base import ScriptStrategyBase + + +class DManV1MultiplePairs(ScriptStrategyBase): + # Account configuration + exchange = "binance_perpetual" + trading_pairs = ["ETH-USDT"] + leverage = 20 + + # Candles configuration + candles_exchange = "binance_perpetual" + candles_interval = "3m" + candles_max_records = 300 + + # Orders configuration + order_amount = Decimal("25") + n_levels = 5 + start_spread = 0.0006 + step_between_orders = 0.009 + order_refresh_time = 60 * 15 # 15 minutes + cooldown_time = 5 + + # Triple barrier configuration + stop_loss = Decimal("0.2") + take_profit = Decimal("0.06") + time_limit = 60 * 60 * 12 + trailing_stop_activation_price_delta = Decimal(str(step_between_orders / 2)) + trailing_stop_trailing_delta = Decimal(str(step_between_orders / 3)) + + # Advanced configurations + natr_length = 100 + + # Applying the configuration + order_level_builder = OrderLevelBuilder(n_levels=n_levels) + order_levels = order_level_builder.build_order_levels( + amounts=order_amount, + spreads=Distributions.arithmetic(n_levels=n_levels, start=start_spread, step=step_between_orders), + triple_barrier_confs=TripleBarrierConf( + stop_loss=stop_loss, take_profit=take_profit, time_limit=time_limit, + trailing_stop_activation_price_delta=trailing_stop_activation_price_delta, + trailing_stop_trailing_delta=trailing_stop_trailing_delta), + order_refresh_time=order_refresh_time, + cooldown_time=cooldown_time, + ) + controllers = {} + markets = {} + executor_handlers = {} + + for trading_pair in trading_pairs: + config = DManV1Config( + exchange=exchange, + trading_pair=trading_pair, + order_levels=order_levels, + candles_config=[ + CandlesConfig(connector=candles_exchange, trading_pair=trading_pair, + interval=candles_interval, max_records=candles_max_records), + ], + leverage=leverage, + natr_length=natr_length, + ) + controller = DManV1(config=config) + markets = controller.update_strategy_markets_dict(markets) + controllers[trading_pair] = controller + + def __init__(self, connectors: Dict[str, ConnectorBase]): + super().__init__(connectors) + for trading_pair, controller in self.controllers.items(): + self.executor_handlers[trading_pair] = MarketMakingExecutorHandler(strategy=self, controller=controller) + + @property + def is_perpetual(self): + """ + Checks if the exchange is a perpetual market. + """ + return "perpetual" in self.exchange + + def on_stop(self): + if self.is_perpetual: + self.close_open_positions() + for executor_handler in self.executor_handlers.values(): + executor_handler.stop() + + def close_open_positions(self): + # we are going to close all the open positions when the bot stops + for connector_name, connector in self.connectors.items(): + for trading_pair, position in connector.account_positions.items(): + if trading_pair in self.markets[connector_name]: + if position.position_side == PositionSide.LONG: + self.sell(connector_name=connector_name, + trading_pair=position.trading_pair, + amount=abs(position.amount), + order_type=OrderType.MARKET, + price=connector.get_mid_price(position.trading_pair), + position_action=PositionAction.CLOSE) + elif position.position_side == PositionSide.SHORT: + self.buy(connector_name=connector_name, + trading_pair=position.trading_pair, + amount=abs(position.amount), + order_type=OrderType.MARKET, + price=connector.get_mid_price(position.trading_pair), + position_action=PositionAction.CLOSE) + + def on_tick(self): + """ + This shows you how you can start meta controllers. You can run more than one at the same time and based on the + market conditions, you can orchestrate from this script when to stop or start them. + """ + for executor_handler in self.executor_handlers.values(): + if executor_handler.status == ExecutorHandlerStatus.NOT_STARTED: + executor_handler.start() + + def format_status(self) -> str: + if not self.ready_to_trade: + return "Market connectors are not ready." + lines = [] + for trading_pair, executor_handler in self.executor_handlers.items(): + lines.extend( + [f"Strategy: {executor_handler.controller.config.strategy_name} | Trading Pair: {trading_pair}", + executor_handler.to_format_status()]) + return "\n".join(lines) diff --git a/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_dman_v2_multiple_pairs.py b/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_dman_v2_multiple_pairs.py index 0779b71b..a3d7af2f 100644 --- a/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_dman_v2_multiple_pairs.py +++ b/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_dman_v2_multiple_pairs.py @@ -1,81 +1,63 @@ from decimal import Decimal from typing import Dict -from hummingbot.connector.connector_base import ConnectorBase, TradeType +from hummingbot.connector.connector_base import ConnectorBase from hummingbot.core.data_type.common import OrderType, PositionAction, PositionSide from hummingbot.data_feed.candles_feed.candles_factory import CandlesConfig from hummingbot.smart_components.controllers.dman_v2 import DManV2, DManV2Config -from hummingbot.smart_components.strategy_frameworks.data_types import ( - ExecutorHandlerStatus, - OrderLevel, - TripleBarrierConf, -) +from hummingbot.smart_components.strategy_frameworks.data_types import ExecutorHandlerStatus, TripleBarrierConf from hummingbot.smart_components.strategy_frameworks.market_making.market_making_executor_handler import ( MarketMakingExecutorHandler, ) +from hummingbot.smart_components.utils.distributions import Distributions +from hummingbot.smart_components.utils.order_level_builder import OrderLevelBuilder from hummingbot.strategy.script_strategy_base import ScriptStrategyBase class DManV2MultiplePairs(ScriptStrategyBase): - trading_pairs = ["RUNE-USDT", "AGLD-USDT"] + # Account configuration exchange = "binance_perpetual" + trading_pairs = ["ETH-USDT"] + leverage = 20 - # This is only for the perpetual markets - leverage_by_trading_pair = { - "HBAR-USDT": 25, - "CYBER-USDT": 20, - "ETH-USDT": 100, - "LPT-USDT": 10, - "UNFI-USDT": 20, - "BAKE-USDT": 20, - "YGG-USDT": 20, - "SUI-USDT": 50, - "TOMO-USDT": 25, - "RUNE-USDT": 25, - "STX-USDT": 25, - "API3-USDT": 20, - "LIT-USDT": 20, - "PERP-USDT": 16, - "HOOK-USDT": 20, - "AMB-USDT": 20, - "ARKM-USDT": 20, - "TRB-USDT": 10, - "OMG-USDT": 25, - "WLD-USDT": 50, - "PEOPLE-USDT": 25, - "AGLD-USDT": 20, - "BAT-USDT": 20 - } + # Candles configuration + candles_exchange = "binance_perpetual" + candles_interval = "3m" + candles_max_records = 300 - triple_barrier_conf = TripleBarrierConf( - stop_loss=Decimal("0.15"), take_profit=Decimal("0.02"), - time_limit=60 * 60 * 12, - take_profit_order_type=OrderType.LIMIT, - trailing_stop_activation_price_delta=Decimal("0.005"), - trailing_stop_trailing_delta=Decimal("0.002"), - ) + # Orders configuration + order_amount = Decimal("25") + n_levels = 5 + start_spread = 0.0006 + step_between_orders = 0.009 + order_refresh_time = 60 * 15 # 15 minutes + cooldown_time = 5 - order_levels = [ - OrderLevel(level=1, side=TradeType.BUY, order_amount_usd=Decimal("10"), - spread_factor=Decimal(0.5), order_refresh_time=60 * 5, - cooldown_time=15, triple_barrier_conf=triple_barrier_conf), - OrderLevel(level=2, side=TradeType.BUY, order_amount_usd=Decimal("20"), - spread_factor=Decimal(1.0), order_refresh_time=60 * 5, - cooldown_time=15, triple_barrier_conf=triple_barrier_conf), - OrderLevel(level=3, side=TradeType.BUY, order_amount_usd=Decimal("30"), - spread_factor=Decimal(1.5), order_refresh_time=60 * 5, - cooldown_time=15, triple_barrier_conf=triple_barrier_conf), + # Triple barrier configuration + stop_loss = Decimal("0.2") + take_profit = Decimal("0.06") + time_limit = 60 * 60 * 12 + trailing_stop_activation_price_delta = Decimal(str(step_between_orders / 2)) + trailing_stop_trailing_delta = Decimal(str(step_between_orders / 3)) - OrderLevel(level=1, side=TradeType.SELL, order_amount_usd=Decimal("10"), - spread_factor=Decimal(0.5), order_refresh_time=60 * 5, - cooldown_time=15, triple_barrier_conf=triple_barrier_conf), - OrderLevel(level=2, side=TradeType.SELL, order_amount_usd=Decimal("20"), - spread_factor=Decimal(1.0), order_refresh_time=60 * 5, - cooldown_time=15, triple_barrier_conf=triple_barrier_conf), - OrderLevel(level=3, side=TradeType.SELL, order_amount_usd=Decimal("30"), - spread_factor=Decimal(1.5), order_refresh_time=60 * 5, - cooldown_time=15, triple_barrier_conf=triple_barrier_conf), - ] + # Advanced configurations + macd_fast = 12 + macd_slow = 26 + macd_signal = 9 + natr_length = 100 + + # Applying the configuration + order_level_builder = OrderLevelBuilder(n_levels=n_levels) + order_levels = order_level_builder.build_order_levels( + amounts=order_amount, + spreads=Distributions.arithmetic(n_levels=n_levels, start=start_spread, step=step_between_orders), + triple_barrier_confs=TripleBarrierConf( + stop_loss=stop_loss, take_profit=take_profit, time_limit=time_limit, + trailing_stop_activation_price_delta=trailing_stop_activation_price_delta, + trailing_stop_trailing_delta=trailing_stop_trailing_delta), + order_refresh_time=order_refresh_time, + cooldown_time=cooldown_time, + ) controllers = {} markets = {} executor_handlers = {} @@ -86,11 +68,14 @@ class DManV2MultiplePairs(ScriptStrategyBase): trading_pair=trading_pair, order_levels=order_levels, candles_config=[ - CandlesConfig(connector=exchange, trading_pair=trading_pair, interval="15m", max_records=300), + CandlesConfig(connector=candles_exchange, trading_pair=trading_pair, + interval=candles_interval, max_records=candles_max_records), ], - macd_fast=21, macd_slow=42, macd_signal=9, - natr_length=100, - leverage=leverage_by_trading_pair.get(trading_pair, 1), + leverage=leverage, + macd_fast=macd_fast, + macd_slow=macd_slow, + macd_signal=macd_signal, + natr_length=natr_length, ) controller = DManV2(config=config) markets = controller.update_strategy_markets_dict(markets) @@ -118,20 +103,21 @@ def close_open_positions(self): # we are going to close all the open positions when the bot stops for connector_name, connector in self.connectors.items(): for trading_pair, position in connector.account_positions.items(): - if position.position_side == PositionSide.LONG: - self.sell(connector_name=connector_name, - trading_pair=position.trading_pair, - amount=abs(position.amount), - order_type=OrderType.MARKET, - price=connector.get_mid_price(position.trading_pair), - position_action=PositionAction.CLOSE) - elif position.position_side == PositionSide.SHORT: - self.buy(connector_name=connector_name, - trading_pair=position.trading_pair, - amount=abs(position.amount), - order_type=OrderType.MARKET, - price=connector.get_mid_price(position.trading_pair), - position_action=PositionAction.CLOSE) + if trading_pair in self.markets[connector_name]: + if position.position_side == PositionSide.LONG: + self.sell(connector_name=connector_name, + trading_pair=position.trading_pair, + amount=abs(position.amount), + order_type=OrderType.MARKET, + price=connector.get_mid_price(position.trading_pair), + position_action=PositionAction.CLOSE) + elif position.position_side == PositionSide.SHORT: + self.buy(connector_name=connector_name, + trading_pair=position.trading_pair, + amount=abs(position.amount), + order_type=OrderType.MARKET, + price=connector.get_mid_price(position.trading_pair), + position_action=PositionAction.CLOSE) def on_tick(self): """ diff --git a/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_dman_v3_multiple_pairs.py b/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_dman_v3_multiple_pairs.py index c0a2af58..dd58f6cb 100644 --- a/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_dman_v3_multiple_pairs.py +++ b/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_dman_v3_multiple_pairs.py @@ -1,81 +1,62 @@ from decimal import Decimal from typing import Dict -from hummingbot.connector.connector_base import ConnectorBase, TradeType +from hummingbot.connector.connector_base import ConnectorBase from hummingbot.core.data_type.common import OrderType, PositionAction, PositionSide from hummingbot.data_feed.candles_feed.candles_factory import CandlesConfig from hummingbot.smart_components.controllers.dman_v3 import DManV3, DManV3Config -from hummingbot.smart_components.strategy_frameworks.data_types import ( - ExecutorHandlerStatus, - OrderLevel, - TripleBarrierConf, -) +from hummingbot.smart_components.strategy_frameworks.data_types import ExecutorHandlerStatus, TripleBarrierConf from hummingbot.smart_components.strategy_frameworks.market_making.market_making_executor_handler import ( MarketMakingExecutorHandler, ) +from hummingbot.smart_components.utils.distributions import Distributions +from hummingbot.smart_components.utils.order_level_builder import OrderLevelBuilder from hummingbot.strategy.script_strategy_base import ScriptStrategyBase class DManV3MultiplePairs(ScriptStrategyBase): - trading_pairs = ["RUNE-USDT", "AGLD-USDT"] + # Account configuration exchange = "binance_perpetual" + trading_pairs = ["ETH-USDT"] + leverage = 20 - # This is only for the perpetual markets - leverage_by_trading_pair = { - "HBAR-USDT": 25, - "CYBER-USDT": 20, - "ETH-USDT": 100, - "LPT-USDT": 10, - "UNFI-USDT": 20, - "BAKE-USDT": 20, - "YGG-USDT": 20, - "SUI-USDT": 50, - "TOMO-USDT": 25, - "RUNE-USDT": 25, - "STX-USDT": 25, - "API3-USDT": 20, - "LIT-USDT": 20, - "PERP-USDT": 16, - "HOOK-USDT": 20, - "AMB-USDT": 20, - "ARKM-USDT": 20, - "TRB-USDT": 10, - "OMG-USDT": 25, - "WLD-USDT": 50, - "PEOPLE-USDT": 25, - "AGLD-USDT": 20, - "BAT-USDT": 20 - } + # Candles configuration + candles_exchange = "binance_perpetual" + candles_interval = "1h" + candles_max_records = 300 + bollinger_band_length = 200 + bollinger_band_std = 3.0 - triple_barrier_conf = TripleBarrierConf( - stop_loss=Decimal("0.15"), take_profit=Decimal("0.02"), - time_limit=60 * 60 * 12, - take_profit_order_type=OrderType.LIMIT, - trailing_stop_activation_price_delta=Decimal("0.005"), - trailing_stop_trailing_delta=Decimal("0.002"), - ) + # Orders configuration + order_amount = Decimal("25") + n_levels = 5 + start_spread = 0.5 # percentage of the bollinger band (0.5 means that the order will be between the bollinger mid-price and the upper band) + step_between_orders = 0.3 # percentage of the bollinger band (0.1 means that the next order will be 10% of the bollinger band away from the previous order) - order_levels = [ - OrderLevel(level=1, side=TradeType.BUY, order_amount_usd=Decimal("10"), - spread_factor=Decimal(0.5), order_refresh_time=60 * 5, - cooldown_time=15, triple_barrier_conf=triple_barrier_conf), - OrderLevel(level=2, side=TradeType.BUY, order_amount_usd=Decimal("20"), - spread_factor=Decimal(1.0), order_refresh_time=60 * 5, - cooldown_time=15, triple_barrier_conf=triple_barrier_conf), - OrderLevel(level=3, side=TradeType.BUY, order_amount_usd=Decimal("30"), - spread_factor=Decimal(1.5), order_refresh_time=60 * 5, - cooldown_time=15, triple_barrier_conf=triple_barrier_conf), + # Triple barrier configuration + stop_loss = Decimal("0.01") + take_profit = Decimal("0.03") + time_limit = 60 * 60 * 6 + trailing_stop_activation_price_delta = Decimal("0.008") + trailing_stop_trailing_delta = Decimal("0.004") - OrderLevel(level=1, side=TradeType.SELL, order_amount_usd=Decimal("10"), - spread_factor=Decimal(0.5), order_refresh_time=60 * 5, - cooldown_time=15, triple_barrier_conf=triple_barrier_conf), - OrderLevel(level=2, side=TradeType.SELL, order_amount_usd=Decimal("20"), - spread_factor=Decimal(1.0), order_refresh_time=60 * 5, - cooldown_time=15, triple_barrier_conf=triple_barrier_conf), - OrderLevel(level=3, side=TradeType.SELL, order_amount_usd=Decimal("30"), - spread_factor=Decimal(1.5), order_refresh_time=60 * 5, - cooldown_time=15, triple_barrier_conf=triple_barrier_conf), - ] + # Advanced configurations + side_filter = True + dynamic_spread_factor = True + dynamic_target_spread = False + smart_activation = False + activation_threshold = Decimal("0.001") + + # Applying the configuration + order_level_builder = OrderLevelBuilder(n_levels=n_levels) + order_levels = order_level_builder.build_order_levels( + amounts=order_amount, + spreads=Distributions.arithmetic(n_levels=n_levels, start=start_spread, step=step_between_orders), + triple_barrier_confs=TripleBarrierConf( + stop_loss=stop_loss, take_profit=take_profit, time_limit=time_limit, + trailing_stop_activation_price_delta=trailing_stop_activation_price_delta, + trailing_stop_trailing_delta=trailing_stop_trailing_delta), + ) controllers = {} markets = {} executor_handlers = {} @@ -86,11 +67,17 @@ class DManV3MultiplePairs(ScriptStrategyBase): trading_pair=trading_pair, order_levels=order_levels, candles_config=[ - CandlesConfig(connector=exchange, trading_pair=trading_pair, interval="15m", max_records=300), + CandlesConfig(connector=candles_exchange, trading_pair=trading_pair, + interval=candles_interval, max_records=candles_max_records), ], - bb_length=200, - bb_std=3.0, - leverage=leverage_by_trading_pair.get(trading_pair, 1), + bb_length=bollinger_band_length, + bb_std=bollinger_band_std, + side_filter=side_filter, + dynamic_spread_factor=dynamic_spread_factor, + dynamic_target_spread=dynamic_target_spread, + smart_activation=smart_activation, + activation_threshold=activation_threshold, + leverage=leverage, ) controller = DManV3(config=config) markets = controller.update_strategy_markets_dict(markets) @@ -118,20 +105,21 @@ def close_open_positions(self): # we are going to close all the open positions when the bot stops for connector_name, connector in self.connectors.items(): for trading_pair, position in connector.account_positions.items(): - if position.position_side == PositionSide.LONG: - self.sell(connector_name=connector_name, - trading_pair=position.trading_pair, - amount=abs(position.amount), - order_type=OrderType.MARKET, - price=connector.get_mid_price(position.trading_pair), - position_action=PositionAction.CLOSE) - elif position.position_side == PositionSide.SHORT: - self.buy(connector_name=connector_name, - trading_pair=position.trading_pair, - amount=abs(position.amount), - order_type=OrderType.MARKET, - price=connector.get_mid_price(position.trading_pair), - position_action=PositionAction.CLOSE) + if trading_pair in self.markets[connector_name]: + if position.position_side == PositionSide.LONG: + self.sell(connector_name=connector_name, + trading_pair=position.trading_pair, + amount=abs(position.amount), + order_type=OrderType.MARKET, + price=connector.get_mid_price(position.trading_pair), + position_action=PositionAction.CLOSE) + elif position.position_side == PositionSide.SHORT: + self.buy(connector_name=connector_name, + trading_pair=position.trading_pair, + amount=abs(position.amount), + order_type=OrderType.MARKET, + price=connector.get_mid_price(position.trading_pair), + position_action=PositionAction.CLOSE) def on_tick(self): """