Completed
Push — master ( 762814...853e43 )
by
unknown
9s
created

__invoke()   D

Complexity

Conditions 9
Paths 16

Size

Total Lines 34
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 90

Importance

Changes 0
Metric Value
dl 0
loc 34
ccs 0
cts 18
cp 0
rs 4.909
c 0
b 0
f 0
cc 9
eloc 18
nc 16
nop 2
crap 90
1
<?php
2
3
namespace Laratrade\Indicators;
4
5
use Illuminate\Support\Collection;
6
use Laratrade\Indicators\Contracts\Indicator;
7
use Laratrade\Indicators\Exceptions\NotEnoughDataPointsException;
8
9
/**
10
 * Hilbert Transform - Instantaneous Trendline 
11
 *
12
 *
13
 * @see http://www2.wealth-lab.com/WL5Wiki/HTTrendLine.ashx
14
 *
15
 *
16
 * The Hilbert Transform is a technique used to generate inphase and quadrature components of a de-trended real-valued
17
 * "analytic-like" signal (such as a Price Series) in order to analyze variations of the instantaneous phase and
18
 * amplitude. HTTrendline (or MESA Instantaneous Trendline) returns the Price Series value after the Dominant Cycle of
19
 * the analytic signal as generated by the Hilbert Transform has been removed. The Dominant Cycle can be thought of as
20
 * being the "most likely" period (in the range of 10 to 40) of a sine function of the Price Series.
21
 *
22
 * smoothed trendline, if the
23
 * price moves 1.5% away from the trendline we can declare a trend.
24
 *
25
 *
26
 * WMA(4)
27
 * trader_ht_trendline
28
 *
29
 * if WMA(4) < htl for five periods then in downtrend (sell in trend mode)
30
 * if WMA(4) > htl for five periods then in uptrend   (buy in trend mode)
31
 *
32
 * // if price is 1.5% more than trendline, then  declare a trend
33
 * (WMA(4)-trendline)/trendline >= 0.15 then trend = 1
34
 */
35
class HilbertTransformInstantaneousTrendlineIndicator implements Indicator
36
{
37
38
    public function __invoke(Collection $ohlcv, int $period = 14): int
39
    {
40
41
        $declared = $uptrend = $downtrend = 0;
42
        $a_htl = $a_wma4 = [];
43
        $htl = trader_ht_trendline($ohlcv->get('close'));
44
45
        if (false === $htl) {
46
            throw new NotEnoughDataPointsException('Not enough data points');
47
        }
48
49
50
        $wma4 = trader_wma($ohlcv->get('close'), 4);
51
52
        for ($a = 0; $a < 5; $a++) {
53
            $a_htl[$a] = array_pop($htl);
54
            $a_wma4[$a] = array_pop($wma4);
55
            $uptrend += ($a_wma4[$a] > $a_htl[$a] ? 1 : 0);
56
            $downtrend += ($a_wma4[$a] < $a_htl[$a] ? 1 : 0);
57
58
            $declared = (($a_wma4[$a] - $a_htl[$a]) / $a_htl[$a]);
59
        }
60
61
62
        if ($uptrend || $declared >= 0.15) {
63
            return static::BUY;
64
        }
65
66
        if ($downtrend || $declared <= 0.15) {
67
            return static::SELL;
68
        }
69
70
        return static::HOLD;
71
    }
72
}
73