$npx -y skills add himself65/finance-skills --skill stock-liquidityAnalyze stock liquidity using bid-ask spreads, volume profiles, order book depth, market impact estimates, and turnover ratios via Yahoo Finance data. Use this skill whenever the user asks about liquidity, trading costs, bid-ask spread, market depth, volume analysis, slippage, ma
| 1 | # Stock Liquidity Analysis Skill |
| 2 | |
| 3 | Analyzes stock liquidity across multiple dimensions — bid-ask spreads, volume patterns, order book depth, estimated market impact, and turnover ratios — using data from Yahoo Finance via [yfinance](https://github.com/ranaroussi/yfinance). |
| 4 | |
| 5 | Liquidity matters because it determines the real cost of trading. The quoted price is not what you actually pay — spreads, slippage, and market impact all eat into returns, especially for larger positions or less liquid names. |
| 6 | |
| 7 | **Important**: This is for research and educational purposes only. Not financial advice. yfinance is not affiliated with Yahoo, Inc. |
| 8 | |
| 9 | --- |
| 10 | |
| 11 | ## Step 1: Ensure Dependencies Are Available |
| 12 | |
| 13 | **Current environment status:** |
| 14 | |
| 15 | ``` |
| 16 | !`python3 -c "import yfinance, pandas, numpy; print(f'yfinance={yfinance.__version__} pandas={pandas.__version__} numpy={numpy.__version__}')" 2>/dev/null || echo "DEPS_MISSING"` |
| 17 | ``` |
| 18 | |
| 19 | If `DEPS_MISSING`, install required packages: |
| 20 | |
| 21 | ```python |
| 22 | import subprocess, sys |
| 23 | subprocess.check_call([sys.executable, "-m", "pip", "install", "-q", "yfinance", "pandas", "numpy"]) |
| 24 | ``` |
| 25 | |
| 26 | If already installed, skip and proceed. |
| 27 | |
| 28 | --- |
| 29 | |
| 30 | ## Step 2: Route to the Correct Sub-Skill |
| 31 | |
| 32 | Classify the user's request and jump to the matching section. If the user asks for a general liquidity assessment without specifying a particular metric, run **Sub-Skill A** (Liquidity Dashboard) which computes all key metrics together. |
| 33 | |
| 34 | | User Request | Route To | Examples | |
| 35 | |---|---|---| |
| 36 | | General liquidity check, "how liquid is X" | **Sub-Skill A: Liquidity Dashboard** | "how liquid is AAPL", "liquidity analysis for TSLA", "is this stock liquid enough" | |
| 37 | | Bid-ask spread, trading costs, effective spread | **Sub-Skill B: Spread Analysis** | "bid-ask spread for AMD", "what's the spread on NVDA options", "trading cost estimate" | |
| 38 | | Volume, ADTV, dollar volume, volume profile | **Sub-Skill C: Volume Analysis** | "volume analysis MSFT", "average daily volume", "volume profile for SPY" | |
| 39 | | Order book depth, market depth, level 2 | **Sub-Skill D: Order Book Depth** | "order book depth for AAPL", "market depth", "show me the book" | |
| 40 | | Market impact, slippage, execution cost for large orders | **Sub-Skill E: Market Impact** | "how much would 50k shares move the price", "slippage estimate", "market impact of $1M order" | |
| 41 | | Turnover ratio, trading activity relative to float | **Sub-Skill F: Turnover Ratio** | "turnover ratio for GME", "float turnover", "how actively traded is this" | |
| 42 | | Compare liquidity across multiple stocks | **Sub-Skill A** (multi-ticker mode) | "compare liquidity AAPL vs TSLA", "which is more liquid AMD or INTC" | |
| 43 | |
| 44 | ### Defaults |
| 45 | |
| 46 | | Parameter | Default | |
| 47 | |---|---| |
| 48 | | Lookback period | `3mo` (3 months) | |
| 49 | | Data interval | `1d` (daily) | |
| 50 | | Market impact model | Square-root model | |
| 51 | | Intraday interval (when needed) | `5m` | |
| 52 | |
| 53 | --- |
| 54 | |
| 55 | ## Sub-Skill A: Liquidity Dashboard |
| 56 | |
| 57 | **Goal**: Produce a comprehensive liquidity snapshot combining all key metrics for one or more tickers. |
| 58 | |
| 59 | ### A1: Fetch data and compute all metrics |
| 60 | |
| 61 | ```python |
| 62 | import yfinance as yf |
| 63 | import pandas as pd |
| 64 | import numpy as np |
| 65 | |
| 66 | def liquidity_dashboard(ticker_symbol, period="3mo"): |
| 67 | ticker = yf.Ticker(ticker_symbol) |
| 68 | info = ticker.info |
| 69 | hist = ticker.history(period=period) |
| 70 | |
| 71 | if hist.empty: |
| 72 | return None |
| 73 | |
| 74 | # --- Spread metrics (from current quote) --- |
| 75 | bid = info.get("bid", None) |
| 76 | ask = info.get("ask", None) |
| 77 | current_price = info.get("currentPrice") or info.get("regularMarketPrice") or hist["Close"].iloc[-1] |
| 78 | |
| 79 | spread = None |
| 80 | spread_pct = None |
| 81 | if bid and ask and bid > 0 and ask > 0: |
| 82 | spread = round(ask - bid, 4) |
| 83 | midpoint = (ask + bid) / 2 |
| 84 | spread_pct = round((spread / midpoint) * 100, 4) |
| 85 | |
| 86 | # --- Volume metrics --- |
| 87 | avg_volume = hist["Volume"].mean() |
| 88 | median_volume = hist["Volume"].median() |
| 89 | avg_dollar_volume = (hist["Close"] * hist["Volume"]).mean() |
| 90 | volume_std = hist["Volume"].std() |
| 91 | volume_cv = volume_std / avg_volume if avg_volume > 0 else None # coefficient of variation |
| 92 | |
| 93 | # --- Turnover ratio --- |
| 94 | shares_outstanding = info.get("sharesOutstanding", None) |
| 95 | float_shar |