見出し画像

DefiLlama API (yields/APY編③)

前回の記事

今回はプール間のAPYを比較する

APYを比較

デフォルトの設定のところで、プロトコル名、チェーン名、シンボル名を設定可能

import requests
import pandas as pd

def get_pool_data(protocol=None, chain=None, symbol=None, top_n=10):
    """
    指定されたプロトコル、チェーン、シンボルに基づいて、yields.llama.fiからプールデータを取得し、整形する関数。

    Parameters:
    - protocol (str): プロトコル名(デフォルト: None)
    - chain (str): チェーン名(デフォルト: None)
    - symbol (str): シンボル名(デフォルト: None)
    - top_n (int): 表示するプールの数(デフォルト: 10)

    Returns:
    - df_pools_sorted (pd.DataFrame): 指定された条件に基づいてフィルタリングおよびソートされたプールデータ
    """
    yieldsUrl = 'https://yields.llama.fi'
    poolData = requests.get(yieldsUrl + '/pools')
    poolJson = poolData.json()

    # APIレスポンスからプールデータを抽出し、DataFrameに変換
    poolList = [[pool['symbol'], pool['chain'], pool['project'], pool['apy'], pool['tvlUsd']] for pool in poolJson['data']]
    df_pools = pd.DataFrame(poolList, columns=['Symbol', 'Chain', 'Project', 'APY', 'TVL'])

    # データの前処理
    df_pools = preprocess_data(df_pools)

    # プロトコル、チェーン、シンボルによるフィルタリング
    df_pools_filtered = filter_data(df_pools, protocol, chain, symbol)
    
    # APYの降順でソートし、上位top_n個のプールを選択
    df_pools_sorted = df_pools_filtered.sort_values('APY', ascending=False).head(top_n)
    
    return df_pools_sorted

def preprocess_data(df_pools):
    """
    プールデータの前処理を行う関数。

    Parameters:
    - df_pools (pd.DataFrame): 生のプールデータ

    Returns:
    - df_pools (pd.DataFrame): 前処理後のプールデータ
    """
    # APYから '%' を削除し、文字列の場合は浮動小数点数に変換
    df_pools['APY'] = df_pools['APY'].apply(lambda x: float(str(x).rstrip('%')))

    # TVLが0のプールを除外
    df_pools = df_pools[df_pools['TVL'] > 0]

    return df_pools

def filter_data(df_pools, protocol, chain, symbol):
    """
    プロトコル、チェーン、シンボルに基づいてプールデータをフィルタリングする関数。

    Parameters:
    - df_pools (pd.DataFrame): 前処理後のプールデータ
    - protocol (str): プロトコル名
    - chain (str): チェーン名
    - symbol (str): シンボル名

    Returns:
    - df_pools_filtered (pd.DataFrame): フィルタリング後のプールデータ
    """
    # プロトコル名が指定されている場合、部分一致でフィルタリング
    if protocol and protocol.lower() != 'all':
        df_pools['Project'] = df_pools['Project'].str.lower()
        df_pools = df_pools[df_pools['Project'].str.contains(protocol.lower())]
    
    # チェーン名が指定されている場合、完全一致でフィルタリング
    if chain and chain.lower() != 'all':
        df_pools['Chain'] = df_pools['Chain'].str.lower()
        df_pools = df_pools[df_pools['Chain'] == chain.lower()]
    
    # シンボル名が指定されている場合、部分一致でフィルタリング
    if symbol and symbol.lower() != 'all':
        df_pools['Symbol'] = df_pools['Symbol'].str.lower()
        df_pools_filtered = df_pools[df_pools['Symbol'].str.split('-').apply(lambda x: symbol.lower() in x)]
        if df_pools_filtered.empty:
            print(f"Warning: No pools found with the symbol '{symbol}'.")
            df_pools_filtered = pd.DataFrame(columns=df_pools.columns)  # 空のDataFrameを返す
    else:
        df_pools_filtered = df_pools

    return df_pools_filtered

def print_top_pools(df_pools_sorted, protocol, chain, symbol, top_n):
    """
    指定された条件に基づいて、上位のプールを表示する関数。

    Parameters:
    - df_pools_sorted (pd.DataFrame): ソートされたプールデータ
    - protocol (str): プロトコル名
    - chain (str): チェーン名
    - symbol (str): シンボル名
    - top_n (int): 表示するプールの数
    """
    print(f"選択されたプール: {protocol if protocol else 'ALL'} (Protocol), {chain if chain else 'ALL'} (Chain), {symbol if symbol else 'ALL'} (Symbol)")
    
    if df_pools_sorted.empty:
        print("検索条件に一致するプールが見つかりませんでした。")
    else:
        print(f"Top {min(top_n, len(df_pools_sorted))} プール (APY順):")
        df_pools_sorted['APY'] = df_pools_sorted['APY'].apply(lambda x: f"{x:.2f}%")
        df_pools_sorted['TVL'] = df_pools_sorted['TVL'].apply(lambda x: f"${x:,.2f}")
        print(df_pools_sorted[['Symbol', 'Chain', 'Project', 'APY', 'TVL']].reset_index(drop=True))

# デフォルトの設定
protocol = 'all' #all, uniswap
chain = 'all' #all, solana
symbol = 'all' #all, usdt
top_n = 10

# メイン処理
df_pools_sorted = get_pool_data(protocol, chain, symbol, top_n)
print_top_pools(df_pools_sorted, protocol, chain, symbol, top_n)

出力結果

選択されたプール: all (Protocol), all (Chain), all (Symbol)
Top 10 プール (APY順):
          Symbol    Chain Project         APY         TVL
0     SOL-TEMPLE   Solana    orca  637027.76%  $10,245.00
1     SOL-MOTION   Solana    orca  481600.81%  $25,395.00
2      WETH-USDT    Manta   gamma  428602.71%  $13,226.00
3      WETH-USDT    Manta   gamma  426318.88%  $13,262.00
4  STMATIC-MATIC  Polygon   beefy  315514.58%  $96,779.00
5      WETH-USDC    Manta   gamma  229072.91%  $14,516.00
6      WETH-USDC    Manta   gamma  228695.54%  $14,545.00
7   SOL-TRUMPWIF   Solana    orca   66746.98%  $33,980.00
8      SOL-LIGER   Solana    orca   66328.69%  $10,819.00
9       SOL-$CCP   Solana    orca   66316.40%  $18,219.00

さらなる改善案

  1. データの可視化
    グラフとか

  2. 出力のフォーマット
    CSVにしたり

  3. 監視
    ループさせて、自分の持ってるトークンのプールが出来たらアラートするとか

yields/APY編は以上になります。

いいなと思ったら応援しよう!