iJam StudioiJam Studio
🤖 บทที่ 7: Trading Bot & Automation

เขียน EA ด้วย MQL5 เบื้องต้น

โครงสร้าง EA, ฟังก์ชันสำคัญ และเขียน EA ตัวแรก

30 นาทีบทเรียนที่ 19

Expert Advisor (EA) คืออะไร

Expert Advisor หรือ EA คือ โปรแกรมที่เทรดอัตโนมัติ บนแพลตฟอร์ม MetaTrader 5 โดย EA จะวิเคราะห์ตลาด ตัดสินใจ และเปิด/ปิด Trade ให้โดยอัตโนมัติตามเงื่อนไขที่เราเขียนไว้

EA ทำอะไรได้:

  • เปิด/ปิด Order อัตโนมัติ

  • จัดการ Stop Loss, Take Profit

  • Trailing Stop อัตโนมัติ

  • วิเคราะห์ Indicator แล้วส่ง Signal

  • เทรด 24 ชั่วโมงไม่มีหยุด (ไม่เหนื่อย ไม่มีอารมณ์)


หมายเหตุ: EA เทรดตามที่เราเขียนเท่านั้น ถ้าเขียนกลยุทธ์ผิด EA ก็ขาดทุน ไม่ใช่ "เครื่องพิมพ์เงิน"


MQL5 คืออะไร

MQL5 (MetaQuotes Language 5) เป็นภาษาโปรแกรมเฉพาะที่ใช้เขียน EA, Custom Indicator, และ Script สำหรับ MetaTrader 5

คุณสมบัติของ MQL5:

  • Syntax คล้าย C++ / C#

  • มี Built-in Functions สำหรับการเทรดโดยเฉพาะ

  • เข้าถึงข้อมูลราคา, Indicator, Account ได้ง่าย

  • Compile เป็น .ex5 ไฟล์ที่รันบน MT5


ถ้าคุณเคยเขียน C, C++, Java, หรือ C# มาก่อน จะเรียน MQL5 ได้เร็วมาก เพราะโครงสร้างคล้ายกัน


MetaEditor — IDE สำหรับเขียน MQL5

MetaEditor เป็น Integrated Development Environment (IDE) ที่มาพร้อมกับ MT5:

วิธีเปิด MetaEditor:

  • ใน MT5 กด F4 หรือไปที่ Tools → MetaQuotes Language Editor


ฟีเจอร์สำคัญ:
  • Code Editor: เขียน/แก้ไขโค้ด MQL5

  • Compiler: คอมไพล์โค้ดเป็น .ex5

  • Debugger: Debug หาข้อผิดพลาด

  • MQL5 Wizard: สร้างโครงสร้าง EA เบื้องต้นให้อัตโนมัติ

  • Help (F1): เอกสารอ้างอิง MQL5 ที่ครบถ้วน


Tip: ใช้ MQL5 Wizard สร้าง EA ใหม่ จะได้โครงสร้างพื้นฐานมาเลย ไม่ต้องเขียนตั้งแต่ศูนย์


โครงสร้าง EA พื้นฐาน

EA ทุกตัวมีโครงสร้างหลัก 3 ส่วน:

//+------------------------------------------------------------------+
//|                                              MyFirstEA.mq5       |
//|                                              iJam Studio         |
//+------------------------------------------------------------------+
#property copyright "iJam Studio"
#property version   "1.00"
#property description "My First Expert Advisor"

//--- Input Parameters (ผู้ใช้ปรับได้ตอนใช้งาน)
input double LotSize = 0.01; // ขนาด Lot
input int StopLoss = 50; // Stop Loss (points)
input int TakeProfit = 100; // Take Profit (points)

//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
Print("EA Started on ", _Symbol, " ", EnumToString(_Period));
return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Print("EA Stopped! Reason: ", reason);
}

//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// โค้ดที่ทำงานทุกครั้งที่ราคาเปลี่ยน (ทุก Tick)
// ใส่ Logic การเทรดตรงนี้
}


อธิบายทุก Function หลัก

OnInit() — เริ่มต้นทำงาน

  • ทำงาน ครั้งเดียว ตอนที่แนบ EA เข้ากับ Chart
  • ใช้สำหรับ:
- ตั้งค่าเริ่มต้น - สร้าง Indicator Handle - ตรวจสอบเงื่อนไขเบื้องต้น (เช่น Symbol ถูกต้องไหม)
  • Return INIT_SUCCEEDED ถ้าทุกอย่าง OK
  • Return INIT_FAILED ถ้ามีปัญหา (EA จะหยุดทำงาน)

OnDeinit() — หยุดทำงาน

  • ทำงาน ครั้งเดียว ตอนที่ถอด EA ออกจาก Chart หรือปิด MT5
  • ใช้สำหรับ:
- ทำความสะอาด (Cleanup) - ลบ Indicator Handle - บันทึกข้อมูล
  • Parameter reason บอกเหตุผลที่ EA หยุด

OnTick() — ทำงานทุก Tick

  • ทำงาน ทุกครั้งที่ราคาเปลี่ยน (ทุก Tick)
  • เป็น หัวใจของ EA — Logic การเทรดทั้งหมดอยู่ตรงนี้
  • สิ่งที่ทำใน OnTick():
- อ่านค่า Indicator - ตรวจสอบเงื่อนไข Entry/Exit - เปิด/ปิด/แก้ไข Order - จัดการ Trailing Stop

ข้อควรระวัง: OnTick() ถูกเรียกบ่อยมาก อย่าใส่โค้ดที่ทำงานหนักเกินไป


Input Parameters

Input Parameters คือ ตัวแปรที่ผู้ใช้สามารถปรับได้ ผ่านหน้าต่าง Properties ของ EA:

input double LotSize       = 0.01;    // ขนาด Lot
input int    StopLoss      = 50;      // Stop Loss (points)
input int    TakeProfit    = 100;     // Take Profit (points)
input int    MagicNumber   = 12345;   // Magic Number (แยก EA)
input int    FastMAPeriod  = 10;      // Fast MA Period
input int    SlowMAPeriod  = 50;      // Slow MA Period

ประโยชน์:

  • ปรับค่าได้ โดยไม่ต้องแก้โค้ด

  • ใช้ใน Optimization (Strategy Tester จะลองค่าต่างๆ ให้)

  • Comment หลัง // จะแสดงเป็นชื่อใน Properties Window



ฟังก์ชันสำคัญใน MQL5

iMA() — เรียกค่า Moving Average

// สร้าง Handle (ทำใน OnInit)
int maHandle = iMA(_Symbol, PERIOD_H1, 20, 0, MODE_EMA, PRICE_CLOSE);

// อ่านค่า (ทำใน OnTick)
double maValue[];
ArraySetAsSeries(maValue, true);
CopyBuffer(maHandle, 0, 0, 3, maValue);
// maValue[0] = ค่า MA ของแท่งปัจจุบัน
// maValue[1] = ค่า MA ของแท่งก่อนหน้า

Parameters ของ iMA():

  • _Symbol — คู่เงินปัจจุบัน

  • PERIOD_H1 — Timeframe

  • 20 — Period

  • 0 — Shift

  • MODE_EMA — ประเภท MA (SMA, EMA, SMMA, LWMA)

  • PRICE_CLOSE — ราคาที่ใช้คำนวณ


CTrade Class — ส่งคำสั่งเทรด

#include <Trade\Trade.mqh>
CTrade trade;

// ตั้ง Magic Number
trade.SetExpertMagicNumber(12345);

// เปิด Buy
trade.Buy(0.01, _Symbol, 0, sl, tp, "Buy Signal");

// เปิด Sell
trade.Sell(0.01, _Symbol, 0, sl, tp, "Sell Signal");

// ปิด Position
trade.PositionClose(_Symbol);

CTrade ทำให้การส่งคำสั่งง่ายขึ้นมาก เมื่อเทียบกับการใช้ OrderSend() โดยตรง

PositionSelect() & PositionGetTicket() — จัดการ Position

// ตรวจสอบว่ามี Position เปิดอยู่หรือไม่
if(PositionSelect(_Symbol))
{
   double profit = PositionGetDouble(POSITION_PROFIT);
   double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
   long type = PositionGetInteger(POSITION_TYPE);
   Print("Position Profit: ", profit);
}

// วนลูปทุก Position
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
if(ticket > 0)
{
string symbol = PositionGetString(POSITION_SYMBOL);
long magic = PositionGetInteger(POSITION_MAGIC);
// ทำอะไรกับ Position...
}
}

SymbolInfoDouble() — ดูราคา Bid/Ask

double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double spread = ask - bid;
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);

Print("Bid: ", bid, " Ask: ", ask, " Spread: ", spread/point, " points");


ตัวอย่าง EA: MA Crossover EA (เต็มรูปแบบ)

นี่คือ EA ที่เทรดตาม สัญญาณ Moving Average Crossover:

//+------------------------------------------------------------------+
//|                                           MACrossoverEA.mq5      |
//|                                           iJam Studio            |
//+------------------------------------------------------------------+
#property copyright "iJam Studio"
#property version   "1.00"
#property description "Simple MA Crossover Expert Advisor"

#include <Trade\Trade.mqh>

//--- Input Parameters
input int FastMAPeriod = 10; // Fast MA Period
input int SlowMAPeriod = 20; // Slow MA Period
input double Lots = 0.01; // Lot Size
input int StopLoss = 50; // Stop Loss (points)
input int TakeProfit = 100; // Take Profit (points)
input int MagicNumber = 10001; // Magic Number

//--- Global Variables
CTrade trade;
int fastMAHandle;
int slowMAHandle;

//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// ตั้ง Magic Number
trade.SetExpertMagicNumber(MagicNumber);

// สร้าง MA Handles
fastMAHandle = iMA(_Symbol, PERIOD_CURRENT, FastMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
slowMAHandle = iMA(_Symbol, PERIOD_CURRENT, SlowMAPeriod, 0, MODE_EMA, PRICE_CLOSE);

// ตรวจสอบว่าสร้าง Handle สำเร็จ
if(fastMAHandle == INVALID_HANDLE || slowMAHandle == INVALID_HANDLE)
{
Print("Error creating MA handles!");
return(INIT_FAILED);
}

Print("MA Crossover EA initialized successfully!");
return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// ลบ Indicator Handles
IndicatorRelease(fastMAHandle);
IndicatorRelease(slowMAHandle);
Print("MA Crossover EA removed.");
}

//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// อ่านค่า MA
double fastMA[], slowMA[];
ArraySetAsSeries(fastMA, true);
ArraySetAsSeries(slowMA, true);

if(CopyBuffer(fastMAHandle, 0, 0, 3, fastMA) < 3) return;
if(CopyBuffer(slowMAHandle, 0, 0, 3, slowMA) < 3) return;

// ตรวจสอบ Crossover
// แท่งก่อนหน้า: fastMA[1] vs slowMA[1]
// แท่งก่อนหน้าอีก: fastMA[2] vs slowMA[2]

bool buySignal = (fastMA[1] > slowMA[1]) && (fastMA[2] <= slowMA[2]);
bool sellSignal = (fastMA[1] < slowMA[1]) && (fastMA[2] >= slowMA[2]);

// ตรวจสอบว่ามี Position อยู่หรือไม่
bool hasPosition = false;
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
if(PositionGetInteger(POSITION_MAGIC) == MagicNumber
&& PositionGetString(POSITION_SYMBOL) == _Symbol)
{
hasPosition = true;

// ถ้ามี Buy Position แล้วเจอ Sell Signal → ปิด Position
if(sellSignal && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
trade.PositionClose(ticket);

// ถ้ามี Sell Position แล้วเจอ Buy Signal → ปิด Position
if(buySignal && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
trade.PositionClose(ticket);
}
}

// เปิด Position ใหม่
if(!hasPosition)
{
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);

if(buySignal)
{
double sl = ask - StopLoss * point;
double tp = ask + TakeProfit * point;
trade.Buy(Lots, _Symbol, ask, sl, tp, "MA Cross Buy");
Print("BUY Signal! Fast MA crossed above Slow MA");
}

if(sellSignal)
{
double sl = bid + StopLoss * point;
double tp = bid - TakeProfit * point;
trade.Sell(Lots, _Symbol, bid, sl, tp, "MA Cross Sell");
Print("SELL Signal! Fast MA crossed below Slow MA");
}
}
}


Compile & Debug

การ Compile

1. เขียนโค้ดเสร็จแล้วกด F7 (หรือ Compile Button)
2. ดูที่ Errors Tab ด้านล่าง:
- 0 errors: คอมไพล์สำเร็จ ไฟล์ .ex5 ถูกสร้าง
- มี errors: ต้องแก้ไข (กดดับเบิ้ลคลิกที่ Error จะพาไปยังบรรทัดที่ผิด)
3. Warnings: ไม่ทำให้ Compile ไม่ผ่าน แต่ควรแก้ไข

Error ที่พบบ่อย:

  • ';' expected: ลืมใส่ Semicolon ท้ายบรรทัด
  • undeclared identifier: ใช้ตัวแปรที่ยังไม่ได้ประกาศ
  • wrong parameters count: ใส่ Parameter ไม่ครบ/เกิน
  • implicit conversion: ประเภทข้อมูลไม่ตรง (เช่น ใส่ int ตรงที่ต้องการ double)

การ Debug

  • ใช้ Print() พิมพ์ค่าตัวแปรออกมาดูใน Experts Tab ของ MT5
  • ใช้ Alert() สำหรับ Pop-up แจ้งเตือน
  • ใช้ Comment() แสดงข้อความบนกราฟ
Print("Fast MA: ", fastMA[0], " Slow MA: ", slowMA[0]);
Comment("Fast MA: ", fastMA[0], "\nSlow MA: ", slowMA[0]);

ติดตั้ง EA บน Chart

ขั้นตอนการติดตั้ง:

1. Compile EA ให้สำเร็จ (ได้ไฟล์ .ex5)
2. ใน MT5 เปิด Navigator Panel (Ctrl+N)
3. ไปที่ Expert Advisors → จะเห็น EA ที่เขียน
4. ลากวาง EA ลงบน Chart ที่ต้องการ
5. ในหน้าต่าง Settings:
- Tab Common: ติ๊ก "Allow Algo Trading"
- Tab Inputs: ปรับค่า Parameter ตามต้องการ
6. กด OK
7. ตรวจสอบว่า AutoTrading ที่มุมบนของ MT5 เปิดอยู่ (ไอคอนสีเขียว)

สัญญาณว่า EA ทำงาน:

  • มุมขวาบนของ Chart แสดง ชื่อ EA พร้อมหน้ายิ้ม
  • ถ้าเห็นหน้า บึ้ง = EA ไม่ได้รับอนุญาตให้เทรด
  • ดู Experts Tab (Ctrl+Tab สลับ Tab ด้านล่าง) จะเห็น Log ของ EA

ข้อควรระวัง: ก่อนใช้ EA กับเงินจริง ต้อง Backtest และทดสอบบน Demo ก่อนเสมอ


สรุป

การเขียน EA ด้วย MQL5 เป็น ทักษะที่ทรงคุณค่า สำหรับเทรดเดอร์ที่ต้องการ Automate การเทรดของตัวเอง

สิ่งที่ได้เรียนรู้:

  • โครงสร้างหลักของ EA: OnInit(), OnDeinit(), OnTick()

  • การใช้ Input Parameters ให้ยืดหยุ่น

  • ฟังก์ชันสำคัญ: iMA(), CTrade, PositionSelect()

  • EA ตัวอย่าง: MA Crossover ที่ใช้งานได้จริง

  • การ Compile, Debug, และติดตั้ง EA


ขั้นตอนต่อไป:
1. ลองเขียน EA ง่ายๆ ตามตัวอย่าง
2. ปรับเปลี่ยน Parameter และทดสอบ
3. Backtest ด้วย Strategy Tester (บทถัดไป)
4. ค่อยๆ เพิ่มความซับซ้อน (เพิ่ม Indicator, Money Management)

"The best EA is the one you understand completely." อย่าใช้ EA ที่คุณไม่เข้าใจ Logic