Any questions from newcomers on MQL4 and MQL5, help and discussion on algorithms and codes - page 745

 

Is it possible to hide all reversal level bands in the indicator, not tested and the rest, and leave only tested ones, i.e. hide extern bool zone_show_weak = true; and below in the code if (zone_strength[i] == ZONE_WEAK && zone_show_weak == false) and others cannot be hidden, I tried to set them all to black, but then if they are not there, they prevent you from seeing the price on the chart in a vertical scale. Maybe someone understands and corrects the code or removes the levels that I described above. Indicator code:

#property copyright "Copyright © 2017 Andrew Sumner"

#property link ""

#property indicator_chart_window

#property indicator_buffers 4

#property indicator_color1 Red

#property indicator_color2 Red

#property indicator_color3 DodgerBlue

#property indicator_color4 DodgerBlue


extern int BackLimit = 300; //Back - back

extern int TimeFrame = 0;

extern string TimeString = "0=Current, 60=H1, 240=H4, 1440=Day, 10080=Week, 43200=Month";


extern color color_support_weak = MediumAquamarine; //support - support for weak DarkSlateGray

extern color color_support_untested = SeaGreen; // unchecked

extern color color_support_verified = Green;

extern color color_support_proven = LimeGreen;

extern color color_support_turncoat = Olive Drab;

extern color color_resist_weak = Sienna;

extern color color_resist_untested = Orchid;

extern color color_resist_verified = Crimson;

extern color color_resist_proven = Red;

extern color color_resist_turncoat = DarkOrange;


extern bool zone_show_weak = true;

extern double zone_fuzzfactor = 0.2;

extern bool zone_solid = false; // true if false, there will be not full stripe zones, but framed by a rectangle with width width

extern int zone_linewidth = 2;

extern int zone_style = 0;

extern bool zone_show_info = true;

extern int zone_label_shift = 22; // horizontal offset of labels, but only after removing the indicator

extern bool zone_show_alerts = false;

extern bool zone_alert_popups = true;

extern bool zone_alert_sounds = true;

extern bool send_email = false;

extern int zone_alert_waitseconds = 300;

extern bool zone_merge = true;

extern bool zone_extend = true;


extern bool fractals_show = false;

extern double fractal_fast_factor = 3.0;

extern double fractal_slow_factor = 6.0;

extern bool SetGlobals = true;


double FastDnPts[], FastUpPts[];

double SlowDnPts[], SlowUpPts[];


double zone_hi[1000], zone_lo[1000];

int zone_start[1000], zone_hits[1000], zone_type[1000], zone_strength[1000], zone_count = 0;

boolzone_turn[1000];


#define ZONE_SUPPORT 1

#define ZONE_RESIST 2


#define ZONE_WEAK 0

#define ZONE_TURNCOAT 1

#define ZONE_UNTESTED 2

#define ZONE_VERIFIED 3

#define ZONE_PROVEN 4


#define UP_POINT 1

#define DN_POINT -1


int time_offset = 0;


int init()

{

IndicatorBuffers(4);


SetIndexBuffer(0, SlowDnPts);

SetIndexBuffer(1, SlowUpPts);

SetIndexBuffer(2, FastDnPts);

SetIndexBuffer(3, FastUpPts);


if (fractals_show == true)

{

SetIndexStyle(0, DRAW_ARROW, 0, 3);

SetIndexStyle(1, DRAW_ARROW, 0, 3);

SetIndexStyle(2, DRAW_ARROW, 0, 1);

SetIndexStyle(3, DRAW_ARROW, 0, 1);

SetIndexArrow(0, 218);

SetIndexArrow(1, 217);

SetIndexArrow(2, 218);

SetIndexArrow(3, 217);

}

else

{

SetIndexStyle(0, DRAW_NONE);

SetIndexStyle(1, DRAW_NONE);

SetIndexStyle(2, DRAW_NONE);

SetIndexStyle(3, DRAW_NONE);

}


if (TimeFrame != 1 && TimeFrame != 5 && TimeFrame != 15 &&

TimeFrame != 60 && TimeFrame != 240 && TimeFrame != 1440 &&

TimeFrame != 10080 && TimeFrame != 43200)

time frame = 0;


if(TimeFrame < Period())

timeframe = period();


return(0);

}


int deinit()

{

DeleteZones();

DeleteGlobalVars();

return(0);

}


int start()

{

if (NewBar() == true)

{

int old_zone_count = zone_count;


Fast Fractals();

SlowFractals();

DeleteZones();

FindZones();

DrawZones();

if (zone_count < old_zone_count)

DeleteOldGlobalVars(old_zone_count);

}


if (zone_show_info == true)

{

for (int i=0; i<zone_count; i++)

{

string lbl;

if (zone_strength[i] == ZONE_PROVEN)

lbl=""; // Proven

else if (zone_strength[i] == ZONE_VERIFIED)

lbl=""; // Checked

else if (zone_strength[i] == ZONE_UNTESTED)

lbl=""; // NOT test

else if (zone_strength[i] == ZONE_TURNCOAT)

lbl=""; // Reversal

else

lbl=""; // Weak


if (zone_type[i] == ZONE_SUPPORT)

lbl = lbl + "under"; //Support

else

lbl = lbl + "sop"; //Resistance


if (zone_hits[i] > 0 && zone_strength[i] > ZONE_UNTESTED)

{

if (zone_hits[i] == 1)

lbl = lbl + ",T=" + zone_hits[i]; //Test Count

else

lbl = lbl + ",T=" + zone_hits[i]; //Test Count

}


int adjust_hpos;

int wbpc = WindowBarsPerChart();

int k;

k = Period() * 60 + (20 + StringLen(lbl));

if (wbpc < 80)

adjust_hpos = Time[0] + k * 4;

else if (wbpc < 125)

adjust_hpos = Time[0] + k * 8;

else if (wbpc < 250)

adjust_hpos = Time[0] + k * 15;

else if (wbpc < 480)

adjust_hpos = Time[0] + k * 29;

else if (wbpc < 950)

adjust_hpos = Time[0] + k * 58;

else

adjust_hpos = Time[0] + k * 115;


int shift = k * zone_label_shift;

double vpos = zone_hi[i] - (zone_hi[i] - zone_lo[i]) / 2;


// Text of level descriptions

string s = "SSSR#"+i+"LBL";

ObjectCreate(s, OBJ_TEXT, 0, 0, 0);

ObjectSet(s, OBJPROP_TIME1, adjust_hpos + shift);

ObjectSet(s, OBJPROP_PRICE1, vpos);

ObjectSetText(s, StringRightPad(lbl, 36, " "), 11, "Courier New",clrWhite); //Black

}

}


CheckAlerts();


return(0);

}


void CheckAlerts()

{

static int lastalert = 0;


if (zone_show_alerts == false)

return;


if (Time[0] - lastalert > zone_alert_waitseconds)

if (CheckEntryAlerts() == true)

lastalert = Time[0];

}


bool CheckEntryAlerts()

{

// check entries

for (int i=0; i<zone_count; i++)

{

if (Close[0] >= zone_lo[i] && Close[0] < zone_hi[i])

{

if (zone_show_alerts == true)

{

if (zone_alert_popups == true)

{

if (zone_type[i] == ZONE_SUPPORT)

Alert(Symbol() + TimeFrameToString(TimeFrame) + ": Support Zone Entered"); //Introduced support zone

else

Alert(Symbol() + TimeFrameToString(TimeFrame) + ": Resistance Zone Entered"); //Introduced resistance zone

}


if (zone_alert_sounds == true)

PlaySound("alert.wav");

}

if (send_email == true)

{

string dir = "";

string msg = StringConcatenate(Symbol(), "-", TimeFrameToString(TimeFrame), " at ", TimeToStr(Time[0], TIME_DATE|TIME_SECONDS),

" ", dir, "Zone Entered");

if (zone_type[i] == ZONE_SUPPORT)

{

dir = "Support";

SendMail("SS_SupRes_v04c alert", msg);

}

else

{

dir="resistance";

SendMail("SS_SupRes_v04c alert", msg);

}

}

return(true);

}

}


return(false);

}


void DeleteGlobalVars()

{

if(SetGlobals==false)

return;


GlobalVariableDel("SSSR_Count_"+Symbol()+TimeFrame);

GlobalVariableDel("SSSR_Updated_"+Symbol()+TimeFrame);


int old_count = zone_count;

zone_count = 0;

DeleteOldGlobalVars(old_count);

}


void DeleteOldGlobalVars(int old_count)

{

if(SetGlobals==false)

return;


for (int i=zone_count; i<old_count; i++)

{

GlobalVariableDel("SSSR_HI_"+Symbol()+TimeFrame+i);

GlobalVariableDel("SSSR_LO_"+Symbol()+TimeFrame+i);

GlobalVariableDel("SSSR_HITS_"+Symbol()+TimeFrame+i);

GlobalVariableDel("SSSR_STRENGTH_"+Symbol()+TimeFrame+i);

GlobalVariableDel("SSSR_AGE_"+Symbol()+TimeFrame+i);

}

}


void FindZones()

{

int i, j, shift, bustcount=0, testcount = 0;

double hival, loval;

bool turned = false, hasturned = false;


double temp_hi[1000], temp_lo[1000];

int temp_start[1000], temp_hits[1000], temp_strength[1000], temp_count = 0;

bool temp_turn[1000], temp_merge[1000];

int merge1[1000], merge2[1000], merge_count = 0;


// loop through zones from oldest to smallest (ignore the last 5 bars),

// finding those who survived to the present...

for (shift=MathMin(iBars(NULL, TimeFrame)-1, BackLimit); shift>5; shift--)

{

double atr = iATR(NULL, TimeFrame, 7, shift);

double fu = atr/2 * zone_fuzzfactor;

bool isWeak;

bool touchOk = false;

bool isBust = false;

double close = iClose(NULL, TimeFrame, shift);

double high = iHigh(NULL, TimeFrame, shift);

double low = iLow(NULL, TimeFrame, shift);

double hi_i;

double lo_i;


if (FastUpPts[shift] > 0.001)

{

// high point zigzag

isWeak = true;

if (SlowUpPts[shift] > 0.001)

isWeak = false;


hival=high;

if (zone_extend == true)

hival += fu;


loval = MathMax(MathMin(close, high-fu), high-fu*2);

turn=false;

hasturned=false;

isbust=false;


buscount = 0;

testcount = 0;


for (i=shift-1; i>=0; i--)

{

hi_i = iHigh(NULL, TimeFrame, i);

lo_i = iLow(NULL, TimeFrame, i);


if ((turned == false && FastUpPts[i] >= loval && FastUpPts[i] <= hival) ||

(turned == true && FastDnPts[i] <= hival && FastDnPts[i] >= loval))

{

// Potential touch, just make sure it's been 10+ candles since last

touchOk = true;

for (j=i+1; j<i+11; j++)

{

if ((turned == false && FastUpPts[j] >= loval && FastUpPts[j] <= hival) ||

(turned == true && FastDnPts[j] <= hival && FastDnPts[j] >= loval))

{

touchOk = false;

break;

}

}


if (touchOk == true)

{

// we have a touch. If it was busted once, remove the bustcount

// since we know this level is still valid and just switched sides

buscount = 0;

testcount++;

}

}


if ((turned == false && hi_i > hival) ||

(turned == true && lo_i < loval))

{

// this level has been busted at least once

bustcount++;


if (bustcount > 1 || isWeak == true)

{

// two or more

isBust = true;

break;

}


if (turned == true)

turn=false;

else if (turned == false)

turn=true;


hasturned = true;


// forget previous hits

testcount = 0;

}

}


if(isBust==false)

{

// level is still valid, add to our list

temp_hi[temp_count] = hival;

temp_lo[temp_count] = loval;

temp_turn[temp_count] = hasturned;

temp_hits[temp_count] = testcount;

temp_start[temp_count] = shift;

temp_merge[temp_count] = false;

if (testcount > 3)

temp_strength[temp_count] = ZONE_PROVEN;

else if (testcount > 0)

temp_strength[temp_count] = ZONE_VERIFIED;

else if (hasturned == true)

temp_strength[temp_count] = ZONE_TURNCOAT;

else if (isWeak == false)

temp_strength[temp_count] = ZONE_UNTESTED;

else

temp_strength[temp_count] = ZONE_WEAK;


temp_count++;

}

}

else if (FastDnPts[shift] > 0.001)

{

// low zigzag point

isWeak = true;

if (SlowDnPts[shift] > 0.001)

isWeak = false;


loval = low;

if (zone_extend == true)

loval = fu;


hival = MathMin(MathMax(close, low+fu), low+fu*2);

turn=false;

hasturned=false;


buscount = 0;

testcount = 0;

isbust=false;


for (i=shift-1; i>=0; i--)

{

hi_i = iHigh(NULL, TimeFrame, i);

lo_i = iLow(NULL, TimeFrame, i);


if ((turned == true && FastUpPts[i] >= loval && FastUpPts[i] <= hival) ||

(turned == false && FastDnPts[i] <= hival && FastDnPts[i] >= loval))

{

// Potential touch, just make sure it's been 10+ candles since last

touchOk = true;

for (j=i+1; j<i+11; j++)

{

if ((turned == true && FastUpPts[j] >= loval && FastUpPts[j] <= hival) ||

(turned == false && FastDnPts[j] <= hival && FastDnPts[j] >= loval))

{

touchOk = false;

break;

}

}


if (touchOk == true)

{

// we have a touch. If it was busted once, remove the bustcount

// since we know this level is still valid and just switched sides

buscount = 0;

testcount++;

}

}


if ((turned == true && hi_i > hival) ||

(turned == false && lo_i < loval))

{

// this level has been busted at least once

bustcount++;


if (bustcount > 1 || isWeak == true)

{

// two or more

isBust = true;

break;

}


if (turned == true)

turn=false;

else if (turned == false)

turn=true;


hasturned = true;


// forget previous hits

testcount = 0;

}

}


if(isBust==false)

{

// level is still valid, add to our list

temp_hi[temp_count] = hival;

temp_lo[temp_count] = loval;

temp_turn[temp_count] = hasturned;

temp_hits[temp_count] = testcount;

temp_start[temp_count] = shift;

temp_merge[temp_count] = false;


if (testcount > 3)

temp_strength[temp_count] = ZONE_PROVEN;

else if (testcount > 0)

temp_strength[temp_count] = ZONE_VERIFIED;

else if (hasturned == true)

temp_strength[temp_count] = ZONE_TURNCOAT;

else if (isWeak == false)

temp_strength[temp_count] = ZONE_UNTESTED;

else

temp_strength[temp_count] = ZONE_WEAK;


temp_count++;

}

}

}


// look for overlapping zones...

if (zone_merge == true)

{

merge_count = 1;

int iterations = 0;

while (merge_count > 0 && iterations < 3)

{

merge_count = 0;

iterations++;


for (i = 0; i < temp_count; i++)

temp_merge[i] = false;


for (i = 0; i < temp_count-1; i++)

{

if (temp_hits[i] == -1 || temp_merge[j] == true)

continue;


for (j = i+1; j < temp_count; j++)

{

if (temp_hits[j] == -1 || temp_merge[j] == true)

continue;


if ((temp_hi[i] >= temp_lo[j] && temp_hi[i] <= temp_hi[j]) ||

(temp_lo[i] <= temp_hi[j] && temp_lo[i] >= temp_lo[j]) ||

(temp_hi[j] >= temp_lo[i] && temp_hi[j] <= temp_hi[i]) ||

(temp_lo[j] <= temp_hi[i] && temp_lo[j] >= temp_lo[i]))

{

merge1[merge_count] = i;

merge2[merge_count] = j;

temp_merge[i] = true;

temp_merge[j] = true;

merge_count++;

}

}

}


// ... and combine them ...

for (i=0; i<merge_count; i++)

{

int target = merge1[i];

int source = merge2[i];


temp_hi[target] = MathMax(temp_hi[target], temp_hi[source]);

temp_lo[target] = MathMin(temp_lo[target], temp_lo[source]);

temp_hits[target] += temp_hits[source];

temp_start[target] = MathMax(temp_start[target], temp_start[source]);

temp_strength[target] = MathMax(temp_strength[target], temp_strength[source]);

if (temp_hits[target] > 3)

temp_strength[target] = ZONE_PROVEN;


if (temp_hits[target] == 0 && temp_turn[target] == false)

{

temp_hits[target] = 1;

if (temp_strength[target] < ZONE_VERIFIED)

temp_strength[target] = ZONE_VERIFIED;

}


if (temp_turn[target] == false || temp_turn[source] == false)

temp_turn[target] = false;

if (temp_turn[target] == true)

temp_hits[target] = 0;


temp_hits[source] = -1;

}

}

}


// copy the rest of the list to our official zones

zone_count = 0;

for (i=0; i<temp_count; i++)

{

if (temp_hits[i] >= 0 && zone_count < 1000)

{

zone_hi[zone_count] = temp_hi[i];

zone_lo[zone_count] = temp_lo[i];

zone_hits[zone_count] = temp_hits[i];

zone_turn[zone_count] = temp_turn[i];

zone_start[zone_count] = temp_start[i];

zone_strength[zone_count] = temp_strength[i];

if (zone_hi[zone_count] < Close[4])

zone_type[zone_count] = ZONE_SUPPORT;

else if (zone_lo[zone_count] > Close[4])

zone_type[zone_count] = ZONE_RESIST;

else

{

for (j=5; j<1000; j++)

{

if (iClose(NULL, TimeFrame, j) < zone_lo[zone_count])

{

zone_type[zone_count] = ZONE_RESIST;

break;

}

else if (iClose(NULL, TimeFrame, j) > zone_hi[zone_count])

{

zone_type[zone_count] = ZONE_SUPPORT;

break;

}

}


if (j == 1000)

zone_type[zone_count] = ZONE_SUPPORT;

}


zone_count++;

}

}

}


void DrawZones()

{

if(SetGlobals==true)

{

GlobalVariableSet("SSSR_Count_"+Symbol()+TimeFrame, zone_count);

GlobalVariableSet("SSSR_Updated_"+Symbol()+TimeFrame, TimeCurrent());

}


for (int i=0; i<zone_count; i++)

{

if (zone_strength[i] == ZONE_WEAK && zone_show_weak == false)

continue;


string s = "SSSR#"+i+" Strength=";

if (zone_strength[i] == ZONE_PROVEN)

s = s + "Proven, Test Count=" + zone_hits[i];

else if (zone_strength[i] == ZONE_VERIFIED)

s = s + "Verified, Test Count=" + zone_hits[i];

else if (zone_strength[i] == ZONE_UNTESTED)

s = s + "Untested";

else if (zone_strength[i] == ZONE_TURNCOAT)

s = s + "Turncoat";

else

s = s + "weak";


ObjectCreate(s, OBJ_RECTANGLE , 0, 0, 0, 0, 0);

ObjectSet(s, OBJPROP_TIME1, iTime(NULL, TimeFrame, zone_start[i]));

ObjectSet(s, OBJPROP_TIME2, TimeCurrent());

ObjectSet(s, OBJPROP_PRICE1, zone_hi[i]);

ObjectSet(s, OBJPROP_PRICE2, zone_lo[i]);

ObjectSet(s, OBJPROP_BACK, zone_solid);

ObjectSet(s, OBJPROP_WIDTH, zone_linewidth);

ObjectSet(s, OBJPROP_STYLE, zone_style);


if (zone_type[i] == ZONE_SUPPORT)

{

// support zone

if (zone_strength[i] == ZONE_TURNCOAT)

ObjectSet(s, OBJPROP_COLOR, color_support_turncoat);

else if (zone_strength[i] == ZONE_PROVEN)

ObjectSet(s, OBJPROP_COLOR, color_support_proven);

else if (zone_strength[i] == ZONE_VERIFIED)

ObjectSet(s, OBJPROP_COLOR, color_support_verified);

else if (zone_strength[i] == ZONE_UNTESTED)

ObjectSet(s, OBJPROP_COLOR, color_support_untested);

else

ObjectSet(s, OBJPROP_COLOR, color_support_weak);

}

else

{

// resistance zone

if (zone_strength[i] == ZONE_TURNCOAT)

ObjectSet(s, OBJPROP_COLOR, color_resist_turncoat);

else if (zone_strength[i] == ZONE_PROVEN)

ObjectSet(s, OBJPROP_COLOR, color_resist_proven);

else if (zone_strength[i] == ZONE_VERIFIED)

ObjectSet(s, OBJPROP_COLOR, color_resist_verified);

else if (zone_strength[i] == ZONE_UNTESTED)

ObjectSet(s, OBJPROP_COLOR, color_resist_untested);

else

ObjectSet(s, OBJPROP_COLOR, color_resist_weak);

}




if(SetGlobals==true)

{

GlobalVariableSet("SSSR_HI_"+Symbol()+TimeFrame+i, zone_hi[i]);

GlobalVariableSet("SSSR_LO_"+Symbol()+TimeFrame+i, zone_lo[i]);

GlobalVariableSet("SSSR_HITS_"+Symbol()+TimeFrame+i, zone_hits[i]);

GlobalVariableSet("SSSR_STRENGTH_"+Symbol()+TimeFrame+i, zone_strength[i]);

GlobalVariableSet("SSSR_AGE_"+Symbol()+TimeFrame+i, zone_start[i]);

}

}

}


bool Fractal(int M, int P, int shift)

{

if (TimeFrame > P)

P = timeframe;

P = P / TimeFrame*2 + MathCeil(P / TimeFrame / 2);

if(shift<p)

return(false);


if (shift > iBars(Symbol(), TimeFrame)-P)

return(false);

for (int i=1; i<=P; i++)

{

if (M == UP_POINT)

{

if (iHigh(NULL, TimeFrame, shift+i) > iHigh(NULL, TimeFrame, shift))

return(false);

if (iHigh(NULL, TimeFrame, shift-i) >= iHigh(NULL, TimeFrame, shift))

return(false);

}

if (M == DN_POINT)

{

if (iLow(NULL, TimeFrame, shift+i) < iLow(NULL, TimeFrame, shift))

return(false);

if (iLow(NULL, TimeFrame, shift-i) <= iLow(NULL, TimeFrame, shift))

return(false);

}

}

return(true);

}


void FastFractals()

{

int-shift;

int limit = MathMin(Bars-1, BackLimit);

int P = TimeFrame * fractal_fast_factor;


FastUpPts[0] = 0.0; FastUpPts[1] = 0.0;

FastDnPts[0] = 0.0; FastDnPts[1] = 0.0;


for (shift=limit; shift>1; shift--)

{

if (Fractal(UP_POINT, P, shift) == true)

FastUpPts[shift] = iHigh(NULL, TimeFrame, shift);

else

FastUpPts[shift] = 0.0;


if (Fractal(DN_POINT, P, shift) == true)

FastDnPts[shift] = iLow(NULL, TimeFrame, shift);

else

FastDnPts[shift] = 0.0;

}

}


void SlowFractals()

{

int-shift;

int limit = MathMin(iBars(Symbol(), TimeFrame) - 1, BackLimit);

int P = TimeFrame * fractal_slow_factor;


SlowUpPts[0] = 0.0; SlowUpPts[1] = 0.0;

SlowDnPts[0] = 0.0; SlowDnPts[1] = 0.0;


for (shift=limit; shift>1; shift--)

{

if (Fractal(UP_POINT, P, shift) == true)

SlowUpPts[shift] = iHigh(NULL, TimeFrame, shift);

else

SlowUpPts[shift] = 0.0;


if (Fractal(DN_POINT, P, shift) == true)

SlowDnPts[shift] = iLow(NULL, TimeFrame, shift);

else

SlowDnPts[shift] = 0.0;

}

}


bool NewBar()

{

static datetime LastTime = 0;

if (iTime(NULL, TimeFrame, 0) != LastTime)

{

LastTime = iTime(NULL, TimeFrame, 0)+time_offset;

return(true);

}

else

return (false);

}


void DeleteZones()

{

intlen = 5;

int i;


while (i < ObjectsTotal())

{

string objName = ObjectName(i);

if (StringSubstr(objName, 0, len) != "SSSR#")

{

i++;

continue;

}

ObjectDelete(objName);

}

}


string TimeFrameToString(int tf) // code from TRO

{

string tfs;


switch(tf)

{

case PERIOD_M1:

tfs="M1" ;

break;

case PERIOD_M5:

tfs="M5" ;

break;

case PERIOD_M15:

tfs="M15" ;

break;

case PERIOD_M30:

tfs="M30" ;

break;

case PERIOD_H1:

tfs="H1" ;

break;

case PERIOD_H4:

tfs="H4" ;

break;

case PERIOD_D1:

tfs="D1" ;

break;

case PERIOD_W1:

tfs="W1" ;

break;

case PERIOD_MN1:

tfs="MN";

}


return(tfs);

}


string StringRepeat(string str, int n = 1)

{

string outstr = "";

for(int i = 0; i < n; i++) outstr = outstr + str;

return(outstr);

}


string StringRightPad(string str, int n=1, string str2=" ")

{

return(str + StringRepeat(str2,n-StringLen(str)));


 

Switching to MT5. Help me with a word. How does MT5 write in code, what is wrong?

//+------------------------------------------------------------------+
//|                                                          123.mq5 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   1
//+----------------------------------------------+
//|  Параметры отрисовки индикатора 1            |
//+----------------------------------------------+
#property indicator_type1   DRAW_ARROW
#property indicator_color1  Blue
#property indicator_style1  STYLE_DASHDOTDOT
#property indicator_width1  0
#property indicator_label1  "Label 1"
//----
input int MAPeriod=13;
//---=
int handle_ma;
double ExtLineBuffer[];
double BufferPrice[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   SetIndexBuffer(0,ExtLineBuffer,INDICATOR_DATA);
   SetIndexBuffer(3,BufferPrice,INDICATOR_CALCULATIONS);
//---- символы для индикатора
   PlotIndexSetInteger(0,PLOT_ARROW,108);
//---- создание метки для отображения в DataWindow
   PlotIndexSetString(0,PLOT_LABEL,"PROBA");
//----
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
   IndicatorSetString(INDICATOR_SHORTNAME," 123");
//---- массива будет производиться как в таймсериях
   ArraySetAsSeries(ExtLineBuffer,true);
   ArraySetAsSeries(BufferPrice,true);
//--- create MA's handles
   ResetLastError();
      handle_ma=iMA(NULL,Period(),MAPeriod,0,MODE_SMA,PRICE_CLOSE); 
   if(handle_ma==INVALID_HANDLE)
     {
      Print("The iMA (1) object was not created: Error ",GetLastError());
      return INIT_FAILED;
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 | 
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
 {
 Comment("");
 }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
//--- Проверка количества доступных баров
   if(rates_total<4) return 0;
//--- Проверка и расчёт количества просчитываемых баров
   int limit=rates_total-prev_calculated;
   if(limit>1)
     {
      limit=rates_total-1;
   ArrayInitialize(ExtLineBuffer,EMPTY_VALUE);
   ArrayInitialize(BufferPrice,0);
     }
//--- Подготовка данных
   int count=(limit>1 ? rates_total : 2),copied=0;
   copied=CopyBuffer(handle_ma,0,0,count,BufferPrice);
   if(copied!=count) return 0;
//----   
 for(int i=limit; i>0 && !IsStopped(); i--)
   {
//----------------------------------------- ОСНОВНОЙ МОДУЛЬ КОТОРЫЙ НЕ РАБОТАЕТ ----------------------------
 if(PERIOD_H1==Period())
  {
//--- High signal
 if(BufferPrice[i]>open[i] && BufferPrice[i]<close[i])   
   ExtLineBuffer[i]=high[i];
//--- Low signal
 if(BufferPrice[i]<open[i] && BufferPrice[i]>close[i])
   ExtLineBuffer[i]=low[i];
  } /*
  else
  {
  ExtLineBuffer[i]=0.0;
  ExtLineBuffer[i]=0.0;
  } */
  }    
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

QUESTION: Why all sorts of rubbish is falling into the buffer?

I am at the stage of Lego constructor, i.e. I copy the module and try to understand the peculiarities of MT5 by experience. Documentation of course.

 
kopeyka2:

Switching to MT5. Help me with a word. How in MT5 is it written in code, what is wrong?

QUESTION: Why all kinds of rubbish is falling into the buffer?

in mt5 the timeseries goes the other way round
if you need it the same way as in mt4, that isArraySetAsSeries

 
kopeyka2:

Switching to MT5. Help me with a word. How in MT5 is it written in code, what is wrong?

QUESTION: Why all sorts of rubbish is falling into the buffer?

I am at the stage of Lego constructor, i.e. I copy the module and understand the peculiarities of MT% by experience. Documentation of course.

//+------------------------------------------------------------------+
//|                                                          123.mq5 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   1
//+----------------------------------------------+
//|  Параметры отрисовки индикатора 1            |
//+----------------------------------------------+
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrBlue
#property indicator_width1  1
#property indicator_label1  "Label 1"
//----
input int MAPeriod=13;
//---=
int handle_ma;
double ExtLineBuffer[];
double BufferPrice[];
//---
int    period;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   period=(MAPeriod<1 ? 1 : MAPeriod);
//---
   SetIndexBuffer(0,ExtLineBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,BufferPrice,INDICATOR_CALCULATIONS);
//---- символы для индикатора
   PlotIndexSetInteger(0,PLOT_ARROW,108);
//---- создание метки для отображения в DataWindow
   PlotIndexSetString(0,PLOT_LABEL,"PROBA");
//----
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
   IndicatorSetString(INDICATOR_SHORTNAME," 123");
//---- массива будет производиться как в таймсериях
   ArraySetAsSeries(ExtLineBuffer,true);
   ArraySetAsSeries(BufferPrice,true);
//--- create MA's handles
   ResetLastError();
   handle_ma=iMA(NULL,PERIOD_CURRENT,period,0,MODE_SMA,PRICE_CLOSE);
   if(handle_ma==INVALID_HANDLE)
     {
      Print("The iMA (",(string)period,") object was not created: Error ",GetLastError());
      return INIT_FAILED;
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 | 
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Comment("");
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//--- 
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true); 
//--- Проверка количества доступных баров
   if(rates_total<4) return 0;
//--- Проверка и расчёт количества просчитываемых баров
   int limit=rates_total-prev_calculated;
   if(limit>1)
     {
      limit=rates_total-1;
      ArrayInitialize(ExtLineBuffer,EMPTY_VALUE);
      ArrayInitialize(BufferPrice,0);
     }
//--- Подготовка данных
   int count=(limit>1 ? rates_total : 2),copied=0;
   copied=CopyBuffer(handle_ma,0,0,count,BufferPrice);
   if(copied!=count) return 0;
//----   
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {
      //----------------------------------------- ОСНОВНОЙ МОДУЛЬ КОТОРЫЙ НЕ РАБОТАЕТ ----------------------------
      if(Period()==PERIOD_H1)
        {
         //--- High signal
         if(BufferPrice[i]>open[i] && BufferPrice[i]<close[i])
            ExtLineBuffer[i]=high[i];
         //--- Low signal
         if(BufferPrice[i]<open[i] && BufferPrice[i]>close[i])
            ExtLineBuffer[i]=low[i];
        }
/*
  else
  {
  ExtLineBuffer[i]=0.0;
  ExtLineBuffer[i]=0.0;
  } */
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
Artyom Trishkin:

Thanks for the reply.

Checked in MT5... What a mess... Points are scattered all over the chart in a strange way, somewhere deep in the history... I do not understand what and why MT5 does not like? The problem is simple!!!

TAKE IT IN MT4

.THIS IS WHAT IT LOOKS LIKE IN MT4


AND SO IN MT5. Of course in one buffer. But the problem is that the indicator is catching points, but not those and not there...(((


Please tell me again. What I did wrong in the code MT5????

I got something in MT5. But buffers ... a mystery

 
kopeyka2:

Thanks for the reply.

Checked in MT5... What a mess... Points are scattered all over the chart in a strange way, somewhere deep in the history... I do not understand what and why MT5 does not like? The problem is simple!!!

TAKE IT IN MT4

.


AND SO IN MT5 . Of course in one buffer. But the problem is that the indicator is catching points, but not those and not there...(((


Please help me again. What I did wrong in the code MT5????

I got something in MT5. But buffers ... a mystery

There is no mystery. The numbering is different from mql4 and the indicator buffers are not zeroed automatically. To clear the "rubbish" the programmer must take care of the cleanliness of the indexes if they are not to contain values.

 
Alexey Viktorov:

No mystery. The numbering is different from mql4 and the indicator buffers are not zeroed automatically. To clear the "rubbish" the programmer must take care of the purity of indexes if they are not to contain values.

The question is, WHY are the marks (dots) put anywhere? I have defined in the code the algorithm!!!! The MA condition in the body of the candle. Is this not enough?

 
kopeyka2:

The question is, WHY are the marks (dots) put anywhere? I have defined in the code the algorithm!!!! The MA condition in the body of the candle. Is this not enough?

Here look.

kopeyka2:
Switching to MT5. Help me with a word.


Artem has given the full code instead of the word help. Everyone has his own approach to it. I try not to give ready-made code, but I still fail sometimes.

kopeyka2:

Thanks for the reply.

Checked in MT5... It's a bit of a mess...


But the charts for comparison are completely different times. How can one judge whether the dots are right or wrong???

Hence a word of help.

Forum on trading, automated trading systems and strategy testing

Any MQL4 beginners questions, help and discussion on algorithms and codes

Alexey Viktorov, 2019.01.21 11:04

No mystery. Numbering is different from mql4 and indicator buffers are not zeroed automatically. To clear the "rubbish" the programmer himself should take care of the cleanliness of indexes if they are not supposed to contain values.

Help: In MT5 they made inadequate sequence of OnInit and OnDeinit execution, hence there may be problems too. But it is in some special cases, and the recalculation of the indicator should ALWAYS be consecutive. Provided that prev_calculated == 0, recalculate on all bars and on each iteration of the loop, if there should be no value in the buffer, fill this index of the array with value EMPTY_VALUE or 0 depending on PLOT_EMPTY_VALUE setting
 
Alexey Viktorov:

Here's a look.

Artyom gave the full code instead of help with the word. Everyone has a different approach to this. I try not to give ready-made code, but still it sometimes fails.

But the graphs for comparison are completely different times. How can one judge whether the dots are right or wrong?

Hence a word of help.

More help in words: In MT5 they made inadequate sequence of OnInit and OnDeinit executions, hence there may be problems too. But it is in some special cases, and the recalculation of the indicator should ALWAYS be consecutive. Provided that prev_calculated == 0, recalculation should be performed for all bars and at each loop iteration, if there shouldn't be any value in the buffer, then fill this array index with value EMPTY_VALUE or 0 depending on PLOT_EMPTY_VALUE setting

Hallelujah!!!!! Changed open[i] and close[i] to iOpen(NULL,PERIOD_H1,i)



 
kopeyka2:

Hallelujah!!!!! Changed open[i] and close[i] to iOpen(NULL,PERIOD_H1,i)



What's the difference? If the indicator is on H1, only in access speed - you have a slower one. In my example, you probably missed that you need to set the arrays open and close to serial indexing. I highlighted what you didn't have. You have a loop from beginning to end - from limit to 0, and you did not index arrays - so it was drawn backwards and forwards.

Reason: