mirror of
https://github.com/aljazceru/hummingbot-dashboard.git
synced 2025-12-21 23:44:19 +01:00
(feat) improve performance card and add logs
This commit is contained in:
@@ -1,17 +1,17 @@
|
||||
import time
|
||||
|
||||
import pandas as pd
|
||||
import streamlit as st
|
||||
from hummingbot.strategy_v2.models.executors import CloseType
|
||||
from streamlit_elements import mui
|
||||
|
||||
from CONFIG import BACKEND_API_HOST, BACKEND_API_PORT
|
||||
from frontend.components.dashboard import Dashboard
|
||||
|
||||
from backend.services.backend_api_client import BackendAPIClient
|
||||
from frontend.st_utils import get_backend_api_client
|
||||
|
||||
TRADES_TO_SHOW = 5
|
||||
WIDE_COL_WIDTH = 250
|
||||
MEDIUM_COL_WIDTH = 170
|
||||
SMALL_COL_WIDTH = 100
|
||||
ULTRA_WIDE_COL_WIDTH = 300
|
||||
WIDE_COL_WIDTH = 160
|
||||
MEDIUM_COL_WIDTH = 140
|
||||
SMALL_COL_WIDTH = 110
|
||||
backend_api_client = get_backend_api_client()
|
||||
|
||||
|
||||
@@ -27,12 +27,16 @@ def archive_bot(bot_name):
|
||||
class BotPerformanceCardV2(Dashboard.Item):
|
||||
DEFAULT_COLUMNS = [
|
||||
{"field": 'id', "headerName": 'ID', "width": WIDE_COL_WIDTH},
|
||||
{"field": 'controller', "headerName": 'Controller', "width": SMALL_COL_WIDTH, "editable": False},
|
||||
{"field": 'connector', "headerName": 'Connector', "width": SMALL_COL_WIDTH, "editable": False},
|
||||
{"field": 'trading_pair', "headerName": 'Trading Pair', "width": SMALL_COL_WIDTH, "editable": False},
|
||||
{"field": 'realized_pnl_quote', "headerName": 'Realized PNL ($)', "width": MEDIUM_COL_WIDTH, "editable": False},
|
||||
{"field": 'unrealized_pnl_quote', "headerName": 'Unrealized PNL ($)', "width": MEDIUM_COL_WIDTH, "editable": False},
|
||||
{"field": 'global_pnl_quote', "headerName": 'NET PNL ($)', "width": MEDIUM_COL_WIDTH, "editable": False},
|
||||
{"field": 'volume_traded', "headerName": 'Volume ($)', "width": MEDIUM_COL_WIDTH, "editable": False},
|
||||
{"field": 'open_order_volume', "headerName": 'Open Order Volume ($)', "width": MEDIUM_COL_WIDTH, "editable": False},
|
||||
{"field": 'imbalance', "headerName": 'Imbalance ($)', "width": MEDIUM_COL_WIDTH, "editable": False},
|
||||
{"field": 'volume_traded', "headerName": 'Volume ($)', "width": SMALL_COL_WIDTH, "editable": False},
|
||||
{"field": 'open_order_volume', "headerName": 'Liquidity Placed ($)', "width": MEDIUM_COL_WIDTH, "editable": False},
|
||||
{"field": 'imbalance', "headerName": 'Imbalance ($)', "width": SMALL_COL_WIDTH, "editable": False},
|
||||
{"field": 'close_types', "headerName": 'Close Types', "width": ULTRA_WIDE_COL_WIDTH, "editable": False}
|
||||
]
|
||||
_active_controller_config_selected = []
|
||||
_stopped_controller_config_selected = []
|
||||
@@ -89,6 +93,8 @@ class BotPerformanceCardV2(Dashboard.Item):
|
||||
bot_data = bot_status.get("data")
|
||||
is_running = bot_data.get("status") == "running"
|
||||
performance = bot_data.get("performance")
|
||||
error_logs = bot_data.get("error_logs")
|
||||
general_logs = bot_data.get("general_logs")
|
||||
if is_running:
|
||||
for controller, inner_dict in performance.items():
|
||||
controller_status = inner_dict.get("status")
|
||||
@@ -98,6 +104,9 @@ class BotPerformanceCardV2(Dashboard.Item):
|
||||
continue
|
||||
controller_performance = inner_dict.get("performance")
|
||||
controller_config = next((config for config in controller_configs if config.get("id") == controller), {})
|
||||
controller_name = controller_config.get("controller_name", controller)
|
||||
connector_name = controller_config.get("connector_name", "NaN")
|
||||
trading_pair = controller_config.get("trading_pair", "NaN")
|
||||
kill_switch_status = True if controller_config.get("manual_kill_switch") is True else False
|
||||
realized_pnl_quote = controller_performance.get("realized_pnl_quote", 0)
|
||||
unrealized_pnl_quote = controller_performance.get("unrealized_pnl_quote", 0)
|
||||
@@ -105,14 +114,25 @@ class BotPerformanceCardV2(Dashboard.Item):
|
||||
volume_traded = controller_performance.get("volume_traded", 0)
|
||||
open_order_volume = controller_performance.get("open_order_volume", 0)
|
||||
imbalance = controller_performance.get("imbalance", 0)
|
||||
close_types = controller_performance.get("close_type_counts", {})
|
||||
tp = close_types.get("CloseType.TAKE_PROFIT", 0)
|
||||
sl = close_types.get("CloseType.STOP_LOSS", 0)
|
||||
time_limit = close_types.get("CloseType.TIME_LIMIT", 0)
|
||||
ts = close_types.get("CloseType.TRAILING_STOP", 0)
|
||||
refreshed = close_types.get("CloseType.EARLY_STOP", 0)
|
||||
close_types_str = f"TP: {tp} | SL: {sl} | TS: {ts} | TL: {time_limit} | RS: {refreshed}"
|
||||
controller_info = {
|
||||
"id": controller,
|
||||
"realized_pnl_quote": realized_pnl_quote,
|
||||
"unrealized_pnl_quote": unrealized_pnl_quote,
|
||||
"global_pnl_quote": global_pnl_quote,
|
||||
"volume_traded": volume_traded,
|
||||
"open_order_volume": open_order_volume,
|
||||
"imbalance": imbalance,
|
||||
"controller": controller_name,
|
||||
"connector": connector_name,
|
||||
"trading_pair": trading_pair,
|
||||
"realized_pnl_quote": round(realized_pnl_quote, 2),
|
||||
"unrealized_pnl_quote": round(unrealized_pnl_quote, 2),
|
||||
"global_pnl_quote": round(global_pnl_quote, 2),
|
||||
"volume_traded": round(volume_traded, 2),
|
||||
"open_order_volume": round(open_order_volume, 2),
|
||||
"imbalance": round(imbalance, 2),
|
||||
"close_types": close_types_str,
|
||||
}
|
||||
if kill_switch_status:
|
||||
stopped_controllers_list.append(controller_info)
|
||||
@@ -270,6 +290,30 @@ class BotPerformanceCardV2(Dashboard.Item):
|
||||
sx={"width": "100%", "height": "100%"}):
|
||||
mui.icon.AddCircleOutline()
|
||||
mui.Typography("Stop")
|
||||
with mui.Accordion(sx={"padding": "10px 15px 10px 15px"}):
|
||||
with mui.AccordionSummary(expandIcon=mui.icon.ExpandMoreIcon()):
|
||||
mui.Typography("Error Logs")
|
||||
with mui.AccordionDetails(sx={"display": "flex", "flexDirection": "column"}):
|
||||
if len(error_logs) > 0:
|
||||
for log in error_logs:
|
||||
timestamp = log.get("timestamp")
|
||||
message = log.get("msg")
|
||||
logger_name = log.get("logger_name")
|
||||
mui.Typography(f"{timestamp} - {logger_name}: {message}")
|
||||
else:
|
||||
mui.Typography("No error logs available.")
|
||||
with mui.Accordion(sx={"padding": "10px 15px 10px 15px"}):
|
||||
with mui.AccordionSummary(expandIcon=mui.icon.ExpandMoreIcon()):
|
||||
mui.Typography("General Logs")
|
||||
with mui.AccordionDetails(sx={"display": "flex", "flexDirection": "column"}):
|
||||
if len(general_logs) > 0:
|
||||
for log in general_logs:
|
||||
timestamp = pd.to_datetime(int(log.get("timestamp")), unit="s")
|
||||
message = log.get("msg")
|
||||
logger_name = log.get("logger_name")
|
||||
mui.Typography(f"{timestamp} - {logger_name}: {message}")
|
||||
else:
|
||||
mui.Typography("No general logs available.")
|
||||
except Exception as e:
|
||||
print(e)
|
||||
with mui.Card(key=self._key,
|
||||
|
||||
Reference in New Issue
Block a user