Aave v3 candles#
Fetch data#
[2]:
from tradingstrategy.client import Client
client = Client.create_jupyter_client()
Started Trading Strategy in Jupyter notebook environment, configuration is stored in /home/h25/.tradingstrategy
[3]:
import pandas as pd
import pyarrow as pa
from tradingstrategy.timebucket import TimeBucket
data: pa.Table = client.fetch_all_lending_protocol_reserves() # requires client version 0.13.6+
df: pd.DataFrame = data.to_pandas()
# Keep only the columns we actually need
df = df[["timestamp", "reserve_id", "liquidity_apr", "stable_borrow_apr", "variable_borrow_apr"]]
df = df.set_index("timestamp")
Compute candles#
[4]:
# We will compute the candles for each reserve separately
by_reserves = dict(iter(df.groupby("reserve_id")))
len(by_reserves)
[4]:
31
[5]:
# RESERVE_ID = 5 # WETH on Polygon
RESERVE_ID = 6 # USDT on Polygon
df_reserve = by_reserves[RESERVE_ID]
[6]:
def compute_candles(reserve_data: pd.DataFrame, bucket: str) -> dict[str, pd.DataFrame]:
"""Compute candles from reserve data.
Data must be indexed by timestamps and sorted in ascending order.
"""
candles = {}
candles["liquidity_apr"] = reserve_data["liquidity_apr"].resample(rule=bucket).agg({
"open": "first",
"close": "last",
"high": "max",
"low": "min",
}).dropna()
candles["stable_borrow_apr"] = reserve_data["stable_borrow_apr"].resample(rule=bucket).agg({
"open": "first",
"close": "last",
"high": "max",
"low": "min",
}).dropna()
candles["variable_borrow_apr"] = reserve_data["variable_borrow_apr"].resample(rule=bucket).agg({
"open": "first",
"close": "last",
"high": "max",
"low": "min",
}).dropna()
return candles
[7]:
BUCKET_WIDTH = "6H" # As accepted by the DataFrame.resample() method
candles = compute_candles(df_reserve, bucket=BUCKET_WIDTH)
Plot the candles#
[8]:
import plotly.graph_objects as go
def plot_candles(candles, plot_title, y_title):
candlesticks = go.Candlestick(
x=candles.index,
open=candles["open"],
close=candles["close"],
high=candles["high"],
low=candles["low"],
)
fig = go.Figure(candlesticks)
fig.update_layout(title=plot_title, height=500)
fig.update_yaxes(title=y_title, showgrid=True, rangemode="tozero")
fig.show()
[9]:
reserve_id = df_reserve['reserve_id'][0]
row_subset = slice(-100, None) # last 100 candles
plot_candles(
candles=candles["liquidity_apr"][row_subset],
plot_title=f"Liquidity APR {BUCKET_WIDTH} candles for reserve ID {reserve_id}",
y_title="Liquidity APR",
)
[10]:
plot_candles(
candles=candles["stable_borrow_apr"][row_subset],
plot_title=f"Stable borrow APR {BUCKET_WIDTH} candles for reserve ID {reserve_id}",
y_title="Stable borrow APR",
)
[11]:
plot_candles(
candles=candles["variable_borrow_apr"][row_subset],
plot_title=f"Variable borrow APR {BUCKET_WIDTH} candles for reserve ID {reserve_id}",
y_title="Variable borrow APR",
)
Plot the APR lines#
This is for easier visual comparison with the graphs on AAVE v3 website
[12]:
def compute_lines(reserve_data: pd.DataFrame, bucket: str) -> dict[str, pd.DataFrame]:
"""Compute line chart data from reserve data.
Data must be indexed by timestamps and sorted in ascending order.
"""
result = pd.DataFrame()
result["liquidity_apr"] = reserve_data["liquidity_apr"].resample(rule=bucket).mean()
result["stable_borrow_apr"] = reserve_data["stable_borrow_apr"].resample(rule=bucket).mean()
result["variable_borrow_apr"] = reserve_data["variable_borrow_apr"].resample(rule=bucket).mean()
result.dropna()
return result
[13]:
line_data = compute_lines(df_reserve, bucket=BUCKET_WIDTH)
[14]:
import plotly.express as px
def plot_lines(data, plot_title):
fig = px.line(data, title=plot_title, height=300)
fig.show()
[15]:
plot_lines(
data=line_data[["stable_borrow_apr", "variable_borrow_apr"]][-120:],
plot_title=f"Borrow APR {BUCKET_WIDTH} for reserve ID {reserve_id}",
)