基于Gregory Morris,《日本蜡烛图技术》
蜡烛图技术的根源可以追溯到18世纪的日本,传奇米交易商Munehisa Homma——来自坂田——开发了分析大阪堂岛米交易所期货价格的技术。Homma的方法演变成我们现在认识的蜡烛图分析。据报道,他执行了超过100 consecutive winning trades并积累了巨额财富,赢得了"市场之神"的称号。
日本方法比西方条形图分析早了一个多世纪。当Charles Dow在1880年代制定他的理论时,日本交易者已经花了200年完善视觉价格分析。Steve Nison在1990年代早期将这些技术引入西方世界;Gregory Morris的工作在此基础上进行了严格的统计测试和实用实施指导。
蜡烛图哲学建立在几个原则上:
| <- 上影线
+-+
| | <- 实际体(开盘到收盘)
| | 白/绿 = 收盘 > 开盘(看涨)
+-+ 黑/红 = 收盘 < 开盘(看跌)
| <- 下影线
全文使用的关键测量:
body_size = abs(close - open)
upper_shadow = high - max(open, close)
lower_shadow = min(open, close) - low
total_range = high - low
body_midpoint = (open + close) / 2
定义: 开盘和收盘相等(或几乎相等)的蜡烛。
识别规则:
body_size <= total_range * 0.05(实体小于总范围的5%)变体:
| 变体 | 上影线 | 下影线 | 含义 |
|---|---|---|---|
| 标准十字星 | 大致相等 | 大致相等 | 纯犹豫 |
| 长腿十字星 | 很长 | 很长 | 极度犹豫,通常在转折点 |
| 蜻蜓十字星 | 最小 | 很长 | 底部看涨反转 |
| 墓碑十字星 | 很长 | 最小 | 顶部看跌反转 |
| 四价十字星 | 无 | 无 | 开盘 = 高 = 低 = 收盘;超低成交量 |
意义: 强趋势后的十字星表示 dominant side正在失去信念。它本身不反转趋势;它警告趋势 vulnerable。
定义: 小实体在范围上端,长下影。出现在下降趋势中。最有效的单蜡烛看涨反转信号。
识别规则:
lower_shadow >= body_size * 2.0(下影至少是实体的两倍)upper_shadow <= body_size * 0.3(上影非常小或没有)心理: 卖家在会话期间将价格推到新低,但买家 aggressive enter并推动价格回到接近开盘。长下影是需求的证据。
定义: 与锤子形状相同,但出现在上升趋势中。看跌警告。
识别规则:
关键区别: 没有次日确认,吊人远比锤子不可靠。许多吊人在强劲上升趋势中失败。莫里斯强调没有次日确认的吊人应该被忽略。
定义: 小实体在范围下端,长上影。出现在上升趋势中。看跌反转信号。
识别规则:
upper_shadow >= body_size * 2.0lower_shadow <= body_size * 0.3心理: 买家将价格推到新高,但卖家压倒他们,推动收盘回到接近开盘。长上影是被拒绝更高价格的视觉 record。
定义: 与流星形状相同,但出现在下降趋势中。看涨信号。
识别规则:
定义: 没有阴影(或非常小的阴影)的蜡烛。代表一方完全 dominance。
识别规则:
upper_shadow <= total_range * 0.01lower_shadow <= total_range * 0.01body_size >= total_range * 0.95变体:
意义: Marubozu表示极端信念。当它出现在整合期之后,通常标志着持续 move 的开始。
定义: 小实体,上下影比实体长。
识别规则:
body_size <= total_range * 0.30upper_shadow > body_sizelower_shadow > body_size意义: 轻度犹豫。不如十字星有力,但当出现在强 directional move 后仍表示动量减弱。
定义: 两根蜡烛形态,大白实体完全吞没先前的小黑实体。出现在下降趋势中。
识别规则:
open_2 < close_1 AND close_2 > open_1定义: 看涨吞没的镜像。大黑实体吞没先前的小白实体 in an uptrend。
识别规则:
open_2 > close_1 AND close_2 < open_1定义: 吞没的反面——小实体包含在先前大实体内。"Harami"在日语中意思是"怀孕"。
看涨孕线规则(在下降趋势中):
open_2 > close_1 AND close_2 < open_1(对于看跌第1根)看跌孕线规则(在上升趋势中):
十字孕线: 当第2根是十字星时,形态称为十字孕线,carries significantly more reversal weight。
定义: 下降趋势中的看涨反转形态。第2根在先前低点下方开盘,收于先前实体的中点上方。
识别规则:
open_2 < low_1(在先前低点下方缺口)close_2 > body_midpoint_1(收于第1实体中点上方)close_2 < open_1(不完全吞没——那将是吞没形态)定义: 刺透线的看跌镜像。在上升趋势中,第2根在先前高点上方开盘,收于先前实体的中点下方。
识别规则:
open_2 > high_1close_2 < body_midpoint_1close_2 > close_1(不完全吞没)定义: 两根或多根具有匹配高点(捉腰带顶)或匹配低点(捉腰带底)的蜡烛。
捉腰带底规则:
abs(low_1 - low_2) <= ATR * 0.01(低点大致相等)捉腰带顶规则:
abs(high_1 - high_2) <= ATR * 0.01意义: 捉腰带标记精确的支撑/阻力水平。它们的可靠性在 component candles本身是可识别的形态时增加(例如,由锤子和看涨吞没形成的捉腰带底)。
定义: 三根蜡烛的看涨反转在下降趋势底部。
识别规则:
max(open_2, close_2) < close_1(理想缺口;在股票中,缺口常见;在外汇中,如果第2根实体非常小,重叠可接受)close_3 > body_midpoint_1晨星十字星: 当第2根是十字星时,形态称为晨星十字星,被认为更强大。
定义: 暮星的看跌镜像。三根蜡烛在顶部反转。
识别规则:
close_3 < body_midpoint_1定义: 三根连续长看涨蜡烛,每根在前一根实体内开盘,收于或接近其高点。看涨持续/反转信号。
识别规则:
open_n > close_(n-1) * 0.7 + open_(n-1) * 0.3(近似——在前一根实体下部开盘)upper_shadow_n <= body_size_n * 0.2定义: 三白兵的看跌镜像。三根连续长看跌蜡烛,每根在前一根实体内开盘,close near its low。
识别规则:
lower_shadow_n <= body_size_n * 0.2定义: 看涨孕线 followed by a confirmation candle that closes above the first candle's open。
识别规则:
close_3 > open_1定义: 看跌孕线 followed by a confirmation candle that closes below the first candle's close。
识别规则:
close_3 < close_1定义: 看涨持续形态。长白蜡烛后跟三根(有时两根或四根)小下降蜡烛,stay within the range of the first candle,然后一根最终大白蜡烛收于第一根高点上方。
识别规则:
定义: 看跌镜像。长黑蜡烛,三根小上升蜡烛在其范围内,然后一根最终大黑蜡烛收于第一根低点下方。
定义: 在上升趋势中,看涨蜡烛与先前看涨蜡烛向上缺口。第3根看跌蜡烛在第2根实体内开盘,收于缺口内但不完全填补。
识别规则:
low_2 > high_1)close_3 > high_1定义: 看跌镜像。gap-down序列,第3根部分填补缺口但不关闭。
定义: 在上升趋势中,看跌蜡烛后跟看涨蜡烛,在看跌蜡烛的开盘价相同价位开盘。趋势继续上涨。
识别规则(看涨):
abs(open_2 - open_1) <= ATR * 0.005成交量是蜡烛图形态确认的最重要单一工具。
规则:
莫里斯强调许多形态需要下一个交易日确认:
蜡烛图分析中最重要的规则:
中间横向范围的锤子不是反转信号。下降趋势中的暮星是无意义的。趋势上下文是不可协商的。
在既定支撑或阻力位出现的形态具有2-3倍的重要性:
集成方法:
示例: 价格下跌至200日移动平均线,一根锤子恰好触及200日MA。次日开盘更高。入场:在锤子高点上方。止损:在锤子低点下方(也在200日MA下方)。这将蜡烛图逻辑与西方结构分析结合。
| 情况 | 信号强度 |
|---|---|
| 看涨形态在上升50日MA | 强 |
| 看跌形态在下降50日MA | 强 |
| 在收敛50/200 MA的形态 | 非常强 |
| 远离任何MA的形态 | 较弱;无结构锚 |
莫里斯提供统计测试结果。形态按可靠性排名:
关键洞察: 没有形态超过约75%可靠性。优势来自将形态与趋势上下文、支撑/阻力和成交量结合。
1. 识别 prevailing trend(上升、下降或横向)。
2. 等待价格达到显著水平(S/R、MA、趋势线)。
3. 识别蜡烛图反转或持续形态。
4. 用成交量和/或次日价格行为确认。
5. 在确认时入场:
- 看涨:在形态最后一根蜡烛高点上方买入。
- 看跌:在形态最后一根蜡烛低点下方卖出。
6. 在形态极端外方放置止损。
7. 在下一显著S/R水平设置目标或使用风险倍数(至少2:1)。
激进入场: 在形态最后一根蜡烛收盘时入场(不等次日确认)。仅用于在具有重成交量的主要水平的第1层形态。
保守入场: 等待次日确认(价格在看涨形态高点上方交易,对于看跌则在低点下方)。接受略微较差的价格以换取更高概率。
超保守入场: 等待收于形态极端上方/下方。错过一些交易但避免大多数假信号。
第1层形态 + 成交量 + 关键水平 -> 完整仓位规模(例如1.0R)
第2层形态 + some confirmation -> 减少仓位(例如0.5-0.75R)
第3-4层形态 -> 最小仓位或跳过(例如0.25R)
| 形态 | 止损放置 |
|---|---|
| 锤子 | 在锤子低点下方 |
| 流星 | 在流星高点上方 |
| 吞没 | 在吞没蜡烛极端外方 |
| 晨星/暮星 | 在星蜡烛极端外方 |
| 刺透线 | 在第1根蜡烛低点下方 |
| 乌云覆盖 | 在第1根蜡烛高点上方 |
始终在形态极端外方添加小缓冲以避免被止损狩猎:
替代方法:将止损放置在 pattern_extreme - 1.5 * ATR(14)。这适应 current volatility并避免 arbitrary fixed-distance止损。
最频繁的错误。锤子不是买入信号。锤子,在支撑,在已成为 overextended 的下降趋势中,有上升成交量,接着确认日——那是买入信号。
初学者在 screaming uptrend中看到"看跌吞没"并做空。形态在趋势上升时不是看跌——它可能只是较大趋势中的回调。首先识别更高时间框架的趋势。
基于回测将实体大小阈值设置到四位小数是曲线拟合。蜡烛图形态本质上是视觉和近似的。使用合理阈值并接受一些主观性是 inherent。
成交量平均以下30%的看涨吞没与成交量200%以上的看涨吞没不同。成交量验证形态背后的信念。
蜡烛图形态告诉您何时入场,不告诉您价格将移动多远。使用单独技术(measured moves、斐波那契扩展、先前S/R)用于目标设置。
蜡烛图形态是为日图设计的。它们可以在周图或4小时图上工作,但在5分钟或1分钟图上,噪音-信号比急剧增加。在更低时间框架上 extended confirmation requirements。
上下文:
- 股票XYZ在8周内从$85下跌至$62。
- 200日MA在$63。6个月前的先前pivot低点在$61.50。
- RSI(14)在28(超卖)。
第1天(周一):
- 大看跌蜡烛:开盘$65.00,高$65.50,低$62.10,收盘$62.50
- 成交量:1.2倍20日平均
- 继续下降到支撑区域。
第2天(周二):
- 小十字星:开盘$61.80,高$62.20,低$61.40,收盘$61.90
- 成交量:0.6倍平均(低成交量 = 犹豫,非信念卖出)
- 在第1根收盘下方缺口。实体微小。这是"星"。
- 低点触及$61.40,就在$61.50 pivot支撑下方。
第3天(周三):
- 大看涨蜡烛:开盘$62.30,高$64.80,低$62.10,收盘$64.50
- 成交量:2.1倍平均(买入兴趣 surge)
- 收于第1天实体深处(第1天中点 = $63.75;收盘$64.50 > $63.75)。
识别形态:在支撑处(200日MA + 先前pivot)的晨星十字星(第1层)。
确认检查清单:
[x] 下降趋势存在(8周下降,较低高低/低)
[x] 形态在显著支撑(200日MA + 先前pivot)
[x] 振荡器超卖(RSI 28)
[x] 第3天成交量 surge
[x] 第3天收于第1天中点上方
入场:买入于$64.90(第3天高点$64.80上方,次日触发)。
止损:$61.25(第2天低点$61.40下方减缓冲)。
风险:$64.90 - $61.25 = 每手$3.65。
目标:$72.00(先前整合区),回报 = $7.10,R:R = 1.95:1。
仓位规模:$100,000账户,risk 1% ($1,000):
股数 = $1,000 / $3.65 = 273股。
仓位价值 = 273 * $64.90 = $17,718(账户的17.7%)。
管理:
- 第5天:价格达到$66.50。移动止损至盈亏平衡($64.90)。
- 第9天:价格达到$69.00。Trailing stop to $67.00(在第8天低点下方)。
- 第12天:价格达到$72.00目标。卖出50%。Trailing remaining with 2-ATR stop。
- 第15天:Trailing stop triggered at $70.50。退出剩余股份。
结果:平均 exit ~$71.25。利润 = ($71.25 - $64.90) * 273 = $1,733(1.73R)。
class Candle:
open: float
high: float
low: float
close: float
volume: float
@property
def body_size(self):
return abs(self.close - self.open)
@property
def upper_shadow(self):
return self.high - max(self.open, self.close)
@property
def lower_shadow(self):
return min(self.open, self.close) - self.low
@property
def total_range(self):
return self.high - self.low
@property
def body_midpoint(self):
return (self.open + self.close) / 2.0
@property
def is_bullish(self):
return self.close > self.open
@property
def is_bearish(self):
return self.close < self.open
@property
def body_top(self):
return max(self.open, self.close)
@property
def body_bottom(self):
return min(self.open, self.close)
def detect_trend(candles, lookback=20):
"""
确定回望期内的 prevailing trend。
返回:'up'、'down'或'sideways'
"""
if len(candles) < lookback:
return 'sideways'
closes = [c.close for c in candles[-lookback:]]
highs = [c.high for c in candles[-lookback:]]
lows = [c.low for c in candles[-lookback:]]
# 收盘的线性回归斜率
slope = linear_regression_slope(closes)
# 计算较高高低 vs 较低低
higher_highs = sum(1 for i in range(1, len(highs)) if highs[i] > highs[i-1])
lower_lows = sum(1 for i in range(1, len(lows)) if lows[i] < lows[i-1])
if slope > 0 and higher_highs > lookback * 0.5:
return 'up'
elif slope < 0 and lower_lows > lookback * 0.5:
return 'down'
else:
return 'sideways'
def is_doji(c: Candle, threshold=0.05) -> bool:
if c.total_range == 0:
return False
return c.body_size / c.total_range <= threshold
def is_dragonfly_doji(c: Candle) -> bool:
return (is_doji(c) and
c.lower_shadow > c.total_range * 0.6 and
c.upper_shadow < c.total_range * 0.1)
def is_gravestone_doji(c: Candle) -> bool:
return (is_doji(c) and
c.upper_shadow > c.total_range * 0.6 and
c.lower_shadow < c.total_range * 0.1)
def is_hammer(c: Candle, trend: str) -> bool:
if trend != 'down':
return False
if c.total_range == 0 or c.body_size == 0:
return False
return (c.lower_shadow >= c.body_size * 2.0 and
c.upper_shadow <= c.body_size * 0.3)
def is_hanging_man(c: Candle, trend: str) -> bool:
if trend != 'up':
return False
if c.total_range == 0 or c.body_size == 0:
return False
return (c.lower_shadow >= c.body_size * 2.0 and
c.upper_shadow <= c.body_size * 0.3)
def is_shooting_star(c: Candle, trend: str) -> bool:
if trend != 'up':
return False
if c.total_range == 0 or c.body_size == 0:
return False
return (c.upper_shadow >= c.body_size * 2.0 and
c.lower_shadow <= c.body_size * 0.3)
def is_inverted_hammer(c: Candle, trend: str) -> bool:
if trend != 'down':
return False
if c.total_range == 0 or c.body_size == 0:
return False
return (c.upper_shadow >= c.body_size * 2.0 and
c.lower_shadow <= c.body_size * 0.3)
def is_marubozu(c: Candle) -> bool:
if c.total_range == 0:
return False
return (c.upper_shadow <= c.total_range * 0.01 and
c.lower_shadow <= c.total_range * 0.01)
def is_spinning_top(c: Candle) -> bool:
if c.total_range == 0:
return False
return (c.body_size <= c.total_range * 0.30 and
c.body_size > c.total_range * 0.05 and # 不是十字星
c.upper_shadow > c.body_size and
c.lower_shadow > c.body_size)
def is_bullish_engulfing(c1: Candle, c2: Candle, trend: str) -> bool:
if trend != 'down':
return False
return (c1.is_bearish and
c2.is_bullish and
c2.open < c1.close and # c2在c1收盘下方开盘
c2.close > c1.open and # c2在c1开盘上方收盘
c2.body_size > c1.body_size)
def is_bearish_engulfing(c1: Candle, c2: Candle, trend: str) -> bool:
if trend != 'up':
return False
return (c1.is_bullish and
c2.is_bearish and
c2.open > c1.close and
c2.close < c1.open and
c2.body_size > c1.body_size)
def is_bullish_harami(c1: Candle, c2: Candle, trend: str) -> bool:
if trend != 'down':
return False
return (c1.is_bearish and
c1.body_size > 0 and
c2.body_bottom > c1.body_bottom and
c2.body_top < c1.body_top and
c2.body_size < c1.body_size * 0.5)
def is_bearish_harami(c1: Candle, c2: Candle, trend: str) -> bool:
if trend != 'up':
return False
return (c1.is_bullish and
c1.body_size > 0 and
c2.body_bottom > c1.body_bottom and
c2.body_top < c1.body_top and
c2.body_size < c1.body_size * 0.5)
def is_piercing_line(c1: Candle, c2: Candle, trend: str) -> bool:
if trend != 'down':
return False
return (c1.is_bearish and
c2.is_bullish and
c2.open < c1.low and
c2.close > c1.body_midpoint and
c2.close < c1.open)
def is_dark_cloud_cover(c1: Candle, c2: Candle, trend: str) -> bool:
if trend != 'up':
return False
return (c1.is_bullish and
c2.is_bearish and
c2.open > c1.high and
c2.close < c1.body_midpoint and
c2.close > c1.close)
def is_tweezer_bottom(c1: Candle, c2: Candle, trend: str, atr: float) -> bool:
if trend != 'down':
return False
tolerance = atr * 0.01
return (abs(c1.low - c2.low) <= tolerance and
c1.is_bearish and c2.is_bullish)
def is_tweezer_top(c1: Candle, c2: Candle, trend: str, atr: float) -> bool:
if trend != 'up':
return False
tolerance = atr * 0.01
return (abs(c1.high - c2.high) <= tolerance and
c1.is_bullish and c2.is_bearish)
def is_morning_star(c1: Candle, c2: Candle, c3: Candle, trend: str) -> bool:
if trend != 'down':
return False
c1_large_bearish = c1.is_bearish and c1.body_size > c1.total_range * 0.5
c2_small_body = c2.body_size < c1.body_size * 0.3
c2_gaps_down = c2.body_top < c1.close # 星在c1收盘下方缺口
c3_large_bullish = c3.is_bullish and c3.body_size > c3.total_range * 0.5
c3_into_c1 = c3.close > c1.body_midpoint
return (c1_large_bearish and c2_small_body and
c3_large_bullish and c3_into_c1)
# 注意:c2_gaps_down是理想的,但对外汇/加密可放宽
def is_evening_star(c1: Candle, c2: Candle, c3: Candle, trend: str) -> bool:
if trend != 'up':
return False
c1_large_bullish = c1.is_bullish and c1.body_size > c1.total_range * 0.5
c2_small_body = c2.body_size < c1.body_size * 0.3
c2_gaps_up = c2.body_bottom > c1.close
c3_large_bearish = c3.is_bearish and c3.body_size > c3.total_range * 0.5
c3_into_c1 = c3.close < c1.body_midpoint
return (c1_large_bullish and c2_small_body and
c3_large_bearish and c3_into_c1)
def is_three_white_soldiers(c1: Candle, c2: Candle, c3: Candle) -> bool:
all_bullish = c1.is_bullish and c2.is_bullish and c3.is_bullish
# 每根在前一根实体内开盘
c2_opens_in_c1 = c1.open < c2.open < c1.close
c3_opens_in_c2 = c2.open < c3.open < c2.close
# 每根收于其高点附近(小上影)
c1_strong_close = c1.upper_shadow <= c1.body_size * 0.25
c2_strong_close = c2.upper_shadow <= c2.body_size * 0.25
c3_strong_close = c3.upper_shadow <= c3.body_size * 0.25
# 实体合理大
avg_range = (c1.total_range + c2.total_range + c3.total_range) / 3.0
c1_large = c1.body_size > avg_range * 0.4
c2_large = c2.body_size > avg_range * 0.4
c3_large = c3.body_size > avg_range * 0.4
return (all_bullish and c2_opens_in_c1 and c3_opens_in_c2 and
c1_strong_close and c2_strong_close and c3_strong_close and
c1_large and c2_large and c3_large)
def is_three_black_crows(c1: Candle, c2: Candle, c3: Candle) -> bool:
all_bearish = c1.is_bearish and c2.is_bearish and c3.is_bearish
c2_opens_in_c1 = c1.close < c2.open < c1.open
c3_opens_in_c2 = c2.close < c3.open < c2.open
c1_strong_close = c1.lower_shadow <= c1.body_size * 0.25
c2_strong_close = c2.lower_shadow <= c2.body_size * 0.25
c3_strong_close = c3.lower_shadow <= c3.body_size * 0.25
avg_range = (c1.total_range + c2.total_range + c3.total_range) / 3.0
c1_large = c1.body_size > avg_range * 0.4
c2_large = c2.body_size > avg_range * 0.4
c3_large = c3.body_size > avg_range * 0.4
return (all_bearish and c2_opens_in_c1 and c3_opens_in_c2 and
c1_strong_close and c2_strong_close and c3_strong_close and
c1_large and c2_large and c3_large)
def is_three_inside_up(c1: Candle, c2: Candle, c3: Candle, trend: str) -> bool:
return (is_bullish_harami(c1, c2, trend) and
c3.is_bullish and
c3.close > c1.open)
def is_three_inside_down(c1: Candle, c2: Candle, c3: Candle, trend: str) -> bool:
return (is_bearish_harami(c1, c2, trend) and
c3.is_bearish and
c3.close < c1.close)
def is_rising_three_methods(candles: list, trend: str) -> bool:
"""需要5根蜡烛:candles[0] 到 candles[4]。"""
if trend != 'up' or len(candles) < 5:
return False
c0, c1, c2, c3, c4 = candles[0], candles[1], candles[2], candles[3], candles[4]
# 第一根蜡烛:大看涨
if not (c0.is_bullish and c0.body_size > c0.total_range * 0.5):
return False
# 中间蜡烛:小,在c0范围内
for mid in [c1, c2, c3]:
if mid.high > c0.high or mid.low < c0.low:
return False
if mid.body_size > c0.body_size * 0.5:
return False
# 最后一根蜡烛:大看涨,收于c0高点上方
if not (c4.is_bullish and c4.close > c0.high):
return False
return True
def is_falling_three_methods(candles: list, trend: str) -> bool:
"""需要5根蜡烛。"""
if trend != 'down' or len(candles) < 5:
return False
c0, c1, c2, c3, c4 = candles[0], candles[1], candles[2], candles[3], candles[4]
if not (c0.is_bearish and c0.body_size > c0.total_range * 0.5):
return False
for mid in [c1, c2, c3]:
if mid.high > c0.high or mid.low < c0.low:
return False
if mid.body_size > c0.body_size * 0.5:
return False
if not (c4.is_bearish and c4.close < c0.low):
return False
return True
def scan_for_patterns(candles: list, atr: float) -> list:
"""
扫描价格序列中的所有已识别蜡烛图形态。
返回(index, pattern_name, direction, tier)元组列表。
"""
results = []
trend_lookback = 20
for i in range(trend_lookback, len(candles)):
trend = detect_trend(candles[:i], lookback=trend_lookback)
c = candles[i]
# --- 单蜡烛形态 ---
if is_doji(c):
results.append((i, 'doji', 'neutral', 4))
if is_hammer(c, trend):
results.append((i, 'hammer', 'bullish', 2))
if is_hanging_man(c, trend):
results.append((i, 'hanging_man', 'bearish', 4))
if is_shooting_star(c, trend):
results.append((i, 'shooting_star', 'bearish', 3))
if is_inverted_hammer(c, trend):
results.append((i, 'inverted_hammer', 'bullish', 4))
if is_marubozu(c):
direction = 'bullish' if c.is_bullish else 'bearish'
results.append((i, 'marubozu', direction, 2))
# --- 双蜡烛形态(需要i >= 1) ---
if i >= 1:
c1, c2 = candles[i-1], candles[i]
if is_bullish_engulfing(c1, c2, trend):
results.append((i, 'bullish_engulfing', 'bullish', 2))
if is_bearish_engulfing(c1, c2, trend):
results.append((i, 'bearish_engulfing', 'bearish', 2))
if is_bullish_harami(c1, c2, trend):
results.append((i, 'bullish_harami', 'bullish', 3))
if is_bearish_harami(c1, c2, trend):
results.append((i, 'bearish_harami', 'bearish', 3))
if is_piercing_line(c1, c2, trend):
results.append((i, 'piercing_line', 'bullish', 2))
if is_dark_cloud_cover(c1, c2, trend):
results.append((i, 'dark_cloud_cover', 'bearish', 2))
if is_tweezer_bottom(c1, c2, trend, atr):
results.append((i, 'tweezer_bottom', 'bullish', 3))
if is_tweezer_top(c1, c2, trend, atr):
results.append((i, 'tweezer_top', 'bearish', 3))
# --- 三蜡烛形态(需要i >= 2) ---
if i >= 2:
c1, c2, c3 = candles[i-2], candles[i-1], candles[i]
if is_morning_star(c1, c2, c3, trend):
results.append((i, 'morning_star', 'bullish', 1))
if is_evening_star(c1, c2, c3, trend):
results.append((i, 'evening_star', 'bearish', 1))
if is_three_white_soldiers(c1, c2, c3):
results.append((i, 'three_white_soldiers', 'bullish', 1))
if is_three_black_crows(c1, c2, c3):
results.append((i, 'three_black_crows', 'bearish', 1))
if is_three_inside_up(c1, c2, c3, trend):
results.append((i, 'three_inside_up', 'bullish', 3))
if is_three_inside_down(c1, c2, c3, trend):
results.append((i, 'three_inside_down', 'bearish', 3))
# --- 五蜡烛持续形态(需要i >= 4) ---
if i >= 4:
five = candles[i-4:i+1]
if is_rising_three_methods(five, trend):
results.append((i, 'rising_three_methods', 'bullish', 2))
if is_falling_three_methods(five, trend):
results.append((i, 'falling_three_methods', 'bearish', 2))
return results
def generate_signals(candles: list, patterns: list, volumes: list,
avg_volume_period: int = 20) -> list:
"""
通过确认规则过滤原始形态以产生可操作信号。
"""
signals = []
for (idx, name, direction, tier) in patterns:
# 跳过如果没有足够的未来数据进行确认
if idx + 1 >= len(candles):
continue
c_pattern = candles[idx]
c_next = candles[idx + 1]
# --- 成交量确认 ---
if idx >= avg_volume_period:
avg_vol = sum(volumes[idx - avg_volume_period:idx]) / avg_volume_period
vol_ratio = volumes[idx] / avg_vol if avg_vol > 0 else 0
else:
vol_ratio = 1.0
volume_confirmed = vol_ratio >= 1.5 # 高于平均50%
# --- 次日确认 ---
if direction == 'bullish':
next_day_confirmed = c_next.close > c_pattern.close
elif direction == 'bearish':
next_day_confirmed = c_next.close < c_pattern.close
else:
next_day_confirmed = False
# --- 计算置信度 ---
confidence = 0.0
if tier == 1:
confidence += 0.40
elif tier == 2:
confidence += 0.30
elif tier == 3:
confidence += 0.20
else:
confidence += 0.10
if volume_confirmed:
confidence += 0.25
if next_day_confirmed:
confidence += 0.25
# 额外的S/R和振荡器检查在这里会增加置信度
# --- 如果置信度阈值满足则生成信号 ---
if confidence >= 0.50:
if direction == 'bullish':
entry = c_pattern.high + (c_pattern.total_range * 0.01)
stop = c_pattern.low - (c_pattern.total_range * 0.05)
elif direction == 'bearish':
entry = c_pattern.low - (c_pattern.total_range * 0.01)
stop = c_pattern.high + (c_pattern.total_range * 0.05)
else:
continue
risk = abs(entry - stop)
target = entry + (2.0 * risk) if direction == 'bullish' \
else entry - (2.0 * risk)
signals.append({
'index': idx,
'pattern': name,
'direction': direction,
'tier': tier,
'confidence': round(confidence, 2),
'entry': round(entry, 4),
'stop': round(stop, 4),
'target': round(target, 4),
'risk_reward': 2.0,
'volume_confirmed': volume_confirmed,
'next_day_confirmed': next_day_confirmed,
})
return signals
蜡烛图形态是警告,不是命令。 它告诉您某些事情正在变化;不保证变化会 follow through。
趋势决定您是寻找看涨还是看跌形态。 在上升趋势中,寻找看涨持续形态;仅在 extended moves后在顶部寻找看跌反转形态。永远不要在单根蜡烛上对抗趋势。
支撑和阻力给形态提供地址。 在空旷价格空间中漂浮的形态比在 well-established 水平的意义小得多。
成交量是测谎仪。 价格在短期内可能操纵;持续成交量不能。无可成交量确认的形态是可疑的。
确认将形态转化为信号。 次日的行为要么验证要么否定形态。耐心等待它。
风险管理不是可选的。 每笔蜡烛图交易必须有基于形态结构的预定义止损。形态定义风险;您决定该风险对您的账户是否可接受。
结合东方和西方技术。 蜡烛图形态识别何时;移动平均线和趋势线识别在哪里;振荡器识别条件是否成熟。Together, they form a complete framework。
简单胜于复杂。 掌握8-10个核心形态而非记忆60个。最可靠的形态是最视觉上 obvious的:吞没、晨/暮星、锤子和三白兵/三黑鸦。
时间框架很重要。 日图产生最可靠的信号。周图产生更少但更强大的信号。日内图产生更多噪音,需要更严格的确认规则。
统计谦逊。 即使在理想条件下,最好的形态最多有65-75%胜率。这意味着25-35%的信号会失败。只有一致的风险管理将概率优势转化为长期 profitability。
实施规范结束。