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

AverageTrueRangeIndicator::__invoke()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 39
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 39
ccs 0
cts 21
cp 0
rs 8.439
c 0
b 0
f 0
cc 5
eloc 21
nc 8
nop 2
crap 30
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
 * Average True Range
11
 *
12
 * @see http://www.investopedia.com/articles/trading/08/atr.asp
13
 *
14
 * The idea is to use ATR to identify breakouts, if the price goes higher than
15
 * the previous close + ATR, a price breakout has occurred.
16
 *
17
 * The position is closed when the price goes 1 ATR below the previous close.
18
 *
19
 * This algorithm uses ATR as a momentum strategy, but the same signal can be used for
20
 * a reversion strategy, since ATR doesn't indicate the price direction (like adx below)
21
 */
22
class AverageTrueRangeIndicator implements Indicator
23
{
24
25
    public function __invoke(Collection $ohlcv, int $period = 14): int
26
    {
27
28
        if ($period > count($ohlcv->get('close'))) {
29
            $period = round(count($ohlcv->get('close')) / 2);
30
        }
31
32
        $data2 = $ohlcv;
33
        $current = array_pop($data2->get('close')); //[count($data['close']) - 1];    // we assume this is current
0 ignored issues
show
Bug introduced by
$data2->get('close') cannot be passed to array_pop() as the parameter $array expects a reference.
Loading history...
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
34
        $prev_close = array_pop($data2->get('close')); //[count($data['close']) - 2]; // prior close
0 ignored issues
show
Bug introduced by
$data2->get('close') cannot be passed to array_pop() as the parameter $array expects a reference.
Loading history...
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
35
36
        $atr = trader_atr(
37
            $ohlcv->get('high'),
38
            $ohlcv->get('low'),
39
            $ohlcv->get('close'),
40
            $period
41
        );
42
43
        if (false === $atr) {
44
            throw new NotEnoughDataPointsException('Not enough data points');
45
        }
46
47
48
        $atr = array_pop($atr); // pick off the last
49
50
        // An upside breakout occurs when the price goes 1 ATR above the previous close
51
        $upside_signal = ($current - ($prev_close + $atr));
52
53
        // A downside breakout occurs when the previous close is 1 ATR above the price
54
        $downside_signal = ($prev_close - ($current + $atr));
55
56
        if ($upside_signal > 0) {
57
            return static::BUY;
58
        } elseif ($downside_signal > 0) {
59
            return static::SELL;
60
        }
61
62
        return static::HOLD;
63
    }
64
}
65