Quick Answer
'iMA' - wrong parameters count is a compile error. You called a function with a different number of arguments than MQL5 expects. The usual reason is MT4 code compiled in MT5: the function has the same name, but it works differently.
In MT4, iMA(...) returns the indicator value. In MT5, iMA(...) returns a handle, a number that identifies the indicator, and you read the values with CopyBuffer. The argument lists are different too, because MT5 has no shift argument in the call. OrderSend changed as well: MT5 takes a request structure, not eleven separate arguments.
Key Facts
| Function | MT4 call (fails in MT5) | MT5 call |
|---|---|---|
| Moving average | iMA(sym, tf, period, shift, method, price, barShift) returns a value | iMA(sym, tf, period, shift, method, price) returns a handle, then CopyBuffer |
| RSI | iRSI(sym, tf, period, price, barShift) | iRSI(sym, tf, period, price) returns a handle |
| ATR | iATR(sym, tf, period, barShift) | iATR(sym, tf, period) returns a handle |
| MACD | iMACD(sym, tf, fast, slow, signal, price, mode, barShift) | iMACD(sym, tf, fast, slow, signal, price) returns a handle |
| Send an order | OrderSend(sym, cmd, volume, price, slippage, sl, tp, comment, magic, exp, color) | OrderSend(request, result) with MqlTradeRequest and MqlTradeResult, or CTrade |
| Bid and Ask | Bid, Ask | SymbolInfoDouble(_Symbol, SYMBOL_BID) and SYMBOL_ASK |
| Order types | OP_BUY, OP_SELL | ORDER_TYPE_BUY, ORDER_TYPE_SELL |
The argument lists in the table follow the MT4 and MT5 documentation. Check the exact signature of any function in the MetaEditor help (select the name and press F1).
Read the Error
The error names the function and counts the arguments:
'iMA' - wrong parameters count
It means the number of arguments in your call does not match any version of the function. Count your arguments and compare them with the MT5 signature. If your call has one more argument than MT5 allows, it is almost always the MT4 shift at the end.
MT4 Code That Fails in MT5
This EA uses the MT4 style. Each marked line fails to compile in MT5:
void OnTick()
{
// 1. wrong parameters count: MT5 iMA has no 'shift' argument at the end
double ma = iMA(_Symbol, _Period, 14, 0, MODE_EMA, PRICE_CLOSE, 1);
// 2. wrong parameters count: same problem with iRSI
double rsi = iRSI(_Symbol, _Period, 14, PRICE_CLOSE, 1);
// 3. wrong parameters count: MT5 iATR takes three arguments
double atr = iATR(_Symbol, _Period, 14, 1);
// 4. wrong parameters count: MT5 OrderSend takes a request and a result
int ticket = OrderSend(_Symbol, OP_BUY, 0.1, Ask, 3, 0, 0, "bot", 1234, 0, clrGreen);
}
Some of these lines give more than one error, such as an undeclared OP_BUY, Ask or clrGreen. The explanation of that error is in MQL5 Undeclared Identifier Error.
Fix It: Handle in OnInit, Values With CopyBuffer
The MT5 pattern has three steps. Create the handle once in OnInit(), read the value with CopyBuffer where you need it, and release the handle in OnDeinit():
int maHandle = INVALID_HANDLE;
int rsiHandle = INVALID_HANDLE;
int atrHandle = INVALID_HANDLE;
int OnInit()
{
maHandle = iMA(_Symbol, _Period, 14, 0, MODE_EMA, PRICE_CLOSE);
rsiHandle = iRSI(_Symbol, _Period, 14, PRICE_CLOSE);
atrHandle = iATR(_Symbol, _Period, 14);
if(maHandle == INVALID_HANDLE || rsiHandle == INVALID_HANDLE || atrHandle == INVALID_HANDLE)
return INIT_FAILED;
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
if(maHandle != INVALID_HANDLE) IndicatorRelease(maHandle);
if(rsiHandle != INVALID_HANDLE) IndicatorRelease(rsiHandle);
if(atrHandle != INVALID_HANDLE) IndicatorRelease(atrHandle);
}
// The MT4 'barShift' argument becomes the 'shift' of CopyBuffer.
bool GetValue(int handle, int shift, double &value)
{
double buf[1];
if(CopyBuffer(handle, 0, shift, 1, buf) != 1)
return false;
value = buf[0];
return true;
}
The bar number that was the last argument in MT4 moves into CopyBuffer. GetValue(maHandle, 1, ma) reads the value on the last closed bar, the same idea as iMA(..., 1) in MT4. The details of CopyBuffer, including what to do when it returns -1, are in MQL5 CopyBuffer guide.
Fix Orders: Use CTrade
The simplest replacement for the MT4 OrderSend is the CTrade class that ships with MT5:
#include <Trade/Trade.mqh>
CTrade trade;
void OpenBuy(double volume, double sl, double tp)
{
trade.SetExpertMagicNumber(1234);
if(!trade.Buy(volume, _Symbol, 0.0, sl, tp, "bot"))
PrintFormat("Buy failed. Retcode %u: %s",
trade.ResultRetcode(), trade.ResultRetcodeDescription());
}
The price argument 0.0 means "use the current Ask" for a market buy. Always check the result, because an order can be sent and still be rejected. The result codes are explained in MQL5 Trade Return Codes, and the stop rules in MQL5 Invalid Stops Error 10016. MT5 also works with positions and not with MT4-style tickets of orders, which is covered in MT5 Hedging vs Netting.
Full MQL5 Example
This EA reads the three indicators once per closed bar with the MT5 pattern and prints them. It does not place trades.
input int MaPeriod = 14;
input int RsiPeriod = 14;
input int AtrPeriod = 14;
int maHandle = INVALID_HANDLE;
int rsiHandle = INVALID_HANDLE;
int atrHandle = INVALID_HANDLE;
datetime g_lastBarTime = 0;
int OnInit()
{
maHandle = iMA(_Symbol, _Period, MaPeriod, 0, MODE_EMA, PRICE_CLOSE);
rsiHandle = iRSI(_Symbol, _Period, RsiPeriod, PRICE_CLOSE);
atrHandle = iATR(_Symbol, _Period, AtrPeriod);
if(maHandle == INVALID_HANDLE || rsiHandle == INVALID_HANDLE || atrHandle == INVALID_HANDLE)
return INIT_FAILED;
g_lastBarTime = iTime(_Symbol, _Period, 0);
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
if(maHandle != INVALID_HANDLE) IndicatorRelease(maHandle);
if(rsiHandle != INVALID_HANDLE) IndicatorRelease(rsiHandle);
if(atrHandle != INVALID_HANDLE) IndicatorRelease(atrHandle);
}
bool IsNewBar()
{
datetime currentBarTime = iTime(_Symbol, _Period, 0);
if(currentBarTime == 0 || currentBarTime == g_lastBarTime)
return false;
g_lastBarTime = currentBarTime;
return true;
}
bool GetValue(int handle, int shift, double &value)
{
double buf[1];
if(CopyBuffer(handle, 0, shift, 1, buf) != 1)
return false;
value = buf[0];
return true;
}
void OnTick()
{
if(!IsNewBar())
return;
double ma, rsi, atr;
if(!GetValue(maHandle, 1, ma)) return;
if(!GetValue(rsiHandle, 1, rsi)) return;
if(!GetValue(atrHandle, 1, atr)) return;
PrintFormat("EMA %.5f | RSI %.2f | ATR %.5f (last closed bar)", ma, rsi, atr);
}
The new-bar check is explained in Pine Script barstate.isnew in MQL5, and the closed-bar rule in Pine Script close[1] in MQL5.
Common Mistakes
- Keeping the MT4
shiftargument. MT5 indicator functions do not take it. It moves toCopyBuffer. - Using the return value as a price. In MT5 it is a handle. Reading it as a value gives a meaningless number.
- Creating the handle in
OnTick(). This builds a new indicator on every tick. Create it once inOnInit(). - Skipping
INVALID_HANDLE. A failed handle then fails everyCopyBuffercall later. - Using
BidandAsk. They are not variables in MT5. Read them withSymbolInfoDouble. - Keeping the 11-argument
OrderSend. UseCTradeor fill a request structure. - Forgetting to release handles. Release them in
OnDeinit().
FAQ
Related Guides
- MQL5 Undeclared Identifier Error: the next error you meet after
OP_BUYandAsk. - MQL5 CopyBuffer guide: read indicator buffers safely.
- Convert an MT5 Indicator to an EA: turn an indicator into an EA that trades.
- MQL5 Zero Divide Error: the runtime error that follows when a lot size divides by a missing symbol value.
- MQL5 Trade Return Codes: check what happened to an order.
- MT5 Hedging vs Netting: how MT5 handles positions.
- Pine Script vs MQL5: how the two languages compare.
- What to check in a trading bot before going live: a pre-live checklist for stops, lot size, spread and trade results.
Convert Strategy Code Without the Guesswork
Porting a strategy between platforms is mostly a list of differences like these. CodeFlowOS translates Pine Script into MQL5 and lets you review the generated code before you test it in the MT5 Strategy Tester. The platform compile check is optional, and outputs are not guaranteed, so always review the result. If the code does not compile, the Error Fixer can suggest a fix, and the free early-bird Code Review checks an EA for common mistakes. For the full process, see the Pine Script to MQL5 guide, or try the converter page.
This article is educational. It does not describe trading performance and is not financial advice. Always compile and test code in MetaEditor and the Strategy Tester before using it on a live account.