Indicators Used
0
Views
0
Downloads
0
Favorites
Bollinger Bands with pre Band Smoothing
//+------------------------------------------------------------------+
//| Bollinger Bands with Pre Smoothing |
//| phade |
//| fxcalculator.io |
//| |
//+------------------------------------------------------------------+
#property copyright "phade"
#property link "fxcalculator.io"
#property description "Bollinger Bands with optional outer band smoothing"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 6
#property indicator_plots 3
// Plot properties for the Bollinger Bands
#property indicator_label1 "Bands upper"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrSilver
#property indicator_width1 2
#property indicator_label2 "Bands lower"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrSilver
#property indicator_width2 2
#property indicator_label3 "Bands middle"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrBisque
// Input parameters
input int BB_Period = 20; // BB Period
input double BB_Deviation = 2.0; // Standard deviation multiplier
input ENUM_MA_METHOD ma_method = MODE_SMA; // MA type
input bool additive_smoothing = true; // Additive outer band smoothing
input int MA_Period_1 = 14; // Upper band MA smoothing period
input int MA_Period_2 = 14; // Lower band MA smoothing period
// Indicator buffers
double BBUpperBuffer[];
double BBLowerBuffer[];
double BBMainBuffer[];
double BBCalcBuffer[];
double ma_buf_a[];
double ma_buf_b[];
// Moving Average handles
int handle;
int handle_2;
int upper;
int lower;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0, BBUpperBuffer, INDICATOR_DATA);
SetIndexBuffer(1, BBLowerBuffer, INDICATOR_DATA);
SetIndexBuffer(2, BBMainBuffer, INDICATOR_DATA);
SetIndexBuffer(3, BBCalcBuffer, INDICATOR_CALCULATIONS);
SetIndexBuffer(4, ma_buf_a, INDICATOR_CALCULATIONS);
SetIndexBuffer(5, ma_buf_b, INDICATOR_CALCULATIONS);
handle = iMA(NULL, 0, BB_Period, 0, ma_method, PRICE_CLOSE);
handle_2 = iMA(NULL, 0, BB_Period, 0, ma_method, PRICE_CLOSE);
upper = iMA(NULL, 0, additive_smoothing ? BB_Period + MA_Period_1 : MA_Period_1, 0, ma_method, PRICE_CLOSE);
lower = iMA(NULL, 0, additive_smoothing ? BB_Period + MA_Period_2 : MA_Period_2, 0, ma_method, PRICE_CLOSE);
IndicatorSetString(INDICATOR_SHORTNAME, "Bollinger Bands with outer band smoothing");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
IndicatorRelease(handle);
IndicatorRelease(handle_2);
IndicatorRelease(upper);
IndicatorRelease(lower);
}
//+------------------------------------------------------------------+
//| 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 < BB_Period)
return 0;
int calculated = BarsCalculated(handle);
if(calculated < rates_total)
{
Print("Not all data of handle is calculated (", calculated, " bars). Error ", GetLastError());
return prev_calculated;
}
calculated = BarsCalculated(handle_2);
if(calculated < rates_total)
{
Print("Not all data of handle_2 is calculated (", calculated, " bars). Error ", GetLastError());
return prev_calculated;
}
calculated = BarsCalculated(upper);
if(calculated < rates_total)
{
Print("Not all data of upper is calculated (", calculated, " bars). Error ", GetLastError());
return prev_calculated;
}
calculated = BarsCalculated(lower);
if(calculated < rates_total)
{
Print("Not all data of lower is calculated (", calculated, " bars). Error ", GetLastError());
return prev_calculated;
}
int to_copy = (prev_calculated > rates_total || prev_calculated < 0) ? rates_total : rates_total - prev_calculated;
if(prev_calculated > 0)
to_copy++;
if(IsStopped()) return 0;
if(CopyBuffer(handle, 0, 0, to_copy, BBMainBuffer) <= 0)
{
Print("Getting main MA failed! Error ", GetLastError());
return 0;
}
if(IsStopped()) return 0;
if(CopyBuffer(handle_2, 0, 0, to_copy, BBCalcBuffer) <= 0)
{
Print("Getting calculation MA failed! Error ", GetLastError());
return prev_calculated;
}
if(IsStopped()) return 0;
if(CopyBuffer(upper, 0, 0, to_copy, ma_buf_a) <= 0)
{
Print("Getting upper smoothing MA failed! Error ", GetLastError());
return prev_calculated;
}
if(IsStopped()) return 0;
if(CopyBuffer(lower, 0, 0, to_copy, ma_buf_b) <= 0)
{
Print("Getting lower smoothing MA failed! Error ", GetLastError());
return prev_calculated;
}
int limit = (prev_calculated == 0) ? 0 : prev_calculated - 1;
for(int i = limit; i < rates_total && !IsStopped(); i++)
{
double stdDev = iDeviation(close, BBCalcBuffer, BB_Period, i);
BBUpperBuffer[i] = ma_buf_a[i] + BB_Deviation * stdDev;
BBLowerBuffer[i] = ma_buf_b[i] - BB_Deviation * stdDev;
}
return rates_total;
}
//+------------------------------------------------------------------+
//| Function to calculate standard deviation |
//+------------------------------------------------------------------+
double iDeviation(const double &price[], const double &ma_price[], int period, int pos)
{
double dSum = 0;
for(int i = 0; i < period && pos >= 0; i++)
{
int index = pos - i;
if(index >= 0 && index < ArraySize(price) && index < ArraySize(ma_price))
dSum += MathPow(price[index] - ma_price[pos], 2);
}
return MathSqrt(dSum / period);
}
Comments
Markdown Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

`code`
```
code block
```
> blockquote
- Item 1
- Item 2
1. First item
2. Second item
---