Merge pull request #101 from hummingbot/feat/cleanup_controllers

Feat/cleanup controllers
This commit is contained in:
dardonacci
2023-11-24 17:22:29 -03:00
committed by GitHub
14 changed files with 314 additions and 832 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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),
],

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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
# 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
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,
)
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 = {}
@@ -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 @@ class DManV2MultiplePairs(ScriptStrategyBase):
# 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):
"""

View File

@@ -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)
# 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")
# 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),
)
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 = {}
@@ -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 @@ class DManV3MultiplePairs(ScriptStrategyBase):
# 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):
"""

View File

@@ -1,5 +1,4 @@
import time
from typing import Optional
import pandas as pd
import pandas_ta as ta

View File

@@ -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

View File

@@ -68,13 +68,14 @@ class DManV1(MarketMakingControllerBase):
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,

View File

@@ -80,13 +80,13 @@ class DManV2(MarketMakingControllerBase):
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,

View File

@@ -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 @@ class DManV3(MarketMakingControllerBase):
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 @@ class DManV3(MarketMakingControllerBase):
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 @@ class DManV3(MarketMakingControllerBase):
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,

View File

@@ -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)