File Coverage

blib/lib/Math/Business/ConnorRSI.pm
Criterion Covered Total %
statement 80 82 97.5
branch 22 30 73.3
condition 11 14 78.5
subroutine 11 13 84.6
pod 0 9 0.0
total 124 148 83.7


line stmt bran cond sub pod time code
1             package Math::Business::ConnorRSI;
2              
3 1     1   4123 use strict;
  1         7  
  1         24  
4 1     1   4 use warnings;
  1         1  
  1         20  
5 1     1   4 use Carp;
  1         2  
  1         40  
6              
7 1     1   339 use Math::Business::RSI;
  1         2  
  1         662  
8              
9             1;
10              
11 0     0 0 0 sub tag { (shift)->{tag} }
12              
13 0     0 0 0 sub recommended { (shift)->new() }
14              
15             sub new {
16 1     1 0 12 my $class = shift;
17 1         4 my $this = bless {}, $class;
18              
19 1   50     5 $this->set_cdays(shift || 3);
20 1   50     5 $this->set_sdays(shift || 2);
21 1   50     5 $this->set_pdays(shift || 100);
22              
23 1         6 $this->{cRSI} = Math::Business::RSI->new($this->{cdays});
24 1         3 $this->{sRSI} = Math::Business::RSI->new($this->{sdays});
25              
26 1         3 return $this;
27             }
28              
29             sub reset {
30 3     3 0 5 my $this = shift;
31              
32 3         5 delete $this->{cy};
33 3         3 delete $this->{st};
34              
35 3 50       5 $this->{cRSI} = Math::Business::RSI->new($this->{cdays}) if exists $this->{cRSI};
36 3 50       6 $this->{sRSI} = Math::Business::RSI->new($this->{sdays}) if exists $this->{sRSI};
37 3         7 $this->{prar} = [];
38             }
39              
40             sub set_cdays {
41 1     1 0 2 my $this = shift;
42 1         2 my $arg = int(shift);
43              
44 1 50       3 croak "days must be a positive non-zero integer" if $arg <= 0;
45              
46 1         4 $this->{cdays} = $arg;
47             $this->{tag} = "CRSI($this->{cdays},$this->{sdays},$this->{pdays})"
48 1 50       4 unless grep {not defined} @$this{qw(cdays sdays pdays)};
  3         7  
49              
50 1         4 $this->reset;
51             }
52              
53             sub set_sdays {
54 1     1 0 2 my $this = shift;
55 1         2 my $arg = int(shift);
56              
57 1 50       3 croak "days must be a positive non-zero integer" if $arg <= 0;
58              
59 1         2 $this->{sdays} = $arg;
60             $this->{tag} = "CRSI($this->{cdays},$this->{sdays},$this->{pdays})"
61 1 50       4 unless grep {not defined} @$this{qw(cdays sdays pdays)};
  3         6  
62              
63 1         2 $this->reset;
64             }
65              
66             sub set_pdays {
67 1     1 0 2 my $this = shift;
68 1         2 my $arg = int(shift);
69              
70 1 50       3 croak "days must be a positive non-zero integer" if $arg <= 0;
71              
72 1         2 $this->{pdays} = $arg;
73             $this->{tag} = "CRSI($this->{cdays},$this->{sdays},$this->{pdays})"
74 1 50       3 unless grep {not defined} @$this{qw(cdays sdays pdays)};
  3         11  
75              
76 1         2 $this->reset;
77             }
78              
79             sub insert {
80 1258     1258 0 6159 my $this = shift;
81 1258         1607 my $close_yesterday = $this->{cy};
82 1258   100     2034 my $streak = $this->{st} || 0;
83              
84 1258         1507 my $sRSI = $this->{sRSI};
85 1258         1466 my $cRSI = $this->{cRSI};
86 1258         1430 my $prar = $this->{prar};
87 1258         1555 my $pdays = $this->{pdays};
88              
89             # we store 1 extra so we can compare $pdays values
90 1258         1503 my $pdaysp1 = $pdays + 1;
91              
92 1258         2308 while( defined( my $close_today = shift ) ) {
93 1258 100       1892 if( defined $close_yesterday ) {
94 1257 100       2897 if( $close_yesterday > $close_today ) {
    100          
95 628 100       938 $streak = $streak >= 0 ? -1 : $streak-1;
96              
97             } elsif( $close_yesterday < $close_today ) {
98 622 100       935 $streak = $streak <= 0 ? 1 : $streak+1;
99              
100             } else {
101 7         14 $streak = 0;
102             }
103              
104 1257         2716 $sRSI->insert($streak);
105              
106 1257         2025 push @$prar, ($close_today - $close_yesterday)/$close_yesterday;
107 1257         2680 shift @$prar while @$prar > $pdaysp1;
108             }
109              
110 1258         2451 $cRSI->insert($close_today);
111              
112 1258         2195 $close_yesterday = $close_today;
113             }
114              
115 1258         1992 $this->{srsi} = my $srsi = $sRSI->query;
116 1258         2030 $this->{crsi} = my $crsi = $cRSI->query;
117              
118 1258 100 100     4563 if( defined $srsi and defined $crsi and @$prar==$pdaysp1 ) {
      100        
119 1157         1539 my $v = $prar->[-1];
120 1157         1292 my $p = 0;
121 1157         1406 my $i = $#$prar;
122              
123             # we skip the first one, cuz that's $v
124 1157         1846 while( (--$i) >= 0 ) {
125 115700 100       191691 $p ++ if $prar->[$i] < $v;
126             }
127              
128 1157         1816 $this->{prank} = my $PR = 100 * ($p/$pdays);
129 1157         1820 $this->{connor} = ( $srsi + $crsi + $PR ) / 3;
130             }
131              
132 1258         1588 $this->{cy} = $close_yesterday;
133 1258         2067 $this->{st} = $streak;
134             }
135              
136             sub query {
137 1258     1258 0 2868 my $this = shift;
138              
139 1258         1973 return $this->{connor};
140             }
141              
142             __END__