diff --git a/hummingbot_files/templates/master_bot_conf/conf_client.yml b/hummingbot_files/templates/master_bot_conf/conf_client.yml deleted file mode 100644 index fe5e1773..00000000 --- a/hummingbot_files/templates/master_bot_conf/conf_client.yml +++ /dev/null @@ -1,194 +0,0 @@ -#################################### -### client_config_map config ### -#################################### - -instance_id: e90c0d6f2b1e2d54fa0c0a69612b07174320963b - -log_level: INFO - -debug_console: false - -strategy_report_interval: 900.0 - -logger_override_whitelist: -- hummingbot.strategy.arbitrage -- hummingbot.strategy.cross_exchange_market_making -- conf - -log_file_path: /home/hummingbot/logs - -kill_switch_mode: {} - -# What to auto-fill in the prompt after each import command (start/config) -autofill_import: disabled - -telegram_mode: {} - -# MQTT Bridge configuration. -mqtt_bridge: - mqtt_host: localhost - mqtt_port: 1883 - mqtt_username: admin - mqtt_password: password - mqtt_namespace: hbot - mqtt_ssl: false - mqtt_logger: true - mqtt_notifier: true - mqtt_commands: true - mqtt_events: true - mqtt_external_events: true - mqtt_autostart: true - -# Error log sharing -send_error_logs: true - -# Can store the previous strategy ran for quick retrieval. -previous_strategy: null - -# Advanced database options, currently supports SQLAlchemy's included dialects -# Reference: https://docs.sqlalchemy.org/en/13/dialects/ -# To use an instance of SQLite DB the required configuration is -# db_engine: sqlite -# To use a DBMS the required configuration is -# db_host: 127.0.0.1 -# db_port: 3306 -# db_username: username -# db_password: password -# db_name: dbname -db_mode: - db_engine: sqlite - -pmm_script_mode: {} - -# Balance Limit Configurations -# e.g. Setting USDT and BTC limits on Binance. -# balance_asset_limit: -# binance: -# BTC: 0.1 -# USDT: 1000 -balance_asset_limit: - kucoin: {} - ciex: {} - ascend_ex_paper_trade: {} - crypto_com: {} - mock_paper_exchange: {} - btc_markets: {} - bitmart: {} - hitbtc: {} - loopring: {} - mexc: {} - polkadex: {} - bybit: {} - foxbit: {} - gate_io_paper_trade: {} - kucoin_paper_trade: {} - altmarkets: {} - ascend_ex: {} - bittrex: {} - probit_kr: {} - binance: {} - bybit_testnet: {} - okx: {} - bitmex: {} - binance_us: {} - probit: {} - gate_io: {} - lbank: {} - whitebit: {} - bitmex_testnet: {} - kraken: {} - huobi: {} - binance_paper_trade: {} - ndax_testnet: {} - coinbase_pro: {} - ndax: {} - bitfinex: {} - -# Fixed gas price (in Gwei) for Ethereum transactions -manual_gas_price: 50.0 - -# Gateway API Configurations -# default host to only use localhost -# Port need to match the final installation port for Gateway -gateway: - gateway_api_host: localhost - gateway_api_port: '15888' - -certs_path: /home/hummingbot/certs - -# Whether to enable aggregated order and trade data collection -anonymized_metrics_mode: - anonymized_metrics_interval_min: 15.0 - -# Command Shortcuts -# Define abbreviations for often used commands -# or batch grouped commands together -command_shortcuts: -- command: spreads - help: Set bid and ask spread - arguments: - - Bid Spread - - Ask Spread - output: - - config bid_spread $1 - - config ask_spread $2 - -# A source for rate oracle, currently ascend_ex, binance, coin_gecko, kucoin, gate_io -rate_oracle_source: - name: binance - -# A universal token which to display tokens values in, e.g. USD,EUR,BTC -global_token: - global_token_name: USD - global_token_symbol: $ - -# Percentage of API rate limits (on any exchange and any end point) allocated to this bot instance. -# Enter 50 to indicate 50%. E.g. if the API rate limit is 100 calls per second, and you allocate -# 50% to this setting, the bot will have a maximum (limit) of 50 calls per second -rate_limits_share_pct: 100.0 - -commands_timeout: - create_command_timeout: 10.0 - other_commands_timeout: 30.0 - -# Tabulate table format style (https://github.com/astanin/python-tabulate#table-format) -tables_format: psql - -paper_trade: - paper_trade_exchanges: - - binance - - kucoin - - ascend_ex - - gate_io - paper_trade_account_balance: - BTC: 1.0 - USDT: 1000.0 - ONE: 1000.0 - USDQ: 1000.0 - TUSD: 1000.0 - ETH: 10.0 - WETH: 10.0 - USDC: 1000.0 - DAI: 1000.0 - -color: - top_pane: '#000000' - bottom_pane: '#000000' - output_pane: '#262626' - input_pane: '#1C1C1C' - logs_pane: '#121212' - terminal_primary: '#5FFFD7' - primary_label: '#5FFFD7' - secondary_label: '#FFFFFF' - success_label: '#5FFFD7' - warning_label: '#FFFF00' - info_label: '#5FD7FF' - error_label: '#FF0000' - gold_label: '#FFD700' - silver_label: '#C0C0C0' - bronze_label: '#CD7F32' - -# The tick size is the frequency with which the clock notifies the time iterators by calling the -# c_tick() method, that means for example that if the tick size is 1, the logic of the strategy -# will run every second. -tick_size: 1.0 diff --git a/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_bollingrid_multiple_pairs.py b/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_bollingrid_multiple_pairs.py deleted file mode 100644 index cac9f481..00000000 --- a/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_bollingrid_multiple_pairs.py +++ /dev/null @@ -1,153 +0,0 @@ -from decimal import Decimal -from typing import Dict - -from hummingbot.connector.connector_base import ConnectorBase, TradeType -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.bollingrid import BollingGrid, BollingGridConfig -from hummingbot.smart_components.strategy_frameworks.data_types import ( - ExecutorHandlerStatus, - OrderLevel, - TripleBarrierConf, -) -from hummingbot.smart_components.strategy_frameworks.market_making.market_making_executor_handler import ( - MarketMakingExecutorHandler, -) -from hummingbot.strategy.script_strategy_base import ScriptStrategyBase - - -class BollinGridMultiplePairs(ScriptStrategyBase): - trading_pairs = ["RUNE-USDT", "AGLD-USDT"] - exchange = "binance_perpetual" - - # 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 - } - - 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"), - ) - - 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), - - 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), - ] - controllers = {} - markets = {} - executor_handlers = {} - - for trading_pair in trading_pairs: - config = BollingGridConfig( - exchange=exchange, - trading_pair=trading_pair, - order_levels=order_levels, - candles_config=[ - CandlesConfig(connector=exchange, trading_pair=trading_pair, interval="15m", max_records=300), - ], - bb_length=200, - bb_std=3.0, - leverage=leverage_by_trading_pair.get(trading_pair, 1), - ) - controller = BollingGrid(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 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_composed.py b/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_dman_composed.py index 385cf6d8..c5398974 100644 --- a/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_dman_composed.py +++ b/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_dman_composed.py @@ -36,22 +36,22 @@ class MarketMakingDmanComposed(ScriptStrategyBase): exchange="binance_perpetual", trading_pair=trading_pair, order_levels=[ - OrderLevel(level=0, side=TradeType.BUY, order_amount_usd=Decimal(15), + OrderLevel(level=0, side=TradeType.BUY, order_amount_usd=Decimal("15"), spread_factor=Decimal(1.0), order_refresh_time=60 * 30, cooldown_time=15, triple_barrier_conf=triple_barrier_conf_top), - OrderLevel(level=1, side=TradeType.BUY, order_amount_usd=Decimal(50), + OrderLevel(level=1, side=TradeType.BUY, order_amount_usd=Decimal("50"), spread_factor=Decimal(5.0), order_refresh_time=60 * 30, cooldown_time=15, triple_barrier_conf=triple_barrier_conf_bottom), - OrderLevel(level=2, side=TradeType.BUY, order_amount_usd=Decimal(50), + OrderLevel(level=2, side=TradeType.BUY, order_amount_usd=Decimal("50"), spread_factor=Decimal(8.0), order_refresh_time=60 * 15, cooldown_time=15, triple_barrier_conf=triple_barrier_conf_bottom), - OrderLevel(level=0, side=TradeType.SELL, order_amount_usd=Decimal(15), + OrderLevel(level=0, side=TradeType.SELL, order_amount_usd=Decimal("15"), spread_factor=Decimal(1.0), order_refresh_time=60 * 30, cooldown_time=15, triple_barrier_conf=triple_barrier_conf_top), - OrderLevel(level=1, side=TradeType.SELL, order_amount_usd=Decimal(50), + OrderLevel(level=1, side=TradeType.SELL, order_amount_usd=Decimal("50"), spread_factor=Decimal(5.0), order_refresh_time=60 * 30, cooldown_time=15, triple_barrier_conf=triple_barrier_conf_bottom), - OrderLevel(level=2, side=TradeType.SELL, order_amount_usd=Decimal(50), + OrderLevel(level=2, side=TradeType.SELL, order_amount_usd=Decimal("50"), spread_factor=Decimal(8.0), order_refresh_time=60 * 15, cooldown_time=15, triple_barrier_conf=triple_barrier_conf_bottom), ], diff --git a/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_dman_v1.py b/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_dman_v1.py deleted file mode 100644 index c1c0c1f5..00000000 --- a/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_dman_v1.py +++ /dev/null @@ -1,98 +0,0 @@ -from decimal import Decimal -from typing import Dict - -from hummingbot.connector.connector_base import ConnectorBase, TradeType -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, - OrderLevel, - TripleBarrierConf, -) -from hummingbot.smart_components.strategy_frameworks.market_making.market_making_executor_handler import ( - MarketMakingExecutorHandler, -) -from hummingbot.strategy.script_strategy_base import ScriptStrategyBase - - -class MarketMakingDmanV1(ScriptStrategyBase): - trading_pair = "HBAR-USDT" - triple_barrier_conf = TripleBarrierConf( - stop_loss=Decimal("0.03"), take_profit=Decimal("0.02"), - time_limit=60 * 60 * 24, - trailing_stop_activation_price_delta=Decimal("0.002"), - trailing_stop_trailing_delta=Decimal("0.0005") - ) - - config_v1 = DManV1Config( - exchange="binance_perpetual", - trading_pair=trading_pair, - order_levels=[ - OrderLevel(level=0, 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=1, side=TradeType.BUY, order_amount_usd=Decimal(50), - spread_factor=Decimal(2.5), order_refresh_time=60 * 5, - cooldown_time=15, triple_barrier_conf=triple_barrier_conf), - OrderLevel(level=0, 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=1, side=TradeType.SELL, order_amount_usd=Decimal(50), - spread_factor=Decimal(2.5), order_refresh_time=60 * 5, - cooldown_time=15, triple_barrier_conf=triple_barrier_conf), - ], - candles_config=[ - CandlesConfig(connector="binance_perpetual", trading_pair=trading_pair, interval="3m", max_records=1000), - ], - leverage=10, - natr_length=21 - ) - - dman_v1 = DManV1(config=config_v1) - - empty_markets = {} - markets = dman_v1.update_strategy_markets_dict(empty_markets) - - def __init__(self, connectors: Dict[str, ConnectorBase]): - super().__init__(connectors) - self.dman_v1_executor = MarketMakingExecutorHandler(strategy=self, controller=self.dman_v1) - - def on_stop(self): - self.close_open_positions() - - 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. - """ - if self.dman_v1_executor.status == ExecutorHandlerStatus.NOT_STARTED: - self.dman_v1_executor.start() - - def format_status(self) -> str: - if not self.ready_to_trade: - return "Market connectors are not ready." - lines = [] - lines.extend(["DMAN V1", self.dman_v1_executor.to_format_status()]) - lines.extend(["\n-----------------------------------------\n"]) - return "\n".join(lines) - - 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) 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.py b/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_dman_v2.py deleted file mode 100644 index 63325026..00000000 --- a/hummingbot_files/templates/master_bot_conf/scripts/v2_market-making_dman_v2.py +++ /dev/null @@ -1,102 +0,0 @@ -from decimal import Decimal -from typing import Dict - -from hummingbot.connector.connector_base import ConnectorBase, TradeType -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.market_making.market_making_executor_handler import ( - MarketMakingExecutorHandler, -) -from hummingbot.strategy.script_strategy_base import ScriptStrategyBase - - -class MarketMakingDmanV2(ScriptStrategyBase): - trading_pair = "HBAR-USDT" - triple_barrier_conf = TripleBarrierConf( - stop_loss=Decimal("0.03"), take_profit=Decimal("0.02"), - time_limit=60 * 60 * 24, - trailing_stop_activation_price_delta=Decimal("0.002"), - trailing_stop_trailing_delta=Decimal("0.0005") - ) - config_v2 = DManV2Config( - exchange="binance_perpetual", - trading_pair=trading_pair, - order_levels=[ - OrderLevel(level=0, side=TradeType.BUY, order_amount_usd=Decimal(15), - spread_factor=Decimal(0.5), order_refresh_time=60 * 5, - cooldown_time=15, triple_barrier_conf=triple_barrier_conf), - OrderLevel(level=1, side=TradeType.BUY, order_amount_usd=Decimal(30), - spread_factor=Decimal(1.0), order_refresh_time=60 * 5, - cooldown_time=15, triple_barrier_conf=triple_barrier_conf), - OrderLevel(level=2, side=TradeType.BUY, order_amount_usd=Decimal(50), - spread_factor=Decimal(2.0), order_refresh_time=60 * 5, - cooldown_time=15, triple_barrier_conf=triple_barrier_conf), - OrderLevel(level=0, side=TradeType.SELL, order_amount_usd=Decimal(15), - spread_factor=Decimal(0.5), order_refresh_time=60 * 5, - cooldown_time=15, triple_barrier_conf=triple_barrier_conf), - OrderLevel(level=1, side=TradeType.SELL, order_amount_usd=Decimal(30), - spread_factor=Decimal(1.0), order_refresh_time=60 * 5, - cooldown_time=15, triple_barrier_conf=triple_barrier_conf), - OrderLevel(level=2, side=TradeType.SELL, order_amount_usd=Decimal(50), - spread_factor=Decimal(2.0), order_refresh_time=60 * 5, - cooldown_time=15, triple_barrier_conf=triple_barrier_conf), - ], - candles_config=[ - CandlesConfig(connector="binance_perpetual", trading_pair=trading_pair, interval="3m", max_records=1000), - ], - leverage=10, - natr_length=21, macd_fast=12, macd_slow=26, macd_signal=9 - ) - dman_v2 = DManV2(config=config_v2) - - empty_markets = {} - markets = dman_v2.update_strategy_markets_dict(empty_markets) - - def __init__(self, connectors: Dict[str, ConnectorBase]): - super().__init__(connectors) - self.dman_v2_executor = MarketMakingExecutorHandler(strategy=self, controller=self.dman_v2) - - def on_stop(self): - self.close_open_positions() - - 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. - """ - if self.dman_v2_executor.status == ExecutorHandlerStatus.NOT_STARTED: - self.dman_v2_executor.start() - - def format_status(self) -> str: - if not self.ready_to_trade: - return "Market connectors are not ready." - lines = [] - lines.extend(["DMAN V2", self.dman_v2_executor.to_format_status()]) - lines.extend(["\n-----------------------------------------\n"]) - return "\n".join(lines) - - 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) 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): """ diff --git a/quants_lab/controllers/bollinger_v1.py b/quants_lab/controllers/bollinger_v1.py index a0f0566d..30c13727 100644 --- a/quants_lab/controllers/bollinger_v1.py +++ b/quants_lab/controllers/bollinger_v1.py @@ -1,5 +1,4 @@ import time -from typing import Optional import pandas as pd import pandas_ta as ta diff --git a/quants_lab/controllers/bollingrid.py b/quants_lab/controllers/bollingrid.py deleted file mode 100644 index 04c1943b..00000000 --- a/quants_lab/controllers/bollingrid.py +++ /dev/null @@ -1,104 +0,0 @@ -import time -from decimal import Decimal - -import pandas_ta as ta # noqa: F401 - -from hummingbot.core.data_type.common import TradeType -from hummingbot.smart_components.executors.position_executor.data_types import PositionConfig, TrailingStop -from hummingbot.smart_components.executors.position_executor.position_executor import PositionExecutor -from hummingbot.smart_components.strategy_frameworks.data_types import OrderLevel -from hummingbot.smart_components.strategy_frameworks.market_making.market_making_controller_base import ( - MarketMakingControllerBase, - MarketMakingControllerConfigBase, -) - - -class BollingGridConfig(MarketMakingControllerConfigBase): - strategy_name: str = "bollinger_grid" - bb_length: int = 12 - bb_std: float = 2.0 - natr_length: int = 14 - - -class BollingGrid(MarketMakingControllerBase): - """ - Directional Market Making Strategy making use of NATR indicator to make spreads dynamic and shift the mid price. - """ - - def __init__(self, config: BollingGridConfig): - super().__init__(config) - self.config = config - - def refresh_order_condition(self, executor: PositionExecutor, order_level: OrderLevel) -> bool: - """ - Checks if the order needs to be refreshed. - You can reimplement this method to add more conditions. - """ - if executor.position_config.timestamp + order_level.order_refresh_time > time.time(): - return False - return True - - def early_stop_condition(self, executor: PositionExecutor, order_level: OrderLevel) -> bool: - """ - If an executor has an active position, should we close it based on a condition. - """ - return False - - def cooldown_condition(self, executor: PositionExecutor, order_level: OrderLevel) -> bool: - """ - After finishing an order, the executor will be in cooldown for a certain amount of time. - This prevents the executor from creating a new order immediately after finishing one and execute a lot - of orders in a short period of time from the same side. - """ - if executor.close_timestamp and executor.close_timestamp + order_level.cooldown_time > time.time(): - return True - return False - - def get_processed_data(self): - """ - Gets the price and spread multiplier from the last candlestick. - """ - candles_df = self.candles[0].candles_df - natr = ta.natr(candles_df["high"], candles_df["low"], candles_df["close"], length=self.config.natr_length) / 100 - candles_df.ta.bbands(length=self.config.bb_length, std=self.config.bb_std, append=True) - bbp = candles_df[f"BBP_{self.config.bb_length}_{self.config.bb_std}"] - - candles_df["spread_multiplier"] = natr - candles_df["price_multiplier"] = bbp - return candles_df - - def get_position_config(self, order_level: OrderLevel) -> PositionConfig: - """ - Creates a PositionConfig object from an OrderLevel object. - Here you can use technical indicators to determine the parameters of the position config. - """ - close_price = self.get_close_price(self.config.exchange, self.config.trading_pair) - bbp, spread_multiplier = self.get_price_and_spread_multiplier() - side_multiplier = -1 if order_level.side == TradeType.BUY else 1 - - if (bbp > 0.7 and side_multiplier == 1) or (bbp < 0.3 and side_multiplier == -1): - order_price = close_price * (1 + order_level.spread_factor * spread_multiplier * side_multiplier) - amount = order_level.order_amount_usd / order_price - if order_level.triple_barrier_conf.trailing_stop_trailing_delta and order_level.triple_barrier_conf.trailing_stop_trailing_delta: - trailing_stop = TrailingStop( - activation_price_delta=order_level.triple_barrier_conf.trailing_stop_activation_price_delta, - trailing_delta=order_level.triple_barrier_conf.trailing_stop_trailing_delta, - ) - else: - trailing_stop = None - position_config = PositionConfig( - timestamp=time.time(), - trading_pair=self.config.trading_pair, - exchange=self.config.exchange, - side=order_level.side, - amount=amount, - take_profit=order_level.triple_barrier_conf.take_profit, - stop_loss=order_level.triple_barrier_conf.stop_loss, - time_limit=order_level.triple_barrier_conf.time_limit, - entry_price=Decimal(order_price), - open_order_type=order_level.triple_barrier_conf.open_order_type, - take_profit_order_type=order_level.triple_barrier_conf.take_profit_order_type, - trailing_stop=trailing_stop, - leverage=self.config.leverage - ) - return position_config diff --git a/quants_lab/controllers/dman_v1.py b/quants_lab/controllers/dman_v1.py index 23b90b76..782e0555 100644 --- a/quants_lab/controllers/dman_v1.py +++ b/quants_lab/controllers/dman_v1.py @@ -68,13 +68,14 @@ def get_position_config(self, order_level: OrderLevel) -> PositionConfig: Creates a PositionConfig object from an OrderLevel object. Here you can use technical indicators to determine the parameters of the position config. """ - close_price = self.get_close_price(self.config.exchange, self.config.trading_pair) - amount = order_level.order_amount_usd / close_price - price_multiplier, spread_multiplier, side_filter = self.get_price_and_spread_multiplier() + close_price = self.get_close_price(self.config.trading_pair) + price_multiplier, spread_multiplier = self.get_price_and_spread_multiplier() price_adjusted = close_price * (1 + price_multiplier) side_multiplier = -1 if order_level.side == TradeType.BUY else 1 order_price = price_adjusted * (1 + order_level.spread_factor * spread_multiplier * side_multiplier) + amount = order_level.order_amount_usd / order_price + if order_level.triple_barrier_conf.trailing_stop_trailing_delta and order_level.triple_barrier_conf.trailing_stop_trailing_delta: trailing_stop = TrailingStop( activation_price_delta=order_level.triple_barrier_conf.trailing_stop_activation_price_delta, diff --git a/quants_lab/controllers/dman_v2.py b/quants_lab/controllers/dman_v2.py index e220352b..402d4793 100644 --- a/quants_lab/controllers/dman_v2.py +++ b/quants_lab/controllers/dman_v2.py @@ -80,13 +80,13 @@ def get_position_config(self, order_level: OrderLevel) -> PositionConfig: Creates a PositionConfig object from an OrderLevel object. Here you can use technical indicators to determine the parameters of the position config. """ - close_price = self.get_close_price(self.config.exchange, self.config.trading_pair) - amount = order_level.order_amount_usd / close_price + close_price = self.get_close_price(self.config.trading_pair) price_multiplier, spread_multiplier = self.get_price_and_spread_multiplier() price_adjusted = close_price * (1 + price_multiplier) side_multiplier = -1 if order_level.side == TradeType.BUY else 1 order_price = price_adjusted * (1 + order_level.spread_factor * spread_multiplier * side_multiplier) + amount = order_level.order_amount_usd / order_price if order_level.triple_barrier_conf.trailing_stop_trailing_delta and order_level.triple_barrier_conf.trailing_stop_trailing_delta: trailing_stop = TrailingStop( activation_price_delta=order_level.triple_barrier_conf.trailing_stop_activation_price_delta, diff --git a/quants_lab/controllers/dman_v3.py b/quants_lab/controllers/dman_v3.py index becf17ad..caea6f2f 100644 --- a/quants_lab/controllers/dman_v3.py +++ b/quants_lab/controllers/dman_v3.py @@ -17,11 +17,17 @@ class DManV3Config(MarketMakingControllerConfigBase): strategy_name: str = "dman_v3" bb_length: int = 100 bb_std: float = 2.0 + side_filter: bool = False + smart_activation: bool = False + activation_threshold: Decimal = Decimal("0.001") + dynamic_spread_factor: bool = True + dynamic_target_spread: bool = False class DManV3(MarketMakingControllerBase): """ - Directional Market Making Strategy making use of NATR indicator to make spreads dynamic and shift the mid price. + Mean reversion strategy with Grid execution making use of Bollinger Bands indicator to make spreads dynamic + and shift the mid price. """ def __init__(self, config: DManV3Config): @@ -60,8 +66,8 @@ def get_processed_data(self): candles_df = self.candles[0].candles_df bbp = ta.bbands(candles_df["close"], length=self.config.bb_length, std=self.config.bb_std) - candles_df["spread_multiplier"] = bbp[f"BBB_{self.config.bb_length}_{self.config.bb_std}"] / 200 candles_df["price_multiplier"] = bbp[f"BBM_{self.config.bb_length}_{self.config.bb_std}"] + candles_df["spread_multiplier"] = bbp[f"BBB_{self.config.bb_length}_{self.config.bb_std}"] / 200 return candles_df def get_position_config(self, order_level: OrderLevel) -> PositionConfig: @@ -69,18 +75,35 @@ def get_position_config(self, order_level: OrderLevel) -> PositionConfig: Creates a PositionConfig object from an OrderLevel object. Here you can use technical indicators to determine the parameters of the position config. """ - close_price = self.get_close_price(self.config.exchange, self.config.trading_pair) + close_price = self.get_close_price(self.config.trading_pair) - amount = order_level.order_amount_usd / close_price - price_multiplier, spread_multiplier = self.get_price_and_spread_multiplier() + bollinger_mid_price, spread_multiplier = self.get_price_and_spread_multiplier() + if not self.config.dynamic_spread_factor: + spread_multiplier = 1 side_multiplier = -1 if order_level.side == TradeType.BUY else 1 - order_spread_multiplier = order_level.spread_factor * spread_multiplier * side_multiplier - order_price = price_multiplier * (1 + order_spread_multiplier) + order_price = bollinger_mid_price * (1 + order_spread_multiplier) + amount = order_level.order_amount_usd / order_price + + # Avoid placing the order from the opposite side + side_filter_condition = self.config.side_filter and ( + (bollinger_mid_price > close_price and side_multiplier == 1) or + (bollinger_mid_price < close_price and side_multiplier == -1)) + if side_filter_condition: + return + + # Smart activation of orders + smart_activation_condition = self.config.smart_activation and ( + side_multiplier == 1 and (close_price < order_price * (1 + self.config.activation_threshold)) or + (side_multiplier == -1 and (close_price > order_price * (1 - self.config.activation_threshold)))) + if smart_activation_condition: + return + + target_spread = spread_multiplier if self.config.dynamic_target_spread else 1 if order_level.triple_barrier_conf.trailing_stop_trailing_delta and order_level.triple_barrier_conf.trailing_stop_trailing_delta: trailing_stop = TrailingStop( - activation_price_delta=order_level.triple_barrier_conf.trailing_stop_activation_price_delta, - trailing_delta=order_level.triple_barrier_conf.trailing_stop_trailing_delta, + activation_price_delta=order_level.triple_barrier_conf.trailing_stop_activation_price_delta * target_spread, + trailing_delta=order_level.triple_barrier_conf.trailing_stop_trailing_delta * target_spread, ) else: trailing_stop = None @@ -90,8 +113,8 @@ def get_position_config(self, order_level: OrderLevel) -> PositionConfig: exchange=self.config.exchange, side=order_level.side, amount=amount, - take_profit=order_level.triple_barrier_conf.take_profit, - stop_loss=order_level.triple_barrier_conf.stop_loss, + take_profit=order_level.triple_barrier_conf.take_profit * target_spread, + stop_loss=order_level.triple_barrier_conf.stop_loss * target_spread, time_limit=order_level.triple_barrier_conf.time_limit, entry_price=Decimal(order_price), open_order_type=order_level.triple_barrier_conf.open_order_type, diff --git a/quants_lab/controllers/macd_bb_v1.py b/quants_lab/controllers/macd_bb_v1.py index c709cf8f..834362f4 100644 --- a/quants_lab/controllers/macd_bb_v1.py +++ b/quants_lab/controllers/macd_bb_v1.py @@ -24,6 +24,9 @@ class MACDBBV1Config(DirectionalTradingControllerConfigBase): class MACDBBV1(DirectionalTradingControllerBase): + """ + Directional Market Making Strategy making use of NATR indicator to make spreads dynamic. + """ def __init__(self, config: MACDBBV1Config): super().__init__(config)