Skip to content

Commit

Permalink
Merge pull request #29 from hummingbot/development
Browse files Browse the repository at this point in the history
sync / backend-api development -> main
  • Loading branch information
nikspz committed Aug 28, 2024
2 parents 4d88bd4 + 17a1dc1 commit a599a27
Show file tree
Hide file tree
Showing 31 changed files with 335 additions and 386 deletions.
24 changes: 24 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Bug Report
description: Create a bug report to help us improve
title: "Bug Report"
labels: bug
body:
- type: textarea
id: what-happened
attributes:
label: Describe the bug
description: A clear and concise description of the bug or issue.
placeholder: Tell us what happened? Please make sure to add all screenshots and error message to help us investigate.
validations:
required: true
- type: textarea
id: reproduce
attributes:
label: Steps to reproduce bug
placeholder: Exact steps to reproduce the buggy behavior
value: |
1.
2.
3.
validations:
required: true
35 changes: 35 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Feature request
description: Suggest an idea for this project 2.0
title: "Feature request"
labels: enhancement
body:
- type: markdown
attributes:
value: |
## **Before Submitting:**
* Please look on our GitHub issues to avoid duplicate tickets
* You can add additional `Labels` to triage this ticket
* For docs/ additional info please visit our [Discord server](https://discord.gg/hummingbot) and [Hummingbot docs](https://hummingbot.org/docs/)
- type: textarea
id: feature-suggestion
attributes:
label: Feature Suggestion
description: A clear and concise description of the feature request. If you have looked at the code and know exactly what code changes are needed then please consider submitting a pull request instead.
placeholder: How you want to achieve the desired behavior
validations:
required: true
- type: textarea
id: feature-impact
attributes:
label: Impact
description: A succinct description of why you want the desired behavior specified above.
placeholder: The desired behavior will allow me to..
validations:
required: true
validations:
required: true
- type: textarea
id: feature-additional-context
attributes:
label: Additional context
description: Add any other context or screenshots about the feature request here (optional)
80 changes: 80 additions & 0 deletions .github/workflows/docker_buildx_workflow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: Backend-API Docker Buildx Workflow

on:
pull_request:
types: [closed]
branches:
- main
- development
release:
types: [published, edited]

jobs:
build_pr:
if: github.event_name == 'pull_request' && github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/[email protected]

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/[email protected]

- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Build and push Development Image
if: github.base_ref == 'development'
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: hummingbot/backend-api:development

- name: Build and push Latest Image
if: github.base_ref == 'main'
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: hummingbot/backend-api:latest

build_release:
if: github.event_name == 'release'
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/[email protected]

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/[email protected]

- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Extract tag name
id: get_tag
run: echo ::set-output name=VERSION::${GITHUB_REF#refs/tags/}

- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: hummingbot/backend-api:${{ steps.get_tag.outputs.VERSION }}
33 changes: 33 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.3.0
hooks:
- id: detect-private-key

- repo: https://github.com/pre-commit/mirrors-eslint
rev: v8.10.0
hooks:
- id: eslint
files: \.[jt]sx?$ # *.js, *.jsx, *.ts and *.tsx
types: [file]

- repo: https://github.com/CoinAlpha/git-hooks
rev: 78f0683233a09c68a072fd52740d32c0376d4f0f
hooks:
- id: detect-wallet-private-key
types: [file]
exclude: .json

- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
files: "\\.(py)$"
args: [--settings-path=pyproject.toml]

- repo: https://github.com/pycqa/flake8
rev: 3.9.2
hooks:
- id: flake8
additional_dependencies: ['flake8']
args: [--max-line-length=130]
17 changes: 3 additions & 14 deletions bots/controllers/directional_trading/bollinger_v1.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,20 @@
from typing import List

import pandas_ta as ta # noqa: F401
from pydantic import Field, validator

from hummingbot.client.config.config_data_types import ClientFieldData
from hummingbot.data_feed.candles_feed.data_types import CandlesConfig
from hummingbot.strategy_v2.controllers.directional_trading_controller_base import (
DirectionalTradingControllerBase,
DirectionalTradingControllerConfigBase,
)
from pydantic import Field, validator


class BollingerV1ControllerConfig(DirectionalTradingControllerConfigBase):
controller_name = "bollinger_v1"
candles_config: List[CandlesConfig] = []
candles_connector: str = Field(
default=None,
client_data=ClientFieldData(
prompt_on_new=True,
prompt=lambda mi: "Enter the connector for the candles data, leave empty to use the same exchange as the connector: ", )
)
candles_trading_pair: str = Field(
default=None,
client_data=ClientFieldData(
prompt_on_new=True,
prompt=lambda mi: "Enter the trading pair for the candles data, leave empty to use the same trading pair as the connector: ", )
)
candles_connector: str = Field(default=None)
candles_trading_pair: str = Field(default=None)
interval: str = Field(
default="3m",
client_data=ClientFieldData(
Expand Down
34 changes: 14 additions & 20 deletions bots/controllers/directional_trading/dman_v3.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
from typing import List, Optional, Tuple

import pandas_ta as ta # noqa: F401
from pydantic import Field, validator

from hummingbot.client.config.config_data_types import ClientFieldData
from hummingbot.core.data_type.common import TradeType
from hummingbot.data_feed.candles_feed.data_types import CandlesConfig
Expand All @@ -14,23 +12,14 @@
)
from hummingbot.strategy_v2.executors.dca_executor.data_types import DCAExecutorConfig, DCAMode
from hummingbot.strategy_v2.executors.position_executor.data_types import TrailingStop
from pydantic import Field, validator


class DManV3ControllerConfig(DirectionalTradingControllerConfigBase):
controller_name: str = "dman_v3"
candles_config: List[CandlesConfig] = []
candles_connector: str = Field(
default=None,
client_data=ClientFieldData(
prompt_on_new=True,
prompt=lambda mi: "Enter the connector for the candles data, leave empty to use the same exchange as the connector: ",)
)
candles_trading_pair: str = Field(
default=None,
client_data=ClientFieldData(
prompt_on_new=True,
prompt=lambda mi: "Enter the trading pair for the candles data, leave empty to use the same trading pair as the connector: ",)
)
candles_connector: str = Field(default=None)
candles_trading_pair: str = Field(default=None)
interval: str = Field(
default="30m",
client_data=ClientFieldData(
Expand Down Expand Up @@ -61,9 +50,10 @@ class DManV3ControllerConfig(DirectionalTradingControllerConfigBase):
dca_spreads: List[Decimal] = Field(
default="0.001,0.018,0.15,0.25",
client_data=ClientFieldData(
prompt=lambda mi: "Enter the spreads for each DCA level (comma-separated) if dynamic_spread=True this value "
"will multiply the Bollinger Bands width, e.g. if the Bollinger Bands width is 0.1 (10%)"
"and the spread is 0.2, the distance of the order to the current price will be 0.02 (2%) ",
prompt=lambda
mi: "Enter the spreads for each DCA level (comma-separated) if dynamic_spread=True this value "
"will multiply the Bollinger Bands width, e.g. if the Bollinger Bands width is 0.1 (10%)"
"and the spread is 0.2, the distance of the order to the current price will be 0.02 (2%) ",
prompt_on_new=True))
dca_amounts_pct: List[Decimal] = Field(
default=None,
Expand Down Expand Up @@ -119,7 +109,9 @@ def validate_amounts(cls, v, values):
return [Decimal('1.0') / len(spreads) for _ in spreads]
return v

def get_spreads_and_amounts_in_quote(self, trade_type: TradeType, total_amount_quote: Decimal) -> Tuple[List[Decimal], List[Decimal]]:
def get_spreads_and_amounts_in_quote(self,
trade_type: TradeType,
total_amount_quote: Decimal) -> Tuple[List[Decimal], List[Decimal]]:
amounts_pct = self.dca_amounts_pct
if amounts_pct is None:
# Equally distribute if amounts_pct is not set
Expand Down Expand Up @@ -151,6 +143,7 @@ class DManV3Controller(DirectionalTradingControllerBase):
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: DManV3ControllerConfig, *args, **kwargs):
self.config = config
self.max_records = config.bb_length
Expand Down Expand Up @@ -201,8 +194,9 @@ def get_executor_config(self, trade_type: TradeType, price: Decimal, amount: Dec
prices = [price * (1 + spread * spread_multiplier) for spread in spread]
if self.config.dynamic_target:
stop_loss = self.config.stop_loss * spread_multiplier
trailing_stop = TrailingStop(activation_price=self.config.trailing_stop.activation_price * spread_multiplier,
trailing_delta=self.config.trailing_stop.trailing_delta * spread_multiplier)
trailing_stop = TrailingStop(
activation_price=self.config.trailing_stop.activation_price * spread_multiplier,
trailing_delta=self.config.trailing_stop.trailing_delta * spread_multiplier)
else:
stop_loss = self.config.stop_loss
trailing_stop = self.config.trailing_stop
Expand Down
17 changes: 3 additions & 14 deletions bots/controllers/directional_trading/macd_bb_v1.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,20 @@
from typing import List

import pandas_ta as ta # noqa: F401
from pydantic import Field, validator

from hummingbot.client.config.config_data_types import ClientFieldData
from hummingbot.data_feed.candles_feed.data_types import CandlesConfig
from hummingbot.strategy_v2.controllers.directional_trading_controller_base import (
DirectionalTradingControllerBase,
DirectionalTradingControllerConfigBase,
)
from pydantic import Field, validator


class MACDBBV1ControllerConfig(DirectionalTradingControllerConfigBase):
controller_name = "macd_bb_v1"
candles_config: List[CandlesConfig] = []
candles_connector: str = Field(
default=None,
client_data=ClientFieldData(
prompt_on_new=True,
prompt=lambda mi: "Enter the connector for the candles data, leave empty to use the same exchange as the connector: ", )
)
candles_trading_pair: str = Field(
default=None,
client_data=ClientFieldData(
prompt_on_new=True,
prompt=lambda mi: "Enter the trading pair for the candles data, leave empty to use the same trading pair as the connector: ", )
)
candles_connector: str = Field(default=None)
candles_trading_pair: str = Field(default=None)
interval: str = Field(
default="3m",
client_data=ClientFieldData(
Expand Down
28 changes: 17 additions & 11 deletions bots/controllers/directional_trading/supertrend_v1.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
from typing import List, Optional

import pandas_ta as ta # noqa: F401
from pydantic import Field, validator

from hummingbot.client.config.config_data_types import ClientFieldData
from hummingbot.data_feed.candles_feed.data_types import CandlesConfig
from hummingbot.strategy_v2.controllers.directional_trading_controller_base import (
DirectionalTradingControllerBase,
DirectionalTradingControllerConfigBase,
)
from pydantic import Field, validator


class SuperTrendConfig(DirectionalTradingControllerConfigBase):
controller_name: str = "supertrend_v1"
candles_config: List[CandlesConfig] = []
candles_connector: Optional[str] = Field(default=None, client_data=ClientFieldData(prompt_on_new=True, prompt=lambda mi: "Enter the connector for the candles data, leave empty to use the same exchange as the connector: ", ))
candles_trading_pair: Optional[str] = Field(default=None, client_data=ClientFieldData(prompt_on_new=True, prompt=lambda mi: "Enter the trading pair for the candles data, leave empty to use the same trading pair as the connector: ", ))
interval: str = Field(default="3m", client_data=ClientFieldData(prompt=lambda mi: "Enter the candle interval (e.g., 1m, 5m, 1h, 1d): ", prompt_on_new=False))
length: int = Field(default=20, client_data=ClientFieldData(prompt=lambda mi: "Enter the supertrend length: ", prompt_on_new=True))
multiplier: float = Field(default=4.0, client_data=ClientFieldData(prompt=lambda mi: "Enter the supertrend multiplier: ", prompt_on_new=True))
percentage_threshold: float = Field(default=0.01, client_data=ClientFieldData(prompt=lambda mi: "Enter the percentage threshold: ", prompt_on_new=True))
candles_connector: Optional[str] = Field(default=None)
candles_trading_pair: Optional[str] = Field(default=None)
interval: str = Field(default="3m")
length: int = Field(default=20, client_data=ClientFieldData(prompt=lambda mi: "Enter the supertrend length: ",
prompt_on_new=True))
multiplier: float = Field(default=4.0,
client_data=ClientFieldData(prompt=lambda mi: "Enter the supertrend multiplier: ",
prompt_on_new=True))
percentage_threshold: float = Field(default=0.01, client_data=ClientFieldData(
prompt=lambda mi: "Enter the percentage threshold: ", prompt_on_new=True))

@validator("candles_connector", pre=True, always=True)
def set_candles_connector(cls, v, values):
Expand Down Expand Up @@ -54,11 +57,14 @@ async def update_processed_data(self):
max_records=self.max_records)
# Add indicators
df.ta.supertrend(length=self.config.length, multiplier=self.config.multiplier, append=True)
df["percentage_distance"] = abs(df["close"] - df[f"SUPERT_{self.config.length}_{self.config.multiplier}"]) / df["close"]
df["percentage_distance"] = abs(df["close"] - df[f"SUPERT_{self.config.length}_{self.config.multiplier}"]) / df[
"close"]

# Generate long and short conditions
long_condition = (df[f"SUPERTd_{self.config.length}_{self.config.multiplier}"] == 1) & (df["percentage_distance"] < self.config.percentage_threshold)
short_condition = (df[f"SUPERTd_{self.config.length}_{self.config.multiplier}"] == -1) & (df["percentage_distance"] < self.config.percentage_threshold)
long_condition = (df[f"SUPERTd_{self.config.length}_{self.config.multiplier}"] == 1) & (
df["percentage_distance"] < self.config.percentage_threshold)
short_condition = (df[f"SUPERTd_{self.config.length}_{self.config.multiplier}"] == -1) & (
df["percentage_distance"] < self.config.percentage_threshold)

# Choose side
df['signal'] = 0
Expand Down
Loading

0 comments on commit a599a27

Please sign in to comment.