(feat) add protocols analysis page

This commit is contained in:
cardosofede
2022-07-14 19:55:27 +02:00
parent c327ceebce
commit fa2a993173
5 changed files with 119 additions and 148 deletions

2
.gitignore vendored
View File

@@ -6,6 +6,8 @@ __pycache__/
# C extensions
*.
*.ipynb
.idea/*
# Distribution / packaging

View File

@@ -0,0 +1,83 @@
from xml.dom.pulldom import default_bufsize
import numpy as np
import streamlit as st
import pandas as pd
import plotly.express as px
from defillama import DefiLlama
from traitlets import default
MIN_TVL = 1000000.
MIN_MCAP = 1000000.
@st.cache
def get_tvl_mcap_data():
# initialize api client
llama = DefiLlama()
# Get all protocols data
df = pd.DataFrame(llama.get_all_protocols())
tvl_mcap_df = df.loc[(df["tvl"]>0) & (df["mcap"]>0), ["name", "tvl", "mcap", "chain", "category", "slug"]].sort_values(by=["mcap"], ascending=False)
return tvl_mcap_df[(tvl_mcap_df["tvl"] > MIN_TVL) & (tvl_mcap_df["mcap"]> MIN_MCAP)]
def get_protocols_by_chain_category(protocols: pd.DataFrame, group_by: list, nth: list):
return protocols.sort_values('tvl', ascending=False).groupby(group_by).nth(nth).reset_index()
st.set_page_config(layout='wide')
st.title("🦉 TVL vs MCAP Analysis")
st.write("---")
st.code("💡 Source: [DefiLlama](https://defillama.com/)")
with st.spinner(text='In progress'):
tvl_mcap_df = get_tvl_mcap_data()
default_chains = ["Ethereum", "Solana", "Binance", "Polygon", "Multi-Chain", "Avalanche"]
# st.write("### Protocols filter 🦅")
# tokens = st.multiselect(
# "Select the protocols to analyze:",
# options=tvl_mcap_df["name"],
# default=tvl_mcap_df[tvl_mcap_df["chain"].isin(default_chains)]["name"])
st.sidebar.write("### Chains filter 🔗")
chains = st.sidebar.multiselect(
"Select the chains to analyze:",
options=tvl_mcap_df["chain"].unique(),
default=default_chains)
scatter = px.scatter(
data_frame=tvl_mcap_df[tvl_mcap_df["chain"].isin(chains)],
x="tvl",
y="mcap",
color="chain",
trendline="ols",
log_x=True,
log_y=True,
height=800,
hover_data=["name"],
template="plotly_dark",
title="TVL vs MCAP",
labels={
"tvl": 'TVL (USD)',
'mcap': 'Market Cap (USD)'
})
st.plotly_chart(scatter, use_container_width=True)
st.sidebar.write("---")
st.sidebar.write("### SunBurst filter 🔗")
groupby = st.sidebar.selectbox('Group by:', [['chain', 'category'], ['category', 'chain']])
nth = st.sidebar.slider('Top protocols by Category', min_value=1, max_value=5)
proto_agg = get_protocols_by_chain_category(tvl_mcap_df[tvl_mcap_df["chain"].isin(chains)], groupby, np.arange(0, nth, 1).tolist())
groupby.append("slug")
sunburst = px.sunburst(
proto_agg,
path=groupby,
values='tvl',
height=800,
title="SunBurst",
template="plotly_dark",)
st.plotly_chart(sunburst, use_container_width=True)
st.sidebar.write("# Data filters 🏷")
st.sidebar.code("🧳 New filters coming. \nReach us on discord \nif you want to propose one!")

View File

@@ -5,19 +5,19 @@ argon2-cffi-bindings==21.2.0
asttokens==2.0.5
attrs==21.4.0
backcall==0.2.0
backports.zoneinfo==0.2.1
beautifulsoup4==4.11.1
bleach==5.0.0
bleach==5.0.1
blinker==1.4
boltons==21.0.0
cachetools==5.2.0
certifi==2022.5.18.1
cffi==1.15.0
charset-normalizer==2.0.12
certifi==2022.6.15
cffi==1.15.1
charset-normalizer==2.1.0
click==8.1.3
commonmark==0.9.1
debugpy==1.6.0
debugpy==1.6.2
decorator==5.1.1
DeFiLlama==1.1.0
defusedxml==0.7.1
entrypoints==0.4
executing==0.8.3
@@ -27,38 +27,38 @@ gitdb==4.0.9
GitPython==3.1.27
glom==22.1.0
idna==3.3
importlib-metadata==4.11.4
importlib-resources==5.7.1
ipykernel==6.13.1
importlib-metadata==4.12.0
ipykernel==6.15.1
ipython==8.4.0
ipython-genutils==0.2.0
ipywidgets==7.7.0
ipywidgets==7.7.1
jedi==0.18.1
Jinja2==3.1.2
jsonschema==4.6.0
jupyter-client==7.3.3
jupyter-core==4.10.0
jsonschema==4.7.2
jupyter-client==7.3.4
jupyter-core==4.11.1
jupyterlab-pygments==0.2.2
jupyterlab-widgets==1.1.0
jupyterlab-widgets==1.1.1
MarkupSafe==2.1.1
matplotlib-inline==0.1.3
mistune==0.8.4
nbclient==0.6.4
nbclient==0.6.6
nbconvert==6.5.0
nbformat==5.4.0
nest-asyncio==1.5.5
notebook==6.4.12
numpy==1.22.4
numpy==1.23.1
packaging==21.3
pandas==1.4.2
pandas==1.4.3
pandocfilters==1.5.0
parso==0.8.3
patsy==0.5.2
pexpect==4.8.0
pickleshare==0.7.5
Pillow==9.1.1
plotly==5.8.0
Pillow==9.2.0
plotly==5.9.0
prometheus-client==0.14.1
prompt-toolkit==3.0.29
prompt-toolkit==3.0.30
protobuf==3.20.1
psutil==5.9.1
ptyprocess==0.7.0
@@ -74,30 +74,32 @@ pyrsistent==0.18.1
python-dateutil==2.8.2
pytz==2022.1
pytz-deprecation-shim==0.1.0.post0
pyzmq==23.1.0
requests==2.27.1
rich==12.4.4
pyzmq==23.2.0
requests==2.28.1
rich==12.5.1
scipy==1.8.1
semver==2.13.0
Send2Trash==1.8.0
six==1.16.0
smmap==5.0.0
soupsieve==2.3.2.post1
stack-data==0.2.0
stack-data==0.3.0
statsmodels==0.13.2
streamlit==1.10.0
tenacity==8.0.1
terminado==0.15.0
tinycss2==1.1.1
toml==0.10.2
toolz==0.11.2
tornado==6.1
traitlets==5.2.2.post1
typing_extensions==4.2.0
toolz==0.12.0
tornado==6.2
traitlets==5.3.0
typing_extensions==4.3.0
tzdata==2022.1
tzlocal==4.2
urllib3==1.26.9
urllib3==1.26.10
validators==0.20.0
watchdog==2.1.8
watchdog==2.1.9
wcwidth==0.2.5
webencodings==0.5.1
widgetsnbextension==3.6.0
zipp==3.8.0
widgetsnbextension==3.6.1
zipp==3.8.1

View File

@@ -1,54 +0,0 @@
import time
from pycoingecko import CoinGeckoAPI
import pandas as pd
import re
class CoinGeckoUtils:
def __init__(self):
self.connector = CoinGeckoAPI()
def get_all_coins_df(self):
coin_list = self.connector.get_coins_list()
return pd.DataFrame(coin_list)
def get_all_coins_markets_df(self):
coin_list = self.connector.get_coins_markets(vs_currency="USD")
return pd.DataFrame(coin_list)
def get_coin_tickers_by_id(self, coin_id: str):
coin_tickers = self.connector.get_coin_ticker_by_id(id=coin_id)
coin_tickers_df = pd.DataFrame(coin_tickers["tickers"])
coin_tickers_df["token_id"] = coin_id
return coin_tickers_df
def get_coin_tickers_by_id_list(self, coins_id: list):
dfs = []
for coin_id in coins_id:
df = self.get_coin_tickers_by_id(coin_id)
dfs.append(df)
time.sleep(1)
coin_tickers_df = pd.concat(dfs)
coin_tickers_df["exchange"] = coin_tickers_df["market"].apply(
lambda x: re.sub("Exchange", "", x["name"]))
coin_tickers_df.drop(columns="market", inplace=True)
coin_tickers_df["trading_pair"] = coin_tickers_df.base + "-" + coin_tickers_df.target
return coin_tickers_df
def get_all_exchanges_df(self):
exchanges_list = self.connector.get_exchanges_list()
return pd.DataFrame(exchanges_list)
def get_exchanges_markets_info_by_id_list(self, exchanges_id: list):
dfs = []
for exchange_id in exchanges_id:
df = pd.DataFrame(self.connector.get_exchanges_by_id(exchange_id)["tickers"])
dfs.append(df)
exchanges_spreads_df = pd.concat(dfs)
exchanges_spreads_df["exchange"] = exchanges_spreads_df["market"].apply(
lambda x: re.sub("Exchange", "", x["name"]))
exchanges_spreads_df.drop(columns="market", inplace=True)
exchanges_spreads_df["trading_pair"] = exchanges_spreads_df.base + "-" + exchanges_spreads_df.target
return exchanges_spreads_df

View File

@@ -1,62 +0,0 @@
import pandas as pd
import requests
from glom import *
class MinerUtils:
MARKETS_ENDPOINT = "https://api.hummingbot.io/bounty/markets"
@staticmethod
def reward_splitter(base, reward_dict):
tmp = {"rewards_HBOT": 0, "rewards_STABLE": 0, "rewards_base": 0, }
if "HBOT" in reward_dict:
tmp["rewards_HBOT"] += reward_dict["HBOT"]
if "USDC" in reward_dict:
tmp["rewards_STABLE"] += reward_dict["USDC"]
if "USDT" in reward_dict:
tmp["rewards_STABLE"] += reward_dict["USDT"]
if base in reward_dict:
tmp["rewards_base"] += reward_dict[base]
return pd.Series(tmp, dtype=float)
@staticmethod
def exchange_coingecko_id(exchange: str):
converter = {
"kucoin": "kucoin",
"binance": "binance",
"gateio": "gate",
"ascendex": "bitmax"
}
return converter[exchange]
def get_miner_stats_df(self):
miner_data = requests.get(self.MARKETS_ENDPOINT).json()
spec = {
'market_id': ('markets', ['market_id']),
'trading_pair': ('markets', ['trading_pair']),
'exchange': ('markets', ['exchange_name']),
'base': ('markets', ['base_asset']),
'quote': ('markets', ['quote_asset']),
'start_timestamp': ('markets', [("active_bounty_periods", ['start_timestamp'])]),
'end_timestamp': ('markets', [("active_bounty_periods", ['end_timestamp'])]),
'budget': ('markets', [("active_bounty_periods", ['budget'])]),
'spread_max': ('markets', [("active_bounty_periods", ['spread_max'])]),
'payout_asset': ('markets', [("active_bounty_periods", ['payout_asset'])]),
'return': ('markets', ['return']),
'last_snapshot_ts': ('markets', ['last_snapshot_ts']),
'hourly_payout_usd': ('markets', ['hourly_payout_usd']),
'bots': ('markets', ['bots']),
'last_hour_bots': ('markets', ['last_hour_bots']),
'filled_24h_volume': ('markets', ['filled_24h_volume']),
'weekly_reward_in_usd': ('markets', ['weekly_reward_in_usd']),
'weekly_reward': ('markets', ['weekly_reward']),
'market_24h_usd_volume': ('markets', ['market_24h_usd_volume'])
}
r = glom(miner_data, spec)
df = pd.DataFrame(r)
df = pd.concat([df, df.apply(lambda x: self.reward_splitter(x.base, x.weekly_reward), axis=1)], axis=1)
df["trading_pair"] = df.apply(lambda x: x.base + "-" + x.quote, axis=1)
df["exchange_coingecko_id"] = df.apply(lambda x: self.exchange_coingecko_id(x.exchange), axis=1)
return df