mcpField
L
liquidity-analysis

liquidity-analysis

github.com/agiprolabsデータ・データベース456446 回インストール8 週間前に更新
リポジトリ

liquidity-analysis について

Solana トークンの DEX プールを分析するスキルです。深度、スリッページ、プール構成から約定と退出のリスクを評価し、スコアリングやリスク検出のスクリプトを備えています。

主な機能

  1. 01トークンの DEX プールを検索
  2. 02流動性の深度とスリッページを測定
  3. 03集中流動性とプール構成を評価
  4. 04流動性リスクの兆候を検出
  5. 05スコアとポジション上限を算出

活用シーン

  1. 01取引前に売買の実行可能性を確認
  2. 02DEX プール間の流動性を比較
  3. 03推定スリッページからポジション上限を設定

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/agiprolabs/claude-trading-skills --skill liquidity-analysis

インストール後、Claude Code で/liquidity-analysisを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
data_sources.md
pool_types.md
slippage_curves.md
scripts/
analyze_liquidity.py
pool_comparison.py

詳細

流動性分析 — Solana トークンの DEX 深度評価

流動性分析では、取引のたびに次の3つの重要な問いに答えます。妥当な価格で取引に入れますか? 必要なときに取引から退出できますか? このプールは安全ですか? 分析しなければ、過度なスリッページ、退出の失敗、ラグプルのリスクがあります。

流動性分析が重要な理由

ポジションサイズ:最大ポジションサイズは、利用可能な流動性によって制限されます。TVL が $20K のプールで $10K のポジションを取ると、価格が大きく動きます。目安として、スリッページを1%未満に抑えるには、取引サイズをプールの深度の2%未満にしてください。

執行コスト:スリッページは直接的なコストです。5 SOL の買いで、スリッページが0.3%の場合と3%の場合の差は、エントリーとエグジットのたびに実際の損失となります。

ラグリスクの検出:流動性が薄いこと、プールが1つしかないこと、LP トークンがロックされていないこと、新しく作成されたプールは警告サインです。流動性分析を行えば、取引に入る前にこれらを検出できます。

エグジット計画:エントリー時の流動性とエグジット時の流動性は異なる場合があります。LP がロックされておらず、1つのウォレットが所有している場合、いつでも引き出される可能性があります。

主な概念

ロックされた合計価値(TVL)

プールに預け入れられた資産の合計価値です。100 SOL と、1枚あたり $0.01 の 1M TOKEN がある SOL/TOKEN プールの場合、TVL = 100 * SOL_price + 1M * $0.01 です。TVL だけでは不十分です。現在の価格帯における深度を確認する必要があります。

流動性深度

価格を X% 動かす前に、どれだけの量を取引できるかを示します。定積 AMM では、深度は均一です。集中流動性(CLMM)では、深度は価格帯によって変わり、現在価格の近くでは厚く、アクティブな価格帯の外では薄いか、ゼロになります。

集中係数(CLMM)

集中流動性プールでは、資本を狭い価格帯に集中させます。その価格帯内では流動性が深くなりますが、帯域外には流動性がありません。TVL が $50K で +/-5% の範囲に集中したプールは、その範囲内では $500K の定積プールと同等の深度を提供しますが、範囲外では深度がゼロです。

スリッページ曲線

スリッページは線形ではありません。取引サイズに対するスリッページをプロットすると、小さな取引では緩やかで、大きな取引では急になる曲線が得られます。曲線の形状は、プールの種類、TVL、流動性の集中度によって異なります。

プール構成

流動性の提供者は重要です。ロックされた LP トークンは引き出せないため、より安全です。片側のみの流動性は、プールのバランスが崩れていることを意味します。プールの経過日数は安定性の目安です。TVL が一貫している7日以上のプールのほうが信頼できます。

データソース

無料のものから包括的なものまで、相互に補完する4つのデータソースがあります。

ソース認証最適な用途制限事項
DexScreenerなしプールの簡易検索、liquidity.usdオンチェーンのプール詳細なし
Jupiter Quote APIなし任意のサイズでの実測スリッページ複数プールの集計値
BirdeyeAPI キー詳細なプールデータ、取引履歴無料プランではレート制限あり
オンチェーンRPC のみLP ロック状態、正確な準備金プログラムに関する知識が必要

エンドポイントの完全なドキュメントと使用例については、references/data_sources.md を参照してください。

分析の基本パイプライン

ステップ 1:プールを特定する

トークンのすべてのプールを取得します。ほとんどの Solana トークンには、Raydium、Orca、Meteora にまたがる複数のプールがあります。

import httpx

def get_pools(mint: str) -> list[dict]:
    """Fetch all DEX pools for a token from DexScreener."""
    resp = httpx.get(f"https://api.dexscreener.com/tokens/v1/solana/{mint}")
    resp.raise_for_status()
    pairs = resp.json()
    return [p for p in pairs if p.get("liquidity", {}).get("usd", 0) > 0]
ステップ 2:深度を測定する

各プールから流動性指標を抽出します。

def extract_depth(pool: dict) -> dict:
    """Extract liquidity metrics from a DexScreener pool."""
    return {
        "dex": pool.get("dexId", "unknown"),
        "liquidity_usd": pool.get("liquidity", {}).get("usd", 0),
        "volume_24h": pool.get("volume", {}).get("h24", 0),
        "pool_age_hours": _pool_age_hours(pool.get("pairCreatedAt", 0)),
        "pair_address": pool.get("pairAddress", ""),
    }
ステップ 3:スリッページを推定する

複数のサイズで Jupiter のクオートを使い、実測のスリッページ曲線を作成します。これにより、すべてのプールをまたいだ実際のルーティングを把握できます。

import httpx

SOL_MINT = "So11111111111111111111111111111111111111112"
LAMPORTS = 1_000_000_000

async def estimate_slippage(token_mint: str, sol_amounts: list[float]) -> list[dict]:
    """Query Jupiter for slippage at multiple trade sizes.

    Args:
        token_mint: Token mint address to buy.
        sol_amounts: List of SOL amounts to test (e.g., [0.1, 0.5, 1, 5, 10]).

    Returns:
        List of dicts with sol_amount, output_tokens, price_per_token, slippage_bps.
    """
    results = []
    base_price = None
    async with httpx.AsyncClient() as client:
        for sol in sol_amounts:
            lamports = int(sol * LAMPORTS)
            resp = await client.get(
                "https://api.jup.ag/quote/v1",
                params={
                    "inputMint": SOL_MINT,
                    "outputMint": token_mint,
                    "amount": str(lamports),
                    "slippageBps": 5000,
                },
            )
            if resp.status_code != 200:
                continue
            data = resp.json()
            out_amount = int(data["outAmount"])
            price = sol / out_amount if out_amount > 0 else 0
            if base_price is None:
                base_price = price
            slippage_bps = int((price - base_price) / base_price * 10000) if base_price > 0 else 0
            results.append({
                "sol_amount": sol,
                "output_tokens": out_amount,
                "price_per_token": price,
                "slippage_bps": max(0, slippage_bps),
            })
    return results
ステップ 4:集中度を評価する

CLMM プール(Orca Whirlpool、Raydium CLMM、Meteora DLMM)では、流動性が狭い価格帯に集中している場合があります。現在価格がアクティブな価格帯内にあるか、また流動性がどこまで深く続いているかを確認します。

def assess_concentration(pools: list[dict]) -> dict:
    """Assess concentration risk from pool data."""
    clmm_pools = [p for p in pools if p.get("dexId") in ("raydium", "orca") and "clmm" in p.get("labels", [])]
    cpmm_pools = [p for p in pools if p not in clmm_pools]

    total_clmm = sum(p.get("liquidity", {}).get("usd", 0) for p in clmm_pools)
    total_cpmm = sum(p.get("liquidity", {}).get("usd", 0) for p in cpmm_pools)
    total = total_clmm + total_cpmm

    return {
        "clmm_ratio": total_clmm / total if total > 0 else 0,
        "cpmm_liquidity": total_cpmm,
        "clmm_liquidity": total_clmm,
        "concentration_risk": "high" if total_clmm / total > 0.8 and total > 0 else "low",
    }
ステップ 5:流動性スコアを算出する

0(危険)から100(深く安全な流動性)までの複合スコアを算出します。

def compute_liquidity_score(
    total_liquidity_usd: float,
    pool_count: int,
    largest_pool_pct: float,
    oldest_pool_hours: float,
    max_slippage_bps_at_1sol: int,
) -> int:
    """Compute composite liquidity score (0-100).

    Components:
        Depth (40%): log-scaled TVL from $1K (0) to $1M+ (40)
        Diversity (15%): more pools = more resilient
        Concentration (15%): penalty if one pool dominates
        Age (15%): older pools are more reliable
        Slippage (15%): lower slippage = better
    """
    import math
    # Depth: 0-40 points
    depth = min(40, int(40 * math.log10(max(total_liquidity_usd, 1)) / 6))

    # Diversity: 0-15 points
    diversity = min(15, pool_count * 3)

    # Concentration: 0-15 points (penalty for single-pool dominance)
    concentration = int(15 * (1 - largest_pool_pct))

    # Age: 0-15 points (7+ days = full marks)
    age = min(15, int(15 * oldest_pool_hours / 168))

    # Slippage: 0-15 points
    slippage = max(0, 15 - max_slippage_bps_at_1sol // 10)

    return max(0, min(100, depth + diversity + concentration + age + slippage))

リスクフラグ

ポジションを建てる前に、以下の条件に該当するか確認してください。

フラグ条件リスクレベル
単一プールDEX プールが 1 つしかない高
流動性が低い合計 TVL < $10,000重大
新しいプールプール作成から 2 時間未満高
LP がロックされていないLP トークンがバーンまたはロックされていない中
出来高の不一致出来高 >> TVL(ウォッシュトレード)中
価格乖離プール間の価格差が >5%高
CLMM への流動性集中狭いレンジの CLMM に流動性の >80% が集中中
def detect_risk_flags(pools: list[dict]) -> list[str]:
    """Detect liquidity risk flags from pool data."""
    flags = []
    if len(pools) < 2:
        flags.append("SINGLE_POOL: Only 1 pool exists — exit may be difficult")

    total_liq = sum(p.get("liquidity", {}).get("usd", 0) for p in pools)
    if total_liq < 10_000:
        flags.append(f"THIN_LIQUIDITY: Total TVL ${total_liq:,.0f} < $10,000")

    for p in pools:
        age_ms = p.get("pairCreatedAt", 0)
        if age_ms > 0:
            import time
            age_hours = (time.time() * 1000 - age_ms) / 3_600_000
            if age_hours < 2:
                flags.append(f"NEW_POOL: {p.get('dexId')} pool is {age_hours:.1f}h old")

    volumes = [p.get("volume", {}).get("h24", 0) for p in pools]
    liqs = [p.get("liquidity", {}).get("usd", 0) for p in pools]
    for v, l, p in zip(volumes, liqs, pools):
        if l > 0 and v / l > 10:
            flags.append(f"VOLUME_MISMATCH: {p.get('dexId')} volume/TVL = {v/l:.1f}x")

    prices = [float(p.get("priceUsd", 0)) for p in pools if float(p.get("priceUsd", 0)) > 0]
    if len(prices) >= 2:
        deviation = (max(prices) - min(prices)) / min(prices)
        if deviation > 0.05:
            flags.append(f"PRICE_DEVIATION: {deviation:.1%} across pools")

    return flags

流動性に基づくポジションサイズ

スリッページを設定したしきい値未満に抑えられるよう、最大ポジションサイズを決めてください。

取引タイプ最大スリッページTVL に対する最大ポジション割合
スキャルプ0.5%(50 bps)1%
スイング2%(200 bps)2-5%
ポジション5%(500 bps)5-10%
def max_position_from_liquidity(
    total_liquidity_usd: float,
    max_slippage_pct: float = 1.0,
    trade_type: str = "swing",
) -> float:
    """Estimate maximum position size in USD based on liquidity.

    Uses rule-of-thumb: max_position = tvl_fraction * total_liquidity.
    For constant-product AMM, 1% of TVL produces ~2% slippage.

    Args:
        total_liquidity_usd: Total liquidity across all pools.
        max_slippage_pct: Maximum acceptable slippage percentage.
        trade_type: "scalp", "swing", or "position".

    Returns:
        Maximum position size in USD.
    """
    fractions = {"scalp": 0.01, "swing": 0.03, "position": 0.07}
    base_fraction = fractions.get(trade_type, 0.03)
    adjusted = base_fraction * (max_slippage_pct / 2.0)
    return total_liquidity_usd * adjusted

スリッページの推定

定積積方式の数式、CLMM モデル、実測データに基づく曲線フィッティングなど、詳細なスリッページ計算については、references/slippage_curves.md を参照してください。

定積積 AMM の主要な数式:

slippage = Δx / (x + Δx)

ここで、Δx は取引サイズ、x はプール内の入力トークンのリザーブです。リザーブが 100 SOL のプールで 1 SOL を取引する場合、スリッページは 1/101 = 0.99% です。

プールの種類

Solana DEX では、流動性の特性が異なるさまざまな AMM 設計が使われています。以下を含む詳しい説明については、references/pool_types.md を参照してください。

  • 定積積(Raydium V4、Orca Legacy):流動性が均一で、スリッページを予測しやすい
  • 集中流動性(Raydium CLMM、Orca Whirlpool):現在の価格では流動性が厚く、レンジ外ではゼロ
  • 動的 AMM(Meteora DLMM):手数料が適応し、ビン単位で流動性を管理

他のスキルとの連携

token-holder-analysis:ポジションを建てる前に LP トークンの保有者分布を確認してください。1 つのウォレットが LP トークンの >50% を保有し、それらがロックされていない場合、退出リスクが高くなります。

position-sizing:max_position_from_liquidity() の出力を上限として、ポジションサイズのモデルに入力してください。

slippage-modeling:このスキルの実測スリッページ曲線を、執行コストモデルの入力として使用してください。

birdeye-api:取引履歴や LP イベントを含む詳細なプールデータを取得します。

dexscreener-api:無料でプールを検索し、基本的な流動性指標を取得します。

ワークフローの例

# Full liquidity assessment for a token
import httpx

TOKEN = "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"  # BONK

# 1. Get pools
resp = httpx.get(f"https://api.dexscreener.com/tokens/v1/solana/{TOKEN}")
pools = [p for p in resp.json() if p.get("liquidity", {}).get("usd", 0) > 0]

# 2. Analyze
total_liq = sum(p["liquidity"]["usd"] for p in pools)
largest = max(p["liquidity"]["usd"] for p in pools)
largest_pct = largest / total_liq if total_liq > 0 else 1.0

# 3. Risk flags
flags = detect_risk_flags(pools)

# 4. Score
score = compute_liquidity_score(total_liq, len(pools), largest_pct, 1000, 50)

# 5. Position sizing
max_pos = max_position_from_liquidity(total_liq, max_slippage_pct=1.0, trade_type="swing")

print(f"Total Liquidity: ${total_liq:,.0f}")
print(f"Pools: {len(pools)}")
print(f"Score: {score}/100")
print(f"Max Position (swing, 1% slip): ${max_pos:,.0f}")
for f in flags:
    print(f"  WARNING: {f}")

ファイル

ファイル説明
references/slippage_curves.md定積積プールと CLMM プールのスリッページ計算、実測データに基づく曲線フィッティング
references/pool_types.mdSolana の AMM 設計:定積積、集中流動性、動的
references/data_sources.md流動性データの取得に使用する API エンドポイントとオンチェーン方式
scripts/analyze_liquidity.pyスコアリングとリスクフラグを含む、流動性の総合評価
scripts/pool_comparison.pyトークンの DEX 間でプールを比較

コメント