mirror of
https://github.com/aljazceru/hummingbot-dashboard.git
synced 2026-01-18 21:04:18 +01:00
Merge pull request #101 from hummingbot/feat/cleanup_controllers
Feat/cleanup controllers
This commit is contained in:
@@ -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
|
||||
@@ -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)
|
||||
@@ -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),
|
||||
],
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import time
|
||||
from typing import Optional
|
||||
|
||||
import pandas as pd
|
||||
import pandas_ta as ta
|
||||
|
||||
@@ -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
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user