SiamCafe.net Blog
Technology

support and resistance for stocks

support and resistance for stocks
support and resistance for stocks | SiamCafe Blog
2026-01-01· อ. บอม — SiamCafe.net· 1,627 คำ

Support and Resistance for Stocks — คู่มือฉบับสมบูรณ์

Support และ Resistance เป็นแนวคิดพื้นฐานที่สำคัญที่สุดใน Technical Analysis สำหรับการเทรดหุ้นและตลาดการเงิน Support คือระดับราคาที่แรงซื้อมากพอจะหยุดการลดลงของราคา Resistance คือระดับราคาที่แรงขายมากพอจะหยุดการเพิ่มขึ้นของราคา การเข้าใจ support/resistance ช่วยในการตัดสินใจ entry/exit, ตั้ง stop loss และ take profit บทความนี้อธิบายทฤษฎี วิธีหาแนวรับแนวต้าน และ Python tools สำหรับวิเคราะห์อัตโนมัติ

Support & Resistance Basics

# sr_basics.py — Support and Resistance fundamentals
import json

class SRBasics:
    CONCEPTS = {
        "support": {
            "name": "Support (แนวรับ)",
            "description": "ระดับราคาที่ demand มากกว่า supply — ราคามักจะเด้งกลับขึ้น",
            "psychology": "Buyers มองว่าราคาถูก → เข้าซื้อ → ราคาหยุดลง",
            "strength": "ยิ่งทดสอบหลายครั้ง + volume สูง = แนวรับแข็งแรง",
        },
        "resistance": {
            "name": "Resistance (แนวต้าน)",
            "description": "ระดับราคาที่ supply มากกว่า demand — ราคามักจะลงกลับ",
            "psychology": "Sellers มองว่าราคาแพง → ขาย → ราคาหยุดขึ้น",
            "strength": "ยิ่งทดสอบหลายครั้ง + volume สูง = แนวต้านแข็งแรง",
        },
        "role_reversal": {
            "name": "Role Reversal (เปลี่ยนบทบาท)",
            "description": "เมื่อ support ถูกทะลุ → กลายเป็น resistance (และกลับกัน)",
            "example": "หุ้นลงทะลุแนวรับ 100 บาท → 100 บาทกลายเป็นแนวต้านใหม่",
        },
        "breakout": {
            "name": "Breakout (ทะลุแนว)",
            "description": "ราคาทะลุแนวรับ/ต้าน + volume สูง = สัญญาณ strong move",
            "caution": "False breakout: ทะลุแล้วกลับมา — ต้อง confirm ด้วย volume + candle close",
        },
    }

    TYPES = {
        "horizontal": "แนวนอน — ระดับราคาคงที่ (เช่น 100, 200, 500 บาท)",
        "trendline": "เส้น trend — ลาก highs/lows ต่อกัน ได้แนวรับ/ต้านแบบเอียง",
        "moving_average": "Moving Average — MA50, MA200 ทำหน้าที่เป็น dynamic support/resistance",
        "fibonacci": "Fibonacci Retracement — 23.6%, 38.2%, 50%, 61.8% เป็นแนวรับ/ต้าน",
        "round_numbers": "ตัวเลขกลม — 100, 500, 1000 บาท มักเป็นแนวรับ/ต้านทางจิตวิทยา",
        "pivot_points": "Pivot Points — คำนวณจาก OHLC ของวันก่อน",
    }

    def show_concepts(self):
        print("=== S/R Concepts ===\n")
        for key, concept in self.CONCEPTS.items():
            print(f"[{concept['name']}]")
            print(f"  {concept['description']}")
            print()

    def show_types(self):
        print("=== Types of S/R ===")
        for stype, desc in self.TYPES.items():
            print(f"  [{stype}] {desc}")

sr = SRBasics()
sr.show_concepts()
sr.show_types()

Python Support/Resistance Finder

# sr_finder.py — Automated support/resistance detection
import json

class SRFinder:
    CODE = """
# find_sr.py — Find support and resistance levels
import numpy as np
import pandas as pd
from scipy.signal import argrelextrema

class SupportResistanceFinder:
    def __init__(self, df, window=20):
        '''
        df: DataFrame with 'close', 'high', 'low', 'volume' columns
        window: lookback window for local extrema
        '''
        self.df = df.copy()
        self.window = window
    
    def find_pivot_points(self):
        '''Find local highs and lows (pivot points)'''
        highs = argrelextrema(self.df['high'].values, np.greater, order=self.window)[0]
        lows = argrelextrema(self.df['low'].values, np.less, order=self.window)[0]
        
        pivot_highs = self.df.iloc[highs][['high', 'volume']].copy()
        pivot_highs.columns = ['price', 'volume']
        pivot_highs['type'] = 'resistance'
        
        pivot_lows = self.df.iloc[lows][['low', 'volume']].copy()
        pivot_lows.columns = ['price', 'volume']
        pivot_lows['type'] = 'support'
        
        return pd.concat([pivot_highs, pivot_lows]).sort_index()
    
    def cluster_levels(self, pivots, tolerance=0.02):
        '''Cluster nearby price levels together'''
        prices = pivots['price'].values
        clusters = []
        used = set()
        
        for i, price in enumerate(prices):
            if i in used:
                continue
            
            cluster = [price]
            for j, other in enumerate(prices):
                if j != i and j not in used:
                    if abs(price - other) / price < tolerance:
                        cluster.append(other)
                        used.add(j)
            
            used.add(i)
            clusters.append({
                'price': np.mean(cluster),
                'touches': len(cluster),
                'strength': len(cluster),
            })
        
        return sorted(clusters, key=lambda x: x['strength'], reverse=True)
    
    def find_levels(self, n_levels=5, tolerance=0.02):
        '''Find top N support/resistance levels'''
        pivots = self.find_pivot_points()
        
        # Separate support and resistance
        supports = pivots[pivots['type'] == 'support']
        resistances = pivots[pivots['type'] == 'resistance']
        
        support_levels = self.cluster_levels(supports, tolerance)[:n_levels]
        resistance_levels = self.cluster_levels(resistances, tolerance)[:n_levels]
        
        current_price = self.df['close'].iloc[-1]
        
        return {
            'current_price': current_price,
            'support': [l for l in support_levels if l['price'] < current_price],
            'resistance': [l for l in resistance_levels if l['price'] > current_price],
        }
    
    def fibonacci_levels(self, high=None, low=None):
        '''Calculate Fibonacci retracement levels'''
        if high is None:
            high = self.df['high'].max()
        if low is None:
            low = self.df['low'].min()
        
        diff = high - low
        levels = {
            '0%': high,
            '23.6%': high - diff * 0.236,
            '38.2%': high - diff * 0.382,
            '50%': high - diff * 0.5,
            '61.8%': high - diff * 0.618,
            '78.6%': high - diff * 0.786,
            '100%': low,
        }
        return levels

# Usage with yfinance
# import yfinance as yf
# df = yf.download("PTT.BK", period="1y")
# finder = SupportResistanceFinder(df, window=10)
# levels = finder.find_levels(n_levels=3)
# fib = finder.fibonacci_levels()
"""

    def show_code(self):
        print("=== S/R Finder ===")
        print(self.CODE[:600])

finder = SRFinder()
finder.show_code()

Trading Strategies

# strategies.py — Trading strategies using S/R
import json
import random

class SRStrategies:
    STRATEGIES = {
        "bounce": {
            "name": "Bounce Trading (เทรดเด้ง)",
            "description": "ซื้อที่แนวรับ / ขายที่แนวต้าน",
            "entry": "ราคาลงมาแตะ support + candle reversal (hammer, engulfing)",
            "stop_loss": "ต่ำกว่า support 1-2%",
            "take_profit": "ที่ resistance ถัดไป หรือ Risk:Reward 1:2+",
            "win_rate": "55-65%",
        },
        "breakout": {
            "name": "Breakout Trading (เทรดทะลุ)",
            "description": "ซื้อเมื่อทะลุ resistance / ขายเมื่อทะลุ support",
            "entry": "ราคา close เหนือ resistance + volume สูงกว่า average 1.5x",
            "stop_loss": "กลับมาต่ำกว่า breakout level",
            "take_profit": "วัด range ของ consolidation → project เป้าหมาย",
            "win_rate": "40-55%",
        },
        "pullback": {
            "name": "Pullback Trading (เทรดย่อ)",
            "description": "รอราคาทะลุ → ย่อกลับมา retest → เข้าซื้อ",
            "entry": "ราคาทะลุ resistance → ย่อมาทดสอบ (resistance เป็น support ใหม่)",
            "stop_loss": "ต่ำกว่า retest level",
            "take_profit": "Fibonacci extension หรือ next resistance",
            "win_rate": "50-60%",
        },
        "range": {
            "name": "Range Trading",
            "description": "เทรดไปมาระหว่าง support-resistance ในช่วง sideway",
            "entry": "ซื้อที่ support + ขายที่ resistance (ทั้งสองทาง)",
            "stop_loss": "นอก range 1-2%",
            "take_profit": "ฝั่งตรงข้ามของ range",
            "win_rate": "60-70% (เฉพาะช่วง sideway)",
        },
    }

    def show_strategies(self):
        print("=== S/R Trading Strategies ===\n")
        for key, strat in self.STRATEGIES.items():
            print(f"[{strat['name']}]")
            print(f"  {strat['description']}")
            print(f"  Entry: {strat['entry']}")
            print(f"  Stop Loss: {strat['stop_loss']}")
            print(f"  Win Rate: {strat['win_rate']}")
            print()

strat = SRStrategies()
strat.show_strategies()

Confirmation Indicators

# confirmation.py — Indicators to confirm S/R levels
import json
import random

class ConfirmationIndicators:
    CODE = """
# sr_confirm.py — Confirm S/R levels with indicators
import pandas as pd
import numpy as np

class SRConfirmation:
    def __init__(self, df):
        self.df = df
    
    def volume_confirmation(self, level, tolerance=0.01):
        '''Check if high volume occurs near S/R level'''
        near_level = self.df[
            abs(self.df['close'] - level) / level < tolerance
        ]
        avg_volume = self.df['volume'].mean()
        
        if len(near_level) == 0:
            return False
        
        high_vol_touches = near_level[near_level['volume'] > avg_volume * 1.5]
        return len(high_vol_touches) / len(near_level) > 0.5
    
    def rsi_confirmation(self, period=14):
        '''RSI confirmation at S/R levels'''
        delta = self.df['close'].diff()
        gain = delta.clip(lower=0).rolling(period).mean()
        loss = (-delta.clip(upper=0)).rolling(period).mean()
        rs = gain / loss
        rsi = 100 - (100 / (1 + rs))
        
        return {
            'current_rsi': rsi.iloc[-1],
            'oversold': rsi.iloc[-1] < 30,  # Near support?
            'overbought': rsi.iloc[-1] > 70,  # Near resistance?
        }
    
    def ma_support_resistance(self, periods=[20, 50, 200]):
        '''Moving averages as dynamic S/R'''
        current_price = self.df['close'].iloc[-1]
        levels = {}
        
        for period in periods:
            ma = self.df['close'].rolling(period).mean().iloc[-1]
            if ma < current_price:
                levels[f'MA{period}'] = {'price': ma, 'type': 'support'}
            else:
                levels[f'MA{period}'] = {'price': ma, 'type': 'resistance'}
        
        return levels
    
    def candlestick_pattern(self):
        '''Detect reversal patterns near S/R'''
        last = self.df.iloc[-1]
        prev = self.df.iloc[-2]
        
        # Hammer (bullish reversal at support)
        body = abs(last['close'] - last['open'])
        lower_shadow = min(last['open'], last['close']) - last['low']
        upper_shadow = last['high'] - max(last['open'], last['close'])
        
        is_hammer = lower_shadow > body * 2 and upper_shadow < body * 0.5
        
        # Engulfing
        is_bullish_engulfing = (prev['close'] < prev['open'] and  # prev bearish
                                last['close'] > last['open'] and  # curr bullish
                                last['close'] > prev['open'] and
                                last['open'] < prev['close'])
        
        return {
            'hammer': is_hammer,
            'bullish_engulfing': is_bullish_engulfing,
        }

# confirm = SRConfirmation(df)
# vol_ok = confirm.volume_confirmation(level=100.0)
# rsi = confirm.rsi_confirmation()
# ma_levels = confirm.ma_support_resistance()
"""

    def show_code(self):
        print("=== Confirmation Indicators ===")
        print(self.CODE[:600])

    def checklist(self):
        print(f"\n=== S/R Confirmation Checklist ===")
        checks = [
            ("Volume สูงกว่า average 1.5x", random.choice([True, False])),
            ("RSI oversold/overbought", random.choice([True, False])),
            ("Candlestick reversal pattern", random.choice([True, False])),
            ("MA support/resistance align", random.choice([True, False])),
            ("Multiple timeframe confirm", random.choice([True, False])),
        ]
        score = sum(1 for _, v in checks if v)
        for check, passed in checks:
            status = "✓" if passed else "✗"
            print(f"  [{status}] {check}")
        print(f"\n  Score: {score}/5 — {'Strong signal' if score >= 3 else 'Weak signal'}")

confirm = ConfirmationIndicators()
confirm.show_code()
confirm.checklist()

Thai Stock Examples

# thai_stocks.py — S/R analysis for Thai stocks
import json
import random

class ThaiStockSR:
    EXAMPLES = {
        "PTT": {
            "name": "PTT (SET)",
            "support": [f"{random.uniform(30, 33):.2f}", f"{random.uniform(28, 30):.2f}"],
            "resistance": [f"{random.uniform(35, 38):.2f}", f"{random.uniform(38, 42):.2f}"],
        },
        "ADVANC": {
            "name": "ADVANC (SET)",
            "support": [f"{random.uniform(195, 205):.2f}", f"{random.uniform(185, 195):.2f}"],
            "resistance": [f"{random.uniform(215, 225):.2f}", f"{random.uniform(225, 240):.2f}"],
        },
        "SCB": {
            "name": "SCB (SET)",
            "support": [f"{random.uniform(95, 100):.2f}", f"{random.uniform(88, 95):.2f}"],
            "resistance": [f"{random.uniform(105, 115):.2f}", f"{random.uniform(115, 125):.2f}"],
        },
    }

    PYTHON_EXAMPLE = """
# thai_sr.py — Analyze Thai stocks with yfinance
import yfinance as yf
import pandas as pd

# Download data
ptt = yf.download("PTT.BK", period="1y")
advanc = yf.download("ADVANC.BK", period="1y")

# Find S/R levels
from sr_finder import SupportResistanceFinder

finder = SupportResistanceFinder(ptt, window=10)
levels = finder.find_levels(n_levels=3)

print(f"PTT Current: {levels['current_price']:.2f}")
print("Support levels:")
for s in levels['support']:
    print(f"  {s['price']:.2f} (touches: {s['touches']})")
print("Resistance levels:")
for r in levels['resistance']:
    print(f"  {r['price']:.2f} (touches: {r['touches']})")

# Fibonacci
fib = finder.fibonacci_levels()
print("\\nFibonacci levels:")
for level, price in fib.items():
    print(f"  {level}: {price:.2f}")
"""

    def show_examples(self):
        print("=== Thai Stock S/R Examples ===\n")
        for key, stock in self.EXAMPLES.items():
            print(f"[{stock['name']}]")
            print(f"  Support: {', '.join(stock['support'])}")
            print(f"  Resistance: {', '.join(stock['resistance'])}")
            print()

    def show_python(self):
        print("=== Python Example ===")
        print(self.PYTHON_EXAMPLE[:500])

thai = ThaiStockSR()
thai.show_examples()
thai.show_python()

FAQ - คำถามที่พบบ่อย

Q: แนวรับแนวต้านแม่นยำแค่ไหน?

A: ไม่ใช่เส้นตรง แต่เป็น zone — ราคาอาจทะลุเล็กน้อยแล้วกลับมา ยิ่ง timeframe ใหญ่ (Daily, Weekly) ยิ่งแม่นยำกว่า timeframe เล็ก (, H1) ยิ่งทดสอบหลายครั้ง + volume สูง ยิ่งเชื่อถือได้ ใช้เป็น probability ไม่ใช่ certainty — ต้องมี risk management เสมอ

Q: ใช้ timeframe ไหนดี?

A: Multiple timeframe analysis ดีที่สุด: Weekly/Monthly: หา major S/R levels (strong zones) Daily: หา intermediate levels + confirm direction H4/H1: หา entry/exit points Rule: S/R จาก timeframe ใหญ่ > timeframe เล็ก เมื่อ levels จากหลาย timeframes ตรงกัน = confluence zone (แข็งแรงมาก)

Q: Fibonacci levels เชื่อถือได้ไหม?

A: เป็น self-fulfilling prophecy — เพราะคนเยอะใช้ จึง work ระดับที่สำคัญที่สุด: 38.2%, 50%, 61.8% ใช้ร่วมกับ horizontal S/R = powerful (confluence) ไม่ควรใช้ Fibonacci อย่างเดียว — ต้อง confirm ด้วย price action + volume

Q: Stop loss ควรตั้งห่างจาก S/R เท่าไหร่?

A: ขึ้นกับ volatility ของหุ้น: หุ้น volatility ต่ำ: 1-2% ต่ำกว่า support หุ้น volatility สูง: 2-5% ต่ำกว่า support ใช้ ATR (Average True Range): SL = support - 1.5 * ATR สำคัญ: stop loss ต้องอยู่ "นอก" S/R zone ไม่ใช่ที่ขอบ zone อย่าตั้ง stop loss ที่ตัวเลขกลม (ถูก hunt ง่าย)

📖 บทความที่เกี่ยวข้อง

stocks resistance and supportอ่านบทความ → xauusd support resistance levels may 1 2025อ่านบทความ → metatrader support and resistance indicatorอ่านบทความ → xauusd key support resistance levelsอ่านบทความ → supply and demand vs support and resistance forexอ่านบทความ →

📚 ดูบทความทั้งหมด →