-
Why did you post your MT4 question in the
Root /
MT5 Indicators section
instead of the
MQL4 section, (bottom of the Root page?)
General rules and best pratices of the Forum. - General - MQL5 programming forum
Next time post in the correct place. The moderators will likely move this thread there soon. extern int IndicatorDist=2000; int OnCalculate(...){ //--- //--- Indicator for(int i = IndicatorDist;i>=1;i--) double test_high=MathMax(close[i],open[i]);
What happens if your chart doesn't have 2000 bars? Why are you recomputing every bar every tick?
How to do your lookbacks correctly.-
There is a difference between the arrays passed to OnCalculate (e.g. low[]) and the predefined variables (e.g.
Low[].) The predefined variables are all ordered AsSeries. The passed
arrays have no default direction.
To determine the indexing direction of time[], open[], high[], low[], close[], tick_volume[], volume[] and spread[], call ArrayGetAsSeries(). In order not to depend on default values, you should unconditionally call the ArraySetAsSeries() function for those arrays, which are expected to work with.
Event Handling Functions - Functions - Language Basics - MQL4 Reference if((test_close2>EMA_small2) && (test_close<EMA_small)){ if(BodyLow[i]!=EMPTY_VALUE){
Since you haven't assigned a value to the buffer yet, when will that condition ever be true?for(int i = IndicatorDist;i>=1;i--){ : BodyLow4[i]=test_low; BodyLow4[i-1]=test_low; BodyLow4[i-2]=test_low; BodyLow4[i-3]=test_low;
What happens when i becomes one?string name = "name"+IntegerToString(i); ObjectDelete(name); ObjectCreate(name, OBJ_ARROW, 0,
The moment a new bar occurs you will have an arrow with a name that doesn't match the bar index (i.e. name1 on bar 2.) Then you will try to create another name1- Use time[i] not i
- Use non-series index (Bars - 1 - i).
- Don't use objects. Why don't you use an buffer of type arrow.
- Use time[i] not i
Thank you very much whroeder1 for you great help!
I have implemented most of your suggestions and the redrawing already works.
Why did you post your MT4 question in the Root / MT5 Indicators section instead of the MQL4 section, (bottom of the Root page?)
General rules and best pratices of the Forum. - General - MQL5 programming forum
Sorry for this, I will do next time.
This will be true when the candle is occupied by a line of the previous candle, because the lines are 3 candles long. I.e. When candle 5 is triggered buffer will be assigned to the next 3 candles. Thus, when candle 3 is also triggered it cannot use buffer, but instead has to use buffer2.
The way I coded it now only provides a 1 candle long line for new candles, since I cannot assign the buffer to future candles. Do you have a suggestion how this can be solved?
//+------------------------------------------------------------------+ //| Close Cross MA Indicator Alert.mq4 | //| Copyright 2017, xxx | //| | //+------------------------------------------------------------------+ #property copyright "Copyright 2017, xxx" #property link "" #property version "1.00" #property strict #property indicator_chart_window #property indicator_buffers 12 #property indicator_color1 clrBlue #property indicator_color2 clrBlue #property indicator_color3 clrBlue #property indicator_color4 clrBlue #property indicator_color5 clrBlue #property indicator_color6 clrBlue #property indicator_color7 clrBlue #property indicator_color8 clrBlue #property indicator_color9 clrBlue #property indicator_color10 clrBlue #property indicator_color11 clrBlue #property indicator_color12 clrRed #property indicator_width1 2 #property indicator_width2 2 #property indicator_width3 2 #property indicator_width4 2 #property indicator_width5 2 #property indicator_width6 2 #property indicator_width7 2 #property indicator_width8 2 #property indicator_width9 2 #property indicator_width10 2 #property indicator_style1 STYLE_SOLID #property indicator_style2 STYLE_SOLID #property indicator_style3 STYLE_SOLID #property indicator_style4 STYLE_SOLID #property indicator_style5 STYLE_SOLID #property indicator_style6 STYLE_SOLID #property indicator_style7 STYLE_SOLID #property indicator_style8 STYLE_SOLID #property indicator_style9 STYLE_SOLID #property indicator_style10 STYLE_SOLID //Inputs extern int TimeFrame = 0; extern int InputMAval_big=200; extern int InputMAtype_big=1; // 0 for Simple (SMA), 1 for Exponential (EMA), 2 for Smoothed (SMMA), 3 for LWMA extern int InputMAshift_big=0; extern int InputMAprice_big=0; // 0=close, 1=open, 2=high, 3=low, 4=Median, 5=Typical, 6=Weighted extern int InputMAval_small=10; extern int InputMAtype_small=1; // 0 for Simple (SMA), 1 for Exponential (EMA), 2 for Smoothed (SMMA), 3 for LWMA extern int InputMAshift_small=0; extern int InputMAprice_small=0; // 0=close, 1=open, 2=high, 3=low, 4=Median, 5=Typical, 6=Weighted extern int DnArrowDist=20; extern int UpArrowDist=20; extern bool AlertAbove = true, AlertBelow = true, AlertSound = true; //Buffer Arrays double BodyHigh[],BodyLow[],BodyHigh2[], BodyLow2[], BodyHigh3[],BodyLow3[],BodyHigh4[], BodyLow4[], BodyHigh5[],BodyLow5[],ArrowUp[],ArrowDown[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,BodyHigh); SetIndexBuffer(1,BodyLow); SetIndexBuffer(2,BodyHigh2); SetIndexBuffer(3,BodyLow2); SetIndexBuffer(4,BodyHigh3); SetIndexBuffer(5,BodyLow3); SetIndexBuffer(6,BodyHigh4); SetIndexBuffer(7,BodyLow4); SetIndexBuffer(8,BodyHigh5); SetIndexBuffer(9,BodyLow5); SetIndexBuffer(10,ArrowUp); SetIndexBuffer(11,ArrowDown); SetIndexStyle(0,DRAW_LINE); SetIndexStyle(1,DRAW_LINE); SetIndexStyle(2,DRAW_LINE); SetIndexStyle(3,DRAW_LINE); SetIndexStyle(4,DRAW_LINE); SetIndexStyle(5,DRAW_LINE); SetIndexStyle(6,DRAW_LINE); SetIndexStyle(7,DRAW_LINE); SetIndexStyle(8,DRAW_LINE); SetIndexStyle(9,DRAW_LINE); SetIndexStyle(10,DRAW_ARROW); SetIndexStyle(11,DRAW_ARROW); SetIndexArrow(10, 241); SetIndexArrow(11, 242); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| 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[]) { //--- //--- Indicator int lookback = 3; for(int iBar = rates_total-1-MathMax(lookback,prev_calculated);iBar>=1;--iBar) { ArraySetAsSeries(close, true); ArraySetAsSeries(open, true); double test_high=MathMax(close[iBar],open[iBar]); double test_low=MathMin(close[iBar],open[iBar]); static int AlertPrevTime = 0; double test_close = iClose(NULL,TimeFrame,iBar); double test_close2 = iClose(NULL,TimeFrame,iBar+1); double EMA_big = iMA(NULL, TimeFrame, InputMAval_big, InputMAshift_big, InputMAtype_big, InputMAprice_big, iBar); double EMA_small = iMA(NULL, TimeFrame, InputMAval_small, InputMAshift_small, InputMAtype_small, InputMAprice_small, iBar); double EMA_small2 = iMA(NULL, TimeFrame, InputMAval_small, InputMAshift_small, InputMAtype_small, InputMAprice_small, iBar+1); string soundfile = "alert.wav"; // Draw line to candle if its close crosses EMA // Beacuse line is 3 candles long, check if buffer is occupied and use different one if so if(EMA_small<EMA_big) { if((test_close2>EMA_small2) && (test_close<EMA_small)){ if(BodyLow[iBar]!=EMPTY_VALUE){ if(BodyLow2[iBar]!=EMPTY_VALUE){ if(BodyLow3[iBar]!=EMPTY_VALUE){ if(BodyLow4[iBar]!=EMPTY_VALUE){ if(iBar>2){ BodyLow5[iBar]=test_low; BodyLow5[iBar-1]=test_low; BodyLow5[iBar-2]=test_low; BodyLow5[iBar-3]=test_low; } if(iBar==2){ BodyLow5[iBar]=test_low; BodyLow5[iBar-1]=test_low; BodyLow5[iBar-2]=test_low; } if(iBar==1){ BodyLow5[iBar]=test_low; BodyLow5[iBar-1]=test_low; } }else{ if(iBar>2){ BodyLow4[iBar]=test_low; BodyLow4[iBar-1]=test_low; BodyLow4[iBar-2]=test_low; BodyLow4[iBar-3]=test_low; } if(iBar==2){ BodyLow4[iBar]=test_low; BodyLow4[iBar-1]=test_low; BodyLow4[iBar-2]=test_low; } if(iBar==1){ BodyLow4[iBar]=test_low; BodyLow4[iBar-1]=test_low; } } }else{ if(iBar>2){ BodyLow3[iBar]=test_low; BodyLow3[iBar-1]=test_low; BodyLow3[iBar-2]=test_low; BodyLow3[iBar-3]=test_low; } if(iBar==2){ BodyLow3[iBar]=test_low; BodyLow3[iBar-1]=test_low; BodyLow3[iBar-2]=test_low; } if(iBar==1){ BodyLow3[iBar]=test_low; BodyLow3[iBar-1]=test_low; } } }else{ if(iBar>2){ BodyLow2[iBar]=test_low; BodyLow2[iBar-1]=test_low; BodyLow2[iBar-2]=test_low; BodyLow2[iBar-3]=test_low; } if(iBar==2){ BodyLow2[iBar]=test_low; BodyLow2[iBar-1]=test_low; BodyLow2[iBar-2]=test_low; } if(iBar==1){ BodyLow2[iBar]=test_low; BodyLow2[iBar-1]=test_low; } } } else{ if(iBar>2){ BodyLow[iBar]=test_low; BodyLow[iBar-1]=test_low; BodyLow[iBar-2]=test_low; BodyLow[iBar-3]=test_low; } if(iBar==2){ BodyLow[iBar]=test_low; BodyLow[iBar-1]=test_low; BodyLow[iBar-2]=test_low; } if(iBar==1){ BodyLow[iBar]=test_low; BodyLow[iBar-1]=test_low; } } //Draw arrow down - obove the candle ArrowDown[iBar]=High[iBar]+DnArrowDist*Point; //Give alert if close cross has happened if (Time[0] > AlertPrevTime){ if(AlertAbove)Alert("["+Symbol()+"]" + " Close below EMA -- Sell"); if(AlertSound)PlaySound(soundfile); AlertPrevTime = Time[0]; } } } if(EMA_small>EMA_big) { if((test_close2<EMA_small2) && (test_close>EMA_small)){ if(BodyHigh[iBar]!=EMPTY_VALUE){ if(BodyHigh2[iBar]!=EMPTY_VALUE){ if(BodyHigh3[iBar]!=EMPTY_VALUE){ if(BodyHigh4[iBar]!=EMPTY_VALUE){ if(iBar>2){ BodyHigh5[iBar]=test_high; BodyHigh5[iBar-1]=test_high; BodyHigh5[iBar-2]=test_high; BodyHigh5[iBar-3]=test_high; } if(iBar==2){ BodyHigh5[iBar]=test_high; BodyHigh5[iBar-1]=test_high; BodyHigh5[iBar-2]=test_high; } if(iBar==1){ BodyHigh5[iBar]=test_high; BodyHigh5[iBar-1]=test_high; } }else{ if(iBar>2){ BodyHigh4[iBar]=test_high; BodyHigh4[iBar-1]=test_high; BodyHigh4[iBar-2]=test_high; BodyHigh4[iBar-3]=test_high; } if(iBar==2){ BodyHigh4[iBar]=test_high; BodyHigh4[iBar-1]=test_high; BodyHigh4[iBar-2]=test_high; } if(iBar==1){ BodyHigh4[iBar]=test_high; BodyHigh4[iBar-1]=test_high; } } }else{ if(iBar>2){ BodyHigh3[iBar]=test_high; BodyHigh3[iBar-1]=test_high; BodyHigh3[iBar-2]=test_high; BodyHigh3[iBar-3]=test_high; } if(iBar==2){ BodyHigh3[iBar]=test_high; BodyHigh3[iBar-1]=test_high; BodyHigh3[iBar-2]=test_high; } if(iBar==1){ BodyHigh3[iBar]=test_high; BodyHigh3[iBar-1]=test_high; } } }else{ if(iBar>2){ BodyHigh2[iBar]=test_high; BodyHigh2[iBar-1]=test_high; BodyHigh2[iBar-2]=test_high; BodyHigh2[iBar-3]=test_high; } if(iBar==2){ BodyHigh2[iBar]=test_high; BodyHigh2[iBar-1]=test_high; BodyHigh2[iBar-2]=test_high; } if(iBar==1){ BodyHigh2[iBar]=test_high; BodyHigh2[iBar-1]=test_high; } } } else{ if(iBar>2){ BodyHigh[iBar]=test_high; BodyHigh[iBar-1]=test_high; BodyHigh[iBar-2]=test_high; BodyHigh[iBar-3]=test_high; } if(iBar==2){ BodyHigh[iBar]=test_high; BodyHigh[iBar-1]=test_high; BodyHigh[iBar-2]=test_high; } if(iBar==1){ BodyHigh[iBar]=test_high; BodyHigh[iBar-1]=test_high; } } //Draw up arrow ArrowUp[iBar]=Low[iBar]+UpArrowDist*Point; if (Time[0] > AlertPrevTime){ if(AlertAbove)Alert("["+Symbol()+"]" + " Close above EMA -- Buy"); if(AlertSound)PlaySound(soundfile); AlertPrevTime = Time[0]; } } } } //--- return value of prev_calculated for next call return(rates_total-1); } //+------------------------------------------------------------------
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hello, this is the first indicator I have written and it hast some flaws. I would be happy I someone could help.
What it should do:
It works okay on past candles, however
I hope some can help me out.
Also, this is probably not the most elegant way of coding, sorry for that.
I'd also be happy about any improvement suggestions (efficiency etc.), since I don't have a background in programming.