mirror of
https://github.com/d0zingcat/deploy.git
synced 2026-05-13 15:09:33 +00:00
(feat) add orchestration pages
This commit is contained in:
0
pages/orchestration/__init__.py
Normal file
0
pages/orchestration/__init__.py
Normal file
19
pages/orchestration/credentials/README.md
Normal file
19
pages/orchestration/credentials/README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
### Description
|
||||
|
||||
This page helps you deploy and manage Hummingbot instances:
|
||||
|
||||
- Starting and stopping Hummingbot Broker
|
||||
- Creating, starting and stopping bot instances
|
||||
- Managing strategy and script files that instances run
|
||||
- Fetching status of running instances
|
||||
|
||||
### Maintainers
|
||||
|
||||
This page is maintained by Hummingbot Foundation as a template other pages:
|
||||
|
||||
* [cardosfede](https://github.com/cardosfede)
|
||||
* [fengtality](https://github.com/fengtality)
|
||||
|
||||
### Wiki
|
||||
|
||||
See the [wiki](https://github.com/hummingbot/dashboard/wiki/%F0%9F%90%99-Bot-Orchestration) for more information.
|
||||
0
pages/orchestration/credentials/__init__.py
Normal file
0
pages/orchestration/credentials/__init__.py
Normal file
106
pages/orchestration/credentials/app.py
Normal file
106
pages/orchestration/credentials/app.py
Normal file
@@ -0,0 +1,106 @@
|
||||
from CONFIG import BACKEND_API_HOST, BACKEND_API_PORT
|
||||
from backend.services.backend_api_client import BackendAPIClient
|
||||
from frontend.st_utils import initialize_st_page, get_backend_api_client
|
||||
import streamlit as st
|
||||
|
||||
|
||||
initialize_st_page(title="Credentials", icon="🔑")
|
||||
|
||||
# Page content
|
||||
client = get_backend_api_client()
|
||||
NUM_COLUMNS = 4
|
||||
|
||||
|
||||
@st.cache_data
|
||||
def get_all_connectors_config_map():
|
||||
return client.get_all_connectors_config_map()
|
||||
|
||||
# Section to display available accounts and credentials
|
||||
accounts = client.get_accounts()
|
||||
all_connector_config_map = get_all_connectors_config_map()
|
||||
st.header("Available Accounts and Credentials")
|
||||
|
||||
if accounts:
|
||||
n_accounts = len(accounts)
|
||||
accounts.remove("master_account")
|
||||
accounts.insert(0, "master_account")
|
||||
for i in range(0, n_accounts, NUM_COLUMNS):
|
||||
cols = st.columns(NUM_COLUMNS)
|
||||
for j, account in enumerate(accounts[i:i + NUM_COLUMNS]):
|
||||
with cols[j]:
|
||||
st.subheader(f"🏦 {account}")
|
||||
credentials = client.get_credentials(account)
|
||||
st.json(credentials)
|
||||
else:
|
||||
st.write("No accounts available.")
|
||||
|
||||
st.markdown("---")
|
||||
|
||||
c1, c2, c3 = st.columns([1, 1, 1])
|
||||
with c1:
|
||||
# Section to create a new account
|
||||
st.header("Create a New Account")
|
||||
new_account_name = st.text_input("New Account Name")
|
||||
if st.button("Create Account"):
|
||||
new_account_name = new_account_name.replace(" ", "_")
|
||||
if new_account_name:
|
||||
if new_account_name in accounts:
|
||||
st.warning(f"Account {new_account_name} already exists.")
|
||||
st.stop()
|
||||
elif new_account_name == "" or all(char == "_" for char in new_account_name):
|
||||
st.warning("Please enter a valid account name.")
|
||||
st.stop()
|
||||
response = client.add_account(new_account_name)
|
||||
st.write(response)
|
||||
else:
|
||||
st.write("Please enter an account name.")
|
||||
|
||||
with c2:
|
||||
# Section to delete an existing account
|
||||
st.header("Delete an Account")
|
||||
delete_account_name = st.selectbox("Select Account to Delete", options=accounts if accounts else ["No accounts available"], )
|
||||
if st.button("Delete Account"):
|
||||
if delete_account_name and delete_account_name != "No accounts available":
|
||||
response = client.delete_account(delete_account_name)
|
||||
st.warning(response)
|
||||
else:
|
||||
st.write("Please select a valid account.")
|
||||
|
||||
with c3:
|
||||
# Section to delete a credential from an existing account
|
||||
st.header("Delete Credential")
|
||||
delete_account_cred_name = st.selectbox("Select the credentials account", options=accounts if accounts else ["No accounts available"],)
|
||||
creds_for_account = [credential.split(".")[0] for credential in client.get_credentials(delete_account_cred_name)]
|
||||
delete_cred_name = st.selectbox("Select a Credential to Delete", options=creds_for_account if creds_for_account else ["No credentials available"])
|
||||
if st.button("Delete Credential"):
|
||||
if (delete_account_cred_name and delete_account_cred_name != "No accounts available") and (delete_cred_name and delete_cred_name != "No credentials available"):
|
||||
response = client.delete_credential(delete_account_cred_name, delete_cred_name)
|
||||
st.warning(response)
|
||||
else:
|
||||
st.write("Please select a valid account.")
|
||||
|
||||
st.markdown("---")
|
||||
|
||||
# Section to add credentials
|
||||
st.header("Add Credentials")
|
||||
c1, c2 = st.columns([1, 1])
|
||||
with c1:
|
||||
account_name = st.selectbox("Select Account", options=accounts if accounts else ["No accounts available"])
|
||||
with c2:
|
||||
all_connectors = list(all_connector_config_map.keys())
|
||||
binance_perpetual_index = all_connectors.index("binance_perpetual") if "binance_perpetual" in all_connectors else None
|
||||
connector_name = st.selectbox("Select Connector", options=all_connectors, index=binance_perpetual_index)
|
||||
config_map = all_connector_config_map[connector_name]
|
||||
|
||||
st.write(f"Configuration Map for {connector_name}:")
|
||||
config_inputs = {}
|
||||
cols = st.columns(NUM_COLUMNS)
|
||||
for i, config in enumerate(config_map):
|
||||
with cols[i % (NUM_COLUMNS - 1)]:
|
||||
config_inputs[config] = st.text_input(config, type="password", key=f"{connector_name}_{config}")
|
||||
|
||||
with cols[-1]:
|
||||
if st.button("Submit Credentials"):
|
||||
response = client.add_connector_keys(account_name, connector_name, config_inputs)
|
||||
if response:
|
||||
st.success(response)
|
||||
13
pages/orchestration/file_manager/README.md
Normal file
13
pages/orchestration/file_manager/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
### Description
|
||||
|
||||
This page helps you manage and edit script files to run with Hummingbot instances:
|
||||
|
||||
- Selecting files
|
||||
- Editing and saving files
|
||||
|
||||
### Maintainers
|
||||
|
||||
This page is maintained by Hummingbot Foundation:
|
||||
|
||||
* [cardosfede](https://github.com/cardosfede)
|
||||
* [fengtality](https://github.com/fengtality)
|
||||
0
pages/orchestration/file_manager/__init__.py
Normal file
0
pages/orchestration/file_manager/__init__.py
Normal file
39
pages/orchestration/file_manager/app.py
Normal file
39
pages/orchestration/file_manager/app.py
Normal file
@@ -0,0 +1,39 @@
|
||||
from types import SimpleNamespace
|
||||
import streamlit as st
|
||||
from streamlit_elements import elements, mui
|
||||
|
||||
from frontend.components.bots_file_explorer import BotsFileExplorer
|
||||
from frontend.components.dashboard import Dashboard
|
||||
from frontend.components.editor import Editor
|
||||
from frontend.st_utils import initialize_st_page
|
||||
|
||||
initialize_st_page(title="Strategy Configs", icon="🗂️")
|
||||
|
||||
|
||||
if "fe_board" not in st.session_state:
|
||||
board = Dashboard()
|
||||
fe_board = SimpleNamespace(
|
||||
dashboard=board,
|
||||
file_explorer=BotsFileExplorer(board, 0, 0, 3, 7),
|
||||
editor=Editor(board, 4, 0, 9, 7),
|
||||
)
|
||||
st.session_state.fe_board = fe_board
|
||||
|
||||
else:
|
||||
fe_board = st.session_state.fe_board
|
||||
|
||||
# Add new tabs
|
||||
for tab_name, content in fe_board.file_explorer.tabs.items():
|
||||
if tab_name not in fe_board.editor.tabs:
|
||||
fe_board.editor.add_tab(tab_name, content["content"], content["language"])
|
||||
|
||||
# Remove deleted tabs
|
||||
for tab_name in list(fe_board.editor.tabs.keys()):
|
||||
if tab_name not in fe_board.file_explorer.tabs:
|
||||
fe_board.editor.remove_tab(tab_name)
|
||||
|
||||
with elements("file_manager"):
|
||||
with mui.Paper(elevation=3, style={"padding": "2rem"}, spacing=[2, 2], container=True):
|
||||
with fe_board.dashboard():
|
||||
fe_board.file_explorer()
|
||||
fe_board.editor()
|
||||
19
pages/orchestration/instances/README.md
Normal file
19
pages/orchestration/instances/README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
### Description
|
||||
|
||||
This page helps you deploy and manage Hummingbot instances:
|
||||
|
||||
- Starting and stopping Hummingbot Broker
|
||||
- Creating, starting and stopping bot instances
|
||||
- Managing strategy and script files that instances run
|
||||
- Fetching status of running instances
|
||||
|
||||
### Maintainers
|
||||
|
||||
This page is maintained by Hummingbot Foundation as a template other pages:
|
||||
|
||||
* [cardosfede](https://github.com/cardosfede)
|
||||
* [fengtality](https://github.com/fengtality)
|
||||
|
||||
### Wiki
|
||||
|
||||
See the [wiki](https://github.com/hummingbot/dashboard/wiki/%F0%9F%90%99-Bot-Orchestration) for more information.
|
||||
0
pages/orchestration/instances/__init__.py
Normal file
0
pages/orchestration/instances/__init__.py
Normal file
73
pages/orchestration/instances/app.py
Normal file
73
pages/orchestration/instances/app.py
Normal file
@@ -0,0 +1,73 @@
|
||||
import time
|
||||
|
||||
import streamlit as st
|
||||
from streamlit_elements import elements, mui
|
||||
from types import SimpleNamespace
|
||||
|
||||
from frontend.components.bot_performance_card import BotPerformanceCardV2
|
||||
from frontend.components.dashboard import Dashboard
|
||||
from frontend.st_utils import initialize_st_page, get_backend_api_client
|
||||
|
||||
# Constants for UI layout
|
||||
CARD_WIDTH = 12
|
||||
CARD_HEIGHT = 4
|
||||
NUM_CARD_COLS = 1
|
||||
|
||||
def get_grid_positions(n_cards: int, cols: int = NUM_CARD_COLS, card_width: int = CARD_WIDTH, card_height: int = CARD_HEIGHT):
|
||||
rows = n_cards // cols + 1
|
||||
x_y = [(x * card_width, y * card_height) for x in range(cols) for y in range(rows)]
|
||||
return sorted(x_y, key=lambda x: (x[1], x[0]))
|
||||
|
||||
|
||||
def update_active_bots(api_client):
|
||||
active_bots_response = api_client.get_active_bots_status()
|
||||
if active_bots_response.get("status") == "success":
|
||||
current_active_bots = active_bots_response.get("data")
|
||||
stored_bots = {card[1]: card for card in st.session_state.active_instances_board.bot_cards}
|
||||
|
||||
new_bots = set(current_active_bots.keys()) - set(stored_bots.keys())
|
||||
removed_bots = set(stored_bots.keys()) - set(current_active_bots.keys())
|
||||
for bot in removed_bots:
|
||||
st.session_state.active_instances_board.bot_cards = [card for card in st.session_state.active_instances_board.bot_cards if card[1] != bot]
|
||||
positions = get_grid_positions(len(current_active_bots), NUM_CARD_COLS, CARD_WIDTH, CARD_HEIGHT)
|
||||
for bot, (x, y) in zip(new_bots, positions[:len(new_bots)]):
|
||||
card = BotPerformanceCardV2(st.session_state.active_instances_board.dashboard, x, y, CARD_WIDTH, CARD_HEIGHT)
|
||||
st.session_state.active_instances_board.bot_cards.append((card, bot))
|
||||
|
||||
|
||||
initialize_st_page(title="Instances", icon="🦅")
|
||||
api_client = get_backend_api_client()
|
||||
|
||||
if not api_client.is_docker_running():
|
||||
st.warning("Docker is not running. Please start Docker and refresh the page.")
|
||||
st.stop()
|
||||
|
||||
if "active_instances_board" not in st.session_state:
|
||||
active_bots_response = api_client.get_active_bots_status()
|
||||
bot_cards = []
|
||||
board = Dashboard()
|
||||
st.session_state.active_instances_board = SimpleNamespace(
|
||||
dashboard=board,
|
||||
bot_cards=bot_cards,
|
||||
)
|
||||
active_bots = active_bots_response.get("data")
|
||||
number_of_bots = len(active_bots)
|
||||
if number_of_bots > 0:
|
||||
positions = get_grid_positions(number_of_bots, NUM_CARD_COLS, CARD_WIDTH, CARD_HEIGHT)
|
||||
for (bot, bot_info), (x, y) in zip(active_bots.items(), positions):
|
||||
bot_status = api_client.get_bot_status(bot)
|
||||
card = BotPerformanceCardV2(board, x, y, CARD_WIDTH, CARD_HEIGHT)
|
||||
st.session_state.active_instances_board.bot_cards.append((card, bot))
|
||||
else:
|
||||
update_active_bots(api_client)
|
||||
|
||||
with elements("active_instances_board"):
|
||||
with mui.Paper(sx={"padding": "2rem"}, variant="outlined"):
|
||||
mui.Typography("🏠 Local Instances", variant="h5")
|
||||
for card, bot in st.session_state.active_instances_board.bot_cards:
|
||||
with st.session_state.active_instances_board.dashboard():
|
||||
card(bot)
|
||||
|
||||
while True:
|
||||
time.sleep(10)
|
||||
st.rerun()
|
||||
19
pages/orchestration/launch_bot_v2/README.md
Normal file
19
pages/orchestration/launch_bot_v2/README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
### Description
|
||||
|
||||
This page helps you deploy and manage Hummingbot instances:
|
||||
|
||||
- Starting and stopping Hummingbot Broker
|
||||
- Creating, starting and stopping bot instances
|
||||
- Managing strategy and script files that instances run
|
||||
- Fetching status of running instances
|
||||
|
||||
### Maintainers
|
||||
|
||||
This page is maintained by Hummingbot Foundation as a template other pages:
|
||||
|
||||
* [cardosfede](https://github.com/cardosfede)
|
||||
* [fengtality](https://github.com/fengtality)
|
||||
|
||||
### Wiki
|
||||
|
||||
See the [wiki](https://github.com/hummingbot/dashboard/wiki/%F0%9F%90%99-Bot-Orchestration) for more information.
|
||||
0
pages/orchestration/launch_bot_v2/__init__.py
Normal file
0
pages/orchestration/launch_bot_v2/__init__.py
Normal file
31
pages/orchestration/launch_bot_v2/app.py
Normal file
31
pages/orchestration/launch_bot_v2/app.py
Normal file
@@ -0,0 +1,31 @@
|
||||
from types import SimpleNamespace
|
||||
|
||||
import streamlit as st
|
||||
from streamlit_elements import elements, mui
|
||||
|
||||
from frontend.components.dashboard import Dashboard
|
||||
from frontend.components.launch_strategy_v2 import LaunchStrategyV2
|
||||
from frontend.st_utils import initialize_st_page
|
||||
|
||||
CARD_WIDTH = 6
|
||||
CARD_HEIGHT = 3
|
||||
NUM_CARD_COLS = 2
|
||||
|
||||
initialize_st_page(title="Launch Bot", icon="🙌")
|
||||
|
||||
if "launch_bots_board" not in st.session_state:
|
||||
board = Dashboard()
|
||||
launch_bots_board = SimpleNamespace(
|
||||
dashboard=board,
|
||||
launch_bot=LaunchStrategyV2(board, 0, 0, 12, 10),
|
||||
)
|
||||
st.session_state.launch_bots_board = launch_bots_board
|
||||
|
||||
else:
|
||||
launch_bots_board = st.session_state.launch_bots_board
|
||||
|
||||
|
||||
with elements("create_bot"):
|
||||
with mui.Paper(elevation=3, style={"padding": "2rem"}, spacing=[2, 2], container=True):
|
||||
with launch_bots_board.dashboard():
|
||||
launch_bots_board.launch_bot()
|
||||
19
pages/orchestration/launch_bot_v2_st/README.md
Normal file
19
pages/orchestration/launch_bot_v2_st/README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
### Description
|
||||
|
||||
This page helps you deploy and manage Hummingbot instances:
|
||||
|
||||
- Starting and stopping Hummingbot Broker
|
||||
- Creating, starting and stopping bot instances
|
||||
- Managing strategy and script files that instances run
|
||||
- Fetching status of running instances
|
||||
|
||||
### Maintainers
|
||||
|
||||
This page is maintained by Hummingbot Foundation as a template other pages:
|
||||
|
||||
* [cardosfede](https://github.com/cardosfede)
|
||||
* [fengtality](https://github.com/fengtality)
|
||||
|
||||
### Wiki
|
||||
|
||||
See the [wiki](https://github.com/hummingbot/dashboard/wiki/%F0%9F%90%99-Bot-Orchestration) for more information.
|
||||
0
pages/orchestration/launch_bot_v2_st/__init__.py
Normal file
0
pages/orchestration/launch_bot_v2_st/__init__.py
Normal file
9
pages/orchestration/launch_bot_v2_st/app.py
Normal file
9
pages/orchestration/launch_bot_v2_st/app.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from frontend.components.deploy_v2_with_controllers import LaunchV2WithControllers
|
||||
from frontend.st_utils import initialize_st_page
|
||||
|
||||
|
||||
initialize_st_page(title="Launch Bot ST", icon="🙌")
|
||||
|
||||
|
||||
launcher = LaunchV2WithControllers()
|
||||
launcher()
|
||||
19
pages/orchestration/portfolio/README.md
Normal file
19
pages/orchestration/portfolio/README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
### Description
|
||||
|
||||
This page helps you deploy and manage Hummingbot instances:
|
||||
|
||||
- Starting and stopping Hummingbot Broker
|
||||
- Creating, starting and stopping bot instances
|
||||
- Managing strategy and script files that instances run
|
||||
- Fetching status of running instances
|
||||
|
||||
### Maintainers
|
||||
|
||||
This page is maintained by Hummingbot Foundation as a template other pages:
|
||||
|
||||
* [cardosfede](https://github.com/cardosfede)
|
||||
* [fengtality](https://github.com/fengtality)
|
||||
|
||||
### Wiki
|
||||
|
||||
See the [wiki](https://github.com/hummingbot/dashboard/wiki/%F0%9F%90%99-Bot-Orchestration) for more information.
|
||||
0
pages/orchestration/portfolio/__init__.py
Normal file
0
pages/orchestration/portfolio/__init__.py
Normal file
154
pages/orchestration/portfolio/app.py
Normal file
154
pages/orchestration/portfolio/app.py
Normal file
@@ -0,0 +1,154 @@
|
||||
from frontend.st_utils import initialize_st_page, get_backend_api_client
|
||||
import streamlit as st
|
||||
import pandas as pd
|
||||
import plotly.graph_objects as go
|
||||
import plotly.express as px
|
||||
|
||||
initialize_st_page(title="Portfolio", icon="💰")
|
||||
|
||||
# Page content
|
||||
client = get_backend_api_client()
|
||||
NUM_COLUMNS = 4
|
||||
|
||||
|
||||
# Convert balances to a DataFrame for easier manipulation
|
||||
def account_state_to_df(account_state):
|
||||
data = []
|
||||
for account, exchanges in account_state.items():
|
||||
for exchange, tokens_info in exchanges.items():
|
||||
for info in tokens_info:
|
||||
data.append({
|
||||
"account": account,
|
||||
"exchange": exchange,
|
||||
"token": info["token"],
|
||||
"price": info["price"],
|
||||
"units": info["units"],
|
||||
"value": info["value"],
|
||||
"available_units": info["available_units"],
|
||||
})
|
||||
return pd.DataFrame(data)
|
||||
|
||||
|
||||
# Convert historical account states to a DataFrame
|
||||
def account_history_to_df(history):
|
||||
data = []
|
||||
for record in history:
|
||||
timestamp = record["timestamp"]
|
||||
for account, exchanges in record["state"].items():
|
||||
for exchange, tokens_info in exchanges.items():
|
||||
for info in tokens_info:
|
||||
data.append({
|
||||
"timestamp": timestamp,
|
||||
"account": account,
|
||||
"exchange": exchange,
|
||||
"token": info["token"],
|
||||
"price": info["price"],
|
||||
"units": info["units"],
|
||||
"value": info["value"],
|
||||
"available_units": info["available_units"],
|
||||
})
|
||||
return pd.DataFrame(data)
|
||||
|
||||
|
||||
# Fetch account state from the backend
|
||||
account_state = client.get_accounts_state()
|
||||
account_history = client.get_account_state_history()
|
||||
if len(account_state) == 0:
|
||||
st.warning("No accounts found.")
|
||||
st.stop()
|
||||
|
||||
# Display the accounts available
|
||||
accounts = st.multiselect("Select Accounts", list(account_state.keys()), list(account_state.keys()))
|
||||
if len(accounts) == 0:
|
||||
st.warning("Please select an account.")
|
||||
st.stop()
|
||||
|
||||
# Display the exchanges available
|
||||
exchanges_available = []
|
||||
for account in accounts:
|
||||
exchanges_available += account_state[account].keys()
|
||||
|
||||
if len(exchanges_available) == 0:
|
||||
st.warning("No exchanges found.")
|
||||
st.stop()
|
||||
exchanges = st.multiselect("Select Exchanges", exchanges_available, exchanges_available)
|
||||
|
||||
# Display the tokens available
|
||||
tokens_available = []
|
||||
for account in accounts:
|
||||
for exchange in exchanges:
|
||||
if exchange in account_state[account]:
|
||||
tokens_available += [info["token"] for info in account_state[account][exchange]]
|
||||
|
||||
token_options = set(tokens_available)
|
||||
tokens_available = st.multiselect("Select Tokens", token_options, token_options)
|
||||
|
||||
|
||||
st.write("---")
|
||||
|
||||
filtered_account_state = {}
|
||||
for account in accounts:
|
||||
filtered_account_state[account] = {}
|
||||
for exchange in exchanges:
|
||||
if exchange in account_state[account]:
|
||||
filtered_account_state[account][exchange] = [token_info for token_info in account_state[account][exchange] if token_info["token"] in tokens_available]
|
||||
|
||||
filtered_account_history = []
|
||||
for record in account_history:
|
||||
filtered_record = {"timestamp": record["timestamp"], "state": {}}
|
||||
for account in accounts:
|
||||
if account in record["state"]:
|
||||
filtered_record["state"][account] = {}
|
||||
for exchange in exchanges:
|
||||
if exchange in record["state"][account]:
|
||||
filtered_record["state"][account][exchange] = [token_info for token_info in record["state"][account][exchange] if token_info["token"] in tokens_available]
|
||||
filtered_account_history.append(filtered_record)
|
||||
|
||||
if len(filtered_account_state) > 0:
|
||||
account_state_df = account_state_to_df(filtered_account_state)
|
||||
total_balance_usd = round(account_state_df["value"].sum(), 2)
|
||||
c1, c2 = st.columns([1, 5])
|
||||
with c1:
|
||||
st.metric("Total Balance (USD)", total_balance_usd)
|
||||
with c2:
|
||||
account_state_df['% Allocation'] = (account_state_df['value'] / total_balance_usd) * 100
|
||||
account_state_df['label'] = account_state_df['token'] + ' ($' + account_state_df['value'].apply(
|
||||
lambda x: f'{x:,.2f}') + ')'
|
||||
|
||||
# Create a sunburst chart with Plotly Express
|
||||
fig = px.sunburst(account_state_df,
|
||||
path=['account', 'exchange', 'label'],
|
||||
values='value',
|
||||
hover_data={'% Allocation': ':.2f'},
|
||||
title='% Allocation by Account, Exchange, and Token',
|
||||
color='account',
|
||||
color_discrete_sequence=px.colors.qualitative.Vivid)
|
||||
|
||||
fig.update_traces(textinfo='label+percent entry')
|
||||
|
||||
fig.update_layout(margin=dict(t=0, l=0, r=0, b=0), height=800, title_x=0.01, title_y=1,)
|
||||
|
||||
st.plotly_chart(fig, use_container_width=True)
|
||||
|
||||
st.dataframe(account_state_df[['exchange', 'token', 'units', 'price', 'value', 'available_units']], width=1800,
|
||||
height=600)
|
||||
|
||||
# Plot the evolution of the portfolio over time
|
||||
if len(filtered_account_history) > 0:
|
||||
account_history_df = account_history_to_df(filtered_account_history)
|
||||
account_history_df['timestamp'] = pd.to_datetime(account_history_df['timestamp'])
|
||||
|
||||
# Aggregate the value of the portfolio over time
|
||||
portfolio_evolution_df = account_history_df.groupby('timestamp')['value'].sum().reset_index()
|
||||
|
||||
fig = px.line(portfolio_evolution_df, x='timestamp', y='value', title='Portfolio Evolution Over Time')
|
||||
fig.update_layout(xaxis_title='Time', yaxis_title='Total Value (USD)', height=600)
|
||||
st.plotly_chart(fig, use_container_width=True)
|
||||
|
||||
# Plot the evolution of each token's value over time
|
||||
token_evolution_df = account_history_df.groupby(['timestamp', 'token'])['value'].sum().reset_index()
|
||||
|
||||
fig = px.area(token_evolution_df, x='timestamp', y='value', color='token', title='Token Value Evolution Over Time',
|
||||
color_discrete_sequence=px.colors.qualitative.Vivid)
|
||||
fig.update_layout(xaxis_title='Time', yaxis_title='Value (USD)', height=600)
|
||||
st.plotly_chart(fig, use_container_width=True)
|
||||
Reference in New Issue
Block a user