pbo-cscv-engine/Include/PBO/BearsPower.mqh

75 lines
3.4 KiB
MQL5
Raw Permalink Normal View History

//+------------------------------------------------------------------+
//| 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);
}
//+------------------------------------------------------------------+