{"id":1729,"date":"2024-12-21T07:57:00","date_gmt":"2024-12-20T23:57:00","guid":{"rendered":"https:\/\/blog.laoyulaoyu.top\/?p=1729"},"modified":"2024-11-28T15:14:47","modified_gmt":"2024-11-28T07:14:47","slug":"%e9%87%91%e8%9e%8d%e8%be%be%e4%ba%ba%e5%bf%85%e5%a4%87%ef%bc%9a%e6%95%99%e4%bd%a0%e7%94%a8python%e8%bd%bb%e6%9d%be%e7%ae%80%e5%8c%96%e6%95%b0%e6%8d%ae%e5%88%86%e6%9e%90%e6%b5%81%e7%a8%8b%ef%bc%81","status":"publish","type":"post","link":"https:\/\/laoyulaoyu.com\/index.php\/2024\/12\/21\/%e9%87%91%e8%9e%8d%e8%be%be%e4%ba%ba%e5%bf%85%e5%a4%87%ef%bc%9a%e6%95%99%e4%bd%a0%e7%94%a8python%e8%bd%bb%e6%9d%be%e7%ae%80%e5%8c%96%e6%95%b0%e6%8d%ae%e5%88%86%e6%9e%90%e6%b5%81%e7%a8%8b%ef%bc%81\/","title":{"rendered":"\u91d1\u878d\u8fbe\u4eba\u5fc5\u5907\uff1a\u6559\u4f60\u7528Python\u8f7b\u677e\u7b80\u5316\u6570\u636e\u5206\u6790\u6d41\u7a0b\uff01"},"content":{"rendered":"\n<p>\u4f5c\u8005\uff1a<a href=\"https:\/\/www.laoyulaoyu.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">\u8001\u4f59\u635e\u9c7c<\/a><\/p>\n\n\n\n<p><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-cyan-bluish-gray-color\">\u539f\u521b\u4e0d\u6613\uff0c\u8f6c\u8f7d\u8bf7\u6807\u660e\u51fa\u5904\u53ca\u539f\u4f5c\u8005\u3002<\/mark><\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.laoyulaoyu.com\/wp-content\/uploads\/2024\/11\/102801-1.png\" alt=\"\" class=\"wp-image-3154\"\/><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<pre class=\"wp-block-verse\"><strong>\u5199\u5728\u524d\u9762\u7684\u8bdd\uff1a<\/strong>\u4eca\u5929\u6211\u60f3\u548c\u5927\u5bb6\u5206\u4eab\u4e00\u7bc7\u5173\u4e8e\u5982\u4f55\u5229\u7528FMP API\u548cPython\u6765\u7b80\u5316\u91d1\u878d\u6570\u636e\u5206\u6790\u6d41\u7a0b\u7684\u6587\u7ae0\u3002<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">\u672c\u6587\u5c06\u8be6\u7ec6\u4ecb\u7ecd\u5982\u4f55\u8fd0\u7528Python\uff0c\u7ed3\u5408FMP API\u7684\u5f3a\u5927\u529f\u80fd\uff0c\u9ad8\u6548\u5730\u5904\u7406\u548c\u5206\u6790SP500\u6307\u6570\u516c\u53f8\u7684\u8d22\u52a1\u6570\u636e\u3002<\/mark>\u4ece\u83b7\u53d6\u80a1\u7968\u4ef7\u683c\u3001\u8d22\u52a1\u62a5\u8868\uff0c\u5230\u5206\u6790\u5173\u952e\u8d22\u52a1\u6307\u6807\uff0c\u6bcf\u4e00\u6b65\u90fd\u5c06\u901a\u8fc7\u5b9e\u9645\u6848\u4f8b\u4e3a\u60a8\u4e00\u4e00\u5c55\u73b0\u3002\u4ee5\u671f\u63d0\u9ad8\u5de5\u4f5c\u6548\u7387\uff0c\u5e76\u5728\u6295\u8d44\u51b3\u7b56\u4e2d\u53d1\u6325\u66f4\u5927\u7684\u4f5c\u7528\u3002<\/pre>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u4e00\u3001\u6570\u636e\u51c6\u5907<\/strong><\/h2>\n\n\n\n<p>\u6211\u4f7f\u7528 FMP API \u5df2\u7ecf\u6709\u4e00\u6bb5\u65f6\u95f4\u4e86\uff0c\u5b83\u7684\u6613\u7528\u6027\u3001\u4ea4\u4e92\u53cb\u597d\u4ee5\u53ca\u72ec\u7279\u7684\u7aef\u70b9\u4ea7\u54c1\uff0c\u4f7f\u5176\u6210\u4e3a\u4efb\u4f55\u60f3\u8981\u8bbf\u95ee\u9ad8\u7ea7\u91d1\u878d\u6570\u636e\u7684\u7a0b\u5e8f\u5458\u3001\u5206\u6790\u5e08\u6216\u6570\u636e\u4e13\u5bb6\u7684\u7edd\u4f73\u9009\u62e9\u3002<\/p>\n\n\n\n<p>\u5730\u5740\uff1a<a href=\"https:\/\/site.financialmodelingprep.com\/\">https:\/\/site.financialmodelingprep.com\/<\/a><\/p>\n\n\n\n<p>\u800c\u672c\u6587\u4e2d\u7684\u7f16\u7a0b\u4e3b\u8981\u5305\u62ec\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\uff08Object-Oriented Programming\uff09\uff0c\u7b80\u79f0 OOP\u3002OOP\u662f\u4e00\u79cd\u4ee3\u7801\u7ec4\u7ec7\u65b9\u5f0f\uff0c\u5b83\u5c06\u6570\u636e\u548c\u529f\u80fd\uff08\u5373\u5c5e\u6027\u548c\u65b9\u6cd5\uff09\u5c01\u88c5\u5728\u4e00\u8d77\uff0c\u4fbf\u4e8e\u7ba1\u7406\u548c\u4f7f\u7528\u3002\u8fd9\u79cd\u65b9\u5f0f\u6781\u5927\u5730\u4fbf\u5229\u4e86\u6211\u4f7f\u7528FMP API\u7684\u8fc7\u7a0b\uff0c\u56e0\u4e3a\u6211\u80fd\u591f\u901a\u8fc7\u64cd\u4f5c\u8fd9\u4e2a\u201c\u5bf9\u8c61\u201d\u6765\u8f7b\u677e\u83b7\u53d6\u6240\u9700\u6570\u636e\u6216\u8fdb\u884c\u6570\u636e\u5206\u6790\u3002\u5982\u679c\u5bf9\u8c61\u7f3a\u5c11\u67d0\u4e9b\u529f\u80fd\uff0c\u6211\u8fd8\u53ef\u4ee5\u968f\u65f6\u4e3a\u5176\u6dfb\u52a0\u65b9\u6cd5\uff0c\u4ece\u6b64\u544a\u522b\u4e86\u7f16\u5199\u989d\u5916\u51fd\u6570\u7684\u70e6\u607c\uff01<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>1.1 \u521b\u5efa\u6570\u636e\u7c7b<\/strong><\/h3>\n\n\n\n<p>\u6211\u521b\u5efa\u7684\u5bf9\u8c61\u540d\u4e3a SP500data \u7c7b\u3002\u8be5\u5bf9\u8c61\u4e0e FMP API \u76f8\u7ed3\u5408\uff0c\u53ef\u4ee5\u5bfc\u5165 SP500 \u6307\u6570\u4e2d\u6700\u65b0\u516c\u53f8\u7684\u4ef7\u683c\u3001\u8d22\u52a1\u62a5\u8868\u3001\u6982\u51b5\u6570\u636e\u548c\u5173\u952e\u8d22\u52a1\u6307\u6807\u3002\u6211\u8fd8\u8ba1\u5212\u6dfb\u52a0\u66f4\u591a\u65b9\u6cd5\uff0c\u4ee5\u5bfc\u5165\u66f4\u591a\u5f62\u5f0f\u7684\u6570\u636e\u5e76\u5feb\u901f\u8fdb\u884c\u5206\u6790\u3002\u8ba9\u6211\u4eec\u6765\u770b\u770b\u8fd9\u4e2a\u5bf9\u8c61\u7684\u521d\u59cb\u5316\u51fd\u6570\u4ee5\u53ca\u5b83\u6240\u9700\u8981\u7684 Python \u5e93\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from concurrent.futures import ThreadPoolExecutor, as_completed\nimport requests\nimport pandas as pd\nfrom tqdm import tqdm\nimport time\n\nclass SP500data:\n    def __init__(self, api_key):\n        self.api_key = api_key\n        \n        ## Symbols and Profiles\n        self.symbol_list = &#91;]\n        self.company_profile_df = None\n        \n        ## Price\n        self.price_data = {}\n\n        ## Financials\n        self.income_statement_data_annual = {}\n        self.balance_sheet_data_annual = {}\n        self.cash_flow_data_annual = {}\n        self.key_metrics_data_annual = {}\n        self.income_statement_data_quarter = {}\n        self.balance_sheet_data_quarter = {}\n        self.cash_flow_data_quarter = {}\n        self.key_metrics_data_quarter = {}<\/code><\/pre>\n\n\n\n<p>\u5982\u60a8\u6240\u89c1\uff0c\u4ee3\u7801\u4e2d\u9700\u8981\u63d0\u4f9b\u7684\u552f\u4e00\u53d8\u91cf\u5c31\u662f\u60a8\u81ea\u5df1\u7684 FMP API\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>1.2 \u83b7\u53d6\u6807\u5fd7\u548c\u516c\u53f8\u7b80\u4ecb<\/strong><\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>def get_symbols(self):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v3\/sp500_constituent?apikey={self.api_key}'\n        stocks = requests.get(url).json()\n        self.symbol_list = &#91;stock&#91;'symbol'] for stock in stocks]<\/code><\/pre>\n\n\n\n<p>get_symbols \u65b9\u6cd5\u5c06\u901a\u8fc7 sp500_constituent \u7aef\u70b9\u4e3a\u6211\u4eec\u68c0\u7d22\u8fd9\u4e9b\u7b26\u53f7\u3002<\/p>\n\n\n\n<p>\u83b7\u53d6\u516c\u53f8\u7b80\u4ecb\u548c\u6211\u8ba1\u5212\u5bfc\u5165\u7684\u5176\u4ed6\u6570\u636e\u53ef\u80fd\u4f1a\u5f88\u8017\u65f6\u3002\u6b64\u5916\uff0c\u5bfc\u5165\u8fd9\u4e9b\u6570\u636e\u7684\u987a\u5e8f\u5e76\u4e0d\u91cd\u8981\u3002\u8003\u8651\u5230\u8fd9\u4e24\u70b9\uff0c\u6211\u521b\u5efa\u4e86\u4e00\u5957\u5229\u7528\u5e76\u884c\u7f16\u7a0b\u5bfc\u5165\u6570\u636e\u7684\u65b9\u6cd5\u3002\u5e76\u884c\u7f16\u7a0b\u6307\u793a\u8ba1\u7b97\u673a\u5c06\u591a\u4e2a\u5de5\u4f5c\u8d1f\u8f7d\u5206\u6563\u5230\u53ef\u7528\u7684\u5904\u7406\u5668\u4e0a\u540c\u65f6\u8fd0\u884c\u3002<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">def fetch_profile(self, symbol):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v3\/profile\/{symbol}?apikey={self.api_key}'\n        response = requests.get(url).json()\n        return pd.DataFrame(response)\n\ndef fetch_profile_data(self):\n        profile_dfs = []\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_symbol = {executor.submit(self.fetch_profile, symbol): symbol for symbol in self.symbol_list}\n            for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                try:\n                    single_df = future.result()\n                    profile_dfs.append(single_df)\n                except Exception as exc:\n                    print(f'Exception for {future_to_symbol[future]}: {exc}')\n        self.company_profile_df = pd.concat(profile_dfs, ignore_index=True)<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>1.3 \u83b7\u53d6\u4ef7\u683c\u3001\u8d22\u52a1\u62a5\u8868\u548c\u5173\u952e\u6307\u6807<\/strong><\/h3>\n\n\n\n<p id=\"074b\">\u4f7f\u7528\u65b9\u6cd5\u5bfc\u5165\u4ee5\u4e0b\u5185\u5bb9\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u6bcf\u5bb6\u516c\u53f8\u6700\u8fd1\u4e94\u5e74\u7684 OHLC \u4ef7\u683c\u6570\u636e\uff1b<\/li>\n\n\n\n<li>\u6536\u5165\u3001\u8d44\u4ea7\u8d1f\u503a\u8868\u548c\u73b0\u91d1\u6d41\u91cf\u8868\u6570\u636e\u5386\u53f2\u6570\u636e\uff1b<\/li>\n\n\n\n<li>\u57fa\u4e8e\u8d22\u52a1\u62a5\u8868\u6570\u636e\u7684\u5173\u952e\u8d22\u52a1\u6307\u6807\u3002<\/li>\n<\/ul>\n\n\n\n<p id=\"6fd7\">\u5f53\u60a8\u8fd0\u7528\u8fd9\u4e9b\u65b9\u6cd5\u540e\uff0c\u60a8\u7684\u5bf9\u8c61\u5c06\u53d8\u6210\u4e00\u4e2a\u5145\u6ee1\u8d22\u52a1\u6570\u636e\u7684\u5b9d\u5e93\u3002\u6bd4\u5982\uff0c\u60a8\u60f3\u8981\u5c55\u793a\u4e00\u5bb6\u516c\u53f8\u5173\u952e\u5229\u6da6\u7387\u7684\u5386\u53f2\u6570\u636e\uff0c\u6216\u8005\u66f4\u4e0a\u4e00\u5c42\u697c\uff0c\u60a8\u5e0c\u671b\u540c\u65f6\u5c55\u793a\u591a\u5bb6\u516c\u53f8\u7684\u6570\u636e\u4ee5\u8fdb\u884c\u5bf9\u6bd4\u5206\u6790\uff01\u53ea\u9700\u7b80\u5355\u8c03\u7528\u8fd9\u4e9b\u65b9\u6cd5\uff0c\u4e00\u884c\u4ee3\u7801\u5373\u53ef\u8ba9\u60a8\u7684\u5b9e\u4f8b\u83b7\u53d6\u6240\u6709\u5fc5\u9700\u7684\u6570\u636e\u3002\u53e6\u5916\uff0c\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0cAPI\u4e5f\u80fd\u591f\u68c0\u7d22\u5b63\u5ea6\u548c\u5e74\u5ea6\u7684\u8d22\u52a1\u62a5\u8868\uff0c\u6ee1\u8db3\u60a8\u4e0d\u540c\u7684\u6570\u636e\u9700\u6c42\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    def fetch_price(self, symbol):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v3\/historical-price-full\/{symbol}?apikey={self.api_key}'\n        response = requests.get(url).json()\n        prices_df = pd.DataFrame(response&#91;'historical'])\n        prices_df = prices_df.sort_values(by='date').reset_index(drop=True)\n        return prices_df\n\n    def fetch_price_data(self):\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_symbol = {executor.submit(self.fetch_price, symbol): symbol for symbol in self.symbol_list}\n            for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                try:\n                    symbol = future_to_symbol&#91;future]\n                    prices_df = future.result()\n                    self.price_data&#91;symbol] = prices_df\n                except Exception as exc:\n                    print(f'Exception for {symbol}: {exc}')\n\n    def fetch_income_statement_annual(self, symbol):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v3\/income-statement\/{symbol}?period=annual&amp;apikey={self.api_key}'\n        response = requests.get(url).json()\n        return pd.DataFrame(response)\n\n    def fetch_income_statement_quarter(self, symbol):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v3\/income-statement\/{symbol}?period=quarter&amp;apikey={self.api_key}'\n        response = requests.get(url).json()\n        return pd.DataFrame(response)\n\n    def fetch_income_statement_data_annual_concurrent(self):\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_symbol = {executor.submit(self.fetch_income_statement_annual, symbol): symbol for symbol in self.symbol_list}\n            for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                try:\n                    symbol = future_to_symbol&#91;future]\n                    income_df = future.result()\n                    self.income_statement_data_annual&#91;symbol] = income_df\n                except Exception as exc:\n                    print(f'Exception for {symbol}: {exc}')\n\n    def fetch_income_statement_data_quarter_concurrent(self):\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_symbol = {executor.submit(self.fetch_income_statement_quarter, symbol): symbol for symbol in self.symbol_list}\n            for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                try:\n                    symbol = future_to_symbol&#91;future]\n                    income_df = future.result()\n                    self.income_statement_data_quarter&#91;symbol] = income_df\n                except Exception as exc:\n                    print(f'Exception for {symbol}: {exc}')\n\n\n    def fetch_balance_sheet_annual(self, symbol):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v3\/balance-sheet-statement\/{symbol}?period=annual&amp;apikey={self.api_key}'\n        response = requests.get(url).json()\n        return pd.DataFrame(response)\n\n    def fetch_balance_sheet_quarter(self, symbol):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v3\/balance-sheet-statement\/{symbol}?period=quarter&amp;apikey={self.api_key}'\n        response = requests.get(url).json()\n        return pd.DataFrame(response)\n\n    def fetch_balance_sheet_data_annual_concurrent(self):\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_symbol = {executor.submit(self.fetch_balance_sheet_annual, symbol): symbol for symbol in self.symbol_list}\n            for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                try:\n                    symbol = future_to_symbol&#91;future]\n                    balance_df = future.result()\n                    self.balance_sheet_data_annual&#91;symbol] = balance_df\n                except Exception as exc:\n                    print(f'Exception for {symbol}: {exc}')\n\n    def fetch_balance_sheet_data_quarter_concurrent(self):\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_symbol = {executor.submit(self.fetch_balance_sheet_quarter, symbol): symbol for symbol in self.symbol_list}\n            for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                try:\n                    symbol = future_to_symbol&#91;future]\n                    balance_df = future.result()\n                    self.balance_sheet_data_quarter&#91;symbol] = balance_df\n                except Exception as exc:\n                    print(f'Exception for {symbol}: {exc}')\n\n    def fetch_cash_flow_annual(self, symbol):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v3\/cash-flow-statement\/{symbol}?period=annual&amp;apikey={self.api_key}'\n        response = requests.get(url).json()\n        return pd.DataFrame(response)\n\n    def fetch_cash_flow_quarter(self, symbol):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v3\/cash-flow-statement\/{symbol}?period=quarter&amp;apikey={self.api_key}'\n        response = requests.get(url).json()\n        return pd.DataFrame(response)\n\n    def fetch_cash_flow_data_annual_concurrent(self):\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_symbol = {executor.submit(self.fetch_cash_flow_annual, symbol): symbol for symbol in self.symbol_list}\n            for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                try:\n                    symbol = future_to_symbol&#91;future]\n                    cash_flow_df = future.result()\n                    self.cash_flow_data_annual&#91;symbol] = cash_flow_df\n                except Exception as exc:\n                    print(f'Exception for {symbol}: {exc}')\n\n    def fetch_cash_flow_data_quarter_concurrent(self):\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_symbol = {executor.submit(self.fetch_cash_flow_quarter, symbol): symbol for symbol in self.symbol_list}\n            for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                try:\n                    symbol = future_to_symbol&#91;future]\n                    cash_flow_df = future.result()\n                    self.cash_flow_data_quarter&#91;symbol] = cash_flow_df\n                except Exception as exc:\n                    print(f'Exception for {symbol}: {exc}')\n\n    def fetch_key_metrics_annual(self, symbol):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v3\/key-metrics\/{symbol}?period=annual&amp;apikey={self.api_key}'\n        response = requests.get(url).json()\n        return pd.DataFrame(response)\n\n    def fetch_key_metrics_quarter(self, symbol):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v3\/key-metrics\/{symbol}?period=quarter&amp;apikey={self.api_key}'\n        response = requests.get(url).json()\n        return pd.DataFrame(response)\n\n    def fetch_key_metrics_data_annual_concurrent(self):\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_symbol = {executor.submit(self.fetch_key_metrics_annual, symbol): symbol for symbol in self.symbol_list}\n            for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                try:\n                    symbol = future_to_symbol&#91;future]\n                    key_metrics_df = future.result()\n                    self.key_metrics_data_annual&#91;symbol] = key_metrics_df\n                except Exception as exc:\n                    print(f'Exception for {symbol}: {exc}')\n\n    def fetch_key_metrics_data_quarter_concurrent(self):\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_symbol = {executor.submit(self.fetch_key_metrics_quarter, symbol): symbol for symbol in self.symbol_list}\n            for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                try:\n                    symbol = future_to_symbol&#91;future]\n                    key_metrics_df = future.result()\n                    self.key_metrics_data_quarter&#91;symbol] = key_metrics_df\n                except Exception as exc:\n                    print(f'Exception for {symbol}: {exc}')<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>1.4 \u7528\u4e00\u884c\u4ee3\u7801\u83b7\u53d6\u6240\u6709\u6570\u636e<\/strong><\/h3>\n\n\n\n<p>\u81f3\u6b64\uff0c\u6211\u5df2\u7ecf\u7f16\u5199\u4e86\u4e00\u7cfb\u5217\u65b9\u6cd5\uff0c\u5982\u679c\u8981\u8fdb\u884c\u8be6\u7ec6\u5206\u6790\uff0c\u6211\u53ef\u80fd\u9700\u8981\u8fd9\u4e9b\u65b9\u6cd5\u83b7\u53d6\u7684\u6240\u6709\u6570\u636e\u3002\u4e3a\u6b64\uff0c\u6211\u521b\u5efa\u4e86\u4e00\u4e2a\u540d\u4e3a&nbsp;<code>fetch_all_data<\/code>&nbsp;\u7684\u65b9\u6cd5\uff0c\u5b83\u8d1f\u8d23\u8c03\u7528\u4e4b\u524d\u6211\u6240\u5b9a\u4e49\u7684\u6240\u6709\u51fd\u6570\u3002\u6211\u8fd8\u52a0\u5165\u4e86\u4e00\u4e2a\u5ef6\u8fdf\u53d8\u91cf\uff0c\u5141\u8bb8\u6700\u7ec8\u7528\u6237\u6839\u636e\u4ed6\u4eec\u7684API\u8c03\u7528\u9650\u5236\u8fdb\u884c\u8c03\u6574\u3002\u4ee5FMP API\u7684\u9ad8\u7ea7\u8ba1\u5212\u4e3a\u4f8b\uff0c\u5b83\u5141\u8bb8\u6bcf\u5206\u949f\u6700\u591a750\u6b21\u8c03\u7528\u3002\u5c3d\u7ba1\u8fd9\u4e2a\u9650\u5236\u5bf9\u6211\u6765\u8bf4\u5df2\u7ecf\u76f8\u5f53\u5bbd\u88d5\uff0c\u4f46\u8fd9\u79cd\u65b9\u6cd5\u6709\u53ef\u80fd\u5728\u77ed\u65f6\u95f4\u5185\u53d1\u8d77\u6570\u5343\u6b21API\u8bf7\u6c42\uff0c\u56e0\u6b64\u6211\u4eec\u9700\u8981\u9002\u5f53\u8bbe\u7f6e\u5ef6\u8fdf\u65f6\u95f4\u3002\u503c\u5f97\u5e86\u5e78\u7684\u662f\uff0c\u4e00\u65e6\u6570\u636e\u63d0\u53d6\u5b8c\u6210\uff0c\u5bf9\u8c61\u7684\u5b9e\u4f8b\u5c31\u5c06\u5305\u542b\u6211\u4eec\u6240\u9700\u7684\u4e00\u5207\u6570\u636e\uff01<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">   def fetch_all_data(self,delay):\n        print(\"Fetching symbols...\")\n        self.get_symbols()\n\n        print(\"Fetching company profiles...\")\n        self.fetch_profile_data()\n\n        print(f\"Waiting for {delay} seconds to comply with API rate limits...\")\n        time.sleep(delay)\n\n        print(\"Fetching price data...\")\n        self.fetch_price_data()\n\n        print(f\"Waiting for {delay} seconds to comply with API rate limits...\")\n        time.sleep(delay)\n\n        print(\"Fetching annual income statements...\")\n        self.fetch_income_statement_data_annual_concurrent()\n\n        print(f\"Waiting for {delay} seconds to comply with API rate limits...\")\n        time.sleep(delay)\n\n        print(\"Fetching quarterly income statements...\")\n        self.fetch_income_statement_data_quarter_concurrent()\n\n        print(f\"Waiting for {delay} seconds to comply with API rate limits...\")\n        time.sleep(delay)\n\n        print(\"Fetching annual balance sheets...\")\n        self.fetch_balance_sheet_data_annual_concurrent()\n\n        print(f\"Waiting for {delay} seconds to comply with API rate limits...\")\n        time.sleep(delay)\n\n        print(\"Fetching quarterly balance sheets...\")\n        self.fetch_balance_sheet_data_quarter_concurrent()\n\n        print(f\"Waiting for {delay} seconds to comply with API rate limits...\")\n        time.sleep(delay)\n\n        print(\"Fetching annual cash flow statements...\")\n        self.fetch_cash_flow_data_annual_concurrent()\n\n        print(f\"Waiting for {delay} seconds to comply with API rate limits...\")\n        time.sleep(delay)\n\n        print(\"Fetching quarterly cash flow statements...\")\n        self.fetch_cash_flow_data_quarter_concurrent()\n\n        print(f\"Waiting for {delay} seconds to comply with API rate limits...\")\n        time.sleep(delay)\n\n        print(\"Fetching annual key metrics...\")\n        self.fetch_key_metrics_data_annual_concurrent()\n\n        print(f\"Waiting for {delay} seconds to comply with API rate limits...\")\n        time.sleep(delay)\n\n        print(\"Fetching quarterly key metrics...\")\n        self.fetch_key_metrics_data_quarter_concurrent()<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u4e8c\u3001\u5b9e\u7528\u6848\u4f8b<\/strong><\/h2>\n\n\n\n<p>\u6211\u6700\u8fd1\u8bfb\u5b8c\u4e86\u7b2c\u4e8c\u904d\u672c\u6770\u660e-\u683c\u96f7\u5384\u59c6\uff08Benjamin Graham\uff09\u7684\u540d\u8457\u300a\u806a\u660e\u7684\u6295\u8d44\u8005\u300b\uff08The Intelligent Investor\uff09\u3002\u4ece\u8fd9\u672c\u4e66\u4e2d\u5f97\u5230\u4e86\u7075\u611f\uff0c\u6211\u60f3\u6839\u636e\u683c\u96f7\u5384\u59c6\u6570\uff08Graham Number\uff09\uff0c\u6309\u884c\u4e1a\u548c\u90e8\u95e8\u7ec4\u5408\u68c0\u7d22\u51fa\u4e00\u4efd\u6298\u6263\u6700\u5927\u7684\u80a1\u7968\u5217\u8868\u3002\u9996\u5148\uff0c\u8ba9\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u5bf9\u8c61\u5b9e\u4f8b\uff0c\u7136\u540e\u8c03\u7528 fetch_all_data \u65b9\u6cd5\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>api_key = 'your_api_key_here'\ndata_object = SP500data(api_key = api_key)\ndata_object.fetch_all_data(delay = 45)<\/code><\/pre>\n\n\n\n<p>\u6211\u4eec\u9700\u8981\u5c06\u516c\u53f8\u6982\u51b5\u6570\u636e\u5e27\u4e2d\u7684\u884c\u4e1a\u548c\u90e8\u95e8\u5217\u5408\u5e76\u6210\u4e00\u5217\u65b0\u5217\u3002\u8fd9\u6837\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u6309\u7167\u5404\u81ea\u7684\u884c\u4e1a\u548c\u4ea7\u4e1a\u7ec4\u5408\u5bf9\u80a1\u7968\u8fdb\u884c\u5feb\u901f\u5206\u7ec4\u3002\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a profile_df \u7684\u5355\u72ec\u6570\u636e\u5e27\uff0c\u5b83\u662f\u6211\u4eec\u5f53\u524d\u6570\u636e\u5e27\u7684\u526f\u672c\u3002\u4ece\u5173\u952e\u6307\u6807\u6570\u636e\u4e2d\u68c0\u7d22\u683c\u96f7\u5384\u59c6\u6570\u5b57\uff0c\u5e76\u5c06\u5176\u6dfb\u52a0\u5230 profile_df\u3002<\/p>\n\n\n\n<p>\u6700\u540e\uff0c\u6211\u4eec\u5c06\u521b\u5efa\u4e00\u4e2a\u65b0\u6307\u6807\uff1a\u6700\u65b0\u80a1\u4ef7\u4e0e\u683c\u96f7\u5384\u59c6\u6570\u503c\u4e4b\u95f4\u7684\u5dee\u989d\u3002\u8bf7\u6ce8\u610f\uff0c\u6839\u636e\u672c\u6770\u660e-\u683c\u96f7\u5384\u59c6\u7684\u903b\u8f91\uff0c\u5982\u679c\u8be5\u6570\u5b57\u4e3a\u8d1f\u6570\uff0c\u5219\u8868\u793a\u80a1\u7968\u76ee\u524d\u4ee5\u6298\u6263\u4ef7\u4ea4\u6613\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>profile_df = data_object.company_profile_df\n\nprofile_df&#91;'sector_industry'] = profile_df&#91;'sector'] + '_' + profile_df&#91;'industry']\nprofile_df&#91;'Graham_Number'] = 0\n\nfor symbol in data_object.symbol_list:\n    gn = data_object.key_metrics_data_quarter&#91;symbol].tail(1)&#91;'grahamNumber'].values&#91;0]\n    profile_df.loc&#91;profile_df&#91;'symbol'] == symbol,'Graham_Number'] = gn\n\nprofile_df&#91;'price_gn_delta'] = profile_df&#91;'price'] \/ profile_df&#91;'Graham_Number'] - 1<\/code><\/pre>\n\n\n\n<p>\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a discount_df \u7684\u65b0\u6570\u636e\u6846\uff0c\u5176\u4e2d\u5c06\u5305\u542b\u6bcf\u4e2a\u884c\u4e1a\u548c\u4ea7\u4e1a\u7ec4\u5408\u4e2d\u6298\u4ef7\u7387\u6700\u9ad8\u7684\u80a1\u7968\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>discount_df = profile_df.groupby('sector_industry').apply(\n    lambda x: x.sort_values('price_gn_delta').head(1)).reset_index(drop=True)\n\ndiscount_df.sort_values(by = 'price_gn_delta')<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u4e09\u3001\u89c2\u70b9\u603b\u7ed3<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>FMP API \u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5de5\u5177<\/strong>\uff0c\u53ef\u4ee5\u5e2e\u52a9\u5f00\u53d1\u8005\u3001\u5206\u6790\u5e08\u548c\u6570\u636e\u4e13\u4e1a\u4eba\u58eb\u8f7b\u677e\u8bbf\u95ee\u9ad8\u7ea7\u91d1\u878d\u6570\u636e\u3002<\/li>\n\n\n\n<li><strong>\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\uff08OOP\uff09<\/strong>&nbsp;\u662f\u7ec4\u7ec7\u548c\u91cd\u7528\u4ee3\u7801\u7684\u6709\u6548\u65b9\u6cd5\uff0c\u7279\u522b\u662f\u5728\u5904\u7406\u590d\u6742\u6570\u636e\u5bfc\u5165\u548c\u5206\u6790\u4efb\u52a1\u65f6\u3002<\/li>\n\n\n\n<li><strong>\u5e76\u884c\u7f16\u7a0b<\/strong>&nbsp;\u53ef\u4ee5\u663e\u8457\u63d0\u9ad8\u6570\u636e\u5904\u7406\u901f\u5ea6\uff0c\u5c24\u5176\u662f\u5728\u5904\u7406\u5927\u91cf\u6570\u636e\u65f6\u3002<\/li>\n\n\n\n<li><strong>\u521b\u5efa\u4e00\u4e2a\u5168\u9762\u7684\u6570\u636e\u7c7b<\/strong>\uff08\u5982&nbsp;<code>SP500data<\/code>\uff09\u53ef\u4ee5\u6781\u5927\u5730\u7b80\u5316\u6570\u636e\u83b7\u53d6\u548c\u5206\u6790\u6d41\u7a0b\u3002<\/li>\n\n\n\n<li><strong>\u9075\u5b88 API \u901f\u7387\u9650\u5236<\/strong>&nbsp;\u662f\u4f7f\u7528\u4efb\u4f55 API \u65f6\u7684\u91cd\u8981\u8003\u8651\u56e0\u7d20\uff0c\u4ee5\u907f\u514d\u88ab\u9650\u5236\u8c03\u7528\u3002<\/li>\n\n\n\n<li><strong>\u5b9e\u7528\u6848\u4f8b\u7684\u63d0\u4f9b<\/strong>&nbsp;\u6709\u52a9\u4e8e\u5c55\u793a\u5982\u4f55\u5c06\u7406\u8bba\u77e5\u8bc6\u5e94\u7528\u4e8e\u5b9e\u9645\u95ee\u9898\u89e3\u51b3\u4e2d\u3002<\/li>\n\n\n\n<li><strong>\u6301\u7eed\u66f4\u65b0\u548c\u6539\u8fdb\u4ee3\u7801<\/strong>\uff0c\u6dfb\u52a0\u65b0\u65b9\u6cd5\u548c\u5c5e\u6027\uff0c\u4ee5\u9002\u5e94\u4e0d\u65ad\u53d8\u5316\u7684\u6570\u636e\u9700\u6c42\u548c\u5206\u6790\u6280\u672f\u3002<\/li>\n<\/ul>\n\n\n\n<p><strong>\u672c\u6587\u5b8c\u6574\u6e90\u4ee3\u7801\u5982\u4e0b\uff1a<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nLibraries\n\nfrom concurrent.futures import ThreadPoolExecutor, as_completed\nimport requests\nimport pandas as pd\nimport numpy as np\nfrom tqdm import tqdm\nimport time\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport re\nfrom docx import Document\nfrom docx.shared import Inches\nfrom docx.shared import RGBColor\n     \nData Class\n\nclass SP500data:\n    def __init__(self, api_key):\n        self.api_key = api_key\n\n        ## Symbols and Profiles\n        self.symbol_list = &#91;]\n        self.company_profile_df = None\n\n        ## Price\n        self.price_data = {}\n\n        ## Dividend Data\n        self.dividend_data = {}\n        self.Gordon_Growth_Model_df = None\n\n        ## Financials\n        self.income_statement_data_annual = {}\n        self.balance_sheet_data_annual = {}\n        self.cash_flow_data_annual = {}\n        self.key_metrics_data_annual = {}\n        self.income_statement_data_quarter = {}\n        self.balance_sheet_data_quarter = {}\n        self.cash_flow_data_quarter = {}\n        self.key_metrics_data_quarter = {}\n\n        ## Transcripts\n        self.transcript_dates = {}\n\n    def get_symbols(self):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v3\/sp500_constituent?apikey={self.api_key}'\n        stocks = requests.get(url).json()\n        self.symbol_list = &#91;stock&#91;'symbol'] for stock in stocks]\n\n    def fetch_profile(self, symbol):\n            url = f'https:\/\/financialmodelingprep.com\/api\/v3\/profile\/{symbol}?apikey={self.api_key}'\n            response = requests.get(url).json()\n            return pd.DataFrame(response)\n\n    def fetch_profile_data(self):\n            profile_dfs = &#91;]\n            with ThreadPoolExecutor(max_workers=10) as executor:\n                future_to_symbol = {executor.submit(self.fetch_profile, symbol): symbol for symbol in self.symbol_list}\n                for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                    try:\n                        single_df = future.result()\n                        profile_dfs.append(single_df)\n                    except Exception as exc:\n                        print(f'Exception for {future_to_symbol&#91;future]}: {exc}')\n            self.company_profile_df = pd.concat(profile_dfs, ignore_index=True)\n\n    def fetch_price(self, symbol):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v3\/historical-price-full\/{symbol}?apikey={self.api_key}'\n        response = requests.get(url).json()\n        prices_df = pd.DataFrame(response&#91;'historical'])\n        prices_df = prices_df.sort_values(by='date').reset_index(drop=True)\n        return prices_df\n\n    def fetch_price_data(self):\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_symbol = {executor.submit(self.fetch_price, symbol): symbol for symbol in self.symbol_list}\n            for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                try:\n                    symbol = future_to_symbol&#91;future]\n                    prices_df = future.result()\n                    self.price_data&#91;symbol] = prices_df\n                except Exception as exc:\n                    print(f'Exception for {symbol}: {exc}')\n\n    def fetch_income_statement_annual(self, symbol):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v3\/income-statement\/{symbol}?period=annual&amp;apikey={self.api_key}'\n        response = requests.get(url).json()\n        return pd.DataFrame(response)\n\n    def fetch_income_statement_quarter(self, symbol):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v3\/income-statement\/{symbol}?period=quarter&amp;apikey={self.api_key}'\n        response = requests.get(url).json()\n        return pd.DataFrame(response)\n\n    def fetch_income_statement_data_annual_concurrent(self):\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_symbol = {executor.submit(self.fetch_income_statement_annual, symbol): symbol for symbol in self.symbol_list}\n            for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                try:\n                    symbol = future_to_symbol&#91;future]\n                    income_df = future.result()\n                    self.income_statement_data_annual&#91;symbol] = income_df\n                except Exception as exc:\n                    print(f'Exception for {symbol}: {exc}')\n\n    def fetch_income_statement_data_quarter_concurrent(self):\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_symbol = {executor.submit(self.fetch_income_statement_quarter, symbol): symbol for symbol in self.symbol_list}\n            for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                try:\n                    symbol = future_to_symbol&#91;future]\n                    income_df = future.result()\n                    self.income_statement_data_quarter&#91;symbol] = income_df\n                except Exception as exc:\n                    print(f'Exception for {symbol}: {exc}')\n\n    def fetch_balance_sheet_annual(self, symbol):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v3\/balance-sheet-statement\/{symbol}?period=annual&amp;apikey={self.api_key}'\n        response = requests.get(url).json()\n        return pd.DataFrame(response)\n\n    def fetch_balance_sheet_quarter(self, symbol):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v3\/balance-sheet-statement\/{symbol}?period=quarter&amp;apikey={self.api_key}'\n        response = requests.get(url).json()\n        return pd.DataFrame(response)\n\n    def fetch_balance_sheet_data_annual_concurrent(self):\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_symbol = {executor.submit(self.fetch_balance_sheet_annual, symbol): symbol for symbol in self.symbol_list}\n            for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                try:\n                    symbol = future_to_symbol&#91;future]\n                    balance_df = future.result()\n                    self.balance_sheet_data_annual&#91;symbol] = balance_df\n                except Exception as exc:\n                    print(f'Exception for {symbol}: {exc}')\n\n    def fetch_balance_sheet_data_quarter_concurrent(self):\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_symbol = {executor.submit(self.fetch_balance_sheet_quarter, symbol): symbol for symbol in self.symbol_list}\n            for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                try:\n                    symbol = future_to_symbol&#91;future]\n                    balance_df = future.result()\n                    self.balance_sheet_data_quarter&#91;symbol] = balance_df\n                except Exception as exc:\n                    print(f'Exception for {symbol}: {exc}')\n\n    def fetch_cash_flow_annual(self, symbol):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v3\/cash-flow-statement\/{symbol}?period=annual&amp;apikey={self.api_key}'\n        response = requests.get(url).json()\n        return pd.DataFrame(response)\n\n    def fetch_cash_flow_quarter(self, symbol):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v3\/cash-flow-statement\/{symbol}?period=quarter&amp;apikey={self.api_key}'\n        response = requests.get(url).json()\n        return pd.DataFrame(response)\n\n    def fetch_cash_flow_data_annual_concurrent(self):\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_symbol = {executor.submit(self.fetch_cash_flow_annual, symbol): symbol for symbol in self.symbol_list}\n            for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                try:\n                    symbol = future_to_symbol&#91;future]\n                    cash_flow_df = future.result()\n                    self.cash_flow_data_annual&#91;symbol] = cash_flow_df\n                except Exception as exc:\n                    print(f'Exception for {symbol}: {exc}')\n\n    def fetch_cash_flow_data_quarter_concurrent(self):\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_symbol = {executor.submit(self.fetch_cash_flow_quarter, symbol): symbol for symbol in self.symbol_list}\n            for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                try:\n                    symbol = future_to_symbol&#91;future]\n                    cash_flow_df = future.result()\n                    self.cash_flow_data_quarter&#91;symbol] = cash_flow_df\n                except Exception as exc:\n                    print(f'Exception for {symbol}: {exc}')\n\n    def fetch_key_metrics_annual(self, symbol):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v3\/key-metrics\/{symbol}?period=annual&amp;apikey={self.api_key}'\n        response = requests.get(url).json()\n        return pd.DataFrame(response)\n\n    def fetch_key_metrics_quarter(self, symbol):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v3\/key-metrics\/{symbol}?period=quarter&amp;apikey={self.api_key}'\n        response = requests.get(url).json()\n        return pd.DataFrame(response)\n\n    def fetch_key_metrics_data_annual_concurrent(self):\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_symbol = {executor.submit(self.fetch_key_metrics_annual, symbol): symbol for symbol in self.symbol_list}\n            for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                try:\n                    symbol = future_to_symbol&#91;future]\n                    key_metrics_df = future.result()\n                    self.key_metrics_data_annual&#91;symbol] = key_metrics_df\n                except Exception as exc:\n                    print(f'Exception for {symbol}: {exc}')\n\n    def fetch_key_metrics_data_quarter_concurrent(self):\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_symbol = {executor.submit(self.fetch_key_metrics_quarter, symbol): symbol for symbol in self.symbol_list}\n            for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                try:\n                    symbol = future_to_symbol&#91;future]\n                    key_metrics_df = future.result()\n                    self.key_metrics_data_quarter&#91;symbol] = key_metrics_df\n                except Exception as exc:\n                    print(f'Exception for {symbol}: {exc}')\n\n    def fetch_dividend_data(self, symbol):\n        url = f\"https:\/\/financialmodelingprep.com\/api\/v3\/historical-price-full\/stock_dividend\/{symbol}?apikey={self.api_key}\"\n        response = requests.get(url).json()\n        if 'historical' in response:\n            div_df = pd.DataFrame(response&#91;'historical'])\n            div_df = div_df.sort_values(by='date').reset_index(drop=True)\n            div_df&#91;'year'] = pd.to_datetime(div_df&#91;'date']).dt.year\n            return div_df\n        else:\n            return pd.DataFrame()\n\n    def fetch_dividend_data_concurrent(self):\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_symbol = {executor.submit(self.fetch_dividend_data, symbol): symbol for symbol in self.symbol_list}\n            for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                try:\n                    symbol = future_to_symbol&#91;future]\n                    key_metrics_df = future.result()\n                    self.dividend_data&#91;symbol] = key_metrics_df\n                except Exception as exc:\n                    print(f'Exception for {symbol}: {exc}')\n\n    def fetch_transcript_dates(self,symbol):\n        url = f'https:\/\/financialmodelingprep.com\/api\/v4\/earning_call_transcript?symbol={symbol}&amp;apikey={self.api_key}'\n        response = requests.get(url).json()\n        transcript_df = pd.DataFrame(response)\n        return transcript_df\n\n    def fetch_transcript_dates_concurrent(self):\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_symbol = {executor.submit(self.fetch_transcript_dates, symbol): symbol for symbol in self.symbol_list}\n            for future in tqdm(as_completed(future_to_symbol), total=len(self.symbol_list)):\n                try:\n                    symbol = future_to_symbol&#91;future]\n                    transcript_df = future.result()\n                    self.transcript_dates&#91;symbol] = transcript_df\n                except Exception as exc:\n                    print(f'Exception for {symbol}: {exc}')\n\n    def fetch_individual_stock_transcripts(self,symbol):\n        transcript_dates_df = self.transcript_dates&#91;symbol]\n        transcripts = &#91;]\n\n        for row in transcript_dates_df.index:\n            q = transcript_dates_df.loc&#91;row]&#91;0]\n            y = transcript_dates_df.loc&#91;row]&#91;1]\n            url = f'https:\/\/financialmodelingprep.com\/api\/v3\/earning_call_transcript\/{symbol}?year={y}&amp;quarter={q}&amp;apikey={api_key}'\n            response = requests.get(url).json()\n            transcripts.append(response&#91;0]&#91;'content'])\n\n        transcript_dates_df&#91;'transcripts'] = transcripts\n        return transcript_dates_df\n     <\/code><\/pre>\n\n\n\n<p><em>\u611f\u8c22\u60a8\u9605\u8bfb\u5230\u6700\u540e\uff0c\u5e0c\u671b\u672c\u6587\u80fd\u7ed9\u60a8\u5e26\u6765\u65b0\u7684\u6536\u83b7\u3002\u795d\u60a8\u6295\u8d44\u987a\u5229\uff01\u5982\u679c\u5bf9\u6587\u4e2d\u7684\u5185\u5bb9\u6709\u4efb\u4f55\u7591\u95ee\uff0c\u8bf7\u7ed9\u6211\u7559\u8a00\uff0c\u5fc5\u590d\u3002<\/em><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"has-text-align-center\" id=\"a1c6\">\u672c\u6587\u5185\u5bb9\u4ec5\u9650\u6280\u672f\u63a2\u8ba8\u548c\u5b66\u4e60\uff0c\u4e0d\u6784\u6210\u4efb\u4f55\u6295\u8d44\u5efa\u8bae\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u4f5c\u8005\uff1a\u8001\u4f59\u635e\u9c7c \u539f\u521b\u4e0d\u6613\uff0c\u8f6c\u8f7d\u8bf7\u6807\u660e\u51fa\u5904\u53ca\u539f\u4f5c\u8005\u3002&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/laoyulaoyu.com\/index.php\/2024\/12\/21\/%e9%87%91%e8%9e%8d%e8%be%be%e4%ba%ba%e5%bf%85%e5%a4%87%ef%bc%9a%e6%95%99%e4%bd%a0%e7%94%a8python%e8%bd%bb%e6%9d%be%e7%ae%80%e5%8c%96%e6%95%b0%e6%8d%ae%e5%88%86%e6%9e%90%e6%b5%81%e7%a8%8b%ef%bc%81\/\">Continue reading<span class=\"screen-reader-text\">\u91d1\u878d\u8fbe\u4eba\u5fc5\u5907\uff1a\u6559\u4f60\u7528Python\u8f7b\u677e\u7b80\u5316\u6570\u636e\u5206\u6790\u6d41\u7a0b\uff01<\/span><\/a><\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[5],"class_list":["post-1729","post","type-post","status-publish","format-standard","hentry","category-aiinvest","tag-ai","entry"],"_links":{"self":[{"href":"https:\/\/laoyulaoyu.com\/index.php\/wp-json\/wp\/v2\/posts\/1729","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/laoyulaoyu.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/laoyulaoyu.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/laoyulaoyu.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/laoyulaoyu.com\/index.php\/wp-json\/wp\/v2\/comments?post=1729"}],"version-history":[{"count":1,"href":"https:\/\/laoyulaoyu.com\/index.php\/wp-json\/wp\/v2\/posts\/1729\/revisions"}],"predecessor-version":[{"id":1730,"href":"https:\/\/laoyulaoyu.com\/index.php\/wp-json\/wp\/v2\/posts\/1729\/revisions\/1730"}],"wp:attachment":[{"href":"https:\/\/laoyulaoyu.com\/index.php\/wp-json\/wp\/v2\/media?parent=1729"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/laoyulaoyu.com\/index.php\/wp-json\/wp\/v2\/categories?post=1729"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/laoyulaoyu.com\/index.php\/wp-json\/wp\/v2\/tags?post=1729"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}