//+------------------------------------------------------------------+ //| ZigZagModule.mqh | //| Copyright 2018, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #include //+------------------------------------------------------------------+ //| Class for obtaining ZigZag indicator data | //+------------------------------------------------------------------+ class CZigZagModule { protected: //--- Segment lines CChartObjectTrend m_trend_lines[]; //--- int m_copy_extremums; // Number of saved highs/lows int m_segments_total; // Number of segments int m_direction; // Direction int m_counter_lows; // Low counter int m_counter_highs; // High counter //--- Extremum prices double m_zz_low[]; double m_zz_high[]; //--- Extremum bars' indices int m_zz_low_bar[]; int m_zz_high_bar[]; //--- Extremum bars' time datetime m_zz_low_time[]; datetime m_zz_high_time[]; //--- Segment lines color color m_lines_color; //--- private: //--- Arrays for obtaining source data double m_zz_lows_temp[]; double m_zz_highs_temp[]; datetime m_zz_time_temp[]; //--- public: CZigZagModule(void); ~CZigZagModule(void); //--- Number of extremums for copying void CopyExtremums(const int total); //--- Number of (1) extremums and (2) segments copied int CopyExtremums(void) { return(m_copy_extremums); } int SegmentsTotal(void) { return(m_segments_total); } //--- Get data void GetZigZagData(const double &zz_h[],const double &zz_l[],const datetime &time[]); void GetZigZagData(const int handle,int buffer_num_highs,int buffer_num_lows, const string symbol,const ENUM_TIMEFRAMES period, const datetime start_time,const datetime stop_time); //--- Update the structure void ZeroZigZagData(void); //--- public: //--- Last segment direction int Direction(void) const { return(m_direction); } //--- Index of an extremum bar by a specified index int LowBar(const int index); int HighBar(const int index); //--- Price of extremums by a specified index double LowPrice(const int index); double HighPrice(const int index); //--- Time of an extremum bar by a specified index datetime LowTime(const int index); datetime HighTime(const int index); //--- Segment size by a specified index double SegmentSize(const int index); //--- Sum of all segments double SegmentsSum(void); //--- Sum of segments directed (1) upwards and (2) downwards double SumSegmentsUp(void); double SumSegmentsDown(void); //--- Direction of a specified segment int SegmentDirection(const int index); //--- Return the start and end bar of a specified segment bool SegmentBars(const int index,int &start_bar,int &stop_bar); //--- Return the start and end prices of a specified segment bool SegmentPrices(const int index,double &start_price,double &stop_price); //--- Return the start and end time of a specified segment bool SegmentTimes(const int index,datetime &start_time,datetime &stop_time); //--- Return the start and end time of a specified segment considering a lower timeframe bool SegmentTimes(const int handle,const int highs_buffer_index,const int lows_buffer_index, const string symbol,const ENUM_TIMEFRAMES period,const ENUM_TIMEFRAMES in_period, const int index,datetime &start_time,datetime &stop_time); //--- Percentage ratio of the segment sums to the total sum of all segments within a set double PercentSumSegmentsUp(void); double PercentSumSegmentsDown(void); //--- Difference between segment sums double PercentSumSegmentsDifference(void); //--- Number of bars in a specified segment int SegmentBars(const int index); //--- (1) Number of bars and (2) seconds in a set of segments int SegmentsTotalBars(void); long SegmentsTotalSeconds(void); //--- (1) Minimum and (2) maximum values in the set double LowMinimum(void); double HighMaximum(void); //--- Price range double PriceRange(void); //--- Smallest minimum time datetime SmallestMinimumTime(void); //--- Largest maximum time datetime LargestMaximumTime(void); //--- Smallest segment in the set double SmallestSegment(void); //--- Largest segment in the set double LargestSegment(void); //--- Smallest number of segment bars in the set int LeastNumberOfSegmentBars(void); //--- Largest number of segment bars in the set int MostNumberOfSegmentBars(void); //--- Deviation in percentage double PercentDeviation(const int index); //--- public: //--- Line color void LinesColor(const color clr) { m_lines_color=clr; } //--- (1) Display and (2) delete objects void ShowSegments(const string suffix=""); void DeleteSegments(void); //--- Comment on a chart void CommentZigZagData(); void CommentShortZigZagData(); //--- private: //--- Copy source data to the passed arrays void CopyData(const int handle,const int buffer_index,const string symbol, const ENUM_TIMEFRAMES period,datetime start_time,datetime stop_time, double &zz_array[],datetime &time_array[]); //--- Return index of the (1) minimum and (2) maximum values from the passed array int GetMinValueIndex(double &zz_lows[]); int GetMaxValueIndex(double &zz_highs[]); //--- Create objects void CreateSegment(const int segment_index,const string suffix=""); //--- Segment size to the string string SegmentSizeToString(const int index); //--- public: //--- Pattern 1 int Pattern1(const double outer_dev,const double inner_dev); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CZigZagModule::CZigZagModule(void) : m_copy_extremums(1), m_segments_total(1), m_lines_color(clrGray) { CopyExtremums(m_copy_extremums); ZeroZigZagData(); //--- Set the reverse indexation order (... 3 2 1 0) ::ArraySetAsSeries(m_zz_lows_temp,true); ::ArraySetAsSeries(m_zz_highs_temp,true); ::ArraySetAsSeries(m_zz_time_temp,true); } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CZigZagModule::~CZigZagModule(void) { } //+------------------------------------------------------------------+ //| Number of extremums for work | //+------------------------------------------------------------------+ void CZigZagModule::CopyExtremums(const int total) { if(total<1) return; //--- m_copy_extremums =total; m_segments_total =total*2-1; //--- ::ArrayResize(m_zz_low,total); ::ArrayResize(m_zz_high,total); ::ArrayResize(m_zz_low_bar,total); ::ArrayResize(m_zz_high_bar,total); ::ArrayResize(m_zz_low_time,total); ::ArrayResize(m_zz_high_time,total); ::ArrayResize(m_trend_lines,m_segments_total); } //+------------------------------------------------------------------+ //| Reset ZigZag variables | //+------------------------------------------------------------------+ void CZigZagModule::ZeroZigZagData(void) { m_counter_lows =0; m_counter_highs =0; //--- ::ArrayInitialize(m_zz_low,0); ::ArrayInitialize(m_zz_high,0); ::ArrayInitialize(m_zz_low_bar,0); ::ArrayInitialize(m_zz_high_bar,0); ::ArrayInitialize(m_zz_low_time,0); ::ArrayInitialize(m_zz_high_time,0); } //+------------------------------------------------------------------+ //| Get ZZ data from passed arrays | //+------------------------------------------------------------------+ void CZigZagModule::GetZigZagData(const double &zz_h[],const double &zz_l[],const datetime &time[]) { int h_total =::ArraySize(zz_h); int l_total =::ArraySize(zz_l); int total =h_total+l_total; //--- Reset ZZ variables ZeroZigZagData(); //--- Move along the copied ZZ values in a loop for(int i=0; i=h_total || i>=l_total) break; //--- Fill in the high value array till the necessary amount is copied if(zz_h[i]>0 && m_counter_highs0 && m_counter_lowsm_zz_low_time[0])? 1 : -1; } //+------------------------------------------------------------------+ //| Get ZZ data from passed data | //+------------------------------------------------------------------+ void CZigZagModule::GetZigZagData(const int handle,int buffer_num_highs,int buffer_num_lows, const string symbol,const ENUM_TIMEFRAMES period, const datetime start_time,const datetime stop_time) { //--- Get source data int times_total =::CopyTime(symbol,period,start_time,stop_time,m_zz_time_temp); int highs_total =::CopyBuffer(handle,buffer_num_highs,start_time,stop_time,m_zz_highs_temp); int lows_total =::CopyBuffer(handle,buffer_num_lows,start_time,stop_time,m_zz_lows_temp); //--- Maximum number of extremums int max_items =(int)::fmax((double)highs_total,(double)lows_total); //--- If not enough, try again if(times_total=max_items) break; } } //--- Counters int lows_counter =0; int highs_counter =0; //--- Calculate highs int h_total=::ArraySize(m_zz_highs_temp); for(int i=0; i0) highs_counter++; } //--- Calculate lows int l_total=::ArraySize(m_zz_lows_temp); for(int i=0; i0) lows_counter++; } //--- Get the number of extremums int copy_extremums=(int)::fmin((double)highs_counter,(double)lows_counter); CopyExtremums(copy_extremums); //--- Move along the copied ZZ values in a loop GetZigZagData(m_zz_highs_temp,m_zz_lows_temp,m_zz_time_temp); } //+------------------------------------------------------------------+ //| Low value by a specified index | //+------------------------------------------------------------------+ double CZigZagModule::LowPrice(const int index) { if(index>=::ArraySize(m_zz_low)) return(0.0); //--- return(m_zz_low[index]); } //+------------------------------------------------------------------+ //| High value by a specified index | //+------------------------------------------------------------------+ double CZigZagModule::HighPrice(const int index) { if(index>=::ArraySize(m_zz_high)) return(0.0); //--- return(m_zz_high[index]); } //+------------------------------------------------------------------+ //| Low bar number by a specified index | //+------------------------------------------------------------------+ int CZigZagModule::LowBar(const int index) { if(index>=::ArraySize(m_zz_low_bar)) return(0); //--- return(m_zz_low_bar[index]); } //+------------------------------------------------------------------+ //| High bar number by a specified index | //+------------------------------------------------------------------+ int CZigZagModule::HighBar(const int index) { if(index>=::ArraySize(m_zz_high_bar)) return(0); //--- return(m_zz_high_bar[index]); } //+------------------------------------------------------------------+ //| Low bar time by a specified index | //+------------------------------------------------------------------+ datetime CZigZagModule::LowTime(const int index) { if(index>=::ArraySize(m_zz_low_time)) return(0); //--- return(m_zz_low_time[index]); } //+------------------------------------------------------------------+ //| High bar time by a specified index | //+------------------------------------------------------------------+ datetime CZigZagModule::HighTime(const int index) { if(index>=::ArraySize(m_zz_high_time)) return(0); //--- return(m_zz_high_time[index]); } //+------------------------------------------------------------------+ //| Return segment size by index | //+------------------------------------------------------------------+ double CZigZagModule::SegmentSize(const int index) { if(index>=m_segments_total) return(-1); //--- double size=0; //--- In case of an even number if(index%2==0) { int i=index/2; size=::fabs(m_zz_high[i]-m_zz_low[i]); } //--- In case of an odd number else { int l=0,h=0; //--- if(Direction()>0) { h=(index-1)/2+1; l=(index-1)/2; } else { h=(index-1)/2; l=(index-1)/2+1; } //--- size=::fabs(m_zz_high[h]-m_zz_low[l]); } //--- return(size); } //+------------------------------------------------------------------+ //| Sum of all segments | //+------------------------------------------------------------------+ double CZigZagModule::SegmentsSum(void) { double sum=0.0; //--- for(int i=0; i0) sum+=::fabs(m_zz_high[i]-m_zz_low[i]); else { if(i>0) sum+=::fabs(m_zz_high[i-1]-m_zz_low[i]); } } //--- return(sum); } //+------------------------------------------------------------------+ //| Return the size of all downward segments | //+------------------------------------------------------------------+ double CZigZagModule::SumSegmentsDown(void) { double sum=0.0; //--- for(int i=0; i0) sum+=::fabs(m_zz_high[i]-m_zz_low[i-1]); } } //--- return(sum); } //+------------------------------------------------------------------+ //| Direction of a specified segment | //+------------------------------------------------------------------+ int CZigZagModule::SegmentDirection(const int index) { return((index%2==0)? Direction() : -Direction()); } //+------------------------------------------------------------------+ //| Return the start and end bar of a specified segment | //+------------------------------------------------------------------+ bool CZigZagModule::SegmentBars(const int index,int &start_bar,int &stop_bar) { if(index>=m_segments_total) return(false); //--- In case of an even number if(index%2==0) { int i=index/2; //--- start_bar =(Direction()>0)? m_zz_low_bar[i] : m_zz_high_bar[i]; stop_bar =(Direction()>0)? m_zz_high_bar[i] : m_zz_low_bar[i]; } //--- In case of an odd number else { int l=0,h=0; //--- if(Direction()>0) { h=(index-1)/2+1; l=(index-1)/2; //--- start_bar =m_zz_high_bar[h]; stop_bar =m_zz_low_bar[l]; } else { h=(index-1)/2; l=(index-1)/2+1; //--- start_bar =m_zz_low_bar[l]; stop_bar =m_zz_high_bar[h]; } } //--- return(true); } //+------------------------------------------------------------------+ //| Return the start and end prices of a specified segment | //+------------------------------------------------------------------+ bool CZigZagModule::SegmentPrices(const int index,double &start_price,double &stop_price) { if(index>=m_segments_total) return(false); //--- In case of an even number if(index%2==0) { int i=index/2; //--- start_price =(Direction()>0)? m_zz_low[i] : m_zz_high[i]; stop_price =(Direction()>0)? m_zz_high[i] : m_zz_low[i]; } //--- In case of an odd number else { int l=0,h=0; //--- if(Direction()>0) { h=(index-1)/2+1; l=(index-1)/2; //--- start_price =m_zz_high[h]; stop_price =m_zz_low[l]; } else { h=(index-1)/2; l=(index-1)/2+1; //--- start_price =m_zz_low[l]; stop_price =m_zz_high[h]; } } //--- return(true); } //+------------------------------------------------------------------+ //| Return the start and end time of a segment | //+------------------------------------------------------------------+ bool CZigZagModule::SegmentTimes(const int index,datetime &start_time,datetime &stop_time) { if(index>=m_segments_total) { Print(__FUNCTION__," > index: ",index,"; m_segments_total: ",m_segments_total); return(false); } //--- In case of an even number if(index%2==0) { int i=index/2; //--- start_time =(Direction()>0)? m_zz_low_time[i] : m_zz_high_time[i]; stop_time =(Direction()>0)? m_zz_high_time[i] : m_zz_low_time[i]; } //--- In case of an odd number else { int l=0,h=0; //--- if(Direction()>0) { h=(index-1)/2+1; l=(index-1)/2; //--- start_time =m_zz_high_time[h]; stop_time =m_zz_low_time[l]; } else { h=(index-1)/2; l=(index-1)/2+1; //--- start_time =m_zz_low_time[l]; stop_time =m_zz_high_time[h]; } } //--- return(true); } //+------------------------------------------------------------------+ //| Return the start and end time of a specified segment | //| considering a lower timeframe | //+------------------------------------------------------------------+ bool CZigZagModule::SegmentTimes(const int handle,const int highs_buffer_index,const int lows_buffer_index, const string symbol,const ENUM_TIMEFRAMES period,const ENUM_TIMEFRAMES in_period, const int index,datetime &start_time,datetime &stop_time) { //--- Get time without considering the current timeframe datetime l_start_time =NULL; datetime l_stop_time =NULL; if(!SegmentTimes(index,l_start_time,l_stop_time)) return(false); //--- double zz_lows[]; double zz_highs[]; datetime zz_lows_time[]; datetime zz_highs_time[]; datetime start =NULL; datetime stop =NULL; int period_seconds=::PeriodSeconds(period); //--- Get source data in case of an upward direction if(SegmentDirection(index)>0) { //--- Data on the higher timeframe's first bar start =l_start_time; stop =l_start_time+period_seconds; CopyData(handle,lows_buffer_index,symbol,in_period,start,stop,zz_lows,zz_lows_time); //--- Data on the higher timeframe's last bar start =l_stop_time; stop =l_stop_time+period_seconds; CopyData(handle,highs_buffer_index,symbol,in_period,start,stop,zz_highs,zz_highs_time); } //--- Get source data in case of a downward direction else { //--- Data on the higher timeframe's first bar start =l_start_time; stop =l_start_time+period_seconds; CopyData(handle,highs_buffer_index,symbol,in_period,start,stop,zz_highs,zz_highs_time); //--- Data on the higher timeframe's last bar start =l_stop_time; stop =l_stop_time+period_seconds; CopyData(handle,lows_buffer_index,symbol,in_period,start,stop,zz_lows,zz_lows_time); } //--- Search for a high (maximum value) index int max_index=GetMaxValueIndex(zz_highs); //--- Search for a low (minimum value) index int min_index=GetMinValueIndex(zz_lows); //--- if(min_index>=::ArraySize(zz_lows_time) || max_index>=::ArraySize(zz_highs_time)) return(false); //--- Get segment start and end time start_time =(SegmentDirection(index)>0)? zz_lows_time[min_index] : zz_highs_time[max_index]; stop_time =(SegmentDirection(index)>0)? zz_highs_time[max_index] : zz_lows_time[min_index]; //--- Successful return(true); } //+------------------------------------------------------------------+ //| Copy source data to the passed arrays | //+------------------------------------------------------------------+ void CZigZagModule::CopyData(const int handle,const int buffer_index,const string symbol, const ENUM_TIMEFRAMES period,datetime start_time,datetime stop_time, double &zz_array[],datetime &time_array[]) { ::CopyBuffer(handle,buffer_index,start_time,stop_time,zz_array); ::CopyTime(symbol,period,start_time,stop_time,time_array); } //+------------------------------------------------------------------+ //| Return a high index from the passed array | //+------------------------------------------------------------------+ int CZigZagModule::GetMaxValueIndex(double &zz_highs[]) { int max_index =0; double max_value =0; int total=::ArraySize(zz_highs); for(int i=0; i0) { if(zz_highs[i]>max_value) { max_index =i; max_value =zz_highs[i]; } } } //--- return(max_index); } //+------------------------------------------------------------------+ //| Return a low index from the passed array | //+------------------------------------------------------------------+ int CZigZagModule::GetMinValueIndex(double &zz_lows[]) { int min_index =0; double min_value =INT_MAX; int total=::ArraySize(zz_lows); for(int i=0; i0) { if(zz_lows[i]=m_copy_extremums*2-1) return(-1); //--- int bars=0; //--- In case of an even number if(index%2==0) { int i=index/2; bars=int(::fabs(m_zz_high_bar[i]-m_zz_low_bar[i])); } //--- In case of an odd number else { int l=0,h=0; //--- if(Direction()>0) { h=(index-1)/2+1; l=(index-1)/2; } else { h=(index-1)/2; l=(index-1)/2+1; } //--- bars=int(::fabs(m_zz_high_bar[h]-m_zz_low_bar[l])); } //--- return(bars); } //+------------------------------------------------------------------+ //| Number of bars of all segments | //+------------------------------------------------------------------+ int CZigZagModule::SegmentsTotalBars(void) { int begin =0; int end =0; int l =m_copy_extremums-1; //--- begin =(m_zz_high_bar[l]>m_zz_low_bar[l])? m_zz_high_bar[l] : m_zz_low_bar[l]; end =(m_zz_high_bar[0]>m_zz_low_bar[0])? m_zz_low_bar[0] : m_zz_high_bar[0]; //--- return(begin-end); } //+------------------------------------------------------------------+ //| Number of seconds of all segments | //+------------------------------------------------------------------+ long CZigZagModule::SegmentsTotalSeconds(void) { datetime begin =NULL; datetime end =NULL; int l=m_copy_extremums-1; //--- begin =(m_zz_high_time[l]max_size)? size : max_size; } //--- return(max_size); } //+------------------------------------------------------------------+ //| Smallest number of segment bars in the set | //+------------------------------------------------------------------+ int CZigZagModule::LeastNumberOfSegmentBars(void) { int min_bars=0; for(int i=0; imax_bars)? bars : max_bars; } //--- return(max_bars); } //+------------------------------------------------------------------+ //| Deviation in percentage | //+------------------------------------------------------------------+ double CZigZagModule::PercentDeviation(const int index) { return(SegmentSize(index)/SegmentSize(index+1)*100); } //+------------------------------------------------------------------+ //| Show ZZ segments on a chart | //+------------------------------------------------------------------+ void CZigZagModule::ShowSegments(const string suffix="") { DeleteSegments(); for(int i=0; i=m_segments_total) return; //--- double hp=0.0,lp=0.0; datetime hd=NULL,ld=NULL; //--- In case of an even number if(segment_index%2==0) { int i=segment_index/2; hp =m_zz_high[i]; lp =m_zz_low[i]; hd =m_zz_high_time[i]; ld =m_zz_low_time[i]; } //--- In case of an odd number else { int h=0,l=0; if(Direction()>0) { h=(segment_index-1)/2+1; l=(segment_index-1)/2; } else { h=(segment_index-1)/2; l=(segment_index-1)/2+1; } //--- hp =m_zz_high[h]; lp =m_zz_low[l]; hd =m_zz_high_time[h]; ld =m_zz_low_time[l]; } //--- Set objects long id=::ChartID(); string name="zz_"+string(id)+"_"+string(segment_index)+suffix; //--- If an object is already present, simply update its location if(::ObjectFind(id,name)>=0) { ::ObjectSetDouble(id,name,OBJPROP_PRICE,0,hp); ::ObjectSetDouble(id,name,OBJPROP_PRICE,1,lp); ::ObjectSetInteger(id,name,OBJPROP_TIME,0,hd); ::ObjectSetInteger(id,name,OBJPROP_TIME,1,ld); } //--- Create a new object else { m_trend_lines[segment_index].Create(id,name,0,hd,hp,ld,lp); m_trend_lines[segment_index].Background(false); m_trend_lines[segment_index].Width(2); m_trend_lines[segment_index].Color(m_lines_color); m_trend_lines[segment_index].Style(STYLE_SOLID); m_trend_lines[segment_index].Description("zz: "+string(segment_index)); } } //+------------------------------------------------------------------+ //| Display ZigZag data in a chart comment | //+------------------------------------------------------------------+ void CZigZagModule::CommentZigZagData(void) { string comment="Current direction : "+string(m_direction)+"\n"+ "Copy extremums: "+string(m_copy_extremums)+"\n"+ "SegmentSize(0): "+::DoubleToString(SegmentSize(0),_Digits)+ "\n---\n"+ "HighPrice(0): "+::DoubleToString(HighPrice(0),_Digits)+"\n"+ "LowPrice(0): "+::DoubleToString(LowPrice(0),_Digits)+ "\n---\n"+ "HighBar(0): "+string(HighBar(0))+"\n"+ "LowBar(0): "+string(LowBar(0))+ "\n---\n"+ "HighTime(0): "+::TimeToString(HighTime(0),TIME_DATE|TIME_MINUTES)+"\n"+ "LowTime(0): "+::TimeToString(LowTime(0),TIME_DATE|TIME_MINUTES)+ "\n---\n"+ "SegmentsTotalBars(): "+string(SegmentsTotalBars())+"\n"+ "SegmentsTotalSeconds(): "+string(SegmentsTotalSeconds())+"\n"+ "SegmentsTotalMinutes(): "+string(SegmentsTotalSeconds()/60)+"\n"+ "SegmentsTotalHours(): "+string(SegmentsTotalSeconds()/60/60)+"\n"+ "SegmentsTotalDays(): "+string(SegmentsTotalSeconds()/60/60/24)+ "\n---\n"+ "LowMinimum(): "+::DoubleToString(LowMinimum(),_Digits)+"\n"+ "HighMaximum(): "+::DoubleToString(HighMaximum(),_Digits)+"\n"+ "PriceRange(): "+::DoubleToString(PriceRange(),_Digits)+ "\n---\n"+ "SegmentsSum(): "+::DoubleToString(SegmentsSum()/_Point,0)+"\n"+ "SegmentsSumUp(): "+::DoubleToString(SumSegmentsUp()/_Point,0)+"\n"+ "SegmentsSumDown(): "+::DoubleToString(SumSegmentsDown()/_Point,0)+ "\n---\n"+ "PercentSumUp(): "+::DoubleToString(SumSegmentsUp()/SegmentsSum()*100,2)+"\n"+ "PercentSumDown(): "+::DoubleToString(SumSegmentsDown()/SegmentsSum()*100,2)+"\n"+ "PercentDifference(): "+::DoubleToString(PercentSumSegmentsDifference(),2); //--- if(m_copy_extremums>1) { comment+="\n---\n"; for(int i=0; i Insufficient segments for defining a pattern! A minimum of 4 (5) segments (3 high/low extremums) required."); return(0); } //--- if(SegmentSize(1)<=0 || SegmentSize(2)<=0 || SegmentSize(3)<=0) return(0); //--- bool condition1=::fabs(SegmentSize(0)/SegmentSize(1)*100-100) > outer_dev; bool condition2=::fabs(SegmentSize(2)/SegmentSize(3)*100-100) > outer_dev; bool condition3=::fabs(SegmentSize(1)/SegmentSize(2)*100-100) < inner_dev; //--- if(m_direction<0) { bool condition4=m_zz_low[0]>> BUY SIGNAL"); return(1); } } else if(m_direction>0) { bool condition4=m_zz_high[0]>m_zz_high[1] && m_zz_high[2]>m_zz_high[1]; //--- if(condition1 && condition2 && condition3 && condition4) { ::Print(__FUNCTION__,"(): >>> SELL SIGNAL"); return(-1); } } //--- return(0); } //+------------------------------------------------------------------+