mirror of
https://github.com/softwaredevelop/mql5.git
synced 2026-07-27 20:47:44 +00:00
refactor: remove old bollinger files
This commit is contained in:
@@ -1,65 +0,0 @@
|
||||
# Bollinger Bands®
|
||||
|
||||
## 1. Summary (Introduction)
|
||||
|
||||
Bollinger Bands® are a technical analysis tool developed by John Bollinger in the 1980s. They are a type of volatility channel, consisting of three lines plotted in relation to a security's price.
|
||||
|
||||
- A **Middle Band**, which is a simple moving average (SMA).
|
||||
- An **Upper Band**, typically two standard deviations above the middle band.
|
||||
- A **Lower Band**, typically two standard deviations below the middle band.
|
||||
|
||||
The primary purpose of Bollinger Bands is to provide a relative definition of high and low prices. By definition, prices are high at the upper band and low at the lower band. This concept can be used to identify potential overbought and oversold conditions, gauge the strength of a trend, and spot potential breakouts.
|
||||
|
||||
## 2. Mathematical Foundations and Calculation Logic
|
||||
|
||||
The indicator's strength lies in its use of standard deviation, which allows the bands to automatically adapt to market volatility.
|
||||
|
||||
### Required Components
|
||||
|
||||
- **Period (N):** The lookback period for both the moving average and the standard deviation calculation (e.g., 20).
|
||||
- **Standard Deviation (σ):** A statistical measure of volatility or dispersion.
|
||||
- **Multiplier (M):** The number of standard deviations to shift the bands away from the middle line (e.g., 2.0).
|
||||
- **Source Price (P):** The price series used for the calculation (e.g., Close).
|
||||
|
||||
### Calculation Steps (Algorithm)
|
||||
|
||||
1. **Calculate the Middle Band:** Compute a Simple Moving Average (SMA) of the source price over the period `N`.
|
||||
$\text{Middle Band}_i = \text{SMA}(P, N)_i$
|
||||
|
||||
2. **Calculate the Standard Deviation:** For each bar, calculate the standard deviation of the source price over the same period `N`.
|
||||
$\sigma_i = \sqrt{\frac{\sum_{k=i-N+1}^{i} (P_k - \text{Middle Band}_i)^2}{N}}$
|
||||
|
||||
3. **Calculate the Upper and Lower Bands:** Add and subtract a multiple of the standard deviation from the middle band.
|
||||
$\text{Upper Band}_i = \text{Middle Band}_i + (M \times \sigma_i)$
|
||||
$\text{Lower Band}_i = \text{Middle Band}_i - (M \times \sigma_i)$
|
||||
|
||||
## 3. MQL5 Implementation Details
|
||||
|
||||
Our MQL5 implementations were refactored to be completely self-contained, robust, and accurate.
|
||||
|
||||
- **Stability via Full Recalculation:** We employ a "brute-force" full recalculation within the `OnCalculate` function. This is our standard practice to ensure maximum stability and prevent calculation errors.
|
||||
|
||||
- **Fully Manual Calculations:** To guarantee 100% accuracy and consistency within our `non-timeseries` calculation model, all calculations are performed manually. The indicators are completely independent of the `<MovingAverages.mqh>` standard library.
|
||||
|
||||
- The **Middle Band (SMA)** is calculated using an efficient **sliding window sum** technique, which is significantly faster than recalculating the sum in every iteration.
|
||||
- The **Standard Deviation** is calculated manually for each bar according to its mathematical definition.
|
||||
|
||||
- **Integrated Calculation Loop:** The `OnCalculate` function uses a single, efficient `for` loop to perform all calculations. Within each iteration, it first updates the SMA, then calculates the standard deviation based on that SMA, and finally computes the upper and lower bands.
|
||||
|
||||
- **Heikin Ashi Variant (`BollingerBands_HeikinAshi.mq5`):**
|
||||
- Our toolkit also includes a "pure" Heikin Ashi version of this indicator. The calculation logic is identical, but it uses the smoothed Heikin Ashi price data (e.g., `ha_close`) as its input for both the SMA and the standard deviation calculations.
|
||||
- This results in a channel that reflects the volatility of the underlying Heikin Ashi trend rather than the raw market price. The bands are often smoother and can provide a different perspective on trend and volatility.
|
||||
|
||||
## 4. Parameters
|
||||
|
||||
- **BB Period (`InpBBPeriod`):** The lookback period for the middle line SMA and the standard deviation calculation. The standard is `20`.
|
||||
- **Deviation (`InpBBDeviation`):** The multiplier for the standard deviation. The standard is `2.0`.
|
||||
- **Applied Price (`InpAppliedPrice`):** The source price used for the calculation. The standard is `PRICE_CLOSE`.
|
||||
|
||||
## 5. Usage and Interpretation
|
||||
|
||||
- **"Walking the Bands":** In a strong uptrend, prices will frequently touch or "ride" the upper band. In a strong downtrend, they will ride the lower band. A move away from the bands can signal a weakening of the trend.
|
||||
- **Mean Reversion (in Ranges):** In a sideways or ranging market, a move to the upper band can be seen as overbought and a potential short opportunity, while a move to the lower band can be seen as oversold and a potential long opportunity.
|
||||
- **The Squeeze:** When the bands narrow significantly, it indicates a period of low volatility. This "squeeze" often precedes a period of high volatility and a potential price breakout. Traders often watch for the price to close outside the bands after a squeeze as a trading signal.
|
||||
- **Breakouts:** A strong close outside the bands can signal the start of a new trend. However, it's important to watch for "head fakes," where the price quickly reverses back inside the bands.
|
||||
- **Caution:** Bollinger Bands are a versatile tool but should not be used in isolation. The signals they provide should be confirmed with other indicators or forms of analysis.
|
||||
@@ -1,155 +0,0 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| BollingerBands.mq5 |
|
||||
//| Copyright 2025, xxxxxxxx |
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2025, xxxxxxxx"
|
||||
#property link ""
|
||||
#property version "1.00"
|
||||
#property description "Bollinger Bands - a volatility indicator"
|
||||
|
||||
//--- Indicator Window and Plot Properties ---
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 3 // Upper, Lower, Middle
|
||||
#property indicator_plots 3
|
||||
|
||||
//--- Plot 1: Upper Band
|
||||
#property indicator_label1 "Upper Band"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrDodgerBlue
|
||||
#property indicator_style1 STYLE_DOT
|
||||
|
||||
//--- Plot 2: Lower Band
|
||||
#property indicator_label2 "Lower Band"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrDodgerBlue
|
||||
#property indicator_style2 STYLE_DOT
|
||||
|
||||
//--- Plot 3: Middle Band (Basis)
|
||||
#property indicator_label3 "Basis"
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrRed
|
||||
#property indicator_style3 STYLE_SOLID
|
||||
|
||||
//--- Input Parameters ---
|
||||
input int InpBBPeriod = 20; // Bollinger Bands Period
|
||||
input double InpBBDeviation = 2.0; // Deviation
|
||||
input ENUM_APPLIED_PRICE InpAppliedPrice = PRICE_CLOSE; // Applied Price
|
||||
|
||||
//--- Indicator Buffers ---
|
||||
double BufferUpper[];
|
||||
double BufferLower[];
|
||||
double BufferMiddle[];
|
||||
|
||||
//--- Global Variables ---
|
||||
int g_ExtBBPeriod;
|
||||
double g_ExtBBDeviation;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function. |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
g_ExtBBPeriod = (InpBBPeriod < 1) ? 1 : InpBBPeriod;
|
||||
g_ExtBBDeviation = (InpBBDeviation <= 0) ? 2.0 : InpBBDeviation;
|
||||
|
||||
SetIndexBuffer(0, BufferUpper, INDICATOR_DATA);
|
||||
SetIndexBuffer(1, BufferLower, INDICATOR_DATA);
|
||||
SetIndexBuffer(2, BufferMiddle, INDICATOR_DATA);
|
||||
|
||||
ArraySetAsSeries(BufferUpper, false);
|
||||
ArraySetAsSeries(BufferLower, false);
|
||||
ArraySetAsSeries(BufferMiddle, false);
|
||||
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
||||
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, g_ExtBBPeriod - 1);
|
||||
PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, g_ExtBBPeriod - 1);
|
||||
PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, g_ExtBBPeriod - 1);
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("BB(%d, %.1f)", g_ExtBBPeriod, g_ExtBBDeviation));
|
||||
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Bollinger Bands calculation 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 < g_ExtBBPeriod)
|
||||
return(0);
|
||||
|
||||
//--- STEP 1: Prepare the source price array
|
||||
double price_source[];
|
||||
ArrayResize(price_source, rates_total);
|
||||
for(int i=0; i<rates_total; i++)
|
||||
{
|
||||
switch(InpAppliedPrice)
|
||||
{
|
||||
case PRICE_OPEN:
|
||||
price_source[i] = open[i];
|
||||
break;
|
||||
case PRICE_HIGH:
|
||||
price_source[i] = high[i];
|
||||
break;
|
||||
case PRICE_LOW:
|
||||
price_source[i] = low[i];
|
||||
break;
|
||||
case PRICE_MEDIAN:
|
||||
price_source[i] = (high[i] + low[i]) / 2.0;
|
||||
break;
|
||||
case PRICE_TYPICAL:
|
||||
price_source[i] = (high[i] + low[i] + close[i]) / 3.0;
|
||||
break;
|
||||
case PRICE_WEIGHTED:
|
||||
price_source[i]= (high[i] + low[i] + 2*close[i]) / 4.0;
|
||||
break;
|
||||
default:
|
||||
price_source[i] = close[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//--- STEP 2: Main calculation loop
|
||||
double sma_sum = 0;
|
||||
for(int i = 0; i < rates_total; i++)
|
||||
{
|
||||
sma_sum += price_source[i];
|
||||
|
||||
if(i >= g_ExtBBPeriod)
|
||||
{
|
||||
sma_sum -= price_source[i - g_ExtBBPeriod];
|
||||
}
|
||||
|
||||
if(i >= g_ExtBBPeriod - 1)
|
||||
{
|
||||
// --- Calculate Middle Band (SMA) ---
|
||||
BufferMiddle[i] = sma_sum / g_ExtBBPeriod;
|
||||
|
||||
// --- Calculate Standard Deviation ---
|
||||
double deviation_sum_sq = 0;
|
||||
for(int j = 0; j < g_ExtBBPeriod; j++)
|
||||
{
|
||||
double diff = price_source[i - j] - BufferMiddle[i];
|
||||
deviation_sum_sq += diff * diff;
|
||||
}
|
||||
double std_dev = MathSqrt(deviation_sum_sq / g_ExtBBPeriod);
|
||||
|
||||
// --- Calculate Upper and Lower Bands ---
|
||||
double dev_offset = g_ExtBBDeviation * std_dev;
|
||||
BufferUpper[i] = BufferMiddle[i] + dev_offset;
|
||||
BufferLower[i] = BufferMiddle[i] - dev_offset;
|
||||
}
|
||||
}
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -1,180 +0,0 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| BollingerBands_HeikinAshi.mq5|
|
||||
//| Copyright 2025, xxxxxxxx |
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2025, xxxxxxxx"
|
||||
#property link ""
|
||||
#property version "1.00"
|
||||
#property description "Bollinger Bands on Heikin Ashi data"
|
||||
|
||||
#include <MyIncludes\HeikinAshi_Tools.mqh>
|
||||
|
||||
//--- Indicator Window and Plot Properties ---
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 3 // Upper, Lower, Middle
|
||||
#property indicator_plots 3
|
||||
|
||||
//--- Plot 1: Upper Band
|
||||
#property indicator_label1 "HA_Upper"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrDodgerBlue
|
||||
#property indicator_style1 STYLE_DOT
|
||||
|
||||
//--- Plot 2: Lower Band
|
||||
#property indicator_label2 "HA_Lower"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrDodgerBlue
|
||||
#property indicator_style2 STYLE_DOT
|
||||
|
||||
//--- Plot 3: Middle Band (Basis)
|
||||
#property indicator_label3 "HA_Basis"
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrRed
|
||||
#property indicator_style3 STYLE_SOLID
|
||||
|
||||
//--- Enum for selecting Heikin Ashi price source ---
|
||||
enum ENUM_HA_APPLIED_PRICE
|
||||
{
|
||||
HA_PRICE_CLOSE,
|
||||
HA_PRICE_OPEN,
|
||||
HA_PRICE_HIGH,
|
||||
HA_PRICE_LOW
|
||||
};
|
||||
|
||||
//--- Input Parameters ---
|
||||
input int InpBBPeriod = 20;
|
||||
input double InpBBDeviation = 2.0;
|
||||
input ENUM_HA_APPLIED_PRICE InpAppliedPrice = HA_PRICE_CLOSE;
|
||||
|
||||
//--- Indicator Buffers ---
|
||||
double BufferUpper[];
|
||||
double BufferLower[];
|
||||
double BufferMiddle[];
|
||||
|
||||
//--- Global Objects and Variables ---
|
||||
int g_ExtBBPeriod;
|
||||
double g_ExtBBDeviation;
|
||||
CHeikinAshi_Calculator *g_ha_calculator;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function. |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
g_ExtBBPeriod = (InpBBPeriod < 1) ? 1 : InpBBPeriod;
|
||||
g_ExtBBDeviation = (InpBBDeviation <= 0) ? 2.0 : InpBBDeviation;
|
||||
|
||||
SetIndexBuffer(0, BufferUpper, INDICATOR_DATA);
|
||||
SetIndexBuffer(1, BufferLower, INDICATOR_DATA);
|
||||
SetIndexBuffer(2, BufferMiddle, INDICATOR_DATA);
|
||||
|
||||
ArraySetAsSeries(BufferUpper, false);
|
||||
ArraySetAsSeries(BufferLower, false);
|
||||
ArraySetAsSeries(BufferMiddle, false);
|
||||
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
||||
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, g_ExtBBPeriod - 1);
|
||||
PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, g_ExtBBPeriod - 1);
|
||||
PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, g_ExtBBPeriod - 1);
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("HA_BB(%d, %.1f)", g_ExtBBPeriod, g_ExtBBDeviation));
|
||||
|
||||
g_ha_calculator = new CHeikinAshi_Calculator();
|
||||
if(CheckPointer(g_ha_calculator) == POINTER_INVALID)
|
||||
{
|
||||
Print("Error creating CHeikinAshi_Calculator object");
|
||||
return(INIT_FAILED);
|
||||
}
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator deinitialization function. |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
if(CheckPointer(g_ha_calculator) != POINTER_INVALID)
|
||||
{
|
||||
delete g_ha_calculator;
|
||||
g_ha_calculator = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Bollinger Bands on Heikin Ashi calculation 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 < g_ExtBBPeriod)
|
||||
return(0);
|
||||
|
||||
//--- Intermediate Heikin Ashi Buffers
|
||||
double ha_open[], ha_high[], ha_low[], ha_close[];
|
||||
ArrayResize(ha_open, rates_total);
|
||||
ArrayResize(ha_high, rates_total);
|
||||
ArrayResize(ha_low, rates_total);
|
||||
ArrayResize(ha_close, rates_total);
|
||||
|
||||
//--- STEP 1: Calculate Heikin Ashi bars
|
||||
g_ha_calculator.Calculate(rates_total, open, high, low, close, ha_open, ha_high, ha_low, ha_close);
|
||||
|
||||
//--- STEP 2: Prepare the Heikin Ashi source price array
|
||||
double ha_price_source[];
|
||||
ArrayResize(ha_price_source, rates_total);
|
||||
switch(InpAppliedPrice)
|
||||
{
|
||||
case HA_PRICE_OPEN:
|
||||
ArrayCopy(ha_price_source, ha_open);
|
||||
break;
|
||||
case HA_PRICE_HIGH:
|
||||
ArrayCopy(ha_price_source, ha_high);
|
||||
break;
|
||||
case HA_PRICE_LOW:
|
||||
ArrayCopy(ha_price_source, ha_low);
|
||||
break;
|
||||
default:
|
||||
ArrayCopy(ha_price_source, ha_close);
|
||||
break;
|
||||
}
|
||||
|
||||
//--- STEP 3: Main calculation loop on HA data
|
||||
double sma_sum = 0;
|
||||
for(int i = 0; i < rates_total; i++)
|
||||
{
|
||||
sma_sum += ha_price_source[i];
|
||||
|
||||
if(i >= g_ExtBBPeriod)
|
||||
{
|
||||
sma_sum -= ha_price_source[i - g_ExtBBPeriod];
|
||||
}
|
||||
|
||||
if(i >= g_ExtBBPeriod - 1)
|
||||
{
|
||||
BufferMiddle[i] = sma_sum / g_ExtBBPeriod;
|
||||
|
||||
double deviation_sum_sq = 0;
|
||||
for(int j = 0; j < g_ExtBBPeriod; j++)
|
||||
{
|
||||
double diff = ha_price_source[i - j] - BufferMiddle[i];
|
||||
deviation_sum_sq += diff * diff;
|
||||
}
|
||||
double std_dev = MathSqrt(deviation_sum_sq / g_ExtBBPeriod);
|
||||
|
||||
double dev_offset = g_ExtBBDeviation * std_dev;
|
||||
BufferUpper[i] = BufferMiddle[i] + dev_offset;
|
||||
BufferLower[i] = BufferMiddle[i] - dev_offset;
|
||||
}
|
||||
}
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
Reference in New Issue
Block a user