My useful functions in mql4 language

My useful functions in mql4 language

14 September 2025, 19:34
Vasyl Nosal
0
300

LIST

  1. Normalize lot
  2. Shifting datain an array
  3. Reviewing all symbols in the market overview
  4. Variable type conversion
  5. Opening an order (binary options)
  6. Search for Fibonacci levels
  7. Pressing the button (object)
  8. Truncation of characters in the tool price
  9. Splitting a string into elements
  10. Code execution on the first tick of a new bar
  11. MultiTimeFrame
  12. Launching an advisor on a Renko (offline) chart
...




1. Normalize lot

There are situations when you need to round a lot.

For example, in martingale when multiplying a lot.

To do this, we need to know to which decimal place we need to round.

string stepS=string(MarketInfo(_Symbol,MODE_LOTSTEP));
int nor_lot=0;
if(StringFind(stepS,".")!=-1) nor_lot=MathAbs(StringFind(stepS,".")-StringLen(stepS)+1);

double Lot_rounded=NormalizeDouble(4887.897,nor_lot) 



2. Shifting data in an array

In this code, we copy the array into itself but with a shift.


Shift the data back by 2 elements. (The 6th becomes the 4th, etc.)

Uncopied elements (far right of the 'shift' quantity) will retain their values.

double buf[6]={2.33,4,8,6,7,8.8};
int shift=2;
ArrayCopy(buf,buf,0,shift); 

Move forward by 1 element.

Uncopied elements (far left of the 'shift' quantity) will retain their values.

double buf[6]={2.33,4,8,6,7,8.8};
int shift=1;
ArrayCopy(buf,buf,shift,0); 



3. Reviewing all symbols in the market overview

In this code, we find out what symbols we have  and write them to the buffer.

The variable 'all_pairs' is responsible for selecting currency pairs from the MarketWatch list (plus pairs used by running indicators, scripts, or trading advisors) or from all currency pairs provided by the broker, including hidden ones.

bool all_pairs=false;

int symbols_tot=SymbolsTotal(all_pairs);
string symbols[]; ArrayResize(symbols,symbols_tot);

for(int i=0;i<symbols_tot;i++)
{
  symbols[i]=SymbolName(i,all_pairs);
}



4. Variable type conversion

If, for example, you need to convert a variable type from datetime to string, you can do it like this.

datetime time_cur=TimeCurrent();
Alert(TimeToString(time_cur)); 

You can write it that way.

datetime time_cur=TimeCurrent();
Alert(string(time_cur)); 



5. Opening an order (binary options)

The only difference is in the comment on the order. You need to write it down like this.

input int expiration_minits = 5;
...
OrderSend(Symbol(),OP_BUY,Lot,Ask,0,0,0,"BO exp:"+string(expiration_minits*60),Magic,0,clrNONE); 



6. Search for Fibonacci levels

You cannot find out the prices of the levels themselves. You can only calculate them.

 string name_fibo="Fibo";


  int levels=int(ObjectGetInteger(0,name_fibo,OBJPROP_LEVELS));
  double fib_prices[]; ArrayResize(fib_prices,levels);
  double price_lev0=ObjectGetDouble(0,name_fibo,OBJPROP_PRICE,1);
  double price_lev100=ObjectGetDouble(0,name_fibo,OBJPROP_PRICE,0);
  bool wayUP=false; if(price_lev0<price_lev100) wayUP=true;
  double perc100_points=MathAbs(price_lev0-price_lev100);


     double level=0;
     for(int i=0;i<levels;i++)
     {
      level=ObjectGetDouble(0,name_fibo,OBJPROP_LEVELVALUE,i);
      if(wayUP) fib_prices[i]=price_lev0+perc100_points*level;
      else
      fib_prices[i]=price_lev0-perc100_points*level;     
     } 

     for(int i=0;i<levels;i++)
     {
     Alert(fib_prices[i]);
     }



7. Pressing the button (object)

OnChartEvent() does not work in the tester. However, there is one universal solution for pressing the button in the tester and live trading.

 if(ObjectGetInteger(0,"BUY_button",OBJPROP_STATE))

{

ObjectSetInteger(0,"BUY_button",OBJPROP_STATE,false);

... 

} 



8. Truncation of characters in the tool price

Only works for prices. If it's something else, then instead of Digits, you need to write a number that is equal to the number of decimal places.

input int Characters_delete = 1;
...
string data=DoubleToString(Bid,Digits); 
string resoult=StringSubstr(data,0,StringLen(data)-Characters_delete); 



9. Splitting a string into elements

For example, we need to split a string with lots and place them in a buffer.

input string Lots="0.01,0.03,0.06";
...
string str_spl[];
int size=StringSplit(Lots,StringGetCharacter(",",0),str_spl);
ArrayResize(lots_buf,size);

for(int i=0;i<size;i++)
{
lots_buf[i]=double(str_spl[i]);
} 

for(int i=ArraySize(lots_buf)-1;i>=0;i--)
{
Alert(lots_buf[i]);
} 


10. Code execution on the first tick of a new bar

First option.

All code beyond this point will be executed on the first tick of the new bar.

int prev_bars=0;
...
if(prev_bars==Bars) return;
prev_bars=Bars; 

Second option.

The code in square brackets will be executed on the first tick of the new bar.

int prev_bars=0;
...
if(prev_bars!=Bars)
{
prev_bars=Bars;
} 


11. MultiTimeFrame

When you need to calculate data from the senior TF. For example, RSI.

input ENUM_TIMEFRAMES TF = PERIOD_CURRENT;
double rsi_buf[];
...
for(int i=0;i<Bars-(IndicatorCounted()-1);i++)
{
rsi_buf[i]=iRSI(Symbol(),TF,14,iBarShift(Symbol(),TF,Time[i]));
} 



12. Launching an advisor on a Renko (offline) chart

Renko is an offline chart.

A new tick will not cause the advisor code to start executing.

You need to use this construction.

double prev_bid;
//////////////////////////////////////////////////////////////
 int OnInit()
 {  
 //offline chart
 if(ChartGetInteger(0,CHART_IS_OFFLINE))
 {
 prev_bid=Close[0];

 while(!IsStopped())
 {
 RefreshRates();
  if(prev_bid!=Close[0]) {prev_bid=Close[0];OnTick();}
 Sleep(100);
 }
 }//end offline chart



 return(INIT_SUCCEEDED);
}