
定期调仓计时器 —— 每季度首个交易日自动输出持仓再平衡清单教学级投资组合管理原型内容包含免责声明和风险提示不荐股、不对接券商、不自动化交易、无任何引流。一、实际应用场景描述在智能证券投资课程中再平衡Rebalancing是投资组合管理的核心教学内容。本程序适用于- 高校量化投资、投资组合管理课程实验- 个人投资者调仓纪律训练- 多资产配置股票 / 债券 / 现金教学- 规则化投资流程演示核心目标- 设定每季度首个交易日为调仓日- 自动检测当前是否为调仓日- 若到达调仓日输出持仓再平衡清单- 强调人工执行不自动下单✅ 不连接券商系统✅ 不执行真实交易✅ 仅作为调仓规则演示工具二、痛点引入真实可感知痛点 表现忘记调仓 “又过了一个季度忘了再平衡”调仓无规律 想起来才调没有固定节奏比例漂移 股票涨多了风险敞口悄悄变大缺乏清单 调仓时手忙脚乱漏调或错调工具过重 专业组合管理系统复杂 需要一个轻量、本地、可解释、可复现的调仓计时工具三、核心逻辑讲解工程视角1️⃣ 数据模型设计TargetPortfolio├── name 标的名称如 沪深300ETF├── ticker 代码├── target_weight 目标权重如 0.4 40%└── current_weight 当前权重由外部更新2️⃣ 调仓日判定规则A 股教学用规则 说明每季度 1 月、4 月、7 月、10 月首个交易日 该月第一个周一教学简化第一个工作日非交易日 跳过顺延至下一交易日高级版实现简化逻辑if 当前月份 in [1, 4, 7, 10]:if 当前日 该月首个交易日:触发调仓3️⃣ 再平衡清单生成逻辑步骤 操作① 读取各标的当前权重② 对比目标权重③ 计算偏离度④ 生成调仓方向增持 / 减持 / 不变⑤ 输出调仓清单4️⃣ 核心公式权重偏离度偏离度 当前权重 − 目标权重调仓方向偏离度 动作 5% 减持 −5% 增持其他 维持不变5️⃣ 设计原则- 只提醒不下单- 规则透明- 可人工覆盖四、Python 模块化代码可直接运行 项目结构rebalancing_timer/│├── main.py├── models.py├── scheduler.py├── rebalancer.py├── reporter.py├── storage.py├── README.md└── DISCLAIMER.md✅ models.py数据建模models.py投资组合持仓数据模型class PortfolioAsset:单个持仓标的def __init__(self, name, ticker, target_weight, current_weight0.0):name: 标的名称ticker: 代码target_weight: 目标权重0–1current_weight: 当前权重0–1self.name nameself.ticker tickerself.target_weight target_weightself.current_weight current_weightdef deviation(self):权重偏离度return self.current_weight - self.target_weightclass Portfolio:投资组合def __init__(self, name, assets):self.name nameself.assets assets✅ scheduler.py调仓日判定scheduler.py每季度首个交易日判定from datetime import datetimeimport calendardef is_rebalance_day(dateNone):判断今天是否为调仓日规则每季度的第一个交易日简化实现取每月第一个工作日if date is None:date datetime.today()# 调仓月份1、4、7、10rebalance_months {1, 4, 7, 10}if date.month not in rebalance_months:return False, 非调仓月份# 找到本月第一个工作日first_day _find_first_workday(date.year, date.month)if date.day first_day:return True, ✅ 今日为调仓日else:return False, f本月调仓日为 {date.month} 月 {first_day} 日def _find_first_workday(year, month):找到指定月份第一个工作日for day in range(1, 8):try:d datetime(year, month, day)# 0–4 代表周一到周五if d.weekday() 5:return dayexcept ValueError:breakreturn 1 # 兜底✅ rebalancer.py再平衡清单生成rebalancer.py持仓再平衡清单生成THRESHOLD 0.05 # 5% 偏离阈值def generate_rebalance_list(portfolio):对比当前权重与目标权重生成调仓清单rebalance_list []total_deviation 0.0for asset in portfolio.assets:deviation asset.deviation()total_deviation abs(deviation)if deviation THRESHOLD:action 减持elif deviation -THRESHOLD:action 增持else:action 维持不变rebalance_list.append({name: asset.name,ticker: asset.ticker,target_weight: round(asset.target_weight * 100, 1),current_weight: round(asset.current_weight * 100, 1),deviation_pct: round(deviation * 100, 1),action: action})return {portfolio: portfolio.name,total_deviation: round(total_deviation * 100, 2),assets: rebalance_list,needs_rebalance: total_deviation THRESHOLD}✅ reporter.py调仓报告输出reporter.py调仓清单与再平衡报告def report(rebalance_result):print(\n * 60)print(f【持仓再平衡清单】)print( * 60)print(f组合{rebalance_result[portfolio]})print(f总偏离度{rebalance_result[total_deviation]}%)if not rebalance_result[needs_rebalance]:print(\n✅ 当前权重偏离较小无需调仓)print( * 60)returnprint(f\n 调仓明细)print(- * 60)print(f{标的:12} {目标:6} {当前:6} {偏离:7} {动作})print(- * 60)for a in rebalance_result[assets]:marker ⚠️ if a[action] ! 维持不变 else print(f{marker} {a[name]:10} f{a[target_weight]:5.1f}% f{a[current_weight]:5.1f}% f{a[deviation_pct]:6.1f}% f{a[action]})print(- * 60)# 统计actions [a for a in rebalance_result[assets] if a[action] ! 维持不变]print(f\n 需调整标的{len(actions)} / {len(rebalance_result[assets])})# 教学提示print(f\n 教学提示)print(- * 60)print(f ① 偏离阈值设定为 ±5%可根据课程需要调整)print(f ② 实际调仓需考虑交易成本与税费)print(f ③ 调仓频率越高 ≠ 效果越好需权衡)print(f ④ 本清单仅供参考请人工确认后执行)print( * 60)✅ storage.py本地存储storage.pyJSON 本地存储import jsonFILE_PATH rebalance_log.jsondef save_log(data):with open(FILE_PATH, w, encodingutf-8) as f:json.dump(data, f, ensure_asciiFalse, indent2)✅ main.py交互入口main.py定期调仓计时器与再平衡清单生成工具from datetime import datetimefrom models import PortfolioAsset, Portfoliofrom scheduler import is_rebalance_dayfrom rebalancer import generate_rebalance_listfrom reporter import reportfrom storage import save_logdef main():print( 定期调仓计时器教学版)print(每季度首个交易日自动输出持仓再平衡清单\n)# 调仓日检测is_rb, msg is_rebalance_day()today datetime.today().strftime(%Y-%m-%d)print(f 今日日期{today})print(f 调仓检测{msg})if not is_rb:print(f\n⏭️ 今日非调仓日无需输出清单)return# 组合配置print(f\n 配置投资组合)portfolio_name input(组合名称如 核心-卫星组合)assets []while True:ticker input(标的代码空结束)if not ticker:breakname input(标的名称)target_w float(input(目标权重如 0.4 表示 40%))current_w float(input(当前权重如 0.5 表示 50%))assets.append(PortfolioAsset(name, ticker, target_w, current_w))if not assets:print(⚠️ 未配置持仓退出)return# 校验权重total_target sum(a.target_weight for a in assets)total_current sum(a.current_weight for a in assets)if abs(total_target - 1.0) 0.01:print(f⚠️ 目标权重之和 {round(total_target * 100, 1)}%不等于 100%)if abs(total_current - 1.0) 0.01:print(f⚠️ 当前权重之和 {round(total_current * 100, 1)}%不等于 100%)portfolio Portfolio(portfolio_name, assets)# 生成再平衡清单result generate_rebalance_list(portfolio)# 输出报告report(result)# 保存日志log_data {date: today,portfolio: portfolio_name,is_rebalance_day: True,result: result}save_log(log_data)print(\n✅ 调仓日志已保存)if __name__ __main__:main()五、README 与使用说明# 定期调仓计时器教学版## 项目说明每季度首个交易日自动检测并输出持仓再平衡清单。## 使用方式bashpython main.py## 调仓规则| 季度 | 调仓月 | 调仓日 ||---|---|---|| Q1 | 1 月 | 第一个工作日 || Q2 | 4 月 | 第一个工作日 || Q3 | 7 月 | 第一个工作日 || Q4 | 10 月 | 第一个工作日 |## 输入示例组合名称核心-卫星组合标的代码510300标的名称沪深300ETF目标权重0.4当前权重0.5## 适用范围- 量化投资课程- 投资组合管理教学- 调仓纪律训练## 注意事项- 不执行真实交易- 不连接券商系统- 使用前请阅读 DISCLAIMER.md六、DISCLAIMER.md免责声明与风险提示# 免责声明与风险提示## 免责声明本程序仅供**教学与科研用途**用于演示再平衡规则与调仓流程。作者不提供任何投资建议不推荐任何证券不承诺任何收益。## 风险提示1. 调仓日判定为简化实现未考虑法定节假日调休2. 偏离阈值 5% 为教学假设非唯一正确答案3. 实际调仓需考虑交易手续费、印花税、滑点等成本4. 高频调仓可能侵蚀收益再平衡摩擦5. 静态权重再平衡 ≠ 最优动态配置策略使用本工具产生的任何后果作者概不负责。七、核心知识点卡片教学向分类 内容Python 类、日期处理、条件分支量化金融 再平衡Rebalancing、权重偏离投资组合 资产配置、目标权重、漂移管理交易纪律 规则化调仓、克服情绪干扰工程思想 调度器与执行器解耦可扩展性 可接入真实交易日历 API八、总结工程师视角这是一个完全中立、去营销化、可教学的原型系统✅ 不鼓吹频繁调仓✅ 不妖魔化偏离✅ 不伪装成智能投顾它真正展示的是如何用 Python 把调仓纪律从模糊的意图变成可定时、可检测、可执行的规则系统核心教学价值场景 数据事实差不多就调吧 无规则的调仓往往过度交易一直不调也行 权重漂移可能让风险悄然失控调仓好麻烦 规则化后调仓只需几分钟本文代码仅供学习与技术交流不构成任何投资建议股市有风险入市需谨慎利用AI解决实际问题如果你觉得这个工具好用欢迎关注长安牧笛