App-financeta
view release on metacpan or search on metacpan
lib/App/financeta/indicators.pm view on Meta::CPAN
light-goldenrod
light-pink
light-turquoise
spring-green
forest-green
sea-green
midnight-blue
navy
medium-blue
skyblue
dark-turquoise
dark-pink
coral
light-coral
orange-red
dark-salmon
khaki
dark-khaki
dark-goldenrod
olive
orange
dark-violet
plum
dark-plum
dark-olivegreen
sandybrown
light-salmon
lemonchiffon
bisque
honeydew
slategrey
seagreen
chartreuse
greenyellow
gray
light-gray
light-grey
grey
dark-grey
dark-gray
slategray
black
)];
sub next_color {
my $self = shift;
my $idx = $self->color_idx; # read
my $colors = $self->colors;
$idx = 0 if $idx >= scalar @$colors; # reset;
$log->info("Using Color Index: $idx");
$self->color_idx($idx + 1); # update
return $colors->[$idx];
}
sub _plot_gnuplot_general {
my ($self, $xdata, $output, $scale) = @_;
# output is the same as the return value of the code-ref above
my @plotinfo = ();
foreach (@$output) {
my $p = (defined $scale) ? $_->[1] / $scale : $_->[1];
my %legend = (legend => $_->[0]) if length $_->[0];
my $args = $_->[2] || {};
$log->debug("Plot args: ", dumper($args));
push @plotinfo, {
with => 'lines',
axes => 'x1y1',
linecolor => $self->next_color,
%legend,
%$args,
}, $xdata, $p;
}
return wantarray ? @plotinfo : \@plotinfo;
}
sub _plot_highcharts_general {
my ($self, $xdata, $output, $scale) = @_;
my @plotinfo = ();
foreach my $o (@$output) {
## this is an array
#[0] => legend title
#[1] => PDL data
#[2] => gnuplot args or undef
#[3] => variable name for execution rules
## let's create a x-y pdl data
## highcharts requires timestamp in milliseconds;
my $xypdl = pdl($xdata * 1000, (defined $scale) ? $o->[1] / $scale : $o->[1])->transpose->setbadtoval(0);
my $xyidx = $xypdl((1))->which;
my $xypdlclean = $xypdl->dice_axis(1, $xyidx);
$log->debug($o->[0], $xypdlclean);
push @plotinfo, {
title => $o->[0],
data => encode_json $xypdlclean->unpdl,
impulses => (ref $o->[2] eq 'HASH' and $o->[2]->{with} eq 'impulses') ? 1 : 0,
id => $o->[3],
};
}
return wantarray ? @plotinfo : \@plotinfo;
}
sub _plot_gnuplot_volume {
my ($self, $xdata, $output) = @_;
my @plotinfo = $self->_plot_gnuplot_general($xdata, $output, 1e6);
return { volume => \@plotinfo };
}
sub _plot_highcharts_volume {
my ($self, $xdata, $output) = @_;
my @plotinfo = $self->_plot_highcharts_general($xdata, $output, 1e6);
return { volume => \@plotinfo };
}
sub _plot_gnuplot_additional {
my ($self, $xdata, $output) = @_;
my @plotinfo = $self->_plot_gnuplot_general($xdata, $output);
return { additional => \@plotinfo };
}
sub _plot_highcharts_additional {
my ($self, $xdata, $output) = @_;
my @plotinfo = $self->_plot_highcharts_general($xdata, $output);
return { additional => \@plotinfo };
}
sub _plot_gnuplot_buysell {
my ($self, $xdata, $output) = @_;
my $ret = { general => undef, additional => undef };
my @bsg = ();
my @bsa = ();
foreach (@$output) {
if ($_->[0] =~ /Buy|Sell/i) {
push @bsg, $_;
} else {
push @bsa, $_;
}
}
$ret->{general} = $self->_plot_gnuplot_general($xdata, \@bsg) if @bsg;
$ret->{additional} = $self->_plot_gnuplot_general($xdata, \@bsa) if @bsa;
return $ret;
}
sub _plot_highcharts_buysell {
## not required
return undef;
}
sub _plot_gnuplot_candlestick {
my ($self, $xdata, $output) = @_;
my @plotinfo = ();
foreach (@$output) {
my $p = $_->[1];
my %legend = (legend => $_->[0]) if length $_->[0];
my $args = $_->[2] || {};
$log->debug("Plot args: ", dumper($args));
push @plotinfo, {
with => 'impulses',
axes => 'x1y2',
linecolor => $self->next_color,
%legend,
%$args,
}, $xdata, $p;
}
return { candle => \@plotinfo };
}
sub _plot_gnuplot_compare {
my ($self, $xdata, $output) = @_;
if (scalar @$output >= 2) {
# we don't want to change the output variable itself
# otherwise the plots don't stay the same
my $o2 = [ @$output ]; # make a copy
my $o1 = pop @$o2;
my @g = $self->_plot_gnuplot_general($xdata, [$o1]);
my @a = $self->_plot_gnuplot_general($xdata, $o2);
return { general => \@g, additional => \@a };
} else {
my @a = $self->_plot_gnuplot_general($xdata, $output);
return { additional => \@a };
}
}
sub _plot_highcharts_candlestick {
my ($self, $xdata, $output) = @_;
my @plotinfo = ();
foreach my $o (@$output) {
## this is an array
#[0] => legend title
#[1] => PDL data
#[2] => gnuplot args or undef
#[3] => variable name for execution rules
## let's create a x-y pdl data
## highcharts requires timestamp in milliseconds;
my $xypdl = pdl($xdata * 1000, $o->[1])->transpose->setbadtoval(0);
my $xyidx = $xypdl((1))->which;
my $xypdlclean = $xypdl->dice_axis(1, $xyidx);
$log->debug($o->[0], $xypdlclean);
push @plotinfo, {
title => $o->[0],
data => encode_json $xypdlclean->unpdl,
impulses => 1,
id => $o->[3],
};
}
return { candle => \@plotinfo };
}
sub _plot_highcharts_compare {
my ($self, $xdata, $output) = @_;
if (scalar @$output >= 2) {
# we don't want to change the output variable itself
# otherwise the plots don't stay the same
my $o2 = [ @$output ]; # make a copy
my $o1 = pop @$o2;
my @g = $self->_plot_highcharts_general($xdata, [$o1]);
my @a = $self->_plot_highcharts_general($xdata, $o2);
return { general => \@g, additional => \@a };
} else {
my @a = $self->_plot_highcharts_general($xdata, $output);
return { additional => \@a };
}
}
has ma_name => {
0 => 'SMA',
1 => 'EMA',
2 => 'WMA',
3 => 'DEMA',
4 => 'TEMA',
5 => 'TRIMA',
6 => 'KAMA',
7 => 'MAMA',
8 => 'T3',
};
#TODO: verify parameters that are entered by the user
has overlaps => {
bbands => {
name => 'Bollinger Bands',
params => [
# key, pretty name, type, default value
[ 'InTimePeriod', 'Period Window (2 - 100000)', PDL::long, 5],
[ 'InNbDevUp', 'Upper Deviation multiplier', PDL::float, 2.0],
[ 'InNbDevDn', 'Lower Deviation multiplier', PDL::float, 2.0],
# this will show up in a combo list
[ 'InMAType', 'Moving Average Type', 'ARRAY',
[
'Simple', #SMA
( run in 0.614 second using v1.01-cache-2.11-cpan-9581c071862 )