{"id":5690,"date":"2025-05-30T22:44:18","date_gmt":"2025-05-30T14:44:18","guid":{"rendered":"http:\/\/cnliutz.pgrm.cc\/?p=5690"},"modified":"2025-05-30T22:44:19","modified_gmt":"2025-05-30T14:44:19","slug":"%e8%82%a1%e7%a5%a8%e7%bb%84%e5%90%88var%e8%ae%a1%e7%ae%97%e5%99%a8-%e8%92%99%e7%89%b9%e5%8d%a1%e6%b4%9b%e6%a8%a1%e6%8b%9f%e6%b3%95","status":"publish","type":"post","link":"http:\/\/cnliutz.wicp.vip\/?p=5690","title":{"rendered":"\u80a1\u7968\u7ec4\u5408VaR\u8ba1\u7b97\u5668-\u8499\u7279\u5361\u6d1b\u6a21\u62df\u6cd5"},"content":{"rendered":"\n<p><strong>akshare\u83b7\u53d6\u6570\u636e<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#\u80a1\u7968\u7ec4\u5408VaR\u8ba1\u7b97\u5668\uff0c\u8499\u7279\u5361\u6d1b\u6a21\u62df\u6cd5\uff0cakshare\u83b7\u53d6\u6570\u636e\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport akshare as ak\nfrom datetime import datetime, timedelta\nimport seaborn as sns\n\n# \u8bbe\u7f6e\u4e2d\u6587\u663e\u793a\nplt.rcParams&#91;\"font.family\"] = &#91;'SimHei', 'Microsoft YaHei', 'SimSun', 'KaiTi']\nplt.rcParams&#91;'axes.unicode_minus'] = False  # \u89e3\u51b3\u8d1f\u53f7\u663e\u793a\u95ee\u9898\n\nclass StockVaRCalculator:\n    \"\"\"A\u80a1\u80a1\u7968\u7ec4\u5408VaR\u8ba1\u7b97\u5668\uff0c\u4f7f\u7528\u8499\u7279\u5361\u6d1b\u6a21\u62df\u6cd5\u548cakshare\u83b7\u53d6\u6570\u636e\"\"\"\n    \n    def __init__(self, stock_tickers, weights=None, investment_value=1000000, \n                 simulation_days=10, num_simulations=10000, confidence_level=0.99):\n        \"\"\"\n        \u521d\u59cb\u5316\u80a1\u7968\u7ec4\u5408VaR\u8ba1\u7b97\u5668\n        \n        \u53c2\u6570:\n            stock_tickers: \u80a1\u7968\u4ee3\u7801\u5217\u8868\uff0c\u4f7f\u7528akshare\u683c\u5f0f\uff08\u4f8b\u5982\uff1a'sh600000' \u8868\u793a\u6d66\u53d1\u94f6\u884c\uff09\n            weights: \u5404\u80a1\u7968\u6743\u91cd\uff0c\u9ed8\u8ba4\u4e3a\u7b49\u6743\u91cd\n            investment_value: \u6295\u8d44\u7ec4\u5408\u603b\u4ef7\u503c\uff08\u5143\uff09\n            simulation_days: \u6a21\u62df\u7684\u5929\u6570\n            num_simulations: \u8499\u7279\u5361\u6d1b\u6a21\u62df\u6b21\u6570\n            confidence_level: VaR\u8ba1\u7b97\u7684\u7f6e\u4fe1\u6c34\u5e73\n        \"\"\"\n        self.stock_tickers = stock_tickers\n        self.num_stocks = len(stock_tickers)\n        \n        # \u5904\u7406\u6743\u91cd\n        if weights is None:\n            self.weights = np.ones(self.num_stocks) \/ self.num_stocks\n        else:\n            self.weights = np.array(weights)\n            # \u5f52\u4e00\u5316\u6743\u91cd\n            self.weights = self.weights \/ np.sum(self.weights)\n            \n        self.investment_value = investment_value\n        self.simulation_days = simulation_days\n        self.num_simulations = num_simulations\n        self.confidence_level = confidence_level\n        \n        self.stock_data = None\n        self.returns = None\n        self.mean_returns = None\n        self.cov_matrix = None\n        self.simulation_results = None\n        \n    def fetch_stock_data(self, start_date=None, end_date=None):\n        \"\"\"\u4f7f\u7528akshare\u83b7\u53d6\u80a1\u7968\u5386\u53f2\u6570\u636e\"\"\"\n        if end_date is None:\n            end_date = datetime.now().strftime('%Y%m%d')\n        if start_date is None:\n            end_date_obj = datetime.strptime(end_date, '%Y%m%d')\n            start_date_obj = end_date_obj - timedelta(days=365)\n            start_date = start_date_obj.strftime('%Y%m%d')\n            \n        print(f\"\u6b63\u5728\u83b7\u53d6{self.stock_tickers}\u7684\u5386\u53f2\u6570\u636e\uff0c\u65f6\u95f4\u8303\u56f4\uff1a{start_date}\u81f3{end_date}\")\n        \n        all_data = pd.DataFrame()\n        \n        for ticker in self.stock_tickers:\n            try:\n                # \u4f7f\u7528akshare\u83b7\u53d6\u80a1\u7968\u65e5\u7ebf\u6570\u636e\n                stock_data = ak.stock_zh_a_hist_tx(symbol=ticker,  \n                                              start_date=start_date, end_date=end_date, \n                                              adjust=\"\")  # \u4f7f\u7528\u524d\u590d\u6743\u4ef7\u683c\n                '''\n                \u5728\u4f7f\u7528 akshare \u83b7\u53d6 A \u80a1\u5386\u53f2\u884c\u60c5\u6570\u636e\u65f6\uff0c\u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6eadjust\u53c2\u6570\u6765\u83b7\u53d6\u9664\u6743\u540e\u6570\u636e\u3002\u8fd9\u4e2a\u53c2\u6570\u652f\u6301\u4e09\u79cd\u53d6\u503c\uff1a\n                \"qfq\"\uff1a\u524d\u590d\u6743\uff08\u6700\u5e38\u7528\uff0c\u4fdd\u6301\u5f53\u524d\u4ef7\u683c\u4e0d\u53d8\uff0c\u8c03\u6574\u5386\u53f2\u4ef7\u683c\uff09\n                \"hfq\"\uff1a\u540e\u590d\u6743\uff08\u4fdd\u6301\u5386\u53f2\u4ef7\u683c\u4e0d\u53d8\uff0c\u8c03\u6574\u5f53\u524d\u4ef7\u683c\uff09\n                \"\"\uff1a\u4e0d\u590d\u6743\uff08\u539f\u59cb\u4ef7\u683c\uff09\n                '''\n                \n                # \u91cd\u547d\u540d\u5217\u5e76\u6dfb\u52a0\u80a1\u7968\u4ee3\u7801\n                stock_data = stock_data.rename(columns={'\u65e5\u671f': 'date', '\u6536\u76d8': 'close'})\n                stock_data&#91;'ticker'] = ticker\n                stock_data = stock_data&#91;&#91;'date', 'ticker', 'close']]\n                \n                # \u8f6c\u6362\u65e5\u671f\u683c\u5f0f\n                stock_data&#91;'date'] = pd.to_datetime(stock_data&#91;'date'])\n                \n                # \u6dfb\u52a0\u5230\u603b\u6570\u636e\u4e2d\n                if all_data.empty:\n                    all_data = stock_data\n                else:\n                    all_data = pd.concat(&#91;all_data, stock_data], ignore_index=True)\n                    \n                print(f\"\u6210\u529f\u83b7\u53d6{ticker}\u7684{len(stock_data)}\u5929\u6570\u636e\")\n                \n            except Exception as e:\n                print(f\"\u83b7\u53d6{ticker}\u6570\u636e\u5931\u8d25: {e}\")\n        \n        # \u91cd\u5851\u6570\u636e\u4e3a\u5bbd\u683c\u5f0f\n        self.stock_data = all_data.pivot(index='date', columns='ticker', values='close')\n        \n        # \u68c0\u67e5\u6570\u636e\u5b8c\u6574\u6027\n        if self.stock_data.isnull().any().any():\n            print(\"\u8b66\u544a\uff1a\u6570\u636e\u5305\u542b\u7f3a\u5931\u503c\uff0c\u6b63\u5728\u8fdb\u884c\u524d\u5411\u586b\u5145\")\n            self.stock_data = self.stock_data.fillna(method='ffill')\n        # \u6253\u5370\u6700\u540e\u4e00\u5929\u7684\u80a1\u7968\u4ef7\u683c\uff08\u786e\u8ba4\u662f\u5426\u5408\u7406\uff09\n        print(\"\u6700\u540e\u4e00\u5929\u80a1\u7968\u4ef7\u683c:\")\n        print(var_calculator.stock_data.iloc&#91;-1])    \n        print(f\"\u6570\u636e\u5904\u7406\u5b8c\u6210\uff0c\u6700\u7ec8\u6570\u636e\u96c6\u5305\u542b{len(self.stock_data)}\u5929\u6570\u636e\")\n\n\n        # \u9a8c\u8bc1\u4ef7\u683c\u5408\u7406\u6027\uff08\u793a\u4f8b\uff1a\u5047\u8bbeA\u80a1\u4ef7\u683c\u901a\u5e38&lt;500\u5143\uff09\n        if (self.stock_data > 500).any().any():\n            print(\"\u8b66\u544a\uff1a\u68c0\u6d4b\u5230\u5f02\u5e38\u9ad8\u4ef7\uff0c\u53ef\u80fd\u6570\u636e\u5355\u4f4d\u9519\u8bef\uff0c\u5c1d\u8bd5\u9664\u4ee510000\")\n            self.stock_data = self.stock_data \/ 10000  # \u5047\u8bbe\u5355\u4f4d\u4e3a\"\u4e07\u5143\"\n            print(f\"**\u4fee\u6b63\u540e\u6700\u540e\u4e00\u5929\u4ef7\u683c: {self.stock_data.iloc&#91;-1]}\")\n\n        return self.stock_data\n    \n    def calculate_returns(self):\n        \"\"\"\u8ba1\u7b97\u80a1\u7968\u6536\u76ca\u7387\"\"\"\n        if self.stock_data is None:\n            raise ValueError(\"\u8bf7\u5148\u83b7\u53d6\u80a1\u7968\u6570\u636e\")\n            \n        # \u8ba1\u7b97\u5bf9\u6570\u6536\u76ca\u7387\n        self.returns = np.log(self.stock_data \/ self.stock_data.shift(1)).dropna()\n        \n        # \u65b0\u589e\uff1a\u6253\u5370\u6536\u76ca\u7387\u6781\u503c\uff08\u6b63\u5e38\u5e94\u5728\u00b110%\u4ee5\u5185\uff09\n        print(\"\u6536\u76ca\u7387\u6781\u503c\u68c0\u6d4b:\")\n        print(f\"\u6700\u5c0f\u65e5\u6536\u76ca\u7387: {self.returns.min().min():.2%}\")\n        print(f\"\u6700\u5927\u65e5\u6536\u76ca\u7387: {self.returns.max().max():.2%}\")\n        # \u8ba1\u7b97\u5747\u503c\u548c\u534f\u65b9\u5dee\u77e9\u9635\n        self.mean_returns = self.returns.mean()\n        self.cov_matrix = self.returns.cov()\n        \n        return self.returns\n        \n    def run_monte_carlo_simulation(self):\n        \"\"\"\u8fd0\u884c\u8499\u7279\u5361\u6d1b\u6a21\u62df\"\"\"\n        if self.returns is None:\n            raise ValueError(\"\u8bf7\u5148\u8ba1\u7b97\u6536\u76ca\u7387\")\n            \n        print(f\"\u6b63\u5728\u8fd0\u884c\u8499\u7279\u5361\u6d1b\u6a21\u62df\uff0c\u6a21\u62df\u6b21\u6570\uff1a{self.num_simulations}\uff0c\u9884\u6d4b\u5929\u6570\uff1a{self.simulation_days}\")\n        \n        # \u8ba1\u7b97\u65e5\u5747\u503c\u548c\u534f\u65b9\u5dee\u77e9\u9635\n        daily_mean = self.mean_returns\n        daily_cov = self.cov_matrix\n        \n        # \u8c03\u6574portfolio_sims\u7684\u7ef4\u5ea6\u987a\u5e8f\u4e3a &#91;\u80a1\u7968\u6570, \u6a21\u62df\u6b21\u6570, \u5929\u6570]\n        portfolio_sims = np.full(shape=(self.num_stocks, self.num_simulations, self.simulation_days), \n                                fill_value=0.0)\n        \n        initial_prices = self.stock_data.iloc&#91;-1].values  # \u4f7f\u7528\u6700\u540e\u4e00\u5929\u7684\u4ef7\u683c\u4f5c\u4e3a\u521d\u59cb\u4ef7\u683c\n        \n        for s in range(self.num_simulations):\n            # \u751f\u6210\u76f8\u5173\u7684\u968f\u673a\u6536\u76ca\u7387\n            daily_returns = np.random.multivariate_normal(\n                daily_mean, \n                daily_cov, \n                self.simulation_days\n            ).T  # &#91;\u80a1\u7968\u6570, \u5929\u6570]\n            \n            # \u8ba1\u7b97\u7d2f\u79ef\u6536\u76ca\u7387\uff08\u6ce8\u610f\uff1a\u8fd9\u91cc\u4f7f\u7528\u6307\u6570\u51fd\u6570\u5c06\u5bf9\u6570\u6536\u76ca\u7387\u8f6c\u6362\u56de\u4ef7\u683c\u6bd4\u7387\uff09\n            cumulative_returns = np.exp(np.cumsum(daily_returns, axis=1))\n            \n            # \u8ba1\u7b97\u6a21\u62df\u4ef7\u683c\u8def\u5f84\n            portfolio_sims&#91;:, s, :] = initial_prices.reshape(-1, 1) * cumulative_returns\n        \n        self.simulation_results = portfolio_sims\n        return portfolio_sims\n    \n    def calculate_portfolio_var(self):\n        \"\"\"\u8ba1\u7b97\u6295\u8d44\u7ec4\u5408\u7684VaR\"\"\"\n        if self.simulation_results is None:\n            raise ValueError(\"\u8bf7\u5148\u8fd0\u884c\u8499\u7279\u5361\u6d1b\u6a21\u62df\")\n            \n        # \u8ba1\u7b97\u6a21\u62df\u7ed3\u675f\u65f6\u7684\u6295\u8d44\u7ec4\u5408\u4ef7\u503c\n        final_values = np.zeros(self.num_simulations)\n        \n        for s in range(self.num_simulations):\n            # \u83b7\u53d6\u6240\u6709\u80a1\u7968\u5728\u6700\u540e\u4e00\u5929\u7684\u4ef7\u683c &#91;num_stocks]\n            stock_values = self.simulation_results&#91;:, s, -1]\n            \n            # \u8ba1\u7b97\u6bcf\u53ea\u80a1\u7968\u7684\u4ef7\u503c = \u6743\u91cd * \u521d\u59cb\u6295\u8d44 * \u6a21\u62df\u4ef7\u683c\/\u521d\u59cb\u4ef7\u683c\n            portfolio_value = np.sum(self.weights * self.investment_value * stock_values \/ \n                                    self.stock_data.iloc&#91;-1].values)\n            final_values&#91;s] = portfolio_value\n            \n        # \u8ba1\u7b97\u6295\u8d44\u7ec4\u5408\u4ef7\u503c\u53d8\u5316\n        portfolio_changes = final_values - self.investment_value\n        \n        # \u8ba1\u7b97VaR\n        var_percentile = 100 * (1 - self.confidence_level)\n        var = -np.percentile(portfolio_changes, var_percentile)\n        \n        # \u8ba1\u7b97CVaR (\u6761\u4ef6VaR)\n        cvar_mask = portfolio_changes &lt;= -var\n        cvar = -np.mean(portfolio_changes&#91;cvar_mask]) if np.sum(cvar_mask) > 0 else 0\n        \n        # \u65b0\u589e\uff1a\u6253\u5370\u6a21\u62df\u7ed3\u679c\u7edf\u8ba1\n        print(\"\\n\u6a21\u62df\u7ed3\u679c\u7edf\u8ba1:\")\n        print(f\"\u521d\u59cb\u6295\u8d44\u7ec4\u5408\u4ef7\u503c: {self.investment_value:,}\u5143\")\n        print(f\"\u6a21\u62df\u540e\u7ec4\u5408\u4ef7\u503c\u8303\u56f4: \u6700\u5c0f\u503c={np.min(final_values):,.2f}\u5143, \u6700\u5927\u503c={np.max(final_values):,.2f}\u5143\")\n        print(f\"\u7ec4\u5408\u4ef7\u503c\u53d8\u5316\u8303\u56f4: \u6700\u5c0f\u503c={np.min(portfolio_changes):,.2f}\u5143, \u6700\u5927\u503c={np.max(portfolio_changes):,.2f}\u5143\")\n        \n        return {\n            'VaR': var,\n            'CVaR': cvar,\n            'VaR_percentage': var \/ self.investment_value * 100,\n            'CVaR_percentage': cvar \/ self.investment_value * 100,\n            'portfolio_changes': portfolio_changes,\n            'final_values': final_values\n        }\n\n    def plot_simulation_results(self, var_results):\n        \"\"\"\u53ef\u89c6\u5316\u6a21\u62df\u7ed3\u679c\"\"\"\n        plt.figure(figsize=(16, 10))\n        \n        # 1. \u7ed8\u5236\u6a21\u62df\u4ef7\u683c\u8def\u5f84 - \u4fee\u6b63\u7ef4\u5ea6\u987a\u5e8f\n        plt.subplot(2, 2, 1)\n        for i, ticker in enumerate(self.stock_tickers):\n            plt.plot(self.simulation_results&#91;i, :, :].T, alpha=0.1)  # \u8f6c\u7f6e\u4ee5\u6b63\u786e\u663e\u793a\u65f6\u95f4\u8f74\n            plt.title(f\"{ticker} \u4ef7\u683c\u6a21\u62df\u8def\u5f84\")\n            plt.xlabel(\"\u5929\u6570\")\n            plt.ylabel(\"\u4ef7\u683c (\u5143)\")\n        \n        # 2. \u7ed8\u5236\u6295\u8d44\u7ec4\u5408\u4ef7\u503c\u5206\u5e03\n        plt.subplot(2, 2, 2)\n        sns.histplot(var_results&#91;'final_values'], bins=50, kde=True)\n        plt.axvline(x=self.investment_value, color='r', linestyle='--', label='\u521d\u59cb\u4ef7\u503c')\n        plt.axvline(x=self.investment_value - var_results&#91;'VaR'], color='g', linestyle='--', label=f'VaR@{self.confidence_level}')\n        plt.title('\u6295\u8d44\u7ec4\u5408\u4ef7\u503c\u5206\u5e03')\n        plt.xlabel('\u7ec4\u5408\u4ef7\u503c (\u5143)')\n        plt.ylabel('\u9891\u7387')\n        plt.legend()\n        \n        # 3. \u7ed8\u5236\u6295\u8d44\u7ec4\u5408\u6536\u76ca\u5206\u5e03\n        plt.subplot(2, 2, 3)\n        sns.histplot(var_results&#91;'portfolio_changes'], bins=50, kde=True)\n        var_percentile = 100 * (1 - self.confidence_level)\n        var_value = -var_results&#91;'VaR']\n        plt.axvline(x=0, color='r', linestyle='--', label='\u65e0\u6536\u76ca')\n        plt.axvline(x=var_value, color='g', linestyle='--', label=f'VaR@{self.confidence_level}')\n        plt.title('\u6295\u8d44\u7ec4\u5408\u6536\u76ca\u5206\u5e03')\n        plt.xlabel('\u6536\u76ca (\u5143)')\n        plt.ylabel('\u9891\u7387')\n        plt.legend()\n        \n        # 4. \u7ed8\u5236\u98ce\u9669\u56e0\u5b50\u70ed\u56fe\n        plt.subplot(2, 2, 4)\n        sns.heatmap(self.cov_matrix, annot=True, cmap='coolwarm', fmt='g')\n        plt.title('\u80a1\u7968\u6536\u76ca\u7387\u534f\u65b9\u5dee\u77e9\u9635')\n        \n        plt.tight_layout()\n        plt.show()    \n        \n    def calculate_risk_contribution(self, var_results):\n        \"\"\"\u8ba1\u7b97\u5404\u80a1\u7968\u5bf9\u6295\u8d44\u7ec4\u5408\u98ce\u9669\u7684\u8d21\u732e\"\"\"\n        if self.simulation_results is None:\n            raise ValueError(\"\u8bf7\u5148\u8fd0\u884c\u8499\u7279\u5361\u6d1b\u6a21\u62df\")\n            \n        # \u8ba1\u7b97\u6bcf\u53ea\u80a1\u7968\u7684VaR\u8d21\u732e\n        risk_contributions = {}\n        \n        for i, ticker in enumerate(self.stock_tickers):\n            # \u8ba1\u7b97\u8be5\u80a1\u7968\u7684\u6743\u91cd\u548c\u6ce2\u52a8\u7387\n            weight = self.weights&#91;i]\n            volatility = np.sqrt(self.cov_matrix.iloc&#91;i, i])\n            \n            # \u8ba1\u7b97\u8fb9\u9645VaR (\u5047\u8bbe\u6b63\u6001\u5206\u5e03)\n            portfolio_volatility = np.sqrt(np.dot(self.weights, np.dot(self.cov_matrix, self.weights)))\n            marginal_var = (weight * volatility * self.cov_matrix.iloc&#91;i, :].dot(self.weights)) \/ (portfolio_volatility ** 2)\n            \n            # \u8ba1\u7b97\u6210\u5206VaR\n            component_var = marginal_var * var_results&#91;'VaR']\n            \n            # \u8ba1\u7b97\u767e\u5206\u6bd4\u8d21\u732e\n            pct_contribution = (component_var \/ var_results&#91;'VaR']) * 100\n            \n            risk_contributions&#91;ticker] = {\n                'weight': weight,\n                'volatility': volatility,\n                'marginal_var': marginal_var,\n                'component_var': component_var,\n                'pct_contribution': pct_contribution\n            }\n            \n        return risk_contributions\n\n# \u4f7f\u7528\u793a\u4f8b\nif __name__ == \"__main__\":\n    # \u8bbe\u7f6e\u8981\u5206\u6790\u7684\u80a1\u7968\u4ee3\u7801\uff08\u4f7f\u7528akshare\u683c\u5f0f\uff09\n    #stock_tickers = &#91;'sh600000', 'sz000001', 'sh601318', 'sz000858', 'sh600519']  # \u6d66\u53d1\u94f6\u884c\u3001\u5e73\u5b89\u94f6\u884c\u3001\u4e2d\u56fd\u5e73\u5b89\u3001\u4e94\u7cae\u6db2\u3001\u8d35\u5dde\u8305\u53f0\n    stock_tickers = &#91;'sh600938', f'sz000937', 'sh601288', 'sz002555', f'sz000538']  # \u6d66\u53d1\u94f6\u884c\u3001\u5e73\u5b89\u94f6\u884c\u3001\u4e2d\u56fd\u5e73\u5b89\u3001\u4e94\u7cae\u6db2\u3001\u8d35\u5dde\u8305\u53f0\n\n    # \u8bbe\u7f6e\u6743\u91cd\uff08\u5982\u679c\u4e0d\u8bbe\u7f6e\uff0c\u9ed8\u8ba4\u4e3a\u7b49\u6743\u91cd\uff09\n    #weights = &#91;0.2, 0.2, 0.2, 0.2, 0.2]\n    weights = &#91;0.4,0.2,0.2,0.1,0.1]\n    '''\n    \u80a1\u7968\t    \u4ee3\u7801\t    \u6301\u4ed3\t    \u6301\u80a1\u6bd4\u4f8b    \n    \u4e2d\u56fd\u6d77\u6cb9\t600938\t \u00a589,775.00 \t0.399\n    \u519c\u4e1a\u94f6\u884c\t601288\t \u00a548,276.00 \t0.215\n    \u4e91\u5357\u767d\u836f\t000538\t \u00a534,020.00 \t0.151\n    \u5180\u4e2d\u80fd\u6e90\t000937\t \u00a552,806.00 \t0.235\n    \u4e09\u4e03\u4e92\u5a31\t002555\t \u00a514,650.00 \t0.065\n\n    '''\n\n    # \u521d\u59cb\u5316\u8ba1\u7b97\u5668\n    var_calculator = StockVaRCalculator(\n        stock_tickers=stock_tickers,\n        weights=weights,\n        investment_value=1000000,  # 100\u4e07\u5143\u6295\u8d44\u7ec4\u5408\n        simulation_days=10,        # \u9884\u6d4b10\u5929\n        num_simulations=10000,     # 10000\u6b21\u6a21\u62df\n        confidence_level=0.99      # 99%\u7f6e\u4fe1\u6c34\u5e73\n    )\n    \n    # \u83b7\u53d6\u6570\u636e\n    var_calculator.fetch_stock_data()\n    \n    # \u8ba1\u7b97\u6536\u76ca\u7387\n    var_calculator.calculate_returns()\n    \n    # \u8fd0\u884c\u8499\u7279\u5361\u6d1b\u6a21\u62df\n    var_calculator.run_monte_carlo_simulation()\n    \n    # \u8ba1\u7b97VaR\n    var_results = var_calculator.calculate_portfolio_var()\n    \n    # \u8ba1\u7b97\u98ce\u9669\u8d21\u732e\n    risk_contributions = var_calculator.calculate_risk_contribution(var_results)\n\n    # \u6253\u5370\u6536\u76ca\u7387\u7edf\u8ba1\u7279\u5f81\uff08\u6b63\u5e38A\u80a1\u65e5\u6536\u76ca\u7387\u5747\u503c\u7ea60.03%\uff0c\u6807\u51c6\u5dee\u7ea62%\uff09\n    print(\"\u6536\u76ca\u7387\u7edf\u8ba1:\")\n    print(var_calculator.returns.describe()) \n    # \u6253\u5370\u7ed3\u679c\n    print(\"\\n===== \u98ce\u9669\u4ef7\u503c\u8ba1\u7b97\u7ed3\u679c =====\")\n    print(f\"\u6295\u8d44\u7ec4\u5408\u603b\u4ef7\u503c: {var_calculator.investment_value:,}\u5143\")\n    print(f\"{var_calculator.simulation_days}\u5929\u6301\u6709\u671f\uff0c{var_calculator.confidence_level*100}%\u7f6e\u4fe1\u6c34\u5e73\u4e0b:\")\n    print(f\"VaR: {var_results&#91;'VaR']:,.2f}\u5143 ({var_results&#91;'VaR_percentage']:.2f}%)\")\n    print(f\"CVaR: {var_results&#91;'CVaR']:,.2f}\u5143 ({var_results&#91;'CVaR_percentage']:.2f}%)\")\n    \n    print(\"\\n===== \u5404\u80a1\u7968\u98ce\u9669\u8d21\u732e =====\")\n    for ticker, contrib in risk_contributions.items():\n        print(f\"{ticker}: \u6743\u91cd={contrib&#91;'weight']:.2%}, \u98ce\u9669\u8d21\u732e={contrib&#91;'pct_contribution']:.2f}%\")\n    \n    # \u53ef\u89c6\u5316\u7ed3\u679c\n    var_calculator.plot_simulation_results(var_results)    \n\n    '''\n\u6210\u529f\u83b7\u53d6sh600938\u7684243\u5929\u6570\u636e\n\u6210\u529f\u83b7\u53d6sz000937\u7684243\u5929\u6570\u636e\n\u6210\u529f\u83b7\u53d6sh601288\u7684243\u5929\u6570\u636e\n\u6210\u529f\u83b7\u53d6sz002555\u7684243\u5929\u6570\u636e\n\u6210\u529f\u83b7\u53d6sz000538\u7684243\u5929\u6570\u636e\n\u6700\u540e\u4e00\u5929\u80a1\u7968\u4ef7\u683c:\nticker\nsh600938    25.79\nsh601288     5.53\nsz000538    56.48\nsz000937     6.70\nsz002555    14.67\nName: 2025-05-30 00:00:00, dtype: float64\n\u6570\u636e\u5904\u7406\u5b8c\u6210\uff0c\u6700\u7ec8\u6570\u636e\u96c6\u5305\u542b243\u5929\u6570\u636e\n\u6536\u76ca\u7387\u6781\u503c\u68c0\u6d4b:\n\u6700\u5c0f\u65e5\u6536\u76ca\u7387: -10.46%\n\u6700\u5927\u65e5\u6536\u76ca\u7387: 9.55%\n\u6b63\u5728\u8fd0\u884c\u8499\u7279\u5361\u6d1b\u6a21\u62df\uff0c\u6a21\u62df\u6b21\u6570\uff1a10000\uff0c\u9884\u6d4b\u5929\u6570\uff1a10\n\n\u6a21\u62df\u7ed3\u679c\u7edf\u8ba1:\n\u521d\u59cb\u6295\u8d44\u7ec4\u5408\u4ef7\u503c: 1,000,000\u5143\n\u6a21\u62df\u540e\u7ec4\u5408\u4ef7\u503c\u8303\u56f4: \u6700\u5c0f\u503c=855,834.29\u5143, \u6700\u5927\u503c=1,143,978.61\u5143\n\u7ec4\u5408\u4ef7\u503c\u53d8\u5316\u8303\u56f4: \u6700\u5c0f\u503c=-144,165.71\u5143, \u6700\u5927\u503c=143,978.61\u5143\n\u6536\u76ca\u7387\u7edf\u8ba1:\nticker    sh600938    sh601288    sz000538    sz000937    sz002555\ncount   242.000000  242.000000  242.000000  242.000000  242.000000\nmean     -0.000572    0.000954    0.000252   -0.000769    0.000091\nstd       0.019611    0.013706    0.013784    0.018998    0.025516\nmin      -0.100268   -0.047677   -0.076738   -0.086876   -0.104602\n25%      -0.009177   -0.007230   -0.006349   -0.009977   -0.015922\n50%       0.000350    0.002075    0.000086   -0.001723   -0.000382\n75%       0.008776    0.008864    0.006127    0.008332    0.013346\nmax       0.078906    0.040574    0.077164    0.074801    0.095478\n\n===== \u98ce\u9669\u4ef7\u503c\u8ba1\u7b97\u7ed3\u679c =====\n\u6295\u8d44\u7ec4\u5408\u603b\u4ef7\u503c: 1,000,000\u5143\n10\u5929\u6301\u6709\u671f\uff0c99.0%\u7f6e\u4fe1\u6c34\u5e73\u4e0b:\nVaR: 87,123.09\u5143 (8.71%)\nCVaR: 99,360.77\u5143 (9.94%)\n\n===== \u5404\u80a1\u7968\u98ce\u9669\u8d21\u732e =====\nsh600938: \u6743\u91cd=40.00%, \u98ce\u9669\u8d21\u732e=1.08%\nsz000937: \u6743\u91cd=20.00%, \u98ce\u9669\u8d21\u732e=0.14%\nsh601288: \u6743\u91cd=20.00%, \u98ce\u9669\u8d21\u732e=0.20%\nsz002555: \u6743\u91cd=10.00%, \u98ce\u9669\u8d21\u732e=0.20%\nsz000538: \u6743\u91cd=10.00%, \u98ce\u9669\u8d21\u732e=0.24%\n    '''<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"680\" src=\"http:\/\/cnliutz.pgrm.cc\/wp-content\/uploads\/2025\/05\/stock_mote_carlo-1024x680.png\" alt=\"\" class=\"wp-image-5691\" srcset=\"http:\/\/cnliutz.wicp.vip\/wp-content\/uploads\/2025\/05\/stock_mote_carlo-1024x680.png 1024w, http:\/\/cnliutz.wicp.vip\/wp-content\/uploads\/2025\/05\/stock_mote_carlo-300x199.png 300w, http:\/\/cnliutz.wicp.vip\/wp-content\/uploads\/2025\/05\/stock_mote_carlo-768x510.png 768w, http:\/\/cnliutz.wicp.vip\/wp-content\/uploads\/2025\/05\/stock_mote_carlo-1536x1020.png 1536w, http:\/\/cnliutz.wicp.vip\/wp-content\/uploads\/2025\/05\/stock_mote_carlo-2048x1361.png 2048w, http:\/\/cnliutz.wicp.vip\/wp-content\/uploads\/2025\/05\/stock_mote_carlo-480x320.png 480w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>akshare\u83b7\u53d6\u6570\u636e<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,24],"tags":[],"class_list":["post-5690","post","type-post","status-publish","format-standard","hentry","category-2","category-24"],"_links":{"self":[{"href":"http:\/\/cnliutz.wicp.vip\/index.php?rest_route=\/wp\/v2\/posts\/5690","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/cnliutz.wicp.vip\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/cnliutz.wicp.vip\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/cnliutz.wicp.vip\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/cnliutz.wicp.vip\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5690"}],"version-history":[{"count":1,"href":"http:\/\/cnliutz.wicp.vip\/index.php?rest_route=\/wp\/v2\/posts\/5690\/revisions"}],"predecessor-version":[{"id":5692,"href":"http:\/\/cnliutz.wicp.vip\/index.php?rest_route=\/wp\/v2\/posts\/5690\/revisions\/5692"}],"wp:attachment":[{"href":"http:\/\/cnliutz.wicp.vip\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5690"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/cnliutz.wicp.vip\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5690"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/cnliutz.wicp.vip\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5690"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}