etf-premium について
etf-premium は、yfinance 経由で Yahoo Finance のデータを使い、ETF の市場価格と NAV の乖離を分析するスキルです。単一銘柄の確認、比較、スクリーニング、背景分析、急変の要因分解に対応します。
主な機能
- 01市場価格と NAV のプレミアム・ディスカウント計算
- 02単一 ETF のスナップショットと同業比較
- 03複数 ETF のランキングとスクリーニング
- 04履歴と市場背景を踏まえた分析
- 05NAV 変動とオプション・ガンマの要因分解
活用シーン
- 01ETF の NAV に対する現在の乖離確認
- 02複数 ETF の乖離幅の比較
- 03大幅なディスカウント銘柄の抽出
- 04ETF の急騰要因の調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ himself65/ finance-skills --skill etf-premiumインストール後、Claude Code で/etf-premiumを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdreferences/etf_premium_reference.mdgamma_squeeze_reference.md詳細
ETF のプレミアム/ディスカウント分析スキル
ホストで以下のシェルプローブがまだ実行されていない場合(たとえば Codex の場合)、セットアップ方法を選ぶ前に、シェルツールを使って ! ラッパー内のコマンドを実行してください。実際の出力を使用してください。シェルにアクセスできない場合は、その制限を報告してください。
yfinance 経由で Yahoo Finance のデータを使用し、ETF の市場価格と純資産価値(NAV)との差から、プレミアムまたはディスカウントを計算します。
重要な理由: ETF の市場価格は、保有資産の価値(NAV)から乖離することがあります。プレミアムで購入すると資産価値に対して割高になり、ディスカウントで購入すると割安になります。米国の流動性の高い株式 ETF では通常この乖離は小さいものの、債券 ETF、国際 ETF、レバレッジ型/インバース型商品、暗号資産 ETF では大きくなることがあり、特に市場が不安定な時期に顕著です。
重要: 調査および教育目的に限ります。投資助言ではありません。yfinance は Yahoo, Inc. とは提携していません。
ステップ 1:依存関係を確認する
現在の環境の状態:
!`python3 -c "exec('try:\n import yfinance, pandas, numpy\n print(f\'yfinance={yfinance.__version__} pandas={pandas.__version__} numpy={numpy.__version__}\')\nexcept Exception:\n print(\'DEPS_MISSING\')')"`
DEPS_MISSING の場合は、必要なパッケージをインストールします。
import subprocess, sys
subprocess.check_call([sys.executable, "-m", "pip", "install", "-q", "yfinance", "pandas", "numpy"])
すでにインストールされている場合は、スキップして続行してください。
ステップ 2:適切なサブスキルに振り分ける
ユーザーのリクエストを分類し、該当するセクションに進んでください。特定の分析タイプを指定せずに ETF のプレミアムまたはディスカウントについて一般的な質問をした場合は、サブスキル A(単一 ETF のスナップショット)をデフォルトとして使用します。
| ユーザーのリクエスト | 振り分け先 | 例 |
|---|---|---|
| 単一 ETF のプレミアム/ディスカウント | サブスキル A:単一 ETF のスナップショット | 「SPY はプレミアムですか?」、「AGG の NAV に対するプレミアム」、「BITO のプレミアム」 |
| 複数 ETF の比較 | サブスキル B:複数 ETF の比較 | 「債券 ETF のディスカウントを比較」、「IBIT と BITO のどちらのプレミアムが大きいか」、「これらの ETF をプレミアム順に並べて」 |
| スクリーナー/大幅なプレミアムを検索 | サブスキル C:プレミアムスクリーナー | 「最も大きなディスカウントがある ETF は?」、「NAV を下回って取引されている ETF を探して」、「プレミアムスクリーナー」 |
| 背景情報を含む詳細分析 | サブスキル D:プレミアムの詳細分析 | 「HYG がディスカウントになっている理由は?」、「ARKK のプレミアムは通常ですか?」、「背景情報を含めた ETF のプレミアム分析」 |
| プレミアムの急上昇/ガンマスクイーズ | サブスキル E:プレミアム急上昇の要因分析 | 「今日 KWEB が 13% 上昇した理由は?」、「この ETF の上昇はガンマが要因ですか?」、「今日の ETF の値動きを要因別に分析して」、「SOXL のディーラー GEX」、「プレミアムが収束するまでどのくらいかかりますか?」 |
デフォルト値
| パラメーター | デフォルト値 |
|---|---|
| データソース | yfinance の navPrice フィールド |
| 価格フィールド | regularMarketPrice(利用できない場合は previousClose にフォールバック) |
| スクリーナーの対象 | カテゴリー別の一般的な ETF リスト(サブスキル C を参照) |
サブスキル A:単一 ETF のスナップショット
目標: 1 つの ETF の現在のプレミアム/ディスカウントを、通常の水準に関する背景情報とともに示し、類似 ETF との比較によって相対的な位置づけを示します。
A1:データを取得して計算する
import yfinance as yf
# Peer groups by category — used to automatically compare the target ETF against its closest peers
CATEGORY_PEERS = {
"Digital Assets": ["IBIT", "BITO", "FBTC", "ETHA", "ARKB", "GBTC"],
"Intermediate Core Bond": ["AGG", "BND", "SCHZ"],
"High Yield Bond": ["HYG", "JNK", "USHY"],
"Long Government": ["TLT", "VGLT", "SPTL"],
"Emerging Markets Bond": ["EMB", "VWOB", "PCY"],
"Large Growth": ["QQQ", "VUG", "IWF", "SCHG"],
"Large Blend": ["SPY", "VOO", "IVV", "VTI"],
"Commodities Focused": ["GLD", "IAU", "SLV", "DBC"],
"China Region": ["KWEB", "FXI", "MCHI"],
"Trading--Leveraged Equity": ["TQQQ", "UPRO", "SOXL", "JNUG"],
"Trading--Inverse Equity": ["SQQQ", "SPXU", "SOXS", "JDST"],
"Derivative Income": ["JEPI", "JEPQ", "QYLD"],
"Large Value": ["SCHD", "VYM", "DVY", "HDV"],
}
def etf_premium_snapshot(ticker_symbol):
ticker = yf.Ticker(ticker_symbol)
info = ticker.info
# Verify this is an ETF
quote_type = info.get("quoteType", "")
if quote_type != "ETF":
return {"error": f"{ticker_symbol} is not an ETF (quoteType={quote_type})"}
price = info.get("regularMarketPrice") or info.get("previousClose")
nav = info.get("navPrice")
if not price or not nav or nav <= 0:
return {"error": f"NAV data not available for {ticker_symbol}"}
premium_pct = (price - nav) / nav * 100
premium_dollar = price - nav
# Additional context
result = {
"ticker": ticker_symbol,
"name": info.get("longName") or info.get("shortName", ""),
"market_price": round(price, 4),
"nav": round(nav, 4),
"premium_discount_pct": round(premium_pct, 4),
"premium_discount_dollar": round(premium_dollar, 4),
"status": "PREMIUM" if premium_pct > 0 else "DISCOUNT" if premium_pct < 0 else "AT NAV",
"category": info.get("category", "N/A"),
"fund_family": info.get("fundFamily", "N/A"),
"total_assets": info.get("totalAssets"),
"net_expense_ratio": info.get("netExpenseRatio"),
"avg_volume": info.get("averageVolume"),
"bid": info.get("bid"),
"ask": info.get("ask"),
"yield_pct": info.get("yield"),
"ytd_return": info.get("ytdReturn"),
}
# Bid-ask spread as context for whether the premium is meaningful
bid = info.get("bid")
ask = info.get("ask")
if bid and ask and bid > 0:
spread_pct = (ask - bid) / ((ask + bid) / 2) * 100
result["bid_ask_spread_pct"] = round(spread_pct, 4)
return result
A2:比較対象 ETF のデータを取得する
対象 ETF のスナップショットを計算した後、その category を調べ、同じカテゴリーに属する ETF のプレミアムデータを取得してください。これにより、プレミアムがその ETF 固有のものか、市場全体に共通するものかをすぐに判断できます。
対象の category を使って CATEGORY_PEERS を選び、対象 ETF を除外したうえで、各比較対象について同じ価格/NAV の計算を行います。利用できない NAV の行は除外しますが、データ欠落がわかるように、取得を依頼した比較対象の数とデータが返された数を報告してください。
メインのスナップショットの後に、小さな表で比較結果を示してください。これにより、プレミアムがユーザーの ETF に固有のものか、カテゴリー全体に共通するものかを把握できます。たとえば、すべての暗号資産 ETF が約 1.5% のプレミアムであれば、ユーザーの ETF は例外的ではありません。
A3: 結果を解釈する
プレミアム/ディスカウントに意味があるかどうかを説明する際は、次の基準を使用してください。
| プレミアム/ディスカウント | 解釈 |
|---|---|
| +/- 0.05%以内 | 実質的にNAVと同水準です。大規模で流動性の高いETFでは一般的です |
| +/- 0.05%~0.25% | わずかな乖離です。よく見られ、通常は対応する必要はありません |
| +/- 0.25%~1.0% | 注目に値します。言及する価値があります。ビッド・アスク・スプレッドとカテゴリーを確認してください |
| +/- 1.0%~3.0% | 大きな乖離です。流動性の低いETF、国際ETF、または特殊なETFではよく見られます |
| +/- 3.0%超 | かなり大きな乖離です。市場の緊張、流動性不足、または構造上の問題を示している可能性があります |
カテゴリーによって状況は異なります。
- 米国大型株(SPY、QQQ、IVV):0.10%を超えるプレミアムは珍しいです
- 債券ETF(AGG、HYG、LQD、TLT):ボラティリティが高い局面では、0.5~2%のディスカウントが発生します
- 国際株式/新興国市場(EEM、VWO、KWEB):時差のずれにより、0.3~1%の乖離が定期的に発生します
- レバレッジ型/インバース型(TQQQ、SQQQ、JNUG):日次リセットの仕組みにより、0.3~1.5%が一般的です
- 暗号資産(IBIT、BITO):特に新しいファンドでは、1~3%のプレミアムがよく見られます
- コモディティ(GLD、USO、UNG):先物のコンタンゴ/バックワーデーションによって異なります
また、プレミアム/ディスカウントをビッド・アスク・スプレッドと比較してください。プレミアムがスプレッドより小さい場合、それはシグナルではなくノイズです。
サブスキル B:複数のETFの比較
目標:複数のETFのプレミアム/ディスカウントを横並びで比較します。
B1: 取得して順位付けする
import yfinance as yf
import pandas as pd
def compare_etf_premiums(tickers):
rows = []
for sym in tickers:
try:
t = yf.Ticker(sym)
info = t.info
if info.get("quoteType") != "ETF":
rows.append({"ticker": sym, "error": "Not an ETF"})
continue
price = info.get("regularMarketPrice") or info.get("previousClose")
nav = info.get("navPrice")
if price and nav and nav > 0:
prem = (price - nav) / nav * 100
bid = info.get("bid", 0)
ask = info.get("ask", 0)
spread = (ask - bid) / ((ask + bid) / 2) * 100 if bid and ask and bid > 0 else None
rows.append({
"ticker": sym,
"name": info.get("shortName", ""),
"price": round(price, 2),
"nav": round(nav, 2),
"premium_pct": round(prem, 4),
"spread_pct": round(spread, 4) if spread else None,
"category": info.get("category", "N/A"),
"total_assets": info.get("totalAssets"),
})
else:
rows.append({"ticker": sym, "error": "NAV unavailable"})
except Exception as e:
rows.append({"ticker": sym, "error": str(e)})
df = pd.DataFrame(rows)
if "premium_pct" in df.columns:
df = df.sort_values("premium_pct", ascending=True)
return df
B2: 順位付けした表で提示する
プレミアム/ディスカウントの順(ディスカウントが最も大きいものを先頭)に並べ替えます。次の点を強調してください。
- 最も大きなディスカウントとなっているETF
- 最も大きなプレミアムとなっているETF
- プレミアム/ディスカウントがビッド・アスク・スプレッドを超えているかどうか(超えていない場合、市場のマイクロストラクチャーによるノイズです)
サブスキル C:プレミアム・スクリーナー
目標:一般的なETFのユニバースをスキャンし、プレミアムまたはディスカウントが最も大きいETFを見つけます。
C1: ユニバースを定義してスキャンする
references/etf_premium_reference.md のカテゴリー別ユニバース、またはユーザー独自のリストを使用します。サブスキル A の計算を各シンボルに適用し、カテゴリーラベルを保持して、指定された絶対プレミアムのしきい値で絞り込み、ディスカウントが最も大きいものからプレミアムが最も大きいものの順に並べ替えます。取得に失敗した件数やNAVが欠落している件数は、ゼロとして扱わず、表示したままにしてください。
C2: 結果を提示する
プレミアム順(ディスカウントが最も大きいものを先頭)に並べ替えた順位付きの表を表示します。リストが長い場合はカテゴリー別にまとめます。次の点を取り上げてください。
- ディスカウントが最も大きい上位5銘柄 — 購入機会の可能性(または市場の緊張の兆候)
- プレミアムが最も大きい上位5銘柄 — 割高で購入するリスク
- カテゴリー別の傾向 — すべての債券ETFがディスカウントになっているか?すべての暗号資産ETFがプレミアムになっているか?
対象ユニバースが大きい場合、1~2分かかることがあると伝えてください。
サブスキル D:プレミアムの詳細分析
目標:プレミアム/ディスカウントのデータに追加のコンテキストを加えて、プレミアムが存在する理由と、それが続く可能性をユーザーが理解できるようにします。
D1: 包括的なデータを収集する
サブスキル A のスナップショットを取得し、続けて3か月分の日次履歴を取得して、次の情報を追加します。
- 年率換算ボラティリティ:
std(daily returns) * sqrt(252) - 1日あたりの平均売買代金:
mean(close * volume) - 3か月間の終値の最高値からの乖離率
- AUM、経費率、利回り、年初来リターン、3年間のベータ
- ビッド・アスク・スプレッドの割合、および絶対プレミアムがそのスプレッドを超えているかどうか
利用できないフィールドは、値を捏造せず null のままにしてください。価格とNAVの入力にはタイムスタンプを付け、比較対象の時点が同期しているかどうかをユーザーが判断できるようにします。
D2: その理由を説明する
データを収集したら、次の診断フレームワークを使ってプレミアム/ディスカウントの理由を説明します。
プレミアムの一般的な原因:
- 需要の急増 — 買い手が増え、認定参加者による設定が追いつかないと発生します(暗号資産のような、新規または人気急上昇中の ETF でよく見られます)
- タイムゾーンのずれ — 原資産の市場が閉まっている時間帯に国際 ETF が取引される場合、価格は予想される値動きを反映します
- 設定メカニズムのボトルネック — 認定参加者が新しい受益権の設定に制約を受けている場合に発生します
- センチメントによるプレミアム — 熱狂的な相場で個人投資家の需要が価格を公正価値以上に押し上げます
ディスカウントの一般的な原因:
- 流動性ストレス — 売りが集中しているとき、社債やクレジット ETF はしばしばディスカウントで取引されます。これは、原資産の債券が ETF 自体よりも価格評価や取引が難しいためです
- 解約圧力 — 資金流出が多い一方で、認定参加者の対応が遅れている状態です
- 古い NAV — 公表される NAV に、取引時間外のニュースや出来事が反映されていない場合があります
- 構造的な問題 — 先物ベースの ETF(USO、UNG)におけるコンタンゴは、継続的な価値の目減りをもたらします
プレミアムは持続する可能性がありますか?
- 流動性の高い米国株 ETF:いいえ — 裁定取引により、乖離は数分以内に修正されます
- ストレス下の債券 ETF:ディスカウントが数日から数週間続くことがあります
- 暗号資産 ETF:ファンドの運用歴が長くなり、AP の活動が活発になるにつれて、プレミアムは縮小する傾向があります
- 国際 ETF:原資産の市場が開くたびに、日次で調整されます
サブスキル E:プレミアム急騰の分解(ガンマスクイーズ分析)
目標:ETF が原資産の保有銘柄と乖離する急激な日中変動を直近で経験した場合、その変動を(1)ファンダメンタルズに基づく NAV 連動部分と、(2)構造的な要因による「過剰プレミアム」に分解します。構造的な要因として最も一般的なのは、オプションディーラーのガンマヘッジ、AP の裁定取引の機能不全、またはセンチメントの急騰です。そのうえで、プレミアムが収束するまでにかかる時間を評価します。
このサブスキルは、ユーザーが次のような報告や質問をした場合に適しています。
- ETF が単一の取引時間内に 5% 以上値動きした
- ETF と明示された原資産との乖離がある(例:「MSTR は 13% 上昇したのに、BTC は 3% しか上昇しなかった」)
- ETF または個別銘柄におけるガンマスクイーズが疑われる
- ディーラーのヘッジが値動きを増幅しているかどうか
E2 を実行する前に、GEX の計算式の導出、ディーラーのポジションに関する慣例、具体的な計算例を確認するため、references/gamma_squeeze_reference.md を読んでください。
E1:今日の値動きを NAV 連動分と過剰プレミアムに分解する
静的な navPrice フィールドからわかるのは、直近の日次終値時点の NAV のみです。現在の保有銘柄のウェイトと同一取引時間内の各保有銘柄のリターンから今日の NAV リターンを推定し、カバー対象ウェイトで正規化してから、次を計算します。
NAV proxy return = sum(weight_i x return_i) / covered weight
Excess premium return = ETF return - NAV proxy return
保有銘柄のカバー率と、計算に使用した銘柄ごとのリターンを報告してください。funds_data.top_holdings が不完全な場合は、発行体が公表する保有銘柄情報またはユーザーが提示したウェイトを優先してください。
注意点:原資産の市場が閉まっている時間帯に取引される国際 ETF(例:米国時間帯に取引されるアジア銘柄)の場合、原資産の代わりに米国上場の代理銘柄(ADR)または先物を使用する必要があります。どちらも利用できない場合は、その旨をユーザーに伝えてください。NAV の代理値が実勢を反映しないためです。
E2: オプションチェーンからディーラーのガンマエクスポージャー(GEX)を算出する
GEX は、原資産が 1%動いた場合のディーラーのヘッジ感応度を概算します。references/gamma_squeeze_reference.md で計算式と 2 種類のポジショニングの規約を確認し、現在のスポット価格、権利行使価格、残存期間、無リスク金利、IV からコントラクトのガンマを計算したうえで、チェーン全体の OI x gamma x spot^2 を集計します。
コール GEX、プット GEX、SqueezeMetrics 方式のネット GEX、グロスのヘッジ圧力、コール/プット OI 比率、ATM 近辺の IV の中央値、分析対象の満期、そして GEX が集中している上位の権利行使価格/満期を返します。符号の規約を明記してください。公開 OI のみから実際のディーラー在庫を推測してはいけません。
出力を解釈します。
net_gex_squeezemetrics_$が大幅なマイナス → ディーラーはショートガンマです。相場上昇時、ヘッジ買いによって上昇が増幅されます。典型的なガンマスクイーズの燃料です。- 近い満期の単一の権利行使価格に集中(例:来月満期のコールの単一権利行使価格に多くの建玉が集中) → スクイーズは脆弱で、ポジションが集中しています。その権利行使価格のオプションが満期を迎えるか、スポット価格がその水準を超えると、ガンマは急激に低下します。
- ATM IV が最近の平均を大きく上回る(例:通常 30~40%のところ 78%) → 市場は大幅な値動きが続くと織り込んでいます。オプションプレミアムの時間的価値の減少だけでも、数日かけてある程度の収束圧力が生じます。
- コール/プット OI 比率が 2.5 超 → コールに偏ったポジショニングであり、強気のガンマスクイーズの構図と一致します。
E3: 構造的な買い圧力と実際の出来高を比較する
次の式でディーラーの推定シェアの上限を算出します。
Implied dealer-driven dollars = abs(GEX per 1% move) x abs(ETF return in percentage points)
Dealer share of volume = implied dealer-driven dollars / (close x volume)
これは概算です。値動きの間、各コントラクトのガンマ全体が単一の方向にヘッジされたと仮定しています。実際のヘッジは段階的に行われ、すべてのディーラーが同じようにヘッジするわけではありません。正確な数値ではなく、上限の目安として扱ってください。必ず前提条件と併せて提示してください。
E4: プレミアム収束のタイムラインを評価する
収束は 3 つの時間軸で進みます(詳細は references/gamma_squeeze_reference.md の「Convergence Timeline」セクションを参照)。
| 時間軸 | メカニズム | 確認事項 |
|---|---|---|
| 時間単位 | AP による設定/償還の裁定取引 | 原資産の市場は開いていますか? 設定ユニットは制限されていますか? 買値/売値のスプレッドは拡大していますか(AP が手を引いている兆候)? |
| 日単位 | オプションの満期/ガンマの低下 | 主要な権利行使価格の満期はいつですか? OI は先の満期へロールしているか、解消されていますか? IV は縮小し始めていますか? |
| 週単位 | 純資金フローの正常化 | ETF には大規模な日次資金流入がありますか(需要が設定能力を上回っている兆候)? 空売り残高は積み上がっていますか(追加のスクイーズの燃料となる可能性)? |
時間単位の見通しでは、原資産の市場が開いているか、設定/償還が制約されているかを記録します。日単位の見通しでは、最大のガンマ集中の満期までの日数を計算し、IV と OI が減少しているか、先の満期へロールしているかを確認します。週単位の見通しでは、利用可能な場合は発行体の資金フロー/設定データを使用します。AUM のみでは概算にしかなりません。
E5: 分解結果を提示する
次の順序で回答を構成します。
-
要点の数値:本日の ETF の値動き、NAV プロキシの値動き、超過プレミアム(pp 単位)。
-
分解表:
要素 寄与度 NAV による変動(保有銘柄 × ウェイト) +X.X% 超過プレミアム(残差) +Y.Y% ETF の合計値動き +Z.Z% -
ディーラーのヘッジ量の定量化:
- ネット GEX(SqueezeMetrics 方式)
- 当日のディーラーによる推定買付額(ドル)と実際の売買代金の比較
- 買い圧力に占めるディーラーの推定シェア
-
リスク指標:ATM IV、コール/プット OI 比率、上位 3 件の権利行使価格/満期への集中状況。
-
収束の見通し:時間/日/週単位の各メカニズムと、その現状を列挙します。
-
注意事項:GEX の推定ではディーラーのポジショニングが一様であると仮定しています。NAV プロキシは夜間取引中は古い値になります。これは将来の価格予測ではありません。
Step 3: ユーザーに回答する
必ず含める項目
- ETF 名とティッカー
- 市場価格とNAV(計算式も示してください)
- 明確にラベル付けしたプレミアム/ディスカウント率
- 背景情報:この乖離は、この ETF カテゴリーでは一般的ですか?
必ず注記する項目
- Yahoo Finance の NAV データは直近の公式 NAV(通常は前取引日の終値時点)を反映したものであり、リアルタイムではありません
- 取引所によっては、市場価格に15 分の遅延が生じる場合があります
- プレミアム/ディスカウントは取引時間中に急速に変動する場合があります。これはスナップショットであり、ライブフィードではありません
- 小幅なプレミアム/ディスカウント(ビッド・アスク・スプレッド未満)は、市場のマイクロストラクチャーノイズであり、実際の誤った価格付けではありません
- プレミアム/ディスカウントだけを根拠に売買を推奨しないでください。データを提示し、判断はユーザーに委ねてください
書式
- 複数の ETF を比較する場合は、Markdown の表を使用してください
- 計算式を示してください:
Premium/Discount = (Market Price - NAV) / NAV x 100 - 本文中の主要な数値は太字にしてください:「0.45%のディスカウントで取引中」または「1.2%のプレミアム」
- 率は、数値の大きさに応じて小数点以下 2~4 桁に丸めてください
参考ファイル
references/etf_premium_reference.md— 詳細な計算式、カテゴリー別のベンチマーク、一般的な ETF の一覧、プレミアムを生み出す設定・償還の仕組みに関する背景情報references/gamma_squeeze_reference.md— プレミアムの分解フレームワーク、SqueezeMetrics と顧客のネットロングの両方の規約に基づくブラック・ショールズのガンマ式と GEX の計算式、収束までの期間のフレームワーク(時間/日/週)、ガンマスクイーズと通常の上昇相場を見分ける診断表、および具体例。サブスキル E を実行する前にお読みください。
ETF のプレミアム/ディスカウントの仕組み、過去の状況、ガンマスクイーズの分解方法について、より詳細な技術情報を得るには、参考ファイルをお読みください。