仮想通貨のオンチェーン分析入門 — Glassnode・Dune・Nansen・Arkhamの活用
オンチェーン分析とは
オンチェーン分析とは、ブロックチェーン上に記録されたトランザクションデータを分析し、市場参加者の行動パターンや資金フローを解読する手法です。伝統的な金融市場では非公開の情報(ファンドの売買記録、銀行間取引など)が、暗号資産では全てブロックチェーン上で公開されているため、オンチェーンデータは投資判断の強力な武器となります。
テクニカル分析 vs オンチェーン分析
| 分析手法 | データソース | 特徴 | 限界 |
|---|---|---|---|
| テクニカル分析 | 価格・出来高 | パターン認識、サポート/レジスタンス | 価格データのみで内部状態が不明 |
| ファンダメンタル分析 | 開発活動・エコシステム | プロジェクトの本質的価値を評価 | 短期的な価格変動を捉えにくい |
| オンチェーン分析 | ブロックチェーンデータ | 実際の資金フロー・保有行動を追跡 | データ解釈に専門知識が必要 |
| センチメント分析 | SNS・ニュース | 市場心理を数値化 | ノイズが多い |
主要オンチェーン指標
MVRV(Market Value to Realized Value)
MVRVは時価総額と実現時価総額の比率で、市場が過熱しているか割安かを判断する代表的指標です。
def calculate_mvrv(market_cap: float, realized_cap: float) -> dict:
"""
MVRV比率の計算と市場状態の判定
market_cap: 現在の時価総額(価格 × 流通供給量)
realized_cap: 実現時価総額(各UTXOの最終移動時の価格で計算した時価総額)
"""
mvrv = market_cap / realized_cap
if mvrv > 3.5:
signal = "強い売りシグナル(市場過熱)"
zone = "danger"
elif mvrv > 2.5:
signal = "利確検討ゾーン"
zone = "caution"
elif mvrv > 1.0:
signal = "ニュートラル(利益保有者が多数)"
zone = "neutral"
elif mvrv > 0.8:
signal = "割安ゾーン(蓄積期間)"
zone = "opportunity"
else:
signal = "強い買いシグナル(降伏売り後の底値圏)"
zone = "strong_buy"
return {
"mvrv": round(mvrv, 3),
"signal": signal,
"zone": zone,
"unrealized_profit_pct": round((mvrv - 1) * 100, 1)
}
# BTCの例(仮定値)
result = calculate_mvrv(
market_cap=1_800_000_000_000, # $1.8T
realized_cap=750_000_000_000 # $750B
)
print(result)
# → {'mvrv': 2.4, 'signal': 'ニュートラル(利益保有者が多数)', 'zone': 'neutral', 'unrealized_profit_pct': 140.0}
SOPR(Spent Output Profit Ratio)
SOPRは使用されたUTXOの売却時価格と取得時価格の比率です。
| SOPR値 | 意味 | 市場への示唆 |
|---|---|---|
| > 1.05 | 大きな利益確定 | 売り圧力の増加 |
| 1.0〜1.05 | 小幅な利益確定 | 健全な上昇トレンド |
| = 1.0 | 損益分岐点 | 重要なサポート/レジスタンスライン |
| 0.95〜1.0 | 小幅な損切り | 弱気心理の兆候 |
| < 0.95 | 大きな降伏売り | 底値圏の可能性 |
def analyze_sopr_trend(sopr_values: list[float], window: int = 14) -> dict:
"""
SOPR値のトレンド分析
sopr_values: 日次SOPRの時系列データ
window: 移動平均のウィンドウ幅
"""
if len(sopr_values) < window:
return {"error": "データ不足"}
recent = sopr_values[-window:]
sma = sum(recent) / len(recent)
current = sopr_values[-1]
# SOPRが1を下回って反発 → 底値シグナル
crossed_above_one = (
sopr_values[-2] < 1.0 and sopr_values[-1] >= 1.0
)
return {
"current_sopr": round(current, 4),
"sma_14": round(sma, 4),
"trend": "上昇" if current > sma else "下降",
"crossed_above_one": crossed_above_one,
"interpretation": (
"底値反発シグナル" if crossed_above_one
else "利益確定フェーズ" if current > 1.02
else "蓄積フェーズ" if 0.98 < current < 1.02
else "降伏売りフェーズ"
)
}
NVT(Network Value to Transactions)
NVTはネットワーク価値(時価総額)と実際のトランザクション量の比率で、「暗号資産のPER」とも呼ばれます。
NVT = 時価総額 / 日次トランザクション量(USD建て)
| NVT値 | 解釈 |
|---|---|
| < 20 | ネットワーク利用に対して割安 |
| 20-40 | 適正範囲 |
| 40-65 | やや割高 |
| > 65 | バブル領域(投機的) |
Exchange Netflow(取引所ネットフロー)
取引所へのBTC入出金フローは、売り圧力と蓄積行動のバロメーターです。
| フロー方向 | 意味 | 解釈 |
|---|---|---|
| 取引所への大量入金 | 売却準備 | 短期的な売り圧力の増加 |
| 取引所からの大量出金 | セルフカストディ | 長期保有意向(蓄積) |
| 穏やかな入出金 | 通常の取引活動 | 方向性なし |
アクティブアドレス数
ネットワークの利用状況を測る基本指標です。
def analyze_active_addresses(
daily_active: list[int],
price: list[float]
) -> dict:
"""
アクティブアドレス数と価格のダイバージェンス分析
daily_active: 日次アクティブアドレス数
price: 日次終値
"""
# 直近30日の変化率
addr_change = (daily_active[-1] - daily_active[-30]) / daily_active[-30]
price_change = (price[-1] - price[-30]) / price[-30]
divergence = None
if price_change > 0.1 and addr_change < -0.05:
divergence = "弱気ダイバージェンス(価格上昇 vs アドレス減少)"
elif price_change < -0.1 and addr_change > 0.05:
divergence = "強気ダイバージェンス(価格下落 vs アドレス増加)"
return {
"address_change_30d": f"{addr_change*100:.1f}%",
"price_change_30d": f"{price_change*100:.1f}%",
"divergence": divergence,
"network_health": "健全" if addr_change > 0 else "注意"
}
その他の重要指標
| 指標 | 計算方法 | 用途 |
|---|---|---|
| STH-SOPR | 短期保有者のSOPR | 短期トレーダーの損益状態 |
| LTH-SOPR | 長期保有者のSOPR | 長期投資家の行動 |
| NUPL | (時価総額 - 実現時価総額) / 時価総額 | 市場全体の未実現損益 |
| Puell Multiple | 日次マイナー収入 / 365日MA | マイナーの収益性 |
| Reserve Risk | 価格 / (HODL Bank) | 長期保有者の確信度 |
| Supply in Profit | 取得価格が現在価格以下のBTC量 | 含み益の割合 |
主要分析ツール
Glassnode
Glassnodeはビットコインを中心としたオンチェーンデータの最大手プロバイダーです。
料金プラン
| プラン | 月額 | 主な特徴 |
|---|---|---|
| Free | $0 | 基本指標、Tier 1のみ、時間足制限あり |
| Advanced | $39 | Tier 1-2指標、日足データ、アラート |
| Professional | $799 | 全指標、分足データ、API完全アクセス |
| Enterprise | 要相談 | カスタムデータ、専用サポート |
API活用例
import requests
class GlassnodeClient:
BASE_URL = "https://api.glassnode.com"
def __init__(self, api_key: str):
self.api_key = api_key
def get_metric(
self,
metric: str,
asset: str = "BTC",
interval: str = "24h",
since: int = None,
until: int = None
) -> list[dict]:
"""Glassnodeからオンチェーンメトリクスを取得"""
params = {
"a": asset,
"api_key": self.api_key,
"i": interval,
}
if since:
params["s"] = since
if until:
params["u"] = until
response = requests.get(
f"{self.BASE_URL}/v1/metrics/{metric}",
params=params
)
response.raise_for_status()
return response.json()
def get_mvrv(self, asset: str = "BTC") -> list[dict]:
"""MVRV比率を取得"""
return self.get_metric("market/mvrv", asset)
def get_sopr(self, asset: str = "BTC") -> list[dict]:
"""SOPRを取得"""
return self.get_metric("indicators/sopr", asset)
def get_exchange_netflow(self, asset: str = "BTC") -> list[dict]:
"""取引所ネットフローを取得"""
return self.get_metric(
"transactions/transfers_volume_exchanges_net",
asset
)
# 使用例
# client = GlassnodeClient(api_key="YOUR_API_KEY")
# mvrv_data = client.get_mvrv("BTC")
Dune Analytics
Dune AnalyticsはSQLクエリでブロックチェーンデータを分析できるオープンプラットフォームです。
特徴
| 機能 | 詳細 |
|---|---|
| 対応チェーン | Ethereum, Polygon, Arbitrum, Optimism, Solana, Base等 |
| クエリ言語 | DuneSQL(Trino/Prestoベース) |
| データ更新 | リアルタイムに近い更新 |
| 共有 | ダッシュボードの公開・フォーク |
| 料金 | 無料枠あり、Pro ($349/月)、Premium |
クエリ例:Uniswap V3 日次取引量
-- Uniswap V3のETH/USDC プール日次取引量
SELECT
date_trunc('day', block_time) AS trade_date,
COUNT(*) AS trade_count,
SUM(
CASE
WHEN token_bought_symbol = 'WETH'
THEN token_bought_amount
ELSE token_sold_amount
END
) AS eth_volume,
SUM(amount_usd) AS volume_usd
FROM
uniswap_v3_ethereum.trades
WHERE
block_time >= NOW() - INTERVAL '30' DAY
AND (
token_bought_symbol IN ('WETH', 'USDC')
AND token_sold_symbol IN ('WETH', 'USDC')
)
GROUP BY 1
ORDER BY 1 DESC;
クエリ例:大口ウォレットのERC-20移動
-- 直近7日間で$1M以上のERC-20トークン移動を検出
SELECT
block_time,
"from" AS sender,
"to" AS receiver,
contract_address AS token_address,
symbol,
amount,
amount_usd
FROM
erc20_ethereum.transfers
WHERE
block_time >= NOW() - INTERVAL '7' DAY
AND amount_usd > 1000000
ORDER BY
amount_usd DESC
LIMIT 50;
Nansen
Nansenはウォレットにラベルを付与し、スマートマネーの動向を追跡できるプラットフォームです。
主要機能
| 機能 | 説明 |
|---|---|
| Smart Money | 高いリターンを出しているウォレットの追跡 |
| Token God Mode | トークンの保有者・フロー分析 |
| NFT Paradise | NFTの取引分析 |
| Wallet Profiler | 特定ウォレットの損益分析 |
| Hot Contracts | トレンドのスマートコントラクト検出 |
| Chain Overview | チェーン横断のアクティビティ概要 |
スマートマネー追跡の方法
Nansenのスマートマネー分類:
┌─────────────────────────────────────┐
│ Smart Money Labels │
├─────────────────────────────────────┤
│ 🏦 Fund (VC・ヘッジファンド) │
│ 🐋 Whale ($1M以上の保有) │
│ 📈 Smart DEX Trader (高勝率DEXトレーダー)│
│ 💎 Diamond Hands (長期ホルダー) │
│ 🎯 Flash Boys (MEV/アービトラージ) │
│ 🏛️ CEX (取引所ウォレット) │
└─────────────────────────────────────┘
料金プラン
| プラン | 月額 | 主な用途 |
|---|---|---|
| Free | $0 | 基本的なウォレット検索 |
| Pioneer | $99 | Smart Money追跡、Token分析 |
| Voyager | $499 | 全機能、高度なアラート |
| Enterprise | 要相談 | API、カスタム分析 |
Arkham Intelligence
Arkhamはブロックチェーンアドレスの実体(エンティティ)を特定することに特化したプラットフォームです。
特徴
| 機能 | 詳細 |
|---|---|
| Entity Identification | ウォレットの所有者をAIで特定 |
| Transaction Tracking | エンティティ間の資金フロー可視化 |
| Alerts | 大口移動・特定アドレスの活動通知 |
| Investigations | ハッキング・不正資金の追跡 |
| Intel Exchange | オンチェーンインテリジェンスの売買市場 |
Arkhamの活用シナリオ
1. ウェイルウォッチング
- 大口アドレスの取引所入出金を監視
- 売り圧力の事前検知
2. ファンド追跡
- VCのトークン売却タイミングを監視
- ロック解除後の行動パターン分析
3. ハッキング追跡
- 盗難資金のフロー分析
- ミキサー/ブリッジ利用の検出
4. プロジェクトデューデリジェンス
- チームウォレットの資金管理確認
- トレジャリーの動向監視
DefiLlama
DefiLlamaはDeFiプロトコルのTVL(Total Value Locked)データを集約するオープンソースプラットフォームです。
主要指標
| 指標 | 意味 | 活用法 |
|---|---|---|
| TVL | ロックされた総資産額 | プロトコルの規模評価 |
| TVL変化率 | TVLの増減率 | 資金フローのトレンド |
| Mcap/TVL | 時価総額 / TVL | トークンの割高/割安判断 |
| Revenue | プロトコル収益 | 収益性の評価 |
| Fees | プロトコル手数料 | ユーザー需要の指標 |
APIの活用
import requests
class DefiLlamaClient:
BASE_URL = "https://api.llama.fi"
def get_protocol_tvl(self, protocol: str) -> dict:
"""特定プロトコルのTVL詳細を取得"""
response = requests.get(f"{self.BASE_URL}/protocol/{protocol}")
response.raise_for_status()
return response.json()
def get_chain_tvl(self, chain: str) -> list[dict]:
"""チェーン別TVL推移を取得"""
response = requests.get(f"{self.BASE_URL}/v2/historicalChainTvl/{chain}")
response.raise_for_status()
return response.json()
def get_top_protocols(self, n: int = 20) -> list[dict]:
"""TVL上位プロトコルを取得"""
response = requests.get(f"{self.BASE_URL}/protocols")
response.raise_for_status()
protocols = response.json()
sorted_protocols = sorted(
protocols, key=lambda x: x.get("tvl", 0), reverse=True
)
return [
{
"name": p["name"],
"tvl": p.get("tvl", 0),
"chain": p.get("chain", "Multi"),
"category": p.get("category", "N/A"),
"change_1d": p.get("change_1d", 0),
"change_7d": p.get("change_7d", 0),
}
for p in sorted_protocols[:n]
]
# 使用例
# client = DefiLlamaClient()
# aave_data = client.get_protocol_tvl("aave")
# top = client.get_top_protocols(10)
無料 vs 有料ツール比較
| ツール | 無料機能 | 有料機能 | おすすめ用途 |
|---|---|---|---|
| Glassnode | 基本指標(日足) | 全指標、分足、API | BTC/ETHの長期分析 |
| Dune Analytics | クエリ実行、ダッシュボード閲覧 | 高速クエリ、プライベートクエリ | カスタム分析、DeFi調査 |
| Nansen | 基本的なウォレット検索 | Smart Money追跡、アラート | スマートマネー追跡 |
| Arkham | 基本的なエンティティ検索 | 高度なアラート、API | ウォレット特定、不正追跡 |
| DefiLlama | 全機能無料 | — | DeFi TVL分析 |
| CryptoQuant | 基本指標 | プロ指標、API | 取引所フロー分析 |
| Santiment | 一部指標 | 全指標、ソーシャル分析 | 指標+センチメント統合 |
アルゴリズム戦略への組み込み
オンチェーンデータを活用したシグナル生成
from dataclasses import dataclass
from enum import Enum
class Signal(Enum):
STRONG_BUY = "強い買い"
BUY = "買い"
NEUTRAL = "中立"
SELL = "売り"
STRONG_SELL = "強い売り"
@dataclass
class OnChainSignals:
mvrv: float
sopr: float
exchange_netflow: float # BTC単位(正=流入、負=流出)
active_addresses_change: float # 前月比変化率
nvt: float
def generate_composite_signal(signals: OnChainSignals) -> dict:
"""
複数のオンチェーン指標を統合してシグナルを生成
各指標にスコア(-2〜+2)を付与し、加重平均で最終シグナルを決定
"""
scores = {}
# MVRV スコアリング
if signals.mvrv > 3.5:
scores["mvrv"] = -2
elif signals.mvrv > 2.5:
scores["mvrv"] = -1
elif signals.mvrv > 1.0:
scores["mvrv"] = 0
elif signals.mvrv > 0.8:
scores["mvrv"] = 1
else:
scores["mvrv"] = 2
# SOPR スコアリング
if signals.sopr > 1.05:
scores["sopr"] = -1
elif signals.sopr > 1.0:
scores["sopr"] = 0
elif signals.sopr > 0.95:
scores["sopr"] = 1
else:
scores["sopr"] = 2
# 取引所ネットフロー スコアリング(大量流入は売り圧力)
if signals.exchange_netflow > 10000:
scores["netflow"] = -2
elif signals.exchange_netflow > 1000:
scores["netflow"] = -1
elif signals.exchange_netflow > -1000:
scores["netflow"] = 0
elif signals.exchange_netflow > -10000:
scores["netflow"] = 1
else:
scores["netflow"] = 2
# アクティブアドレス変化率
if signals.active_addresses_change > 0.1:
scores["active_addr"] = 1
elif signals.active_addresses_change > -0.05:
scores["active_addr"] = 0
else:
scores["active_addr"] = -1
# NVT スコアリング
if signals.nvt > 65:
scores["nvt"] = -2
elif signals.nvt > 40:
scores["nvt"] = -1
elif signals.nvt > 20:
scores["nvt"] = 0
else:
scores["nvt"] = 1
# 加重平均(MVRVとネットフローを重視)
weights = {
"mvrv": 0.30,
"sopr": 0.20,
"netflow": 0.25,
"active_addr": 0.10,
"nvt": 0.15
}
composite = sum(scores[k] * weights[k] for k in scores)
if composite > 1.0:
signal = Signal.STRONG_BUY
elif composite > 0.3:
signal = Signal.BUY
elif composite > -0.3:
signal = Signal.NEUTRAL
elif composite > -1.0:
signal = Signal.SELL
else:
signal = Signal.STRONG_SELL
return {
"composite_score": round(composite, 3),
"signal": signal.value,
"component_scores": scores,
"weights": weights
}
# 使用例
signals = OnChainSignals(
mvrv=2.4,
sopr=1.02,
exchange_netflow=-5000, # 5000 BTC流出(蓄積)
active_addresses_change=0.08,
nvt=35
)
result = generate_composite_signal(signals)
print(result)
ウェイルウォッチング自動化
import asyncio
from typing import Callable
async def whale_alert_monitor(
threshold_usd: float = 1_000_000,
callback: Callable = None
):
"""
大口取引の監視ループ(概念コード)
threshold_usd: アラート閾値(USD)
callback: アラート時のコールバック関数
"""
print(f"ウェイルアラート監視開始(閾値: ${threshold_usd:,.0f})")
while True:
# 実際にはWebSocketやAPIで新規トランザクションを監視
# ここでは概念的な擬似コード
transactions = await fetch_recent_large_transactions(threshold_usd)
for tx in transactions:
alert = {
"hash": tx["hash"],
"amount_usd": tx["amount_usd"],
"token": tx["token"],
"from_label": tx.get("from_label", "Unknown"),
"to_label": tx.get("to_label", "Unknown"),
"type": classify_whale_movement(tx)
}
if callback:
await callback(alert)
await asyncio.sleep(60) # 1分間隔でポーリング
def classify_whale_movement(tx: dict) -> str:
"""大口移動のタイプを分類"""
from_is_exchange = "exchange" in tx.get("from_label", "").lower()
to_is_exchange = "exchange" in tx.get("to_label", "").lower()
if from_is_exchange and not to_is_exchange:
return "取引所出金(蓄積シグナル)"
elif not from_is_exchange and to_is_exchange:
return "取引所入金(売却準備)"
elif from_is_exchange and to_is_exchange:
return "取引所間移動"
else:
return "ウォレット間移動(OTC等)"
実践的ワークフロー
日次オンチェーン分析ルーティン
| 時間帯 | 分析項目 | 使用ツール | チェック内容 |
|---|---|---|---|
| 朝 | マクロ指標確認 | Glassnode | MVRV, SOPR, NUPL, 取引所残高 |
| 朝 | DeFi TVL変動 | DefiLlama | 主要プロトコルのTVL変化 |
| 日中 | スマートマネー追跡 | Nansen | Smart Moneyの新規ポジション |
| 日中 | 大口移動監視 | Arkham | ウェイルの取引所入出金 |
| 夕方 | カスタム分析 | Dune | 特定プロトコルの詳細分析 |
| 夕方 | シグナル統合 | 自作ツール | 複合シグナルの生成 |
注意点とベストプラクティス
- 単一指標に依存しない: 複数の指標を組み合わせて総合判断する
- タイムフレームの整合: オンチェーンデータは中長期(週足〜月足)で有効性が高い
- ラベリングの限界: ウォレットラベルは100%正確ではない
- データの遅延: 一部のデータは数時間〜1日の遅延がある
- コスト管理: 有料ツールの費用対効果を定期的に評価する
- バックテストの実施: オンチェーンシグナルも必ず過去データで検証する
まとめ
オンチェーン分析は、ブロックチェーンの透明性という特性を最大限に活用した暗号資産固有の分析手法です。MVRV、SOPR、NVT、取引所ネットフローなどの指標は、価格チャートだけでは見えない市場参加者の行動を可視化します。
Glassnode、Dune Analytics、Nansen、Arkham、DefiLlamaといったツールはそれぞれ異なる強みを持つため、分析目的に応じて使い分けることが重要です。無料枠でも十分な分析が可能なため、まずはDefiLlamaとDune Analyticsから始め、必要に応じて有料ツールに移行する段階的なアプローチを推奨します。
アルゴリズムトレーディングに組み込む場合は、オンチェーン指標を中長期のトレンド判断に使い、短期的な売買タイミングはテクニカル分析やオーダーブック分析と組み合わせるのが効果的です。