Skip to content

Commit

Permalink
WIP. Indi_Bands now uses OnCalculate() method. Fixing shifts in all t…
Browse files Browse the repository at this point in the history
…he indicators.
  • Loading branch information
nseam committed Nov 3, 2022
1 parent ecc90c4 commit 545f320
Show file tree
Hide file tree
Showing 34 changed files with 293 additions and 277 deletions.
111 changes: 49 additions & 62 deletions Indicator/Details.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#Explanation of shift parameters in Indicator / IndicatorData / other classes for following methods:
#Explanation of shift parameters in Indicator / IndicatorData / other classes for following methods:
- `GetEntryValue(int _mode = 0, int _abs_shift = 0)`
- `GetEntryAlter(IndicatorDataEntry &_entry, int _rel_shift)`
- `GetValue(int _mode = 0, int _rel_shift = 0)`
Expand All @@ -11,75 +11,52 @@ Method must be overriden in any new indicator and MUST NOT apply shift from `ipa

Returns indicators's value for a given mode and absolute shift (the shift is directly passed to built-in methods such as iATR(), OnCalculate methods such as `iVIDyAOnIndicator()` and also to `iCustom()`).

For `OnCalculate()` methods such as iVIDyAOnIndicator(), the shift is passed to `return _cache.GetTailValue<double>(_mode, _shift);
` so we can return value calculated in the past(or just retrieve * *DBL_MAX * *in case the value was not yet calculated)
.Note that `OnCalculate()` methods uses single /
multiple price buffers,
e.g.,
applied price or OHLCs from base indicator.

In scenario of `VIDyA[shift = 2] < -Candle < -TickMt` call hierarchy looks like :
```cpp - VIDyA::GetEntry(_rel_shift = 1) // Then per each mode:
- entry.values[_mode] =
Indicator::GetValue(_mode, _rel_shift = 1) - VIDyA::GetEntryValue(_mode, _abs_shift = iparams.shift + 1) -
VIDyA::iVIDyAOnIndicator(..., _mode, _shift = 3) then : // Shift is absolute.
-VIDyA::iVIDyAOnArray(..., _mode, _shift = 3) then
: // Shift is absolute.
return _cache.GetTailValue<double>(_mode, _shift = 3); // Shift is absolute.
``` Last line means that we will retrieve **VIDyA **value shifted by 3(2 from `iparams.shift` + 1 from `GetEntry()`)
.It is correct.

##GetEntryAlter(IndicatorDataEntry &_entry, int _rel_shift) -
overridable method

Shift passed is relative to the shift from `IndicatorParams::shift` (read via `Indicator::iparams.shift`)
.

Method calls(seen in **MWMFI **, **CCI **, **Envelopes **, **Momentum **, **Pivot **)
:
For `OnCalculate()` methods such as iVIDyAOnIndicator(), the shift is passed to `return _cache.GetTailValue<double>(_mode, _shift);` so we can return value calculated in the past (or just retrieve **DBL_MAX** in case the value was not yet calculated).
Note that `OnCalculate()` methods uses single/multiple price buffers, e.g., applied price or OHLCs from base indicator.

In scenario of `VIDyA[shift = 2] <- Candle <- TickMt` call hierarchy looks like:
```cpp
-
GetValue<double>(_mode, _rel_shift) // GetValue<T>() takes relative shift.
- VIDyA::GetEntry(_rel_shift = 1) // Then per each mode:
- entry.values[_mode] = Indicator::GetValue(_mode, _rel_shift = 1)
- VIDyA::GetEntryValue(_mode, _abs_shift = iparams.shift + 1)
- VIDyA::iVIDyAOnIndicator(..., _mode, _shift = 3) then: // Shift is absolute.
- VIDyA::iVIDyAOnArray(..., _mode, _shift = 3) then: // Shift is absolute.
return _cache.GetTailValue<double>(_mode, _shift = 3); // Shift is absolute.
```
Last line means that we will retrieve **VIDyA** value shifted by 3 (2 from `iparams.shift` + 1 from `GetEntry()`). It is correct.

##GetValue(int _mode = 0, int _rel_shift = 0) -
non -
overridable method
## GetEntryAlter(IndicatorDataEntry &_entry, int _rel_shift) - overridable method

Shift passed is relative to the shift from `IndicatorParams::shift` (read via `Indicator::iparams.shift`)
.
Shift passed is relative to the shift from `IndicatorParams::shift` (read via `Indicator::iparams.shift`).

Method calls :
Method calls (seen in **MWMFI**, **CCI**, **Envelopes**, **Momentum**, **Pivot**):
```cpp
-
GetEntryValue(_mode, _abs_shift = iparams.shift + _rel_shift)
- GetValue<double>(_mode, _rel_shift) // GetValue<T>() takes relative shift.
```

##GetEntry(int _rel_shift = 0) -
overridable method
Shift passed is relative to the shift from `IndicatorParams::shift` (read via `Indicator::iparams.shift`)
.
If you need to access entries from absolute shift,
use `GetEntryByAbsShift(int _abs_shift)`
.
Note that values accessed via index
operator `storage[rel_shift]` e.g.,
inside `OnCalculate()` methods like `double _o =
open[rel_shift = 4].Get()` will take relative shift
and retrieve open price shifted by(in this scenario) `4 + iparams.shift` set in base indicator :
```cpp - double _o =
open[_rel_shift = 4] - IndicatorBufferValueStorage::Fetch(_rel_shift = 4) -
IndicatorData::GetValue(_mode, _rel_shift = 4) -
Indicator::GetEntryValue(
_mode, _abs_shift = iparams.shift +
4) // As GetEntryValue() takes absolute shift, we add shift from iparams.shift.
- Indicator::GetEntry(_rel_shift =
_abs_shift -
iparams.shift)... // Converting absolute shift into relative one for GetEntry().
- ...[_mode]; // IndicatorDataEntry.values[_mode].Get(...);
## GetValue(int _mode = 0, int _rel_shift = 0) - non-overridable method

Shift passed is relative to the shift from `IndicatorParams::shift` (read via `Indicator::iparams.shift`).

Method calls:
```cpp
- GetEntryValue(_mode, _abs_shift = iparams.shift + _rel_shift)
```

## GetEntry(int _rel_shift = 0) - overridable method

Shift passed is relative to the shift from `IndicatorParams::shift` (read via `Indicator::iparams.shift`).

If you need to access entries from absolute shift, use `GetEntryByAbsShift(int _abs_shift)`.

Note that values accessed via index operator `storage[rel_shift]` e.g., inside `OnCalculate()` methods like `double _o = open[rel_shift = 4].Get()` will take relative shift and retrieve open price shifted by (in this scenario) `4 + iparams.shift` set in base indicator:
```cpp
- double _o = open[_rel_shift = 4]
- IndicatorBufferValueStorage::Fetch(_rel_shift = 4)
- IndicatorData::GetValue(_mode, _rel_shift = 4)
- Indicator::GetEntryValue(_mode, _abs_shift = iparams.shift + 4) // As GetEntryValue() takes absolute shift, we add shift from iparams.shift.
- Indicator::GetEntry(_rel_shift = _abs_shift - iparams.shift)... // Converting absolute shift into relative one for GetEntry().
- ...[_mode]; // IndicatorDataEntry.values[_mode].Get(...);
```

## GetBarTime(int _rel_shift = 0)
Expand All @@ -101,3 +78,13 @@ Shift passed is relative to the shift from `IndicatorParams::shift` (read via `I
## Indi_\*::\*OnIndicator(..., _shift, [_shift1], [_shift2])

All shifts passed are relative to the shift from `IndicatorParams::shift` (read via `Indicator::iparams.shift`).

## IndicatorCalculateCache::GetValue()/GetTailValue(int _buffer_index, int _shift)

Shift passed may be relative or absolute. It depends on the ValueStorage specialization.

E.g., `HistoryValueStorage` operates on relative shifts, but `NativeValueStorage` operates on absolute shift, because it is unaware for which indicator values are stored.

Thus way, `IndicatorCalculateCache::GetValue()` and `IndicatorCalculateCache::GetTailValue()` also don't know which type of shift was passed. However, all current indicators uses `NativeValueStorage` for storing indicator values, so shift passed must is treated as absolute.

In scenario where indicator (shift **2**) has **8** values in the buffer with (assuming **10** candles have passed), `GetEntry(0)` would retrieve cache value from shift
11 changes: 7 additions & 4 deletions Indicators/Indi_ADXW.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ class Indi_ADXW : public Indicator<IndiADXWParams> {
/**
* Calculates ADX Wilder on the array of values.
*/
static double iADXWilderOnArray(INDICATOR_CALCULATE_PARAMS_LONG, int _period, int _mode, int _shift,
static double iADXWilderOnArray(INDICATOR_CALCULATE_PARAMS_LONG, int _period, int _mode, int _abs_shift,
IndicatorCalculateCache<double> *_cache, bool _recalculate = false) {
_cache.SetPriceBuffer(_open, _high, _low, _close);

Expand All @@ -142,15 +142,17 @@ class Indi_ADXW : public Indicator<IndiADXWParams> {

// Returns value from the first calculation buffer.
// Returns first value for as-series array or last value for non-as-series array.
return _cache.GetTailValue<double>(_mode, _shift);
return _cache.GetTailValue<double>(_mode, _abs_shift);
}

/**
* On-indicator version of ADX Wilder.
*/
static double iADXWilder(IndicatorData *_indi, int _period, int _mode = 0, int _shift = 0) {
static double iADXWilder(IndicatorData *_indi, int _period, int _mode = 0, int _rel_shift = 0) {
INDI_REQUIRE_BARS_OR_RETURN_EMPTY(_indi, _period);
INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG(_indi, Util::MakeKey(_period));
return iADXWilderOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _period, _mode, _shift, _cache);
return iADXWilderOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _period, _mode,
_indi PTR_DEREF ToAbsShift(_rel_shift), _cache);
}

/**
Expand All @@ -163,6 +165,7 @@ class Indi_ADXW : public Indicator<IndiADXWParams> {
ValueStorage<double> &ExtTRBuffer, ValueStorage<double> &ExtATRBuffer,
ValueStorage<double> &ExtDXBuffer, int ExtADXWPeriod) {
int i;

// Checking for bars count.
if (rates_total < ExtADXWPeriod) return (0);
// Detect start position.
Expand Down
4 changes: 2 additions & 2 deletions Indicators/Indi_AMA.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class Indi_AMA : public Indicator<IndiAMAParams> {
* Calculates AMA on the array of values.
*/
static double iAMAOnArray(INDICATOR_CALCULATE_PARAMS_SHORT, int _ama_period, int _fast_ema_period,
int _slow_ema_period, int _ama_shift, int _mode, int _shift,
int _slow_ema_period, int _ama_shift, int _mode, int _abs_shift,
IndicatorCalculateCache<double> *_cache, bool _recalculate = false) {
_cache.SetPriceBuffer(_price);

Expand All @@ -127,7 +127,7 @@ class Indi_AMA : public Indicator<IndiAMAParams> {
_cache.SetPrevCalculated(Indi_AMA::Calculate(INDICATOR_CALCULATE_GET_PARAMS_SHORT, _cache.GetBuffer<double>(0),
_ama_period, _fast_ema_period, _slow_ema_period, _ama_shift));

return _cache.GetTailValue<double>(_mode, _shift);
return _cache.GetTailValue<double>(_mode, _abs_shift);
}

/**
Expand Down
9 changes: 5 additions & 4 deletions Indicators/Indi_ASI.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,16 @@ class Indi_ASI : public Indicator<IndiASIParams> {
/**
* OnCalculate-based version of ASI as there is no built-in one.
*/
static double iASI(IndicatorData *_indi, double _mpc, int _mode = 0, int _shift = 0) {
static double iASI(IndicatorData *_indi, double _mpc, int _mode = 0, int _rel_shift = 0) {
INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG(_indi, Util::MakeKey(_mpc));
return iASIOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _mpc, _mode, _shift, _cache);
return iASIOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _mpc, _mode, _indi PTR_DEREF ToAbsShift(_rel_shift),
_cache);
}

/**
* Calculates ASI on the array of values.
*/
static double iASIOnArray(INDICATOR_CALCULATE_PARAMS_LONG, double _mpc, int _mode, int _shift,
static double iASIOnArray(INDICATOR_CALCULATE_PARAMS_LONG, double _mpc, int _mode, int _abs_shift,
IndicatorCalculateCache<double> *_cache, bool _recalculate = false) {
_cache.SetPriceBuffer(_open, _high, _low, _close);

Expand All @@ -123,7 +124,7 @@ class Indi_ASI : public Indicator<IndiASIParams> {
_cache.SetPrevCalculated(Indi_ASI::Calculate(INDICATOR_CALCULATE_GET_PARAMS_LONG, _cache.GetBuffer<double>(0),
_cache.GetBuffer<double>(1), _cache.GetBuffer<double>(2), _mpc));

return _cache.GetTailValue<double>(_mode, _shift);
return _cache.GetTailValue<double>(_mode, _abs_shift);
}

/**
Expand Down
14 changes: 8 additions & 6 deletions Indicators/Indi_BWZT.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class Indi_BWZT : public Indicator<IndiBWZTParams> {
/**
* OnCalculate-based version of BWZT as there is no built-in one.
*/
static double iBWZT(IndicatorData *_indi, int _mode = 0, int _shift = 0) {
static double iBWZT(IndicatorData *_indi, int _mode = 0, int _rel_shift = 0) {
INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG(_indi, "");

// Will return Indi_AC with the same candles source as _indi's.
Expand All @@ -127,13 +127,14 @@ class Indi_BWZT : public Indicator<IndiBWZTParams> {
// Will return Indi_AO with the same candles source as _indi's.
Indi_AO *_indi_ao = Indi_AO::GetCached(_indi);

return iBWZTOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _mode, _shift, _cache, _indi_ac, _indi_ao);
return iBWZTOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _mode, _indi PTR_DEREF ToAbsShift(_rel_shift),
_cache, _indi_ac, _indi_ao);
}

/**
* Calculates BWZT on the array of values.
*/
static double iBWZTOnArray(INDICATOR_CALCULATE_PARAMS_LONG, int _mode, int _shift,
static double iBWZTOnArray(INDICATOR_CALCULATE_PARAMS_LONG, int _mode, int _abs_shift,
IndicatorCalculateCache<double> *_cache, Indi_AC *_indi_ac, Indi_AO *_indi_ao,
bool _recalculate = false) {
_cache.SetPriceBuffer(_open, _high, _low, _close);
Expand All @@ -151,20 +152,21 @@ class Indi_BWZT : public Indicator<IndiBWZTParams> {
_cache.GetBuffer<double>(2), _cache.GetBuffer<double>(3), _cache.GetBuffer<double>(4),
_cache.GetBuffer<double>(5), _cache.GetBuffer<double>(6), 38, _indi_ac, _indi_ao));

return _cache.GetTailValue<double>(_mode, _shift);
return _cache.GetTailValue<double>(_mode, _abs_shift);
}

/**
* On-indicator version of BWZT.
*/
static double iBWZTOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _mode, int _shift,
static double iBWZTOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _mode, int _rel_shift,
IndicatorData *_obj) {
INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG(_indi, Util::MakeKey("Indi_BWZT_ON_" + _indi.GetFullName()));

Indi_AC *_indi_ac = _obj.GetDataSource(INDI_AC);
Indi_AO *_indi_ao = _obj.GetDataSource(INDI_AO);

return iBWZTOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _mode, _shift, _cache, _indi_ac, _indi_ao);
return iBWZTOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _mode, _indi PTR_DEREF ToAbsShift(_rel_shift),
_cache, _indi_ac, _indi_ao);
}

/**
Expand Down
Loading

0 comments on commit 545f320

Please sign in to comment.