Head and Shoulders Pattern คืออะไร
Head and Shoulders เป็น chart pattern ที่บ่งบอกถึงการกลับตัวของแนวโน้ม (trend reversal) จัดเป็นหนึ่งใน pattern ที่น่าเชื่อถือมากที่สุดใน Technical Analysis ประกอบด้วย 3 ยอดคือ Left Shoulder ที่เป็นยอดแรก Head ที่เป็นยอดสูงสุดตรงกลาง และ Right Shoulder ที่เป็นยอดสุดท้ายอยู่ระดับเดียวกับ Left Shoulder
Neckline คือเส้นที่ลากผ่านจุดต่ำสุดระหว่าง Left Shoulder กับ Head และจุดต่ำสุดระหว่าง Head กับ Right Shoulder เมื่อราคาทะลุ neckline ลงมาถือว่า pattern สมบูรณ์และเป็นสัญญาณขาย
Head and Shoulders แบ่งเป็น 2 ประเภทคือ Head and Shoulders Top ที่เกิดหลังขาขึ้นและบ่งบอกว่าราคาจะกลับตัวลง และ Inverse Head and Shoulders (Head and Shoulders Bottom) ที่เกิดหลังขาลงและบ่งบอกว่าราคาจะกลับตัวขึ้น
ปริมาณการซื้อขาย (Volume) มีบทบาทสำคัญในการยืนยัน pattern โดยทั่วไป volume จะสูงที่ Left Shoulder ลดลงที่ Head และลดลงอีกที่ Right Shoulder เมื่อราคาทะลุ neckline volume ควรเพิ่มขึ้นอย่างมากเพื่อยืนยันการ breakout
วิธีระบุ Head and Shoulders บน Chart
ขั้นตอนการระบุ Head and Shoulders Pattern อย่างเป็นระบบ
# ขั้นตอนระบุ Head and Shoulders Top Pattern
#
# 1. ระบุ Uptrend ก่อนหน้า
# - ราคาต้องอยู่ในขาขึ้นก่อนจะเกิด pattern
# - ถ้าไม่มี uptrend ก่อนหน้า ไม่ใช่ H&S
#
# 2. ระบุ Left Shoulder
# - ราคาขึ้นไปถึงจุดสูงสุดแล้วย่อตัวลง
# - Volume สูง
#
# 3. ระบุ Head
# - ราคาขึ้นไปสูงกว่า Left Shoulder
# - แล้วย่อตัวลงมาใกล้ระดับเดียวกับจุดต่ำสุดของ Left Shoulder
# - Volume อาจเท่าหรือน้อยกว่า Left Shoulder
#
# 4. ระบุ Right Shoulder
# - ราคาขึ้นไปอีกครั้งแต่ไม่ถึงระดับ Head
# - ควรอยู่ระดับใกล้เคียงกับ Left Shoulder
# - Volume ลดลงอย่างชัดเจน (สำคัญมาก)
#
# 5. วาด Neckline
# - ลากเส้นจากจุดต่ำสุดระหว่าง LS-Head ถึง Head-RS
# - Neckline อาจเอียงขึ้นหรือลงเล็กน้อย
# - Neckline แนวนอนถือว่าน่าเชื่อถือกว่า
#
# 6. รอ Breakout
# - ราคาทะลุ neckline ลงมาพร้อม volume สูง
# - อาจมี pullback มาทดสอบ neckline แล้วลงต่อ
#
# 7. คำนวณ Target Price
# - Distance = Head Price - Neckline Price
# - Target = Neckline Price - Distance
# - เรียกว่า "Measured Move"
#
# ตัวอย่าง:
# Left Shoulder: $150
# Head: $165
# Right Shoulder: $152
# Neckline: $140
# Distance: $165 - $140 = $25
# Target: $140 - $25 = $115
# เกณฑ์ประเมินคุณภาพ H&S Pattern:
# ✓ Symmetry: RS ใกล้เคียง LS (ดี)
# ✓ Volume: ลดลงจาก LS → Head → RS
# ✓ Neckline: แนวนอนหรือเอียงลงเล็กน้อย
# ✓ Breakout Volume: สูงกว่าค่าเฉลี่ย
# ✓ Prior Trend: มี uptrend ชัดเจน
# ✗ RS สูงกว่า Head: ไม่ใช่ H&S
# ✗ Volume เพิ่มขึ้นที่ RS: สัญญาณอ่อน
Inverse Head and Shoulders สำหรับขาขึ้น
Inverse Head and Shoulders เป็น bullish reversal pattern ที่เกิดหลังขาลง
# Inverse Head and Shoulders (H&S Bottom)
#
# โครงสร้าง:
# Neckline
# ___/ \___
# / \ / \ / \
# / \ / Head\ / \
# \/ \/
# Left Right
# Shoulder Shoulder
#
# ขั้นตอน:
# 1. ระบุ Downtrend ก่อนหน้า
# 2. Left Shoulder: ราคาลงไปถึงจุดต่ำสุดแล้วเด้งกลับขึ้น
# 3. Head: ราคาลงไปต่ำกว่า Left Shoulder แล้วเด้งกลับ
# 4. Right Shoulder: ราคาลงอีกครั้งแต่ไม่ต่ำเท่า Head
# 5. Neckline: ลากจากจุดสูงสุดระหว่าง LS-Head ถึง Head-RS
# 6. Breakout: ราคาทะลุ neckline ขึ้นไปพร้อม volume สูง
#
# Volume Profile:
# - Left Shoulder: volume สูง
# - Head: volume ลดลง
# - Right Shoulder: volume เริ่มเพิ่มขึ้น (ต่างจาก H&S Top)
# - Breakout: volume สูงมาก (สำคัญมากสำหรับ bullish breakout)
#
# ตัวอย่าง:
# Left Shoulder: $80
# Head: $65
# Right Shoulder: $78
# Neckline: $95
# Distance: $95 - $65 = $30
# Target: $95 + $30 = $125
# Complex Head and Shoulders
# บางครั้งอาจเจอ pattern ที่ซับซ้อนกว่า:
# - Double Left Shoulder
# - Double Right Shoulder
# - Tilted Neckline (เอียงขึ้นหรือลง)
# - Extended Right Shoulder
# ยังคงใช้หลักการเดียวกันแต่ต้องยืดหยุ่นในการวิเคราะห์
ตรวจจับ Pattern อัตโนมัติด้วย Python
สร้างระบบตรวจจับ Head and Shoulders Pattern อัตโนมัติ
#!/usr/bin/env python3
# hs_detector.py — Head and Shoulders Pattern Detector
import pandas as pd
import numpy as np
import yfinance as yf
class HSDetector:
def __init__(self, data, lookback=5, tolerance=0.03):
self.data = data.copy()
self.lookback = lookback
self.tolerance = tolerance # 3% tolerance สำหรับ symmetry
def find_peaks(self):
"""หาจุดยอด (peaks) และจุดต่ำสุด (troughs)"""
high = self.data["High"].values
low = self.data["Low"].values
n = self.lookback
peaks = []
troughs = []
for i in range(n, len(high) - n):
if high[i] == max(high[i-n:i+n+1]):
peaks.append((i, high[i]))
if low[i] == min(low[i-n:i+n+1]):
troughs.append((i, low[i]))
return peaks, troughs
def detect_hs_top(self):
"""ตรวจจับ Head and Shoulders Top"""
peaks, troughs = self.find_peaks()
patterns = []
for i in range(len(peaks) - 2):
ls_idx, ls_price = peaks[i]
head_idx, head_price = peaks[i + 1]
rs_idx, rs_price = peaks[i + 2]
# เงื่อนไข: Head สูงกว่า LS และ RS
if head_price <= ls_price or head_price <= rs_price:
continue
# เงื่อนไข: LS และ RS ใกล้เคียงกัน
symmetry = abs(ls_price - rs_price) / ls_price
if symmetry > self.tolerance:
continue
# หา Neckline
trough1 = None
trough2 = None
for t_idx, t_price in troughs:
if ls_idx < t_idx < head_idx:
trough1 = (t_idx, t_price)
if head_idx < t_idx < rs_idx:
trough2 = (t_idx, t_price)
if trough1 is None or trough2 is None:
continue
neckline = (trough1[1] + trough2[1]) / 2
distance = head_price - neckline
target = neckline - distance
# ตรวจสอบ breakout
broken = False
breakout_idx = None
for j in range(rs_idx + 1, min(rs_idx + 30, len(self.data))):
if self.data["Close"].iloc[j] < neckline:
broken = True
breakout_idx = j
break
patterns.append({
"type": "H&S Top",
"left_shoulder": (self.data.index[ls_idx], ls_price),
"head": (self.data.index[head_idx], head_price),
"right_shoulder": (self.data.index[rs_idx], rs_price),
"neckline": round(neckline, 2),
"target": round(target, 2),
"distance": round(distance, 2),
"symmetry": round(symmetry * 100, 1),
"broken": broken,
"breakout_date": self.data.index[breakout_idx] if broken else None,
})
return patterns
def detect_inverse_hs(self):
"""ตรวจจับ Inverse Head and Shoulders"""
peaks, troughs = self.find_peaks()
patterns = []
for i in range(len(troughs) - 2):
ls_idx, ls_price = troughs[i]
head_idx, head_price = troughs[i + 1]
rs_idx, rs_price = troughs[i + 2]
if head_price >= ls_price or head_price >= rs_price:
continue
symmetry = abs(ls_price - rs_price) / ls_price
if symmetry > self.tolerance:
continue
peak1 = None
peak2 = None
for p_idx, p_price in peaks:
if ls_idx < p_idx < head_idx:
peak1 = (p_idx, p_price)
if head_idx < p_idx < rs_idx:
peak2 = (p_idx, p_price)
if peak1 is None or peak2 is None:
continue
neckline = (peak1[1] + peak2[1]) / 2
distance = neckline - head_price
target = neckline + distance
broken = False
breakout_idx = None
for j in range(rs_idx + 1, min(rs_idx + 30, len(self.data))):
if self.data["Close"].iloc[j] > neckline:
broken = True
breakout_idx = j
break
patterns.append({
"type": "Inverse H&S",
"left_shoulder": (self.data.index[ls_idx], ls_price),
"head": (self.data.index[head_idx], head_price),
"right_shoulder": (self.data.index[rs_idx], rs_price),
"neckline": round(neckline, 2),
"target": round(target, 2),
"distance": round(distance, 2),
"symmetry": round(symmetry * 100, 1),
"broken": broken,
"breakout_date": self.data.index[breakout_idx] if broken else None,
})
return patterns
if __name__ == "__main__":
data = yf.download("AAPL", period="1y")
detector = HSDetector(data, lookback=5, tolerance=0.05)
hs_patterns = detector.detect_hs_top()
ihs_patterns = detector.detect_inverse_hs()
print(f"=== Head & Shoulders Patterns: AAPL ===\n")
for p in hs_patterns:
status = "CONFIRMED" if p["broken"] else "FORMING"
print(f"[{p['type']}] {status}")
print(f" LS: {p['left_shoulder'][0].strftime('%Y-%m-%d')} @ {p['left_shoulder'][1]:.2f}")
print(f" Head: {p['head'][0].strftime('%Y-%m-%d')} @ {p['head'][1]:.2f}")
print(f" RS: {p['right_shoulder'][0].strftime('%Y-%m-%d')} @ {p['right_shoulder'][1]:.2f}")
print(f" Neckline: {p['neckline']} | Target: {p['target']}")
print(f" Symmetry: {p['symmetry']}%\n")
for p in ihs_patterns:
status = "CONFIRMED" if p["broken"] else "FORMING"
print(f"[{p['type']}] {status}")
print(f" LS: {p['left_shoulder'][0].strftime('%Y-%m-%d')} @ {p['left_shoulder'][1]:.2f}")
print(f" Head: {p['head'][0].strftime('%Y-%m-%d')} @ {p['head'][1]:.2f}")
print(f" RS: {p['right_shoulder'][0].strftime('%Y-%m-%d')} @ {p['right_shoulder'][1]:.2f}")
print(f" Neckline: {p['neckline']} | Target: {p['target']}\n")
กลยุทธ์การเทรดด้วย Head and Shoulders
ขั้นตอนการเทรดด้วย H&S Pattern อย่างมีระบบ
# กลยุทธ์การเทรด Head and Shoulders
#
# === Entry Strategies ===
#
# 1. Breakout Entry (ปลอดภัยที่สุด)
# - รอราคาทะลุ neckline แล้วเข้า sell/buy ทันที
# - ข้อดี: ยืนยันแล้วว่า pattern สมบูรณ์
# - ข้อเสีย: อาจพลาดส่วนหนึ่งของ move
#
# 2. Pullback Entry (ดีที่สุดสำหรับ Risk:Reward)
# - รอราคา pullback กลับมาทดสอบ neckline
# - เข้าเมื่อราคาเด้งจาก neckline
# - ข้อดี: entry ดีกว่า, stop loss แคบกว่า
# - ข้อเสีย: อาจไม่มี pullback
#
# 3. Aggressive Entry (ความเสี่ยงสูง)
# - เข้าเมื่อ right shoulder กำลังก่อตัว
# - ข้อดี: entry เร็วมาก, RR สูง
# - ข้อเสีย: pattern อาจไม่สมบูรณ์
# === Stop Loss Placement ===
# H&S Top:
# - Above right shoulder (ปลอดภัย)
# - Above neckline + ATR (แน่น)
#
# Inverse H&S:
# - Below right shoulder (ปลอดภัย)
# - Below neckline - ATR (แน่น)
# === Take Profit ===
# Target 1: Measured Move (distance from head to neckline)
# Target 2: 1.618x Measured Move (Fibonacci extension)
# Target 3: Next support/resistance level
# Position Sizing
# Risk per trade: 1-2% of account
# Position size = (Account * Risk%) / (Entry - Stop Loss)
#
# ตัวอย่าง H&S Top:
# Account: $100,000
# Risk: 1% = $1,000
# Entry (short): $140 (neckline break)
# Stop Loss: $153 (above right shoulder)
# Risk per share: $153 - $140 = $13
# Position size: $1,000 / $13 = 76 shares
# Target: $115 (measured move)
# Reward: ($140 - $115) * 76 = $1,900
# Risk:Reward = 1:1.9
Backtesting และวัดผล Pattern
ทดสอบประสิทธิภาพของ H&S Pattern ด้วยข้อมูลจริง
#!/usr/bin/env python3
# hs_backtest.py — Backtest Head and Shoulders Strategy
import yfinance as yf
import numpy as np
def backtest_hs(symbol="SPY", period="5y"):
data = yf.download(symbol, period=period)
detector = HSDetector(data, lookback=7, tolerance=0.05)
# ตรวจจับ patterns
hs_top = detector.detect_hs_top()
ihs = detector.detect_inverse_hs()
results = []
# Backtest H&S Top (Short)
for p in hs_top:
if not p["broken"] or p["breakout_date"] is None:
continue
entry_price = p["neckline"]
stop_loss = p["right_shoulder"][1] * 1.01 # 1% above RS
target = p["target"]
# ดูผลลัพธ์ 30 วันหลัง breakout
bo_idx = data.index.get_loc(p["breakout_date"])
hit_target = False
hit_stop = False
for j in range(bo_idx + 1, min(bo_idx + 60, len(data))):
if data["High"].iloc[j] >= stop_loss:
hit_stop = True
results.append({
"type": "H&S Top", "result": "LOSS",
"pnl_pct": -abs(stop_loss - entry_price) / entry_price * 100
})
break
if data["Low"].iloc[j] <= target:
hit_target = True
results.append({
"type": "H&S Top", "result": "WIN",
"pnl_pct": abs(entry_price - target) / entry_price * 100
})
break
if not hit_target and not hit_stop:
final_price = data["Close"].iloc[min(bo_idx + 60, len(data) - 1)]
pnl = (entry_price - final_price) / entry_price * 100
results.append({
"type": "H&S Top",
"result": "WIN" if pnl > 0 else "LOSS",
"pnl_pct": pnl
})
# สรุปผล
if results:
wins = [r for r in results if r["result"] == "WIN"]
losses = [r for r in results if r["result"] == "LOSS"]
total_pnl = sum(r["pnl_pct"] for r in results)
print(f"\n=== H&S Backtest: {symbol} ({period}) ===")
print(f"Total Patterns: {len(results)}")
print(f"Wins: {len(wins)} | Losses: {len(losses)}")
print(f"Win Rate: {len(wins)/len(results)*100:.1f}%")
print(f"Avg Win: {np.mean([r['pnl_pct'] for r in wins]):.2f}%" if wins else "")
print(f"Avg Loss: {np.mean([r['pnl_pct'] for r in losses]):.2f}%" if losses else "")
print(f"Total P&L: {total_pnl:.2f}%")
else:
print("No confirmed H&S patterns found")
return results
# backtest_hs("SPY", "5y")
FAQ คำถามที่พบบ่อย
Q: Head and Shoulders มี success rate เท่าไหร่?
A: จากการศึกษาของ Thomas Bulkowski ใน Encyclopedia of Chart Patterns พบว่า H&S Top มี success rate ประมาณ 83% สำหรับการกลับตัวลง และ Inverse H&S มี success rate ประมาณ 89% สำหรับการกลับตัวขึ้น ตัวเลขนี้วัดจากราคาที่ทะลุ neckline แล้วเคลื่อนที่ไปในทิศทางที่คาดไว้
Q: Neckline ต้องเป็นเส้นตรงแนวนอนเท่านั้นไหม?
A: ไม่จำเป็น Neckline อาจเอียงขึ้นหรือลงได้ สำหรับ H&S Top neckline ที่เอียงลงมักให้ผลลัพธ์ดีกว่าเพราะแสดงว่าแนวโน้มอ่อนตัวแล้ว ส่วน neckline ที่เอียงขึ้นมากอาจลดความน่าเชื่อถือของ pattern ลง สิ่งสำคัญคือ neckline ต้องเชื่อมจุดต่ำสุด 2 จุดได้ชัดเจน
Q: ใช้ timeframe ไหนสำหรับ Head and Shoulders?
A: H&S ใน timeframe สูงเช่น Daily หรือ Weekly มีความน่าเชื่อถือมากที่สุดเพราะมี volume สนับสนุนมากกว่า timeframe ต่ำเช่น 15M หรือ 1H สามารถใช้ได้แต่มี false signal มากกว่า สำหรับ swing trading แนะนำ Daily chart สำหรับ position trading ใช้ Weekly chart
Q: ถ้า Right Shoulder สูงกว่า Left Shoulder ยังเป็น H&S ไหม?
A: ยังเป็นได้แต่ pattern จะอ่อนกว่า Right Shoulder ที่สูงกว่า Left Shoulder แสดงว่าแรงซื้อยังไม่หมด pattern อาจล้มเหลว ในทางตรงกันข้าม Right Shoulder ที่ต่ำกว่า Left Shoulder แสดงว่าแรงซื้ออ่อนลงชัดเจนและ pattern มีโอกาสสำเร็จมากกว่า