基于 Martin J. Pring,Technical Analysis Explained(第五版,2014年)
Martin J. Pring 是全球最受欢迎的技术分析教育者之一。他创立了 Pring Research 和《跨市场评论》通讯,撰写了十几本著作,并在技术分析会议上担任主讲人超过四十年。他的工作填补了古典图表分析、动量分析和跨市场关系之间的空白——这种组合使 Technical Analysis Explained 成为该学科最全面的单卷本著作之一。
第一版发行于1979年。第五版(2014年)将原作扩展至800多页,融合了数十年来对 Pring 指标和周期模型的完善。该书自创立以来一直是 CMT(特许市场技术分析师)考试的標準教材。
Pring 的核心论点建立在三个支柱之上:
1. 市场按商业周期驱动运行。
债券、股票和商品按可预测的顺序见顶和见底。
2. 趋势识别是首要任务。
每个指标——移动平均线、动量振荡器、成交量指标——
都旨在回答一个问题:当前趋势的方向是什么?
3. 多个时间周期和指标的确认减少了假信号。
没有任何单一指标能够单独可靠。趋势延续或反转的概率
取决于从价格、动量、成交量和广度中收集的证据权重。
Pring 并未承诺一个消除判断的机械系统。他提供了一个结构化框架,将海量市场数据组织成可操作的结论。
Pring 坚持认为每项分析必须指定所考虑的时间周期:
| 时间周期 | 典型持续时间 | 主要工具 |
|---|---|---|
| 短期 | 3–6 周 | 日线图、短期 KST |
| 中期 | 6 周 – 9 个月 | 周线图、中期 KST |
| 长期 | 9 个月 – 2+ 年 | 月线图、长期 KST |
日线图上的看涨信号发生在看跌的中期趋势内,可靠性远低于与中期和长期趋势一致信号。Pring 称此原则为 主趋势的方向是最重要的单一因素。
Pring 反复强调不应单独使用任何指标。他的方法汇总了多个独立来源的信号:
证据类别:
- 价格趋势(移动平均线方向、趋势线完整性)
- 动量(KST、RSI、MACD、ROC——背离和交叉)
- 成交量(确认价格走势、检测派发/吸筹)
- 广度(涨跌线、新高与新低)
- 相对强度(板块轮动、领涨股分析)
- 跨市场(商业周期内债券/股票/商品的序列)
当这些类别中的大多数一致时,正确交易的概率显著提高。Pring 称这种汇聚为"证据权重"——该短语在全书出现了数十次。
Pring 对技术分析最独特的贡献是他的六阶段市场周期模型,该模型绘制了债券、股票和商品在商业周期中的顺序行为。该模型基于一个简单观察:每个资产类别在不同的阶段对商业周期做出反应。
商业周期序列(理想化):
经济收缩 → 债券最先见底(利率下降有利于债券)
经济仍然疲弱 → 股票其次见底(折现未来复苏)
经济复苏 → 商品最后见底(实际需求回升)
经济扩张 → 债券最先见顶(利率上升损害债券)
经济仍然强劲 → 股票其次见顶(折现未来放缓)
经济过热 → 商品最后见顶(需求最后冲刺)
这一序列产生六个截然不同的阶段,每个阶段由哪些资产类别上涨或下跌来定义。
阶段1:只有债券上涨。股票和商品仍在下跌。
→ 经济处于衰退。利率正在下降。
→ 债券已经见底并转向上涨。股票和商品尚未响应。
阶段2:债券和股票都在上涨。商品仍在下跌。
→ 经济开始复苏。流动性正在改善。
→ 股票已经见底并加入债券的上涨趋势。
阶段3:债券、股票和商品都在上涨。
→ 经济处于全面复苏。这是看涨阶段。
→ 商品已经见底并加入反弹。
阶段4:只有股票和商品在上涨。债券已经见顶并下跌。
→ 经济正在扩张。通胀压力正在积累。
→ 利率上升正在损害债券。股票仍从盈利增长中受益。
阶段5:只有商品在上涨。债券和股票都在下跌。
→ 经济过热。通胀加速。
→ 股票已经见顶。债券继续下跌。
阶段6:三者都在下跌。
→ 经济正在收缩。这是看跌阶段。
→ 商品终于见顶。衰退正在进行或即将到来。
Pring 使用长期 KST 指标(见第3节)应用于每个资产类别,以确定该类别是处于上涨还是下跌趋势。操作规则如下:
资产类别处于上涨的条件:
- 其长期 KST 在信号线上方,或
- 其长期 KST 正在上升且已穿越零轴上方
资产类别处于下跌的条件:
- 其长期 KST 在信号线下方,或
- 其长期 KST 正在下降且已穿越零轴下方
通过对三个资产类别(债券、股票、商品)分别分类为上涨或下跌,可以从六阶段框架中识别当前阶段。
| 阶段 | 债券 | 股票 | 商品 | 最优策略 |
|---|---|---|---|---|
| 1 | 涨 | 跌 | 跌 | 买入债券。回避股票。回避商品。 |
| 2 | 涨 | 涨 | 跌 | 积极买入股票。持有债券。 |
| 3 | 涨 | 涨 | 涨 | 持有所有品种。最大看涨敞口。 |
| 4 | 跌 | 涨 | 涨 | 卖出债券。谨慎持有股票。买入商品。 |
| 5 | 跌 | 跌 | 涨 | 卖出股票。持有商品。做空债券。 |
| 6 | 跌 | 跌 | 跌 | 持现金。防御姿态。等待阶段1。 |
Pring 用时钟类比来可视化周期:
12点钟 = 阶段3(一切都在上涨,乐观情绪峰值)
6点钟 = 阶段6(一切都在下跌,悲观情绪峰值)
10-11点钟 = 阶段2(股票加入债券的反弹)
1-2点钟 = 阶段4(债券见顶,通胀上升)
3-4点钟 = 阶段5(股票见顶,商品仍强劲)
7-8点钟 = 阶段1(债券筑底,衰退)
周期不是机械定时的——阶段可以持续数周或数年取决于经济状况——但序列在数十年的数据中非常一致。
KST(确定无疑)是 Pring 的标志性指标,也是他对技术分析最原创的贡献。其目的是通过结合不同回溯期的多个变化率(ROC)来识别给定时间周期的趋势。
核心洞察:单个 ROC 振荡器嘈杂且产生许多鞭毛效应。通过组合四个不同长度的 ROC 计算并对较长的赋予更大权重,KST 过滤短期噪音同时仍能对真正的趋势变化做出反应。"确定无疑"这个名称是有意讽刺的——Pring 承认没有任何指标提供确定性,但 KST 比任何单一动量指标更接近捕捉确认趋势反转的"确定无疑"。
KST 分三步构建:
第1步:计算四个不同周期的变化率(ROC)。
ROC(n) = ((收盘价 - N周期前收盘价) / N周期前收盘价) * 100
第2步:用简单移动平均线(SMA)平滑每个 ROC。
平滑ROC_1 = SMA(ROC(周期_1), 平滑_1)
平滑ROC_2 = SMA(ROC(周期_2), 平滑_2)
平滑ROC_3 = SMA(ROC(周期_3), 平滑_3)
平滑ROC_4 = SMA(ROC(周期_4), 平滑_4)
第3步:用递增权重组合。
KST = (平滑ROC_1 * 权重_1)
+ (平滑ROC_2 * 权重_2)
+ (平滑ROC_3 * 权重_3)
+ (平滑ROC_4 * 权重_4)
信号线 = SMA(KST, 信号周期)
Pring 为每个时间周期指定了默认参数:
短期 KST(日线数据):
| 成分 | ROC 周期 | SMA 平滑 | 权重 |
|---|---|---|---|
| ROC 1 | 10 | 10 | 1 |
| ROC 2 | 15 | 10 | 2 |
| ROC 3 | 20 | 10 | 3 |
| ROC 4 | 30 | 15 | 4 |
| 信号 | — | 9 | — |
中期 KST(周线数据):
| 成分 | ROC 周期 | SMA 平滑 | 权重 |
|---|---|---|---|
| ROC 1 | 10 | 10 | 1 |
| ROC 2 | 13 | 13 | 2 |
| ROC 3 | 15 | 15 | 3 |
| ROC 4 | 20 | 20 | 4 |
| 信号 | — | 9 | — |
长期 KST(月线数据):
| 成分 | ROC 周期 | SMA 平滑 | 权重 |
|---|---|---|---|
| ROC 1 | 9 | 6 | 1 |
| ROC 2 | 12 | 6 | 2 |
| ROC 3 | 18 | 6 | 3 |
| ROC 4 | 24 | 9 | 4 |
| 信号 | — | 9 | — |
信号线交叉:
买入信号:KST 穿越至信号线上方。
卖出信号:KST 穿越至信号线下方。
零轴交叉:
看涨确认:KST 穿越零轴上方 → 趋势已转正。
看跌确认:KST 穿越零轴下方 → 趋势已转负。
背离(最强大的信号):
看涨背离:价格创出新低,但 KST 创出更高低。
→ 下跌动量正在减弱。潜在底部正在形成。
看跌背离:价格创出新低,但 KST 创出更高低。
→ 上涨动量正在减弱。潜在顶部正在形成。
看跌背离:价格创出更高高,但 KST 创出更高低。
→ 上涨动量正在减弱。潜在顶部正在形成。
超买/超卖:
KST 是无界指标(与 RSI 不同),因此超买/超卖水平必须根据每个证券的历史范围进行校准。Pring 建议在历史上与反转同时发生的水平处绘制水平参考线。
当所有三个 KST 时间周期一致时,产生最高信念信号:
最大看涨:长期 KST 上升 + 中期 KST 上升 + 短期 KST 买入信号
最大看跌:长期 KST 下降 + 中期 KST 下降 + 短期 KST 卖出信号
谨慎区:短期 KST 给出买入信号,但长期 KST 正在下降。
→ 逆趋势反弹可能。减少仓位或完全跳过。
Pring 使用简单移动平均线(SMAs)作为主要趋势识别工具。他承认指数移动平均线但更偏好 SMA,因为其概念清晰且是市场参与者最广泛关注的。
各时间周期的关键周期:
短期:10日、25日、30日 SMA
中期:40周(200日)、65日 SMA
长期:12个月、24个月 SMA
200日(40周)SMA 是 Pring 框架中最重要的单一移动平均线。它作为牛市和熊市的分界线。
金叉:短期 MA 穿越至长期 MA 上方 → 看涨。
死叉:短期 MA 穿越至长期 MA 下方 → 看跌。
Pring 的完善:交叉仅在较长 MA 也朝交叉方向移动时才有效。
- 金叉仅在200日 SMA 持平或上升时才有效。
- 死叉仅在200日 SMA 持平或下降时才有效。
Pring 使用围绕移动平均线的百分比通道来识别超买/超卖状况:
上通道 = MA * (1 + 百分比)
下通道 = MA * (1 - 百分比)
典型通道宽度:
- 200日 SMA:+/- 10%(股票)
- 40周 SMA:+/- 15%(波动市场)
- 短期 MAs 的通道更窄
价格触及或突破通道边界表明趋势过度延伸,容易出现均值回归修正。
最简单的动量指标,也是 KST 的基础:
ROC = ((今日收盘价 - N日前收盘价) / N日前收盘价) * 100
Pring 的用法:
标准构建(Appel 原始版本):
MACD 线 = 12周期 EMA - 26周期 EMA
信号线 = MACD 线的 9周期 EMA
柱状图 = MACD 线 - 信号线
Pring 的解读:
Pring 使用的 Wilder 的14周期 RSI:
RSI = 100 - (100 / (1 + RS))
RS = N周期平均收益 / N周期平均损失
Pring 的规则:
Lane 的随机指标,Pring 的应用:
%K = ((收盘价 - N日内最低价) / (N日内最高价 - N日内最低价)) * 100
%D = %K 的 3周期 SMA
典型周期:n = 14、21 或 5,取决于时间周期。
Pring 的规则:
Pring 的动量框架:
强买入信号:KST 买入 + MACD 买入 + RSI 从超卖反弹 + 随机买入
→ 多个独立指标确认相同信息。
弱/可疑信号:仅一两个指标触发。
→ 谨慎行事。减少仓位。
矛盾信号:一些指标看涨,其他看跌。
→ 观望。等待明朗。
Pring 遵循经典的成交量解读规则:
规则1:成交量应在趋势方向扩展。
- 在上涨趋势中,成交量应在上涨日较重,下跌日较轻。
- 在下跌趋势中,成交量应在下跌日较重,上涨日较轻。
规则2:成交量领先价格。
- 上涨中成交量下降警告趋势失去信心。
- 下跌中成交量上升警告激进卖盘和潜在抛售。
规则3:成交量高潮往往标志转折点。
- 高潮顶部:最后冲刺时成交量极高 → 衰竭。
- 抛售高潮:最后暴跌时成交量极高 → 恐慌。
如果收盘 > 前收盘:OBV = 前 OBV + 成交量
如果收盘 < 前收盘:OBV = 前 OBV - 成交量
如果收盘 = 前收盘:OBV = 前 OBV
Pring 的解读:
Pring 将 ROC 应用于成交量本身以检测异常成交量飙升:
成交量 ROC = ((今日成交量 - N周期前成交量) / N周期前成交量) * 100
在支撑或阻力位的成交量 ROC 峰值很重要。它们表明价格走势背后有强烈信念,并增加该水平将维持或果断突破的概率。
Pring 还讨论了需求指数和各种成交量振荡器,将上涨成交量与下跌成交量进行比较。原则保持不变:成交量必须确认价格,趋势才能被视为可靠。当成交量未能确认时,证据权重转向不利当前趋势的方向。
Pring 将形态分为两类:
反转形态(标志趋势变化):
- 头肩顶(及其倒置)
- 双顶和双底
- 圆顶和圆底(碟形)
- 扩散形态
- 钻石顶
持续形态(标志暂停后趋势恢复):
- 三角形(对称、上升、下降)
- 旗形和尖旗
- 矩形
- 楔形
Pring 教授每种形态的标准测量技术:
头肩顶:
目标 = 颈线 ± (头部 - 颈线距离)
双顶/双底:
目标 = 突破点 ± (形态高度)
三角形:
目标 = 突破点 ± (三角形最宽处)
旗形/尖旗:
目标 = 突破点 + (旗杆长度)
这些是 最小 价格目标。Pring 强调实际走势可能显著超过测量目标,特别是当证据权重支持该方向时。
头肩顶:
- 左肩成交量最高。
- 头部成交量较低。
- 右肩成交量最低。
- 颈线突破时成交量扩大。
三角形:
- 三角形形成时成交量收缩。
- 突破时成交量扩大。
- 低成交量突破值得怀疑,容易失败。
旗形/尖旗:
- 旗形形成期间成交量收缩。
- 持续突破时成交量飙升。
Pring 明确指出形态失败——快速反转的突破:
失败的形态本身就是相反方向的强大信号。
如果头肩顶突破了颈线但立即反弹至其上方,
失败的破位成为强烈的看涨信号。被困的空头必须回补,
为反弹增添动力。
相对强度(RS)比较一只证券相对于基准的表现:
RS = 证券价格 / 基准价格(例如标普500)
如果 RS 上升 → 该证券跑赢基准。
如果 RS 下降 → 该证券跑输基准。
规则1:买入 RS 线处于上涨趋势的股票。
这些是跑赢者——它们在牛市上涨更多,在熊市下跌更少。
规则2:回避或做空 RS 线处于下跌趋势的股票。
这些是跑输者——它们有结构性弱点。
规则3:RS 趋势变化往往领先价格趋势变化。
如果 RS 开始恶化而价格仍在上涨,
该股票正在失去其领先地位。
规则4:将相同的技术工具应用于 RS 线本身。
移动平均线、趋势线和 RS 线上的图表形态
都是有效的,往往领先价格信号。
Pring 将 RS 分析直接关联到他的六阶段周期模型。不同板块在不同阶段领先:
阶段1-2:利率敏感板块领先(公用事业、金融、REITs)。
阶段2-3:消费周期股和科技开始跑赢。
阶段3-4:基础材料和工业股接棒。
阶段4-5:能源和商品最后见顶。
阶段5-6:防御板块(医疗保健、消费必需品)在市场下跌中保持最好。
监测板块 RS 线有助于确认市场处于哪个阶段,以及应强调或回避哪些板块。
A/D 线 = 上涨家数 - 下跌家数的累积总和
Pring 的规则:
NH-NL = 创52周新高的股票数量 - 创52周新低的股票数量
200日均线上方百分比:长期趋势健康性的广泛衡量。
50日均线上方百分比:中期广度。
超买:> 80% 在均线上方(容易修正)。
超卖:< 20% 在均线上方(反弹潜力)。
Pring 将这些用作确认指标而非独立信号。极端读数结合动量背离产生高置信度反转信号。
Pring 讨论这些高级广度工具:
McClellan 振荡器 = (上涨 - 下跌)的19日 EMA - (上涨 - 下跌)的39日 EMA
McClellan 加总指数 = McClellan 振荡器的累积总和
加总指数 > 0 → 看涨广度环境。
加总指数 < 0 → 看跌广度环境。
Pring 的跨市场框架监控四个相互关联的市场:
1. 美元(美元指数)
2. 债券(国债/利率)
3. 股票(标普500、广泛指数)
4. 商品(CRB 指数、黄金、石油)
债券与利率:
- 反向关系。利率上升 → 债券价格下跌。
- 债券市场见顶/见底通常领先股票市场见顶/见底。
股票与债券:
- 在商业周期早期/中期通常一起移动。
- 在晚期分化:债券下跌(利率上升)而股票上涨(盈利)。
- 当债券已下跌较长时间,股票变得脆弱。
商品与债券:
- 通常反向。商品上涨 → 通胀压力 → 债券下跌。
- 这是驱动阶段4 → 阶段5 转换的主要机制。
美元与商品:
- 通常反向。强势美元 → 疲弱商品,反之亦然。
- 美元强弱有助于确认商品周期转折。
看涨跨市场设置:
- 债券上涨(利率下降)
- 美元稳定或下跌
- 商品筑底
- 股票显示正向广度背离
→ 与阶段2 入场条件一致。
看跌跨市场设置:
- 债券下跌(利率上升)持续较长时间
- 商品飙升(通胀)
- 尽管指数强劲但广度恶化
→ 与阶段5 一致,接近阶段6。
Pring 没有提供僵硬的机械系统,但他的框架意味着以下综合:
主要条件(应全部满足):
1. 市场周期处于阶段2或阶段3(债券和股票上涨)。
2. 股价在200日均线上方,且均线正在上升。
3. 中期 KST 已给出买入信号(穿越至信号线上方)。
4. 成交量确认上涨趋势(上涨时扩大,回调时收缩)。
次要条件(至少应满足两个):
5. 短期 KST 在中期趋势方向触发买入信号。
6. 看涨图表形态已完结(突破阻力位并伴随成交量)。
7. 该股票的 RS 线相对于市场处于上涨趋势。
8. 广度指标确认市场强度(A/D 线上升,新高扩大)。
入场触发:
- 在条件满足后,买入回调至上升50日均线,或
- 在图表形态突破时伴随成交量确认买入。
强制出场信号(任一触发即卖出):
1. 中期 KST 穿越至信号线下方。
2. 价格坚决收于200日均线下方。
3. 主要反转形态完结(例如头肩顶颈线突破)。
警告信号(开始收紧止损):
4. 价格与任两个动量指标之间的看跌背离。
5. 上涨时成交量下降而下跌时成交量扩大。
6. RS 线打破其上涨趋势。
7. 市场周期从阶段3转向阶段4(债券转跌)。
主要条件:
1. 市场周期处于阶段5或阶段6。
2. 价格在200日均线下方,且均线正在下降。
3. 中期 KST 已给出卖出信号。
入场触发:
- 在下降50日均线反弹时做空,或
- 在图表形态(例如头肩顶、下降三角形)破位时做空。
Pring 倡导在技术重要位设置止损:
多头仓位:
- 在最近一波低点下方。
- 在200日均线下方(如果价格接近)。
- 在已完结看涨形态的颈线下方。
- 在趋势通道下边界下方。
空头仓位:
- 在最近一波高点上方。
- 在200日均线上方(如果价格接近)。
- 在已完结看跌形态的颈线上方。
Pring 没有规定具体的仓位配置公式,但他的框架意味着:
全仓:所有主要和多个次要条件都满足。
周期阶段有利。证据权重强劲。
半仓:主要条件满足,但次要条件混杂。
一些指标相互矛盾。
无仓:主要条件不满足,无论图表看起来多吸引人。
价格波动的幅度通常与先前盘整或反转形态的持续时间成比例。
- 长期底部 → 大幅反弹。
- 短暂盘整 → 有限的持续。
- 指标在超买/超卖区域停留越久,
最终反转越强劲。
错误:将单一指标视为绝对可靠。
修复:没有任何指标总是有效。使用证据权重。
如果四个指标说买而一个说卖,概率支持买——
但持异议的指标应作为风险因素得到关注。
错误:在长期下跌趋势中采取短期买入信号,
并期望完整的反弹。
修复:逆趋势信号本质上是低概率的。
主要(长期)趋势定义了游戏场地。
短期信号应用于在中期和长期趋势方向入场。
错误:无限调整指标参数以完美拟合历史数据。
修复:最好的参数是那些在多个市场和时期都有效的参数,
而不是恰好适合过去6个月的参数。
Pring 的 KST 默认值是数十年测试的产物,
正是因为它们稳健,而非优化。
错误:分析价格而不考虑成交量。
修复:低成交量突破值得怀疑。成交量下降的反弹
正在失去信心。成交量是燃料——没有它,
价格走势不可靠。
错误:坚持市场"必须"处于特定阶段,
因为你想进行特定交易。
修复:有时周期阶段是模糊的。当证据不明确时,
正确的做法是什么都不做。现金也是一种仓位。
错误:购买 RS 线正在上升的股票,
但未注意到该股票本身正在下跌(只是比市场跌得少)。
修复:RS 分析识别跑赢者和跑输者。
熊市中上升的 RS 线意味着该股票亏损较少——
但不意味着它值得购买。绝对趋势仍必须向上。
背景:
- 2002年10月:标普500 已处于熊市2.5年。
- 债券在整个2002年一直在上涨(利率下降)。
- 商品(CRB 指数)在2001年底筑底并正在适度上涨。
周期阶段评估:
- 债券:上涨 → 上升
- 股票:仍在下跌 → 下降
- 商品:上涨 → 上升
→ 这不符合干净的双六阶段模板(债券和商品上涨,
股票下跌)。Pring 会注意到这是过渡期。
2003年3月:
- 股票形成双底形态(2002年10月低点被重新测试)。
- 标普500 的长期 KST 开始走平并向上弯曲。
- 中期 KST 给出买入信号(穿越至信号线上方)。
- 广度:A/D 线与价格低点呈正向背离。
- 成交量:3月出现抛售高潮,随后回调时成交量下降。
信号:中期 KST 买入信号 + 双底完结 + 广度背离。
入场:在双底颈线突破时买入标普500(或强势 RS 股票)。
假设入场在标普500 = 880。
止损:在双底低点下方 800。风险 = 80点(9.1%)。
2003年4月-6月:
- 价格在一年多来首次上涨至200日均线上方。
- 短期 KST 在回调期间给出间歇性买入信号。
- 成交量在反弹时扩大,在回调时收缩 → 健康。
- RS 分析:科技和消费自由裁量板块领先。
→ 在价格突破200日均线后移动止损至盈亏平衡(880)。
2003年7月-12月:
- 长期 KST 穿越至零轴上方 → 确认长期趋势变化。
- 周期阶段明确过渡至阶段2,然后阶段3。
- A/D 线创出新高 → 广度确认。
→ 追踪止损至最近一波低点下方,约1000。
2004年初:
- 标普500 达到约1150。
- 中期 KST 开始走平,最终穿越至信号线下方。
- 第一次部分退出:在约1130卖出半仓。
- 短期 KST 给出卖出信号。
- 在中期回调加深时以约1100全部退出。
结果:
入场:880
出场:平均约1115
利润:约235点(26.7%)
承担风险:80点
风险回报比:2.9:1
def calculate_kst(close_prices, timeframe="intermediate"):
"""
计算 KST(确定无疑)指标。
参数:
-----------
close_prices : 收盘价数组
timeframe : "short"、"intermediate" 或 "long"
返回:
--------
kst_values : KST 值数组
signal_values: 信号线值数组
"""
params = {
"short": {
"roc_periods": [10, 15, 20, 30],
"sma_periods": [10, 10, 10, 15],
"weights": [1, 2, 3, 4],
"signal_period": 9
},
"intermediate": {
"roc_periods": [10, 13, 15, 20],
"sma_periods": [10, 13, 15, 20],
"weights": [1, 2, 3, 4],
"signal_period": 9
},
"long": {
"roc_periods": [9, 12, 18, 24],
"sma_periods": [6, 6, 6, 9],
"weights": [1, 2, 3, 4],
"signal_period": 9
}
}
p = params[timeframe]
n = len(close_prices)
roc = []
for i in range(4):
period = p["roc_periods"][i]
roc_series = []
for j in range(n):
if j < period:
roc_series.append(None)
else:
value = ((close_prices[j] - close_prices[j - period])
/ close_prices[j - period]) * 100
roc_series.append(value)
roc.append(roc_series)
smoothed_roc = []
for i in range(4):
sma_period = p["sma_periods"][i]
smoothed = simple_moving_average(roc[i], sma_period)
smoothed_roc.append(smoothed)
kst_values = []
for j in range(n):
components_valid = all(smoothed_roc[i][j] is not None for i in range(4))
if not components_valid:
kst_values.append(None)
else:
kst = sum(smoothed_roc[i][j] * p["weights"][i] for i in range(4))
kst_values.append(kst)
signal_values = simple_moving_average(kst_values, p["signal_period"])
return kst_values, signal_values
def simple_moving_average(values, period):
result = []
for i in range(len(values)):
if i < period - 1:
result.append(None)
continue
window = values[i - period + 1 : i + 1]
if any(v is None for v in window):
result.append(None)
else:
result.append(sum(window) / period)
return result
def generate_kst_signals(kst_values, signal_values):
signals = []
for i in range(1, len(kst_values)):
if kst_values[i] is None or signal_values[i] is None:
continue
if kst_values[i - 1] is None or signal_values[i - 1] is None:
continue
prev_diff = kst_values[i - 1] - signal_values[i - 1]
curr_diff = kst_values[i] - signal_values[i]
if prev_diff <= 0 and curr_diff > 0:
signals.append((i, "BUY"))
elif prev_diff >= 0 and curr_diff < 0:
signals.append((i, "SELL"))
if kst_values[i - 1] <= 0 and kst_values[i] > 0:
signals.append((i, "ZERO_CROSS_UP"))
elif kst_values[i - 1] >= 0 and kst_values[i] < 0:
signals.append((i, "ZERO_CROSS_DOWN"))
return signals
def detect_cycle_stage(bond_kst, stock_kst, commodity_kst,
bond_signal, stock_signal, commodity_signal):
def is_rising(kst, signal):
if kst is None or signal is None:
return None
return kst > signal
bonds_up = is_rising(bond_kst, bond_signal)
stocks_up = is_rising(stock_kst, stock_signal)
commodities_up = is_rising(commodity_kst, commodity_signal)
if None in (bonds_up, stocks_up, commodities_up):
return 0, "数据不足,无法确定周期阶段。"
stage_map = {
(True, False, False): (1, "阶段1:仅债券上涨。经济衰退。买入债券。"),
(True, True, False): (2, "阶段2:债券和股票上涨。早期复苏。买入股票。"),
(True, True, True): (3, "阶段3:全部上涨。全面复苏。最大看涨。"),
(False, True, True): (4, "阶段4:股票和商品上涨。债券见顶。卖出债券。"),
(False, False, True): (5, "阶段5:仅商品上涨。经济过热。卖出股票。"),
(False, False, False): (6, "阶段6:全部下跌。衰退。持现金。"),
}
key = (bonds_up, stocks_up, commodities_up)
if key in stage_map:
return stage_map[key]
return 0, (f"过渡/模糊阶段。"
f"债券={'上涨' if bonds_up else '下跌'},"
f"股票={'上涨' if stocks_up else '下跌'},"
f"商品={'上涨' if commodities_up else '下跌'}。"
f"等待明朗。")
def recommend_allocation(stage):
allocations = {
1: {"bonds": 0.60, "stocks": 0.00, "commodities": 0.00, "cash": 0.40,
"note": "积累债券。开始观察股票底部。"},
2: {"bonds": 0.30, "stocks": 0.50, "commodities": 0.00, "cash": 0.20,
"note": "从债券转向股票。偏好利率敏感板块。"},
3: {"bonds": 0.20, "stocks": 0.50, "commodities": 0.20, "cash": 0.10,
"note": "全仓。跨资产类别广泛参与。"},
4: {"bonds": 0.00, "stocks": 0.35, "commodities": 0.35, "cash": 0.30,
"note": "退出债券。偏好商品关联股和周期股。"},
5: {"bonds": 0.00, "stocks": 0.00, "commodities": 0.40, "cash": 0.60,
"note": "退出股票。持有商品。积极持现金。"},
6: {"bonds": 0.00, "stocks": 0.00, "commodities": 0.00, "cash": 1.00,
"note": "最大现金。等待债券市场筑底(阶段1)。"},
}
return allocations.get(stage, {
"bonds": 0.00, "stocks": 0.00, "commodities": 0.00, "cash": 1.00,
"note": "阶段不明确。默认持现金,直到周期阶段确认。"
})
def detect_divergence(prices, indicator, lookback=20):
if len(prices) < lookback or len(indicator) < lookback:
return None
recent_prices = prices[-lookback:]
recent_indicator = indicator[-lookback:]
price_low_idx = recent_prices.index(min(recent_prices))
price_high_idx = recent_prices.index(max(recent_prices))
if price_high_idx > lookback // 2:
first_half_price_high = max(recent_prices[:lookback // 2])
first_half_ind_high = max(recent_indicator[:lookback // 2])
second_half_price_high = max(recent_prices[lookback // 2:])
second_half_ind_high = max(recent_indicator[lookback // 2:])
if (second_half_price_high > first_half_price_high and
second_half_ind_high < first_half_ind_high):
return "bearish_divergence"
if price_low_idx > lookback // 2:
first_half_price_low = min(recent_prices[:lookback // 2])
first_half_ind_low = min(recent_indicator[:lookback // 2])
second_half_price_low = min(recent_prices[lookback // 2:])
second_half_ind_low = min(recent_indicator[lookback // 2:])
if (second_half_price_low < first_half_price_low and
second_half_ind_low > first_half_ind_low):
return "bullish_divergence"
return None
"技术分析方法本质上是反映价格走势受投资者对各种经济、货币、政治和心理因素态度变化影响的理念。"
"技术分析的艺术——因为它是一门艺术——是在相对早期阶段识别趋势反转并在该趋势中持有,直到证据权重显示或证明趋势已经反转。"
"在技术分析中只使用一个指标是一个主要错误。证据权重是关键概念。"
"KST 旨在通过测量四个不同时间跨度的价格变化率,平滑每个,并按与周期长度成比例的权重加权,来识别股票市场周期中有意义的转折点。"
"成交量随趋势。在上涨市场中,成交量应在反弹时扩大,在回调时收缩。在下跌市场中,成交量应在下跌时扩大,在反弹时收缩。违反这一原则警告当前趋势可能即将反转。"
"市场在无人可买时见顶,在无人可卖时见底。广度指标比单纯的价格更能衡量这一衰竭过程。"
"技术分析中最重要的单一因素是主要趋势方向的识别。沿主要趋势方向移动的指标应得到尊重;逆趋势移动的指标应受到怀疑。"
"相对强度可能是技术分析师武器库中单一套餐最未被充分利用的工具。在牛市阶段不能跑赢市场的股票在熊市阶段几乎肯定会跑输。"
"跨市场关系提供了个人市场分析的背景。孤立研究股票市场的技术分析师就像医生只测量患者的体温但忽略血压、心率和呼吸功能。"
"商业周期内债券、股票和商品见顶和见底的序列是所有金融市场分析中最可靠和最有用的关系之一。"
实施规范结束。