Hướng dẫn chi tiết các phép toán cơ bản và ứng dụng trong tính toán pip, profit/loss, và risk management.
MQL5 hỗ trợ đầy đủ các phép toán số học cơ bản, được sử dụng rộng rãi trong tính toán trading logic.
// Cộng integers
int a = 100 + 50; // 150
// Cộng doubles
double price1 = 1.12345;
double price2 = 0.00100;
double total = price1 + price2; // 1.12445
// Cộng với point value
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double takeProfit = ask + 100 * point; // +100 pips
// Increment operators
int counter = 0;
counter++; // counter = 1 (post-increment)
++counter; // counter = 2 (pre-increment)
counter += 5; // counter = 7 (compound assignment)
// Trừ integers
int difference = 150 - 50; // 100
// Tính spread
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double spread = ask - bid;
int spreadPips = (int)((spread / point) + 0.5);
// Tính profit/loss
double openPrice = 1.12345;
double closePrice = 1.12445;
double pips = (closePrice - openPrice) / point; // 100 pips
// Decrement operators
int counter = 10;
counter--; // counter = 9 (post-decrement)
--counter; // counter = 8 (pre-decrement)
counter -= 3; // counter = 5 (compound assignment)
// Nhân integers
int lots = 5;
int pipsPerLot = 100;
int totalPips = lots * pipsPerLot; // 500
// Tính pip value
double lotSize = 0.1;
double pipValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
double profitPerPip = lotSize * pipValue * 10; // For 0.1 lot
// Tính risk amount
double accountBalance = AccountInfoDouble(ACCOUNT_BALANCE);
double riskPercent = 2.0;
double riskAmount = accountBalance * (riskPercent / 100.0);
// Compound assignment
double value = 10.0;
value *= 2.5; // value = 25.0
// Integer division (kết quả nguyên)
int a = 100;
int b = 30;
int result = a / b; // 3 (không phải 3.33)
// Double division (kết quả thập phân)
double x = 100.0;
double y = 30.0;
double result2 = x / y; // 3.333333
// Mixed type division
int intVal = 100;
double doubleVal = 30.0;
double result3 = intVal / doubleVal; // 3.333333 (promoted to double)
// Tính average
double prices[] = {1.12345, 1.12445, 1.12545};
double sum = 0;
for(int i = 0; i < ArraySize(prices); i++) {
sum += prices[i];
}
double average = sum / ArraySize(prices);
// ⚠️ Check division by zero!
int divisor = 0;
double safeResult = (divisor != 0) ? (100.0 / divisor) : 0.0;
// Compound assignment
double value = 100.0;
value /= 2.0; // value = 50.0
// Modulo operator - chỉ dùng với integers
int a = 100;
int b = 30;
int remainder = a % b; // 10
// Kiểm tra số chẵn/lẻ
int number = 15;
if(number % 2 == 0) {
Print("Even number");
} else {
Print("Odd number"); // ✅ This will execute
}
// Vòng lặp mỗi N lần
for(int i = 0; i < 100; i++) {
if(i % 10 == 0) {
Print("Checkpoint at: ", i); // 0, 10, 20, 30, ...
}
}
// Limit giá trị trong khoảng
int barIndex = 150;
int maxBars = 100;
int wrapped = barIndex % maxBars; // 50 (wrap around)
// Compound assignment
int counter = 17;
counter %= 5; // counter = 2
// Multiplication/Division trước Addition/Subtraction
int result1 = 10 + 5 * 2; // 20 (not 30)
int result2 = (10 + 5) * 2; // 30 (use parentheses)
// Ví dụ phức tạp
double price = 1.12345;
double point = 0.00001;
double stopLoss = price - 50 * point + 10 * point; // -50 pips, +10 pips
// = price - 50*point + 10*point
// = price - 0.0005 + 0.0001
// = 1.12295
// Best practice: Sử dụng dấu ngoặc để rõ ràng
double stopLoss2 = price - ((50 - 10) * point); // Same result, clearer
// Hàm tính lot size dựa trên risk
double CalculateLotSize(double stopLossPips, double riskPercent) {
// Get account balance
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
// Calculate risk amount in currency
double riskAmount = balance * (riskPercent / 100.0);
// Get pip value
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
double pipValue = tickValue * 10; // 1 pip = 10 points for 5-digit
// Calculate lot size
double lotSize = riskAmount / (stopLossPips * pipValue);
// Normalize to lot step
double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
lotSize = MathFloor(lotSize / lotStep) * lotStep;
// Check min/max limits
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
if(lotSize < minLot) lotSize = minLot;
if(lotSize > maxLot) lotSize = maxLot;
return NormalizeDouble(lotSize, 2);
}
// Sử dụng
void OnTick() {
double stopLossPips = 50;
double riskPercent = 2.0; // 2% risk
double lotSize = CalculateLotSize(stopLossPips, riskPercent);
Print("Calculated Lot Size: ", lotSize);
}
Lỗi 1: Integer Division Truncation
❌ int result = 100 / 3; // 33 (mất .333...)
✅ double result = 100.0 / 3.0; // 33.333333
Lỗi 2: Division by Zero
❌ double result = price / 0; // Runtime error!
✅ double result = (divisor > 0.0001) ? (price / divisor) : 0.0;
Lỗi 3: Overflow
❌ int big = 2000000000 * 2; // Overflow!
✅ long big = 2000000000LL * 2; // Use long for large numbers
double cho tính toán giá cả() để làm rõ thứ tự phép toánNormalizeDouble(result, digits)SymbolInfo