Skip to content

Commit

Permalink
Merge pull request #171 from hummingbot/development
Browse files Browse the repository at this point in the history
sync / Dashboard development -> main
  • Loading branch information
nikspz authored Aug 28, 2024
2 parents 876302a + 22b3116 commit b0e6494
Show file tree
Hide file tree
Showing 108 changed files with 694 additions and 117,028 deletions.
75 changes: 54 additions & 21 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,47 +1,80 @@
name: Build and Push Docker image
name: Dashboard Docker Buildx Workflow

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

jobs:
build:
build_pr:
if: github.event_name == 'pull_request' && github.event.pull_request.merged == true
runs-on: ubuntu-latest
if: github.event.pull_request.merged == true
steps:
- name: Checkout code
uses: actions/checkout@v3.5.3
uses: actions/checkout@v4.1.1

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

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

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

- name: Build and push
id: docker_build
uses: docker/[email protected]
- 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/dashboard: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/dashboard: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
build-args: |
BRANCH=${{ github.ref }}
COMMIT=${{ github.sha }}
BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
cache-from: type=registry,ref=hummingbot/dashboard:latest
cache-to: type=inline

- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}
push: true
tags: hummingbot/dashboard:${{ 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]
7 changes: 3 additions & 4 deletions CONFIG.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@

from dotenv import load_dotenv


load_dotenv()

MINER_COINS = ["Algorand", "Avalanche", "DAO Maker", "Faith Tribe", "Fear", "Frontier",
"Harmony", "Hot Cross", "HUMAN Protocol", "Oddz", "Shera", "Firo",
"Vesper Finance", "Youclout", "Nimiq"]
"Harmony", "Hot Cross", "HUMAN Protocol", "Oddz", "Shera", "Firo",
"Vesper Finance", "Youclout", "Nimiq"]
MINER_EXCHANGES = ["Binance", "FTX", "Coinbase Exchange", "Huobi Global", "OKX", "KuCoin",
"Kraken", "Bybit (Spot)", "FTX.US", "Crypto.com Exchange", "Binance US",
"MEXC Global", "Gate.io", "BitMart", "Bitfinex", "AscendEX (BitMax)",
Expand All @@ -18,7 +17,7 @@
CERTIFIED_EXCHANGES = ["ascendex", "binance", "bybit", "gate.io", "hitbtc", "huobi", "kucoin", "okx", "gateway"]
CERTIFIED_STRATEGIES = ["xemm", "cross exchange market making", "pmm", "pure market making"]

AUTH_SYSTEM_ENABLED = False
AUTH_SYSTEM_ENABLED = os.getenv("AUTH_SYSTEM_ENABLED", "False").lower() in ("true", "1", "t")

BACKEND_API_HOST = os.getenv("BACKEND_API_HOST", "127.0.0.1")
BACKEND_API_PORT = os.getenv("BACKEND_API_PORT", 8000)
36 changes: 33 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,19 +1,49 @@
.ONESHELL:
.SHELLFLAGS := -c

.PHONY: run
.PHONY: uninstall
.PHONY: install
.PHONY: install-pre-commit
.PHONY: docker_build
.PHONY: docker_run


detect_conda_bin := $(shell bash -c 'if [ "${CONDA_EXE} " == " " ]; then \
CONDA_EXE=$$((find /opt/conda/bin/conda || find ~/anaconda3/bin/conda || \
find /usr/local/anaconda3/bin/conda || find ~/miniconda3/bin/conda || \
find /root/miniconda/bin/conda || find ~/Anaconda3/Scripts/conda || \
find $$CONDA/bin/conda) 2>/dev/null); fi; \
if [ "${CONDA_EXE}_" == "_" ]; then \
echo "Please install Anaconda w/ Python 3.10+ first"; \
echo "See: https://www.anaconda.com/distribution/"; \
exit 1; fi; \
echo $$(dirname $${CONDA_EXE})')

CONDA_BIN := $(detect_conda_bin)

run:
streamlit run main.py
streamlit run main.py --server.headless true

uninstall:
conda env remove -n dashboard

install:
conda env create -f environment_conda.yml
if conda env list | grep -q '^dashboard '; then \
echo "Environment already exists."; \
else \
conda env create -f environment_conda.yml; \
fi
$(MAKE) install-pre-commit

install-pre-commit:
/bin/bash -c 'source "${CONDA_BIN}/activate" dashboard && \
if ! conda list pre-commit | grep pre-commit &> /dev/null; then \
pip install pre-commit; \
fi && pre-commit install'

docker_build:
docker build -t hummingbot/dashboard:latest .

docker_run:
docker run -p 8501:8501 dashboard:latest
docker run -p 8501:8501 hummingbot/dashboard:latest
5 changes: 3 additions & 2 deletions backend/services/backend_api_client.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Optional, Dict
from typing import Dict, Optional

import pandas as pd
import requests
Expand Down Expand Up @@ -115,7 +115,8 @@ def start_bot(self, start_bot_config: dict):
def stop_bot(self, bot_name: str, skip_order_cancellation: bool = False, async_backend: bool = True):
"""Stop a Hummingbot bot."""
endpoint = "stop-bot"
return self.post(endpoint, payload={"bot_name": bot_name, "skip_order_cancellation": skip_order_cancellation, "async_backend": async_backend})
return self.post(endpoint, payload={"bot_name": bot_name, "skip_order_cancellation": skip_order_cancellation,
"async_backend": async_backend})

def import_strategy(self, strategy_config: dict):
"""Import a trading strategy to a bot."""
Expand Down
4 changes: 2 additions & 2 deletions backend/services/coingecko_client.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import re
import time

from pycoingecko import CoinGeckoAPI
import pandas as pd
import re
from pycoingecko import CoinGeckoAPI


class CoinGeckoClient:
Expand Down
2 changes: 1 addition & 1 deletion backend/services/miner_client.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pandas as pd
import requests
from glom import *
from glom import glom


class MinerClient:
Expand Down
14 changes: 1 addition & 13 deletions backend/utils/optuna_database_manager.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import os
import json
import os
from typing import Optional

import pandas as pd
Expand Down Expand Up @@ -102,18 +102,6 @@ def _get_trial_system_attributes_table(self):
except Exception as e:
return f"Error: {str(e)}"

@property
def trial_system_attributes(self):
return self._get_trial_system_attributes_table()

def _get_trial_system_attributes_table(self):
try:
with self.session_maker() as session:
df = pd.read_sql_query(text("SELECT * FROM trial_system_attributes"), session.connection())
return df
except Exception as e:
return f"Error: {str(e)}"

@property
def version_info(self):
return self._get_version_info_table()
Expand Down
13 changes: 9 additions & 4 deletions backend/utils/os_utils.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import glob
import subprocess
import importlib.util
import inspect
import os
import subprocess

import pandas as pd

import yaml
from hummingbot.strategy_v2.controllers.directional_trading_controller_base import DirectionalTradingControllerBase, DirectionalTradingControllerConfigBase
from hummingbot.strategy_v2.controllers.market_making_controller_base import MarketMakingControllerBase, MarketMakingControllerConfigBase
from hummingbot.strategy_v2.controllers.directional_trading_controller_base import (
DirectionalTradingControllerBase,
DirectionalTradingControllerConfigBase,
)
from hummingbot.strategy_v2.controllers.market_making_controller_base import (
MarketMakingControllerBase,
MarketMakingControllerConfigBase,
)


def remove_files_from_directory(directory: str):
Expand Down
13 changes: 7 additions & 6 deletions credentials.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
cookie:
expiry_days: 30
key: random_signature_key
name: random_cookie_name
credentials:
usernames:
admin:
email: [email protected]
name: Admin User
password: abc # To be replaced with hashed password: hashed_passwords = stauth.Hasher(['abc', 'def']).generate()
preauthorized: # the preferred way to add users since there is no need for manual hashing of passwords
logged_in: False
password: abc
cookie:
expiry_days: 0
key: some_signature_key # Must be string
name: some_cookie_name
pre-authorized:
emails:
- [email protected]
3 changes: 3 additions & 0 deletions environment_conda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@ dependencies:
- streamlit-elements==0.1.*
- streamlit-authenticator
- pydantic==1.10.4
- flake8
- isort
- pre-commit
11 changes: 6 additions & 5 deletions frontend/components/backtesting.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import streamlit as st
from datetime import datetime, timedelta

import streamlit as st


def backtesting_section(inputs, backend_api_client):
st.write("### Backtesting")
Expand All @@ -13,7 +14,8 @@ def backtesting_section(inputs, backend_api_client):
end_date = st.date_input("End Date", default_end_time,
help="End date is inclusive, make sure that you are not including the current date.")
with c3:
backtesting_resolution = st.selectbox("Backtesting Resolution", options=["1m", "3m", "5m", "15m", "30m", "1h", "1s"], index=0)
backtesting_resolution = st.selectbox("Backtesting Resolution",
options=["1m", "3m", "5m", "15m", "30m", "1h", "1s"], index=0)
with c4:
trade_cost = st.number_input("Trade Cost (%)", min_value=0.0, value=0.06, step=0.01, format="%.2f")
with c5:
Expand All @@ -24,16 +26,15 @@ def backtesting_section(inputs, backend_api_client):
end_datetime = datetime.combine(end_date, datetime.max.time())
try:
backtesting_results = backend_api_client.run_backtesting(
start_time=int(start_datetime.timestamp()) * 1000,
end_time=int(end_datetime.timestamp()) * 1000,
start_time=int(start_datetime.timestamp()),
end_time=int(end_datetime.timestamp()),
backtesting_resolution=backtesting_resolution,
trade_cost=trade_cost / 100,
config=inputs,
)
except Exception as e:
st.error(e)
return None

if len(backtesting_results["processed_data"]) == 0:
st.error("No trades were executed during the backtesting period.")
return None
Expand Down
Loading

0 comments on commit b0e6494

Please sign in to comment.