token-holder-analysis について
Solana トークンの保有者分布と集中リスクを分析するスキルです。オンチェーンデータと複数の分布指標を組み合わせ、バンドラー、スナイパー、開発者の保有状況も調べます。
主な機能
- 01上位 N 保有者の割合を計算
- 02Gini・HHI・Nakamoto 指標を算出
- 03バンドラーとスナイパーのパターンを検出
- 04開発者保有のリスクを評価
- 05プログラムとプールのアカウントを除外
活用シーン
- 01取引前のトークン集中度チェック
- 02複数トークンの分布リスク比較
- 03初期購入者の協調的な動きを確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ agiprolabs/ claude-trading-skills --skill token-holder-analysisインストール後、Claude Code で/token-holder-analysisを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/concentration_metrics.mddata_sources.mdinsider_patterns.mdscripts/analyze_holders.pyconcentration_scanner.py詳細
トークン保有者の分析 — 集中度、分布、リスク
トークンを誰が保有しているのか、所有権がどの程度集中しているのか、インサイダーの保有パターンがリスクを示唆しているかを分析します。これは取引前に欠かせない安全確認です。保有が集中していると、少数のウォレットが価格を暴落させる可能性があります。
クイックスタート
import httpx
import math
# Using Helius DAS API for holder data
HELIUS_KEY = os.getenv("HELIUS_API_KEY", "")
HELIUS = f"https://mainnet.helius-rpc.com/?api-key={HELIUS_KEY}"
# Or using SolanaTracker for holder + risk data
ST_KEY = os.getenv("SOLANATRACKER_API_KEY", "")
ST = "https://data.solanatracker.io"
# Get top holders via RPC
def get_top_holders(mint: str) -> list[dict]:
resp = httpx.post(HELIUS, json={
"jsonrpc": "2.0", "id": 1,
"method": "getTokenLargestAccounts",
"params": [mint],
})
return resp.json()["result"]["value"]
holders = get_top_holders("TOKEN_MINT")
データソース
| ソース | 提供される情報 | 認証 |
|---|---|---|
Solana RPC (getTokenLargestAccounts) | 上位20の保有者、供給量 | RPC キー |
Helius DAS (getAsset, token accounts) | パース済み保有者データ、メタデータ | API キー |
SolanaTracker (/tokens/{t}/holders/top) | 上位100の保有者、バンドラー検出 | API キー |
Birdeye (/defi/token_security) | 上位10%、作成者の残高、凍結/ミント権限 | API キー |
集中度の指標
上位N保有者の割合
最も単純な指標です。上位N人の保有者が供給量の何%を支配しているでしょうか?
def top_n_percentage(holders: list[dict], supply: int, n: int = 10) -> float:
"""Calculate percentage held by top N holders.
Args:
holders: Sorted list of holders (largest first).
supply: Total token supply.
n: Number of top holders.
Returns:
Percentage (0-100) held by top N.
"""
top_n_amount = sum(int(h.get("amount", 0)) for h in holders[:n])
return top_n_amount / supply * 100 if supply > 0 else 0
リスクのしきい値:
- 上位10が30%未満:十分に分散
- 上位10が30~50%:中程度の集中
- 上位10が50~80%:高い集中 — 大幅な売り抜けリスク
- 上位10が80%超:極端な集中 — 少数のウォレットが支配している可能性が高い
ジニ係数
トークン分布の不平等度を測定します(0=完全に平等、1=1人の保有者がすべてを保有)。
def gini_coefficient(amounts: list[float]) -> float:
"""Calculate Gini coefficient for holder distribution.
Args:
amounts: List of holder amounts (any order).
Returns:
Gini coefficient between 0 and 1.
"""
if not amounts or all(a == 0 for a in amounts):
return 0.0
sorted_amounts = sorted(amounts)
n = len(sorted_amounts)
cumsum = sum((i + 1) * a for i, a in enumerate(sorted_amounts))
total = sum(sorted_amounts)
return (2 * cumsum) / (n * total) - (n + 1) / n
暗号資産トークンにおける解釈:
- ジニ係数 < 0.6:珍しい状態で、非常によく分散されています
- ジニ係数 0.6~0.8:確立されたトークンでは一般的です
- ジニ係数 0.8~0.95:新しいトークンではよく見られます
- ジニ係数 > 0.95:極端な集中で、高リスクです
ハーフィンダール・ハーシュマン指数(HHI)
市場の集中度を測定します。市場シェアの二乗の合計です。
def hhi(amounts: list[float]) -> float:
"""Calculate HHI for holder concentration.
Args:
amounts: List of holder amounts.
Returns:
HHI value (0-10000). Higher = more concentrated.
"""
total = sum(amounts)
if total == 0:
return 0.0
shares = [a / total * 100 for a in amounts]
return sum(s ** 2 for s in shares)
解釈:
- HHI < 1500:競争的(集中していない)
- HHI 1500~2500:中程度の集中
- HHI > 2500:高い集中
ナカモト係数
供給量の50%超を支配するために必要な最小保有者数です。
def nakamoto_coefficient(amounts: list[float]) -> int:
"""Calculate Nakamoto coefficient (holders needed for 51%).
Args:
amounts: Sorted list of holder amounts (largest first).
Returns:
Number of holders needed for majority control.
"""
total = sum(amounts)
if total == 0:
return 0
threshold = total * 0.51
cumulative = 0
for i, amount in enumerate(sorted(amounts, reverse=True)):
cumulative += amount
if cumulative >= threshold:
return i + 1
return len(amounts)
インサイダー検出のパターン
バンドラー検出
バンドラーはアトミックなトランザクションバンドル(Jito 経由)を使い、トークンのローンチ時に協調して購入します。検出の手がかり:
def detect_bundler_patterns(holders: list[dict], first_buyers: list[dict]) -> dict:
"""Identify potential bundler activity.
Args:
holders: Current top holders.
first_buyers: Early buyers from SolanaTracker /first-buyers endpoint.
Returns:
Bundler risk analysis.
"""
early_still_holding = [
b for b in first_buyers
if b.get("holdingAmount", 0) > 0
]
early_holder_pct = sum(
b.get("holdingPercentage", 0) for b in early_still_holding
)
return {
"early_buyers_count": len(first_buyers),
"still_holding_count": len(early_still_holding),
"early_holder_pct": round(early_holder_pct, 2),
"risk": "HIGH" if early_holder_pct > 20 else
"MODERATE" if early_holder_pct > 10 else "LOW",
}
開発者の保有
作成者のウォレットにトークンが残っていることは、リスクの兆候です。
def check_developer_risk(token_data: dict) -> dict:
"""Check developer wallet holdings and authority.
Args:
token_data: Token info from SolanaTracker or Birdeye.
Returns:
Developer risk assessment.
"""
risk = token_data.get("risk", {})
flags = []
# Check creator balance (from Birdeye security endpoint)
creator_balance = token_data.get("creatorBalance", 0)
if creator_balance > 10:
flags.append(f"Creator holds {creator_balance:.1f}% of supply")
# Check mint authority
if token_data.get("mintAuthority") or token_data.get("ownerAddress"):
flags.append("Mint authority NOT renounced — supply can increase")
# Check freeze authority
if token_data.get("freezeAuthority") or token_data.get("freezeable"):
flags.append("Freeze authority enabled — tokens can be frozen")
return {
"flags": flags,
"risk_level": "HIGH" if len(flags) >= 2 else
"MODERATE" if len(flags) == 1 else "LOW",
}
スナイパー検出
スナイパーはトークン作成後、最初の数秒/ブロック以内に購入します。
def analyze_sniper_concentration(first_buyers: list[dict], total_supply: float) -> dict:
"""Analyze sniper impact on holder distribution.
Args:
first_buyers: First buyers data from SolanaTracker.
total_supply: Total token supply.
Returns:
Sniper concentration analysis.
"""
# Snipers typically buy in first 10 seconds
snipers = first_buyers[:10] # first N buyers are potential snipers
sniper_holding = sum(b.get("holdingAmount", 0) for b in snipers)
sniper_pct = sniper_holding / total_supply * 100 if total_supply > 0 else 0
return {
"sniper_count": len(snipers),
"sniper_holding_pct": round(sniper_pct, 2),
"sniper_still_holding": sum(1 for s in snipers if s.get("holdingAmount", 0) > 0),
"risk": "HIGH" if sniper_pct > 15 else
"MODERATE" if sniper_pct > 5 else "LOW",
}
完全な分析パイプライン
def full_holder_analysis(mint: str) -> dict:
"""Run complete holder analysis for a token.
Combines RPC, SolanaTracker, and computed metrics.
"""
# 1. Get supply and top holders via RPC
supply_result = rpc_call("getTokenSupply", [mint])
total_supply = int(supply_result["result"]["value"]["amount"])
holders = get_top_holders(mint)
amounts = [int(h["amount"]) for h in holders]
# 2. Compute concentration metrics
metrics = {
"total_supply": total_supply,
"holder_count": len(holders),
"top_1_pct": top_n_percentage(holders, total_supply, 1),
"top_5_pct": top_n_percentage(holders, total_supply, 5),
"top_10_pct": top_n_percentage(holders, total_supply, 10),
"top_20_pct": top_n_percentage(holders, total_supply, 20),
"gini": round(gini_coefficient(amounts), 4),
"hhi": round(hhi(amounts), 1),
"nakamoto": nakamoto_coefficient(amounts),
}
# 3. Risk classification
t10 = metrics["top_10_pct"]
if t10 > 80:
metrics["risk"] = "EXTREME"
elif t10 > 50:
metrics["risk"] = "HIGH"
elif t10 > 30:
metrics["risk"] = "MODERATE"
else:
metrics["risk"] = "LOW"
return metrics
リスク分類の概要
| 指標 | 低リスク | 中程度 | 高リスク | 極端 |
|---|---|---|---|---|
| 上位10の割合 | <30% | 30-50% | 50-80% | >80% |
| ジニ係数 | <0.7 | 0.7-0.85 | 0.85-0.95 | >0.95 |
| HHI | <1500 | 1500-2500 | 2500-5000 | >5000 |
| ナカモト係数 | >10 | 5-10 | 2-4 | 1 |
| ミント権限 | 放棄済み | — | 有効 | 有効 + 開発者の保有率が高い |
| 凍結権限 | 無効 | — | 有効 | 有効 + 流動性が低い |
既知の除外対象
保有者の集中度を計算する際、個人の保有者ではなくプログラム/プールである以下のアドレスを除外してください。
- DEX プールアドレス(Raydium、Orca、Meteora のプール)
- トークンプログラムのボールト
- ブリッジのエスクローアカウント
- 既知のバーンアドレス
KNOWN_PROGRAMS = {
"5Q544fKrFoe6tsEbD7S8EmxGTJYAKtTVhAW5Q5pge4j1", # Raydium authority
"GThUX1Atko4tqhN2NaiTazWSeFWMuiUvfFnyJyUghFMJ", # Orca authority
# Add more as needed
}
def filter_real_holders(holders: list[dict]) -> list[dict]:
"""Remove known program/pool accounts from holder list."""
return [h for h in holders if h.get("address") not in KNOWN_PROGRAMS]
ファイル
参考資料
references/concentration_metrics.md— ジニ係数、HHI、ナカモト係数の数式と導出references/insider_patterns.md— バンドラー、スナイパー、開発者の検出方法references/data_sources.md— 各 API ソースから保有者データを取得する方法
スクリプト
scripts/analyze_holders.py— 保有者の完全な分析:保有者データの取得、指標の計算、リスクレポートの生成scripts/concentration_scanner.py— 複数のトークンをスキャンして集中リスクを検出
コメント
Markdown 対応