Trend Following
Trend Following Systems Moving Average Breakout Risk Management Backtesting Automated Trading EMA ATR Position Sizing Stop Loss Drawdown Diversification
| Strategy | Signal | Win Rate | Risk:Reward | เหมาะกับ |
|---|---|---|---|---|
| MA Crossover | EMA 20/50 | 35% | 1:3 | เริ่มต้น |
| Donchian Breakout | 20-day High/Low | 30% | 1:4 | Commodity |
| Bollinger Breakout | BB Upper/Lower | 35% | 1:3 | Volatility |
| Turtle Trading | 20/55 Breakout | 30% | 1:5 | Futures |
| ADX + MA | ADX > 25 + MA | 40% | 1:2.5 | Filter Trend |
Strategy Implementation
# === Trend Following Strategy ===
# pip install pandas numpy yfinance backtesting
import pandas as pd
import numpy as np
# Simulated price data
np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=252, freq='B')
prices = 100 + np.cumsum(np.random.randn(252) * 1.5)
df = pd.DataFrame({'Close': prices}, index=dates)
# EMA Crossover Strategy
def ema_crossover(df, fast=20, slow=50):
df = df.copy()
df['EMA_fast'] = df['Close'].ewm(span=fast).mean()
df['EMA_slow'] = df['Close'].ewm(span=slow).mean()
df['Signal'] = 0
df.loc[df['EMA_fast'] > df['EMA_slow'], 'Signal'] = 1
df.loc[df['EMA_fast'] < df['EMA_slow'], 'Signal'] = -1
df['Position'] = df['Signal'].shift(1)
df['Returns'] = df['Close'].pct_change()
df['Strategy'] = df['Position'] * df['Returns']
return df
result = ema_crossover(df)
# Performance Metrics
total_return = (1 + result['Strategy'].dropna()).prod() - 1
sharpe = result['Strategy'].dropna().mean() / result['Strategy'].dropna().std() * np.sqrt(252)
max_dd = (result['Strategy'].dropna().cumsum() - result['Strategy'].dropna().cumsum().cummax()).min()
print("=== EMA Crossover Backtest ===")
print(f" Total Return: {total_return:.2%}")
print(f" Sharpe Ratio: {sharpe:.2f}")
print(f" Max Drawdown: {max_dd:.2%}")
print(f" Total Trades: {(result['Signal'].diff() != 0).sum()}")
# ATR-based Stop Loss
def calculate_atr(df, period=14):
high = df['Close'] * 1.02 # simulated
low = df['Close'] * 0.98
tr = high - low
atr = tr.rolling(period).mean()
return atr
atr = calculate_atr(df)
print(f"\n Current ATR(14): {atr.iloc[-1]:.2f}")
print(f" Stop Loss (2x ATR): {df['Close'].iloc[-1] - 2*atr.iloc[-1]:.2f}")
Risk Management
# === Position Sizing & Risk Management ===
class RiskManager:
def __init__(self, capital, risk_per_trade=0.02):
self.capital = capital
self.risk_pct = risk_per_trade
def position_size(self, entry, stop_loss):
risk_amount = self.capital * self.risk_pct
risk_per_share = abs(entry - stop_loss)
if risk_per_share == 0:
return 0
shares = int(risk_amount / risk_per_share)
return shares
def portfolio_heat(self, open_positions):
total_risk = sum(p['risk_amount'] for p in open_positions)
return total_risk / self.capital
rm = RiskManager(capital=1000000, risk_per_trade=0.01)
# Example trades
trades = [
{"symbol": "SET50", "entry": 950, "stop": 920, "atr": 15},
{"symbol": "GOLD", "entry": 2300, "stop": 2250, "atr": 25},
{"symbol": "BTCUSD", "entry": 65000, "stop": 60000, "atr": 2500},
{"symbol": "EURUSD", "entry": 1.0850, "stop": 1.0750, "atr": 0.005},
]
print("=== Position Sizing ===")
print(f" Capital: {rm.capital:,.0f} | Risk/Trade: {rm.risk_pct:.0%}\n")
for t in trades:
size = rm.position_size(t['entry'], t['stop'])
risk_amt = rm.capital * rm.risk_pct
print(f" [{t['symbol']}]")
print(f" Entry: {t['entry']} | Stop: {t['stop']} | ATR: {t['atr']}")
print(f" Size: {size} units | Risk: {risk_amt:,.0f}")
# Risk Rules
rules = [
"Max Risk per Trade: 1-2% of Capital",
"Max Portfolio Heat: 6-10% total risk",
"Max Correlated Positions: 3 per sector",
"Stop Loss: 2-3x ATR from entry",
"Trailing Stop: Move to breakeven after 1R",
"Cut Loss: Never move stop further away",
"Let Profits Run: Trail stop, don't take profit early",
]
print(f"\n\nRisk Rules:")
for i, r in enumerate(rules, 1):
print(f" {i}. {r}")
Automated Trading
# === Automated Trading System ===
# Architecture:
# 1. Data Feed -> Yahoo Finance / Broker API
# 2. Signal Engine -> Calculate indicators, generate signals
# 3. Risk Manager -> Position sizing, portfolio heat
# 4. Order Executor -> Send orders to broker
# 5. Logger -> Record all trades and performance
# import schedule
# import time
#
# class TrendFollower:
# def __init__(self, symbols, capital):
# self.symbols = symbols
# self.rm = RiskManager(capital)
# self.positions = {}
#
# def check_signals(self):
# for symbol in self.symbols:
# df = get_data(symbol, period='6mo')
# df = ema_crossover(df)
# signal = df['Signal'].iloc[-1]
#
# if signal == 1 and symbol not in self.positions:
# self.enter_long(symbol, df)
# elif signal == -1 and symbol in self.positions:
# self.exit_position(symbol)
#
# def enter_long(self, symbol, df):
# entry = df['Close'].iloc[-1]
# atr = calculate_atr(df).iloc[-1]
# stop = entry - 2 * atr
# size = self.rm.position_size(entry, stop)
# self.positions[symbol] = {
# 'entry': entry, 'stop': stop,
# 'size': size, 'atr': atr
# }
# print(f"BUY {symbol}: {size} @ {entry:.2f}")
#
# # Schedule daily check
# schedule.every().day.at("16:30").do(trader.check_signals)
performance = {
"CAGR": "12.5%",
"Sharpe Ratio": "0.85",
"Max Drawdown": "-22%",
"Win Rate": "35%",
"Avg Win/Avg Loss": "3.2x",
"Profit Factor": "1.72",
"Total Trades (1yr)": "85",
"Avg Holding Period": "18 days",
"Best Month": "+8.5%",
"Worst Month": "-6.2%",
}
print("System Performance (Backtest 5yr):")
for k, v in performance.items():
print(f" {k}: {v}")
pitfalls = [
"Overfitting: ระวัง Optimize มากเกินไป ใช้ Walk-forward",
"Drawdown: ต้องทนได้ 20-30% DD อย่าเลิกกลางทาง",
"Slippage: ราคาจริงต่างจาก Backtest คิด Slippage ด้วย",
"Commission: คิดค่า Commission ในการ Backtest",
"Survivorship Bias: ระวังข้อมูลย้อนหลังที่ขาดหุ้นที่เลิกไป",
"Curve Fitting: Parameter ไม่ควร Sensitive เกินไป",
]
print(f"\n\nCommon Pitfalls:")
for i, p in enumerate(pitfalls, 1):
print(f" {i}. {p}")
เคล็ดลับ
- Simple: Strategy ง่ายๆ ทำงานได้ดีที่สุดในระยะยาว
- Risk: Risk Management สำคัญกว่า Entry Signal
- Backtest: ทดสอบก่อนใช้จริงทุกครั้ง Walk-forward
- Discipline: ทำตามระบบ 100% ไม่ใช้อารมณ์
- Diversify: กระจายหลายตลาด ลด Drawdown
การนำความรู้ไปประยุกต์ใช้งานจริง
แหล่งเรียนรู้ที่แนะนำ ได้แก่ Official Documentation ที่อัพเดทล่าสุดเสมอ Online Course จาก Coursera Udemy edX ช่อง YouTube คุณภาพทั้งไทยและอังกฤษ และ Community อย่าง Discord Reddit Stack Overflow ที่ช่วยแลกเปลี่ยนประสบการณ์กับนักพัฒนาทั่วโลก
เปรียบเทียบข้อดีและข้อเสีย
จากตารางเปรียบเทียบจะเห็นว่าข้อดีมีมากกว่าข้อเสียอย่างชัดเจน โดยเฉพาะในแง่ของประสิทธิภาพและความสามารถในการ Scale สำหรับข้อเสียส่วนใหญ่สามารถแก้ไขได้ด้วยการเรียนรู้อย่างเป็นระบบและวางแผนทรัพยากรให้เหมาะสม
Trend Following คืออะไร
กลยุทธ์เทรดตามเทรนด์ ซื้อเมื่อขึ้น ขายเมื่อลง Moving Average Breakout Big Trend ขาดทุนเล็กหลายครั้ง หุ้น Forex Crypto Commodity
Moving Average Strategy ทำงานอย่างไร
EMA 20 50 Golden Cross ซื้อ Death Cross ขาย ATR Stop Loss Position Sizing Risk % Backtest ก่อนใช้จริง
Risk Management สำคัญอย่างไร
Win Rate 30-40% Risk 1-2% ATR Position Sizing Stop Loss Cut Loss Let Profit Run Drawdown 20-30% Diversify
Backtest ระบบเทรดอย่างไร
Python pandas backtesting.py Backtrader Yahoo Finance Strategy Return Sharpe Drawdown Walk-forward Overfitting Out-of-sample
สรุป
Trend Following Systems Moving Average Breakout Risk Management Position Sizing ATR Backtesting Python Automated Trading Sharpe Drawdown Diversification Discipline
