From d468d3c330b26258805e6f639e62e79edc0535cc Mon Sep 17 00:00:00 2001 From: shellway-pc <413209390@qq.com> Date: Wed, 12 Aug 2026 22:21:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E7=8E=B0=E9=87=91?= =?UTF-8?q?=E6=B5=81=E9=87=8F=E8=A1=A8=E5=88=9D=E6=AC=A1=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E7=9A=84=E6=A8=A1=E5=9D=97=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- quantitative_data/importer.py | 69 ++++++++++++++++++++++++++++ quantitative_data/数据批量导入.ipynb | 36 +++++++++++++-- 2 files changed, 101 insertions(+), 4 deletions(-) diff --git a/quantitative_data/importer.py b/quantitative_data/importer.py index 54d592a..40770a0 100644 --- a/quantitative_data/importer.py +++ b/quantitative_data/importer.py @@ -1058,6 +1058,75 @@ def import_cashflow_batch( return success +def import_cashflow_initial( + start_date: str = "2010-01-01", + end_date: str = "2015-12-31", + sleep_interval: float = 0.3, +) -> int: + """ + 首次批量导入现金流量表 (cashflow) - 按报告期全市场循环导入 + - 自动生成 start_date ~ end_date 范围内的所有季度报告期 (0331/0630/0930/1231) + - 每个报告期调用一次 cashflow_vip(period=...) 一次性拉取全市场数据 + - 适用于首次初始化导入;后续增量/修补请用 import_cashflow(period=...) 或 import_cashflow_batch + + 示例: + import_cashflow_initial(start_date="2010-01-01", end_date="2015-12-31") + 内部循环调用: pro.cashflow_vip(period='20100331'), pro.cashflow_vip(period='20100630'), ..., + pro.cashflow_vip(period='20151231'),共 24 个报告期 + + 返回: 累计导入的记录数 + """ + # 解析年份范围 (支持 "2010-01-01" / "20100101" / "2010" 等格式) + start_compact = str(start_date).replace("-", "") + end_compact = str(end_date).replace("-", "") + start_year = int(start_compact[:4]) + end_year = int(end_compact[:4]) + + # 自动生成所有季度报告期 (YYYYMMDD) + periods = [] + for year in range(start_year, end_year + 1): + for month_day in ["0331", "0630", "0930", "1231"]: + period_str = f"{year}{month_day}" + # 过滤掉首尾年份中超出日期范围的报告期 + if period_str < start_compact or period_str > end_compact: + continue + periods.append(period_str) + + if not periods: + logger.warning(f" 日期范围 {start_date} ~ {end_date} 内无报告期") + return 0 + + total = len(periods) + logger.info("=" * 60) + logger.info( + f"[6.3] 首次批量导入现金流量表 (cashflow_vip 按报告期): " + f"{start_date} ~ {end_date}" + ) + logger.info(f" 共 {total} 个报告期: {periods[0]} ~ {periods[-1]}") + + conn = get_pg_connection() + success = 0 + fail_list = [] + for i, period in enumerate(periods, 1): + try: + n = import_cashflow(period=period, conn=conn) + success += n + except Exception as e: + logger.warning(f" [{period}] 现金流量表导入失败: {e}") + fail_list.append(period) + conn.rollback() + + if i % 5 == 0 or i == total: + logger.info(f" 进度: {i}/{total}, 累计导入 {success} 条") + time.sleep(sleep_interval) + + conn.close() + logger.info(f" 首次现金流量表批量导入完成: 成功 {success} 条") + if fail_list: + logger.warning(f" 失败报告期({len(fail_list)}): {fail_list}") + return success + + # ============================================================ # 7. 导入指数日线行情 # ============================================================ diff --git a/quantitative_data/数据批量导入.ipynb b/quantitative_data/数据批量导入.ipynb index a0be129..5a5417c 100644 --- a/quantitative_data/数据批量导入.ipynb +++ b/quantitative_data/数据批量导入.ipynb @@ -94,6 +94,7 @@ " import_financial_statements,\n", " import_cashflow,\n", " import_cashflow_batch,\n", + " import_cashflow_initial,\n", " import_index_daily,\n", " get_all_stock_codes,\n", " get_stock_codes_from_db,\n", @@ -525,11 +526,38 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### 7.1 单独导入现金流量表 (cashflow_vip VIP 接口)\n", + "### 7.1 单独导入现金流量表 (cashflow_vip VIP 接口)\n", + "\n", + "`import_cashflow` 使用 Tushare VIP 接口 `cashflow_vip`,支持两种方式:\n", + "- 按报告期全市场导入: `import_cashflow(period=\"20181231\")`,对应示例 `df2 = pro.cashflow_vip(period='20181231', fields='')`\n", + "- 按股票导入: `import_cashflow(ts_code=\"000001.SZ\", start_date=..., end_date=...)`,或批量 `import_cashflow_batch(stock_list, ...)`" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 方式A2: 首次批量导入 (推荐初始化数据)\n", "\n", - "`import_cashflow` 使用 Tushare VIP 接口 `cashflow_vip`,支持两种方式:\n", - "- 按报告期全市场导入: `import_cashflow(period=\"20181231\")`,对应示例 `df2 = pro.cashflow_vip(period='20181231', fields='')`\n", - "- 按股票导入: `import_cashflow(ts_code=\"000001.SZ\", start_date=..., end_date=...)`,或批量 `import_cashflow_batch(stock_list, ...)`" + "`import_cashflow_initial` 自动生成日期范围内的所有季度报告期 (0331/0630/0930/1231),\n", + "每个报告期调用一次 `cashflow_vip(period=...)` 一次拉取全市场数据。\n", + "\n", + "以下示例一次导入 **2010年1月1日 ~ 2015年12月31日** 共 24 个报告期的所有上市公司现金流量表数据。" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# 首次批量导入: 一次导入 2010-01-01 到 2015-12-31 的所有上市公司现金流量表\n", + "# 自动循环 24 个季度报告期 (20100331 ~ 20151231),每个报告期拉取全市场数据\n", + "import_cashflow_initial(\n", + " start_date=\"2010-01-01\",\n", + " end_date=\"2015-12-31\",\n", + " sleep_interval=0.3,\n", + ")" ] }, {