stock-liquidity について
stock-liquidityは、yfinance経由で取得したYahoo Financeのデータを使って株式の流動性を評価する調査スキルです。売買コストや複数銘柄の流動性を分析する人向けに、スプレッド、出来高、板の深さの代理指標、市場インパクト、回転率を扱います。
主な機能
- 01複数指標による流動性ダッシュボード
- 02気配値とオプションのスプレッド分析
- 03出来高と回転率のパターン測定
- 04板の深さの代理指標の推定
- 05市場インパクトとスリッページのモデル化
活用シーン
- 01複数銘柄の流動性比較
- 02銘柄の売買コストの評価
- 03予定注文による市場インパクトの推定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ himself65/ finance-skills --skill stock-liquidityインストール後、Claude Code で/stock-liquidityを入力して読み込まれたか確認します。
同梱ファイルREADME.mdreferences/liquidity_reference.md
詳細
株式流動性分析スキル
ホストが以下のシェルプローブをすでに実行していない場合(たとえば Codex)、セットアップ方法を選ぶ前に、シェルツールを使って ! で囲まれたコマンドを実行してください。実際の出力を使用してください。シェルにアクセスできない場合は、その制限を報告してください。
yfinance を通じて Yahoo Finance のデータを使用し、ビッド・アスク・スプレッド、出来高パターン、注文板の厚み、推定マーケットインパクト、売買回転率など、複数の観点から株式の流動性を分析します。
流動性が重要なのは、取引にかかる実際のコストを左右するためです。提示価格が実際の支払価格とは限りません。スプレッド、スリッページ、マーケットインパクトは、特にポジションが大きい場合や流動性の低い銘柄では、いずれもリターンを損ないます。
重要:これは調査および教育目的に限られます。投資助言ではありません。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:適切なサブスキルに振り分ける
ユーザーのリクエストを分類し、該当するセクションに進んでください。特定の指標を指定せず、全般的な流動性評価を求めている場合は、主要な指標をすべてまとめて算出する サブスキル A(流動性ダッシュボード)を実行してください。
| ユーザーのリクエスト | 振り分け先 | 例 |
|---|---|---|
| 全般的な流動性の確認、「X の流動性はどの程度か」 | サブスキル A:流動性ダッシュボード | 「AAPL の流動性はどの程度か」、「TSLA の流動性分析」、「この株式は十分な流動性がありますか」 |
| ビッド・アスク・スプレッド、取引コスト、実効スプレッド | サブスキル B:スプレッド分析 | 「AMD のビッド・アスク・スプレッド」、「NVDA オプションのスプレッドはどのくらいか」、「取引コストの見積もり」 |
| 出来高、ADTV、売買代金、出来高プロファイル | サブスキル C:出来高分析 | 「MSFT の出来高分析」、「平均日次出来高」、「SPY の出来高プロファイル」 |
| 注文板の厚み、マーケットデプス、レベル 2 | サブスキル D:注文板の厚み | 「AAPL の注文板の厚み」、「マーケットデプス」、「注文板を見せて」 |
| 大口注文のマーケットインパクト、スリッページ、約定コスト | サブスキル E:マーケットインパクト | 「5 万株で価格はどのくらい動くか」、「スリッページの見積もり」、「100 万ドルの注文のマーケットインパクト」 |
| 売買回転率、浮動株数に対する取引活動 | サブスキル F:売買回転率 | 「GME の売買回転率」、「浮動株回転率」、「この株式はどのくらい活発に取引されていますか」 |
| 複数の株式間で流動性を比較する | サブスキル A(複数ティッカーモード) | 「AAPL と TSLA の流動性を比較」、「AMD と INTC ではどちらの流動性が高いか」 |
デフォルト値
| パラメーター | デフォルト値 |
|---|---|
| 参照期間 | 3mo(3 か月) |
| データ間隔 | 1d(日次) |
| マーケットインパクトモデル | 平方根モデル |
| 日中の間隔(必要な場合) | 5m |
サブスキル A:流動性ダッシュボード
目標:1 つまたは複数のティッカーについて、主要な指標をすべて組み合わせた包括的な流動性の概要を作成します。
A1:データを取得し、すべての指標を算出する
import yfinance as yf
import pandas as pd
import numpy as np
def liquidity_dashboard(ticker_symbol, period="3mo"):
ticker = yf.Ticker(ticker_symbol)
info = ticker.info
hist = ticker.history(period=period)
if hist.empty:
return None
# --- Spread metrics (from current quote) ---
bid = info.get("bid", None)
ask = info.get("ask", None)
current_price = info.get("currentPrice") or info.get("regularMarketPrice") or hist["Close"].iloc[-1]
spread = None
spread_pct = None
if bid and ask and bid > 0 and ask > 0:
spread = round(ask - bid, 4)
midpoint = (ask + bid) / 2
spread_pct = round((spread / midpoint) * 100, 4)
# --- Volume metrics ---
avg_volume = hist["Volume"].mean()
median_volume = hist["Volume"].median()
avg_dollar_volume = (hist["Close"] * hist["Volume"]).mean()
volume_std = hist["Volume"].std()
volume_cv = volume_std / avg_volume if avg_volume > 0 else None # coefficient of variation
# --- Turnover ratio ---
shares_outstanding = info.get("sharesOutstanding", None)
float_shares = info.get("floatShares", None)
base_shares = float_shares or shares_outstanding
turnover_ratio = round(avg_volume / base_shares, 6) if base_shares else None
# --- Amihud illiquidity ratio ---
# Average of |daily return| / daily dollar volume
returns = hist["Close"].pct_change().dropna()
dollar_volume = (hist["Close"] * hist["Volume"]).iloc[1:] # align with returns
amihud_values = returns.abs() / dollar_volume
amihud = amihud_values[amihud_values.replace([np.inf, -np.inf], np.nan).notna()].mean()
# --- Market impact estimate (square-root model) ---
# For a hypothetical order of 1% of ADV
adv = avg_volume
order_size = adv * 0.01
daily_volatility = returns.std()
sigma = daily_volatility
participation_rate = order_size / adv if adv > 0 else 0
impact_bps = sigma * np.sqrt(participation_rate) * 10000 # in basis points
return {
"ticker": ticker_symbol,
"current_price": round(current_price, 2),
"bid": bid,
"ask": ask,
"spread": spread,
"spread_pct": spread_pct,
"avg_daily_volume": int(avg_volume),
"median_daily_volume": int(median_volume),
"avg_dollar_volume": round(avg_dollar_volume, 0),
"volume_cv": round(volume_cv, 3) if volume_cv else None,
"shares_outstanding": shares_outstanding,
"float_shares": float_shares,
"turnover_ratio": turnover_ratio,
"amihud_illiquidity": round(amihud * 1e9, 4) if not np.isnan(amihud) else None,
"daily_volatility": round(daily_volatility * 100, 2),
"impact_1pct_adv_bps": round(impact_bps, 2),
"observations": len(hist),
}
A2:解釈して提示する
概要カードとして提示してください。アミフド流動性比率は、読みやすくするために 1e9 を掛けてください(標準的な慣例)。
流動性評価(米国株式におけるおおよその基準として、以下を使用してください):
| 評価 | 平均売買代金 | スプレッド(%) | アミフド(×10⁹) |
|---|---|---|---|
| 非常に高い | > $500M/日 | < 0.03% | < 0.01 |
| 高い | $50M–$500M/日 | 0.03–0.10% | 0.01–0.1 |
| 中程度 | $5M–$50M/日 | 0.10–0.50% | 0.1–1.0 |
| 低い | $500K–$5M/日 | 0.50–2.00% | 1.0–10 |
| 非常に低い | < $500K/日 | > 2.00% | > 10 |
複数のティッカーを比較する場合は、左右に並べた表を示し、どちらの流動性が高いか、その理由とともに強調してください。
サブスキル B:スプレッド分析
目標:現在のスプレッド、オプションデータによる過去との比較、実効スプレッドの推定を含む、詳細なビッド・アスク・スプレッド分析を行います。
B1:気配値から現在のスプレッドを取得する
import yfinance as yf
def spread_analysis(ticker_symbol):
ticker = yf.Ticker(ticker_symbol)
info = ticker.info
bid = info.get("bid", 0)
ask = info.get("ask", 0)
bid_size = info.get("bidSize", None)
ask_size = info.get("askSize", None)
current_price = info.get("currentPrice") or info.get("regularMarketPrice", 0)
result = {"bid": bid, "ask": ask, "bid_size": bid_size, "ask_size": ask_size}
if bid > 0 and ask > 0:
midpoint = (bid + ask) / 2
result["absolute_spread"] = round(ask - bid, 4)
result["relative_spread_pct"] = round((ask - bid) / midpoint * 100, 4)
result["relative_spread_bps"] = round((ask - bid) / midpoint * 10000, 2)
return result
B2:オプションのスプレッドのコンテキスト
yfinance のオプションデータには各ストライクの買値/売値が含まれており、デリバティブの流動性の目安になります。最も近い満期を使用し、アット・ザ・マネーに近いコールとプットを抽出して、それぞれのスプレッドとスプレッド率を計算します。
完全なコードテンプレートについては、references/liquidity_reference.md の「Options Spread Analysis」を参照してください。
B3:結果を提示する
次の項目を示します。
- 現在の提示スプレッド(絶対値、相対%、ベーシスポイント)
- 利用可能な場合は買い/売りの数量
- コンテキストとして、アット・ザ・マネーに近いオプションのスプレッド
- この時価総額区分における一般的な範囲と比べたスプレッド
サブスキル C:出来高分析
目標:取引出来高のパターン(平均、トレンド、相対出来高、売買代金)を分析します。
C1:出来高指標を計算する
import yfinance as yf
import pandas as pd
import numpy as np
def volume_analysis(ticker_symbol, period="3mo"):
ticker = yf.Ticker(ticker_symbol)
hist = ticker.history(period=period)
if hist.empty:
return None
vol = hist["Volume"]
close = hist["Close"]
dollar_vol = vol * close
# Relative volume (today vs average)
rvol = vol.iloc[-1] / vol.mean() if vol.mean() > 0 else None
# Volume trend (linear regression slope over the period)
x = np.arange(len(vol))
slope, _ = np.polyfit(x, vol.values, 1) if len(vol) > 1 else (0, 0)
trend_pct = (slope * len(vol)) / vol.mean() * 100 # % change over period
# Volume profile by day of week
hist_copy = hist.copy()
hist_copy["DayOfWeek"] = hist_copy.index.dayofweek
day_names = {0: "Mon", 1: "Tue", 2: "Wed", 3: "Thu", 4: "Fri"}
vol_by_day = hist_copy.groupby("DayOfWeek")["Volume"].mean()
vol_by_day.index = vol_by_day.index.map(day_names)
# High/low volume days
high_vol_days = hist.nlargest(5, "Volume")[["Close", "Volume"]]
low_vol_days = hist.nsmallest(5, "Volume")[["Close", "Volume"]]
return {
"avg_volume": int(vol.mean()),
"median_volume": int(vol.median()),
"avg_dollar_volume": round(dollar_vol.mean(), 0),
"current_volume": int(vol.iloc[-1]),
"relative_volume": round(rvol, 2) if rvol else None,
"volume_trend_pct": round(trend_pct, 1),
"volume_by_day": vol_by_day.to_dict(),
"high_vol_days": high_vol_days,
"low_vol_days": low_vol_days,
"max_volume": int(vol.max()),
"min_volume": int(vol.min()),
}
C2:結果を提示する
次の項目を示します。
- 比較用の中央値を添えた平均日次出来高(株数と売買代金)
- 相対出来高(RVOL):本日の出来高と平均の比較。RVOL > 1.5 は高水準、RVOL < 0.5 は通常より著しく低い水準です
- 出来高のトレンド:取引活動は増加していますか、それとも減少していますか?
- 曜日ごとのパターン(意味のある差がある場合)
- 出来高が多かった上位 5 日とその背景(決算?ニュース?)
サブスキル D:板の厚み
目標:株式の気配値とオプションチェーンから得られる買値/売値データを使って、板の厚みを推定します。
Yahoo Finance では、完全な Level 2/板情報は提供されません。この制約については明確に伝えてください。利用できるのは次の情報です。
- 株式の気配値:買値、売値、買い数量、売り数量(最良気配のみ)
- オプションチェーン:ストライク全体の買値/売値と建玉は、デリバティブの板の厚みの代替指標になります
- 日中の出来高分布:日中の出来高分布から、連続取引市場の厚みがうかがえます
D1:利用可能な板の厚みデータを収集する
次の 3 つのデータポイントを収集します。
- 最良気配:
ticker.infoの bid、ask、bidSize、askSize - 日中の出来高分布:過去 5 日間の 5 分足を時間帯別に集計し、日次出来高に対する割合として標準化
- オプションの建玉:最も近い満期のコール/プットの合計建玉と出来高を、デリバティブの板の厚みの代替指標として使用
完全なコードテンプレートについては、references/liquidity_reference.md の「Order Book Depth Proxy」を参照してください。
D2:結果を提示する
次の項目を示します。
- 最良気配:現在の買値/売値と数量
- 日中の出来高パターン:出来高が集中する時間帯(寄り付き/引けと、日中)
- オプションの厚み:デリバティブの流動性の代替指標としての合計建玉と出来高
- 制約を正直に説明:「Yahoo Finance では最良気配のみが提供されます。完全な Level 2 の板の厚みを得るには、直接の市場データフィード(例:NYSE OpenBook、NASDAQ TotalView)が必要です。」
サブスキル E:マーケットインパクト
目標:平方根マーケットインパクトモデルを使って、指定された注文サイズが価格をどの程度動かすかを推定します。
実務で標準的に使われるモデルは、インパクト(%)= σ × √(Q / V) です。ここで、σ は日次ボラティリティ、Q は注文サイズ(株数)、V は平均日次出来高です。これは、機関投資家が使用する Almgren-Chriss フレームワークを簡略化したものです。
E1:マーケットインパクトの推定値を計算する
import yfinance as yf
import numpy as np
def market_impact(ticker_symbol, order_shares=None, order_dollars=None, period="3mo"):
ticker = yf.Ticker(ticker_symbol)
hist = ticker.history(period=period)
info = ticker.info
if hist.empty:
return None
current_price = info.get("currentPrice") or hist["Close"].iloc[-1]
avg_volume = hist["Volume"].mean()
daily_volatility = hist["Close"].pct_change().dropna().std()
# Determine order size in shares
if order_dollars and not order_shares:
order_shares = order_dollars / current_price
elif not order_shares:
# Default: estimate for various sizes
order_shares = avg_volume * 0.01 # 1% of ADV
participation_rate = order_shares / avg_volume if avg_volume > 0 else 0
pct_adv = (order_shares / avg_volume * 100) if avg_volume > 0 else 0
# Square-root impact model
impact_pct = daily_volatility * np.sqrt(participation_rate) * 100
impact_bps = impact_pct * 100
impact_dollars = impact_pct / 100 * current_price * order_shares
# Generate impact curve for multiple order sizes
sizes = [0.001, 0.005, 0.01, 0.02, 0.05, 0.10, 0.20, 0.50] # as fraction of ADV
curve = []
for s in sizes:
q = avg_volume * s
imp = daily_volatility * np.sqrt(s) * 100
curve.append({
"pct_adv": round(s * 100, 1),
"shares": int(q),
"dollars": round(q * current_price, 0),
"impact_bps": round(imp * 100, 1),
"impact_dollars_per_share": round(imp / 100 * current_price, 4),
})
return {
"ticker": ticker_symbol,
"current_price": round(current_price, 2),
"avg_daily_volume": int(avg_volume),
"daily_volatility_pct": round(daily_volatility * 100, 2),
"order_shares": int(order_shares),
"order_dollars": round(order_shares * current_price, 0),
"pct_of_adv": round(pct_adv, 2),
"estimated_impact_bps": round(impact_bps, 1),
"estimated_impact_pct": round(impact_pct, 4),
"estimated_impact_total_dollars": round(impact_dollars, 2),
"impact_curve": curve,
}
E2:結果を提示する
次の項目を示します。
- ユーザーが指定した注文サイズに対する推定インパクト
- 注文サイズに応じたコストの変化を示すインパクト曲線の表
- コンテキスト:「これは、機関投資家の標準的な推定手法である平方根マーケットインパクトモデルを使用しています。実際のインパクトは、執行戦略(VWAP、TWAP など)、時間帯、現在の市場状況によって異なります。」
- 約 25 bps を超える場合は、その注文が当該銘柄の流動性に対して大きいことを示します。約 50 bps を超える場合は明確に警告し、アルゴリズム執行を検討するか、複数日に分けて注文を執行するよう提案します
サブスキル F:回転率
目標:発行済み株式数と浮動株に対して、株式がどの程度活発に取引されているかを測定します。
F1:回転率指標を計算する
import yfinance as yf
import pandas as pd
import numpy as np
def turnover_analysis(ticker_symbol, period="3mo"):
ticker = yf.Ticker(ticker_symbol)
hist = ticker.history(period=period)
info = ticker.info
if hist.empty:
return None
avg_volume = hist["Volume"].mean()
shares_outstanding = info.get("sharesOutstanding")
float_shares = info.get("floatShares")
result = {
"avg_daily_volume": int(avg_volume),
"shares_outstanding": shares_outstanding,
"float_shares": float_shares,
}
if shares_outstanding:
daily_turnover = avg_volume / shares_outstanding
result["daily_turnover_ratio"] = round(daily_turnover, 6)
result["annualized_turnover"] = round(daily_turnover * 252, 2)
result["days_to_trade_float"] = round(
(float_shares or shares_outstanding) / avg_volume, 1
) if avg_volume > 0 else None
if float_shares:
float_turnover = avg_volume / float_shares
result["float_turnover_daily"] = round(float_turnover, 6)
result["float_turnover_annualized"] = round(float_turnover * 252, 2)
# Turnover trend
vol = hist["Volume"]
base = float_shares or shares_outstanding
if base:
hist_copy = hist.copy()
hist_copy["turnover"] = hist_copy["Volume"] / base
recent_turnover = hist_copy["turnover"].tail(20).mean()
older_turnover = hist_copy["turnover"].head(20).mean()
if older_turnover > 0:
result["turnover_trend_pct"] = round(
(recent_turnover - older_turnover) / older_turnover * 100, 1
)
return result
F2: 結果の提示
以下を表示します。
- 日次および年率換算の売買回転率(発行済み株式数および浮動株数に対する割合)
- 「浮動株の売買にかかる日数」— 平均出来高で浮動株全体を売買するのに何日かかるか
- 売買回転率の推移 — 株式の売買が活発になっているか、低調になっているか
- 目安:
| 年率換算の売買回転率 | 解釈 |
|---|---|
| > 500% | 非常に活発 — 投機またはモメンタム主導の可能性が高い |
| 100–500% | 活発に売買されている |
| 30–100% | 中程度の活発さ |
| < 30% | 取引が薄い — 機関投資家による長期保有、または注目されていない可能性が高い |
ステップ 3:ユーザーに応答する
適切なサブスキルを実行した後、以下のように応答します。
常に含める項目
- 過去の指標に使用した参照期間
- データのタイムスタンプ — スプレッドと気配値はスナップショットであり、リアルタイムのデータではありません
- 空のデータが返されたティッカー(無効なシンボル、上場廃止など)
常に注意書きを添える項目
- Yahoo Finance の気配値データは、ほとんどの取引所で15 分遅延します。表示されるスプレッドは現在の市場状況を反映していない可能性があります
- 全板(レベル 2)データは、Yahoo Finance では取得できません
- マーケットインパクトの推定値はモデルに基づくものであり、保証ではありません — 実際の約定コストは、戦略、タイミング、市場状況によって異なります
- 流動性は急速に変化する可能性があります — 今日流動性の高い株式が、明日もそうとは限りません(特にイベント時、取引停止時、取引時間外)
実践的なガイダンス(該当する場合に記載)
- ポジションサイズ:推定インパクトが約 25 bps を超える場合、そのポジションは株式の流動性に対して大きすぎる可能性があります(サブスキル E のしきい値を参照)
- 小型株・超小型株に関する警告:1 日の売買代金が 100 万ドル未満の株式では、慎重な執行が必要です
- スプレッドコストの累積:往復取引(買い+売り)でスプレッドが 0.10% の場合、コストは 0.20% になります — アクティブな戦略ではこのコストが積み重なります
- 非流動性プレミアム:流動性の低い株式は、対価として歴史的に高いリターンを上げてきましたが、取引コストによってこのプレミアムが相殺されることがあります
流動性データを提示し、ユーザー自身が判断できるようにしてください。特定の取引を推奨しないでください。
参照ファイル
references/liquidity_reference.md— すべての流動性指標について、詳細な計算式、拡張コードテンプレート、指標の解釈ガイド、学術的な参考文献を掲載しています
正確な計算式、特殊ケースの処理、または流動性指標の詳しい背景が必要な場合は、参照ファイルを読んでください。