Trade opening on every tick

 

Hi all,

Could I please get some advise on the following (very new to all this - so just a simple EA based on a 20SMA)


//+------------------------------------------------------------------+
//|                                              Inside_bar(new).mq5 |
//|                                                             Matt |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Matt"
#property link      ""
#property version   "1.00"

#include<Trade\Trade.mqh> // Import module
CTrade trade; // Instantiate CTrade class

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+


// Constants para's'
int simple_ma = 20;
int offset = 0;



// Handle for SMA
int moving_average_def = iMA(Symbol(), _Period, simple_ma, offset, MODE_SMA, PRICE_CLOSE);



//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

// Function - decide is PA is above or below (or IN) the MA - give entry direction from there
int ma_indicator(double &ma_array[], double &low_array[], double &high_array[]) //Array needs to be passed AS REFERENCE (&)
  {

   int signal;

   if((low_array[1] >= ma_array[1]) && (high_array[1] >= ma_array[1]))
     {
      signal = 1; // BUY Signal
     }

   else if((low_array[1] <= ma_array[1]) && (high_array[1] <= ma_array[1]))
     {
      signal = 2; // SELL Signal
     }
   else
     {
      signal = 0; // Do Nothing
     }

   return signal;

  }





int OnInit()
  {
//---
   Print("Inside Bar EA Running...");


//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   Print("Inside Bar EA - Stopped");
   Comment(" "); // Clear comments from Screen
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---


// Log the highs per candle for the last 3 candles
   double high[]; // double array
   ArraySetAsSeries(high, true);
   CopyHigh(Symbol(),PERIOD_CURRENT,0,4,high); // High price of the last 10 bars (0,4)


// Log the lows per candle for the last 3 candles
   double low[]; // double array
   ArraySetAsSeries(low, true);
   CopyLow(Symbol(),PERIOD_CURRENT,0,4,low); // Low price of the last 10 bars (0,4)



// Log the SMA results per candle for the last 3 candles
   double moving_average_array[]; // double array
   ArraySetAsSeries(moving_average_array, true);
   CopyBuffer(moving_average_def, offset, 0, 4, moving_average_array);



// Pass the function result back to decide if the MA criteria is met
int ma_indicator_output = ma_indicator(moving_average_array, low, high);

   if(ma_indicator_output == 1) // BUY
     {
      Comment("BUY POTENTIAL");
      
         if ((high[3] >= high[2]) && (low[3] <= low[2]))
         {
         trade.Buy(0.10, Symbol(), high[3], low[3], (high[3]-low[3])+high[3],"Buy trade entered");
         }
     }

   else if(ma_indicator_output == 2) // SELL
     {
      Comment("SELL POTENTIAL");
         if ((high[3] >= high[2]) && (low[3] <= low[2]))
         {
            trade.Sell(0.10, Symbol(), low[3], high[3], low[3]-(high[3]-low[3]),"Sell trade entered");
         }

     }
   else if(ma_indicator_output == 0) // Do Nothing
     {
      Comment("NO SIGNAL");
     }
   else
     {
      Comment("Error 1"); // Should never happen
     }


  }
//+------------------------------------------------------------------+

The intention is: If the high and the low of the last closed candle is clear of the 20SMA && above == BUY, if its clear of the 20SMA && below == SELL


The issue is it seems to (rightly so) create a new position each time a new tick comes in and the conditions are met. 

This must be a fundamental concern of MQL (operating functions per tick - but only wanting a condition to fire once, once met)


How do you get around this? 


PS: If I could just re-iterate - I'm pretty new, the more detailed a response you can give me the better for my progress. 

Thanks in advance for your help.

 
  1. Don't use ints when you mean bool or an enumeration. You are not returning a count.
    int ma_indicator(…){
    
                    
       int signal;
       if(…)      signal = 1; // BUY Signal
       else if(…) signal = 2; // SELL Signal
       else       signal = 0; // Do Nothing
       return signal;
    }
    ⋮
       int ma_indicator_output = ma_indicator(moving_average_array, low, high);
       if(ma_indicator_output == 1) // BUY
    Use an enumeration and make your code self documenting.
    
                    
    enum Signal{ SIGNAL_BUY, SIGNAL_SELL, SIGNAL_NONE };
    Signal ma_indicator(…){
       if(…) return SIGNAL_BUY;
       if(…) return SIGNAL_SELL;
             return SIGNAL_NONE;
    }
    ⋮
       Signal ma_indicator_output = ma_indicator(moving_average_array, low, high);
       if(ma_indicator_output == SIGNAL_BUY)

  2. Check for open position before trying to open.

  3. You are looking at a signal. Act on a change of signal.
              MQL4 (in Strategy Tester) - double testing of entry conditions - MQL5 programming forum #1 2017.12.12

 

@william - thanks for your help mate

1. Good point on the bool Vs Ints - I used Ints as there were 3 conditions (BUY, SELL, NO SIGNAL) and not 2 - but that same thing was on my mind too!

2. ENUM usage - you got me. You're right, I'll stop being lazy and fix that up :) Great suggestion.

3. To clarify: are you suggesting I identify the time diff between the first trade and the current time - if less then the chart-period = wait?

If thats the case: Is there a way to make the identification of the period (5m 1h, 4h, etc) variable - so I can program something to say "wait for 1 candle before re-assessing" - and have a scalable solution?


Again - thanks for your help