{"id":5715,"date":"2025-06-03T09:00:32","date_gmt":"2025-06-03T01:00:32","guid":{"rendered":"http:\/\/cnliutz.ipyingshe.net\/?p=5715"},"modified":"2025-06-04T05:54:51","modified_gmt":"2025-06-03T21:54:51","slug":"%e4%bd%bf%e7%94%a8python%e5%92%8cakshare%e5%ba%93%e5%88%86%e6%9e%90%e8%82%a1%e7%a5%a8%e9%a3%8e%e9%99%a9","status":"publish","type":"post","link":"http:\/\/cnliutz.wicp.vip\/?p=5715","title":{"rendered":"\u4f7f\u7528Python\u548cakshare\u5e93\u5206\u6790\u80a1\u7968\u98ce\u9669"},"content":{"rendered":"\n<p>\u8981\u5206\u6790\u67d0\u53ea\u80a1\u7968\u7684\u98ce\u9669\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528akshare\u5e93\u83b7\u53d6\u80a1\u7968\u6570\u636e\uff0c\u7136\u540e\u8fdb\u884c\u98ce\u9669\u6307\u6807\u8ba1\u7b97\u7ed8\u56fe\u3002\u4ee5\u4e0b\u662f\u4e00\u4e2a\u5b8c\u6574\u7684Python\u4ee3\u7801\u793a\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import akshare as ak\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom scipy.stats import norm\nfrom datetime import datetime, timedelta\n\n# \u8bbe\u7f6e\u4e2d\u6587\u663e\u793a\nplt.rcParams&#91;'font.sans-serif'] = &#91;'SimHei']\nplt.rcParams&#91;'axes.unicode_minus'] = False\n\ndef get_stock_data(stock_code, start_date, end_date):\n    \"\"\"\n    \u83b7\u53d6\u80a1\u7968\u5386\u53f2\u6570\u636e\n    \"\"\"\n    try:\n        # \u4f7f\u7528akshare\u83b7\u53d6\u80a1\u7968\u6570\u636e\n        df = ak.stock_zh_a_hist(symbol=stock_code, period=\"daily\", start_date=start_date, end_date=end_date, adjust=\"hfq\")\n        df&#91;'\u65e5\u671f'] = pd.to_datetime(df&#91;'\u65e5\u671f'])\n        df.set_index('\u65e5\u671f', inplace=True)\n        df.sort_index(inplace=True)\n        return df\n    except Exception as e:\n        print(f\"\u83b7\u53d6\u6570\u636e\u5931\u8d25: {e}\")\n        return None\n\ndef calculate_risk_metrics(df):\n    \"\"\"\n    \u8ba1\u7b97\u98ce\u9669\u6307\u6807\n    \"\"\"\n    if df is None or len(df) &lt; 30:\n        print(\"\u6570\u636e\u4e0d\u8db3\u6216\u83b7\u53d6\u5931\u8d25\")\n        return None\n    \n    # \u8ba1\u7b97\u65e5\u6536\u76ca\u7387\n    df&#91;'\u65e5\u6536\u76ca\u7387'] = df&#91;'\u6536\u76d8'].pct_change()\n    \n    # \u8ba1\u7b97\u98ce\u9669\u6307\u6807\n    metrics = {}\n    \n    # 1. \u6ce2\u52a8\u7387(\u5e74\u5316)\n    daily_volatility = df&#91;'\u65e5\u6536\u76ca\u7387'].std()\n    annual_volatility = daily_volatility * np.sqrt(252)\n    metrics&#91;'\u5e74\u5316\u6ce2\u52a8\u7387'] = annual_volatility\n    \n    # 2. \u6700\u5927\u56de\u64a4\n    df&#91;'\u7d2f\u8ba1\u6536\u76ca\u7387'] = (1 + df&#91;'\u65e5\u6536\u76ca\u7387']).cumprod()\n    df&#91;'\u524d\u9ad8'] = df&#91;'\u7d2f\u8ba1\u6536\u76ca\u7387'].cummax()\n    df&#91;'\u56de\u64a4'] = (df&#91;'\u7d2f\u8ba1\u6536\u76ca\u7387'] - df&#91;'\u524d\u9ad8']) \/ df&#91;'\u524d\u9ad8']\n    max_drawdown = df&#91;'\u56de\u64a4'].min()\n    metrics&#91;'\u6700\u5927\u56de\u64a4'] = max_drawdown\n    \n    # 3. VaR (95%\u7f6e\u4fe1\u5ea6)\n    var_95 = norm.ppf(0.05, df&#91;'\u65e5\u6536\u76ca\u7387'].mean(), df&#91;'\u65e5\u6536\u76ca\u7387'].std())\n    metrics&#91;'\u65e5VaR(95%)'] = var_95\n    \n    # 4. \u590f\u666e\u6bd4\u7387(\u5047\u8bbe\u65e0\u98ce\u9669\u5229\u7387\u4e3a3%)\n    annual_return = (1 + df&#91;'\u65e5\u6536\u76ca\u7387'].mean()) ** 252 - 1\n    risk_free_rate = 0.03\n    sharpe_ratio = (annual_return - risk_free_rate) \/ annual_volatility\n    metrics&#91;'\u590f\u666e\u6bd4\u7387'] = sharpe_ratio\n    \n    # 5. Beta\u7cfb\u6570(\u9700\u8981\u5e02\u573a\u6570\u636e\uff0c\u8fd9\u91cc\u7b80\u5316\u5904\u7406)\n    # \u5b9e\u9645\u5e94\u7528\u4e2d\u9700\u8981\u83b7\u53d6\u5e02\u573a\u6307\u6570\u6570\u636e\u8ba1\u7b97\n    \n    return metrics\n\ndef plot_stock_risk(df):\n    \"\"\"\n    \u7ed8\u5236\u98ce\u9669\u76f8\u5173\u56fe\u8868\n    \"\"\"\n    if df is None or len(df) &lt; 30:\n        return\n    \n    plt.figure(figsize=(15, 10))\n    \n    # 1. \u4ef7\u683c\u8d70\u52bf\n    plt.subplot(2, 2, 1)\n    plt.plot(df&#91;'\u6536\u76d8'], label='\u6536\u76d8\u4ef7')\n    plt.title('\u80a1\u7968\u4ef7\u683c\u8d70\u52bf')\n    plt.xlabel('\u65e5\u671f')\n    plt.ylabel('\u4ef7\u683c')\n    plt.legend()\n    \n    # 2. \u6536\u76ca\u7387\u5206\u5e03\n    plt.subplot(2, 2, 2)\n    plt.hist(df&#91;'\u65e5\u6536\u76ca\u7387'].dropna(), bins=50, density=True, alpha=0.6, color='g')\n    plt.title('\u65e5\u6536\u76ca\u7387\u5206\u5e03')\n    plt.xlabel('\u65e5\u6536\u76ca\u7387')\n    plt.ylabel('\u9891\u7387')\n    \n    # 3. \u7d2f\u8ba1\u6536\u76ca\u7387\u548c\u56de\u64a4\n    plt.subplot(2, 2, 3)\n    plt.plot(df&#91;'\u7d2f\u8ba1\u6536\u76ca\u7387'], label='\u7d2f\u8ba1\u6536\u76ca\u7387')\n    plt.plot(df&#91;'\u524d\u9ad8'], label='\u524d\u9ad8', linestyle='--')\n    plt.title('\u7d2f\u8ba1\u6536\u76ca\u7387\u4e0e\u56de\u64a4')\n    plt.xlabel('\u65e5\u671f')\n    plt.ylabel('\u7d2f\u8ba1\u6536\u76ca\u7387')\n    plt.legend()\n    \n    # 4. \u56de\u64a4\u66f2\u7ebf\n    plt.subplot(2, 2, 4)\n    plt.plot(df&#91;'\u56de\u64a4'], label='\u56de\u64a4', color='r')\n    plt.title('\u56de\u64a4\u66f2\u7ebf')\n    plt.xlabel('\u65e5\u671f')\n    plt.ylabel('\u56de\u64a4\u6bd4\u4f8b')\n    plt.legend()\n    \n    plt.tight_layout()\n    plt.show()\n\ndef analyze_stock_risk(stock_code, start_date, end_date):\n    \"\"\"\n    \u5206\u6790\u80a1\u7968\u98ce\u9669\u7684\u4e3b\u51fd\u6570\n    \"\"\"\n    print(f\"\u6b63\u5728\u5206\u6790\u80a1\u7968 {stock_code} \u7684\u98ce\u9669...\")\n    \n    # \u83b7\u53d6\u6570\u636e\n    df = get_stock_data(stock_code, start_date, end_date)\n    \n    if df is None:\n        return\n    \n    # \u8ba1\u7b97\u98ce\u9669\u6307\u6807\n    metrics = calculate_risk_metrics(df)\n    \n    if metrics:\n        print(\"\\n\u98ce\u9669\u6307\u6807\u5206\u6790\u7ed3\u679c:\")\n        for key, value in metrics.items():\n            print(f\"{key}: {value:.4f}\")\n        \n        # \u7ed8\u5236\u56fe\u8868\n        plot_stock_risk(df)\n    else:\n        print(\"\u65e0\u6cd5\u8ba1\u7b97\u98ce\u9669\u6307\u6807\")\n\n# \u793a\u4f8b\u4f7f\u7528\nif __name__ == \"__main__\":\n    # \u8bbe\u7f6e\u80a1\u7968\u4ee3\u7801\u548c\u65f6\u95f4\u8303\u56f4\n    stock_code = \"601288\"  # \u5e73\u5b89\u94f6\u884c\uff0c\u53ef\u4ee5\u66ff\u6362\u4e3a\u5176\u4ed6\u80a1\u7968\u4ee3\u7801\n    # \u8ba1\u7b97\u4e24\u5e74\u524d\u7684\u65e5\u671f\n    start_date = (datetime.now() - timedelta(days=365*1)).strftime(\"%Y%m%d\")\n    # \u83b7\u53d6\u5f53\u524d\u65e5\u671f\n    end_date = datetime.now().strftime(\"%Y%m%d\")\n    \n    analyze_stock_risk(stock_code, start_date, end_date)\n<\/code><\/pre>\n\n\n\n<p>\u4ee3\u7801\u8bf4\u660e<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u6570\u636e\u83b7\u53d6:<\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u4f7f\u7528akshare\u7684<br>&#8220;stock_zh_a_hist&#8221;\u51fd\u6570\u83b7\u53d6A\u80a1\u5386\u53f2\u6570\u636e<\/li>\n\n\n\n<li>\u6570\u636e\u5305\u62ec\u65e5\u671f\u3001\u5f00\u76d8\u4ef7\u3001\u6536\u76d8\u4ef7\u3001\u6700\u9ad8\u4ef7\u3001\u6700\u4f4e\u4ef7\u7b49<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u98ce\u9669\u6307\u6807\u8ba1\u7b97:<\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5e74\u5316\u6ce2\u52a8\u7387: \u53cd\u6620\u80a1\u7968\u4ef7\u683c\u7684\u6ce2\u52a8\u7a0b\u5ea6<\/li>\n\n\n\n<li>\u6700\u5927\u56de\u64a4: \u8861\u91cf\u4ece\u6700\u9ad8\u70b9\u5230\u6700\u4f4e\u70b9\u7684\u6700\u5927\u635f\u5931<\/li>\n\n\n\n<li>VaR(\u98ce\u9669\u4ef7\u503c): \u572895%\u7f6e\u4fe1\u5ea6\u4e0b\u7684\u65e5\u6700\u5927\u635f\u5931<\/li>\n\n\n\n<li>\u590f\u666e\u6bd4\u7387: \u8861\u91cf\u98ce\u9669\u8c03\u6574\u540e\u7684\u6536\u76ca<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u53ef\u89c6\u5316:<\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u4ef7\u683c\u8d70\u52bf\u56fe<\/li>\n\n\n\n<li>\u6536\u76ca\u7387\u5206\u5e03\u76f4\u65b9\u56fe<\/li>\n\n\n\n<li>\u7d2f\u8ba1\u6536\u76ca\u7387\u548c\u524d\u9ad8\u66f2\u7ebf<\/li>\n\n\n\n<li>\u56de\u64a4\u66f2\u7ebf<\/li>\n<\/ul>\n\n\n\n<p>\u4f7f\u7528\u8bf4\u660e<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u5b89\u88c5\u6240\u9700\u5e93:<br>&#8220;pip install akshare pandas numpy matplotlib scipy&#8221;<\/li>\n\n\n\n<li>\u4fee\u6539<br>&#8220;stock_code&#8221;\u4e3a\u4f60\u60f3\u5206\u6790\u7684\u80a1\u7968\u4ee3\u7801(\u5982&#8221;600519&#8243;\u4e3a\u8d35\u5dde\u8305\u53f0)<\/li>\n\n\n\n<li>\u8c03\u6574<br>&#8220;start_date&#8221;\u548c<br>&#8220;end_date&#8221;\u8bbe\u7f6e\u5206\u6790\u7684\u65f6\u95f4\u8303\u56f4<\/li>\n\n\n\n<li>\u8fd0\u884c\u4ee3\u7801\u5373\u53ef\u83b7\u53d6\u98ce\u9669\u5206\u6790\u7ed3\u679c\u548c\u53ef\u89c6\u5316\u56fe\u8868<\/li>\n<\/ol>\n\n\n\n<p>\u6ce8\u610f\u4e8b\u9879<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>akshare\u7684\u6570\u636e\u63a5\u53e3\u53ef\u80fd\u4f1a\u6709\u53d8\u5316\uff0c\u5982\u679c\u83b7\u53d6\u5931\u8d25\u8bf7\u68c0\u67e5akshare\u6587\u6863<\/li>\n\n\n\n<li>Beta\u7cfb\u6570\u7684\u8ba1\u7b97\u9700\u8981\u5e02\u573a\u6307\u6570\u6570\u636e\uff0c\u8fd9\u91cc\u7b80\u5316\u5904\u7406\u672a\u5b9e\u73b0<\/li>\n\n\n\n<li>\u66f4\u5168\u9762\u7684\u98ce\u9669\u5206\u6790\u53ef\u4ee5\u6dfb\u52a0\u66f4\u591a\u6307\u6807\uff0c\u5982\u4e0b\u884c\u98ce\u9669\u3001\u7d22\u63d0\u8bfa\u6bd4\u7387\u7b49<\/li>\n<\/ol>\n\n\n\n<p>\u5e0c\u671b\u8fd9\u4e2a\u4ee3\u7801\u80fd\u5e2e\u52a9\u4f60\u5206\u6790\u80a1\u7968\u98ce\u9669\uff01\u5982\u9700\u8fdb\u4e00\u6b65\u6269\u5c55\uff0c\u53ef\u4ee5\u8003\u8651\u6dfb\u52a0\u66f4\u591a\u98ce\u9669\u6307\u6807\u6216\u4e0e\u5176\u4ed6\u91d1\u878d\u6570\u636e\u7684\u5173\u8054\u5206\u6790\u3002<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"726\" src=\"http:\/\/192.168.1.29\/wp-content\/uploads\/2025\/06\/\u5c4f\u5e55\u622a\u56fe-2025-06-04-054530-1024x726.png\" alt=\"\" class=\"wp-image-5728\" srcset=\"http:\/\/cnliutz.wicp.vip\/wp-content\/uploads\/2025\/06\/\u5c4f\u5e55\u622a\u56fe-2025-06-04-054530-1024x726.png 1024w, http:\/\/cnliutz.wicp.vip\/wp-content\/uploads\/2025\/06\/\u5c4f\u5e55\u622a\u56fe-2025-06-04-054530-300x213.png 300w, http:\/\/cnliutz.wicp.vip\/wp-content\/uploads\/2025\/06\/\u5c4f\u5e55\u622a\u56fe-2025-06-04-054530-768x544.png 768w, http:\/\/cnliutz.wicp.vip\/wp-content\/uploads\/2025\/06\/\u5c4f\u5e55\u622a\u56fe-2025-06-04-054530-1536x1088.png 1536w, http:\/\/cnliutz.wicp.vip\/wp-content\/uploads\/2025\/06\/\u5c4f\u5e55\u622a\u56fe-2025-06-04-054530-2048x1451.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>\u8981\u5206\u6790\u67d0\u53ea\u80a1\u7968\u7684\u98ce\u9669\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528akshare\u5e93\u83b7\u53d6\u80a1\u7968\u6570\u636e\uff0c\u7136\u540e\u8fdb\u884c\u98ce\u9669\u6307\u6807 <span class=\"readmore\"><a href=\"http:\/\/cnliutz.wicp.vip\/?p=5715\">Continue Reading<\/a><\/span><\/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-5715","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\/5715","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=5715"}],"version-history":[{"count":2,"href":"http:\/\/cnliutz.wicp.vip\/index.php?rest_route=\/wp\/v2\/posts\/5715\/revisions"}],"predecessor-version":[{"id":5729,"href":"http:\/\/cnliutz.wicp.vip\/index.php?rest_route=\/wp\/v2\/posts\/5715\/revisions\/5729"}],"wp:attachment":[{"href":"http:\/\/cnliutz.wicp.vip\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5715"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/cnliutz.wicp.vip\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5715"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/cnliutz.wicp.vip\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5715"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}