optimus-metrics / app.py
gauravlochab
Add transaction metrics and visualizations
07ba1e6
raw
history blame
6.16 kB
import requests
import pandas as pd
import gradio as gr
import plotly.express as px
from datetime import datetime
# Function to fetch and process the transaction data from the API
def fetch_transactions():
url = "https://li.quest/v1/analytics/transfers?integrator=valory"
headers = {"accept": "application/json"}
response = requests.get(url, headers=headers)
return response.json()
# Function to parse the transaction data and prepare it for visualization
def process_transactions(data):
transactions = data["transfers"]
# Convert the data into a pandas DataFrame for easy manipulation
rows = []
for tx in transactions:
# Normalize amounts
sending_amount = float(tx["sending"]["amount"]) / (10 ** tx["sending"]["token"]["decimals"])
receiving_amount = float(tx["receiving"]["amount"]) / (10 ** tx["receiving"]["token"]["decimals"])
# Convert timestamps to datetime objects
sending_timestamp = datetime.utcfromtimestamp(tx["sending"]["timestamp"])
receiving_timestamp = datetime.utcfromtimestamp(tx["receiving"]["timestamp"])
# Prepare row data
rows.append({
"transactionId": tx["transactionId"],
"from_address": tx["fromAddress"],
"to_address": tx["toAddress"],
"sending_chain": tx["sending"]["chainId"],
"receiving_chain": tx["receiving"]["chainId"],
"sending_token_symbol": tx["sending"]["token"]["symbol"],
"receiving_token_symbol": tx["receiving"]["token"]["symbol"],
"sending_amount": sending_amount,
"receiving_amount": receiving_amount,
"sending_amount_usd": float(tx["sending"]["amountUSD"]),
"receiving_amount_usd": float(tx["receiving"]["amountUSD"]),
"sending_gas_used": int(tx["sending"]["gasUsed"]),
"receiving_gas_used": int(tx["receiving"]["gasUsed"]),
"sending_timestamp": sending_timestamp,
"receiving_timestamp": receiving_timestamp,
"date": sending_timestamp.date(), # Group by day
"week": sending_timestamp.strftime('%Y-%W') # Group by week
})
df = pd.DataFrame(rows)
return df
# Function to create visualizations based on the metrics
def create_visualizations():
transactions_data = fetch_transactions()
df = process_transactions(transactions_data)
# Ensure that chain IDs are strings for consistent grouping
df["sending_chain"] = df["sending_chain"].astype(str)
df["receiving_chain"] = df["receiving_chain"].astype(str)
# 1. Number of Transactions per Chain per Day per Agent
tx_per_chain_agent = df.groupby(["date", "from_address", "sending_chain"]).size().reset_index(name="transaction_count")
fig_tx_chain_agent = px.bar(tx_per_chain_agent, x="date", y="transaction_count", color="sending_chain", barmode="group",
facet_col="from_address", title="Number of Transactions per Chain per Agent per Day")
# 2. Number of Opportunities Taken per Agent per Day
opportunities_per_agent = df.groupby(["date", "from_address"]).size().reset_index(name="opportunities_taken")
fig_opportunities_agent = px.bar(opportunities_per_agent, x="date", y="opportunities_taken", color="from_address",
title="Number of Opportunities Taken per Agent per Day")
# 3. Amount of Investment in Pools Daily per Agent (Note: Assuming sending_amount_usd as investment)
# Since we might not have explicit data about pool investments, we'll use sending_amount_usd
investment_per_agent = df.groupby(["date", "from_address"])["sending_amount_usd"].sum().reset_index()
fig_investment_agent = px.bar(investment_per_agent, x="date", y="sending_amount_usd", color="from_address",
title="Amount of Investment (USD) per Agent per Day")
# 4. Number of Swaps per Day
# Assuming each transaction is a swap if sending and receiving tokens are different
df["is_swap"] = df.apply(lambda x: x["sending_token_symbol"] != x["receiving_token_symbol"], axis=1)
swaps_per_day = df[df["is_swap"]].groupby("date").size().reset_index(name="swap_count")
fig_swaps_per_day = px.bar(swaps_per_day, x="date", y="swap_count", title="Number of Swaps per Day")
# 5. Aggregated Metrics over All Traders
amount_usd = df["sending_amount_usd"]
stats = {
"Total": amount_usd.sum(),
"Average": amount_usd.mean(),
"Min": amount_usd.min(),
"Max": amount_usd.max(),
"25th Percentile": amount_usd.quantile(0.25),
"50th Percentile (Median)": amount_usd.median(),
"75th Percentile": amount_usd.quantile(0.75),
}
stats_df = pd.DataFrame(list(stats.items()), columns=["Metric", "Value"])
# Visualization for Aggregated Metrics
fig_stats = px.bar(stats_df, x="Metric", y="Value", title="Aggregated Transaction Amount Metrics (USD)")
return fig_tx_chain_agent, fig_opportunities_agent, fig_investment_agent, fig_swaps_per_day, fig_stats
# Gradio interface
def dashboard():
with gr.Blocks() as demo:
gr.Markdown("# Valory Transactions Dashboard")
# Fetch and display visualizations
with gr.Tab("Transactions per Chain per Agent"):
fig_tx_chain_agent, _, _, _, _ = create_visualizations()
gr.Plot(fig_tx_chain_agent)
with gr.Tab("Opportunities per Agent"):
_, fig_opportunities_agent, _, _, _ = create_visualizations()
gr.Plot(fig_opportunities_agent)
with gr.Tab("Investment per Agent"):
_, _, fig_investment_agent, _, _ = create_visualizations()
gr.Plot(fig_investment_agent)
with gr.Tab("Swaps per Day"):
_, _, _, fig_swaps_per_day, _ = create_visualizations()
gr.Plot(fig_swaps_per_day)
with gr.Tab("Aggregated Metrics"):
_, _, _, _, fig_stats = create_visualizations()
gr.Plot(fig_stats)
return demo
# Launch the dashboard
if __name__ == "__main__":
dashboard().launch()