แนวคิดการออกแบบระบบ Adaptive Hybrid Grid (AHG) ระบบนี้ถูกสร้างขึ้นมาเพื่ออุดจุดอ่อนที่อันตรายที่สุดของ Grid System (นั่นคือการโดนลากจนพอร์ตแตกช่วงมีเทรนด์) โดยใช้ Market Structure, แนวรับแนวต้าน และ Price Action เป็นสมองกลคอยสั่งการว่าจะ “เปิด” หรือ “ปิด” โหมด Grid รวมถึงเปลี่ยนตัวเองเป็นระบบ Trend Following เวลาตลาดเลือกข้างแรงๆ
เราจะแบ่งโครงสร้างการทำงานของระบบออกเป็น 3 ส่วนหลัก: 1. ตัวจำแนกสภาวะตลาด (The Classifier), 2. กลยุทธ์การลุยหน้างานตามแนวรับแนวต้าน และ 3. โหมดการเทรด (Execution Modes)
1. สมองกล: จำแนกสภาวะตลาด (Market Structure)
เราจะใช้โครงสร้างราคา ($Market\ Structure$) และอินดิเคเตอร์วัดความแรงของเทรนด์ (เช่น ADX หรือ Bollinger Bands Width) มาแบ่งสถานะตลาดออกเป็น 3 รูปแบบ:
- Strong Trend (เทรนด์แรง): ราคาทำ $Higher\ High\ (HH) / Higher\ Low\ (HL)$ หรือ $Lower\ Low\ (LL) / Lower\ High\ (LH)$ ชัดเจน และความชันสูง
- Weak Trend / Sideway Up-Down (เทรนด์อ่อน): ราคาเคลื่อนที่ในทิศทางใดทิศทางหนึ่ง แต่มีระยะย่อตัวลึก โครงสร้างเริ่มซ้อนทับกัน ($Overlapping$)
- Ranging / Sideway (ไม่มีเทรนด์): ราคาติดอยู่ในกรอบแนวรับแนวต้านที่ชัดเจน ไม่สามารถสร้าง High ใหม่หรือ Low ใหม่ได้
2. กลยุทธ์เมื่อราคาเข้าใกล้ “แนวรับ-แนวต้าน” (Key Zones)
เมื่อราคาเดินทางมาถึงแนวรับแนวต้านหลัก (เช่น ในกรอบ $H4$ หรือ $Daily$) ระบบจะไม่วาง Grid แบบสุ่มสี่สุ่มห้า แต่จะหยิบ Price Action มาพิจารณาดังนี้:
เคสที่ A: ราคาวิ่งเข้าหาแนวต้าน + ตลาดเป็นเทรนด์ขาขึ้น (Uptrend)
- พิจารณาจาก Price Action:
- หากเกิดแท่งเทียนพุ่งแรง ($Marubozu$) ทะลุแนวต้าน $\rightarrow$ ประเมินว่า Breakout ให้เปลี่ยนเป็นโหมดติดตามเทรนด์ทันที
- หากเกิดปฏิเสธราคา ($Price\ Rejection$) เช่น $Pin\ Bar$, $Bearish\ Engulfing$ $\rightarrow$ ประเมินว่าติดแนวต้าน ระบบจะเริ่มเปิด Grid ฝั่ง Short (Sell) เฉพาะบริเวณด้านบนของกรอบ โดยมีระยะคุมขาดทุนชัดเจน
เคสที่ B: ราคาวิ่งเข้าหาแนวรับ + ตลาดเป็นเทรนด์ขาลง (Downtrend)
- พิจารณาจาก Price Action:
- หากทะลุพรวดแบบมีโวลุ่ม $\rightarrow$ Follow Sell ตามเทรนด์แรง
- หากเริ่มสร้างฐาน เกิด $Bullish\ Divergence$ หรือ $Morning\ Star$ $\rightarrow$ เปิด Grid ฝั่ง Long (Buy) เพื่อดักกินรอบเด้งตรงแนวรับ
3. ผังการทำงานของระบบ (Execution Flow)
เมื่อระบบเข้าใจสภาวะตลาดและตำแหน่งของราคาแล้ว ระบบจะสลับโหมดการทำงานโดยอัตโนมัติดังนี้ครับ:
[ วิเคราะห์โครงสร้างตลาด (Market Structure) ]
|
-----------------------------------------------------------------
| | |
[ Strong Trend ] [ Weak Trend ] [ Ranging / No Trend ]
| | |
v v v
(โหมด Trend Following) (โหมด Trend-Biased Grid) (โหมด Classic Range Grid)
- วิ่งทิศทางเดียว - วาง Grid เฉพาะฝั่งเทรนด์ - วาง Grid ทั้งสองฝั่ง (Buy/Sell)
- ถือรันเทรนด์คำใหญ่ - ย่อซื้อ (Buy) / เด้งขาย (Sell) - เน้นเก็บ Cash Flow ระยะสั้น
- มี Trailing Stop - ถอนออเดอร์หากหลุดโครงสร้าง - มี Max Drawdown คุมหัวท้าย
เจาะลึกการทำงานของแต่ละโหมด (How it works)
🚀 โหมดที่ 1: Trend Following (สำหรับ Strong Trend)
สภาวะ: ตลาดระเบิดตัวออกจากกรอบ เลือกทิศทางชัดเจน
- การวาง Grid: ปิดระบบ Grid สวนเทรนด์เด็ดขาด! (ห้ามเปิด Sell สวนตอนขาขึ้น)
- การเข้าออเดอร์: เปลี่ยนมาใช้การเข้าแบบ Pyramiding (Grid ตามเทรนด์) แทน คือจะเปิดออเดอร์เพิ่มเมื่อราคาเบรคทะลุ $High$ เดิมขึ้นไป หรือเปิดเมื่อราคาย่อตัวลงมาแตะแนวรับย่อย ($Pullback$)
- การล็อกกำไร: ออเดอร์ทั้งหมดในชุดนี้ จะถูกผูกเข้ากับ Trailing Stop (เช่น ขยับตาม $Moving\ Average$ หรือตาม $Higher\ Low$ ล่าสุด) หากเทรนด์กลับตัว จะปิดทำกำไรพร้อมกันทั้งหมด ได้กำไรคำใหญ่มาก
🔄 โหมดที่ 2: Trend-Biased Grid (สำหรับ Weak Trend / เทรนด์อ่อน)
สภาวะ: ตลาดค่อยๆ ไต่ระดับขึ้นหรือลง มีการย่อตัวบ่อยและลึก
- การวาง Grid: วาง Grid ทิศทางเดียว (One-way Grid) ตามเทรนด์หลักเท่านั้น เช่น ถ้าเป็นเทรนด์ขาขึ้นอ่อนๆ จะเปิดเฉพาะ “Grid Buy” ด้านล่างของราคาปัจจุบัน (ไม่เปิด Grid Sell สวน)
- กลยุทธ์ลดความเสี่ยง:
- ใช้ Market Structure คุม: อาร์เรย์ของ Grid Buy ชุดนี้ จะมีจุด Stop Loss ร่วมกัน (Global SL) อยู่ที่แนวรับ $Lower\ Low$ ก่อนหน้า หากราคาหลุดโครงสร้างขาขึ้น แปลว่าเทรนด์พัง ระบบจะตัดขาดทุนทันที เจ็บน้อย ไม่ยอมโดนลากจนพอร์ตแตก
- เมื่อราคาวิ่งขึ้นไปทำ $New\ High$ ระบบจะขยับโซน Grid Buy ตามขึ้นไปเป็นขั้นบันได
🦘 โหมดที่ 3: Classic Range Grid (สำหรับ Sideway / ไม่มีเทรนด์)
สภาวะ: ราคาแกว่งตัวไร้ทิศทาง อยู่ระหว่างแนวรับ-แนวต้านที่ชัดเจน
- การวาง Grid: เปิดใช้งาน Two-way Grid (ทั้ง Buy และ Sell)
- กลยุทธ์ลดความเสี่ยง:
- โซนปลอดภัย: วาง Grid Buy เฉพาะครึ่งล่างของกรอบ (ใกล้แนวรับ) และวาง Grid Sell เฉพาะครึ่งบนของกรอบ (ใกล้แนวต้าน)
- Price Action Confirmation: แทนที่จะวาง Limit Order ทิ้งไว้เฉลี่ยทุกๆ 10 pips ระบบจะยอมให้เปิดเส้น Grid นั้นๆ ก็ต่อเมื่อมี Price Action กลับตัวสั้นๆ ในไทม์เฟรมย่อย (เช่น M5/M15) เกิดขึ้นที่เส้นนั้นก่อน เพื่อป้องกันกรณีที่ราคาวิ่งทะลุกรอบแรงๆ
💡 สรุปคีย์สำคัญที่ทำให้ระบบนี้รอดในระยะยาว
- มีประตูทางออกเสมอ (Absolute Stop Loss): ระบบนี้ใช้ Market Structure ($HH/HL/LH/LL$) เป็นตัวกำหนดจุดยอมแพ้ของ Grid เสมอ ทำให้เราจำกัดความเสียหายสูงสุด ($Max\ Loss$) ได้ล่วงหน้า ไม่เหมือน Grid ทั่วไปที่ปล่อยลากไม่มีจุดจบ
- เปลี่ยนศัตรูให้เป็นมิตร: ในระบบ Grid ทั่วไป “เทรนด์แรง” คือฝันร้ายที่จะมาล้างพอร์ต แต่ในระบบ Hybrid Grid นี้ เทรนด์แรงคือ “โอกาสทำเงินที่ใหญ่ที่สุด” เพราะระบบจะสลับไปเป็นโหมดรันเทรนด์โดยอัตโนมัติครับ
นี่คือโค้ด MQL4 (สำหรับ MT4 EA) ที่ถูกออกแบบมาตามโครงสร้างระบบ Adaptive Hybrid Grid (AHG) อย่างครบถ้วนครับ โดยเก็บแนวคิดหลักทั้งหมดไว้ และแก้ปัญหาเรื่องภาษาไทยในโค้ด (Encoding) ด้วยการใช้ภาษาอังกฤษในส่วนเทคนิค เพื่อความเสถียรในการรันบนระบบสากลครับ
โค้ดนี้ใช้ ATR ในการคำนวณระยะกรอบ, ใช้ Donchian Channel / Moving Average ในการแยกแยะ Market Structure และใช้การเช็คแท่งเทียนในการทำ Price Action Confirmation ครับ
Code snippet
//+------------------------------------------------------------------+
//| Adaptive_Hybrid_Grid.mq4|
//| Copyright 2026, HybridTrader AI|
//| https://www.your.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026"
#property link "https://www.your.com"
#property version "1.00"
#property strict
//--- INPUT PARAMETERS ---
input string _s1 = "=== Risk & Money Management ===";
input double InpBaseLot = 0.01; // Base Lot Size
input double InpMaxDrawdownPct = 20.0; // Max Account Equity DD % to Close All
input int InpMaxGridOrders = 6; // Max Allowed Grid Orders per Side
input string _s2 = "=== Market Structure Settings ===";
input int InpTrendPeriod = 50; // Period for Trend Identification
input int InpATRPeriod = 14; // ATR Period for Dynamic Grid Distance
input double InpATRMultiplier = 1.5; // Grid Distance = ATR * Multiplier
input string _s3 = "=== Trend Following Mode ===";
input int InpTrailingStop = 300; // Trailing Stop in Points for Trend Mode
input int InpTrailingStep = 50; // Trailing Step in Points
//--- ENUMS ---
enum ENUM_MARKET_STATE {
STATE_STRONG_TREND_UP,
STATE_STRONG_TREND_DOWN,
STATE_WEAK_TREND,
STATE_RANGING
};
//--- GLOBAL VARIABLES ---
int MagicNumber = 881122;
datetime lastBarTime;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit() {
lastBarTime = 0;
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick() {
// 1. Emergency Global Risk Management (Safety Guard)
CheckGlobalProtection();
// Run core logic once per bar to ensure structural stability
if(Time[0] == lastBarTime) return;
lastBarTime = Time[0];
// 2. Classify Market Structure
ENUM_MARKET_STATE currentMarketState = ClassifyMarketStructure();
// 3. Get Key Support / Resistance Zones
double supportZone = 0, resistanceZone = 0;
FindSupportResistance(supportZone, resistanceZone);
// 4. Execution Core Logic based on state and zones
ExecuteCoreStrategy(currentMarketState, supportZone, resistanceZone);
}
//+------------------------------------------------------------------+
//| 1. MARKET STRUCTURE CLASSIFIER |
//+------------------------------------------------------------------+
ENUM_MARKET_STATE ClassifyMarketStructure() {
double maFast = iMA(Symbol(), Period(), InpTrendPeriod / 2, 0, MODE_EMA, PRICE_CLOSE, 1);
double maSlow = iMA(Symbol(), Period(), InpTrendPeriod, 0, MODE_EMA, PRICE_CLOSE, 1);
double atr = iATR(Symbol(), Period(), InpATRPeriod, 1);
// Check price standard deviation or bandwidth to differentiate strong trend vs ranging
double upperBand = iBands(Symbol(), Period(), 20, 2.0, 0, PRICE_CLOSE, MODE_UPPER, 1);
double lowerBand = iBands(Symbol(), Period(), 20, 2.0, 0, PRICE_CLOSE, MODE_LOWER, 1);
double bandwidth = upperBand - lowerBand;
double minBandwidth = 300 * Point; // Adaptive baseline threshold
// High/Low structure check
bool isHH = (High[1] > High[2] && High[2] > High[3]);
bool isLL = (Low[1] < Low[2] && Low[2] < Low[3]);
if(maFast > maSlow && isHH && bandwidth > minBandwidth) {
return(STATE_STRONG_TREND_UP);
}
if(maFast < maSlow && isLL && bandwidth > minBandwidth) {
return(STATE_STRONG_TREND_DOWN);
}
if(bandwidth < minBandwidth) {
return(STATE_RANGING);
}
return(STATE_WEAK_TREND);
}
//+------------------------------------------------------------------+
//| 2. KEY ZONE DETECTION (SUPPORT & RESISTANCE) |
//+------------------------------------------------------------------+
void FindSupportResistance(double &sup, double &res) {
// Using Donchian Channel concept over past 24 bars to identify local structural boundaries
int highestBar = iHighest(Symbol(), Period(), MODE_HIGH, 24, 2);
int lowestBar = iLowest(Symbol(), Period(), MODE_LOW, 24, 2);
res = High[highestBar];
sup = Low[lowestBar];
}
//+------------------------------------------------------------------+
//| 3. PRICE ACTION CONFIRMATION ENGINE |
//+------------------------------------------------------------------+
bool IsPriceActionConfirmed(string type) {
// Simple Price Action validation (Pin Bar / Rejection Check)
double body = MathAbs(Close[1] - Open[1]);
double upperShadow = High[1] - MathMax(Open[1], Close[1]);
double lowerShadow = MathMin(Open[1], Close[1]) - Low[1];
if(type == "BULLISH_REJECTION") {
// Pinbar pattern pointing down at support zone
if(lowerShadow > (body * 2) && Close[1] >= Open[1]) return true;
}
if(type == "BEARISH_REJECTION") {
// Pinbar pattern pointing up at resistance zone
if(upperShadow > (body * 2) && Close[1] <= Open[1]) return true;
}
return false;
}
//+------------------------------------------------------------------+
//| 4. CORE EXECUTION ENGINE (ALIGNED WITH SYSTEM MODES) |
//+------------------------------------------------------------------+
void ExecuteCoreStrategy(ENUM_MARKET_STATE state, double sup, double res) {
int totalBuyGrid = CountOrders(OP_BUY);
int totalSellGrid = CountOrders(OP_SELL);
double currentPrice = Close[0];
double atr = iATR(Symbol(), Period(), InpATRPeriod, 1);
double gridDistance = atr * InpATRMultiplier;
//----------------------------------------------------------------
// MODE 1: STRONG TREND FOLLOWING (Pyramiding Mode - No Counter Grid)
//----------------------------------------------------------------
if(state == STATE_STRONG_TREND_UP) {
CloseAllOrdersByType(OP_SELL); // Strictly kill counter-trend positions
if(totalBuyGrid == 0) {
SendMarketOrder(OP_BUY, InpBaseLot);
} else {
// Pyramiding on Breakout: Open next grid level only if price clears previous high
double lastBuyPrice = GetLastOrderPrice(OP_BUY);
if(currentPrice > lastBuyPrice + gridDistance && totalBuyGrid < InpMaxGridOrders) {
SendMarketOrder(OP_BUY, InpBaseLot);
}
}
ApplyGlobalTrailingStop(OP_BUY);
return;
}
if(state == STATE_STRONG_TREND_DOWN) {
CloseAllOrdersByType(OP_BUY); // Strictly kill counter-trend positions
if(totalSellGrid == 0) {
SendMarketOrder(OP_SELL, InpBaseLot);
} else {
double lastSellPrice = GetLastOrderPrice(OP_SELL);
if(currentPrice < lastSellPrice - gridDistance && totalSellGrid < InpMaxGridOrders) {
SendMarketOrder(OP_SELL, InpBaseLot);
}
}
ApplyGlobalTrailingStop(OP_SELL);
return;
}
//----------------------------------------------------------------
// MODE 2: TREND-BIASED GRID (Weak Trend Management)
//----------------------------------------------------------------
if(state == STATE_WEAK_TREND) {
double maFast = iMA(Symbol(), Period(), 20, 0, MODE_SMA, PRICE_CLOSE, 1);
double maSlow = iMA(Symbol(), Period(), 50, 0, MODE_SMA, PRICE_CLOSE, 1);
if(maFast > maSlow) { // Weak Bullish
CloseAllOrdersByType(OP_SELL); // Safety: No Sell Grid allowed
// Biased Grid Placement: Place Buy grid elements safely below market price (Pullbacks)
if(totalBuyGrid == 0 && currentPrice <= sup + (atr * 0.5)) {
SendMarketOrder(OP_BUY, InpBaseLot);
} else if(totalBuyGrid > 0 && totalBuyGrid < InpMaxGridOrders) {
double lastBuy = GetLastOrderPrice(OP_BUY);
if(currentPrice <= lastBuy - gridDistance) {
SendMarketOrder(OP_BUY, InpBaseLot);
}
}
// Absolute Structural Stop Loss (Safety Valve)
ManageStructuralStopLoss(OP_BUY, sup);
}
else { // Weak Bearish
CloseAllOrdersByType(OP_BUY); // Safety: No Buy Grid allowed
if(totalSellGrid == 0 && currentPrice >= res - (atr * 0.5)) {
SendMarketOrder(OP_SELL, InpBaseLot);
} else if(totalSellGrid > 0 && totalSellGrid < InpMaxGridOrders) {
double lastSell = GetLastOrderPrice(OP_SELL);
if(currentPrice >= lastSell + gridDistance) {
SendMarketOrder(OP_SELL, InpBaseLot);
}
}
ManageStructuralStopLoss(OP_SELL, res);
}
return;
}
//----------------------------------------------------------------
// MODE 3: CLASSIC RANGE GRID (Sideway Range Management)
//----------------------------------------------------------------
if(state == STATE_RANGING) {
double midPoint = (sup + res) / 2.0;
// GRID BUY: Only valid in the bottom half of the range near support
if(currentPrice < midPoint && currentPrice > sup) {
if(totalBuyGrid == 0 && IsPriceActionConfirmed("BULLISH_REJECTION")) {
SendMarketOrder(OP_BUY, InpBaseLot);
} else if(totalBuyGrid > 0 && totalBuyGrid < InpMaxGridOrders) {
double lastBuy = GetLastOrderPrice(OP_BUY);
if(currentPrice <= lastBuy - gridDistance) {
SendMarketOrder(OP_BUY, InpBaseLot);
}
}
}
// GRID SELL: Only valid in the top half of the range near resistance
if(currentPrice > midPoint && currentPrice < res) {
if(totalSellGrid == 0 && IsPriceActionConfirmed("BEARISH_REJECTION")) {
SendMarketOrder(OP_SELL, InpBaseLot);
} else if(totalSellGrid > 0 && totalSellGrid < InpMaxGridOrders) {
double lastSell = GetLastOrderPrice(OP_SELL);
if(currentPrice >= lastSell + gridDistance) {
SendMarketOrder(OP_SELL, InpBaseLot);
}
}
}
// Hard exit bounds if price breaks completely out of range structure
ManageStructuralStopLoss(OP_BUY, sup - (atr * 0.5));
ManageStructuralStopLoss(OP_SELL, res + (atr * 0.5));
// Clean target basket TP closures
CheckGridBasketTakeProfit();
}
}
//+------------------------------------------------------------------+
//| HELPER UTILITY FUNCTIONS |
//+------------------------------------------------------------------+
void SendMarketOrder(int type, double lot) {
double price = (type == OP_BUY) ? Ask : Bid;
int ticket = OrderSend(Symbol(), type, lot, price, 3, 0, 0, "AHG_Order", MagicNumber, 0, (type == OP_BUY) ? clrGreen : clrRed);
}
int CountOrders(int type) {
int count = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderType() == type) {
count++;
}
}
}
return count;
}
double GetLastOrderPrice(int type) {
double price = 0;
datetime lastTime = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderType() == type) {
if(OrderOpenTime() > lastTime) {
lastTime = OrderOpenTime();
price = OrderOpenPrice();
}
}
}
}
return price;
}
void CloseAllOrdersByType(int type) {
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderType() == type) {
bool res = OrderClose(OrderTicket(), OrderLots(), (type == OP_BUY) ? Bid : Ask, 3, clrWhite);
}
}
}
}
void ManageStructuralStopLoss(int type, double invalidationLevel) {
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderType() == type) {
if(type == OP_BUY && Close[0] < invalidationLevel) {
bool res = OrderClose(OrderTicket(), OrderLots(), Bid, 3, clrOrange);
}
if(type == OP_SELL && Close[0] > invalidationLevel) {
bool res = OrderClose(OrderTicket(), OrderLots(), Ask, 3, clrOrange);
}
}
}
}
}
void ApplyGlobalTrailingStop(int type) {
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderType() == type) {
if(type == OP_BUY) {
if(Bid - OrderOpenPrice() > InpTrailingStop * Point) {
if(OrderStopLoss() < Bid - InpTrailingStop * Point) {
bool res = OrderModify(OrderTicket(), OrderOpenPrice(), Bid - InpTrailingStop * Point, OrderTakeProfit(), 0, clrBlue);
}
}
}
if(type == OP_SELL) {
if(OrderOpenPrice() - Ask > InpTrailingStop * Point) {
if(OrderStopLoss() > Ask + InpTrailingStop * Point || OrderStopLoss() == 0) {
bool res = OrderModify(OrderTicket(), OrderOpenPrice(), Ask + InpTrailingStop * Point, OrderTakeProfit(), 0, clrBlue);
}
}
}
}
}
}
}
void CheckGridBasketTakeProfit() {
// Average-based basket recovery closing logic for Ranging mode
double totalProfit = 0;
int openTrades = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
totalProfit += OrderProfit() + OrderSwap() + OrderCommission();
openTrades++;
}
}
}
// If the combined basket profit hits target metric (e.g., small profit cushion), close all grid elements
if(openTrades > 0 && totalProfit > (openTrades * 2.0)) {
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
bool res = OrderClose(OrderTicket(), OrderLots(), (OrderType() == OP_BUY) ? Bid : Ask, 3, clrGold);
}
}
}
}
}
void CheckGlobalProtection() {
// Account Equity Drawdown Protection Safeguard
double balance = AccountBalance();
double equity = AccountEquity();
double currentDD = ((balance - equity) / balance) * 100.0;
if(currentDD >= InpMaxDrawdownPct) {
Print("CRITICAL ALERT: Max Drawdown Limit Reached. Closing all active assets.");
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
bool res = OrderClose(OrderTicket(), OrderLots(), (OrderType() == OP_BUY) ? Bid : Ask, 3, clrViolet);
}
}
}
}
}
🔍 จุดสำคัญที่ EA ตัวนี้รักษาแนวคิดระบบอย่างเข้มงวด:
- โหมด Strong Trend (ผันตัวเองเป็น Trend Following): เมื่อ
ClassifyMarketStructure()ตรวจสอบเจอว่าตลาดมีโมเมนตัมแรง มันจะสั่งลบออเดอร์ฝั่งสวนเทรนด์ออกทันที (CloseAllOrdersByType) และเปลี่ยนการกดออเดอร์เป็นแบบ Pyramiding เท่านั้น (เข้าออเดอร์เพิ่มเมื่อราคาทำลายระดับ High/Low เดิม) พร้อมเปิดระบบ Trailing Stop เพื่อรันเทรนด์กินคำใหญ่ - โหมด Weak Trend (Grid ฝั่งเดียว): ระบบจะตรวจจับทิศทางหลัก หากเป็นขาขึ้นแต่แรงไม่มาก มันจะอนุญาตให้ใช้แค่ Grid Buy ในจังหวะย่อตัว และสั่งตัดสิทธิ์การออกออเดอร์ Grid Sell เด็ดขาด เพื่อป้องกันปัญหาโดนลากจนพอร์ตพัง
- Price Action & Key Zone Confirmation: ในช่วงที่ตลาดเป็น Ranging (Sideway) ระบบจะไม่วาง Pending Order ทิ้งไว้สะเปะสะปะ แต่มันจะคำนวณ
midPointเพื่อแบ่งฝั่งเล่น (ซื้อต่ำ-ขายสูง) และจะเข้าออเดอร์ผ่านสัญญาณทางจิตวิทยาตลาด (IsPriceActionConfirmed) โดยดูการทิ้งไส้เทียนปฏิเสธราคา ($Rejection\ Pin\ Bar$) ที่โซนแนวรับแนวต้านก่อนเปิดออเดอร์กริดแรก - ความปลอดภัยชั้นสุดท้าย (Safety Invalidation): มีระบบ
ManageStructuralStopLossคอยเฝ้า หากสภาวะตลาดเปลี่ยนกระทันหันแล้วราคาดันหลุดจุดต่ำสุดหรือทะลุจุดสูงสุดเก่า ระบบจะปิดคัทลอสชุดกริดทันที ไม่ปล่อยให้ลาก และมีตัวคุม Equity Drawdown (CheckGlobalProtection) เป็นเบรกมือตัวสุดท้ายครับ
Prompt
You are an expert algorithmic trading system architect and a senior quantitative developer. Your task is to develop a complete, production-ready, and highly robust Expert Advisor/Trading Script based on the “Adaptive Hybrid Grid (AHG)” architecture described below.
You must strictly adhere to the structural logic, market states, and safety mechanics without taking shortcuts.
1. CORE ARCHITECTURE OVERVIEW
The Adaptive Hybrid Grid (AHG) is designed to mitigate the fatal flaw of traditional grid systems (getting blown out by a strong trend) by dynamically switching its execution behavior between “Trend Following” and “Range-Bound Grid” based on Market Structure, Key Zones (Support/Resistance), and Price Action confirmation.
2. MARKET CLASSIFICATION ENGINE (THE BRAIN)
The system must analyze the market structure at the closing of each bar and classify it into one of the following 4 states:
- STATE_STRONG_TREND_UP: Fast MA > Slow MA AND Price making clean Higher Highs (HH) & Higher Lows (HL) AND Market Volatility/Bandwidth expands above baseline.
- STATE_STRONG_TREND_DOWN: Fast MA < Slow MA AND Price making clean Lower Lows (LL) & Lower Highs (LH) AND Market Volatility/Bandwidth expands above baseline.
- STATE_WEAK_TREND: Moving averages show a directional bias, but market structure is overlapping or shallow, indicating a grinding/weak trend.
- STATE_RANGING: Market volatility contracts, and price is trapped inside localized structural boundaries (Support/Resistance) with no clear direction.
3. EXECUTION LOGIC PER MARKET STATE (STRICT COMPLIANCE)
MODE 1: STRONG TREND FOLLOWING (For STATE_STRONG_TREND_UP / DOWN)
- ACTION: Turn OFF all counter-trend grid placements immediately. If counter-trend orders exist, close them instantly.
- ENTRY: Activate “Pyramiding Grid” (Pro-Trend Grid). Open the first trade in the direction of the trend. Only open subsequent grid levels if the price breaks and closes beyond the previous grid level’s high/low (Breakout entry).
- RISK MANAGEMENT: All positions in this mode must be managed by a tight Trailing Stop based on the latest structural Higher Low / Lower High or a fixed trailing step.
MODE 2: TREND-BIASED GRID (For STATE_WEAK_TREND)
- ACTION: Restrict grid operations to ONE-WAY ONLY.
- BULLISH BIAS: Disallow all Sell orders. Only allow “Buy Grid” elements placed BELOW the current market price (catching pullbacks).
- BEARISH BIAS: Disallow all Buy orders. Only allow “Sell Grid” elements placed ABOVE the current market price (catching retracements).
- RISK MANAGEMENT: Apply a strict “Global Structural Stop Loss”. If the price breaks and invalidates the local key support (for Buy Grid) or key resistance (for Sell Grid), close the entire grid basket immediately. Do not let it hang.
MODE 3: CLASSIC RANGE GRID (For STATE_RANGING)
- ACTION: Enable Two-Way Grid trading, but restrict the placement zones.
- BOUNDARY RULE: Split the current trading range into two halves (Upper and Lower). Only allow “Grid Buy” in the lower half near the Support Zone. Only allow “Grid Sell” in the upper half near the Resistance Zone.
- PRICE ACTION ENGINE: Do not blind-place pending orders. Before opening the first grid level near a support or resistance zone, validate via a Price Action engine looking for “Rejection Candles” (e.g., Pin Bars with long wicks rejecting the zone).
- EXIT RULE: Implement a basket take profit (cushion recovery closure) to clear out the grid when the combined basket net profit hits the target.
4. SAFETY SYSTEMS & RISK GUARDRAILS (CRITICAL)
- Dynamic Grid Distance: Grid spacing must not be static. It must be dynamically calculated using the Average True Range (ATR) multiplied by a user-defined factor (e.g., Distance = ATR * 1.5).
- Global Equity Protection: Monitor the total account drawdown. If the floating drawdown of this specific system exceeds a user-defined threshold (e.g., 20% of account equity), trigger an emergency circuit breaker: close all open positions, delete all pending orders, and halt execution.
OUTPUT REQUIREMENTS
- Write clean, modular, and fully commented code.
- Ensure there are no infinite loops or memory leaks in the data arrays.
- Provide descriptive input parameters for: Base Lot Size, Max Allowed Grid Orders, Trend Filter Periods, ATR Settings, and Emergency Max Drawdown %.

