Học cách khai báo biến local, global, static và constants trong MQL5 với scope và lifetime management.
Trong MQL5, biến là vùng nhớ lưu trữ giá trị có thể thay đổi trong quá trình chạy chương trình, trong khi hằng số là giá trị không thể thay đổi sau khi khởi tạo.
void OnTick() {
// Biến local - chỉ tồn tại trong hàm OnTick()
int counter = 0;
double price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
string message = "Hello";
counter++; // Biến này sẽ reset về 0 mỗi lần OnTick() được gọi
Print("Counter: ", counter); // Luôn in ra 1
}
// ❌ Lỗi: Không thể truy cập biến local từ hàm khác
void AnotherFunction() {
Print(counter); // ERROR: 'counter' - undeclared identifier
}
void OnTick() {
// Biến static - giữ giá trị giữa các lần gọi hàm
static int counter = 0;
static double lastPrice = 0;
counter++; // Tăng dần: 1, 2, 3, 4, ...
Print("Counter: ", counter);
double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
if(lastPrice > 0) {
double change = currentPrice - lastPrice;
Print("Price changed by: ", change);
}
lastPrice = currentPrice;
}
// Ứng dụng: Detect new bar
void CheckNewBar() {
static datetime lastBarTime = 0;
datetime currentBarTime = iTime(_Symbol, PERIOD_CURRENT, 0);
if(currentBarTime != lastBarTime) {
Print("New bar detected!");
lastBarTime = currentBarTime;
// Execute logic only on new bar
}
}
// Khai báo ở đầu file, bên ngoài mọi hàm
int g_magicNumber = 12345;
double g_lotSize = 0.1;
string g_symbol = "EURUSD";
bool g_isTrading = false;
// Có thể truy cập từ mọi hàm trong file
void OnInit() {
Print("Magic Number: ", g_magicNumber);
g_isTrading = true;
}
void OnTick() {
if(!g_isTrading) return;
double ask = SymbolInfoDouble(g_symbol, SYMBOL_ASK);
// Use g_lotSize for trading...
}
void OnDeinit(const int reason) {
g_isTrading = false;
Print("EA stopped");
}
// Input variables - có thể thay đổi từ EA properties
input int InpMagicNumber = 12345; // Magic number
input double InpLotSize = 0.1; // Lot size
input int InpStopLoss = 50; // Stop loss (pips)
input int InpTakeProfit = 100; // Take profit (pips)
input bool InpUseTrailingStop = true; // Use trailing stop
input string InpComment = "My EA"; // Order comment
// Enum input
enum ENUM_TRADE_MODE {
TRADE_MANUAL, // Manual trading
TRADE_AUTO, // Automatic trading
TRADE_SEMI_AUTO // Semi-automatic
};
input ENUM_TRADE_MODE InpTradeMode = TRADE_AUTO;
// Sinput: Simple input (hiển thị đơn giản hơn)
sinput string s1 = "=== Risk Management ===";
input double InpRiskPercent = 2.0;
input int InpMaxOrders = 5;
void OnInit() {
// Sử dụng input variables
Print("Lot Size: ", InpLotSize);
Print("Stop Loss: ", InpStopLoss, " pips");
}
// Hằng số - không thể thay đổi
const int MAGIC_NUMBER = 20250114;
const double MAX_LOT = 100.0;
const string EA_NAME = "My Expert Advisor";
const int MAX_SLIPPAGE = 3;
// ❌ Lỗi: Không thể thay đổi giá trị const
void OnTick() {
MAGIC_NUMBER = 99999; // ERROR: Cannot modify const variable
}
// ✅ Sử dụng đúng
void OpenOrder() {
MqlTradeRequest request = {};
request.magic = MAGIC_NUMBER;
request.volume = 0.1;
request.deviation = MAX_SLIPPAGE;
request.comment = EA_NAME;
// ...
}
// Enum constants
enum ENUM_SIGNAL_TYPE {
SIGNAL_NONE = 0,
SIGNAL_BUY = 1,
SIGNAL_SELL = -1
};
ENUM_SIGNAL_TYPE CheckSignal() {
// Logic to determine signal
return SIGNAL_BUY;
}
// Global variables: prefix g_
int g_totalOrders = 0;
double g_accountBalance = 0;
// Input variables: prefix Inp
input int InpPeriod = 14;
input double InpRisk = 2.0;
// Constants: UPPERCASE
const int MAX_RETRY = 3;
const double EPSILON = 0.000001;
// Local variables: camelCase hoặc snake_case
int orderCount = 0;
double stop_loss = 0;
// Static variables: prefix s_
static int s_barCounter = 0;
// Private member variables (in class): prefix m_
class CMyClass {
private:
int m_value;
double m_price;
};
// Global scope
int g_globalVar = 100;
void Function1() {
// Local scope
int localVar = 10;
Print("Global: ", g_globalVar); // ✅ OK
Print("Local: ", localVar); // ✅ OK
{
// Block scope
int blockVar = 5;
Print("Block: ", blockVar); // ✅ OK
Print("Local: ", localVar); // ✅ OK
}
// Print("Block: ", blockVar); // ❌ ERROR: out of scope
}
void Function2() {
Print("Global: ", g_globalVar); // ✅ OK
// Print("Local: ", localVar); // ❌ ERROR: undefined
}
// ✅ Khởi tạo ngay khi khai báo
int counter = 0;
double price = 1.12345;
string symbol = "EURUSD";
// ⚠️ Không khởi tạo: Giá trị mặc định
int uninitializedInt; // = 0
double uninitializedDouble; // = 0.0
string uninitializedString; // = ""
bool uninitializedBool; // = false
// Khởi tạo từ expression
int digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
datetime now = TimeCurrent();
// Multiple declaration and initialization
int a = 10, b = 20, c = 30;
double x = 1.1, y = 2.2, z = 3.3;
// === Input Parameters ===
input int InpMagicNumber = 12345;
input double InpLotSize = 0.1;
input int InpStopLoss = 50;
input int InpTakeProfit = 100;
// === Global Variables ===
int g_totalBuyOrders = 0;
int g_totalSellOrders = 0;
double g_totalProfit = 0;
datetime g_lastTradeTime = 0;
// === Constants ===
const int MAX_ORDERS = 10;
const int MIN_DISTANCE = 20; // pips
// === OnInit: Initialize ===
int OnInit() {
// Reset global variables
g_totalBuyOrders = 0;
g_totalSellOrders = 0;
g_totalProfit = 0;
g_lastTradeTime = 0;
Print("EA Initialized - Magic: ", InpMagicNumber);
return INIT_SUCCEEDED;
}
// === OnTick: Main Logic ===
void OnTick() {
// Static variable: track last bar
static datetime s_lastBarTime = 0;
datetime currentBarTime = iTime(_Symbol, PERIOD_CURRENT, 0);
if(currentBarTime == s_lastBarTime) return;
s_lastBarTime = currentBarTime;
// Local variables
int signal = CheckSignal();
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
// Update global counters
g_totalBuyOrders = CountOrders(ORDER_TYPE_BUY);
g_totalSellOrders = CountOrders(ORDER_TYPE_SELL);
// Check max orders limit
if(g_totalBuyOrders + g_totalSellOrders >= MAX_ORDERS) {
return;
}
// Trading logic...
}
const cho giá trị không đổig_ cho global, Inp cho inputstatic cho biến cần giữ giá trị