The Keltner Channel is defined by two bands above and below the current price of an asset. The bands are volatility based and placed at a distance that is defined by the average true range of the asset over a number of periods. The bands are anchored on an exponential moving average which defines the middle of the channel.
Source Code
Save the source code under Indicators/AlgoGen.KeltnerChannel.mq4. After compiling it you can include it as a study in your charts or use it in your Expert Advisors for trading.
//+------------------------------------------------------------------+
//| AlgoGen.KeltnerChannel.mq4 |
//| Copyright 2020, AlgoGen |
//| https://www.algogen.io |
//+------------------------------------------------------------------+
input ENUM_APPLIED_PRICE priceMode = PRICE_TYPICAL; // Price
input ENUM_MA_METHOD movingAverageMode = MODE_EMA; // Moving Average
input int movingAveragePeriod = 21; // Keltner Channel Moving Average Period
input int atrPeriod = 21; // Keltner Channel ATR Period
input double multiplier = 3.0; // Keltner Channel ATR Multiplier
#property copyright "Copyright 2020, AlgoGen."
#property link "https://www.algogen.io"
#property version "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots 3
#property indicator_label1 "UPPER"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
#property indicator_label2 "MAIN"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
#property indicator_label3 "LOWER"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrRed
#property indicator_style3 STYLE_SOLID
#property indicator_width3 1
double UPPERBuffer[];
double MAINBuffer[];
double LOWERBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit() {
SetIndexBuffer(0, UPPERBuffer);
SetIndexBuffer(1, MAINBuffer);
SetIndexBuffer(2, LOWERBuffer);
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[]
) {
int limit;
int countedBars = IndicatorCounted();
if (countedBars < 0) return (-1);
if (countedBars > 0) countedBars--;
limit = Bars - countedBars;
for (int i = 0; i < limit; i++) {
double middle = iMA(NULL, 0, movingAveragePeriod, 0, movingAverageMode, priceMode, i);
double atr = iATR(NULL, 0, atrPeriod, i);
double upper = middle + multiplier * atr;
double lower = middle - multiplier * atr;
UPPERBuffer[i] = upper;
MAINBuffer[i] = middle;
LOWERBuffer[i] = lower;
}
return 0;
}
Usage
You can call the Keltner Channel indicator with the built-in iCustom function:
iCustom(
// symbol
NULL,
// timeframe
0,
// name
"AlgoGen.KeltnerChannel",
// applied price,
PRICE_CLOSE,
// moving average,
MODE_EMA,
// moving average period
21,
// atr period
14,
// atr multiplier
3,
// line index
0,
// shift
0
)