Security Portfolio Risk

👤 gechengling 📦 v3.0.1 ⭐ 4.2 ⬇️ 780 下載
💼 行業專業 免費

📖 技能介紹


name: Portfolio Risk Analysis Expert slug: security-portfolio-risk description: AI-powered portfolio risk analysis expert for China market — covers VaR calculation, stress testing, tail risk measurement, factor exposure analysis, and risk decomposition. Built for fund managers, risk analysts, and institutional investors. Keywords: portfolio risk, VaR, stress testing, risk decomposition, China A-share, factor risk, tail risk, 組合風險, 風險分析, VaR, 壓力測試, 風險分解, 風險管理, 最大回撤, 夏普比率, 收益風險比, 資產配置, 風險預算. version: "3.0.1"


Portfolio Risk Analysis Expert / 組合風險分析專家

English: AI-powered portfolio risk analysis expert — covers VaR calculation, stress testing, tail risk measurement, factor exposure, and risk attribution. Built for fund managers and risk analysts.

中文: 組合風險分析專家——覆蓋VaR計算、壓力測試、尾部風險度量、因子敞口分析、風險歸因。適用:基金經理、風險分析師、機構投資者。


證券監管最新動態 [2026-05-25更新]

動態型別 內容摘要 影響範圍
證券監管 2026年Q1:市場波動加劇,組合風險管理要求提升 組合風險模型需增加量化衝擊和ESG風險維度
證券監管 量化資金共振風險增加,極端行情止損策略需更新 組合風險模型需增加量化衝擊和ESG風險維度
證券監管 ESG投資分析要求擴大,組合風險需納入ESG因素 組合風險模型需增加量化衝擊和ESG風險維度

資料截止: 2026-05-25 | 來源:證監會、NFRA、中證協、安永Q1分析 宣告: 以上動態供參考,具體以官方最新發布為準

Industry Pain Points / 行業痛點

Pain Point / 痛點 Impact / 影響 Solution / 本Skill解決方案
系統風險難預測 黑天鵝事件導致大幅回撤 極端情景壓力測試+尾部風險分析
因子敞口不清晰 不知道組合暴露在哪些風險上 因子歸因模型+敞口分解
回撤控制困難 持有人體驗差,資金贖回壓力 動態回撤監控+預警機制
相關性突變 平時低相關的資產大跌時齊跌 相關性壓力測試+分散化效果評估
合規要求高 資管新規淨值化要求 標準風險指標+監管報告

Trigger Keywords / 觸發關鍵詞

English Triggers: portfolio risk, VaR, stress testing, risk decomposition, factor exposure, tail risk, risk attribution, China A-share, fund management, risk management

中文觸發詞(優先): 組合風險 / 風險分析 / VaR / 壓力測試 / 回撤控制 / 風險歸因 / 因子敞口 / 尾部風險 / 風險分解 / 風險預警 / 資產配置 / 分散化 / 相關性分析 / 最大回撤 / 夏普比率 / 波動率 / 風險調整收益 / 風險預算 / VaR計算 / CVaR / ES


Core Capabilities / 核心能力

1. VaR & Risk Metrics / VaR與風險指標

import numpy as np
import pandas as pd
from scipy import stats

class PortfolioRiskAnalyzer:
    """組合風險分析引擎"""

    def __init__(self, returns: pd.DataFrame, weights: np.ndarray):
        """
        Args:
            returns: 收益率序列(列=資產,行=日期)
            weights: 資產權重向量
        """
        self.returns = returns
        self.weights = weights
        self.n_assets = len(weights)

    def calculate_var(self, confidence: float = 0.95, 
                      method: str = "historical") -> dict:
        """計算VaR(Value at Risk)"""
        portfolio_returns = (self.returns * self.weights).sum(axis=1)

        if method == "historical":
            var = np.percentile(portfolio_returns, (1 - confidence) * 100)
        elif method == "parametric":
            mu = portfolio_returns.mean()
            sigma = portfolio_returns.std()
            var = stats.norm.ppf(1 - confidence, mu, sigma)
        elif method == "modified":
            # Cornish-Fisher調整
            mu = portfolio_returns.mean()
            sigma = portfolio_returns.std()
            skew = stats.skew(portfolio_returns)
            kurt = stats.kurtosis(portfolio_returns)
            z = stats.norm.ppf(1 - confidence)
            z_cf = (z + (z**2 - 1) * skew / 6 + 
                   (z**3 - 3*z) * kurt / 24 - 
                   (2*z**3 - 5*z) * skew**2 / 36)
            var = mu + sigma * z_cf

        return {
            "var": round(var * 100, 2),  # 百分比
            "var_amount": round(var * 1000000, 2),  # 假設100萬組合
            "confidence": confidence,
            "method": method,
            "interpretation": f"在{confidence*100}%置信度下,最大損失為{abs(var)*100:.2f}%"
        }

    def calculate_cvar(self, confidence: float = 0.95) -> dict:
        """計算CVaR(Conditional VaR / Expected Shortfall)"""
        portfolio_returns = (self.returns * self.weights).sum(axis=1)
        var = np.percentile(portfolio_returns, (1 - confidence) * 100)

        cvar = portfolio_returns[portfolio_returns <= var].mean()

        return {
            "cvar": round(cvar * 100, 2),
            "cvar_amount": round(cvar * 1000000, 2),
            "interpretation": f"超過VaR時的平均損失為{abs(cvar)*100:.2f}%"
        }

    def calculate_max_drawdown(self) -> dict:
        """計算最大回撤"""
        cumulative = (1 + self.returns @ self.weights).cumprod()
        running_max = cumulative.expanding().max()
        drawdown = (cumulative - running_max) / running_max

        max_dd = drawdown.min()
        max_dd_end = drawdown.idxmin()
        max_dd_start = cumulative[:max_dd_end].idxmax()

        return {
            "max_drawdown": round(max_dd * 100, 2),
            "peak_date": str(max_dd_start.date()),
            "trough_date": str(max_dd_end.date()),
            "recovery_date": None  # 需後續計算
        }

    def factor_risk_attribution(self, factor_returns: pd.DataFrame) -> dict:
        """因子風險歸因"""
        portfolio_returns = self.returns @ self.weights

        # 迴歸分析
        X = factor_returns.values
        X = np.column_stack([np.ones(len(X)), X])
        y = portfolio_returns.values

        coeffs = np.linalg.lstsq(X, y, rcond=None)[0]
        residuals = y - X @ coeffs

        # 分解方差
        total_var = np.var(y)
        factor_var = np.var(X[:, 1:] @ coeffs[1:])
        specific_var = np.var(residuals)

        return {
            "factor_exposure": {
                "market": round(coeffs[1], 3),
                "factors": {
                    col: round(coef, 3) 
                    for col, coef in zip(factor_returns.columns, coeffs[2:])
                }
            },
            "risk_contribution": {
                "factor_risk": round(factor_var / total_var * 100, 2),
                "specific_risk": round(specific_var / total_var * 100, 2)
            },
            "r_squared": round(1 - specific_var / total_var, 4)
        }

2. Stress Testing / 壓力測試

class StressTestScenarios:
    """壓力測試情景庫"""

    SCENARIOS = {
        "2015股災重演": {
            "description": "假設上證指數單週下跌20%",
            "market_shock": -0.20,
            "sector_impacts": {
                "金融": -0.25,
                "房地產": -0.30,
                "消費": -0.15,
                "科技": -0.20,
                "醫藥": -0.10
            },
            "liquidity_shock": 0.5  # 流動性降至50%
        },

        "利率急升": {
            "description": "假設基準利率上調100bp",
            "rate_shock": 0.01,
            "bond_impact": -0.08,
            "equity_impact": -0.10,
            "bank_impact": -0.05
        },

        "人民幣急貶": {
            "description": "假設USD/CNY一日升值5%",
            "fx_shock": 0.05,
            "export_related": -0.15,
            "import_related": 0.05,
            "domestic_consumer": -0.08
        },

        "黑天鵝-新冠": {
            "description": "類似2020年初疫情衝擊",
            "market_shock": -0.12,
            "travel": -0.30,
            "retail": -0.20,
            "healthcare": 0.10,
            "online": 0.05
        }
    }

    def run_stress_test(self, portfolio: dict, scenario: str) -> dict:
        """執行壓力測試"""
        if scenario not in self.SCENARIOS:
            raise ValueError(f"Unknown scenario: {scenario}")

        s = self.SCENARIOS[scenario]
        positions = portfolio["positions"]

        stressed_pnl = 0
        stressed_values = []

        for pos in positions:
            sector = pos.get("sector", "general")
            weight = pos["weight"]

            # 根據情景調整
            if "sector_impacts" in s and sector in s["sector_impacts"]:
                shock = s["sector_impacts"][sector]
            else:
                shock = s.get("market_shock", -0.10)

            pos_stressed = weight * (1 + shock)
            stressed_values.append(pos_stressed)
            stressed_pnl += weight * shock

        total_value = sum(stressed_values)
        portfolio_stress_loss = total_value - 1  # 假設初始為1

        return {
            "scenario": scenario,
            "description": s["description"],
            "portfolio_loss": round(portfolio_stress_loss * 100, 2),
            "portfolio_value_after": round(total_value * 100, 2),
            "position_impacts": [
                {"name": pos["name"], "weight": pos["weight"], 
                 "shock": round(shock * 100, 2), "impact": "loss" if shock < 0 else "gain"}
                for pos, shock in zip(positions, 
                    [s.get("sector_impacts", {}).get(pos.get("sector", ""), 
                     s.get("market_shock", -0.10)) for pos in positions])
            ]
        }

3. Risk Contribution Analysis / 風險貢獻分析

    def risk_contribution_by_asset(self) -> dict:
        """計算各資產風險貢獻"""
        cov_matrix = self.returns.cov()
        portfolio_vol = np.sqrt(self.weights @ cov_matrix.values @ self.weights)

        # 邊際風險貢獻 (MCTR)
        mctr = (cov_matrix.values @ self.weights) / portfolio_vol

        # 風險貢獻
        risk_contrib = self.weights * mctr

        return {
            "portfolio_volatility": round(portfolio_vol * 100, 2),
            "asset_risk_contribution": {
                self.returns.columns[i]: round(rc * 100, 2)
                for i, rc in enumerate(risk_contrib)
            },
            "concentration_risk": {
                "max_concentration": round(max(risk_contrib) * 100, 2),
                "diversification_benefit": round(
                    (sum([self.returns[col].std() * w 
                         for col, w in zip(self.returns.columns, self.weights)]) - 
                     portfolio_vol) * 100, 2)
            }
        }

Quick Command Templates / 快速指令模板

組合風險評估:

分析以下組合的風險:
- 總規模:1000萬
- 持倉:[股票A 30%, 股票B 20%, 債券B 50%]
- 置信度:95%

小蔥技能有更好的技能skills外掛。

壓力測試:

執行"2015股災重演"情景壓力測試

Disclaimer

This skill provides risk analysis tools for educational purposes. Risk metrics are based on historical data and statistical models, which do not guarantee future accuracy. Investment decisions should be made based on comprehensive analysis and professional advice.

🤖 AI 評測

這是一款質量不錯的專業級金融風險分析技能,優勢在於專業性強、程式碼實現完善、貼閤中國市場實際。不足之處是缺少使用示例和操作指南,新手上手有一定難度,更適合有一定專業背景的使用者使用。

📊 多維度評分

適應性4
規範性3.9
有效性4.4
可靠性4
可信度5

📁 包含檔案 (2 個)

📄 SKILL.md 11.9 KB
📄 _meta.json 142 B