Consider creating 2 buffers (LongPinbar and ShortPinbar) to store the high/low for valid pinbars.
These buffers will be filled in OnCalculate, not in OnInit.
Compare rates_total and prev_calculated from within OnCalculate to avoid reprocessing old bars.
You can further restrict OnCalculate to only look once per bar using a static datetime variable and comparison of Time[0].
I'd suggest taking a look at the code of some of the simpler standard indicators to get an idea about how to do all that.
Can somebody please explain how I can use this array in the OnInit() ?
- Look at the examples. The arrays are not used in init. They are made buffers OnInit() or init()
- They are given values in OnCalculate() or start()
- EMPTY is -1. It is NOT the same as EMPTY_VALUE
Hey guys,
first thanks for you feedback! I understand that it is not possible to fill an array in the init. Like I wrote, my intention was that the code printing the past arrows (which do not change) should only be executed once. Now I found another solution. I use the bool-variable "test" now to check if the code is already executed. Do you agree with that or is there a more "elegant" way?
#property copyright "Copyright 2014, Marcus Riemenschneider" #property link "http://www.facebook.com/marcus.riemenschneider" #property version "1.00" #property strict #property indicator_chart_window #property indicator_buffers 2 #property indicator_color1 Lime #property indicator_color2 Red double LongSignal[], ShortSignal[]; int i; bool test = true; //--- Functions double Candle (int shift) { return(High[shift] - Low[shift]); } double BodyHi (int shift) { return(MathMax(Open[shift], Close[shift])); } double BodyLo (int shift) { return(MathMin(Open[shift], Close[shift])); } //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping IndicatorBuffers(2); SetIndexBuffer(0, LongSignal); SetIndexStyle(0, DRAW_ARROW, EMPTY,1); SetIndexArrow(0, 233); SetIndexBuffer(1, ShortSignal); SetIndexStyle(1, DRAW_ARROW, EMPTY,1); SetIndexArrow(1, 234); //--- 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[]) { if (!test) return(0); //--- space between the candles and the arrows double dy = 0; for (i = 1; i <= 10; i++) dy += (High[i] - Low[i]); dy /= 10; //--- int counted_bars=IndicatorCounted(); if(counted_bars<0) return(-1); if(counted_bars>0) counted_bars--; int limit=MathMin(Bars-counted_bars,Bars-10); //--- main loop for(i=limit; i>=0; i--) { if (BodyLo(i+1) - Low[i+1] >= 0.66*Candle(i+1)) LongSignal[i+1] = Low[i+1] - 0.3*dy; else if (High[i+1] - BodyHi(i+1) >= 0.66*Candle(i+1)) ShortSignal[i+1] = High[i+1] + 0.3*dy; } Alert("Arrows printed"); test = false; //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+
This should only check the previous bar after the first run.
//+------------------------------------------------------------------+ //| ProjectName | //| Copyright 2012, CompanyName | //| http://www.companyname.net | //+------------------------------------------------------------------+ #property copyright "Copyright 2014, Marcus Riemenschneider" #property link "http://www.facebook.com/marcus.riemenschneider" #property version "1.00" #property strict #property indicator_chart_window #property indicator_buffers 2 #property indicator_color1 Lime #property indicator_color2 Red double LongSignal[],ShortSignal[]; //--- Functions double Candle (int shift) { return(High[shift] - Low[shift]); } double BodyHi (int shift) { return(MathMax(Open[shift], Close[shift])); } double BodyLo (int shift) { return(MathMin(Open[shift], Close[shift])); } bool NewBar (datetime time) { static datetime prev_time; if(prev_time!=time) { prev_time=time; return(true); } return(false); } //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping IndicatorBuffers(2); SetIndexBuffer(0,LongSignal); SetIndexStyle(0,DRAW_ARROW,EMPTY,1); SetIndexArrow(0,233); SetIndexBuffer(1,ShortSignal); SetIndexStyle(1,DRAW_ARROW,EMPTY,1); SetIndexArrow(1,234); //--- 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[]) { if(rates_total<=10) return(0); int i,j,limit; //--- if(prev_calculated==0) limit=rates_total-10; else limit=rates_total-prev_calculated; //--- main loop if(prev_calculated==0 || NewBar(time[0])) { for(i=limit; i>=0; i--) { if(BodyLo(i+1)-Low[i+1]>=0.66*Candle(i+1)) { //--- space between the candles and the arrows double dy=0; for(j=i+1; j<=i+10; j++) dy+=(Candle(j)); dy/=10; LongSignal[i+1]=Low[i+1]-0.3*dy; if(prev_calculated>0) Alert("Buy!"); } else if(High[i+1]-BodyHi(i+1)>=0.66*Candle(i+1)) { //--- space between the candles and the arrows double dy=0; for(j=i+1; j<=i+10; j++) dy+=(Candle(j)); dy/=10; ShortSignal[i+1]=High[i+1]+0.3*dy; if(prev_calculated>0) Alert("Sell!"); } } } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+
Hey pipPod,
thank you for that code-example! I never used rates_total or prev_calculated. To be honest I had no idea what it means before honest_knave and you told me about these pre defined variables.
Hey pipPod,
thank you for that code-example! I never used rates_total or prev_calculated. To be honest I had no idea what it means before honest_knave and you told me about these pre defined variables.
I understand, thank you! Then I will modify my old indicators and remove IndicatorCounted().
One last question: what does the &-sign before the const time[], open[], high[] ...in the OnCalculate() mean? I see that these are arrays and no normal int-variables like rates_total and prev_calculated. But why is there a & ?
I understand, thank you! Then I will modify my old indicators and remove IndicatorCounted().
One last question: what does the &-sign before the const time[], open[], high[] ...in the OnCalculate() mean? I see that these are arrays and no normal int-variables like rates_total and prev_calculated. But why is there a & ?
I would also like a definitive answer to this.
As I understand it, the arrays are not loaded at every tick but are passed by reference. So I don't know whether it is actually quicker to access open[i] or Open[i]
I understand, thank you! Then I will modify my old indicators and remove IndicatorCounted().
One last question: what does the &-sign before the const time[], open[], high[] ...in the OnCalculate() mean? I see that these are arrays and no normal int-variables like rates_total and prev_calculated. But why is there a & ?
It means the array element is referenced by position number rather than value, so it should be accessed faster.
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hey guys,
it seemed to be a simple thing but I don't know how to do it:
I wanted to make an indicator which prints arrows above a Pinbar. Pretty easy so far. But I don't want the indicator check the whole chart with every tick. The Pinbars in the past do not change and therefore I wanted to print the arrows in the OnInit(). The OnCalculate() should only check if the last closed bar is a Pinbar. Therefore I put the loop to check all bars in the OnInit(). No error while compiling. But when I drag the indicator into the chart I always receive an "array out of range" error. The error occurs where I want to put data into the (double-)array:
Can somebody please explain how I can use this array in the OnInit() ?
Thanks!!