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   3525 use strict;
  1         5  
  1         20  
4 1     1   3 use warnings;
  1         2  
  1         17  
5 1     1   3 use Carp;
  1         1  
  1         34  
6              
7 1     1   298 use Math::Business::RSI;
  1         2  
  1         552  
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 9 my $class = shift;
17 1         3 my $this = bless {}, $class;
18              
19 1   50     4 $this->set_cdays(shift || 3);
20 1   50     4 $this->set_sdays(shift || 2);
21 1   50     4 $this->set_pdays(shift || 100);
22              
23 1         4 $this->{cRSI} = Math::Business::RSI->new($this->{cdays});
24 1         3 $this->{sRSI} = Math::Business::RSI->new($this->{sdays});
25              
26 1         2 return $this;
27             }
28              
29             sub reset {
30 3     3 0 5 my $this = shift;
31              
32 3         4 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       5 $this->{sRSI} = Math::Business::RSI->new($this->{sdays}) if exists $this->{sRSI};
37 3         5 $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         3 $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         6  
49              
50 1         2 $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       3 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         1 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       2 unless grep {not defined} @$this{qw(cdays sdays pdays)};
  3         8  
75              
76 1         2 $this->reset;
77             }
78              
79             sub insert {
80 1258     1258 0 4827 my $this = shift;
81 1258         1294 my $close_yesterday = $this->{cy};
82 1258   100     1693 my $streak = $this->{st} || 0;
83              
84 1258         1177 my $sRSI = $this->{sRSI};
85 1258         1146 my $cRSI = $this->{cRSI};
86 1258         1146 my $prar = $this->{prar};
87 1258         1208 my $pdays = $this->{pdays};
88              
89             # we store 1 extra so we can compare $pdays values
90 1258         1250 my $pdaysp1 = $pdays + 1;
91              
92 1258         1748 while( defined( my $close_today = shift ) ) {
93 1258 100       1443 if( defined $close_yesterday ) {
94 1257 100       2354 if( $close_yesterday > $close_today ) {
    100          
95 628 100       752 $streak = $streak >= 0 ? -1 : $streak-1;
96              
97             } elsif( $close_yesterday < $close_today ) {
98 622 100       770 $streak = $streak <= 0 ? 1 : $streak+1;
99              
100             } else {
101 7         11 $streak = 0;
102             }
103              
104 1257         2100 $sRSI->insert($streak);
105              
106 1257         1466 push @$prar, ($close_today - $close_yesterday)/$close_yesterday;
107 1257         2197 shift @$prar while @$prar > $pdaysp1;
108             }
109              
110 1258         2080 $cRSI->insert($close_today);
111              
112 1258         1784 $close_yesterday = $close_today;
113             }
114              
115 1258         1991 $this->{srsi} = my $srsi = $sRSI->query;
116 1258         1533 $this->{crsi} = my $crsi = $cRSI->query;
117              
118 1258 100 100     3339 if( defined $srsi and defined $crsi and @$prar==$pdaysp1 ) {
      100        
119 1157         1181 my $v = $prar->[-1];
120 1157         1085 my $p = 0;
121 1157         1064 my $i = $#$prar;
122              
123             # we skip the first one, cuz that's $v
124 1157         1519 while( (--$i) >= 0 ) {
125 115700 100       156295 $p ++ if $prar->[$i] < $v;
126             }
127              
128 1157         1455 $this->{prank} = my $PR = 100 * ($p/$pdays);
129 1157         1409 $this->{connor} = ( $srsi + $crsi + $PR ) / 3;
130             }
131              
132 1258         1300 $this->{cy} = $close_yesterday;
133 1258         1643 $this->{st} = $streak;
134             }
135              
136             sub query {
137 1258     1258 0 2325 my $this = shift;
138              
139 1258         1574 return $this->{connor};
140             }
141              
142             __END__