line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Math::Business::LaguerreFilter; |
2
|
|
|
|
|
|
|
|
3
|
2
|
|
|
2
|
|
16152
|
use strict; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
88
|
|
4
|
2
|
|
|
2
|
|
11
|
use warnings; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
62
|
|
5
|
2
|
|
|
2
|
|
11
|
use Carp; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
242
|
|
6
|
|
|
|
|
|
|
use constant { |
7
|
2
|
|
|
|
|
1514
|
ALPHA => 2, |
8
|
|
|
|
|
|
|
LENGTH => 3, |
9
|
|
|
|
|
|
|
F => -2, |
10
|
|
|
|
|
|
|
TAG => -1, |
11
|
2
|
|
|
2
|
|
13
|
}; |
|
2
|
|
|
|
|
4
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
1; |
14
|
|
|
|
|
|
|
|
15
|
0
|
|
|
0
|
0
|
0
|
sub tag { (shift)->[TAG] } |
16
|
|
|
|
|
|
|
|
17
|
0
|
|
|
0
|
0
|
0
|
sub recommended { croak "no recommendation" } |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
sub dnew { |
20
|
0
|
|
|
0
|
0
|
0
|
my $class = shift; |
21
|
0
|
0
|
|
|
|
0
|
my $days = int shift; $days = 4 unless $days > 1; |
|
0
|
|
|
|
|
0
|
|
22
|
0
|
|
|
|
|
0
|
my $this = $class->new(2/(1+$days)); |
23
|
|
|
|
|
|
|
|
24
|
0
|
|
|
|
|
0
|
return $this; |
25
|
|
|
|
|
|
|
} |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
sub new { |
28
|
2
|
|
|
2
|
0
|
1111
|
my $class = shift; |
29
|
2
|
|
|
|
|
11
|
my $this = bless [], $class; |
30
|
|
|
|
|
|
|
|
31
|
2
|
|
|
|
|
8
|
my $alpha = shift; |
32
|
2
|
50
|
|
|
|
13
|
if( defined $alpha ) { |
33
|
2
|
|
|
|
|
12
|
$this->set_alpha( $alpha ); |
34
|
|
|
|
|
|
|
} |
35
|
|
|
|
|
|
|
|
36
|
2
|
|
|
|
|
5
|
my $length = shift; |
37
|
2
|
50
|
|
|
|
10
|
if( defined $length ) { |
38
|
0
|
|
|
|
|
0
|
$this->set_adaptive( $length ); |
39
|
|
|
|
|
|
|
} |
40
|
|
|
|
|
|
|
|
41
|
2
|
|
|
|
|
8
|
return $this; |
42
|
|
|
|
|
|
|
} |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
sub set_days { |
45
|
0
|
|
|
0
|
0
|
0
|
my $this = shift; |
46
|
0
|
|
|
|
|
0
|
my $arg = 0+shift; |
47
|
|
|
|
|
|
|
|
48
|
0
|
|
|
|
|
0
|
my $alpha = 2/(1+$arg); |
49
|
0
|
|
|
|
|
0
|
eval { $this->set_alpha( $alpha ) }; |
|
0
|
|
|
|
|
0
|
|
50
|
0
|
0
|
|
|
|
0
|
croak "set_days() is basically set_alpha(2/(1+$arg)), which complained: $@" if $@; |
51
|
|
|
|
|
|
|
|
52
|
0
|
|
|
|
|
0
|
$this->{tag} = "LAG($arg)"; |
53
|
|
|
|
|
|
|
} |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
sub set_alpha { |
56
|
2
|
|
|
2
|
0
|
6
|
my $this = shift; |
57
|
2
|
|
|
|
|
9
|
my $alpha = 0+shift; |
58
|
|
|
|
|
|
|
|
59
|
2
|
50
|
33
|
|
|
32
|
croak "alpha must be a real between >=0 and <=1" unless $alpha >= 0 and $alpha <= 1; |
60
|
2
|
|
|
|
|
26
|
@$this = ( |
61
|
|
|
|
|
|
|
[], # P-hist |
62
|
|
|
|
|
|
|
[], # L0-L4 |
63
|
|
|
|
|
|
|
$alpha, |
64
|
|
|
|
|
|
|
0, # adaptive length |
65
|
|
|
|
|
|
|
[], # adaptive diff history |
66
|
|
|
|
|
|
|
undef, # filter |
67
|
|
|
|
|
|
|
undef, # tag |
68
|
|
|
|
|
|
|
); |
69
|
|
|
|
|
|
|
|
70
|
2
|
|
|
|
|
11
|
my $arg = int ( (1/$alpha)*2-1 ); # pretty sure... gah, algebra |
71
|
2
|
|
|
|
|
14
|
$this->[TAG] = "LAG($arg)"; |
72
|
|
|
|
|
|
|
} |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
sub set_adaptive { |
75
|
1
|
|
|
1
|
0
|
7
|
my $this = shift; |
76
|
1
|
|
|
|
|
2
|
my $that = int shift; |
77
|
|
|
|
|
|
|
|
78
|
1
|
50
|
|
|
|
5
|
croak "adaptive length must be an non-negative integer" unless $that >= 0; |
79
|
1
|
|
|
|
|
4
|
$this->[LENGTH] = $that; |
80
|
|
|
|
|
|
|
} |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
sub insert { |
83
|
7002
|
|
|
7002
|
0
|
440731
|
my $this = shift; |
84
|
7002
|
|
|
|
|
15784
|
my ($h, $L, $alpha, $length, $diff, $filter) = @$this; |
85
|
|
|
|
|
|
|
|
86
|
7002
|
50
|
|
|
|
15901
|
croak "You must set the number of days before you try to insert" if not defined $alpha; |
87
|
2
|
|
|
2
|
|
22
|
no warnings 'uninitialized'; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
1212
|
|
88
|
|
|
|
|
|
|
|
89
|
7002
|
|
|
|
|
17299
|
while( defined( my $P = shift ) ) { |
90
|
7002
|
50
|
|
|
|
15671
|
if( ref $P ) { |
91
|
0
|
0
|
|
|
|
0
|
my @a = eval {@$P}; croak $@ if $@; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
92
|
0
|
|
|
|
|
0
|
my $c = 0+@a; |
93
|
0
|
0
|
|
|
|
0
|
croak "high+low should only be two elements, not c=$c" unless $c == 2; |
94
|
0
|
|
|
|
|
0
|
$P = ($a[0]+$a[1])/$c; |
95
|
|
|
|
|
|
|
} |
96
|
|
|
|
|
|
|
|
97
|
7002
|
100
|
|
|
|
13389
|
if( defined $L->[0] ) { |
98
|
|
|
|
|
|
|
# adapt alpha {{{ |
99
|
7000
|
100
|
100
|
|
|
30071
|
if( $length and defined($filter) ) { |
100
|
3497
|
|
|
|
|
7266
|
my $d = abs($P-$filter); |
101
|
3497
|
|
|
|
|
7325
|
push @$diff, $d; |
102
|
|
|
|
|
|
|
|
103
|
3497
|
|
|
|
|
5898
|
my $k = @$diff - $length; |
104
|
3497
|
100
|
|
|
|
10464
|
splice @$diff, 0, $k if $k>0; |
105
|
|
|
|
|
|
|
|
106
|
3497
|
100
|
|
|
|
7226
|
if( $k > 0 ) { # NOTE Ehler really does this, "CurrentBar > Length". See below. |
107
|
|
|
|
|
|
|
# IE, $k will only by >0 when we've moved past the 20th point |
108
|
3477
|
|
|
|
|
5354
|
my $HH = $d; |
109
|
3477
|
|
|
|
|
4087
|
my $LL = $d; |
110
|
|
|
|
|
|
|
|
111
|
3477
|
|
|
|
|
6547
|
for(@$diff) { |
112
|
69540
|
100
|
|
|
|
178189
|
$HH = $_ if $_ > $HH; |
113
|
69540
|
100
|
|
|
|
182869
|
$LL = $_ if $_ < $LL; |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
3477
|
50
|
|
|
|
10029
|
if( $HH != $LL ) { |
117
|
|
|
|
|
|
|
# Ehler: If CurrentBar > Length and HH - LL <> 0 then alpha = Median(((Diff - LL) / (HH - LL)), 5); |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
# NOTE: wtf is a "5 bar median"? I guess it's this, or |
120
|
|
|
|
|
|
|
# pretty close to it. I imagine Median() runs through |
121
|
|
|
|
|
|
|
# the [] hist for Diff, LL, and HH, but I can't say for |
122
|
|
|
|
|
|
|
# sure without access to the programming language he |
123
|
|
|
|
|
|
|
# uses in the book. |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
# AVG # my $sum = ($diff->[-5]-$LL)/($HH-$LL); |
126
|
|
|
|
|
|
|
# AVG # $sum += ($diff->[$_]-$LL)/($HH-$LL) for (-4 .. -1); |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
# AVG # ($this->[ALPHA] = $alpha = $sum / 5); |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
# NOTE (later): he appears to mean the median (not |
131
|
|
|
|
|
|
|
# average) of a scalar $HH/$LL against the last 5 @diff |
132
|
|
|
|
|
|
|
|
133
|
3477
|
|
|
|
|
6240
|
my @b5 = sort {$a<=>$b}map {(($diff->[$_]-$LL)/($HH-$LL))} -5 .. -1; |
|
25903
|
|
|
|
|
62410
|
|
|
17385
|
|
|
|
|
60792
|
|
134
|
|
|
|
|
|
|
|
135
|
3477
|
|
|
|
|
13568
|
$this->[ALPHA] = $alpha = $b5[2]; |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
} |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
# }}} |
140
|
|
|
|
|
|
|
|
141
|
7000
|
|
|
|
|
18450
|
my $O = [ @$L ]; |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
# L0 = alpha*Price + (1 - alpha)*L0[1] = alpha*P + (1-alpha)*O[0] |
144
|
|
|
|
|
|
|
|
145
|
7000
|
|
|
|
|
15725
|
$L->[0] = $alpha*$P + (1-$alpha)*$O->[0]; |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
# L1 = (1 - alpha)*L1[1] - (1 - alpha)*L0 + L0[1] = (1 - alpha)*O[1] - (1 - alpha)*L[0] + O[0] |
148
|
|
|
|
|
|
|
# L2 = (1 - alpha)*L2[1] - (1 - alpha)*L1 + L1[1] = (1 - alpha)*O[2] - (1 - alpha)*L[1] + O[1] |
149
|
|
|
|
|
|
|
# L3 = (1 - alpha)*L3[1] - (1 - alpha)*L2 + L2[1] = (1 - alpha)*O[3] - (1 - alpha)*L[2] + O[2] |
150
|
|
|
|
|
|
|
|
151
|
7000
|
100
|
|
|
|
23743
|
$L->[1] = defined($O->[1]) ? (1 - $alpha)*$O->[1] - (1 - $alpha)*$L->[0] + $O->[0] : $O->[0]; |
152
|
7000
|
100
|
|
|
|
17792
|
$L->[2] = defined($O->[2]) ? (1 - $alpha)*$O->[2] - (1 - $alpha)*$L->[1] + $O->[1] : $O->[1]; |
153
|
7000
|
100
|
|
|
|
39691
|
$L->[3] = defined($O->[3]) ? (1 - $alpha)*$O->[3] - (1 - $alpha)*$L->[2] + $O->[2] : $O->[2]; |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
} else { |
156
|
2
|
|
|
|
|
12
|
$L->[0] = $P; |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
|
160
|
7002
|
100
|
|
|
|
11622
|
if( 4 == grep {defined $_} @$L ) { |
|
28002
|
|
|
|
|
70678
|
|
161
|
6996
|
|
|
|
|
36328
|
$this->[F] = ($L->[0] + 2*$L->[1] + 2*$L->[2] + $L->[3])/6; |
162
|
|
|
|
|
|
|
} |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
sub query { |
166
|
7002
|
|
|
7002
|
0
|
36438
|
my $this = shift; |
167
|
|
|
|
|
|
|
|
168
|
7002
|
|
|
|
|
19915
|
return $this->[F]; |
169
|
|
|
|
|
|
|
} |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
__END__ |