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}",
)