[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M70KBDDXKMQTP7QCX7X5BCEY":3,"skill-same:01M70KBDDXKMQTP7QCX7X5BCEY":61},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":32,"linkOnly":33,"markdownContent":34,"markdownBody":35,"frontMatter":36,"refName":37,"commitSha":38,"skillDirectory":39,"forksCount":40,"repositoryHtmlUrl":41,"repositoryHomepageUrl":42,"ownerHtmlUrl":43,"ownerBlogUrl":44,"ownerDescription":45,"updatedAt":46,"install":47,"resources":60},"01M70KBDDXKMQTP7QCX7X5BCEY","risk-metrics-calculation",null,"Calculate portfolio risk metrics including VaR, CVaR, Sharpe, Sortino, and drawdown analysis. Use when measuring portfolio risk, implementing risk limits, or building risk monitoring systems.","shengdabai\u002FTony-Claude-Code-Skills","shengdabai","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F116417419?v=4","01M70F6D2WY5PQV5A92BKYJQEW","Tony Sheng","01M70F6D3GAAAYZ5H4CC1G8VXM",3,"MIT","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002F_collections\u002Fwshobson-agents\u002Fplugins\u002Fquantitative-trading\u002Fskills\u002Frisk-metrics-calculation\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31],"risk","calculation","risk metrics calculation","metrics","implementing","use","when","analysis","monitoring","limits","portfolio","systems","calculate","2026-11-10 10:12:30",false,"---\nname: risk-metrics-calculation\ndescription: Calculate portfolio risk metrics including VaR, CVaR, Sharpe, Sortino, and drawdown analysis. Use when measuring portfolio risk, implementing risk limits, or building risk monitoring systems.\n---\n\n# Risk Metrics Calculation\n\nComprehensive risk measurement toolkit for portfolio management, including Value at Risk, Expected Shortfall, and drawdown analysis.\n\n## When to Use This Skill\n\n- Measuring portfolio risk\n- Implementing risk limits\n- Building risk dashboards\n- Calculating risk-adjusted returns\n- Setting position sizes\n- Regulatory reporting\n\n## Core Concepts\n\n### 1. Risk Metric Categories\n\n| Category | Metrics | Use Case |\n|----------|---------|----------|\n| **Volatility** | Std Dev, Beta | General risk |\n| **Tail Risk** | VaR, CVaR | Extreme losses |\n| **Drawdown** | Max DD, Calmar | Capital preservation |\n| **Risk-Adjusted** | Sharpe, Sortino | Performance |\n\n### 2. Time Horizons\n\n```\nIntraday:   Minute\u002Fhourly VaR for day traders\nDaily:      Standard risk reporting\nWeekly:     Rebalancing decisions\nMonthly:    Performance attribution\nAnnual:     Strategic allocation\n```\n\n## Implementation\n\n### Pattern 1: Core Risk Metrics\n\n```python\nimport numpy as np\nimport pandas as pd\nfrom scipy import stats\nfrom typing import Dict, Optional, Tuple\n\nclass RiskMetrics:\n    \"\"\"Core risk metric calculations.\"\"\"\n\n    def __init__(self, returns: pd.Series, rf_rate: float = 0.02):\n        \"\"\"\n        Args:\n            returns: Series of periodic returns\n            rf_rate: Annual risk-free rate\n        \"\"\"\n        self.returns = returns\n        self.rf_rate = rf_rate\n        self.ann_factor = 252  # Trading days per year\n\n    # Volatility Metrics\n    def volatility(self, annualized: bool = True) -> float:\n        \"\"\"Standard deviation of returns.\"\"\"\n        vol = self.returns.std()\n        if annualized:\n            vol *= np.sqrt(self.ann_factor)\n        return vol\n\n    def downside_deviation(self, threshold: float = 0, annualized: bool = True) -> float:\n        \"\"\"Standard deviation of returns below threshold.\"\"\"\n        downside = self.returns[self.returns \u003C threshold]\n        if len(downside) == 0:\n            return 0.0\n        dd = downside.std()\n        if annualized:\n            dd *= np.sqrt(self.ann_factor)\n        return dd\n\n    def beta(self, market_returns: pd.Series) -> float:\n        \"\"\"Beta relative to market.\"\"\"\n        aligned = pd.concat([self.returns, market_returns], axis=1).dropna()\n        if len(aligned) \u003C 2:\n            return np.nan\n        cov = np.cov(aligned.iloc[:, 0], aligned.iloc[:, 1])\n        return cov[0, 1] \u002F cov[1, 1] if cov[1, 1] != 0 else 0\n\n    # Value at Risk\n    def var_historical(self, confidence: float = 0.95) -> float:\n        \"\"\"Historical VaR at confidence level.\"\"\"\n        return -np.percentile(self.returns, (1 - confidence) * 100)\n\n    def var_parametric(self, confidence: float = 0.95) -> float:\n        \"\"\"Parametric VaR assuming normal distribution.\"\"\"\n        z_score = stats.norm.ppf(confidence)\n        return self.returns.mean() - z_score * self.returns.std()\n\n    def var_cornish_fisher(self, confidence: float = 0.95) -> float:\n        \"\"\"VaR with Cornish-Fisher expansion for non-normality.\"\"\"\n        z = stats.norm.ppf(confidence)\n        s = stats.skew(self.returns)  # Skewness\n        k = stats.kurtosis(self.returns)  # Excess kurtosis\n\n        # Cornish-Fisher expansion\n        z_cf = (z + (z**2 - 1) * s \u002F 6 +\n                (z**3 - 3*z) * k \u002F 24 -\n                (2*z**3 - 5*z) * s**2 \u002F 36)\n\n        return -(self.returns.mean() + z_cf * self.returns.std())\n\n    # Conditional VaR (Expected Shortfall)\n    def cvar(self, confidence: float = 0.95) -> float:\n        \"\"\"Expected Shortfall \u002F CVaR \u002F Average VaR.\"\"\"\n        var = self.var_historical(confidence)\n        return -self.returns[self.returns \u003C= -var].mean()\n\n    # Drawdown Analysis\n    def drawdowns(self) -> pd.Series:\n        \"\"\"Calculate drawdown series.\"\"\"\n        cumulative = (1 + self.returns).cumprod()\n        running_max = cumulative.cummax()\n        return (cumulative - running_max) \u002F running_max\n\n    def max_drawdown(self) -> float:\n        \"\"\"Maximum drawdown.\"\"\"\n        return self.drawdowns().min()\n\n    def avg_drawdown(self) -> float:\n        \"\"\"Average drawdown.\"\"\"\n        dd = self.drawdowns()\n        return dd[dd \u003C 0].mean() if (dd \u003C 0).any() else 0\n\n    def drawdown_duration(self) -> Dict[str, int]:\n        \"\"\"Drawdown duration statistics.\"\"\"\n        dd = self.drawdowns()\n        in_drawdown = dd \u003C 0\n\n        # Find drawdown periods\n        drawdown_starts = in_drawdown & ~in_drawdown.shift(1).fillna(False)\n        drawdown_ends = ~in_drawdown & in_drawdown.shift(1).fillna(False)\n\n        durations = []\n        current_duration = 0\n\n        for i in range(len(dd)):\n            if in_drawdown.iloc[i]:\n                current_duration += 1\n            elif current_duration > 0:\n                durations.append(current_duration)\n                current_duration = 0\n\n        if current_duration > 0:\n            durations.append(current_duration)\n\n        return {\n            \"max_duration\": max(durations) if durations else 0,\n            \"avg_duration\": np.mean(durations) if durations else 0,\n            \"current_duration\": current_duration\n        }\n\n    # Risk-Adjusted Returns\n    def sharpe_ratio(self) -> float:\n        \"\"\"Annualized Sharpe ratio.\"\"\"\n        excess_return = self.returns.mean() * self.ann_factor - self.rf_rate\n        vol = self.volatility(annualized=True)\n        return excess_return \u002F vol if vol > 0 else 0\n\n    def sortino_ratio(self) -> float:\n        \"\"\"Sortino ratio using downside deviation.\"\"\"\n        excess_return = self.returns.mean() * self.ann_factor - self.rf_rate\n        dd = self.downside_deviation(threshold=0, annualized=True)\n        return excess_return \u002F dd if dd > 0 else 0\n\n    def calmar_ratio(self) -> float:\n        \"\"\"Calmar ratio (return \u002F max drawdown).\"\"\"\n        annual_return = (1 + self.returns).prod() ** (self.ann_factor \u002F len(self.returns)) - 1\n        max_dd = abs(self.max_drawdown())\n        return annual_return \u002F max_dd if max_dd > 0 else 0\n\n    def omega_ratio(self, threshold: float = 0) -> float:\n        \"\"\"Omega ratio.\"\"\"\n        returns_above = self.returns[self.returns > threshold] - threshold\n        returns_below = threshold - self.returns[self.returns \u003C= threshold]\n\n        if returns_below.sum() == 0:\n            return np.inf\n\n        return returns_above.sum() \u002F returns_below.sum()\n\n    # Information Ratio\n    def information_ratio(self, benchmark_returns: pd.Series) -> float:\n        \"\"\"Information ratio vs benchmark.\"\"\"\n        active_returns = self.returns - benchmark_returns\n        tracking_error = active_returns.std() * np.sqrt(self.ann_factor)\n        active_return = active_returns.mean() * self.ann_factor\n        return active_return \u002F tracking_error if tracking_error > 0 else 0\n\n    # Summary\n    def summary(self) -> Dict[str, float]:\n        \"\"\"Generate comprehensive risk summary.\"\"\"\n        dd_stats = self.drawdown_duration()\n\n        return {\n            # Returns\n            \"total_return\": (1 + self.returns).prod() - 1,\n            \"annual_return\": (1 + self.returns).prod() ** (self.ann_factor \u002F len(self.returns)) - 1,\n\n            # Volatility\n            \"annual_volatility\": self.volatility(),\n            \"downside_deviation\": self.downside_deviation(),\n\n            # VaR & CVaR\n            \"var_95_historical\": self.var_historical(0.95),\n            \"var_99_historical\": self.var_historical(0.99),\n            \"cvar_95\": self.cvar(0.95),\n\n            # Drawdowns\n            \"max_drawdown\": self.max_drawdown(),\n            \"avg_drawdown\": self.avg_drawdown(),\n            \"max_drawdown_duration\": dd_stats[\"max_duration\"],\n\n            # Risk-Adjusted\n            \"sharpe_ratio\": self.sharpe_ratio(),\n            \"sortino_ratio\": self.sortino_ratio(),\n            \"calmar_ratio\": self.calmar_ratio(),\n            \"omega_ratio\": self.omega_ratio(),\n\n            # Distribution\n            \"skewness\": stats.skew(self.returns),\n            \"kurtosis\": stats.kurtosis(self.returns),\n        }\n```\n\n### Pattern 2: Portfolio Risk\n\n```python\nclass PortfolioRisk:\n    \"\"\"Portfolio-level risk calculations.\"\"\"\n\n    def __init__(\n        self,\n        returns: pd.DataFrame,\n        weights: Optional[pd.Series] = None\n    ):\n        \"\"\"\n        Args:\n            returns: DataFrame with asset returns (columns = assets)\n            weights: Portfolio weights (default: equal weight)\n        \"\"\"\n        self.returns = returns\n        self.weights = weights if weights is not None else \\\n            pd.Series(1\u002Flen(returns.columns), index=returns.columns)\n        self.ann_factor = 252\n\n    def portfolio_return(self) -> float:\n        \"\"\"Weighted portfolio return.\"\"\"\n        return (self.returns @ self.weights).mean() * self.ann_factor\n\n    def portfolio_volatility(self) -> float:\n        \"\"\"Portfolio volatility.\"\"\"\n        cov_matrix = self.returns.cov() * self.ann_factor\n        port_var = self.weights @ cov_matrix @ self.weights\n        return np.sqrt(port_var)\n\n    def marginal_risk_contribution(self) -> pd.Series:\n        \"\"\"Marginal contribution to risk by asset.\"\"\"\n        cov_matrix = self.returns.cov() * self.ann_factor\n        port_vol = self.portfolio_volatility()\n\n        # Marginal contribution\n        mrc = (cov_matrix @ self.weights) \u002F port_vol\n        return mrc\n\n    def component_risk(self) -> pd.Series:\n        \"\"\"Component contribution to total risk.\"\"\"\n        mrc = self.marginal_risk_contribution()\n        return self.weights * mrc\n\n    def risk_parity_weights(self, target_vol: float = None) -> pd.Series:\n        \"\"\"Calculate risk parity weights.\"\"\"\n        from scipy.optimize import minimize\n\n        n = len(self.returns.columns)\n        cov_matrix = self.returns.cov() * self.ann_factor\n\n        def risk_budget_objective(weights):\n            port_vol = np.sqrt(weights @ cov_matrix @ weights)\n            mrc = (cov_matrix @ weights) \u002F port_vol\n            rc = weights * mrc\n            target_rc = port_vol \u002F n  # Equal risk contribution\n            return np.sum((rc - target_rc) ** 2)\n\n        constraints = [\n            {\"type\": \"eq\", \"fun\": lambda w: np.sum(w) - 1},  # Weights sum to 1\n        ]\n        bounds = [(0.01, 1.0) for _ in range(n)]  # Min 1%, max 100%\n        x0 = np.array([1\u002Fn] * n)\n\n        result = minimize(\n            risk_budget_objective,\n            x0,\n            method=\"SLSQP\",\n            bounds=bounds,\n            constraints=constraints\n        )\n\n        return pd.Series(result.x, index=self.returns.columns)\n\n    def correlation_matrix(self) -> pd.DataFrame:\n        \"\"\"Asset correlation matrix.\"\"\"\n        return self.returns.corr()\n\n    def diversification_ratio(self) -> float:\n        \"\"\"Diversification ratio (higher = more diversified).\"\"\"\n        asset_vols = self.returns.std() * np.sqrt(self.ann_factor)\n        weighted_vol = (self.weights * asset_vols).sum()\n        port_vol = self.portfolio_volatility()\n        return weighted_vol \u002F port_vol if port_vol > 0 else 1\n\n    def tracking_error(self, benchmark_returns: pd.Series) -> float:\n        \"\"\"Tracking error vs benchmark.\"\"\"\n        port_returns = self.returns @ self.weights\n        active_returns = port_returns - benchmark_returns\n        return active_returns.std() * np.sqrt(self.ann_factor)\n\n    def conditional_correlation(\n        self,\n        threshold_percentile: float = 10\n    ) -> pd.DataFrame:\n        \"\"\"Correlation during stress periods.\"\"\"\n        port_returns = self.returns @ self.weights\n        threshold = np.percentile(port_returns, threshold_percentile)\n        stress_mask = port_returns \u003C= threshold\n        return self.returns[stress_mask].corr()\n```\n\n### Pattern 3: Rolling Risk Metrics\n\n```python\nclass RollingRiskMetrics:\n    \"\"\"Rolling window risk calculations.\"\"\"\n\n    def __init__(self, returns: pd.Series, window: int = 63):\n        \"\"\"\n        Args:\n            returns: Return series\n            window: Rolling window size (default: 63 = ~3 months)\n        \"\"\"\n        self.returns = returns\n        self.window = window\n\n    def rolling_volatility(self, annualized: bool = True) -> pd.Series:\n        \"\"\"Rolling volatility.\"\"\"\n        vol = self.returns.rolling(self.window).std()\n        if annualized:\n            vol *= np.sqrt(252)\n        return vol\n\n    def rolling_sharpe(self, rf_rate: float = 0.02) -> pd.Series:\n        \"\"\"Rolling Sharpe ratio.\"\"\"\n        rolling_return = self.returns.rolling(self.window).mean() * 252\n        rolling_vol = self.rolling_volatility()\n        return (rolling_return - rf_rate) \u002F rolling_vol\n\n    def rolling_var(self, confidence: float = 0.95) -> pd.Series:\n        \"\"\"Rolling historical VaR.\"\"\"\n        return self.returns.rolling(self.window).apply(\n            lambda x: -np.percentile(x, (1 - confidence) * 100),\n            raw=True\n        )\n\n    def rolling_max_drawdown(self) -> pd.Series:\n        \"\"\"Rolling maximum drawdown.\"\"\"\n        def max_dd(returns):\n            cumulative = (1 + returns).cumprod()\n            running_max = cumulative.cummax()\n            drawdowns = (cumulative - running_max) \u002F running_max\n            return drawdowns.min()\n\n        return self.returns.rolling(self.window).apply(max_dd, raw=False)\n\n    def rolling_beta(self, market_returns: pd.Series) -> pd.Series:\n        \"\"\"Rolling beta vs market.\"\"\"\n        def calc_beta(window_data):\n            port_ret = window_data.iloc[:, 0]\n            mkt_ret = window_data.iloc[:, 1]\n            cov = np.cov(port_ret, mkt_ret)\n            return cov[0, 1] \u002F cov[1, 1] if cov[1, 1] != 0 else 0\n\n        combined = pd.concat([self.returns, market_returns], axis=1)\n        return combined.rolling(self.window).apply(\n            lambda x: calc_beta(x.to_frame()),\n            raw=False\n        ).iloc[:, 0]\n\n    def volatility_regime(\n        self,\n        low_threshold: float = 0.10,\n        high_threshold: float = 0.20\n    ) -> pd.Series:\n        \"\"\"Classify volatility regime.\"\"\"\n        vol = self.rolling_volatility()\n\n        def classify(v):\n            if v \u003C low_threshold:\n                return \"low\"\n            elif v > high_threshold:\n                return \"high\"\n            else:\n                return \"normal\"\n\n        return vol.apply(classify)\n```\n\n### Pattern 4: Stress Testing\n\n```python\nclass StressTester:\n    \"\"\"Historical and hypothetical stress testing.\"\"\"\n\n    # Historical crisis periods\n    HISTORICAL_SCENARIOS = {\n        \"2008_financial_crisis\": (\"2008-09-01\", \"2009-03-31\"),\n        \"2020_covid_crash\": (\"2020-02-19\", \"2020-03-23\"),\n        \"2022_rate_hikes\": (\"2022-01-01\", \"2022-10-31\"),\n        \"dot_com_bust\": (\"2000-03-01\", \"2002-10-01\"),\n        \"flash_crash_2010\": (\"2010-05-06\", \"2010-05-06\"),\n    }\n\n    def __init__(self, returns: pd.Series, weights: pd.Series = None):\n        self.returns = returns\n        self.weights = weights\n\n    def historical_stress_test(\n        self,\n        scenario_name: str,\n        historical_data: pd.DataFrame\n    ) -> Dict[str, float]:\n        \"\"\"Test portfolio against historical crisis period.\"\"\"\n        if scenario_name not in self.HISTORICAL_SCENARIOS:\n            raise ValueError(f\"Unknown scenario: {scenario_name}\")\n\n        start, end = self.HISTORICAL_SCENARIOS[scenario_name]\n\n        # Get returns during crisis\n        crisis_returns = historical_data.loc[start:end]\n\n        if self.weights is not None:\n            port_returns = (crisis_returns @ self.weights)\n        else:\n            port_returns = crisis_returns\n\n        total_return = (1 + port_returns).prod() - 1\n        max_dd = self._calculate_max_dd(port_returns)\n        worst_day = port_returns.min()\n\n        return {\n            \"scenario\": scenario_name,\n            \"period\": f\"{start} to {end}\",\n            \"total_return\": total_return,\n            \"max_drawdown\": max_dd,\n            \"worst_day\": worst_day,\n            \"volatility\": port_returns.std() * np.sqrt(252)\n        }\n\n    def hypothetical_stress_test(\n        self,\n        shocks: Dict[str, float]\n    ) -> float:\n        \"\"\"\n        Test portfolio against hypothetical shocks.\n\n        Args:\n            shocks: Dict of {asset: shock_return}\n        \"\"\"\n        if self.weights is None:\n            raise ValueError(\"Weights required for hypothetical stress test\")\n\n        total_impact = 0\n        for asset, shock in shocks.items():\n            if asset in self.weights.index:\n                total_impact += self.weights[asset] * shock\n\n        return total_impact\n\n    def monte_carlo_stress(\n        self,\n        n_simulations: int = 10000,\n        horizon_days: int = 21,\n        vol_multiplier: float = 2.0\n    ) -> Dict[str, float]:\n        \"\"\"Monte Carlo stress test with elevated volatility.\"\"\"\n        mean = self.returns.mean()\n        vol = self.returns.std() * vol_multiplier\n\n        simulations = np.random.normal(\n            mean,\n            vol,\n            (n_simulations, horizon_days)\n        )\n\n        total_returns = (1 + simulations).prod(axis=1) - 1\n\n        return {\n            \"expected_loss\": -total_returns.mean(),\n            \"var_95\": -np.percentile(total_returns, 5),\n            \"var_99\": -np.percentile(total_returns, 1),\n            \"worst_case\": -total_returns.min(),\n            \"prob_10pct_loss\": (total_returns \u003C -0.10).mean()\n        }\n\n    def _calculate_max_dd(self, returns: pd.Series) -> float:\n        cumulative = (1 + returns).cumprod()\n        running_max = cumulative.cummax()\n        drawdowns = (cumulative - running_max) \u002F running_max\n        return drawdowns.min()\n```\n\n## Quick Reference\n\n```python\n# Daily usage\nmetrics = RiskMetrics(returns)\nprint(f\"Sharpe: {metrics.sharpe_ratio():.2f}\")\nprint(f\"Max DD: {metrics.max_drawdown():.2%}\")\nprint(f\"VaR 95%: {metrics.var_historical(0.95):.2%}\")\n\n# Full summary\nsummary = metrics.summary()\nfor metric, value in summary.items():\n    print(f\"{metric}: {value:.4f}\")\n```\n\n## Best Practices\n\n### Do's\n- **Use multiple metrics** - No single metric captures all risk\n- **Consider tail risk** - VaR isn't enough, use CVaR\n- **Rolling analysis** - Risk changes over time\n- **Stress test** - Historical and hypothetical\n- **Document assumptions** - Distribution, lookback, etc.\n\n### Don'ts\n- **Don't rely on VaR alone** - Underestimates tail risk\n- **Don't assume normality** - Returns are fat-tailed\n- **Don't ignore correlation** - Increases in stress\n- **Don't use short lookbacks** - Miss regime changes\n- **Don't forget transaction costs** - Affects realized risk\n\n## Resources\n\n- [Risk Management and Financial Institutions (John Hull)](https:\u002F\u002Fwww.amazon.com\u002FRisk-Management-Financial-Institutions-5th\u002Fdp\u002F1119448115)\n- [Quantitative Risk Management (McNeil, Frey, Embrechts)](https:\u002F\u002Fwww.amazon.com\u002FQuantitative-Risk-Management-Techniques-Princeton\u002Fdp\u002F0691166277)\n- [pyfolio Documentation](https:\u002F\u002Fquantopian.github.io\u002Fpyfolio\u002F)\n","# Risk Metrics Calculation\n\nComprehensive risk measurement toolkit for portfolio management, including Value at Risk, Expected Shortfall, and drawdown analysis.\n\n## When to Use This Skill\n\n- Measuring portfolio risk\n- Implementing risk limits\n- Building risk dashboards\n- Calculating risk-adjusted returns\n- Setting position sizes\n- Regulatory reporting\n\n## Core Concepts\n\n### 1. Risk Metric Categories\n\n| Category | Metrics | Use Case |\n|----------|---------|----------|\n| **Volatility** | Std Dev, Beta | General risk |\n| **Tail Risk** | VaR, CVaR | Extreme losses |\n| **Drawdown** | Max DD, Calmar | Capital preservation |\n| **Risk-Adjusted** | Sharpe, Sortino | Performance |\n\n### 2. Time Horizons\n\n```\nIntraday:   Minute\u002Fhourly VaR for day traders\nDaily:      Standard risk reporting\nWeekly:     Rebalancing decisions\nMonthly:    Performance attribution\nAnnual:     Strategic allocation\n```\n\n## Implementation\n\n### Pattern 1: Core Risk Metrics\n\n```python\nimport numpy as np\nimport pandas as pd\nfrom scipy import stats\nfrom typing import Dict, Optional, Tuple\n\nclass RiskMetrics:\n    \"\"\"Core risk metric calculations.\"\"\"\n\n    def __init__(self, returns: pd.Series, rf_rate: float = 0.02):\n        \"\"\"\n        Args:\n            returns: Series of periodic returns\n            rf_rate: Annual risk-free rate\n        \"\"\"\n        self.returns = returns\n        self.rf_rate = rf_rate\n        self.ann_factor = 252  # Trading days per year\n\n    # Volatility Metrics\n    def volatility(self, annualized: bool = True) -> float:\n        \"\"\"Standard deviation of returns.\"\"\"\n        vol = self.returns.std()\n        if annualized:\n            vol *= np.sqrt(self.ann_factor)\n        return vol\n\n    def downside_deviation(self, threshold: float = 0, annualized: bool = True) -> float:\n        \"\"\"Standard deviation of returns below threshold.\"\"\"\n        downside = self.returns[self.returns \u003C threshold]\n        if len(downside) == 0:\n            return 0.0\n        dd = downside.std()\n        if annualized:\n            dd *= np.sqrt(self.ann_factor)\n        return dd\n\n    def beta(self, market_returns: pd.Series) -> float:\n        \"\"\"Beta relative to market.\"\"\"\n        aligned = pd.concat([self.returns, market_returns], axis=1).dropna()\n        if len(aligned) \u003C 2:\n            return np.nan\n        cov = np.cov(aligned.iloc[:, 0], aligned.iloc[:, 1])\n        return cov[0, 1] \u002F cov[1, 1] if cov[1, 1] != 0 else 0\n\n    # Value at Risk\n    def var_historical(self, confidence: float = 0.95) -> float:\n        \"\"\"Historical VaR at confidence level.\"\"\"\n        return -np.percentile(self.returns, (1 - confidence) * 100)\n\n    def var_parametric(self, confidence: float = 0.95) -> float:\n        \"\"\"Parametric VaR assuming normal distribution.\"\"\"\n        z_score = stats.norm.ppf(confidence)\n        return self.returns.mean() - z_score * self.returns.std()\n\n    def var_cornish_fisher(self, confidence: float = 0.95) -> float:\n        \"\"\"VaR with Cornish-Fisher expansion for non-normality.\"\"\"\n        z = stats.norm.ppf(confidence)\n        s = stats.skew(self.returns)  # Skewness\n        k = stats.kurtosis(self.returns)  # Excess kurtosis\n\n        # Cornish-Fisher expansion\n        z_cf = (z + (z**2 - 1) * s \u002F 6 +\n                (z**3 - 3*z) * k \u002F 24 -\n                (2*z**3 - 5*z) * s**2 \u002F 36)\n\n        return -(self.returns.mean() + z_cf * self.returns.std())\n\n    # Conditional VaR (Expected Shortfall)\n    def cvar(self, confidence: float = 0.95) -> float:\n        \"\"\"Expected Shortfall \u002F CVaR \u002F Average VaR.\"\"\"\n        var = self.var_historical(confidence)\n        return -self.returns[self.returns \u003C= -var].mean()\n\n    # Drawdown Analysis\n    def drawdowns(self) -> pd.Series:\n        \"\"\"Calculate drawdown series.\"\"\"\n        cumulative = (1 + self.returns).cumprod()\n        running_max = cumulative.cummax()\n        return (cumulative - running_max) \u002F running_max\n\n    def max_drawdown(self) -> float:\n        \"\"\"Maximum drawdown.\"\"\"\n        return self.drawdowns().min()\n\n    def avg_drawdown(self) -> float:\n        \"\"\"Average drawdown.\"\"\"\n        dd = self.drawdowns()\n        return dd[dd \u003C 0].mean() if (dd \u003C 0).any() else 0\n\n    def drawdown_duration(self) -> Dict[str, int]:\n        \"\"\"Drawdown duration statistics.\"\"\"\n        dd = self.drawdowns()\n        in_drawdown = dd \u003C 0\n\n        # Find drawdown periods\n        drawdown_starts = in_drawdown & ~in_drawdown.shift(1).fillna(False)\n        drawdown_ends = ~in_drawdown & in_drawdown.shift(1).fillna(False)\n\n        durations = []\n        current_duration = 0\n\n        for i in range(len(dd)):\n            if in_drawdown.iloc[i]:\n                current_duration += 1\n            elif current_duration > 0:\n                durations.append(current_duration)\n                current_duration = 0\n\n        if current_duration > 0:\n            durations.append(current_duration)\n\n        return {\n            \"max_duration\": max(durations) if durations else 0,\n            \"avg_duration\": np.mean(durations) if durations else 0,\n            \"current_duration\": current_duration\n        }\n\n    # Risk-Adjusted Returns\n    def sharpe_ratio(self) -> float:\n        \"\"\"Annualized Sharpe ratio.\"\"\"\n        excess_return = self.returns.mean() * self.ann_factor - self.rf_rate\n        vol = self.volatility(annualized=True)\n        return excess_return \u002F vol if vol > 0 else 0\n\n    def sortino_ratio(self) -> float:\n        \"\"\"Sortino ratio using downside deviation.\"\"\"\n        excess_return = self.returns.mean() * self.ann_factor - self.rf_rate\n        dd = self.downside_deviation(threshold=0, annualized=True)\n        return excess_return \u002F dd if dd > 0 else 0\n\n    def calmar_ratio(self) -> float:\n        \"\"\"Calmar ratio (return \u002F max drawdown).\"\"\"\n        annual_return = (1 + self.returns).prod() ** (self.ann_factor \u002F len(self.returns)) - 1\n        max_dd = abs(self.max_drawdown())\n        return annual_return \u002F max_dd if max_dd > 0 else 0\n\n    def omega_ratio(self, threshold: float = 0) -> float:\n        \"\"\"Omega ratio.\"\"\"\n        returns_above = self.returns[self.returns > threshold] - threshold\n        returns_below = threshold - self.returns[self.returns \u003C= threshold]\n\n        if returns_below.sum() == 0:\n            return np.inf\n\n        return returns_above.sum() \u002F returns_below.sum()\n\n    # Information Ratio\n    def information_ratio(self, benchmark_returns: pd.Series) -> float:\n        \"\"\"Information ratio vs benchmark.\"\"\"\n        active_returns = self.returns - benchmark_returns\n        tracking_error = active_returns.std() * np.sqrt(self.ann_factor)\n        active_return = active_returns.mean() * self.ann_factor\n        return active_return \u002F tracking_error if tracking_error > 0 else 0\n\n    # Summary\n    def summary(self) -> Dict[str, float]:\n        \"\"\"Generate comprehensive risk summary.\"\"\"\n        dd_stats = self.drawdown_duration()\n\n        return {\n            # Returns\n            \"total_return\": (1 + self.returns).prod() - 1,\n            \"annual_return\": (1 + self.returns).prod() ** (self.ann_factor \u002F len(self.returns)) - 1,\n\n            # Volatility\n            \"annual_volatility\": self.volatility(),\n            \"downside_deviation\": self.downside_deviation(),\n\n            # VaR & CVaR\n            \"var_95_historical\": self.var_historical(0.95),\n            \"var_99_historical\": self.var_historical(0.99),\n            \"cvar_95\": self.cvar(0.95),\n\n            # Drawdowns\n            \"max_drawdown\": self.max_drawdown(),\n            \"avg_drawdown\": self.avg_drawdown(),\n            \"max_drawdown_duration\": dd_stats[\"max_duration\"],\n\n            # Risk-Adjusted\n            \"sharpe_ratio\": self.sharpe_ratio(),\n            \"sortino_ratio\": self.sortino_ratio(),\n            \"calmar_ratio\": self.calmar_ratio(),\n            \"omega_ratio\": self.omega_ratio(),\n\n            # Distribution\n            \"skewness\": stats.skew(self.returns),\n            \"kurtosis\": stats.kurtosis(self.returns),\n        }\n```\n\n### Pattern 2: Portfolio Risk\n\n```python\nclass PortfolioRisk:\n    \"\"\"Portfolio-level risk calculations.\"\"\"\n\n    def __init__(\n        self,\n        returns: pd.DataFrame,\n        weights: Optional[pd.Series] = None\n    ):\n        \"\"\"\n        Args:\n            returns: DataFrame with asset returns (columns = assets)\n            weights: Portfolio weights (default: equal weight)\n        \"\"\"\n        self.returns = returns\n        self.weights = weights if weights is not None else \\\n            pd.Series(1\u002Flen(returns.columns), index=returns.columns)\n        self.ann_factor = 252\n\n    def portfolio_return(self) -> float:\n        \"\"\"Weighted portfolio return.\"\"\"\n        return (self.returns @ self.weights).mean() * self.ann_factor\n\n    def portfolio_volatility(self) -> float:\n        \"\"\"Portfolio volatility.\"\"\"\n        cov_matrix = self.returns.cov() * self.ann_factor\n        port_var = self.weights @ cov_matrix @ self.weights\n        return np.sqrt(port_var)\n\n    def marginal_risk_contribution(self) -> pd.Series:\n        \"\"\"Marginal contribution to risk by asset.\"\"\"\n        cov_matrix = self.returns.cov() * self.ann_factor\n        port_vol = self.portfolio_volatility()\n\n        # Marginal contribution\n        mrc = (cov_matrix @ self.weights) \u002F port_vol\n        return mrc\n\n    def component_risk(self) -> pd.Series:\n        \"\"\"Component contribution to total risk.\"\"\"\n        mrc = self.marginal_risk_contribution()\n        return self.weights * mrc\n\n    def risk_parity_weights(self, target_vol: float = None) -> pd.Series:\n        \"\"\"Calculate risk parity weights.\"\"\"\n        from scipy.optimize import minimize\n\n        n = len(self.returns.columns)\n        cov_matrix = self.returns.cov() * self.ann_factor\n\n        def risk_budget_objective(weights):\n            port_vol = np.sqrt(weights @ cov_matrix @ weights)\n            mrc = (cov_matrix @ weights) \u002F port_vol\n            rc = weights * mrc\n            target_rc = port_vol \u002F n  # Equal risk contribution\n            return np.sum((rc - target_rc) ** 2)\n\n        constraints = [\n            {\"type\": \"eq\", \"fun\": lambda w: np.sum(w) - 1},  # Weights sum to 1\n        ]\n        bounds = [(0.01, 1.0) for _ in range(n)]  # Min 1%, max 100%\n        x0 = np.array([1\u002Fn] * n)\n\n        result = minimize(\n            risk_budget_objective,\n            x0,\n            method=\"SLSQP\",\n            bounds=bounds,\n            constraints=constraints\n        )\n\n        return pd.Series(result.x, index=self.returns.columns)\n\n    def correlation_matrix(self) -> pd.DataFrame:\n        \"\"\"Asset correlation matrix.\"\"\"\n        return self.returns.corr()\n\n    def diversification_ratio(self) -> float:\n        \"\"\"Diversification ratio (higher = more diversified).\"\"\"\n        asset_vols = self.returns.std() * np.sqrt(self.ann_factor)\n        weighted_vol = (self.weights * asset_vols).sum()\n        port_vol = self.portfolio_volatility()\n        return weighted_vol \u002F port_vol if port_vol > 0 else 1\n\n    def tracking_error(self, benchmark_returns: pd.Series) -> float:\n        \"\"\"Tracking error vs benchmark.\"\"\"\n        port_returns = self.returns @ self.weights\n        active_returns = port_returns - benchmark_returns\n        return active_returns.std() * np.sqrt(self.ann_factor)\n\n    def conditional_correlation(\n        self,\n        threshold_percentile: float = 10\n    ) -> pd.DataFrame:\n        \"\"\"Correlation during stress periods.\"\"\"\n        port_returns = self.returns @ self.weights\n        threshold = np.percentile(port_returns, threshold_percentile)\n        stress_mask = port_returns \u003C= threshold\n        return self.returns[stress_mask].corr()\n```\n\n### Pattern 3: Rolling Risk Metrics\n\n```python\nclass RollingRiskMetrics:\n    \"\"\"Rolling window risk calculations.\"\"\"\n\n    def __init__(self, returns: pd.Series, window: int = 63):\n        \"\"\"\n        Args:\n            returns: Return series\n            window: Rolling window size (default: 63 = ~3 months)\n        \"\"\"\n        self.returns = returns\n        self.window = window\n\n    def rolling_volatility(self, annualized: bool = True) -> pd.Series:\n        \"\"\"Rolling volatility.\"\"\"\n        vol = self.returns.rolling(self.window).std()\n        if annualized:\n            vol *= np.sqrt(252)\n        return vol\n\n    def rolling_sharpe(self, rf_rate: float = 0.02) -> pd.Series:\n        \"\"\"Rolling Sharpe ratio.\"\"\"\n        rolling_return = self.returns.rolling(self.window).mean() * 252\n        rolling_vol = self.rolling_volatility()\n        return (rolling_return - rf_rate) \u002F rolling_vol\n\n    def rolling_var(self, confidence: float = 0.95) -> pd.Series:\n        \"\"\"Rolling historical VaR.\"\"\"\n        return self.returns.rolling(self.window).apply(\n            lambda x: -np.percentile(x, (1 - confidence) * 100),\n            raw=True\n        )\n\n    def rolling_max_drawdown(self) -> pd.Series:\n        \"\"\"Rolling maximum drawdown.\"\"\"\n        def max_dd(returns):\n            cumulative = (1 + returns).cumprod()\n            running_max = cumulative.cummax()\n            drawdowns = (cumulative - running_max) \u002F running_max\n            return drawdowns.min()\n\n        return self.returns.rolling(self.window).apply(max_dd, raw=False)\n\n    def rolling_beta(self, market_returns: pd.Series) -> pd.Series:\n        \"\"\"Rolling beta vs market.\"\"\"\n        def calc_beta(window_data):\n            port_ret = window_data.iloc[:, 0]\n            mkt_ret = window_data.iloc[:, 1]\n            cov = np.cov(port_ret, mkt_ret)\n            return cov[0, 1] \u002F cov[1, 1] if cov[1, 1] != 0 else 0\n\n        combined = pd.concat([self.returns, market_returns], axis=1)\n        return combined.rolling(self.window).apply(\n            lambda x: calc_beta(x.to_frame()),\n            raw=False\n        ).iloc[:, 0]\n\n    def volatility_regime(\n        self,\n        low_threshold: float = 0.10,\n        high_threshold: float = 0.20\n    ) -> pd.Series:\n        \"\"\"Classify volatility regime.\"\"\"\n        vol = self.rolling_volatility()\n\n        def classify(v):\n            if v \u003C low_threshold:\n                return \"low\"\n            elif v > high_threshold:\n                return \"high\"\n            else:\n                return \"normal\"\n\n        return vol.apply(classify)\n```\n\n### Pattern 4: Stress Testing\n\n```python\nclass StressTester:\n    \"\"\"Historical and hypothetical stress testing.\"\"\"\n\n    # Historical crisis periods\n    HISTORICAL_SCENARIOS = {\n        \"2008_financial_crisis\": (\"2008-09-01\", \"2009-03-31\"),\n        \"2020_covid_crash\": (\"2020-02-19\", \"2020-03-23\"),\n        \"2022_rate_hikes\": (\"2022-01-01\", \"2022-10-31\"),\n        \"dot_com_bust\": (\"2000-03-01\", \"2002-10-01\"),\n        \"flash_crash_2010\": (\"2010-05-06\", \"2010-05-06\"),\n    }\n\n    def __init__(self, returns: pd.Series, weights: pd.Series = None):\n        self.returns = returns\n        self.weights = weights\n\n    def historical_stress_test(\n        self,\n        scenario_name: str,\n        historical_data: pd.DataFrame\n    ) -> Dict[str, float]:\n        \"\"\"Test portfolio against historical crisis period.\"\"\"\n        if scenario_name not in self.HISTORICAL_SCENARIOS:\n            raise ValueError(f\"Unknown scenario: {scenario_name}\")\n\n        start, end = self.HISTORICAL_SCENARIOS[scenario_name]\n\n        # Get returns during crisis\n        crisis_returns = historical_data.loc[start:end]\n\n        if self.weights is not None:\n            port_returns = (crisis_returns @ self.weights)\n        else:\n            port_returns = crisis_returns\n\n        total_return = (1 + port_returns).prod() - 1\n        max_dd = self._calculate_max_dd(port_returns)\n        worst_day = port_returns.min()\n\n        return {\n            \"scenario\": scenario_name,\n            \"period\": f\"{start} to {end}\",\n            \"total_return\": total_return,\n            \"max_drawdown\": max_dd,\n            \"worst_day\": worst_day,\n            \"volatility\": port_returns.std() * np.sqrt(252)\n        }\n\n    def hypothetical_stress_test(\n        self,\n        shocks: Dict[str, float]\n    ) -> float:\n        \"\"\"\n        Test portfolio against hypothetical shocks.\n\n        Args:\n            shocks: Dict of {asset: shock_return}\n        \"\"\"\n        if self.weights is None:\n            raise ValueError(\"Weights required for hypothetical stress test\")\n\n        total_impact = 0\n        for asset, shock in shocks.items():\n            if asset in self.weights.index:\n                total_impact += self.weights[asset] * shock\n\n        return total_impact\n\n    def monte_carlo_stress(\n        self,\n        n_simulations: int = 10000,\n        horizon_days: int = 21,\n        vol_multiplier: float = 2.0\n    ) -> Dict[str, float]:\n        \"\"\"Monte Carlo stress test with elevated volatility.\"\"\"\n        mean = self.returns.mean()\n        vol = self.returns.std() * vol_multiplier\n\n        simulations = np.random.normal(\n            mean,\n            vol,\n            (n_simulations, horizon_days)\n        )\n\n        total_returns = (1 + simulations).prod(axis=1) - 1\n\n        return {\n            \"expected_loss\": -total_returns.mean(),\n            \"var_95\": -np.percentile(total_returns, 5),\n            \"var_99\": -np.percentile(total_returns, 1),\n            \"worst_case\": -total_returns.min(),\n            \"prob_10pct_loss\": (total_returns \u003C -0.10).mean()\n        }\n\n    def _calculate_max_dd(self, returns: pd.Series) -> float:\n        cumulative = (1 + returns).cumprod()\n        running_max = cumulative.cummax()\n        drawdowns = (cumulative - running_max) \u002F running_max\n        return drawdowns.min()\n```\n\n## Quick Reference\n\n```python\n# Daily usage\nmetrics = RiskMetrics(returns)\nprint(f\"Sharpe: {metrics.sharpe_ratio():.2f}\")\nprint(f\"Max DD: {metrics.max_drawdown():.2%}\")\nprint(f\"VaR 95%: {metrics.var_historical(0.95):.2%}\")\n\n# Full summary\nsummary = metrics.summary()\nfor metric, value in summary.items():\n    print(f\"{metric}: {value:.4f}\")\n```\n\n## Best Practices\n\n### Do's\n- **Use multiple metrics** - No single metric captures all risk\n- **Consider tail risk** - VaR isn't enough, use CVaR\n- **Rolling analysis** - Risk changes over time\n- **Stress test** - Historical and hypothetical\n- **Document assumptions** - Distribution, lookback, etc.\n\n### Don'ts\n- **Don't rely on VaR alone** - Underestimates tail risk\n- **Don't assume normality** - Returns are fat-tailed\n- **Don't ignore correlation** - Increases in stress\n- **Don't use short lookbacks** - Miss regime changes\n- **Don't forget transaction costs** - Affects realized risk\n\n## Resources\n\n- [Risk Management and Financial Institutions (John Hull)](https:\u002F\u002Fwww.amazon.com\u002FRisk-Management-Financial-Institutions-5th\u002Fdp\u002F1119448115)\n- [Quantitative Risk Management (McNeil, Frey, Embrechts)](https:\u002F\u002Fwww.amazon.com\u002FQuantitative-Risk-Management-Techniques-Princeton\u002Fdp\u002F0691166277)\n- [pyfolio Documentation](https:\u002F\u002Fquantopian.github.io\u002Fpyfolio\u002F)\n",{"name":5,"description":7},"main","7850740bd837adb32f0a109ab2af82482196c6f2","skills\u002F_collections\u002Fwshobson-agents\u002Fplugins\u002Fquantitative-trading\u002Fskills\u002Frisk-metrics-calculation",1,"https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills","https:\u002F\u002Fzturnsgo.com","https:\u002F\u002Fgithub.com\u002Fshengdabai","https:\u002F\u002Fzturnsgo.com\u002F","AI × education creator — producer, not consumer. Taught 6,000+ learners; shipping learning tools & daily essays with Claude Code, practicing @xiaolai's way 🥋","2026-11-01 21:28:23",{"source":8,"skillName":5,"commands":48,"prompt":58,"zipAvailable":59},[49,52,55],{"tool":50,"command":51},"npx","npx skills add shengdabai\u002FTony-Claude-Code-Skills --skill risk-metrics-calculation",{"tool":53,"command":54},"bunx","bunx skills add shengdabai\u002FTony-Claude-Code-Skills --skill risk-metrics-calculation",{"tool":56,"command":57},"pnpm","pnpm dlx skills add shengdabai\u002FTony-Claude-Code-Skills --skill risk-metrics-calculation","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002F_collections\u002Fwshobson-agents\u002Fplugins\u002Fquantitative-trading\u002Fskills\u002Frisk-metrics-calculation\u002FSKILL.md",true,[],[62,81,115,140,162,182],{"skillNo":63,"name":64,"nameZh":6,"description":65,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":66,"categories":67,"keywords":73,"publishedAt":32},"01M70P17DAD4C1C47NPH6A96EM","xiaolai-methodology","以李笑来(Li Xiaolai)的思考方式、方法论与表达风格,为用户做全方位 1-on-1 教练指导,覆盖创业、赚钱、投资、学习、自学、读书写作、用 AI、以及人生心态与自我管理。当用户提到 \"李笑来\"、\"笑来\"、\"笑来老师\"、\"扮演李笑来\"、\"找笑来聊聊\"、\"笑来怎么看\"、\"xiaolai\"、\"把时间当作朋友\"、\"通往财富自由之路\"、\"定投改变命运\"、\"韭菜的自我修养\"、\"自学是门手艺\"、\"让时间陪你慢慢变富\"、\"七年就是一辈子\"、\"元认知\"、\"活在未来\"、\"复利\u002F长期主义\"、\"践行\"、\"痴迷改进\"、\"个人商业模式\u002F出售时间\"、\"睡后收入\"、\"定投\"、\"财富自由\"、\"操作系统升级\"、\"最少必要知识\"、\"北极星提示词\"、\"用 AI 该怎么学\u002F思考\" 等任一触发词,或当用户带着关于创业\u002F赚钱\u002F投资\u002F学习\u002F职业\u002F重大人生决策的困惑、希望被人用笑来式的「逻辑 + 大白话 + 类比 + 重新定义 + 践行导向」来点醒和指导时,自动进入李笑来教练模式。","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fxiaolai-methodology\u002FSKILL.md",[68],{"categoryNo":69,"categoryName":70,"taxonomyType":71,"taxonomyTypeDesc":72},"01JBSEEDCAT000000000000018","写作与文案","SCENARIO","使用场景",[74,75,76,77,78,79,80],"methodology","xiaolai","xiaolai methodology","朋友","投资","writing","收入",{"skillNo":82,"name":83,"nameZh":6,"description":84,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":85,"categories":86,"keywords":95,"publishedAt":32},"01M70P13NB9YP7ACJR1S861CDS","zread","Produce and consume a wiki-style knowledge base for a code repository via the `zread` CLI and its on-disk output under `.\u002F.zread\u002Fwiki\u002F`. Use this skill whenever the user wants to understand, onboard onto, explore, summarize, map, or get an overview of an unfamiliar codebase; asks for architecture docs, a project wiki, a repo walkthrough, module\u002Fpackage explanations, or \"what does this repo do\"; wants to generate, regenerate, resume, browse, or serve code documentation locally; or mentions zread \u002F zread.ai directly. Also use it proactively before diving into a large unknown repo — if `.\u002F.zread\u002Fwiki\u002Fcurrent` exists, read the generated pages instead of crawling source file-by-file; if it doesn't, consider offering to run `zread generate`. The trigger is the intent (understand a codebase through generated docs), not the literal word \"zread\".","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fzread\u002FSKILL.md",[87,90],{"categoryNo":88,"categoryName":89,"taxonomyType":71,"taxonomyTypeDesc":72},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":91,"categoryName":92,"taxonomyType":93,"taxonomyTypeDesc":94},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[83,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114],"knowledge","wiki","explore","walkthrough","project","get","knowledge base","run","generate","intent","cli","map","documentation","project wiki","disk","architecture","code","unknown","generated",{"skillNo":116,"name":117,"nameZh":6,"description":118,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":119,"categories":120,"keywords":125,"publishedAt":32},"01M70P10S4SWMZQ8BJAFBFDRW3","youtube","Launch the YouTube Creator Agent to auto-generate videos.\nUse when: user types \u002Fyoutube, wants to create YouTube videos,\ngenerate video content, or upload to YouTube.\nKeywords: youtube, video, 视频, 创作视频, 发布视频","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fyoutube\u002FSKILL.md",[121,122],{"categoryNo":88,"categoryName":89,"taxonomyType":71,"taxonomyTypeDesc":72},{"categoryNo":123,"categoryName":124,"taxonomyType":93,"taxonomyTypeDesc":94},"01JBSEEDCAT000000000000036","内容创作者",[117,126,127,128,129,130,131,132,104,133,134,135,25,24,136,137,138,139],"user","content","视频","creator","generate video","videos","launch","video content","create","upload","auto","types","Video","创作",{"skillNo":141,"name":142,"nameZh":6,"description":143,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":144,"categories":145,"keywords":147,"publishedAt":32},"01M70P0YE95D8BACZCGV8BK90K","youtube-script-sync","Sync, update, or optimize Tony's GetNote knowledge base `Youtube视频逐字稿` by turning each parent recording or first-person idea note into an idempotent child note containing a directly recordable YouTube long-video or Shorts script. Use when the user says “更新\u002F同步\u002F优化 Youtube视频逐字稿知识库”, or says “更新\u002F同步\u002F优化该知识库” while this knowledge base is the active context.","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fyoutube-script-sync\u002FSKILL.md",[146],{"categoryNo":88,"categoryName":89,"taxonomyType":71,"taxonomyTypeDesc":72},[148,149,117,150,151,138,152,153,154,155,156,157,158,159,102,160,25,24,96,161],"sync","script","youtube script sync","recording","shorts","first","base","person","update","active","child","optimize","idempotent","long",{"skillNo":163,"name":164,"nameZh":6,"description":165,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":166,"categories":167,"keywords":172,"publishedAt":32},"01M70P0WMV5XT0EEC0N445PW07","writing-skills","How to write SKILL.md files that trigger reliably and teach effectively. Use when creating, improving, or reviewing Claude Code skills.","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fxiaolai\u002Fnlpm\u002Fskills\u002Fnlpm\u002Fwriting-skills\u002FSKILL.md",[168,169,170,171],{"categoryNo":69,"categoryName":70,"taxonomyType":71,"taxonomyTypeDesc":72},{"categoryNo":88,"categoryName":89,"taxonomyType":71,"taxonomyTypeDesc":72},{"categoryNo":91,"categoryName":92,"taxonomyType":93,"taxonomyTypeDesc":94},{"categoryNo":123,"categoryName":124,"taxonomyType":93,"taxonomyTypeDesc":94},[173,79,174,175,176,177,112,25,24,178,179,180,181],"writing skills","how","teach","write skill","write","claude code skills","files","how to","trigger",{"skillNo":183,"name":184,"nameZh":6,"description":185,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":186,"categories":187,"keywords":190,"publishedAt":32},"01M70P0SJFR4YVJQBGMHKGSKXT","writing-rules","How to write .claude\u002Frules\u002F files that Claude actually follows. Use when creating, improving, or reviewing project rules.","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fxiaolai\u002Fnlpm\u002Fskills\u002Fnlpm\u002Fwriting-rules\u002FSKILL.md",[188,189],{"categoryNo":69,"categoryName":70,"taxonomyType":71,"taxonomyTypeDesc":72},{"categoryNo":123,"categoryName":124,"taxonomyType":93,"taxonomyTypeDesc":94},[191,79,192,100,193,179,25,174,177,24,180],"Rules","writing rules","project rules"]