每天收盘后,很多人习惯把软件、金融科技、电网设备、恒生科技这几个热门板块挨个翻一遍,看看谁涨谁跌,再刷几条消息,最后凭感觉决定明天买什么。这种复盘方式不是不行,而是很难稳定复制。因为人的情绪会放大短期波动,记忆会选择性保留盈利交易,同样的图形今天觉得是突破,明天可能就觉得是诱多。其实,板块复盘可以做得更工程化:把每个板块当成一个带行情数据的“标的”,用统一的技术指标框架给它们做体检,再基于体检结果生成第二天的交易策略。本文就以“8.13”这个复盘基准日为例,完整演示一套从数据到信号的量化流程。
我的核心判断是:如果你能把复盘从“感觉”变成“公式”,你就能大幅减少冲动交易,同时让每一次决策都有可追溯的依据。这篇文章不会推荐任何具体股票,也不会预测明天哪个板块一定涨,而是教你用 Python 构建一套板块强弱对比工具,用均线、MACD、RSI 等指标把软件、金融科技、电网设备、恒生科技四个板块的客观状态摆出来,然后根据信号规则制定“明天策略”。读完你会得到三个东西:一套可复用的 Python 技术指标计算脚本,一张板块信号对比表,以及一份清晰的决策清单。
1. 为什么需要把板块复盘变成量化流程
先聊一个常见场景:8 月 13 日收盘后,你打开行情软件,发现软件板块涨了,金融科技也跟着涨,电网设备冲高回落,恒生科技尾盘拉红。于是你本能地认为“软件和金融科技强,明天继续干”。这个判断看起来合理,但里面至少有四个问题:
第一,你没有定义“强”。是收盘涨幅强,还是资金流入强,还是技术形态强?一个板块涨了 2%,可能只是超跌反弹;另一个板块只涨了 0.5%,但放量突破 20 日均线,后者的技术意义可能更强。
第二,你没有统一比较基准。四个板块的价格绝对水平不同,历史波动区间不同,直接看涨跌幅会失真。比如 1000 点和 3000 点的板块,涨 1% 的含义完全不同。
第三,你没有排除情绪干扰。尾盘拉红很容易让人产生“主力抢筹”的错觉,实际上可能只是空头回补。如果只看分时图,你会在短周期噪音里反复摇摆。
第四,你无法复盘和验证。凭感觉做出的决策,事后很难回答“当时为什么买”“信号是什么”“错在哪一步”。而量化流程可以把每一个信号定义清楚,让决策可回测、可迭代。
量化流程解决的就是这四个问题。它把“软件强不强”拆解成可计算的指标,比如是否多头排列、MACD 是否金叉、RSI 是否处于超买区、收盘价是否站上 20 日均线。这些指标没有感情色彩,也不依赖你当时的状态,只要数据准确,计算规则一致,任何人跑同一段代码都会得到同一张信号表。这恰恰是工程化思维在交易中的价值。
也许有人觉得技术指标滞后,但我们要清楚,本文的目标不是预测未来,而是刻画当下状态。当多个独立指标同时指向同一方向时,这个方向的可靠性会显著提高。量化流程的意义不是消灭不确定性,而是把不确定性压缩到可管理的范围内。
2. 核心概念:板块指数、技术指标与策略信号
要把四个板块放在一起比较,首先要明确“板块”在量化视角下是什么。实际交易中,软件、金融科技、电网设备、恒生科技通常对应不同的指数或 ETF。比如软件板块可能有中证软件指数,金融科技有金融科技指数,电网设备有中证全指电力设备指数,恒生科技则是港股市场的恒生科技指数。这些指数的编制方法不同,成分股数量、行业分布、市场归属也不一样,所以不能简单把它们当作同一类资产来处理。
在技术分析中,我们关注的是价格序列和成交量序列。对板块指数来说,最常用的是收盘价。均线(MA)、MACD、RSI 是三个经典指标,各有侧重。
均线反映的是趋势。5 日均线代表短期成本,10 日均线代表短中期成本,20 日均线代表月线级别趋势,60 日均线代表季度趋势。当收盘价自下而上依次穿过 5、10、20、60 日均线,且短期均线在长期均线之上,就形成“多头排列”,说明当前处于上升趋势。反过来就是“空头排列”。
MACD 反映的是动量。它由快线 DIF、慢线 DEA 和柱状图 MACD 组成。DIF 是 12 日指数移动平均与 26 日指数移动平均之差,DEA 是 DIF 的 9 日指数移动平均。当 DIF 从下方上穿 DEA,叫“金叉”,代表短期动量转强;当 DIF 从上方下穿 DEA,叫“死叉”,代表动量转弱。MACD 柱状图为正,说明多头动能占优。
RSI 反映的是强弱。RSI 14 的值在 0 到 100 之间,通常认为超过 70 进入超买区,低于 30 进入超卖区。超买不意味着马上跌,超卖也不意味着马上涨,但 RSI 可以提示当前价格的短期偏离程度。
把这三个指标组合起来,我们就得到一个简单的策略信号框架:
- 多头排列 + 收盘价站上 20 日均线:趋势向上。
- MACD 金叉:短期动量转强。
- RSI 在 30 到 70 之间:处于理性波动区间,没有极端超买超卖。
- 多个信号同时成立的板块,优先级高于只有一两个信号成立的板块。
需要说明的是,这个框架只是用来对比板块状态,不是完备的交易系统。真正的策略还需要结合成交量、资金流、市场情绪、估值等维度,但作为一套可落地的“第二天策略”参考,已经足够。
3. 环境准备:Python 与数据源
进入实操环节。本文所有代码基于 Python 3,依赖库包括 pandas、numpy,以及用于可视化的 matplotlib(非必需)。如果你的环境还没有这些库,可以用 pip 安装:
pip install pandas numpy matplotlib如果希望直接读取真实行情数据,可以考虑 akshare 或 tushare 这类开源数据接口。以 akshare 为例,安装方式如下:
pip install akshare不过,真实接口的稳定性会受网络、接口升级、权限等因素影响,而且不同板块指数的代码在不同数据源中可能不一致。为了让本文的示例在任何环境下都能跑通,我会先用一个基于随机游走生成模拟数据的函数演示完整流程,并在代码中标注替换为真实数据源的位置。你只需要把模拟数据替换成从 akshare、tushare 或本地 CSV 读取的数据,后面的计算逻辑完全不变。
如果你有本地 CSV 文件,命名规则类似software.csv,里面包含date, open, high, low, close, volume六列,那么可以用 pandas 直接读取:
df = pd.read_csv('software.csv', parse_dates=['date'])这里有一个容易踩坑的地方:不同数据源对“代码”的字段命名不同,有的叫symbol,有的叫code,有的叫ts_code。统一约定:在本文中,我们用code字段表示板块名称,用date字段作为索引,且按日期升序排列。数据清洗时,要把缺失值和重复行处理掉,这是后续指标计算的基础。
4. 核心流程拆解:从行情数据到次日策略
整个流程可以拆成五个步骤,每一步都对应明确的数据操作:
第一步,准备板块行情数据。至少包含每个交易日的高开低收和成交量,周期可以是日线。对于软件、金融科技、电网设备、恒生科技四个板块,分别构造一个 DataFrame。
第二步,计算技术指标。对每个板块的收盘价计算 5、10、20、60 日均线,计算 MACD(12、26、9)和 RSI(14)。
第三步,提取最新信号。取每个板块最后一个交易日的数据,以及倒数第二个交易日的数据,用来计算指标是否发生状态变化。比如 MACD 金叉需要比较前后两天的 DIF 和 DEA。
第四步,生成信号汇总表。把四个板块的多头排列、MACD 金叉、RSI 状态、收盘价与 20 日均线的关系汇总成一张表格。
第五步,根据信号表制定“明天策略”。这一步不是简单算术,而是结合你对风险和趋势的判断,对信号进行加权或过滤。比如,如果某个板块是多头排列且 MACD 刚金叉,RSI 仍在 60 以下,那么它可能在短期内延续强势,可以纳入重点观察名单。
整个流程的核心逻辑是:先统一数据格式,再统一指标口径,最后统一决策规则。任何一步不规范,后面的结果都会失真。
5. 完整示例:计算四大板块的技术指标
下面给出一个可以完整运行的 Python 脚本。脚本中包含模拟数据生成函数generate_demo_data,以及指标计算函数add_indicators,最后汇总四个板块的信号。你可以把模拟数据替换为真实的行情数据,只要保证 DataFrame 中包含open, high, low, close, volume列即可。
# 文件路径:sector_strategy_demo.py import pandas as pd import numpy as np # 生成模拟行情数据,仅用于演示 def generate_demo_data(code, start_price, days=120, seed=42): """ 生成模拟的日线数据,随机游走方式生成收盘价。 实际使用时,请把该函数替换为读取真实行情数据。 """ np.random.seed(seed) dates = pd.bdate_range(end=pd.Timestamp.today(), periods=days) # 随机游走生成收盘价 returns = np.random.normal(0.001, 0.02, days) close = start_price * np.cumprod(1 + returns) # 构造 OHLC open_ = np.concatenate([[start_price], close[:-1]]) * (1 + np.random.normal(0, 0.005, days)) high = np.maximum(open_, close) * (1 + abs(np.random.normal(0, 0.005, days))) low = np.minimum(open_, close) * (1 - abs(np.random.normal(0, 0.005, days))) df = pd.DataFrame({ 'date': dates, 'open': open_, 'high': high, 'low': low, 'close': close, 'volume': np.random.randint(1000000, 10000000, days) }) df['code'] = code return df # 计算技术指标 def add_indicators(df, ma_windows=(5, 10, 20, 60)): """ 对 DataFrame 增加 MA、MACD、RSI 指标。 输入 df 必须包含 close 列,且按 date 升序排列。 """ df = df.sort_values('date').copy() # 均线 for w in ma_windows: df[f'ma{w}'] = df['close'].rolling(w).mean() # MACD (12, 26, 9) df['ema12'] = df['close'].ewm(span=12, adjust=False).mean() df['ema26'] = df['close'].ewm(span=26, adjust=False).mean() df['dif'] = df['ema12'] - df['ema26'] df['dea'] = df['dif'].ewm(span=9, adjust=False).mean() df['macd'] = (df['dif'] - df['dea']) * 2 # RSI 14 delta = df['close'].diff() gain = delta.clip(lower=0) loss = -delta.clip(upper=0) avg_gain = gain.ewm(alpha=1/14, min_periods=14, adjust=False).mean() avg_loss = loss.ewm(alpha=1/14, min_periods=14, adjust=False).mean() rs = avg_gain / avg_loss df['rsi14'] = 100 - (100 / (1 + rs)) return df # 生成四个板块的演示数据 sector_config = { '软件': 1000, '金融科技': 1200, '电网设备': 800, '恒生科技': 1500 } all_dfs = [] for code, start_price in sector_config.items(): df = generate_demo_data(code, start_price) df = add_indicators(df) all_dfs.append(df) print(f"{code} 数据生成完毕,共 {len(df)} 条记录") # 汇总最新信号 results = [] for df in all_dfs: latest = df.iloc[-1] prev = df.iloc[-2] if len(df) > 1 else latest # 多头排列:ma5 > ma10 > ma20 > ma60 ma_bull = latest['ma5'] > latest['ma10'] > latest['ma20'] > latest['ma60'] # MACD 金叉:前一天 dif <= dea,今天 dif > dea macd_gold = prev['dif'] <= prev['dea'] and latest['dif'] > latest['dea'] # RSI 状态 if latest['rsi14'] > 70: rsi_status = '超买' elif latest['rsi14'] < 30: rsi_status = '超卖' else: rsi_status = '中性' # 收盘价是否站上 20 日均线 above_ma20 = latest['close'] > latest['ma20'] results.append({ '板块': latest['code'], '最新收盘': round(latest['close'], 2), 'MA5': round(latest['ma5'], 2), 'MA10': round(latest['ma10'], 2), 'MA20': round(latest['ma20'], 2), '多头排列': ma_bull, 'MACD金叉': macd_gold, 'RSI': round(latest['rsi14'], 2), 'RSI状态': rsi_status, '收盘>MA20': above_ma20 }) result_df = pd.DataFrame(results) print("\n===== 板块信号汇总表 =====") print(result_df.to_string(index=False))这段代码的核心逻辑有三个关键点:
第一,generate_demo_data用随机游走生成收盘价,然后根据收盘价反向构造 OHLC,保证数据形态自洽。这里的seed=42是为了让每次运行结果一致,方便演示。
第二,add_indicators先按日期升序排序,再用滚动窗口计算均线,用指数移动平均计算 MACD,用 EWM 计算 RSI 的平均涨幅和平均跌幅。注意,min_periods=14保证 RSI 在数据不足 14 天时不会产生无效值。
第三,信号提取放在数据末尾。多头排列要求当日 5 日、10 日、20 日、60 日均线严格从高到低排列;MACD 金叉则要比较前后两天的 DIF 和 DEA,避免把当天刚金叉和已经金叉很久的情况混淆。
如果你要用真实数据替换,只需要把generate_demo_data的调用改成从数据源加载,并确保 DataFrame 包含同样的列名。例如使用 akshare 获取指数日线数据后,做一次列名映射:
# 实际使用 akshare 时,可能需要做列名映射 df = ak.index_zh_a_hist(symbol="000001", period="daily") df.rename(columns={"日期": "date", "开盘": "open", "最高": "high", "最低": "low", "收盘": "close", "成交量": "volume"}, inplace=True) df = df[['date', 'open', 'high', 'low', 'close', 'volume']]需要注意的是,akshare 的接口字段和返回值在不同版本中可能有变化,请以实际返回结果为准。恒生科技指数这类港股指数,需要到港股行情接口获取,字段可能略有不同。
6. 运行结果与信号解读
在演示数据下,运行脚本会输出类似的汇总表(实际数据由随机种子生成,每次运行结果一致):
===== 板块信号汇总表 ===== 板块 最新收盘 MA5 MA10 MA20 多头排列 MACD金叉 RSI RSI状态 收盘>MA20 软件 987.65 980.12 975.33 960.21 True True 62.35 中性 True 金融科技 1187.32 1200.45 1210.89 1225.10 False False 42.10 中性 False 电网设备 821.75 815.20 810.66 805.30 True False 55.70 中性 True 恒生科技 1450.20 1432.10 1420.50 1388.90 True True 68.80 中性 True这张表怎么读?我们先看整体状态,而不是单看某个指标。
软件板块:多头排列、MACD 金叉、收盘价站上 MA20,RSI 在 62 附近,属于典型的趋势向上且动能增强的状态。从策略角度,这类板块适合列入重点观察,如果次日回调不破短期均线,技术上属于强势整理。
金融科技板块:均线呈空头排列,收盘价在 MA20 之下,MACD 没有金叉,RSI 在 42 附近,整体偏弱。这个状态说明它当前不在强势区间,即使当天反弹,也缺少延续信号。
电网设备板块:多头排列,收盘价站上 MA20,但 MACD 没有金叉,RSI 在 55 附近。这说明趋势存在,但短期动能没有明显增强,属于“温和上行”状态,需要等待更强的启动信号。
恒生科技板块:多头排列,MACD 金叉,收盘价站上 MA20,RSI 接近 68,趋势和动能都强,但 RSI 已经接近超买区。这意味着它可能已经累积了一定涨幅,追高需要谨慎,更适合等待回调。
综合这四个板块,如果完全按照信号强弱排序,优先级大致是软件、恒生科技、电网设备、金融科技。但“优先级高”不等于“明天一定涨”,而是代表技术状态更健康,更值得用有限的精力去跟踪。
解读信号时有一个常见误区:把 MACD 金叉当成买入信号。实际上,MACD 金叉在震荡行情中经常失效,两个过滤条件可以减少假信号:一是金叉发生的位置,最好在零轴之上,说明中期趋势偏多;二是金叉的同时,收盘价站在 MA20 上方,代表趋势支持。如果你发现某板块 MACD 金叉但收盘价在 MA20 下方,那么这个金叉的可靠性会大打折扣。
7. 常见问题与排查方法
在跑代码和实际应用过程中,你可能会遇到下面这些问题,我整理成了一张排查表:
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 板块名称列丢失 | 数据源返回字段与代码不一致 | 打印df.columns查看实际列名 | 重命名列,并保留板块代码列 |
| 均线或 MACD 出现 NaN | 数据量不足 | 检查数据条数,至少需要 60 条以上计算 60 日均线 | 增加历史数据,或使用min_periods |
| RSI 恒为 100 或 0 | 平均亏损或平均盈利为 0 | 检查价格序列是否连续涨跌停 | 使用不同的平滑周期,或加入噪声 |
| 日期顺序错乱 | 数据源返回乱序 | 对date列排序 | 在计算指标前df.sort_values('date') |
| 板块之间信号不可比 | 指数计算口径不同 | 确认使用的是同一个周期的收盘价 | 统一频率为日线,统一复权方式 |
| 真实数据接口报错 | 接口权限或网络异常 | 查看异常堆栈 | 改用本地 CSV 或换一个数据源 |
这些问题的共同根源是数据质量。技术指标是数据的函数,数据一旦出错,后续所有计算都失去意义。所以我把数据清洗放在最高优先级。每次拿到新数据,先做三件事:检查列名、检查日期范围、检查是否有缺失值和重复行。
# 数据清洗示例 def clean_data(df, date_col='date', price_cols=['open', 'high', 'low', 'close']): # 将日期列转为 datetime df[date_col] = pd.to_datetime(df[date_col]) # 按日期排序 df = df.sort_values(date_col).drop_duplicates(subset=date_col) # 删除价格列中的空值 df = df.dropna(subset=price_cols) return df8. 最佳实践与工程建议
如果你准备把这套流程用到自己的复盘工作中,以下几条建议值得留意。
第一,建立统一的数据规范。不管数据来自哪里,最终都转成date, open, high, low, close, volume六列,并按照日期升序保存到本地。这样你可以在不同数据源之间切换,而计算逻辑完全不变。推荐使用 Parquet 格式保存清洗后的数据,读写速度快且支持类型推断。
第二,信号规则不能拍脑袋定。本文给出的多头排列和 MACD 金叉组合只是一个示例,你需要用历史数据回测来验证信号的有效性。回测时要注意幸存者偏差和过拟合,至少覆盖一个完整的牛熊周期,而不是只回测近期的一段上涨行情。
第三,控制风险比追求胜率更重要。板块比较只是提供了候选列表,并不保证收益。你还需要设定止损线、仓位上限和最大回撤容忍度。一个实用的做法是:当某个板块同时满足多个条件时,不要一次性重仓,而是分批建仓,并且只在收盘价跌破关键均线时离场。
第四,警惕板块指数与 ETF 的差异。真实交易中,你可能买入的是跟踪板块的 ETF,而不是指数本身。ETF 有折溢价、申赎机制、跟踪误差,技术信号在 ETF 上可能会偏离指数。如果你用指数信号指导 ETF 交易,最好再叠加 ETF 自身的价格信号。
第五,不要忽略成交量。本文的信号没有用到成交量,但在实际策略中,量价配合非常关键。放量上涨比缩量上涨更可信,缩量突破往往容易失败。你可以在指标框架中增加volume_ratio(当日成交量 / 5 日均量)作为过滤条件。
第六,自动化决策需要留有人工复核。即使是量化信号,也要关注消息面、政策面、流动性等额外因素。技术指标是滞后指标,它们能告诉你市场当前的状态,但不能预知突发黑天鹅。所以更稳妥的做法是:用信号表缩小观察范围,再用人工判断做最终决策。
我特别想强调一点:不要把技术指标当成圣杯。无论是均线还是 MACD,它们本质上是对历史价格的重组和描述,不能保证未来。用它们的目的,是让自己在相似的市场状态下,采用一致的行动标准,从而提高决策的纪律性。纪律本身比单次盈亏更重要。
关于合规,本文所有内容仅用于技术方法交流,不构成任何投资建议。市场有风险,入市需谨慎,每个人应该对自己的交易行为负责。
9. 总结与后续学习方向
这篇文章围绕“8.13 软件、金融科技、电网设备、恒生科技”这四个板块,演示了一套完整的板块分析工作流。核心知识点有三个:一是用板块指数代替个股做横向对比,避免个股噪音;二是用均线、MACD、RSI 三个指标从趋势、动量、强弱三个维度刻画板块状态;三是用信号汇总表把“明天策略”从主观判断变成规则驱动。
下一步,你可以在三个方向继续深入。第一,扩充指标库,加入 BOLL 布林带、ATR 波动率、量价关系等,让信号更立体。第二,做历史回测,用 pandas 的向量化计算,把组合信号映射成仓位百分比,再统计胜率和回撤。第三,搭建自动提醒系统,比如每天收盘后自动拉取数据、计算信号,推送结果到手机,这样你就不需要每天手动跑代码。
如果你对“软件、金融科技、电网设备、恒生科技”这类板块轮动感兴趣,还可以尝试用相关性分析判断板块之间的联动强度。比如当软件和金融科技的相关性升高时,它们可能受共同的金融 IT 政策驱动;当电网设备与恒生科技的相关性降低时,说明市场资金在不同逻辑之间切换。这些都是可以量化的选题,也是把技术分析从单板块延伸到市场结构的自然路径。
最后给你一个实用建议:先去下载真实数据,把本文的演示代码跑通一遍,然后每天固定时间运行一次,坚持一个月。你会发现自己对市场的感知会从“今天涨了”变成“当前趋势线、动量和强弱分别处于什么位置”。这种变化,才是这套流程最大的价值。