NOTES ON PROGRAMMING MQL4 FROM EEVVIILL

NOTES ON PROGRAMMING MQL4 FROM EEVVIILL

7 March 2016, 10:58
eevviill7
[Deleted]
0
416

Note 1 - shift data in the array

A task. Move data on 1 element ago. (6th will 5th etc.)

ArrayCopy(buf,buf,0,1);

Slide 1 forward.

ArrayCopy(buf,buf,1,0);

 

 

Note 2 - enumeration all the characters in the Market Review

uint symbols_tot;

string symbols[];


//////////////////////////////////////////////////////////////

int OnInit()
{
symbols_tot=SymbolsTotal(true);
ArrayResize(symbols,symbols_tot);
 
for(int i=0;i<symbols_tot;i++)
{
  symbols[i]=SymbolName(i,true);
}

return(INIT_SUCCEEDED);
}


///////////////////////////////////////////////////////////////
void OnTick()
{
for(int i=0;i<symbols_tot;i++)
{
Alert("Symbol:"+symbols[i]);
}

}

 

 

Note 3 - Type conversion

If you need for example to convert the variable type from datetime to string, you can do so

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

But you can do like this

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

 

 

Note 4 - opening order (binary options)

All the salt in the comment to the order. It should be written as

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

 

 

Note 5 - find Fibonacci price

Price of levels can not be found. Just calculate.

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;    

     }

 

 

Note 6 - pressing

OnChartEvent () in the tester does not work. But the one-stop solution for the pressing in the tester and live trading there.
 if(ObjectGetInteger(0,"BUY_button",OBJPROP_STATE))
{
ObjectSetInteger(0,"BUY_button",OBJPROP_STATE,false);
...
}

 

 

 Note 7 - circumsision characters in price of instrument

Suitable only for the price. If there is something else, you have to write the number instead of Digits is exactly the number of fraction symbols.

extern ushort Characters_delete = 1;

///////////////////////////////////////////
string data=DoubleToString(Bid,Digits);
string resoult=StringSubstr(data,0,StringLen(data)-Characters_delete);

 

 

Note 8 - split string into elements

For example, we need to share the line with lots and put them in a buffer.

extern 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]);
}

 

 

Note 9 - determination on the first tick of a new candle (working time at the bar)

And just so it is necessary to determine the arrival of a new bar. Many use the Time [0], but it will not work properly if you are not updating the schedule switch to turn on the terminal, or after inactivity.

int prevbars;
...
if(Bars==prevbars) return;
 prevbars=Bars;

 

 

Note 10 - renko chart

If you need EA to work on offline chart,than you need to write like this:

double prev_bid=Close[0];
int OnInit()
 {  
 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);
 }
 }

 return(INIT_SUCCEEDED);
}

 

 

 

Note 11 - mql5 get data

To get some data(open price of 4-th candle ex.) of series(or other type) need to write like

//if(open(4)>0)...

//////////////////////////////
double open(int CC)
{
double open[1]; 
CopyOpen(Symbol(),0,CC,1,open);

return(open[0]);
}

 

 

Note 12 - chek 1-st second of new bar

If you use OnTimer and you need to know first second of bar,you need to write like this.

int prevbars;
datetime new_bar_time;
int time_shift;
int CC; //bar to chek signal(iCustom,Close[]...)
bool once_chaked;

//////////////////////////////////////////
void OnTick()
{
if(!once_chaked)
{
once_chaked=true;
time_shift=int(TimeLocal()-TimeCurrent());
EventSetTimer(1);
}
}

////////////////////////////////////////////
void OnTimer()
{
   if(Bars==prevbars) 
   {
   new_bar_time=Time[0]+Period()*60;
   CC=0;
   }
   else 
   {
   new_bar_time=Time[0];
   CC=1;
    prevbars=Bars;
   }
 if(TimeLocal()-time_shift<new_bar_time) return;

}

 


Note 13 - chek possibility for EA trading(for example OnTimer)

//trading is not allowed
 if(!IsTradeAllowed() || !IsTradeAllowed(Symbol(),TimeCurrent())) return;

 

Note 14 - OnTimer in tester

On timer do not works in tester. So you need to write like this.
void OnTick()
 { 
 if(IsTesting()) All();
 }
//////////
 void OnTimer()
 {  
 All();
 }


//////////
void All()
{
//your code
}

 

 

Note 15 - new closed order

 Function detects if one(or couple) of order with some magic has been closed.

int prev_Hist_tot;
datetime last_Hist_order_chaked_time;
datetime buf_time;

void OnTick()
{
chek_order_closes_f();
}

/////////////////////////////////////////////////////
void chek_order_closes_f()
{
bool last_cheked=false;

if(OrdersHistoryTotal()>prev_Hist_tot)
{   
for (int i=OrdersHistoryTotal()-1; i>=0; i--)
 {
   if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
   {
   if(OrderMagicNumber()==Magic)
   {
   if(OrderSymbol()==Symbol())
   { 
   if(OrderCloseTime()<=last_Hist_order_chaked_time) break;
    
    Alert("Order ",string(OrderTicket())," closes!",);

     if(!last_cheked) 
     {
     last_cheked=true;
     buf_time=OrderCloseTime();
     }
   }
   }
   }
  }

}

   prev_Hist_tot=OrdersHistoryTotal();
   last_Hist_order_chaked_time=buf_time;

}

 

 

 

Note 16 - TimeFrame to string

Period of chart transforms to string names.

string TF_str_f(int tf)
{
string tf_ret="";

switch(tf)
{
case PERIOD_M1:tf_ret="M1";
break;
case PERIOD_M5:tf_ret="M5";
break;
case PERIOD_M15:tf_ret="M15";
break;
case PERIOD_M30:tf_ret="M30";
break;
case PERIOD_H1:tf_ret="H1";
break;
case PERIOD_H4:tf_ret="H4";
break;
case PERIOD_D1:tf_ret="D1";
break;
case PERIOD_W1:tf_ret="W1";
break;
case PERIOD_MN1:tf_ret="MN1";
break;

default:tf_ret="?";
}


return(tf_ret);
}

 

Share it with friends: