Programming question, MQL4 - page 2

 
Thirteen:

Try this:

 Not compiled or tested

 

worked great... Thank you so much

 

Hi, I want to develop EA in MT4, I have made some EA before and have experience with C++.

Now, since MQL4 supports OOP which I'm more comfortable than procedural language, is it wise to learn new MQL4 language which is adapted from MQL5 ?

Unfortunately its still lack of tutorial although the documentation is there.

 

Continuing on my programming learning endeavor, 

I am trying to develop an EA now just for educational purposes. The idea is simple. It detects candle spike and put an order (buy or sell) with a TP and SL. Ihe idea is based mainly on simple candle pattern.SpikySpike EA Idea  

This picture would help to get the idea.  Here is the code under but still not working.  I am not sure why?

//+-----------------------------------------------------------------------+
//|                                               spikySpike EA V1   mq4  |
//|                                                         EgyAlgoTrader |
//+-----------------------------------------------------------------------+
#property copyright "EgyAlgoTrader"
#property link      "https://forum.mql4.com/66171/page2"
#property version   "1.00"

//+Extern Variables---------------------------------------------------------------+
extern int                bar_volume_min        = 5;
extern int                spike_volume_min      = 5;
extern double             starting_LotSize      = 0.01;
extern int                spike_min_factor      = 2;
extern double             Slippage              = 5;
extern int                StopLoss              = 10;
extern int                TP                    = 5;
extern int                bMagic                = 12345;
extern int                sMagic                = 6789;

//+Global Variables-----------------------------------------------------------------+
double pt;
double TPS;
double TPB;
double stopLossB;
double stopLossS;
double absHighToClose5 = MathAbs (High [1]-Close [1]);
double absHighToOpen1 = MathAbs (High [1]-Open [1]);
double absLowToClose2 = MathAbs (Low [1]-Close [1]);
double absLowToOpen4 = MathAbs (Low [1]-Open [1]);
double absOpenToClose3 = MathAbs (Open [1]-Close [1]);
  
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
Comment("Copyright © 2014, Spike EA Educational");
   
  if(Digits==3 || Digits==5) pt=10*Point;  // when use at broker with 5 digits 
    else                       pt=Point;     // pricing, this function is useful 
    double stoplevel;                        // minimal pips for stop
    stoplevel=MarketInfo(Symbol(),MODE_STOPLEVEL);  // get broker's stoplevel
    if(StopLoss<=stoplevel) StopLoss=stoplevel;   // we compare our StopLoss with
                                             // stoplevel and adjust it when error occured
    if(TP<=stoplevel) TP=stoplevel;  // we compared our TakeProfit
                                             // as we compared our StopLoss
//----                                        
    return(0);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
  
    if ( SignalBuy () )
    { Comment( "\n", " Singal Buy Found");
   int buyTicket = OrderSend (Symbol(),OP_BUY,starting_LotSize,Ask,Slippage,StopLossB (),TargetProfitB (),"",bMagic,0,clrLawnGreen);
   if (buyTicket == -1){Comment ("\n\n", " Last buy order error  ",  GetLastError ());}
    
    }
    
    if (!SignalBuy ())
    {Comment( "\n\n\n", " No Singal Buy Found"); }
    if ( SignalSell () )
    
    { Comment ("\n\n\n\n", " Sell signal Found");
    int sellTicket = OrderSend(Symbol(),OP_SELL,starting_LotSize,Bid,Slippage,StopLossS (),TargetProfitS (),"",sMagic,0,clrOrangeRed);
    if (sellTicket == -1) { Comment ("\n\n\n\n\n", " Last Sell Order error   ", GetLastError ());}
    }
    
    if (!SignalSell ())
    {Comment( "\n\n\n\n\n\n", " No Singal Sell Found"); }
    return;
    }
 

//+------------------------------------------------------------------+
//| Get Buy Signal                                                   |
//+------------------------------------------------------------------+

bool SignalBuy ()
{  
  for (int i=OrdersTotal ()-1;i>=0; i--)
  
   { if (OrderSelect ( i, SELECT_BY_POS))
        { if (OrderType () != OP_BUY                            &&
              absLowToOpen4 > absOpenToClose3                   &&
              absLowToOpen4 > absHighToClose5                   &&
              Close [1] > Open [1]                              &&
              absLowToOpen4 >= spike_min_factor*absOpenToClose3 &&
              absLowToOpen4 >= bar_volume_min *pt )
        
        { return (true);}
         
        
        else return (false);

       }
   }
}

//+------------------------------------------------------------------+
//| Get Sell Signal                                                  |
//+------------------------------------------------------------------+

bool SignalSell ()
{  for (int i=OrdersTotal()-1;i>=0; i--)
   
   {    if (OrderSelect (i, SELECT_BY_POS))                
      { if (OrderType () != OP_SELL                        && 
        absHighToOpen1 > absOpenToClose3                   &&
        absHighToOpen1 > absLowToClose2                    &&
        Close [1] < Open [1]                               &&
        absHighToOpen1 >= spike_min_factor*absOpenToClose3 &&
        absHighToOpen1 >= bar_volume_min *pt )
        
        { return (true);}

        else return (false);
      }
   }
}

//+------------------------------------------------------------------+
//| Calculate TP for Buy order                                       |
//+------------------------------------------------------------------+

double TargetProfitB ( )
{   
    TPB =  High [2] + TP*pt;
   return (TPB);
   
}
       
//+------------------------------------------------------------------+
//| Calculate TP for sell  order                                     |
//+------------------------------------------------------------------+

double TargetProfitS ( )
{  
    TPS =  Low [2] - TP*pt;
   return (TPS);
   
}

//+------------------------------------------------------------------+
//| Calculate StopLoss_B                                             |
//+------------------------------------------------------------------+

double StopLossB ( )
{  
    TPB =  Low [1] - StopLoss*pt;
   return (stopLossB);
   
}
       
//+------------------------------------------------------------------+
//| Calculate StopLoss_sell                                          |
//+------------------------------------------------------------------+

double StopLossS ( )
{  
    TPS = High [1]+ StopLoss*pt;
   return (stopLossS);
   
}
 
fixed some embarrassing mistakes. but not working yet.  I think it might be the signal logic is bad .. more specifically, the way i am looking for previous buys or sells. 
//+-----------------------------------------------------------------------+
//|                                               spikySpike EA V1   mq4  |
//|                                                         EgyAlgoTrader |
//+-----------------------------------------------------------------------+
#property copyright "EgyAlgoTrader"
#property link      "https://forum.mql4.com/66171/page2"
#property version   "1.00"

//+Extern Variables---------------------------------------------------------------+
extern int                bar_volume_min        = 5;
extern int                spike_volume_min      = 5;
extern double             starting_LotSize      = 0.01;
extern int                spike_min_factor      = 2;
extern double             Slippage              = 5;
extern int                StopLoss              = 10;
extern int                TP                    = 5;
extern int                bMagic                = 12345;
extern int                sMagic                = 6789;

//+Global Variables-----------------------------------------------------------------+
double pt;
double stopLossB;
double stopLossS;
double absHighToClose5 = MathAbs (High [1]-Close [1]);
double absHighToOpen1 = MathAbs (High [1]-Open [1]);
double absLowToClose2 = MathAbs (Low [1]-Close [1]);
double absLowToOpen4 = MathAbs (Low [1]-Open [1]);
double absOpenToClose3 = MathAbs (Open [1]-Close [1]);
  
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
Comment("Copyright © 2014, SpikySpike EA for Educational purposes");
   
  if(Digits==3 || Digits==5) pt=10*Point;  // when use at broker with 5 digits 
    else                       pt=Point;     // pricing, this function is useful 
    double stoplevel;                        // minimal pips for stop
    stoplevel=MarketInfo(Symbol(),MODE_STOPLEVEL);  // get broker's stoplevel
    if(StopLoss<=stoplevel) StopLoss=stoplevel;   // we compare our StopLoss with
                                             // stoplevel and adjust it when error occured
    if(TP<=stoplevel) TP=stoplevel;  // we compared our TakeProfit
                                             // as we compared our StopLoss
//----                                        
    return(0);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
  
    if ( SignalBuy () )
    { Comment( "\n", " Singal Buy Found");
   int buyTicket = OrderSend (Symbol(),OP_BUY,starting_LotSize,Ask,Slippage,StopLossB (),TargetProfitB (),"",bMagic,0,clrLawnGreen);
   if (buyTicket == -1){Comment ("\n\n", " Last buy order error  ",  GetLastError ());}
    
    }
    
    if (!SignalBuy ())
    {Comment( "\n\n\n", " No Singal Buy Found"); }
    if ( SignalSell () )
    
    { Comment ("\n\n\n\n", " Sell signal Found");
    int sellTicket = OrderSend(Symbol(),OP_SELL,starting_LotSize,Bid,Slippage,StopLossS (),TargetProfitS (),"",sMagic,0,clrOrangeRed);
    if (sellTicket == -1) { Comment ("\n\n\n\n\n", " Last Sell Order error   ", GetLastError ());}
    }
    
    if (!SignalSell ())
    {Comment( "\n\n\n\n\n\n", " No Singal Sell Found"); }
    return;
    }
 

//+------------------------------------------------------------------+
//| Get Buy Signal                                                   |
//+------------------------------------------------------------------+

bool SignalBuy ()
{  
  for (int i=OrdersTotal ()-1;i>=0; i--)// I wanted here to make sure that EA opens only one buy or one sell at any time. 
                                        // However, i am thinking what would happen if there is no orders at all. How this could work
  
   { if (OrderSelect ( i, SELECT_BY_POS))
        { if (OrderType () != OP_BUY                            && // if no buy before
              absLowToOpen4 > absOpenToClose3                   &&
              absLowToOpen4 > absHighToClose5                   &&
              Close [1] > Open [1]                              &&
              absLowToOpen4 >= spike_min_factor*absOpenToClose3 &&
              absLowToOpen4 >= bar_volume_min *pt )
        
        { return (true);}
         
        
        else return (false);

       }
   }
}

//+------------------------------------------------------------------+
//| Get Sell Signal                                                  |
//+------------------------------------------------------------------+

bool SignalSell ()
{  for (int i=OrdersTotal()-1;i>=0; i--)
   
   {    if (OrderSelect (i, SELECT_BY_POS))                
      { if (OrderType () != OP_SELL                        && // if no sell before
        absHighToOpen1 > absOpenToClose3                   &&
        absHighToOpen1 > absLowToClose2                    &&
        Close [1] < Open [1]                               &&
        absHighToOpen1 >= spike_min_factor*absOpenToClose3 &&
        absHighToOpen1 >= bar_volume_min *pt )
        
        { return (true);}

        else return (false);
      }
   }
}

//+------------------------------------------------------------------+
//| Calculate TP for Buy order                                       |
//+------------------------------------------------------------------+

double TargetProfitB ( )
{   
    double TPB =  High [2] + TP*pt;
   return (TPB);
   
}
       
//+------------------------------------------------------------------+
//| Calculate TP for sell  order                                     |
//+------------------------------------------------------------------+

double TargetProfitS ( )
{  
    double TPS =  Low [2] - TP*pt;
   return (TPS);
   
}

//+------------------------------------------------------------------+
//| Calculate StopLoss_B                                             |
//+------------------------------------------------------------------+

double StopLossB ( )
{  
    double SLB =  Low [1] - StopLoss*pt;
   return (SLB);
   
}
       
//+------------------------------------------------------------------+
//| Calculate StopLoss_sell                                          |
//+------------------------------------------------------------------+

double StopLossS ( )
{  
    double SLS = High [1]+ StopLoss*pt;
   return (SLS);
   
}
 
//I wanted here to make sure that EA opens only one buy  " or /and " one sell at any time. 
// However, i am thinking what would happen if there is no orders at all. How this could work
 

You can try something like

bool SignalBuy ()
{  
  for (int i=OrdersTotal ()-1;i>=0; i--)
   { 
   if (OrderSelect ( i, SELECT_BY_POS))
     { 
     if (OrderType () == OP_BUY && OrderMagicNumber()==bMagic)
        return(false);
     }
   }
   
   if(absLowToOpen4 > absOpenToClose3                   &&
      absLowToOpen4 > absHighToClose5                   &&
      Close [1] > Open [1]                              &&
      absLowToOpen4 >= spike_min_factor*absOpenToClose3 &&
      absLowToOpen4 >= bar_volume_min *pt )
         return (true);
         
        
   return (false);
}

 Also, the variables absHighToClose5 etc are not assigned values in OnTick so will not change from when the EA is started. Is that what you want?

 
double absHighToClose5 = MathAbs (High [1]-Close [1]);
double absHighToOpen1 = MathAbs (High [1]-Open [1]);
double absLowToClose2 = MathAbs (Low [1]-Close [1]);
double absLowToOpen4 = MathAbs (Low [1]-Open [1]);
double absOpenToClose3 = MathAbs (Open [1]-Close [1]);
These variables are constant. You need to assign them in OnTick
 

Thank you so much.. It was a new info to know about this kind of variables. I have done the modifications. Buy orders did work but SELL did not.

//+-----------------------------------------------------------------------+
//|                                               spikySpike EA V1   mq4  |
//|                                                         EgyAlgoTrader |
//+-----------------------------------------------------------------------+
#property copyright "EgyAlgoTrader"
#property link      "https://forum.mql4.com/66171/page2"
#property version   "1.00"

//+Extern Variables---------------------------------------------------------------+
extern int                bar_volume_min        = 1;
extern int                spike_volume_min      = 1;
extern double             starting_LotSize      = 0.01;
extern int                spike_min_factor      = 2;
extern double             Slippage              = 5;
extern int                StopLoss              = 10;
extern int                TP                    = 5;
extern int                bMagic                = 12345;
extern int                sMagic                = 6789;

//+Global Variables-----------------------------------------------------------------+
double pt;
double stopLossB;
double stopLossS;

double absHighToClose5 ;
double absHighToOpen1;
double absLowToClose2 ;
double absLowToOpen4 ;
double absOpenToClose3;

  
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
Comment("Copyright © 2014, SpikySpike EA for Educational purposes");
   
  if(Digits==3 || Digits==5) pt=10*Point;  // when use at broker with 5 digits 
    else                       pt=Point;     // pricing, this function is useful 
    double stoplevel;                        // minimal pips for stop
    stoplevel=MarketInfo(Symbol(),MODE_STOPLEVEL);  // get broker's stoplevel
    if(StopLoss<=stoplevel) StopLoss=stoplevel;   // we compare our StopLoss with
                                             // stoplevel and adjust it when error occured
    if(TP<=stoplevel) TP=stoplevel;  // we compared our TakeProfit
                                             // as we compared our StopLoss
//----                                        
    return(0);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {   
      absHighToOpen1 = MathAbs (High [1]-Open [1]);
      absLowToOpen4 = MathAbs (Low [1]-Open [1]);
      absOpenToClose3 = MathAbs (Open [1]-Close [1]);
  
    if ( FindNewBar () == true && SignalBuy ()== true )
    { Comment( "\n", " Singal Buy Found");
   int buyTicket = OrderSend (Symbol(),OP_BUY,starting_LotSize,Ask,Slippage,StopLossB (),TargetProfitB (),"",bMagic,0,clrLawnGreen);
   if (buyTicket == -1){Comment ("\n\n", " Last buy order error  ",  GetLastError ());}
    
    }
    
    else if ( FindNewBar () == false && SignalBuy ()== false)
    {Comment( "\n\n\n", " No Singal Buy Found"); }
    
    
    else if ( FindNewBar () == true && SignalSell ()== true )
    { Comment ("\n\n\n\n", " Sell signal Found");
    int sellTicket = OrderSend(Symbol(),OP_SELL,starting_LotSize,Bid,Slippage,StopLossS (),TargetProfitS (),"",sMagic,0,clrOrangeRed);
    if (sellTicket == -1) { Comment ("\n\n\n\n\n", " Last Sell Order error   ", GetLastError ());}
    }
    
    else if (FindNewBar () == false && SignalSell ()== false)
    {Comment( "\n\n\n\n\n\n", " No Singal Sell Found"); }
    return;
    }
 

//+------------------------------------------------------------------+
//| Get Buy Signal                                                   |
//+------------------------------------------------------------------+

bool SignalBuy ()
{  
  for (int i=OrdersTotal ()-1;i>=0; i--)
   { 
   if (OrderSelect ( i, SELECT_BY_POS))
     { 
     if (OrderType () == OP_BUY && OrderMagicNumber()==bMagic)
        return(false);
     }
   }
   
   if(Close [1] > Open [1]                              &&
      Close [2] < Open [2]                              &&
      Close [3] < Open [3]                              &&
      Close [4] < Open [4]                              &&
      Low  [2] > Low [1]                                &&
      absLowToOpen4 >= spike_min_factor*absOpenToClose3 &&
      absOpenToClose3 >= bar_volume_min *pt )
         return (true);
     
}

//+------------------------------------------------------------------+
//| Get Sell Signal                                                  |
//+------------------------------------------------------------------+

bool SignalSell ()
{  
  for (int i=OrdersTotal ()-1;i>=0; i--)
   { 
   if (OrderSelect ( i, SELECT_BY_POS))
     { 
     if (OrderType () == OP_SELL && OrderMagicNumber()==sMagic)
        Print (" SignalSell False");
        return(false);
        
     }
   }
   
   if(Close [1] < Open [1]                              &&
      Close [2] > Open [2]                              &&
      High  [2] < High [1]                              &&
      absHighToOpen1 >= spike_min_factor*absOpenToClose3 &&
      absOpenToClose3 >= bar_volume_min *pt )
      Print (" SignalSell True");
      return (true);
}

//+------------------------------------------------------------------+
//| Calculate TP for Buy order                                       |
//+------------------------------------------------------------------+

double TargetProfitB ( )
{   
    double TPB =  High [2] + (TP*pt);
   return (TPB);
   
}
       
//+------------------------------------------------------------------+
//| Calculate TP for sell  order                                     |
//+------------------------------------------------------------------+

double TargetProfitS ( )
{  
    double TPS =  Low [2] - (TP*pt);
   return (TPS);
   
}

//+------------------------------------------------------------------+
//| Calculate StopLoss_B                                             |
//+------------------------------------------------------------------+

double StopLossB ( )
{  
    double SLB =  Low [1] - (StopLoss*pt);
   return (SLB);
   
}
       
//+------------------------------------------------------------------+
//| Calculate StopLoss_sell                                          |
//+------------------------------------------------------------------+

double StopLossS ( )
{  
    double SLS = High [1]+ (StopLoss*pt);
   return (SLS);
   
}


//+------------------------------------------------------------------+
//| Find New Bar                                         |
//+------------------------------------------------------------------+
bool FindNewBar() 
{

   static datetime oldTime = 0;
   
   if (oldTime == 0)
   
      {oldTime = Time[0];
      return (false);}
      
     else if (oldTime < Time[0]) {
      Print ("New bar found! (", TimeToStr(TimeCurrent(), TIME_DATE|TIME_MINUTES|TIME_SECONDS), ")");
      oldTime = Time[0];
      return (true);   
   }

   return(0);
}

 In the log, it says there is sell signal true but EA did not open. What i can say is "Programming is really fun". :)

 
Buy SignalHappy New Year
 
    if ( FindNewBar () == true && SignalBuy ()== true )
    { 
      :
    }
    
    else if ( FindNewBar () == false && ...
You can only call FindNewBar once per tick. Every subsequent call always returns false. That is why I recommend that that is never placed in a function.
void OnTick(){
   static datetime Time0=0;
   bool isNewBar = Time0 != Time[0]; Time0=Time[0];

   if(isNewBar ...