基于 John J. Murphy,Technical Analysis of the Futures Markets(1999年)
技术分析是通过图表研究市场行为,主要目的是预测未来价格趋势。"市场行为"包含三个主要信息来源:价格、成交量和持仓量(在期货中)。Murphy 认为这三个数据流,如果正确解读,包含了分析师需要知道的一切。
市场行为消化一切。 任何可能影响价格的因素——基本面、政治、心理学、天气——都已经反映在价格中。技术分析师不需要知道 为什么 价格会移动;图表已经包含答案。
价格按趋势移动。 整个图表绘制的目的是尽早识别趋势,以便交易者能够持有趋势。处于运动中的趋势继续的可能性大于反转。这是技术分析中最重要的概念,所有形态识别和指标分析都源于此。
历史重演。 已经运行了一百多年的图表形态继续有效,因为它们反映的心理学不会改变。这些形态是多头或空头心理的图片——相同的集体情绪在每一代人身上产生相同的价格足迹。
Murphy 不否定基本面分析。他认为它们回答不同的问题:基本面回答 买什么,技术分析回答 何时买。技术分析师具有灵活性——相同的方法适用于任何市场、任何时间周期,无需行业特定的领域知识。一套图表阅读技能可以从大豆转移到国债再到标普500。
期货市场带来独特特征:杠杆、追加保证金要求和持仓量数据。技术分析在期货中可以说 更重要,因为这些市场的杠杆特性要求精确时机,这是技术分析师的核心优势。
Charles Dow 从未写过正式的论文。他的想法发表在《华尔街日报》的社论上(1900-1902年),由 William Hamilton、Robert Rhea 和后来的 Richard Russell 汇编而成。道氏理论仍然是技术分析的基石——Murphy 书中大多数技术都是对 Dow 原始原则的扩展或阐述。
原则1:平均指数消化一切。 市场知识总和——供需、作物报告、美联储政策、战争风险——都反映在价格中。没有新信息能逃脱市场的处理机制。
原则2:市场有三种趋势。
长线持仓交易者关心主要趋势。次要趋势提供入场机会。短期趋势主要是噪音。
原则3:主要趋势有三个阶段。
原则4:平均指数必须相互确认。 工业股中的买入信号仅在运输股确认时有效。在期货中,Murphy 将此扩展到相关市场:黄金突破应得到银的确认;原油趋势应与取暖油一致。
原则5:成交量必须确认趋势。 成交量应在主要趋势方向扩大。在上涨趋势中,成交量在反弹时增加在回调时减少。反弹时成交量萎缩是早期警告。
原则6:趋势被假定持续直到明确反转信号出现。 这是惯性原则。声称趋势已结束的分析员承担举证责任。在趋势线突破、移动平均线交叉或确认的形态形成之前,现有趋势被给予怀疑的好处。
批评者称道氏理论滞后(在入场和出场时错过20-25%的运动)。Murphy 反驳说,在主要趋势中捕获50-60%是高度盈利的,而且没有系统能捕获顶部和底部。真正的价值是纪律:道氏理论使交易者保持在主要趋势的正确一侧。
K线图是 Murphy 的主要工具。每根K线代表一个时间段:
收盘价与范围的关系揭示情绪:收盘接近高位是看涨;接近低位是看跌。范围扩大(窄K线后出现宽K线)信号动量开始。
Murphy 将日本K线图作为 K线图的视觉增强。实体(开盘到收盘范围)根据方向填充或空心。关键单根K线形态:
K线图增加了细微差别但不替代经典形态分析。Murphy 将它们视为覆盖层,而非独立系统。
仅收盘价的图表。在K线噪音遮蔽图形时,用于简洁性和识别趋势线突破。也适用于长期月线图,因为收盘是最有意义的数据点。
(见第10节完整说明。)P&F 图表完全剥离时间,仅记录重要的价格变化。它们减少噪音并产生清晰的支撑/阻力位。
Murphy 强调多时间周期分析:长期(周/月)图表确定主要趋势;中期(日)图表安排入场时机;短期(日内)图表微调执行。交易者应始终从最长的时间周期开始向内工作。
未能创出新高(在上涨趋势中)或新低(在下跌趋势中)是趋势变化的第一警告。当随后跌破最近的低点(或突破最近的高点)时,反转得到确认。
关键原则:
上涨趋势线绘制在连续反应低点下方。下跌趋势线绘制在连续反弹高点上方。有效性需要至少两个触点;三个或更多增加可靠性。
趋势线突破规则:
通道线绘制在趋势线对面,与价格平行。在上涨趋势中,通道线连接在上涨趋势线上方的高点。通道提供利润目标:当价格未能达到通道线时,信号趋势正在减弱。当价格超越通道线时,信号趋势加速。
趋势线突破后,从相同起点到第一个反应点绘制一条新的(更平坦的)趋势线。如果这也被突破,绘制第三条线。第三条扇形线被突破是可靠的反转信号。三条扇形线都被突破信号确定性的趋势变化。
价格通常在恢复之前回撤先前运动的一部分。Murphy 的关键水平:
这些与道氏理论次要修正以及 Murphy 稍后介绍的斐波那契比率(38.2%、50%、61.8%)一致。
将先前运动分成三等分。从运动起点通过三分之一和三分之二点绘制线。在上涨趋势回调中,第一条被突破的线是三分之一线;如果三分之二线也被突破,完全回撤可能发生。
镜像图像,但有一个关键区别:颈线上方突破时成交量绝对必要。没有上方突破时的大量成交量,形态可疑。
三个在相似水平的峰值或低点。类似于头肩但没有突出的中间峰值。突破和测量规则相同。
逐渐的、弧形的反转,持续较长时间。成交量在形态形成时收缩,在突破时扩大。没有明确的测量规则;持续时间暗示幅度。
突然的、暴力反转,几乎没有警告。关键反转日(与先前趋势收盘相反的Outside日)或岛形反转(缺口后紧接着相反方向的缺口)是唯一信号。这些最难交易,需要立即止损保护。
对称三角形 — 较低高点和较高低点的收敛趋势线。休息形态,通常在先前趋势方向解决。突破应发生在从底部到顶点的距离的一半到四分之三之间。太接近顶点突破不可靠。成交量在形成时收缩,在突破时扩大。
上升三角形 — 平坦上边界(阻力)和上升下趋势线。无论先前趋势如何,看涨偏见。平坦顶部提供明确的突破水平。
下降三角形 — 平坦下边界(支撑)和下降上趋势线。看跌偏见。上升三角形的镜像。
所有三角形的测量规则: 底部高度(最宽处),从突破点投射。
急剧、近乎垂直运动后的短暂停顿。旗形是的小平行四边形,倾斜方向与先前运动相反。尖旗是形成在旗杆后的小对称三角形。两者都应在1-3周内完成,是最可靠的持续形态之一。成交量在形态期间枯竭,在突破时爆发。
测量规则: 旗形或尖旗据说"飘在旗杆半腰"。先前的急剧运动(旗杆)从突破点投射。
收敛趋势线都朝同一方向倾斜。上升楔形是看跌的;下降楔形是看涨的。楔形比旗形/尖旗需要更长时间形成——通常超过三周。成交量在楔形发展时应明显减少。
价格在明确定义的支撑和阻力之间振荡。矩形是趋势的暂停,突破方向通常遵循先前趋势,尽管矩形也可以作为反转形态。区间内反弹时成交量较高有时能提示方向。
成交量衡量价格运动的强度。Murphy 的规则:
| 价格 | 成交量 | 解读 |
|---|---|---|
| 上涨 | 增加 | 看涨 — 强劲趋势 |
| 上涨 | 减少 | 可疑反弹 |
| 下跌 | 增加 | 看跌 — 强劲趋势 |
| 下跌 | 减少 | 卖压减弱 |
成交量领先价格。价格创出新高而成交量下降之间的背离是趋势衰竭最早期的警告之一。
由 Joe Granville 开发。累计运行总量:如果收盘上涨,加上当天成交量;如果收盘下跌,减去成交量。绝对数字不重要——只有 OBV 线の方向重要。如果 OBV 在价格之前创出新高,吸筹正在进行。如果 OBV 背离(未能确认新高价格),派发正在进行。
持仓量是尚未平仓或交割的未平仓合约总数。它反映资金流入或流出期货市场。
| 价格 | 持仓量 | 解读 |
|---|---|---|
| 上涨 | 增加 | 新资金进入 — 看涨 |
| 上涨 | 减少 | 空头回补反弹 — 看跌信号 |
| 下跌 | 增加 | 新空头进入 — 看跌 |
| 下跌 | 减少 | 多头清算 — 熊市减弱 |
Murphy 强调 CFTC 的每周 COT 报告,将持仓量分为三类:商业(对冲者)、大投机者和小投机者。商业是"聪明钱"——当他们的净持仓与价格急剧分化时要注意。小投机者在极端时通常错误。
高潮顶部通常伴随成交量和持仓量的飙升,然后两者都急剧下降,因为运动反转。这些高潮标志情绪极端,信号潜在趋势衰竭。
移动平均线平滑价格数据以揭示潜在趋势。它们是追随者,不是领导者。它们从不预测——它们反应。它们的价值在于识别和确认趋势,而不是在于发出转折点信号。
过去 N 个收盘价的算术平均值。每个数据点权重相等。最常见的周期:10日(短期)、50日(中期)、200日(长期)。
局限性: 一个异常价格滑出窗口可以移动平均值,即使当前价格没有实质性变化。
对近期价格应用更大权重。比相同周期的 SMA 更快响应价格变化。平滑因子为 2/(N+1)。Murphy 注意到 EMA 减少滞后但增加鞭打风险——没有免费午餐。
每天的价格乘以权重因子(最近一天获得最高权重)。在实践中不如 EMA 常见,但概念上目的相似。
单一移动平均线系统:
双移动平均线交叉:
三重移动平均线系统(4-9-18):
Murphy 简要介绍布林的概念:SMA 上下两条标准差线。价格触及上带不一定是超买——在强劲趋势中,价格"行走于带上"。收缩(带收窄)先于波动性扩张。突破的方向决定交易。
移动平均线上方和下方固定百分比。Murphy 使用21日 MA 周围3%通道作为常见配置。通道突破信号过度延伸状况。
振荡器在市场处于交易区间时最有用,趋势跟踪方法会产生鞭打。它们识别超买和超卖状况,它们与价格的背离提供技术分析中最强大的信号。
三个主要振荡器信号:
最简单的振荡器:今天收盘价减去 N 天前收盘价(动量),或今天收盘价除以 N 天前收盘价再乘以100(变化率)。10日动量在零轴上方是看涨的;下方是看跌的。动量线的变化率很重要——即使为正但正在减速的动量警告即将下跌。
由 J. Welles Wilder 开发。公式:
RS = N周期平均收益 / N周期平均损失
RSI = 100 - (100 / (1 + RS))
标准周期:14。超买高于70,超卖低于30。Murphy 强调:
由 George Lane 开发。衡量收盘价相对于 N 周期内高低范围的位置。
%K = 100 * (收盘价 - N日内最低价) / (N日内最高价 - N日内最低价)
%D = %K 的 3周期 SMA
标准周期:%K 为14,%D 为3。超买高于80,超卖低于20。
信号:
由 Gerald Appel 开发。使用三个 EMA:
MACD 线 = EMA(12) - EMA(26)
信号线 = MACD 线的 EMA(9)
柱状图 = MACD 线 - 信号线
信号:
类似于随机但反转和无平滑:
%R = -100 * (N日最高价 - 收盘价) / (N日最高价 - N日最低价)
刻度从0到-100。超买高于-20,超卖低于-80。标准周期:14。Murphy 注意到它本质上是快速随机 %K 的倒数。
由 Donald Lambert 开发。衡量价格与其统计平均值的偏差:
典型价格 = (H + L + C) / 3
CCI = (典型价格 - SMA(典型价格, 20)) / (0.015 * 平均偏差)
读数高于+100表明市场"异常强劲"(潜在超买);低于-100,异常疲弱。最初设计用于识别商品中的周期性转折。
Murphy 用一节讨论情绪分析。当大多数市场参与者看涨时,谁还有可买入?逆向观点使用顾问、通讯作家和交易者的调查来衡量极端。市场看涨共识(由 Market Vane 发布)是主要工具:读数高于75%暗示市场顶部;低于25%,暗示底部。逆向观点在极端时效果最好,在中间地带无用。
P&F 图表使用 X 表示上涨价格,O 表示下跌价格。它们消除时间,专注于纯粹的价格运动。两个参数定义图表:
水平计数: 计算盘整区域的列数,乘以盒子大小和反转量,从突破点投射。这给出价格目标。
垂直计数: 计算突破后第一列中的盒子数,乘以反转量,从该列底部投射。
P&F 趋势线从重要低点(看涨支撑)或高点(看跌阻力)以45度角绘制。价格在上趋势线上方确认牛市。跌破45度线信号卖出。
Ralph Nelson Elliott(1930年代)发现市场价格以与斐波那契数列相关的可识别模式展开。基本模式是五浪上涨随后三浪调整(5-3循环):
Murphy 将艾略特波浪作为补充框架而非独立方法。波浪计数有助于估计趋势进展到多远(例如,认识到第五浪正在进行表明趋势已成熟)。将波浪分析与传统形态识别和振荡器读数结合提高信心。
波浪计数是主观的。通常同时存在多个有效计数。Murphy 警告不要被"波浪计数瘫痪",建议将其作为众多工具之一使用。
Murphy 用一章讨论市场表现出重复周期性行为的概念。周期四个原则:
Murphy 编目了几个广泛观察的周期:
周期分析用于调整其他工具。如果20天周期是主导的,那么10天(一半周期)移动平均线是最佳的。振荡器周期应设置为主导周期的一半。当周期表明低谷即将到来时,来自超卖振荡器的买入信号更有分量。
Murphy 开创了跨市场技术分析概念,认为没有市场孤立存在。四个主要组相互关联:
债券和商品 — 反向关系。 上涨的商品价格(通胀)导致债券价格下跌(利率上升)。CRB 指数和国债价格朝相反方向移动。商品价格往往在转折点领先债券价格。
债券和股票 — 正向关系(有时间差)。 债券通常在股票之前转向。下跌利率(上涨债券价格)对股票有利,因为它们降低资本成本并使股票股息相对于债券收益率更有吸引力。债券市场见顶是对股票市场的警告。
美元和商品 — 反向关系。 下跌的美元使美元计价商品更贵,推动商品价格上涨。上涨的美元压低商品价格。黄金是对美元变动最敏感的的商品。
美元和债券 — 复杂关系。 下跌的美元最初可以提振债券(外国投资者避险被通胀预期抵消所抵消)。然而,随着时间推移,弱美元提高通胀预期,对债券看跌。
通缩序列相反。Murphy 强调这些关系会变化,分析师必须验证而不是盲目假设。
在股票市场内,板块根据商业周期轮动:
跨市场分析师检查一个市场的交易是否被相关市场的行为确认或反驳。如果债券正在上涨且 CRB 指数稳定,标普500的买入信号更可靠。如果美元正在走弱,黄金买入信号更可信。
Murphy 坚持认为资金管理比入场方法更重要。拥有优秀资金管理的平庸系统将击败拥有糟糕资金管理的卓越系统。
Murphy 没有给出正式公式(没有 Kelly criterion 或固定比例),但他的框架暗示固定百分比风险模型:
仓位大小 = (账户权益 * 最大风险%) / (入场价格 - 止损价格)
在盈利仓位上加仓应遵循递减增量(例如4手,然后2手,然后1手)。绝不在亏损仓位上加仓。每个新加仓应有自己的止损,置于先前仓位的盈亏平衡点。
每笔交易应在入场前确定三个要素:
如果三个中的任何一个缺失,交易就没有准备好。
Murphy 涵盖自动交易系统作为纪律执行器。机械系统通过产生客观信号消除情绪。交易者必须提前决定是否遵循每个信号或使用判断力覆盖。
Murphy 的元建议:在趋势市场使用趋势跟踪方法(移动平均线、趋势线),在交易区间使用振荡器。挑战在于识别市场处于哪种状态。一个启发式方法:如果 ADX(平均方向指数)高于25且上升,市场在趋势中——使用移动平均线。如果 ADX 低于20,市场在盘整中——使用振荡器。
逆趋势交易。 试图挑选顶部和底部而不是遵循确认的趋势。Murphy 的第一条戒律:趋势是你的朋友。
不使用止损。 希望亏损仓位会恢复。"希望不是策略。"
将止损移向错误方向。 扩大止损以避免被止损销毁了止损的目的。
过度交易。 持仓过多,交易过大,或对每个信号都交易。没有过滤的选择性是一种美德。
忽视更大的时间周期。 在看跌周线趋势中的看涨日线信号是低概率交易。
过度依赖单一指标。 没有指标总是有效。Murphy 强调使用一组工具进行确认。
回测中的曲线拟合。 优化系统参数直到历史权益曲线看起来完美保证未来表现不佳。
忽视成交量。 没有成交量确认的突破可疑。成交量是推动价格运动的燃料。
情绪化交易。 亏损后的报复交易、出于恐惧的过早止盈、出于自负的加倍下注。治愈方法是书面交易计划,然后机械执行。
忽视跨市场分析。 在不看美元的情况下交易黄金,或在不看商品的情况下交易债券,都是闭着一只眼交易。
使用过短的时间周期。 短时间周期有更多噪音。Murphy 建议从周线图开始获取方向,日线图安排时机。
混淆精确与准确。 信号精确到Tick的系统不一定比识别区域系统更好。力求大致正确而不是精确错误。
第1步 — 自上而下背景(周线图)。 周线原油图表显示一系列更高低点和更高高点。40周均线正在上升且价格在均线上方。周线 MACD 在信号线上方且在零轴上方。主要趋势:上涨。寻找买入机会。
第2步 — 跨市场检查。 美元指数正在下跌(对商品看涨)。国债稳定(没有即将加息的压力)。CRB 指数正在上涨。跨市场一致:看涨。
第3步 — 日线图形态。 价格从$78回调至$72,这是$62至$78反弹的38.2%斐波那契回撤。一个对称三角形在$72水平形成,历时三周。成交量在三角形内收缩。这是确认趋势中的经典持续形态。
第4步 — 振荡器确认。 日线 RSI(14) 回落至45(中性,未超卖)并正在转向上涨。日线随机正在从30下方交叉向上。MACD 柱状图停止下降并显示其第一个正值柱。所有振荡器都为恢复上涨趋势对齐。
第5步 — 入场。 在三角形上边界突破至$73.50收盘时买入两份合约。突破K线显示成交量比20日均值高40%——确认。
第6步 — 止损。 初始止损置于$71.00,在三角形下边界和50日均线下方。每份合约风险:$73.50 - $71.00 = $2.50。总风险:$2.50 * 2合约 * 1000桶 = $5,000。账户权益为$100,000。风险:5.0%——在 Murphy 的最大阈值。
第7步 — 利润目标。 三角形高度为$3.00(从$75到$72在最宽点)。从突破点$73.50投射,目标为$76.50。之前波段高点为$78.00。使用$76.50作为T1(平仓一份合约)和$78.00作为T2。
第8步 — 交易管理。 价格反弹至$75.00。将剩余合约的止损移动至$73.00(盈亏平衡减去小额缓冲)。价格达到$76.50——为$3.00利润平仓一份合约。使用当前在$74.80的10日 EMA 追踪剩余合约的止损。
第9步 — 出场。 价格达到$78.50,略高于之前高点。RSI(14) 达到75——超买。周线图显示价格处于上通道线。MACD 柱状图开始下降。在随机交叉卖出信号时以$78.00平仓最后一份合约。
第10步 — 交易后回顾。 合约1:+$3.00 ($3,000)。合约2:+$4.50 ($4,500)。总利润:$7,500。风险回报:$7,500 / $5,000 = 1.5:1实现(计划最低3:1;部分退出策略降低了实现比率但锁定了保证利润)。在日记中记录交易。备注:跨市场一致和周线趋势确认是信心的主要原因。
function detect_trend(prices, lookback=50):
highs = rolling_max(prices.high, lookback)
lows = rolling_min(prices.low, lookback)
higher_highs = highs[-1] > highs[-lookback//2] > highs[-lookback]
higher_lows = lows[-1] > lows[-lookback//2] > lows[-lookback]
lower_highs = highs[-1] < highs[-lookback//2] < highs[-lookback]
lower_lows = lows[-1] < lows[-lookback//2] < lows[-lookback]
if higher_highs and higher_lows:
trend = "UPTREND"
elif lower_highs and lower_lows:
trend = "DOWNTREND"
else:
trend = "SIDEWAYS"
sma_50 = SMA(prices.close, 50)
sma_200 = SMA(prices.close, 200)
ma_trend = "BULLISH" if sma_50 > sma_200 else "BEARISH"
adx = compute_ADX(prices, 14)
is_trending = adx > 25
return {
trend: trend,
ma_trend: ma_trend,
adx: adx,
is_trending: is_trending,
recommended_approach: "TREND_FOLLOW" if is_trending else "OSCILLATOR"
}
function compute_trendline(prices, direction, min_touches=3):
if direction == "UP":
pivots = find_swing_lows(prices, window=5)
line = linear_regression(pivots)
touches = count_touches(prices.low, line, tolerance=0.5%)
valid = touches >= min_touches
else:
pivots = find_swing_highs(prices, window=5)
line = linear_regression(pivots)
touches = count_touches(prices.high, line, tolerance=0.5%)
valid = touches >= min_touches
return {
slope: line.slope,
intercept: line.intercept,
touches: touches,
valid: valid,
current_value: line.project(current_bar)
}
function check_trendline_break(price, trendline, penetration_filter=0.03):
if trendline.direction == "UP":
break_level = trendline.current_value * (1 - penetration_filter)
is_broken = price.close < break_level
else:
break_level = trendline.current_value * (1 + penetration_filter)
is_broken = price.close > break_level
return is_broken
function scan_head_and_shoulders(prices, window=60):
peaks = find_swing_highs(prices, window=5)
troughs = find_swing_lows(prices, window=5)
if len(peaks) < 3 or len(troughs) < 2:
return None
left_shoulder = peaks[-3]
head = peaks[-2]
right_shoulder = peaks[-1]
neckline_left = troughs[-2]
neckline_right = troughs[-1]
is_valid = (
head.price > left_shoulder.price and
head.price > right_shoulder.price and
abs(left_shoulder.price - right_shoulder.price) / head.price < 0.03 and
abs(neckline_left.price - neckline_right.price) / head.price < 0.03
)
if not is_valid:
return None
neckline = linear_fit(neckline_left, neckline_right)
pattern_height = head.price - neckline.at(head.bar)
target = neckline.current_value - pattern_height
signal = prices.close[-1] < neckline.current_value
return {
pattern: "HEAD_AND_SHOULDERS",
neckline: neckline.current_value,
target: target,
signal: signal,
volume_declining: volume_at(right_shoulder) < volume_at(left_shoulder)
}
function scan_triangle(prices, window=30):
highs = find_swing_highs(prices[-window:], window=3)
lows = find_swing_lows(prices[-window:], window=3)
if len(highs) < 2 or len(lows) < 2:
return None
upper_slope = (highs[-1].price - highs[-2].price) / (highs[-1].bar - highs[-2].bar)
lower_slope = (lows[-1].price - lows[-2].price) / (lows[-1].bar - lows[-2].bar)
if upper_slope < 0 and lower_slope > 0:
type = "SYMMETRICAL"
elif abs(upper_slope) < 0.001 and lower_slope > 0:
type = "ASCENDING"
elif upper_slope < 0 and abs(lower_slope) < 0.001:
type = "DESCENDING"
else:
return None
vol_trend = linear_regression(volumes[-window:])
volume_contracting = vol_trend.slope < 0
if upper_slope != lower_slope:
apex_bar = (lows[-2].price - highs[-2].price) / (upper_slope - lower_slope)
progress = window / apex_bar
timing_valid = 0.5 < progress < 0.75
else:
timing_valid = False
base_height = highs[-len(highs)//2].price - lows[-len(lows)//2].price
return {
pattern: "TRIANGLE_" + type,
upper_boundary: project_line(highs, current_bar),
lower_boundary: project_line(lows, current_bar),
target_up: upper_boundary + base_height,
target_down: lower_boundary - base_height,
volume_contracting: volume_contracting,
timing_valid: timing_valid
}
function scan_double_top(prices, tolerance=0.02, min_gap=10):
peaks = find_swing_highs(prices, window=5)
for i in range(len(peaks)-1):
for j in range(i+1, len(peaks)):
if abs(peaks[i].price - peaks[j].price) / peaks[i].price < tolerance:
if peaks[j].bar - peaks[i].bar >= min_gap:
trough = min(prices.low[peaks[i].bar : peaks[j].bar])
height = peaks[i].price - trough
signal = prices.close[-1] < trough
return {
pattern: "DOUBLE_TOP",
peak_level: (peaks[i].price + peaks[j].price) / 2,
neckline: trough,
target: trough - height,
signal: signal,
volume_lighter_second: vol_at(peaks[j]) < vol_at(peaks[i])
}
return None
function RSI(prices, period=14):
changes = diff(prices.close)
gains = [max(c, 0) for c in changes]
losses = [abs(min(c, 0)) for c in changes]
avg_gain = EMA(gains, period)
avg_loss = EMA(losses, period)
rs = avg_gain / max(avg_loss, 0.0001)
rsi = 100 - (100 / (1 + rs))
price_highs = find_swing_highs(prices.close, 5)
rsi_highs = find_swing_highs(rsi, 5)
bearish_div = (price_highs[-1] > price_highs[-2] and
rsi_highs[-1] < rsi_highs[-2])
price_lows = find_swing_lows(prices.close, 5)
rsi_lows = find_swing_lows(rsi, 5)
bullish_div = (price_lows[-1] < price_lows[-2] and
rsi_lows[-1] > rsi_lows[-2])
return {
value: rsi[-1],
overbought: rsi[-1] > 70,
oversold: rsi[-1] < 30,
bearish_divergence: bearish_div,
bullish_divergence: bullish_div
}
function Stochastic(prices, k_period=14, d_period=3, smooth=3):
lowest = rolling_min(prices.low, k_period)
highest = rolling_max(prices.high, k_period)
fast_k = 100 * (prices.close - lowest) / max(highest - lowest, 0.0001)
slow_k = SMA(fast_k, smooth)
slow_d = SMA(slow_k, d_period)
crossover_buy = slow_k[-1] > slow_d[-1] and slow_k[-2] <= slow_d[-2] and slow_d[-1] < 20
crossover_sell = slow_k[-1] < slow_d[-1] and slow_k[-2] >= slow_d[-2] and slow_d[-1] > 80
return {
k: slow_k[-1],
d: slow_d[-1],
overbought: slow_d[-1] > 80,
oversold: slow_d[-1] < 20,
buy_signal: crossover_buy,
sell_signal: crossover_sell
}
function MACD(prices, fast=12, slow=26, signal=9):
ema_fast = EMA(prices.close, fast)
ema_slow = EMA(prices.close, slow)
macd_line = ema_fast - ema_slow
signal_line = EMA(macd_line, signal)
histogram = macd_line - signal_line
signal_cross_buy = macd_line[-1] > signal_line[-1] and macd_line[-2] <= signal_line[-2]
signal_cross_sell = macd_line[-1] < signal_line[-1] and macd_line[-2] >= signal_line[-2]
zero_cross_buy = macd_line[-1] > 0 and macd_line[-2] <= 0
zero_cross_sell = macd_line[-1] < 0 and macd_line[-2] >= 0
hist_rising = histogram[-1] > histogram[-2]
hist_falling = histogram[-1] < histogram[-2]
return {
macd: macd_line[-1],
signal: signal_line[-1],
histogram: histogram[-1],
buy_signal: signal_cross_buy,
sell_signal: signal_cross_sell,
bullish_zero_cross: zero_cross_buy,
bearish_zero_cross: zero_cross_sell,
histogram_momentum: "RISING" if hist_rising else "FALLING"
}
function WilliamsR(prices, period=14):
highest = rolling_max(prices.high, period)
lowest = rolling_min(prices.low, period)
wr = -100 * (highest - prices.close) / max(highest - lowest, 0.0001)
return {
value: wr[-1],
overbought: wr[-1] > -20,
oversold: wr[-1] < -80
}
function CCI(prices, period=20, constant=0.015):
tp = (prices.high + prices.low + prices.close) / 3
sma_tp = SMA(tp, period)
mean_dev = rolling_mean_deviation(tp, period)
cci = (tp - sma_tp) / (constant * mean_dev)
return {
value: cci[-1],
strong: cci[-1] > 100,
weak: cci[-1] < -100
}
function intermarket_analysis(dollar, bonds, commodities, stocks):
dollar_trend = detect_trend(dollar)
bond_trend = detect_trend(bonds)
comm_trend = detect_trend(commodities)
stock_trend = detect_trend(stocks)
dollar_comm_inverse = (
(dollar_trend.trend == "UPTREND" and comm_trend.trend == "DOWNTREND") or
(dollar_trend.trend == "DOWNTREND" and comm_trend.trend == "UPTREND")
)
bond_comm_inverse = (
(bond_trend.trend == "UPTREND" and comm_trend.trend == "DOWNTREND") or
(bond_trend.trend == "DOWNTREND" and comm_trend.trend == "UPTREND")
)
return {
dollar_trend: dollar_trend,
bond_trend: bond_trend,
comm_trend: comm_trend,
stock_trend: stock_trend,
relationships_valid: {
"dollar_comm_inverse": dollar_comm_inverse,
"bond_comm_inverse": bond_comm_inverse
}
}
"技术分析本质上是研究市场行为——主要通过图表——目的是预测未来价格趋势。"
"技术分析的艺术——因为它是一门艺术——是在相对早期阶段识别趋势反转并持有直到证据权重显示趋势已经反转。"
"顺势而为。在清晰确认趋势反转之前,假设趋势持续是合适的。"
"成交量是衍生信息——它跟随价格运动。如果价格和成交量不一致,其中一个必须让步。"
"最重要的单一信息是趋势的方向。不要逆势而行。"
"摆动指标在市场横向盘整时最有用,在趋势市场中倾向于误导。"
"没有任何单一指标或系统始终有效。成功的分析师结合几种方法并权衡证据。"
"期货市场中的杠杆是双刃剑。它放大了利润和损失。资金管理的重要性怎么强调都不为过。"
"将你的分析限制在你完全理解的市场。技术分析在流动性好、趋势明显的期货合约中最有效。"
"市场自己照顾自己。技术分析师的工作不是预测而是反应——尽早识别趋势并坚持直到有明确理由退出。"
实施规范结束。