SiamCafe.net Blog
Technology

technical analysis and stock trends

technical analysis and stock trends
technical analysis and stock trends | SiamCafe Blog
2025-10-25· อ. บอม — SiamCafe.net· 8,633 คำ

Technical Analysis

Technical Analysis วิเคราะห์หุ้นจากราคาและปริมาณซื้อขายในอดีต Chart Patterns Indicators Trend Lines คาดการณ์แนวโน้มราคา เชื่อว่าราคาสะท้อนข้อมูลทั้งหมด

Stock Trends แบ่งเป็น Uptrend ขาขึ้น Downtrend ขาลง Sideways ไม่มีทิศทาง ใช้ Moving Average Trend Lines ระบุแนวโน้ม

Indicatorประเภทการใช้งาน
Moving AverageTrendดูแนวโน้ม ตัดกัน = สัญญาณ
RSIMomentum>70 Overbought, <30 Oversold
MACDMomentumSignal Line Crossover
Bollinger BandsVolatilityราคาใกล้ Band = กลับตัว
VolumeVolumeยืนยัน Breakout/Breakdown

Python Technical Analysis

# === Technical Analysis ด้วย Python ===
# pip install yfinance pandas ta matplotlib

import pandas as pd
import numpy as np

# ดาวน์โหลดข้อมูลหุ้น
# import yfinance as yf
# df = yf.download("AAPL", start="2023-01-01", end="2024-12-31")

# สร้างข้อมูลจำลอง
np.random.seed(42)
dates = pd.date_range("2024-01-01", periods=252, freq="B")
price = 150 + np.cumsum(np.random.randn(252) * 2)
volume = np.random.randint(1000000, 5000000, 252)

df = pd.DataFrame({
    "Open": price + np.random.randn(252),
    "High": price + abs(np.random.randn(252)) * 2,
    "Low": price - abs(np.random.randn(252)) * 2,
    "Close": price,
    "Volume": volume,
}, index=dates)

# 1. Moving Averages
df["SMA_20"] = df["Close"].rolling(window=20).mean()
df["SMA_50"] = df["Close"].rolling(window=50).mean()
df["SMA_200"] = df["Close"].rolling(window=200).mean()

# EMA (Exponential Moving Average)
df["EMA_12"] = df["Close"].ewm(span=12).mean()
df["EMA_26"] = df["Close"].ewm(span=26).mean()

# 2. RSI (Relative Strength Index)
def calculate_rsi(data, period=14):
    delta = data.diff()
    gain = delta.where(delta > 0, 0)
    loss = -delta.where(delta < 0, 0)
    avg_gain = gain.rolling(window=period).mean()
    avg_loss = loss.rolling(window=period).mean()
    rs = avg_gain / avg_loss
    rsi = 100 - (100 / (1 + rs))
    return rsi

df["RSI"] = calculate_rsi(df["Close"])

# 3. MACD
df["MACD"] = df["EMA_12"] - df["EMA_26"]
df["MACD_Signal"] = df["MACD"].ewm(span=9).mean()
df["MACD_Hist"] = df["MACD"] - df["MACD_Signal"]

# 4. Bollinger Bands
df["BB_Middle"] = df["Close"].rolling(window=20).mean()
df["BB_Std"] = df["Close"].rolling(window=20).std()
df["BB_Upper"] = df["BB_Middle"] + (df["BB_Std"] * 2)
df["BB_Lower"] = df["BB_Middle"] - (df["BB_Std"] * 2)

# 5. Volume Analysis
df["Vol_SMA"] = df["Volume"].rolling(window=20).mean()
df["Vol_Ratio"] = df["Volume"] / df["Vol_SMA"]

# แสดงผลล่าสุด
latest = df.iloc[-1]
print("Technical Analysis Summary:")
print(f"  Date: {df.index[-1].strftime('%Y-%m-%d')}")
print(f"  Close: {latest['Close']:.2f}")
print(f"  SMA 20: {latest['SMA_20']:.2f}")
print(f"  SMA 50: {latest['SMA_50']:.2f}")
print(f"  RSI: {latest['RSI']:.1f}")
print(f"  MACD: {latest['MACD']:.2f}")
print(f"  BB Upper: {latest['BB_Upper']:.2f}")
print(f"  BB Lower: {latest['BB_Lower']:.2f}")

# สัญญาณ
signals = []
if latest["Close"] > latest["SMA_50"]:
    signals.append("Price > SMA50 (Bullish)")
if latest["RSI"] > 70:
    signals.append("RSI > 70 (Overbought)")
elif latest["RSI"] < 30:
    signals.append("RSI < 30 (Oversold)")
if latest["MACD"] > latest["MACD_Signal"]:
    signals.append("MACD > Signal (Bullish)")

print(f"\n  Signals:")
for s in signals:
    print(f"    - {s}")

Backtesting Strategy

# backtesting.py — Simple Backtesting Framework
from dataclasses import dataclass, field
from typing import List, Dict
import numpy as np

@dataclass
class Trade:
    entry_date: str
    exit_date: str
    entry_price: float
    exit_price: float
    side: str  # long/short
    pnl: float = 0
    pnl_pct: float = 0

    def __post_init__(self):
        if self.side == "long":
            self.pnl = self.exit_price - self.entry_price
            self.pnl_pct = (self.pnl / self.entry_price) * 100
        else:
            self.pnl = self.entry_price - self.exit_price
            self.pnl_pct = (self.pnl / self.entry_price) * 100

class SimpleBacktester:
    """Simple Moving Average Crossover Backtester"""

    def __init__(self, prices, dates, fast_period=20, slow_period=50):
        self.prices = np.array(prices)
        self.dates = dates
        self.fast_period = fast_period
        self.slow_period = slow_period
        self.trades: List[Trade] = []
        self.equity_curve: List[float] = []

    def calculate_ma(self, period):
        ma = np.full_like(self.prices, np.nan)
        for i in range(period - 1, len(self.prices)):
            ma[i] = np.mean(self.prices[i - period + 1:i + 1])
        return ma

    def run(self, initial_capital=100000):
        """Run Backtest"""
        fast_ma = self.calculate_ma(self.fast_period)
        slow_ma = self.calculate_ma(self.slow_period)

        capital = initial_capital
        position = None
        self.equity_curve = [capital]

        for i in range(self.slow_period, len(self.prices)):
            if np.isnan(fast_ma[i]) or np.isnan(slow_ma[i]):
                self.equity_curve.append(capital)
                continue

            # Buy Signal: Fast MA crosses above Slow MA
            if (fast_ma[i] > slow_ma[i] and
                fast_ma[i-1] <= slow_ma[i-1] and
                position is None):
                position = {
                    "entry_date": str(self.dates[i]),
                    "entry_price": self.prices[i],
                }

            # Sell Signal: Fast MA crosses below Slow MA
            elif (fast_ma[i] < slow_ma[i] and
                  fast_ma[i-1] >= slow_ma[i-1] and
                  position is not None):
                trade = Trade(
                    entry_date=position["entry_date"],
                    exit_date=str(self.dates[i]),
                    entry_price=position["entry_price"],
                    exit_price=self.prices[i],
                    side="long",
                )
                self.trades.append(trade)
                capital += trade.pnl * (capital / position["entry_price"])
                position = None

            self.equity_curve.append(capital)

    def report(self):
        """Backtest Report"""
        if not self.trades:
            print("  No trades executed")
            return

        wins = [t for t in self.trades if t.pnl > 0]
        losses = [t for t in self.trades if t.pnl <= 0]

        total_pnl = sum(t.pnl_pct for t in self.trades)
        win_rate = len(wins) / len(self.trades) * 100

        print(f"\n{'='*50}")
        print(f"Backtest Report: MA({self.fast_period}/{self.slow_period})")
        print(f"{'='*50}")
        print(f"  Total Trades: {len(self.trades)}")
        print(f"  Winning: {len(wins)} | Losing: {len(losses)}")
        print(f"  Win Rate: {win_rate:.1f}%")
        print(f"  Total PnL: {total_pnl:.2f}%")

        if wins:
            print(f"  Avg Win: {np.mean([t.pnl_pct for t in wins]):.2f}%")
        if losses:
            print(f"  Avg Loss: {np.mean([t.pnl_pct for t in losses]):.2f}%")

        print(f"\n  Recent Trades:")
        for t in self.trades[-5:]:
            status = "WIN" if t.pnl > 0 else "LOSS"
            print(f"    {t.entry_date[:10]} -> {t.exit_date[:10]}: "
                  f"{t.pnl_pct:+.2f}% [{status}]")

# รัน Backtest
np.random.seed(42)
prices = 150 + np.cumsum(np.random.randn(252) * 2)
dates = pd.date_range("2024-01-01", periods=252, freq="B")

bt = SimpleBacktester(prices, dates, fast_period=20, slow_period=50)
bt.run(initial_capital=100000)
bt.report()

Chart Patterns

# chart_patterns.py — Chart Pattern Recognition
from dataclasses import dataclass
from typing import List, Optional
import numpy as np

@dataclass
class ChartPattern:
    name: str
    pattern_type: str  # reversal, continuation
    signal: str  # bullish, bearish
    description: str
    confirmation: str

class PatternLibrary:
    """Chart Pattern Library"""

    def __init__(self):
        self.patterns: List[ChartPattern] = []

    def add(self, pattern: ChartPattern):
        self.patterns.append(pattern)

    def show_all(self):
        print(f"\n{'='*55}")
        print(f"Chart Patterns Library")
        print(f"{'='*55}")

        for ptype in ["reversal", "continuation"]:
            patterns = [p for p in self.patterns if p.pattern_type == ptype]
            if patterns:
                print(f"\n  [{ptype.upper()} PATTERNS]")
                for p in patterns:
                    signal_icon = "Bullish" if p.signal == "bullish" else "Bearish"
                    print(f"    {p.name} ({signal_icon})")
                    print(f"      {p.description}")
                    print(f"      Confirmation: {p.confirmation}")

library = PatternLibrary()

patterns = [
    ChartPattern("Head and Shoulders", "reversal", "bearish",
                "สามยอด ยอดกลางสูงสุด บ่งบอกการกลับตัวจากขาขึ้นเป็นขาลง",
                "ราคาทะลุ Neckline ลงพร้อม Volume เพิ่ม"),
    ChartPattern("Inverse Head and Shoulders", "reversal", "bullish",
                "สามร่อง ร่องกลางลึกสุด บ่งบอกการกลับตัวจากขาลงเป็นขาขึ้น",
                "ราคาทะลุ Neckline ขึ้นพร้อม Volume เพิ่ม"),
    ChartPattern("Double Top", "reversal", "bearish",
                "สองยอดราคาใกล้เคียงกัน ขึ้นไม่ผ่าน Resistance",
                "ราคาทะลุ Support ลงพร้อม Volume"),
    ChartPattern("Double Bottom", "reversal", "bullish",
                "สองร่องราคาใกล้เคียงกัน ลงไม่ผ่าน Support",
                "ราคาทะลุ Resistance ขึ้นพร้อม Volume"),
    ChartPattern("Ascending Triangle", "continuation", "bullish",
                "แนวต้านแนวนอน แนวรับเป็นเส้นขึ้น ราคาบีบตัว",
                "ราคาทะลุ Resistance ขึ้นพร้อม Volume เพิ่ม"),
    ChartPattern("Flag", "continuation", "bullish",
                "พักตัวเป็นช่อง เอียงลงเล็กน้อยหลัง Rally",
                "ราคาทะลุขอบบนของ Flag พร้อม Volume"),
    ChartPattern("Cup and Handle", "continuation", "bullish",
                "รูปถ้วย ตามด้วยหูจับเล็กๆ",
                "ราคาทะลุ Resistance ของหูจับ"),
]

for p in patterns:
    library.add(p)

library.show_all()

# Candlestick Patterns
candlestick = {
    "Doji": "เปิดปิดราคาเท่ากัน ตลาดลังเล อาจกลับตัว",
    "Hammer": "แท่งเทียนหัวเล็กหางยาวล่าง Bullish reversal",
    "Shooting Star": "แท่งเทียนหัวเล็กหางยาวบน Bearish reversal",
    "Engulfing": "แท่งใหญ่กลืนแท่งก่อน Bullish/Bearish reversal",
    "Morning Star": "3 แท่ง ลง-เล็ก-ขึ้น Bullish reversal",
    "Evening Star": "3 แท่ง ขึ้น-เล็ก-ลง Bearish reversal",
}

print(f"\n  Candlestick Patterns:")
for name, desc in candlestick.items():
    print(f"    {name}: {desc}")

เคล็ดลับ

การนำความรู้ไปประยุกต์ใช้งานจริง

แหล่งเรียนรู้ที่แนะนำ ได้แก่ Official Documentation ที่อัพเดทล่าสุดเสมอ Online Course จาก Coursera Udemy edX ช่อง YouTube คุณภาพทั้งไทยและอังกฤษ และ Community อย่าง Discord Reddit Stack Overflow ที่ช่วยแลกเปลี่ยนประสบการณ์กับนักพัฒนาทั่วโลก

Technical Analysis คืออะไร

วิเคราะห์หุ้นจากราคาปริมาณซื้อขายอดีต Chart Patterns Indicators Trend Lines คาดการณ์แนวโน้ม ราคาสะท้อนข้อมูลทั้งหมด

Indicators ที่นิยมมีอะไรบ้าง

Moving Average ดูแนวโน้ม RSI Overbought Oversold MACD Momentum Bollinger Bands Volatility Volume ปริมาณ Stochastic Fibonacci แนวรับแนวต้าน

Chart Pattern ที่สำคัญมีอะไรบ้าง

Head and Shoulders กลับตัว Double Top Bottom Triangle Flag Pennant พักตัว Cup Handle ต่อเนื่อง Wedge Channel ยืนยันด้วย Volume

วิธีเริ่มต้น Technical Analysis ทำอย่างไร

Candlestick Chart อ่านกราฟเทียน Support Resistance แนวรับแนวต้าน Moving Average แนวโน้ม RSI Overbought Oversold ดูกราฟจริงทุกวัน Paper Trading ฝึกก่อน

สรุป

Technical Analysis วิเคราะห์หุ้นจากราคาและ Volume Moving Average RSI MACD Bollinger Bands Chart Patterns Head Shoulders Double Top Triangle Python สำหรับ Backtesting ทดสอบกลยุทธ์ Risk Management Stop Loss Paper Trading ก่อนใช้เงินจริง

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

gold technical analysis support resistance xauusdอ่านบทความ → what is the difference between etf and mutual fundอ่านบทความ → is head and shoulders veganอ่านบทความ → support and resistance indicatorอ่านบทความ →

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