75 lines
3.4 KiB
MQL5
75 lines
3.4 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| BearsPower.mqh |
|
|
//| Astralys LLC |
|
|
//| |
|
|
//| Alexander Elder, 1989, as one half of the Elder-Ray indicator. |
|
|
//| It measures how far the sellers managed to push price below the |
|
|
//| trend, by taking the distance between the low of the bar and an |
|
|
//| exponential moving average of the close: |
|
|
//| |
|
|
//| alpha = 2 / (n + 1) |
|
|
//| EMA_1 = Close_1 |
|
|
//| EMA_t = (Close_t - EMA_{t-1}) * alpha + EMA_{t-1} |
|
|
//| Bears_t = Low_t - EMA_t |
|
|
//| |
|
|
//| The more negative the value, the stronger the sellers. |
|
|
//| |
|
|
//| NORMALISATION. Like every indicator built from a subtraction |
|
|
//| rather than a ratio, the raw value is expressed in price units |
|
|
//| and is not comparable across a long sample of a growing market. |
|
|
//| Dividing by the moving average turns it into a percentage. |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Astralys LLC"
|
|
#property link "https://pulsar-terminal.com"
|
|
#property version "1.00"
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Bears Power over a whole series. |
|
|
//| |
|
|
//| low[], close[] input series, index 0 = oldest, same size |
|
|
//| n period of the exponential moving average |
|
|
//| normalise true -> percentage of the average |
|
|
//| false -> raw distance in price units |
|
|
//| out[] output. The first n-1 values are set to |
|
|
//| EMPTY_VALUE so the exponential average has time |
|
|
//| to settle and the grid stays aligned with the |
|
|
//| other indicators. |
|
|
//| |
|
|
//| Returns the index of the first valid value, or -1 on error. |
|
|
//+------------------------------------------------------------------+
|
|
int BearsPower(const double &low[], const double &close[], const int n,
|
|
const bool normalise, double &out[])
|
|
{
|
|
const int size = ArraySize(close);
|
|
if(size <= 0 || n <= 1 || n > size || ArraySize(low) != size)
|
|
return(-1);
|
|
|
|
if(ArrayResize(out, size) != size)
|
|
return(-1);
|
|
|
|
const double alpha = 2.0 / (n + 1.0);
|
|
|
|
double ema = close[0];
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
if(i > 0)
|
|
ema = (close[i] - ema) * alpha + ema;
|
|
|
|
if(i < n - 1) // warm-up, not reported
|
|
{
|
|
out[i] = EMPTY_VALUE;
|
|
continue;
|
|
}
|
|
|
|
if(!normalise)
|
|
{
|
|
out[i] = low[i] - ema;
|
|
continue;
|
|
}
|
|
|
|
out[i] = (ema > 0.0) ? (low[i] - ema) / ema * 100.0 : 0.0;
|
|
}
|
|
|
|
return(n - 1);
|
|
}
|
|
//+------------------------------------------------------------------+
|