Martingale Strategy คืออะไร
Martingale เป็นกลยุทธ์การจัดการเงิน (Money Management) ที่มาจากทฤษฎีความน่าจะเป็น หลักการคือเพิ่ม Lot Size เป็น 2 เท่าหลังจากขาดทุนแต่ละครั้ง เมื่อชนะครั้งเดียวจะได้กำไรคืนทั้งหมดที่ขาดทุนไปบวกกำไรเท่ากับ Lot แรก
ตัวอย่าง เริ่มที่ 0.01 Lot ขาดทุน → เพิ่มเป็น 0.02 Lot ขาดทุนอีก → เพิ่มเป็น 0.04 Lot ชนะ → ได้กำไรคืนทั้งหมด กลับไปเริ่มที่ 0.01 Lot ข้อเสียคือถ้าขาดทุนติดกันหลายครั้ง Lot Size จะใหญ่มากจนอาจ Margin Call ดังนั้นต้องมี Risk Control ที่ดี
Martingale Expert Advisor — MQL4 Code
//+------------------------------------------------------------------+
//| MartingaleEA.mq4 — Martingale Expert Advisor |
//| พร้อม Risk Management และ Safety Features |
//+------------------------------------------------------------------+
#property copyright "SiamCafe Blog"
#property version "2.0"
#property strict
//--- Input Parameters
input double BaseLot = 0.01; // Lot เริ่มต้น
input double Multiplier = 2.0; // ตัวคูณ Lot (Martingale)
input int MaxLevel = 6; // จำนวนครั้งสูงสุดที่เพิ่ม Lot
input int TakeProfit = 30; // Take Profit (pips)
input int StopLoss = 30; // Stop Loss (pips)
input int MagicNumber = 12345; // Magic Number
input int MaxSpread = 3; // Max Spread ที่ยอมรับ (pips)
input double MaxDrawdownPct = 30.0; // Max Drawdown % ก่อนหยุดเทรด
input bool UseTimeFilter = true; // ใช้ Time Filter
input int StartHour = 8; // เริ่มเทรด (ชั่วโมง Server)
input int EndHour = 20; // หยุดเทรด (ชั่วโมง Server)
input int SignalPeriod = 14; // RSI Period สำหรับ Signal
//--- Global Variables
int currentLevel = 0;
double currentLot;
datetime lastTradeTime;
double initialBalance;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
initialBalance = AccountBalance();
currentLot = BaseLot;
currentLevel = 0;
Print("Martingale EA initialized. Balance: ", initialBalance);
Print("Base Lot: ", BaseLot, " | Max Level: ", MaxLevel);
Print("TP: ", TakeProfit, " | SL: ", StopLoss);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// ตรวจสอบ Drawdown
if(CheckDrawdown())
{
Comment("STOPPED: Max Drawdown reached (",
MaxDrawdownPct, "%)");
return;
}
// ตรวจสอบเวลาเทรด
if(UseTimeFilter && !IsTradeTime())
return;
// ตรวจสอบ Spread
double spread = MarketInfo(Symbol(), MODE_SPREAD);
if(spread > MaxSpread * 10)
return;
// ตรวจสอบว่ามี Order เปิดอยู่หรือไม่
if(CountOpenOrders() > 0)
return;
// ตรวจสอบ Order ล่าสุดว่าชนะหรือแพ้
CheckLastOrder();
// คำนวณ Signal
int signal = GetSignal();
if(signal == 1) // Buy Signal
OpenOrder(OP_BUY);
else if(signal == -1) // Sell Signal
OpenOrder(OP_SELL);
}
//+------------------------------------------------------------------+
//| คำนวณ Trading Signal ด้วย RSI |
//+------------------------------------------------------------------+
int GetSignal()
{
double rsi = iRSI(Symbol(), PERIOD_CURRENT, SignalPeriod, PRICE_CLOSE, 0);
double rsi_prev = iRSI(Symbol(), PERIOD_CURRENT, SignalPeriod, PRICE_CLOSE, 1);
// RSI Oversold → Buy
if(rsi_prev < 30 && rsi >= 30)
return 1;
// RSI Overbought → Sell
if(rsi_prev > 70 && rsi <= 70)
return -1;
return 0; // No Signal
}
//+------------------------------------------------------------------+
//| เปิด Order |
//+------------------------------------------------------------------+
void OpenOrder(int orderType)
{
double price, sl, tp;
double point = MarketInfo(Symbol(), MODE_POINT);
int digits = (int)MarketInfo(Symbol(), MODE_DIGITS);
// ปรับ Point สำหรับ 5-digit broker
double pip = point;
if(digits == 3 || digits == 5)
pip = point * 10;
if(orderType == OP_BUY)
{
price = Ask;
sl = NormalizeDouble(price - StopLoss * pip, digits);
tp = NormalizeDouble(price + TakeProfit * pip, digits);
}
else
{
price = Bid;
sl = NormalizeDouble(price + StopLoss * pip, digits);
tp = NormalizeDouble(price - TakeProfit * pip, digits);
}
// ตรวจสอบ Lot Size
double lotSize = CalculateLotSize();
if(lotSize <= 0) return;
int ticket = OrderSend(Symbol(), orderType, lotSize, price,
3, sl, tp, "Martingale EA",
MagicNumber, 0, clrGreen);
if(ticket > 0)
{
Print("Order opened: ", orderType == OP_BUY ? "BUY" : "SELL",
" | Lot: ", lotSize, " | Level: ", currentLevel,
" | Price: ", price);
lastTradeTime = TimeCurrent();
}
else
{
Print("Order failed: Error ", GetLastError());
}
}
//+------------------------------------------------------------------+
//| คำนวณ Lot Size ตาม Martingale Level |
//+------------------------------------------------------------------+
double CalculateLotSize()
{
double lot = BaseLot * MathPow(Multiplier, currentLevel);
// ตรวจสอบ Max Lot
double maxLot = MarketInfo(Symbol(), MODE_MAXLOT);
double minLot = MarketInfo(Symbol(), MODE_MINLOT);
double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
lot = MathMin(lot, maxLot);
lot = MathMax(lot, minLot);
lot = NormalizeDouble(lot / lotStep, 0) * lotStep;
// ตรวจสอบ Margin
double marginRequired = MarketInfo(Symbol(), MODE_MARGINREQUIRED) * lot;
if(marginRequired > AccountFreeMargin() * 0.8)
{
Print("Not enough margin. Required: ", marginRequired,
" Free: ", AccountFreeMargin());
return 0;
}
return lot;
}
//+------------------------------------------------------------------+
//| ตรวจสอบ Order ล่าสุด |
//+------------------------------------------------------------------+
void CheckLastOrder()
{
for(int i = OrdersHistoryTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
if(OrderProfit() >= 0)
{
// ชนะ — Reset กลับ Level 0
currentLevel = 0;
Print("WIN: Reset to Level 0");
}
else
{
// แพ้ — เพิ่ม Level (ถ้าไม่เกิน Max)
if(currentLevel < MaxLevel)
{
currentLevel++;
Print("LOSS: Increase to Level ", currentLevel);
}
else
{
// เกิน Max Level — Reset
currentLevel = 0;
Print("MAX LEVEL reached. Reset to Level 0");
}
}
break;
}
}
}
}
//+------------------------------------------------------------------+
//| นับ Open Orders |
//+------------------------------------------------------------------+
int CountOpenOrders()
{
int count = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
count++;
}
return count;
}
//+------------------------------------------------------------------+
//| ตรวจสอบ Drawdown |
//+------------------------------------------------------------------+
bool CheckDrawdown()
{
double currentBalance = AccountBalance();
double drawdown = (initialBalance - currentBalance) / initialBalance * 100;
return (drawdown >= MaxDrawdownPct);
}
//+------------------------------------------------------------------+
//| ตรวจสอบเวลาเทรด |
//+------------------------------------------------------------------+
bool IsTradeTime()
{
int hour = Hour();
return (hour >= StartHour && hour < EndHour);
}
Risk Management Table
| Level | Lot Size | ถ้าชนะ (30 pips) | สะสมขาดทุน | Margin ที่ต้องใช้ (EURUSD) |
|---|---|---|---|---|
| 0 | 0.01 | $3.00 | $0 | ~$11 |
| 1 | 0.02 | $6.00 | -$3.00 | ~$22 |
| 2 | 0.04 | $12.00 | -$9.00 | ~$44 |
| 3 | 0.08 | $24.00 | -$21.00 | ~$88 |
| 4 | 0.16 | $48.00 | -$45.00 | ~$176 |
| 5 | 0.32 | $96.00 | -$93.00 | ~$352 |
| 6 | 0.64 | $192.00 | -$189.00 | ~$704 |
Python Script วิเคราะห์ Martingale Risk
# martingale_analysis.py — วิเคราะห์ความเสี่ยง Martingale
import random
import statistics
def simulate_martingale(base_lot=0.01, multiplier=2.0, max_level=6,
tp_pips=30, sl_pips=30, win_rate=0.55,
initial_balance=1000, num_trades=1000,
pip_value=10):
"""จำลอง Martingale Strategy"""
balance = initial_balance
level = 0
max_drawdown = 0
peak_balance = balance
trades = []
consecutive_losses = 0
max_consecutive = 0
for i in range(num_trades):
lot = base_lot * (multiplier ** level)
# Random win/loss based on win_rate
if random.random() < win_rate:
profit = lot * tp_pips * pip_value
balance += profit
trades.append({"trade": i, "result": "win", "lot": lot,
"profit": profit, "balance": balance,
"level": level})
level = 0 # Reset
consecutive_losses = 0
else:
loss = lot * sl_pips * pip_value
balance -= loss
trades.append({"trade": i, "result": "loss", "lot": lot,
"profit": -loss, "balance": balance,
"level": level})
consecutive_losses += 1
max_consecutive = max(max_consecutive, consecutive_losses)
if level < max_level:
level += 1
else:
level = 0 # Reset at max level
# Track drawdown
peak_balance = max(peak_balance, balance)
drawdown = (peak_balance - balance) / peak_balance * 100
max_drawdown = max(max_drawdown, drawdown)
# Margin Call check
if balance <= 0:
print(f"MARGIN CALL at trade {i}!")
break
profits = [t["profit"] for t in trades]
wins = [t for t in trades if t["result"] == "win"]
print(f"=== Martingale Simulation ===")
print(f"Trades: {len(trades)}")
print(f"Win Rate: {len(wins)/len(trades)*100:.1f}%")
print(f"Final Balance: ")
print(f"Net Profit: ")
print(f"Max Drawdown: {max_drawdown:.1f}%")
print(f"Max Consecutive Losses: {max_consecutive}")
print(f"Avg Profit/Trade: ")
return trades, balance
# จำลอง 10 ครั้ง
results = []
for run in range(10):
_, final = simulate_martingale(win_rate=0.55, num_trades=500)
results.append(final)
print(f"\n=== 10 Simulations Summary ===")
print(f"Avg Final Balance: ")
print(f"Min: | Max: ")
print(f"Profitable: {sum(1 for r in results if r > 1000)}/10")
ข้อควรระวังและ Best Practices
- กำหนด Max Level: จำกัดจำนวนครั้งที่เพิ่ม Lot เช่น 5-7 ครั้ง เกินนี้ Reset กลับ Lot เริ่มต้น
- ใช้ Stop Loss เสมอ: ทุก Order ต้องมี Stop Loss ไม่ปล่อยให้ขาดทุนไม่จำกัด
- Max Drawdown: ตั้งขีดจำกัด Drawdown เช่น 30% เมื่อถึงให้หยุดเทรดอัตโนมัติ
- Backtest อย่างละเอียด: ทดสอบหลาย Period หลาย Symbol หลายสภาวะตลาด
- Demo ก่อน Live: ทดสอบบน Demo Account อย่างน้อย 3 เดือนก่อนใช้เงินจริง
- เงินทุนเพียงพอ: ต้องมีเงินทุนรองรับ Worst Case เช่น ขาดทุน Max Level ติดกัน 2 รอบ
- ไม่เหมาะกับทุกตลาด: Martingale ทำงานดีในตลาด Ranging ไม่ดีในตลาด Trending แรง
Martingale Strategy คืออะไร
Martingale เพิ่ม Lot Size 2 เท่าหลังขาดทุน ชนะครั้งเดียวได้กำไรคืนทั้งหมด ข้อเสียคือ Lot Size ใหญ่มากเมื่อขาดทุนติดกันหลายครั้ง อาจ Margin Call ต้องมี Risk Control ที่ดี
MQL4 คืออะไร
MQL4 เป็นภาษาโปรแกรมสำหรับ MetaTrader 4 ไวยากรณ์คล้าย C++ ใช้เขียน Expert Advisors (EA), Custom Indicators และ Scripts เข้าถึง Market Data, Order Management และ Technical Indicators ได้ทั้งหมด
Martingale EA มีความเสี่ยงอย่างไร
ความเสี่ยงหลักคือ Drawdown สูง ขาดทุน 10 ครั้งติด Lot เพิ่มเป็น 1024 เท่า อาจ Margin Call ต้องกำหนด Max Level, Max Drawdown, Stop Loss และมีเงินทุนเพียงพอรองรับ Worst Case
วิธี Backtest EA ทำอย่างไร
ใช้ Strategy Tester ใน MT4 เลือก EA Symbol Period Date Range รัน Backtest ดู Profit Factor Max Drawdown Win Rate ทดสอบหลาย Period หลาย Symbol ใช้ Demo Account อย่างน้อย 3 เดือนก่อนใช้จริง
สรุป
Martingale เป็นกลยุทธ์ที่ทรงพลังแต่มีความเสี่ยงสูง การเขียน EA ด้วย MQL4 ต้องมี Risk Management ที่ดี ได้แก่ กำหนด Max Level, Stop Loss ทุก Order, Max Drawdown Limit, Time Filter, Spread Filter และเงินทุนที่เพียงพอ Backtest อย่างละเอียด ทดสอบบน Demo ก่อน Live และไม่ควรใช้เงินที่ไม่สามารถเสียได้
