//+------------------------------------------------------------------+ //| 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;} } } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+
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;} } } } //+------------------------------------------------------------------+
Thanks Alain.
I had wondered how other users made their programs look this way. I will use this tool from now on.
Mark

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
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