尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Python构建投资实证数据工作流:股息率计算与持仓快照

Python构建投资实证数据工作流:股息率计算与持仓快照 案例背景经济学教师投资实证DAY61。这一天的记录里有一个非常典型的场景腾讯中报发布后市场对成长股盈利预期的讨论明显升温稳健派的持仓逻辑被重新审视实际操作上实证账户买入大唐发电601991和中国神华601088。这两个动作放在一起看不是简单的“抄底”或“追涨”而更像一次从成长中枢向高股息红利端的再平衡。这篇文章不打算复述消息面而是把 DAY61 这个实证场景拆成一套可复用的技术工作流用 Python 批量拉取财务和行情数据计算股息率、PB、PE、ROE 等核心指标把买入原因写入交易日志最终生成持仓快照。拿到这套流程后下一次再遇到中报冲击、行业政策变化或个股估值波动都能按同一套步骤完成数据复盘而不是手动贴一堆截图然后凭感觉解释。这套流程适合这几种读者一是正在做个人投资实证、想给每笔交易留下数据依据的人二是持有腾讯、大唐、神华这类标的想在中报季快速批量更新基本面数据的人三是做稳健型持仓管理希望把股息率、ROE、持仓集中度做成固定报表的人。硬性门槛不高一台普通办公电脑就能跑不需要显卡也不需要 GPU 服务器。需要特别提醒的是本文属于实证记录与数据处理方法分享不构成任何投资建议所有代码和参数仅供参考。1. 核心能力速览能力项说明项目类型个人投资实证跟踪与复盘流程案例场景DAY61腾讯中报冲击稳健持仓逻辑买入大唐发电、中国神华核心技术Python、AKShare 数据接口、pandas 指标计算、SQLite 交易日志主要功能批量拉取行情/财务数据计算股息率、PB、PE、ROE记录买卖日志生成持仓快照硬件要求普通 CPU 即可无需独立显卡运行平台Windows / macOS / Linux启动方式命令行运行脚本或用 schedule 配置定时任务是否支持 API数据源提供接口本地脚本按批次调用是否支持批量任务支持按股票池循环更新输出形式CSV、SQLite 数据库、控制台报表适合场景个人投资复盘、财报季批量跟踪、稳健型持仓管理合规边界仅限个人研究不构成投资建议不自动化下单这套能力速览的关键信息是它不是一个自动交易系统而是一个让投资实证“可回看、可计算、可批量更新”的数据底座。DAY61 只是这套底座上的一个案例。2. 适用场景与使用边界这套流程定位很窄但使用频率很高。它首先服务于“投资实证”这件事本身。经济学教师做到 DAY61意味着前面已经跑了几十个交易日的连续记录这种持续记录最怕两件事第一是数据口径前后不一致比如今天用不复权价格、明天用前复权价格股息率就会算乱第二是操作原因记不清时间一长就分不清楚当时到底是基于估值还是基于情绪。用数据库和脚本能同时解决这两个问题。腾讯中报落地后持仓者真正关心的不是新闻标题而是三个可计算的问题自己的持仓估值中枢变了多少、组合里高股息资产的占比够不够、卖出或买入操作是否在数据上站得住脚。本文提供的流程就是把“腾讯中报 → 预期变化 → 调仓买入大唐和神华”这个链条转成可查询、可回看的结构化记录。买大唐和神华的时候至少要在表里写清楚买的是高股息、低估值的防御属性还是补仓能源电力板块的仓位。使用边界也要说清楚。这套流程不适合短线高频交易因为 AKShare 这类公开财经数据接口的延迟和限频支撑不了盘中秒级决策更不适合自动化下单。本文所有代码都不对接券商交易接口也不会把分析结果直接转成交易指令。还有一个容易被忽略的合规边界从数据源获取行情和财报数据后如果要发布到博客、社区或公众号应当遵循数据源的版权要求不能把原始数据打包二次分发。交易记录属于个人敏感信息数据库文件不要公开提交到 GitHub。如果账户涉及他人资金或委托关系更需要明确授权并遵守当地证券法规。3. 环境准备与前置条件本地环境需要准备的东西不多核心是 Python、数据科学库和网络。依赖项建议版本用途Python3.9 及以上运行脚本pandas1.5 及以上数据清洗与指标计算AKShare最新稳定版获取 A 股/港股行情和财务数据SQLAlchemy 或 sqlite3内置即可存储交易记录和持仓快照schedule最新版定时批量更新python-dotenv最新版管理数据源 Token 等配置网络方面只要能访问常用的财经数据接口即可。磁盘占用很小整个项目加上数据文件通常不超过 200MB。这个项目没有固定的 Web 服务端口如果以后接可视化面板再考虑 8000 或 8501 这类端口。需要提前说明一点AKShare 的接口名称和返回字段会随上游页面调整安装时建议锁定版本并定期查看官方更新。本文代码是流程模板不是永久有效的接口字典运行时报错优先检查接口名。4. 安装部署与启动方式下面给出一套完整的本地安装流程。先创建项目目录和虚拟环境再安装依赖。mkdir invest-tracker cd invest-tracker python -m venv venv # Windows 激活 venv\Scripts\activate # macOS / Linux 激活 source venv/bin/activate pip install akshare pandas sqlalchemy schedule python-dotenv建议把环境版本写入 requirements.txt方便后续重建。pip freeze requirements.txt项目目录可以这样组织invest-tracker/ ├── data/ │ ├── 601088.csv │ ├── 601991.csv │ └── 00700.csv ├── scripts/ │ ├── fetch_kline.py │ ├── calc_indicators.py │ └── update_daily.py ├── portfolio.db ├── stock_list.csv └── .envdata/放行情数据scripts/放脚本portfolio.db是 SQLite 数据库stock_list.csv放股票池基础信息。如果不想每次都在命令行敲 Python可以做双击启动。Windows 下写一个start.batecho off cd /d %~dp0 call venv\Scripts\activate.bat python scripts\update_daily.py pause首次运行建议直接执行更新脚本确认股票池里的三只标的能正常取数再往后续逻辑扩展。5. 功能测试与效果验证这一章按功能拆开测。每个功能都给出操作步骤、预期结果和常见排查点。5.1 拉取腾讯与A股标的核心行情数据测试目的确认 AKShare 能正常拿到大唐发电601991、中国神华601088的 A 股日线数据。腾讯是港股代码是 00700港股接口和 A 股接口通常不同需要单独处理。import akshare as ak # 示意代码AKShare 接口版本更新较快请以当前官方文档为准 # 大唐发电 df_600991 ak.stock_zh_a_hist( symbol601991, perioddaily, start_date20240101, end_date20240901, adjustqfq ) print(大唐发电 rows:, len(df_600991)) print(df_600991.tail())预期结果是输出最近若干个交易日的开盘价、收盘价、成交量等字段。如果这里报错先检查接口名是否已更新再检查网络是否正常。港股腾讯类数据建议单独查 AKShare 的港股接口不要在 A 股接口上硬套否则会出现代码失效或数据错乱。5.2 计算稳健持仓核心指标测试目的把行情价格和基本面字段组合起来计算股息率、PB、PE、ROE。下面用一份 CSV 作为输入字段需要提前准备好代码、名称、当前价格、每股分红 DPS、每股净资产 BPS、每股收益 EPS。import pandas as pd df pd.read_csv(stock_list.csv) df[股息率] df[每股分红DPS] / df[当前价格] * 100 df[PB] df[当前价格] / df[每股净资产BPS] df[PE] df[当前价格] / df[每股收益EPS] df[ROE] df[每股收益EPS] / df[每股净资产BPS] * 100 result df.sort_values(股息率, ascendingFalse) print(result.to_string(indexFalse))操作时需要注意字段对齐腾讯的“每股分红DPS”要按港币或人民币口径统一大唐和神华是 A 股使用人民币口径。不同市场放在同一张表里比较时务必先统一币种。预期结果是一张包含股息率、PB、PE、ROE 的排序表。判断成功与否的标准是大唐和神华这类高股息标的的股息率排名明显靠前腾讯则体现出高 ROE、相对低股息率的特征。5.3 买入日志与持仓快照测试目的把 DAY61 的买入操作写入数据库并生成持仓快照。这个功能是整个实证流程的地基。import sqlite3 from datetime import date conn sqlite3.connect(portfolio.db) conn.execute( CREATE TABLE IF NOT EXISTS trades ( id INTEGER PRIMARY KEY AUTOINCREMENT, trade_date TEXT NOT NULL, symbol TEXT NOT NULL, name TEXT, side TEXT, price REAL, shares REAL, reason TEXT ) ) conn.execute( INSERT INTO trades (trade_date, symbol, name, side, price, shares, reason) VALUES (?,?,?,?,?,?,?), ( 2024-08-15, 601991, 大唐发电, BUY, 3.50, 10000, DAY61中报后高股息逻辑验证降低组合波动, ) ) conn.commit() for row in conn.execute(SELECT trade_date, symbol, name, side, price, shares FROM trades): print(row)需要说明的是上面的价格和股数是示意值。实际运行时应替换成真实成交数据同时保留买入理由。预期结果是交易记录插入成功之后可以通过统计函数计算市值占比和持仓集中度。5.4 中报冲击后的复盘维度腾讯中报对稳健派持仓逻辑的冲击常见影响集中在三个维度。第一盈利预期变化。将中报披露的净利润同比增速与财报发布前的一致预期增速对比如果实际增速低于预期意味着基于未来 EPS 的估值中枢要下调这时 PE 的参考价值会改变。第二股东回报变化。腾讯这类互联网公司现金分红和回购政策对股息率有直接影响。中报如果提高分红或扩大回购静态股息率会上升如果资本开支加大、分红收缩股息率会下降。稳健派持仓关注的是“自由现金流能不能支撑分红”。第三组合再平衡。DAY61 买入大唐和神华一个典型动机是用高股息资产的稳定现金流对冲成长股盈利波动。验证这一步的数据方法是把组合中成长股和红利股的权重变化记录下来并定期对比组合整体的股息率和最大回撤。针对大唐和神华复盘时需要关注的数据维度不完全一样。大唐发电这类电力公司的核心跟踪指标是上网电量、电价和燃料成本这些会直接传导到净利润和股息支付能力中国神华这种煤电一体化公司要重点看长协煤比例、分红承诺和 ROE 稳定性。财务数据落地后当前面的calc_indicators.py重新跑一遍如果高股息标的的股息率依然稳定买入逻辑就得到一次数据验证。5.5 判断买入逻辑是否成立的通用标准建议用三个标准衡量一次买入是否与实证逻辑一致股息率是否高于组合现有持仓的中位数且分红来源具备可持续性。买入后组合的行业集中度是否明显上升如果超过预设阈值需要限制仓位。交易日志里是否写清楚了触发条件例如“中报净利润增速低于预期”“股息率超过 4%”这类可验证条件而不是“感觉会涨”。如果三条都符合这笔操作就是流程化决策如果一条都不符合那就说明这次买入更接近情绪驱动需要单独标记避免后续复盘时误认为是策略结果。6. 接口 API 与批量任务AKShare 本质上是通过 HTTP 接口抓取公开财经数据。对个人实证项目来说没必要封装成服务直接写脚本循环调用即可。需要注意限频批量任务加一点随机等待避免请求过密。下面给出一个批量更新股票池的模板import schedule import time import akshare as ak import pandas as pd WATCH_LIST [601088, 601991, 00700] def update_daily(): for symbol in WATCH_LIST: try: # 示意代码实际接口需要按AKShare版本调整 df ak.stock_zh_a_hist( symbolsymbol, perioddaily, start_date20240101, end_date20241231, adjustqfq ) df.to_csv(fdata/{symbol}.csv, indexFalse) print(f{symbol} updated, rows{len(df)}) except Exception as exc: print(f{symbol} error: {exc}) schedule.every().day.at(09:30).do(update_daily) while True: schedule.run_pending() time.sleep(60)这个脚本有一个明显隐患港股 00700 不能直接放在 A 股接口里循环。实际使用时要把港股标的单独走港股接口或者至少增加一个交易所字段在循环里判断市场再选接口。批量任务的工程化建议更新任务必须写日志记录每次更新的起止时间、成功数量、失败标的。对失败标的做重试最多重试两次。把股票池和运行配置分开不要每次改代码。如果数据源返回字段变化先停止任务更新字段映射后再继续。如果后续要做成 Web API 服务可以留一个最小接口入口用 Flask 暴露本地服务from flask import Flask, jsonify import pandas as pd app Flask(__name__) app.route(/api/indicators) def indicators(): df pd.read_csv(stock_list.csv) return jsonify(df.to_dict(orientrecords)) if __name__ __main__: app.run(host127.0.0.1, port8000)这里只返回本地计算结果不接收外部下单指令安全边界更清晰。7. 资源占用与性能观察这个项目不涉及 GPU所以不存在显存占用问题。资源占用主要体现在三个方面CPU、网络、磁盘 IO。单次拉取日线行情AKShare 接口耗时通常在几百毫秒到几秒之间。批量更新 3 到 50 只股票如果每只都重新请求整体耗时会在几分钟以内。CPU 占用率很低pandas 计算几百行数据基本不构成压力。比较值得关注的是网络请求频率公开财经接口通常有限频短时间大量请求容易触发限制或被封。如果要降低请求压力可以只在每周实证更新时拉全量数据平时只增量拉最近几天。增量更新可以减少约九成请求量。磁盘方面SQLite 数据库加 CSV 文件在几十 MB 以下部署在轻量服务器上完全没问题。观察资源占用的方法是在任务运行期间打开系统任务管理器重点看 Python 进程的 CPU 和内存波动。如果发现内存持续上涨优先怀疑数据在循环里反复拼接没有释放建议把每轮处理后的 DataFrame 及时写盘。8. 常见问题与排查方法问题现象可能原因排查方式解决方案AKShare 接口报错接口名或字段升级查看官方文档和更新日志替换为当前版本接口名港股 00700 拉不到数据误用 A 股接口检查代码中的市场判断港股标的走港股接口股息率计算偏差价格未复权币种未统一核对复权字段和币种统一使用前复权价格和人民币口径数据库重复记录重复执行插入脚本查询 trades 表增加唯一约束或先查重再插入定时任务没跑电脑休眠或 Python 进程退出查看日志文件在服务器或常开电脑上部署批量任务被限频请求过于密集查看返回限制提示增加 sleep降低频率收益率口径混乱分红再投逻辑不一致检查计算函数固定收益率口径在代码注释中写明数据源字段缺失股票停牌或新股上市打印原始字段增加字段缺失处理这类问题最常出现在前几次运行。建议每加一个功能先跑通单只股票再扩展到全部股票池。9. 最佳实践与使用建议第一先小参数测试。第一次运行先只拉一个星期数据只算一只股票确认字段对齐后再上全量数据。投资实证记录的最大敌人是脏数据不是代码复杂。第二保留一套最小可运行配置。把stock_list.csv、数据库建表语句、指标计算脚本固定下来每次更新只改数据文件不轻易改计算逻辑。第三交易日志要覆盖操作原因。买大唐和神华时原因写得越具体越好例如“中报后组合股息率低于 3.5%卖出部分高波动成长股买入高股息标的做再平衡”。这种原因在三个月后回看仍然有意义。第四批量任务必须加日志和失败重试。哪怕只是个人项目也要把每次运行结果留档否则定时任务半夜失败第二天早上只能看到一堆旧数据。第五接口服务要限制访问范围。如果开了 Flask 接口绑定127.0.0.1即可不要默认开放到0.0.0.0。数据库文件也不要放在公开目录。第六涉及人脸、声音、版权素材的合规提醒在这里不适用但涉及持仓数据、账户信息和第三方数据源版权时约束反而是最紧的。不要把原始行情数据打包发布不要暴露个人交易明细不要在未授权情况下代客操作。第七发布或商用前要做效果复核。如果这篇实证内容要对外发布所有计算数字都要重新跑一遍重点检查 A 股和港股市场代码、分红币种、复权方式是否一致。10. 总结与下一步DAY61 的实证记录里真正值得复制的东西不是“买入大唐和神华”这个结论而是把“腾讯中报 → 稳健持仓受影响 → 买入高股息资产”这个决策过程变成可计算的数据。先用 AKShare 批量拉行情和财务数据再用 pandas 计算股息率、PB、PE、ROE最后把买入原因写进 SQLite这一整套流程在任何一次调仓中都能复用。如果你准备照这个方向做建议先验证三件事第一AKShare 当前版本的接口是否能正常返回腾讯、大唐、神华的数据第二本地calc_indicators.py能不能算出一张字段完整的指标表第三交易日志和持仓快照是否能稳定写入 SQLite。这三步通过后就可以把 DAY61 这种实证日复盘做成每周固定任务了。最容易踩的坑集中在接口版本和字段对齐。AKShare 接口不是一成不变的遇到报错优先看官方更新腾讯是港股不要强行塞进 A 股接口里。财务字段要统一币种和复权口径否则股息率算出来虚高或虚低复盘结论就会出现偏差。后续的扩展方向可以考虑接入一致预期数据做业绩对比增加收益率回测模块或者用 Grafana 做持仓可视化面板。但核心依然是先保住数据的准确性和可追溯性。下一笔买入之前先让自己的数据库能回答一个问题这笔交易的理由是数据证明过的还是情绪驱动的。本文全部内容均为投资实证记录与数据处理方法分享不构成投资建议。
返回列表