Pinbar Signal EA

 

Hi MQL 4/5 users.

 

I have created an EA that detects Pinbars (Yes, I know it's been done before but I'm very new to coding and this is my version which I intend on building additional confluence and trading functionality into).

 

So far, the EA checks prior candles (the quantity specified by the user) for a specific shape, etc and then places an arrow above or below the Pinbar. And this will be required once I have completed all other parts of the program and want to export the results to a CSV file for historical analysis. This section is run via the OnInit event.

 

However, once the Market is open, I would like to keep updating the chart as each new candle closes and becomes Candle [1]. So I'm guessing I need to create a function in the OnTick event which checks all my criteria once Candle[0] has closed. Sort of the way a custom indicator works but within an EA as I need the EA's functionality.

 

I have attached my program and would be very grateful if someone could point me in the right direction.

 

One more thing - I'm using MQL4. 

 

Mark 

Files:
FOR_loop.mq4  4 kb
 
Best practise: upload at Codebase section. you will get more feedbacks from there instead. Good luck
 
//+------------------------------------------------------------------+
//|                                                     FOR loop.mq4 |
//|                                       Copyright 2015 Mark Falzon |
//|                                             https://www.mql4.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015 Mark Falzon"
#property link      "https://www.mql4.com"
#property version   "1.00"
#property strict

input string Variables="**********************";
input double Tail_ratio=2.0; // Minimum tail (ratio)
input double Nose_percentage=25; // Maximum nose percentage (%)
input double Min_candle_length=10; //Minimum length of Pinbar (pips)
input double Max_candle_length=150; //Maximum length of Pinbar (pips)
input int Total_bars=15; // Total bars to be tested

double Range,Body,Ratio,Upper_Shadow,Lower_Shadow;
bool Bull_PB=False,Bear_PB=False;
int i=0,ObjectsDeleteAll,Pair=10000;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   ObjectsDeleteAll();
   Alert("New Run Start Point");
   for(i=0;i<Total_bars;i++)
     {
      Range=NormalizeDouble((High[i]-Low[i]),5);
      Body=NormalizeDouble(fabs((Close[i]-Open[i])),5);

      if(Digits==5)
        {Pair=10000;}
      else
        {Pair=100;}

      if((Range<=(Max_candle_length/Pair)) && (Range>=(Min_candle_length/Pair)))
        {
         if(Close[i]>Open[i])
           {
            Upper_Shadow=NormalizeDouble((High[i]-Close[i]),5);
            Lower_Shadow=NormalizeDouble((Open[i]-Low[i]),5);
           }
         else
           {
            Upper_Shadow=NormalizeDouble((High[i]-Open[i]),5);
            Lower_Shadow=NormalizeDouble((Close[i]-Low[i]),5);
           }

         if((Upper_Shadow<(Range*Nose_percentage/100)) && (Lower_Shadow>(Body*Tail_ratio)))
           {
            Ratio=NormalizeDouble((Lower_Shadow/Body),1);
            Bull_PB=True;
            ObjectCreate("Bullish Pinbar on candle "+IntegerToString(i)+" at "+TimeToStr(Time[i]),OBJ_ARROW_UP,0,Time[i],High[i]+Range/2);
           }
         else
           {Bull_PB=False;}

         if((Upper_Shadow>(Body*Tail_ratio)) && (Lower_Shadow<(Range*Nose_percentage/100)))
           {
            Ratio=NormalizeDouble((Upper_Shadow/Body),1);
            Bear_PB=True;
            ObjectCreate("Bearish Pinbar on candle "+IntegerToString(i)+" at "+TimeToStr(Time[i]),OBJ_ARROW_DOWN,0,Time[i],Low[i]-Range/3);
           }
         else
           {Bear_PB=False;}
        }

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

//+------------------------------------------------------------------+
 
Donald Gibson:

Thanks Donald. Won't that just keep on analysing historic data each time a new tick comes in?

 

I've changed my program such that the user can now choose whether they want to analyse historic data and live data. If the user wants to analyse historic data, it is carried out once in the OnInit event. If the user wants to analyse live data, the analysis is carried out at the start of each new bar on the prior closed bar. I am using Time[0] as an indication of when a new candle forms. So I think I've answered my own question. But any suggestions on how to make this more efficient is much appreciated. My latest program is as follows:

 

 //+------------------------------------------------------------------+

//|                                                     FOR loop.mq4 |

//|                                       Copyright 2015 Mark Falzon |

//|                                             https://www.mql4.com |

//+------------------------------------------------------------------+

#property copyright "Copyright 2015 Mark Falzon"

#property link      "https://www.mql4.com"

#property version   "1.00"

#property strict


input string   Variables="**********************";

input double   Tail_ratio=2.0; // Minimum tail (ratio)

input double   Nose_percentage=28.6; // Maximum nose percentage (%)

input double   Min_candle_length=0.5; //Minimum length of Pinbar (pips)

input double   Max_candle_length=150; //Maximum length of Pinbar (pips)

input int      Total_bars=100; // Total bars to be tested

input bool     Historic_data=True; // Do you want to analyse historic data?

input bool     Live_data=True; // Do you want to analyse live data?


double         Range, Body, Upper_Shadow, Lower_Shadow;

bool           Bull_PB=false, Bear_PB=false, SendNotification;

int            i=0, ObjectsDeleteAll, Pair=10000;


//+------------------------------------------------------------------+

//| Expert initialization function                                   |

//+------------------------------------------------------------------+


int OnInit()

  {

//--- Comment on what operations have been chosen


   if ((Historic_data&&Live_data)==true)

      {Comment(""+

      "\nHistoric data has been analysed over the last "+IntegerToString(Total_bars)+" candles"+

      "\nLive data is being analysed");}

   if ((Historic_data&&Live_data)==false)

      {Comment(""+

      "\nNeither historic data nor live data are being analysed");}

   if (Historic_data==true&&Live_data==false)

      {Comment(""+

     "\nHistoric data has been analysed over the last "+IntegerToString(Total_bars)+" candles"+

     "\nLive data isn't being analysed");}

   if (Historic_data==false&&Live_data==true)

      {Comment(""+

     "\nHistoric data has not been been analysed"+

     "\nLive data is being analysed");}


//--- Clearing data from chart

   

   ObjectsDeleteAll();

   Alert("New Run Start Point");


//--- Analysing Historic Data


   if (Historic_data==True)

      {

      for(i=1;i<Total_bars;i++)

      {

      Range=NormalizeDouble((High[i]-Low[i]),5);

      Body=NormalizeDouble(fabs((Close[i]-Open[i])),5);

      

      if (Digits==5)

         {Pair=10000;}

      else

         {Pair=100;}

   

      if ((Range<=(Max_candle_length/Pair))&&(Range>=(Min_candle_length/Pair)))

         {

         if (Close[i]>Open[i])

            {Upper_Shadow=NormalizeDouble((High[i]-Close[i]),5);

            Lower_Shadow=NormalizeDouble((Open[i]-Low[i]),5);}

         else

            {Upper_Shadow=NormalizeDouble((High[i]-Open[i]),5);

            Lower_Shadow=NormalizeDouble((Close[i]-Low[i]),5);}

            

         if ((Upper_Shadow<(Range*Nose_percentage/100))&&(Lower_Shadow>(Body*Tail_ratio)))

            {Bull_PB=True;

            ObjectCreate("Bullish Pinbar on candle "+IntegerToString(i)+" at "+TimeToStr(Time[i]),OBJ_ARROW_UP,0,Time[i],High[i]+Range/2);}

         else

            {Bull_PB=False;}

            

         if ((Upper_Shadow>(Body*Tail_ratio))&&(Lower_Shadow<(Range*Nose_percentage/100)))

            {Bear_PB=True;

            ObjectCreate("Bearish Pinbar on candle "+IntegerToString(i)+" at "+TimeToStr(Time[i]),OBJ_ARROW_DOWN,0,Time[i],Low[i]-Range/3);}

         else

            {Bear_PB=False;}

         }

      }

      }

//---

   return(INIT_SUCCEEDED);

  }


//+------------------------------------------------------------------+

//| Expert deinitialization function                                 |

//+------------------------------------------------------------------+


 void OnDeinit(const int reason)

  {

//---

   

  }

  

//+------------------------------------------------------------------+

//| Expert tick function                                             |

//+------------------------------------------------------------------+


void OnTick()

  {

  

//--- Analysing Live Data


   if (Live_data==True)

      {

      static datetime Time0;

      if (Time0 == Time[0])

      return;

      Time0 = Time[0];

   

         Range=NormalizeDouble((High[1]-Low[1]),5);

         Body=NormalizeDouble(fabs((Close[1]-Open[1])),5);

         

         if (Digits==5)

            {Pair=10000;}

         else

            {Pair=100;}

      

         if ((Range<=(Max_candle_length/Pair))&&(Range>=(Min_candle_length/Pair)))

            {

            if (Close[1]>Open[1])

               {Upper_Shadow=NormalizeDouble((High[1]-Close[1]),5);

               Lower_Shadow=NormalizeDouble((Open[1]-Low[1]),5);}

            else

               {Upper_Shadow=NormalizeDouble((High[1]-Open[1]),5);

               Lower_Shadow=NormalizeDouble((Close[1]-Low[1]),5);}

               

            if ((Upper_Shadow<(Range*Nose_percentage/100))&&(Lower_Shadow>(Body*Tail_ratio)))

               {Bull_PB=True;

               ObjectCreate("Bullish Pinbar on candle "+IntegerToString(1)+" at "+TimeToStr(Time[1]),OBJ_ARROW_UP,0,Time[1],High[1]+Range/2);

               Alert("A Bullish pinbar has just formed on the M"+IntegerToString(Period())+" Chart");

               SendNotification("A Pinbar has just formed on the M"+IntegerToString(Period())+" Chart");}

            else

               {Bull_PB=False;}

               

            if ((Upper_Shadow>(Body*Tail_ratio))&&(Lower_Shadow<(Range*Nose_percentage/100)))

               {Bear_PB=True;

               ObjectCreate("Bearish Pinbar on candle "+IntegerToString(1)+" at "+TimeToStr(Time[1]),OBJ_ARROW_DOWN,0,Time[1],Low[1]-Range/3);

               Alert("A Pinbar has just formed on the M"+IntegerToString(Period())+" Chart");

               SendNotification("A Bearish pinbar has just formed on the M"+IntegerToString(Period())+" Chart");}

            else

               {Bear_PB=False;}

            }

      }

}

  

//+------------------------------------------------------------------+
 

Forum on trading, automated trading systems and testing trading strategies


Hello,

Please use the SRC button when you post code. Thank you.


This time, I edited it for you.


 
Alain Verleyen:

Thanks Alain.

 

I had wondered how other users made their programs look this way. I will use this tool from now on.

 

Mark