Skip to content

Commit

Permalink
Merge pull request #109 from Synthetixio/feat/add-arbitrum-perps
Browse files Browse the repository at this point in the history
Add Arbitrum Perps
  • Loading branch information
Tburm authored Sep 5, 2024
2 parents 342d582 + 09715ee commit d4eaf80
Show file tree
Hide file tree
Showing 94 changed files with 19,568 additions and 4,669 deletions.
14 changes: 14 additions & 0 deletions dashboard/modules/all_chains/perp_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,24 @@ def fetch_data(filters):
FROM {st.secrets.database.DB_ENV}_optimism_mainnet.fct_v2_stats_{resolution}_optimism_mainnet
where ts >= '{filters["start_date"]}'
and ts <= '{filters["end_date"]}'
),
arbitrum as (
SELECT
ts,
'Arbitrum (V3)' as label,
volume,
trades,
exchange_fees as fees,
liquidated_accounts as liquidations
FROM {st.secrets.database.DB_ENV}_arbitrum_mainnet.fct_perp_stats_{resolution}_arbitrum_mainnet
WHERE ts >= '{start_date}' and ts <= '{end_date}'
)
select * from base
union all
select * from optimism
union all
select * from arbitrum
order by ts
""",
db,
Expand Down
309 changes: 309 additions & 0 deletions dashboard/modules/arbitrum_mainnet/perp_account.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,309 @@
import streamlit as st
import pandas as pd
import sqlite3
import plotly.express as px
from datetime import datetime, timedelta
from utils import get_connection
from utils import chart_bars, chart_lines, export_data

## set default filters
filters = {
"account_id": "NULL",
"start_date": datetime.today().date() - timedelta(days=14),
"end_date": datetime.today().date() + timedelta(days=1),
}


## data
@st.cache_data(ttl=60)
def fetch_data(filters):
# get filters
account_id = filters["account_id"]
start_date = filters["start_date"]
end_date = filters["end_date"]

# initialize connection
db = get_connection()

# read data
df_order = pd.read_sql_query(
f"""
SELECT distinct account_id, sender FROM {st.secrets.database.DB_ENV}_arbitrum_mainnet.fct_perp_orders_arbitrum_mainnet
""",
db,
)
df_order_expired = pd.read_sql_query(
f"""
SELECT
block_timestamp,
cast(account_id as text) as account_id,
market_id,
acceptable_price,
commitment_time
FROM {st.secrets.database.DB_ENV}_arbitrum_mainnet.fct_perp_previous_order_expired_arbitrum_mainnet
WHERE account_id = {account_id if account_id else 'NULL'}
and date(block_timestamp) >= '{start_date}' and date(block_timestamp) <= '{end_date}'
""",
db,
)
df_trade = pd.read_sql_query(
f"""
SELECT
ts,
cast(account_id as text) as account_id,
market_id,
market_symbol,
position_size,
notional_position_size,
trade_size,
notional_trade_size,
fill_price,
total_fees,
accrued_funding,
tracking_code
FROM {st.secrets.database.DB_ENV}_arbitrum_mainnet.fct_perp_trades_arbitrum_mainnet
WHERE account_id = '{account_id}'
and ts >= '{start_date}' and ts <= '{end_date}'
""",
db,
)
df_transfer = pd.read_sql_query(
f"""
SELECT
block_timestamp,
cast(account_id as text) as account_id,
synth_market_id,
amount_delta
FROM {st.secrets.database.DB_ENV}_arbitrum_mainnet.fct_perp_collateral_modified_arbitrum_mainnet
WHERE account_id = {account_id if account_id else 'NULL'}
and date(block_timestamp) >= '{start_date}' and date(block_timestamp) <= '{end_date}'
""",
db,
)
df_interest = pd.read_sql_query(
f"""
SELECT
block_timestamp,
transaction_hash,
cast(account_id as text) as account_id,
interest
FROM {st.secrets.database.DB_ENV}_arbitrum_mainnet.fct_perp_interest_charged_arbitrum_mainnet
WHERE account_id = {account_id if account_id else 'NULL'}
and date(block_timestamp) >= '{start_date}' and date(block_timestamp) <= '{end_date}'
""",
db,
)

df_account_liq = pd.read_sql_query(
f"""
SELECT
ts,
account_id,
total_reward
FROM {st.secrets.database.DB_ENV}_arbitrum_mainnet.fct_perp_liq_account_arbitrum_mainnet
WHERE account_id = '{account_id}'
and ts >= '{start_date}' and ts <= '{end_date}'
""",
db,
)
df_hourly = pd.read_sql_query(
f"""
SELECT
ts,
cumulative_volume,
cumulative_fees
FROM {st.secrets.database.DB_ENV}_arbitrum_mainnet.fct_perp_account_stats_hourly_arbitrum_mainnet
WHERE account_id = '{account_id}'
and ts >= '{start_date}' and ts <= '{end_date}'
order by ts
""",
db,
)

df_accounts = df_order[["account_id", "sender"]].drop_duplicates()
df_accounts.columns = ["id", "owner"]

# one basic transform
df_transfer["amount_delta"] = df_transfer["amount_delta"] / 1e18

db.close()

return {
"accounts": df_accounts,
"order_expired": df_order_expired,
"interest": df_interest,
"trade": df_trade,
"transfer": df_transfer,
"account_liq": df_account_liq,
"hourly": df_hourly,
}


def make_charts(data):
return {
"cumulative_volume": chart_lines(
data["hourly"], "ts", ["cumulative_volume"], "Cumulative Volume"
),
"cumulative_fees": chart_lines(
data["hourly"], "ts", ["cumulative_fees"], "Cumulative Fees"
),
}


def main():
st.markdown("## V3 Perps Accounts")
data = fetch_data(filters)

## date filter
with st.expander("Date filter"):
filt_col1, filt_col2 = st.columns(2)
with filt_col1:
filters["start_date"] = st.date_input("Start", filters["start_date"])

with filt_col2:
filters["end_date"] = st.date_input("End", filters["end_date"])

## account lookup
with st.expander("Look up accounts by address"):
address = st.text_input("Enter an address to look up associated accounts")

df_accounts = data["accounts"]
account_numbers = df_accounts[(df_accounts["owner"] == address)]["id"].unique()

# account_numbers
if len(account_numbers) > 0:
st.dataframe(account_numbers, hide_index=True)

## account select
accounts = data["accounts"]["id"].unique()
accounts = sorted(list([int(_) for _ in accounts]))
filters["account_id"] = st.selectbox("Select account", accounts, index=0)
data = fetch_data(filters)

## do some lighter transforms
df_open_positions = (
data["trade"]
.sort_values("ts")
.groupby(["account_id", "market_id"])
.last()
.reset_index()
)
df_open_positions = df_open_positions[df_open_positions["position_size"].abs() > 0]

## make the charts
charts = make_charts(data)

## display
# Open positions
df_open_account = df_open_positions[
df_open_positions["account_id"] == filters["account_id"]
]

last_liq = (
data["account_liq"]
.loc[data["account_liq"]["account_id"] == filters["account_id"], "ts"]
.max()
)

# this is a hack to handle the case where there are no liquidations
last_liq = last_liq if pd.isna(last_liq) == False else "2023-01-01 00:00:00+00:00"

df_open_account = df_open_account.loc[
df_open_account["ts"] > last_liq,
["account_id", "market_symbol", "position_size", "notional_position_size"],
]

st.markdown(
"""
### Open Positions
"""
)
if len(df_open_account) > 0:
df_open_account
else:
st.markdown(
"""
No open positions
"""
)

col1, col2 = st.columns(2)

with col1:
st.plotly_chart(charts["cumulative_volume"], use_container_width=True)
pass

with col2:
st.plotly_chart(charts["cumulative_fees"], use_container_width=True)
pass

# Recent trades
st.markdown(
"""
### Recent Trades
"""
)

st.dataframe(
data["trade"].sort_values("ts", ascending=False).head(50),
use_container_width=True,
hide_index=True,
)

# Recent transfers
st.markdown(
"""
### Recent Transfers
"""
)

st.dataframe(
data["transfer"].sort_values("block_timestamp", ascending=False).head(50),
use_container_width=True,
hide_index=True,
)

# Account liquidations table
st.markdown(
"""
### Liquidations
"""
)

st.dataframe(
data["account_liq"].sort_values("ts", ascending=False).head(25),
use_container_width=True,
hide_index=True,
)

# Expired orders table
st.markdown(
"""
### Expired Orders
"""
)

st.dataframe(
data["order_expired"],
use_container_width=True,
hide_index=True,
)

# Interest charged table
st.markdown(
"""
### Interest Charged
"""
)

st.dataframe(
data["interest"],
use_container_width=True,
hide_index=True,
)

## export
exports = [{"title": export, "df": data[export]} for export in data.keys()]
with st.expander("Exports"):
for export in exports:
export_data(export["title"], export["df"])
Loading

0 comments on commit d4eaf80

Please sign in to comment.