Quick Answer
Every Pine Script input.* call becomes an input variable at the top of your MQL5 file. input.int, input.float, input.bool and input.string map to input int, input double, input bool and input string. A dropdown (options=[...]) becomes an enum, input.timeframe becomes ENUM_TIMEFRAMES, and input.source becomes ENUM_APPLIED_PRICE.
MQL5 has no minval, maxval, step or tooltip. The label comes from the comment on the same line, and value limits must be checked in code, in OnInit().
From the author: I convert strategies between Pine Script, MQL5 and cTrader C#, and I publish Expert Advisors on the MQL5 Market. The inputs block is the part of a conversion that is easiest to underestimate, because a wrong default or a missing limit does not cause a compile error. The code runs, it just behaves differently from the Pine version. That is why this guide ends with a checklist you can run on your own conversion.
Key Facts
| Pine Script | MQL5 |
|---|---|
| input.int(20, "Length") | input int InpLength = 20; // Length |
| input.float(2.0, "Multiplier") | input double InpMult = 2.0; // Multiplier |
| input.bool(true, "Use filter") | input bool InpUseFilter = true; // Use filter |
| input.string("a", "Text") | input string InpText = "a"; // Text |
| options=["A", "B"] | An enum, then input ENUM_NAME InpMode = ...; |
| input.timeframe("60", "Higher TF") | input ENUM_TIMEFRAMES InpTF = PERIOD_H1; |
| input.source(close, "Source") | input ENUM_APPLIED_PRICE InpSource = PRICE_CLOSE; |
| input.color(color.red, "Color") | input color InpColor = clrRed; |
| group = "Trend" | input group "Trend" before the inputs |
| minval, maxval | Check in OnInit() and return INIT_PARAMETERS_INCORRECT |
| tooltip, inline | No equivalent. Put the hint in the label comment |
The Pine Script Version
//@version=5
strategy("Inputs example", overlay = true)
grp = "Trend"
length = input.int(20, "EMA length", minval = 1, group = grp)
src = input.source(close, "Source", group = grp)
mult = input.float(2.0, "ATR multiplier", minval = 0.1, step = 0.1)
useFilter = input.bool(true, "Use filter")
mode = input.string("Long only", "Direction", options = ["Long only", "Short only", "Both"])
htf = input.timeframe("60", "Higher timeframe")
Six inputs: two numbers, a price source, a switch, a dropdown and a timeframe.
The MQL5 Version
enum ENUM_DIRECTION
{
DIR_LONG_ONLY = 0, // Long only
DIR_SHORT_ONLY = 1, // Short only
DIR_BOTH = 2 // Both
};
input group "Trend"
input int InpLength = 20; // EMA length
input ENUM_APPLIED_PRICE InpSource = PRICE_CLOSE; // Source
input group "Risk and filters"
input double InpMult = 2.0; // ATR multiplier
input bool InpUseFilter = true; // Use filter
input ENUM_DIRECTION InpDirection = DIR_LONG_ONLY; // Direction
input ENUM_TIMEFRAMES InpHigherTF = PERIOD_H1; // Higher timeframe
int OnInit()
{
if(InpLength < 1)
{
Print("EMA length must be 1 or more");
return INIT_PARAMETERS_INCORRECT;
}
if(InpMult < 0.1)
{
Print("ATR multiplier must be 0.1 or more");
return INIT_PARAMETERS_INCORRECT;
}
return INIT_SUCCEEDED;
}
In the inputs window, the comment after each variable becomes its label, and the comment after each enum value becomes the text in the dropdown. A comment used as a label can be at most 63 characters, so keep labels short. The Inp prefix is a habit, not a rule. It keeps inputs easy to tell apart from local variables.
Dropdowns: options Become an enum
Pine takes a list of strings. MQL5 takes an enum, and the user picks one of its values:
enum ENUM_DIRECTION
{
DIR_LONG_ONLY = 0, // Long only
DIR_SHORT_ONLY = 1, // Short only
DIR_BOTH = 2 // Both
};
input ENUM_DIRECTION InpDirection = DIR_BOTH; // Direction
In the code, compare against the enum value, not a string:
bool longsAllowed = (InpDirection == DIR_LONG_ONLY || InpDirection == DIR_BOTH);
bool shortsAllowed = (InpDirection == DIR_SHORT_ONLY || InpDirection == DIR_BOTH);
Set the default to the same option as the Pine defval. A different default is a common reason why two versions give different results.
input.source and input.timeframe
input.source(close) in Pine can point to any series. In MQL5, the indicators you call take an ENUM_APPLIED_PRICE, and the common Pine sources have a match:
| Pine source | MQL5 applied price |
|---|---|
| close | PRICE_CLOSE |
| open | PRICE_OPEN |
| high | PRICE_HIGH |
| low | PRICE_LOW |
| hl2 | PRICE_MEDIAN |
| hlc3 | PRICE_TYPICAL |
| hlcc4 | PRICE_WEIGHTED |
| ohlc4 | No built-in match. Calculate it yourself |
Then pass the input to the indicator, for example iMA(_Symbol, _Period, InpLength, 0, MODE_EMA, InpSource).
For input.timeframe, use ENUM_TIMEFRAMES. The value PERIOD_CURRENT means the chart timeframe, like an empty string in Pine. Reading values from a higher timeframe is a separate step, explained in Pine Script request.security in MQL5.
Inputs Are Read-Only: Copy Them if You Need to Change Them
An MQL5 input cannot be changed by the program while it runs, and you cannot assign to it. If your logic changes a value, such as a risk size that grows after a loss, copy the input into a normal variable in OnInit():
input double InpRiskPercent = 1.0; // Risk per trade, %
double g_riskPercent = 0.0;
int OnInit()
{
g_riskPercent = InpRiskPercent;
return INIT_SUCCEEDED;
}
Use g_riskPercent everywhere in the code, and keep InpRiskPercent only as the starting value.
Optimization: input and sinput
In the Strategy Tester, every input can be selected for optimization. If a value should never be optimized, such as a magic number or a log switch, declare it with sinput (static input):
sinput long InpMagic = 123456; // Magic number
A sinput still shows in the inputs window, but the tester does not offer it for ordinary optimization. Pine has no such option, so decide yourself which converted inputs you want to optimize.
Full MQL5 Example
This EA uses the inputs above to create an EMA handle and print the last closed EMA value once per bar. It does not place trades.
input group "Trend"
input int InpLength = 20; // EMA length
input ENUM_APPLIED_PRICE InpSource = PRICE_CLOSE; // Source
int emaHandle = INVALID_HANDLE;
int OnInit()
{
if(InpLength < 1)
{
Print("EMA length must be 1 or more");
return INIT_PARAMETERS_INCORRECT;
}
emaHandle = iMA(_Symbol, _Period, InpLength, 0, MODE_EMA, InpSource);
if(emaHandle == INVALID_HANDLE)
return INIT_FAILED;
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
if(emaHandle != INVALID_HANDLE)
IndicatorRelease(emaHandle);
}
bool IsNewBar()
{
static datetime lastBarTime = 0;
datetime currentBarTime = iTime(_Symbol, _Period, 0);
if(currentBarTime == 0 || currentBarTime == lastBarTime)
return false;
lastBarTime = currentBarTime;
return true;
}
void OnTick()
{
if(!IsNewBar())
return;
double buf[1];
if(CopyBuffer(emaHandle, 0, 1, 1, buf) != 1) // shift 1 = last closed bar
return;
PrintFormat("EMA(%d) on last closed bar: %.5f", InpLength, buf[0]);
}
If the handle or the buffer read fails, see MQL5 CopyBuffer guide.
Checklist: Verify Your Converted Inputs
A converted input block can compile cleanly and still be wrong. Before you trust a conversion, go through these steps:
- List every Pine input with its default, its
minvalandmaxval, and its type. Put the MQL5 inputs next to that list and tick them off one by one. A missing input is easy to miss because nothing fails. - Compare defaults. Each MQL5 default must equal the Pine
defval, including dropdown choices and timeframes. - Test the limits. Enter a value below your minimum in the inputs window and confirm the EA stops with
INIT_PARAMETERS_INCORRECTand prints your message in the Experts tab. - Check the dropdown order. Open each dropdown and confirm the options and their order match the Pine
optionslist. - Check sources. For each
input.source, confirm the applied price matches.hlcc4isPRICE_WEIGHTED, andohlc4has to be calculated. - Run the Strategy Tester on the defaults over the same period and symbol as your TradingView chart, and compare the first few signals bar by bar before you look at any totals.
If the first signals already differ, the cause is usually a default, a source or a bar shift, not the strategy logic. The other common causes are in Why a Pine Script Strategy Gives Different Results in MQL5.
Common Mistakes
- Using a normal global instead of
input. The value then does not appear in the inputs window, and the Strategy Tester cannot optimize it. - Trying to change an input in code. It is read-only. Copy it to a variable in
OnInit(). - Skipping
minvalandmaxval. MQL5 does not enforce them. Check the values inOnInit()and stop withINIT_PARAMETERS_INCORRECT. - A different default from Pine. Check every default value against the Pine script.
- Reordering enum values. Saved settings and optimization results refer to the value, so keep the order stable once you publish an EA.
- Using a string for a dropdown. Use an
enum, so the user cannot type a wrong value. - Forgetting
PERIOD_CURRENTsemantics. A timeframe input set to the chart timeframe makes the "higher timeframe" logic compare the chart with itself.
FAQ
Related Guides
- Pine Script request.security in MQL5: use the timeframe input to read a higher timeframe.
- Pine Script ta.rsi and ta.ema vs MQL5: pass the length and source inputs to
iMAandiRSI. - Pine Script ta.atr, ta.highest and ta.lowest in MQL5: the ATR period and channel length are typical inputs to convert.
- MQL5 CopyBuffer guide: read the values of an indicator created from your inputs.
- Pine Script var and varip in MQL5: keep state between bars.
- Why a Pine Script Strategy Gives Different Results in MQL5: wrong defaults are one of the causes.
Convert Inputs Without Missing One
A missed default or a dropdown turned into a string can change how a strategy behaves. 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. 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.