Trang chủ Kiến thức OnInit() trong MQL5: Khởi Tạo Expert Advisor
Knowledge

OnInit() trong MQL5: Khởi Tạo Expert Advisor

14 tháng 11, 2025

Hướng dẫn chi tiết về hàm OnInit() - initialization event handler, setup indicators, validate parameters và return codes.

OnInit(): Hàm Khởi Tạo EA

OnInit() là event handler được gọi một lần khi EA được load lên chart. Đây là nơi khởi tạo indicators, validate input parameters, và setup môi trường trading.

Cú Pháp Cơ Bản

// OnInit() is called once when EA starts
int OnInit() {
    // Initialization code here
    Print("EA Initialized");
    
    return INIT_SUCCEEDED;  // Must return initialization result
}

// Return codes:
// INIT_SUCCEEDED (0) - Initialization successful, EA will run
// INIT_FAILED - Initialization failed, EA will not run
// INIT_PARAMETERS_INCORRECT - Invalid input parameters

Return Codes Chi Tiết

int OnInit() {
    // Check if symbol is valid
    if(_Symbol == "") {
        Print("Error: Invalid symbol");
        return INIT_FAILED;
    }
    
    // Validate input parameters
    if(InpLotSize <= 0 || InpLotSize > 100) {
        Print("Error: Invalid lot size - must be between 0 and 100");
        return INIT_PARAMETERS_INCORRECT;
    }
    
    if(InpStopLoss < 0 || InpTakeProfit < 0) {
        Print("Error: Stop loss and take profit must be >= 0");
        return INIT_PARAMETERS_INCORRECT;
    }
    
    // All checks passed
    Print("EA initialized successfully");
    return INIT_SUCCEEDED;
}

Khởi Tạo Indicator Handles

// Global variables for indicator handles
int g_maHandle = INVALID_HANDLE;
int g_rsiHandle = INVALID_HANDLE;
int g_macdHandle = INVALID_HANDLE;

int OnInit() {
    // Create MA indicator
    g_maHandle = iMA(_Symbol, PERIOD_CURRENT, 50, 0, MODE_SMA, PRICE_CLOSE);
    if(g_maHandle == INVALID_HANDLE) {
        Print("Error: Failed to create MA indicator");
        return INIT_FAILED;
    }
    
    // Create RSI indicator
    g_rsiHandle = iRSI(_Symbol, PERIOD_CURRENT, 14, PRICE_CLOSE);
    if(g_rsiHandle == INVALID_HANDLE) {
        Print("Error: Failed to create RSI indicator");
        IndicatorRelease(g_maHandle);  // Clean up MA handle
        return INIT_FAILED;
    }
    
    // Create MACD indicator
    g_macdHandle = iMACD(_Symbol, PERIOD_CURRENT, 12, 26, 9, PRICE_CLOSE);
    if(g_macdHandle == INVALID_HANDLE) {
        Print("Error: Failed to create MACD indicator");
        IndicatorRelease(g_maHandle);
        IndicatorRelease(g_rsiHandle);
        return INIT_FAILED;
    }
    
    Print("All indicators created successfully");
    return INIT_SUCCEEDED;
}

// Clean up in OnDeinit()
void OnDeinit(const int reason) {
    if(g_maHandle != INVALID_HANDLE)
        IndicatorRelease(g_maHandle);
    if(g_rsiHandle != INVALID_HANDLE)
        IndicatorRelease(g_rsiHandle);
    if(g_macdHandle != INVALID_HANDLE)
        IndicatorRelease(g_macdHandle);
}

Initialize Global Variables

// Input parameters
input double InpLotSize = 0.1;
input int InpMagicNumber = 12345;

// Global variables
datetime g_lastBarTime = 0;
double g_pointValue = 0;
int g_digits = 0;
double g_tickValue = 0;

int OnInit() {
    // Get symbol properties
    g_pointValue = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
    g_digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);
    g_tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
    
    // Validate properties
    if(g_pointValue <= 0 || g_tickValue <= 0) {
        Print("Error: Invalid symbol properties");
        return INIT_FAILED;
    }
    
    // Initialize last bar time
    g_lastBarTime = iTime(_Symbol, PERIOD_CURRENT, 0);
    
    Print("Symbol properties initialized:");
    Print("  Point: ", g_pointValue);
    Print("  Digits: ", g_digits);
    Print("  Tick Value: ", g_tickValue);
    
    return INIT_SUCCEEDED;
}

Chart Objects Setup

int OnInit() {
    // Create label on chart
    string labelName = "EA_Info";
    if(ObjectCreate(0, labelName, OBJ_LABEL, 0, 0, 0)) {
        ObjectSetInteger(0, labelName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
        ObjectSetInteger(0, labelName, OBJPROP_XDISTANCE, 10);
        ObjectSetInteger(0, labelName, OBJPROP_YDISTANCE, 20);
        ObjectSetInteger(0, labelName, OBJPROP_COLOR, clrWhite);
        ObjectSetInteger(0, labelName, OBJPROP_FONTSIZE, 10);
        ObjectSetString(0, labelName, OBJPROP_TEXT, "EA Running...");
    }
    
    // Create horizontal line at current price
    double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
    string lineName = "EA_PriceLine";
    if(ObjectCreate(0, lineName, OBJ_HLINE, 0, 0, currentPrice)) {
        ObjectSetInteger(0, lineName, OBJPROP_COLOR, clrGreen);
        ObjectSetInteger(0, lineName, OBJPROP_WIDTH, 2);
        ObjectSetInteger(0, lineName, OBJPROP_STYLE, STYLE_DASH);
    }
    
    Print("Chart objects created");
    return INIT_SUCCEEDED;
}

void OnDeinit(const int reason) {
    // Clean up chart objects
    ObjectDelete(0, "EA_Info");
    ObjectDelete(0, "EA_PriceLine");
}

Timer Setup

int OnInit() {
    // Set timer to trigger every 60 seconds
    if(!EventSetTimer(60)) {
        Print("Error: Failed to set timer");
        return INIT_FAILED;
    }
    
    Print("Timer set: 60 seconds");
    return INIT_SUCCEEDED;
}

void OnTimer() {
    // This function called every 60 seconds
    Print("Timer event: ", TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS));
    
    // Check account status
    double balance = AccountInfoDouble(ACCOUNT_BALANCE);
    double equity = AccountInfoDouble(ACCOUNT_EQUITY);
    Print("Balance: $", balance, " | Equity: $", equity);
}

void OnDeinit(const int reason) {
    // Kill timer
    EventKillTimer();
    Print("Timer stopped");
}

Multi-Symbol EA Setup

// Input: Symbols to trade
input string InpSymbols = "EURUSD,GBPUSD,USDJPY";

// Global arrays
string g_symbols[];
int g_maHandles[];

int OnInit() {
    // Parse symbols
    string delimiter = ",";
    int count = StringSplit(InpSymbols, StringGetCharacter(delimiter, 0), g_symbols);
    
    if(count <= 0) {
        Print("Error: No symbols specified");
        return INIT_PARAMETERS_INCORRECT;
    }
    
    // Resize handles array
    ArrayResize(g_maHandles, count);
    
    // Create indicator for each symbol
    for(int i = 0; i < count; i++) {
        StringTrimLeft(g_symbols[i]);
        StringTrimRight(g_symbols[i]);
        
        // Check if symbol exists
        if(!SymbolSelect(g_symbols[i], true)) {
            Print("Error: Symbol not found - ", g_symbols[i]);
            return INIT_FAILED;
        }
        
        // Create MA indicator
        g_maHandles[i] = iMA(g_symbols[i], PERIOD_CURRENT, 50, 0, MODE_SMA, PRICE_CLOSE);
        if(g_maHandles[i] == INVALID_HANDLE) {
            Print("Error: Failed to create MA for ", g_symbols[i]);
            // Clean up previous handles
            for(int j = 0; j < i; j++) {
                IndicatorRelease(g_maHandles[j]);
            }
            return INIT_FAILED;
        }
        
        Print("Initialized: ", g_symbols[i]);
    }
    
    Print("Multi-symbol EA ready. Trading ", count, " symbols");
    return INIT_SUCCEEDED;
}

Best Practices

  • ✅ Luôn validate input parameters trong OnInit()
  • ✅ Khởi tạo tất cả indicator handles trong OnInit()
  • ✅ Return appropriate codes (INIT_SUCCEEDED, INIT_FAILED, INIT_PARAMETERS_INCORRECT)
  • ✅ Check symbol validity và properties
  • ✅ Initialize global variables
  • ✅ Print informative messages để debug
  • ✅ Clean up resources trong OnDeinit()
  • ⛔ Không mở trades trong OnInit()
  • ⛔ Tránh heavy calculations trong OnInit()

Bài Tập Thực Hành

  1. Viết OnInit() validate: LotSize (0.01-100), StopLoss (10-500 pips)
  2. Tạo OnInit() khởi tạo 3 indicators: MA(50), RSI(14), BB(20,2)
  3. Implement multi-timeframe EA với indicators cho M15, H1, H4

Tài Liệu Tham Khảo