I think I got something. It's a bit clunky but it gets the job done:
//+------------------------------------------------------------------+ //| KeltnerChannel.mq4 | //| Coded by Gilani | //| Copyright © 2019, MetaQuotes Software Corp. | //| http://www.metaquotes.net | //+------------------------------------------------------------------+ #property copyright "Copyright © 2005, MetaQuotes Software Corp." #property link "http://www.metaquotes.net" //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ #include <BreakPoint.mqh> #include <multipairsfunctions.mqh> #property indicator_chart_window #property indicator_buffers 3 #property indicator_color1 White #property indicator_color2 White #property indicator_color3 White double upper[], middle[], lower[]; extern string aSymbol = ""; extern int MA_PERIOD = 20; extern ENUM_MA_METHOD MA_METHOD = MODE_SMA;//MA type. should be MODE_EMA extern ENUM_APPLIED_PRICE PRICE_MODE = PRICE_CLOSE; //Price type extern int ATR_PERIOD = 20;//10 extern double MA_DISTANCE = 1.5; // Coefficient of distance from mean extern bool ATR_MODE = true; //Use ATR instead of Sum(High-Low) extern ENUM_TIMEFRAMES ChartTimeframe=0; string indicatorfilename; void OnInit(void) { SetIndexStyle(0,DRAW_LINE); SetIndexShift(0,0); SetIndexDrawBegin(0,0); SetIndexBuffer(0,upper); SetIndexStyle(1,DRAW_LINE,STYLE_DOT); SetIndexShift(1,0); SetIndexDrawBegin(1,0); SetIndexBuffer(1,middle); SetIndexStyle(2,DRAW_LINE); SetIndexShift(2,0); SetIndexDrawBegin(2,0); SetIndexBuffer(2,lower); indicatorfilename = __FILE__; } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { //processing int x=0,cnt=0; double avg=0; int counted_bars=0; //BreakPoint("","","",true,"aSymbol",aSymbol,"ChartTimeframe",IntegerToString(ChartTimeframe),"MA_PERIOD",IntegerToString(MA_PERIOD),"MA_METHOD",IntegerToString(MA_METHOD),"PRICE_MODE",IntegerToString(PRICE_MODE),"ATR_PERIOD",IntegerToString(ATR_PERIOD),"MA_DISTANCE",DoubleToStr(MA_DISTANCE),"ATR_MODE",IntegerToString(ATR_MODE) ); counted_bars=IndicatorCounted2(aSymbol,indicatorfilename); // Number of counted bars x = iBars(aSymbol,ChartTimeframe) - counted_bars - 1;// Index of the first uncounted if( (x+1)>limit )x=limit; cnt = x; while(x>=0)//Loop for uncounted bars { middle[x] = iMA(aSymbol, ChartTimeframe, MA_PERIOD, 0, MA_METHOD, PRICE_MODE, x);//value of 1 buffer on x bar if (ATR_MODE) avg = iATR(aSymbol,0,ATR_PERIOD, x); else avg = findAvg(ATR_PERIOD, x); upper[x] = middle[x] + MA_DISTANCE*avg;//value of 0 buffer on x bar lower[x] = middle[x] - MA_DISTANCE*avg;//value of 2 buffer on x bar x--; } updateIndicatorCounted2( aSymbol,indicatorfilename,(cnt-1) );//total bars that have been processed. i minus 1 inorder to always force update of shift 1. return(0); } //+------------------------------------------------------------------+ double findAvg(int period, int shift) { double sum=0; for (int x=shift;x<(shift+period);x++) { //sum += High[x]-Low[x]; sum += iHigh(aSymbol,ChartTimeframe,x) - iLow(aSymbol,ChartTimeframe,x); } if(period>0)sum = sum/period; return (sum); }
And the result:
Limitation:
This can be used to trade several currencies simultaneously in one EA, as long as you don't request a keltner value for shift 2 and above. This is because the buffer line will contain previous values from other currency pairs. I know each pair should get its own line but I really don't want this to consume too much cpu and my machine is old. I don't need values above shift 1 so I am ok with this. If you are doing just one currency within the EA then there is no discernible problem.
Files:

You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
Hi. I am converting a single currency indicator to a multipairs indicator and I would like to know the correct way to proceed. The indicator I am working on is a keltner channel, which works ok on the current symbol, however, I don't fully understand how to use IndicatorCounted() on a external pair(a pair that's not the current). Below, you will find the context in which I am using IndicatorCounted() and hopefully that will show you what I would like to accomplish.
The code also shows my attempt at reducing cpu usage by limiting the amount of calls to calculate the bands to once per second, using local time. The BreakPoint() is NOT part of the indicator but I left it in just incase you might want to see the values that are coming out of the indicator. They can be commented out.