基于 Robert D. Edwards & John Magee,Technical Analysis of Stock Trends(第十版)
股票的市场价格反映了在任何给定时刻对该股票可知的一切。所有基本面数据、内幕知识、机构持仓和大众心理学都已嵌入价格和成交量行为中。技术分析师不需要知道 为什么 价格会移动——只知道它们会移动,并以可识别、可重复的形态移动。
市场行为消化一切。 价格是最终的仲裁者。财报、利率决策、地缘政治事件——所有这些在公众意识到之前就已定价,因为知情参与者先行动。
价格按趋势移动。 处于运动中的股票倾向于保持运动。趋势持续直到出现明确的反转信号。技术分析师的首要任务是在早期识别趋势并持有直到证据表明趋势已结束。
历史重演。 图表形态会重现,因为人性不会改变。恐惧、贪婪、希望和绝望在每一代人身上产生相同的价格足迹。
Edwards 和 Magee 几乎完全专注于价格-成交量K线图分析。他们的方法是视觉形态识别,加上确认、测量含义和止损设置的严格规则。这本书本质上是 决策框架:何时行动、预期多少、以及何时承认分析错误。
原则1:平均指数消化一切。 道琼斯工业平均指数和运输平均指数共同反映了所有市场知识和预期的总和。没有事件能逃脱市场的定价机制。
原则2:市场有三种趋势。
原则3:主要趋势有三个阶段。
原则4:平均指数必须相互确认。 有效的主要趋势信号需要工业和运输指数都在合理时间内创出新高(牛市)或新低(熊市)。一个指数单独创新高值得怀疑,必须在得到确认后才能行动。时间越近,确认越强。
原则5:成交量必须确认趋势。 在牛市中,成交量应在上涨时扩大,在回调时收缩。在熊市中,成交量应在下跌时扩大,在反弹时收缩。成交量是次要指标——价格优先——但价格与成交量的背离是早期警告。
原则6:趋势被假定持续直到给出明确的反转信号。 这是实施中最重要的原则。不要预测反转。等待确认信号。举证责任总是在反转上,而非持续上。
| 信号 | 条件 |
|---|---|
| 牛市确认 | 工业和运输指数都创出高于先前次要反应峰值的新高 |
| 熊市确认 | 工业和运输指数都创出低于先前次要反应谷底的新低 |
| 非确认(警告) | 一个指数创新高/低但另一个在合理窗口内未能确认 |
| 次要反应确认 | 下跌达先前主要上涨的33-66%,持续3+周,成交量下降 |
日K线图是主要分析工具。每根K线记录:
构建规则:
点数图剥离时间,专注于纯粹的价格运动:
识别规则:
成交量形态:
测量公式:
入场触发:
止损设置:
失败条件:
识别规则: 头肩顶的镜像,但有一个关于成交量的关键区别:
测量公式: 与常规头肩形态相同——从头低到颈线的距离,从突破点向上投射。
入场触发:
止损设置:
双顶识别:
双底识别:
测量公式:
常见错误: 在谷底被跌破之前不要称为双顶。两个相同水平的峰值在确认之前只是阻力。许多明显的双顶向上解决。
入场和止损:
识别:
与矩形区分:
测量公式:
特征:
实施挑战:
没有特定测量公式:
特征:
实施挑战:
确认:
| 形态 | 最短持续时间 | 成交量特征 | 测量目标 | 可靠性 |
|---|---|---|---|---|
| 头肩顶 | 1-3个月 | 右肩成交量下降 | 头到颈线距离 | 高 |
| 头肩底 | 1-3个月 | 突破时必须扩大 | 头到颈线距离 | 高 |
| 双顶 | 峰值间隔3+周 | 第二个峰值较轻 | 峰值到谷底距离 | 中-高 |
| 双底 | 低点间隔3+周 | 突破时扩大 | 谷底到峰值距离 | 中-高 |
| 三顶/三底 | 2+个月 | 每次测试成交量下降 | 形态高度 | 高 |
| 碟形 | 数周至数月 | 碟形成交量 | 无特定公式 | 中 |
| V形 | 数天 | 高潮成交量飙升 | 无特定公式 | 低(难交易) |
识别:
突破规则:
测量公式:
重要提示:
识别:
方向偏见:
突破规则:
测量公式:
识别:
方向偏见:
突破和测量:
识别:
方向偏见:
测量公式:
在矩形内交易:
识别:
半旗规则:
入场触发:
止损设置:
失败:
上升楔形:
下降楔形:
测量公式:
| 形态 | 典型持续时间 | 偏见 | 成交量 | 测量方法 |
|---|---|---|---|---|
| 对称三角形 | 1-3个月 | 持续 | 收缩,突破时扩大 | 底部宽度从突破点 |
| 上升三角形 | 1-3个月 | 看涨 | 收缩,突破时扩大 | 高度从突破点 |
| 下降三角形 | 1-3个月 | 看跌 | 收缩,突破时扩大 | 高度从突破点 |
| 矩形 | 1-3个月 | 持续 | 混合;向突破方向较重 | 高度从突破点 |
| 旗形 | 1-3周 | 持续 | 干涸,突破时飙升 | 旗杆 = 剩余移动 |
| 尖旗 | 1-3周 | 持续 | 干涸,突破时飙升 | 旗杆 = 剩余移动 |
| 上升楔形 | 3-6周 | 看跌 | 收缩 | 返回楔形起源 |
| 下降楔形 | 3-6周 | 看涨 | 收缩 | 返回楔形起源 |
普通(区域)缺口:
突破缺口:
逃逸(测量)缺口:
衰竭缺口:
岛形反转:
1. 缺口在盘整区域内吗?
是 → 普通缺口(忽略)
否 → 继续步骤2
2. 缺口从明确定义的图表形态中突破吗?
是 → 突破缺口(沿方向交易)
否 → 继续步骤3
3. 趋势已经确立了吗?
否 → 可能是突破缺口
是 → 继续步骤4
4. 移动已经运行很长时间且已有多个缺口了吗?
否 → 可能是逃逸/测量缺口
是 → 可能是衰竭缺口(观察反转)
成交量确认趋势方向:
成交量领先价格:
顶部:
底部:
由 Joseph Granville 引入,在后续版本中引用:
买入高潮:
卖出高潮:
先前的高点和低点。 任何重要的摆动高或低都成为潜在支撑/阻力水平。摆动越突出,水平越重要。
盘整区域。 价格长时间来回交易的区域。在一个水平交易的成交量越多,参与者对该价格的承诺越大,作为支撑或阻力就越重要。
整数。 心理重要性:$10、$25、$50、$100。许多订单聚集在整数,创建自然的支撑和阻力。
先前缺口边界。 未填补缺口的边缘作为支撑和阻力。
这是书中最重要的概念之一:
机制:在阻力附近卖出的参与者现在后悔卖出,会在回调至该水平时买入(旧阻力成为支撑)。在支撑附近买入并看着它破位的参与者现在想要"保本出",会在反弹回该水平时卖出(旧支撑成为阻力)。
对于每个价格水平 L:
significance_score = (触点数量 * 2)
+ (该水平总成交量 / 平均成交量)
+ (自首次接触以来的周数 / 4)
+ (如果是整数则 +3)
如果 significance_score > 阈值:
将 L 标记为重要支撑/阻力水平。
两点趋势线:
三点趋势线:
绘制规则:
当陡峭趋势线被突破时:
扇形原则起作用是因为每条连续的趋势线都较缓,代表动量减速。当甚至最缓的可持续趋势线也被突破时,趋势已衰竭。
由 Edson Gould 开发,纳入后续版本:
解读:
并非每个趋势线突破都重要。Edwards 和 Magee 提供了几种过滤:
百分比过滤(1-3%规则):
两天规则:
成交量过滤:
组合过滤(推荐方法):
简单移动平均线(SMA):
加权移动平均线(WMA):
指数移动平均线(EMA):
EMA_今日 = (收盘 - EMA_昨日) * 乘数 + EMA_昨日乘数 = 2 / (N + 1)| 周期 | 用途 |
|---|---|
| 10日 | 短期交易,捕捉微小波动 |
| 20日 | 约一个月; swing 交易者流行 |
| 50日 | 中期趋势;机构基准。股价在50日均线上方是"健康" |
| 150日 | 长期趋势过滤;Stan Weinstein 阶段分析使用30周(约150日) |
| 200日 | 主要趋势的黄金标准。机构广泛注视 |
价格-MA 交叉:
双 MA 交叉:
三重 MA 系统:
作者强调移动平均线是次要工具。图表形态和趋势线优先。移动平均线用于:
移动平均线不适用于:
最可靠的止损设置方法是使用图表形态本身:
| 情况 | 止损位置 |
|---|---|
| 头肩底突破后做多 | 右肩低点下方 |
| 双底突破后做多 | 第二个低点下方 |
| 上升三角形突破后做多 | 三角形内最后反应低点下方 |
| 旗形突破后做多 | 旗形最低点下方 |
| 头肩顶破位后做空 | 右肩高点上方 |
| 下降三角形破位后做空 | 三角形内最后反弹高点上方 |
逻辑很简单:如果形态有效,价格不应返回形态另一侧。如果返回,形态失败,必须退出。
当满足以下条件时确认牛市:
实施逻辑:
state = BEAR(默认)
每当道琼斯工业平均指数创新高时:
检查:道琼斯运输平均指数自上次次要反应以来也创新高了吗?
如果是:state = BULL
每当道琼斯工业平均指数创新低时:
检查:道琼斯运输平均指数自上次次要反弹以来也创新低了吗?
如果是:state = BEAR
当满足以下条件时确认熊市:
-许多从业者用标普500代替道琼斯工业平均指数,用运输 ETF(IYT)或道琼斯运输平均指数代替运输平均指数。
看到不存在的形态。 确认偏见是技术分析师最大的敌人。形态在满足所有识别标准之前无效。如果你正在眯眼和合理化,它就不是形态。
在确认之前行动。 头肩形态直到颈线突破才是头肩形态。双顶直到谷底突破才是双顶。预测完结是亏损之路。
忽视成交量。 没有成交量确认的突破(尤其是上涨突破)不可靠。成交量是市场的测谎仪。
在不适合的股票上使用形态。 交易清淡的股票、微型股和被严重操纵的股票不会形成可靠形态。坚持流通、活跃交易的股票。
混淆时间周期。 日线图上的形态和周线图上的形态分量不同。始终知道你在哪个时间周期交易。
对抗主要趋势。 反对主要趋势的形态交易成功率高得多。只要可能,沿主要趋势方向交易。
重新绘制趋势线以避免承认突破。 如果趋势线被突破,接受它。如果趋势恢复,从头绘制新的。
忽视扇形原则。 当陡峭趋势线被突破时,它们通常被更缓的替换。第三条扇形线突破是明确信号。
没有止损。 每笔交易必须有预定义的亏损退出点。没有止损,小亏损变大亏损,大亏损变成灾难。
将止损移向错误方向。 止损是基于形态的无效点设置的。如果你移动它给交易"更多空间",你是在用希望覆盖分析。
基于信念而非风险确定仓位大小。 根据止损位置确定仓位大小,而不是根据你有多自信。市场不在乎你的信念。
过早卖出赢家而持有输家。 处置效应。让赢家运行至测量目标。在止损位砍输家。
第1步:背景评估
第2步:形态识别
第3步:测量目标
第4步:风险评估
第5步:入场执行
第6步:交易管理
第7步:出场
结果:
function detect_head_and_shoulders(prices, volumes, lookback=120):
pivots = find_pivot_points(prices, lookback)
highs = [p for p in pivots if p.type == HIGH]
lows = [p for p in pivots if p.type == LOW]
for i in range(len(highs) - 2):
left_shoulder = highs[i]
head = highs[i+1]
right_shoulder = highs[i+2]
if head.price <= left_shoulder.price or head.price <= right_shoulder.price:
continue
shoulder_diff = abs(left_shoulder.price - right_shoulder.price) / left_shoulder.price
if shoulder_diff > 0.05:
continue
low_1 = find_lowest_between(lows, left_shoulder.date, head.date)
low_2 = find_lowest_between(lows, head.date, right_shoulder.date)
if low_1 is None or low_2 is None:
continue
neckline = Line(low_1, low_2)
vol_left = average_volume(volumes, left_shoulder.date, window=5)
vol_right = average_volume(volumes, right_shoulder.date, window=5)
if vol_right >= vol_left:
continue
neckline_at_head = neckline.value_at(head.date)
pattern_height = head.price - neckline_at_head
current_price = prices[-1]
current_neckline = neckline.value_at(current_date)
if current_price < current_neckline:
return {
'pattern': 'HEAD_AND_SHOULDERS_TOP',
'left_shoulder': left_shoulder,
'head': head,
'right_shoulder': right_shoulder,
'neckline': neckline,
'target': current_neckline - pattern_height,
'stop': right_shoulder.price,
'confirmed': True
}
return None
function detect_triangle(prices, lookback=90):
pivots = find_pivot_points(prices, lookback)
highs = [p for p in pivots if p.type == HIGH]
lows = [p for p in pivots if p.type == LOW]
if len(highs) < 2 or len(lows) < 2:
return None
upper_line = linear_regression(highs)
lower_line = linear_regression(lows)
upper_slope = upper_line.slope
lower_slope = lower_line.slope
FLAT_THRESHOLD = 0.001
if upper_slope < -FLAT_THRESHOLD and lower_slope > FLAT_THRESHOLD:
triangle_type = 'SYMMETRICAL'
bias = 'CONTINUATION'
elif abs(upper_slope) < FLAT_THRESHOLD and lower_slope > FLAT_THRESHOLD:
triangle_type = 'ASCENDING'
bias = 'BULLISH'
elif upper_slope < -FLAT_THRESHOLD and abs(lower_slope) < FLAT_THRESHOLD:
triangle_type = 'DESCENDING'
bias = 'BEARISH'
else:
return None
if upper_slope - lower_slope >= 0:
return None
apex_date = (lower_line.intercept - upper_line.intercept) / (upper_slope - lower_slope)
base_date = min(highs[0].date, lows[0].date)
current_position = (current_date - base_date) / (apex_date - base_date)
if current_position < 0.5 or current_position > 0.75:
pass
base_width = highs[0].price - lows[0].price
current_price = prices[-1]
upper_boundary = upper_line.value_at(current_date)
lower_boundary = lower_line.value_at(current_date)
if current_price > upper_boundary:
return {
'pattern': f'{triangle_type}_TRIANGLE',
'breakout_direction': 'UP',
'target': current_price + base_width,
'stop': lower_boundary,
'bias': bias
}
elif current_price < lower_boundary:
return {
'pattern': f'{triangle_type}_TRIANGLE',
'breakout_direction': 'DOWN',
'target': current_price - base_width,
'stop': upper_boundary,
'bias': bias
}
return {
'pattern': f'{triangle_type}_TRIANGLE',
'breakout_direction': 'PENDING',
'upper_boundary': upper_boundary,
'lower_boundary': lower_boundary,
'bias': bias
}
function find_support_resistance(prices, volumes, lookback=252):
levels = {}
pivots = find_pivot_points(prices, lookback)
for pivot in pivots:
matched = False
for level in levels:
if abs(pivot.price - level) / level < 0.015:
levels[level].append(pivot)
matched = True
break
if not matched:
levels[pivot.price] = [pivot]
scored_levels = []
for price, touches in levels.items():
score = 0
score += len(touches) * 2
score += sum(v.volume for v in touches) / avg_vol
score += (current_date - touches[0].date).days / 30
if price % 10 == 0 or price % 25 == 0:
score += 3
scored_levels.append({
'price': price,
'touches': len(touches),
'score': score,
'type': 'SUPPORT' if price < current_price else 'RESISTANCE'
})
return sorted(scored_levels, key=lambda x: x['score'], reverse=True)[:10]
function detect_flag(prices, volumes, lookback=30):
pole_lookback = 15
recent_high = max(prices[-pole_lookback:])
recent_low = min(prices[-pole_lookback:])
pole_move = (recent_high - recent_low) / recent_low
if pole_move < 0.08:
return None
if prices[-1] > prices[-pole_lookback]:
pole_direction = 'UP'
pole_start = recent_low
pole_end = recent_high
else:
pole_direction = 'DOWN'
pole_start = recent_high
pole_end = recent_low
consolidation = prices[-10:]
consol_range = max(consolidation) - min(consolidation)
pole_range = abs(pole_end - pole_start)
if consol_range / pole_range > 0.38:
return None
vol_during_pole = mean(volumes[-pole_lookback:-10])
vol_during_consol = mean(volumes[-10:])
if vol_during_consol >= vol_during_pole:
return None
consol_slope = linear_regression(consolidation).slope
if pole_direction == 'UP' and consol_slope > 0:
return None
if pole_direction == 'DOWN' and consol_slope < 0:
return None
if pole_direction == 'UP':
target = pole_end + pole_range
stop = min(consolidation)
else:
target = pole_start - pole_range
stop = max(consolidation)
return {
'pattern': 'FLAG' if pole_direction == 'UP' else 'PENNANT',
'direction': pole_direction,
'target': target,
'stop': stop,
'pole_move': pole_move,
'consolidation_slope': consol_slope
}
"市场价格反映了在任一时刻可知晓的关于该股票的一切。"
"处于运动中的趋势倾向于保持运动,直到明确的反转信号出现。"
"图表形态会重现,因为驱动它们的人类心理不会改变。"
"交易量确认价格运动。在牛市中,上涨的成交量应大于下跌的成交量。在熊市中则相反。"
"形态越大,其后续运动越大。"
"在价格上涨之前积累。在价格下跌之前派发。"
"趋势线需要三个点来确认。在那之前,它只是试探性的。"
"止损是保险——你购买它,希望永远不需要使用它。"
"技术分析不是关于预测确定性;而是关于识别概率。"
"最重要的规则是:永远不要与主要趋势对抗。"
实施规范结束。