view release on metacpan or search on metacpan
'Pod::Usage' => '2.03',
'Data::Dumper' => '2.183',
'File::Spec' => '3.78',
'File::ShareDir' => '1.118',
'File::HomeDir' => '1.006',
'File::Path' => '2.18',
'Path::Tiny' => '0.144',
'Capture::Tiny' => '0.48',
'Try::Tiny' => '0.31',
'PDL' => '2.081',
'DateTime' => '1.59',
'DateTime::Format::Strptime' => '1.79',
'Finance::QuoteHist' => '1.32',
'LWP::UserAgent' => '6.52',
'JSON::XS' => '4.03',
'PDL::Finance::TA' => '0.010',
'Prima' => '1.68002',
'PDL::Graphics::Gnuplot' => '2.021',
'Scalar::Util' => '1.63',
'Getopt::Long' => '2.54',
'Browser::Open' => '0.04',
'YAML::Any' => '1.30',
"Module::Build" : "0"
}
},
"runtime" : {
"requires" : {
"Browser::Open" : "0.04",
"Capture::Tiny" : "0.48",
"Carp" : "0",
"Cwd" : "0",
"Data::Dumper" : "2.183",
"DateTime" : "1.59",
"DateTime::Format::Strptime" : "1.79",
"File::HomeDir" : "1.006",
"File::Path" : "2.18",
"File::ShareDir" : "1.118",
"File::Spec" : "3.78",
"Finance::QuoteHist" : "1.32",
"Getopt::Long" : "2.54",
"JSON::XS" : "4.03",
"LWP::UserAgent" : "6.52",
"Log::Any" : "1.713",
"PDL" : "2.081",
version: '0.16'
App::financeta::utils:
file: lib/App/financeta/utils.pm
version: '0.16'
requires:
Browser::Open: '0.04'
Capture::Tiny: '0.48'
Carp: '0'
Cwd: '0'
Data::Dumper: '2.183'
DateTime: '1.59'
DateTime::Format::Strptime: '1.79'
File::HomeDir: '1.006'
File::Path: '2.18'
File::ShareDir: '1.118'
File::Spec: '3.78'
Finance::QuoteHist: '1.32'
Getopt::Long: '2.54'
JSON::XS: '4.03'
LWP::UserAgent: '6.52'
Log::Any: '1.713'
PDL: '2.081'
lib/App/financeta/data/gemini.pm view on Meta::CPAN
package App::financeta::data::gemini;
use strict;
use warnings;
use 5.10.0;
use Try::Tiny;
use LWP::UserAgent;
use JSON::XS qw(decode_json);
use DateTime;
use App::financeta::utils qw(dumper log_filter);
use Log::Any '$log', filter => \&App::financeta::utils::log_filter;
use PDL::Lite;#for pdl
our $VERSION = '0.16';
$VERSION = eval $VERSION;
#our @EXPORT_OK = (qw(ohlcv));
sub ohlcv {
my ($symbol, $start_date, $end_date) = @_;
my $data;
try {
$log->info("Starting to download quotes for $symbol for date range: $start_date -> $end_date");
my $start_time = (ref $start_date eq 'DateTime') ? $start_date->epoch() : DateTime->new($start_date)->set_time_zone('UTC')->epoch;
my $end_time = (ref $end_date eq 'DateTime') ? $end_date->epoch() : DateTime->new($end_date)->set_time_zone('UTC')->epoch;
my $difftime = abs($end_time - $start_time);
$log->debug("Start Date $start_date is $start_time in UNIX time");
$log->debug("End Date $end_date is $end_time in UNIX time");
my $granularity;
if ($difftime <= 86400) {
$granularity = '1m';
} elsif ($difftime <= 5 * 86400) {
$granularity = '5m';
} elsif ($difftime <= 30 * 86400) {
$granularity = '15m';
lib/App/financeta/data/yahoo.pm view on Meta::CPAN
package App::financeta::data::yahoo;
use strict;
use warnings;
use 5.10.0;
use Try::Tiny;
use Finance::QuoteHist;
use DateTime;
use App::financeta::utils qw(dumper log_filter);
use Log::Any '$log', filter => \&App::financeta::utils::log_filter;
use PDL::Lite;#for pdl
our $VERSION = '0.16';
$VERSION = eval $VERSION;
#our @EXPORT_OK = (qw(ohlcv));
sub ohlcv {
my ($symbol, $start_date, $end_date) = @_;
my $data;
try {
my @quotes = ();
my $fq = Finance::QuoteHist->new(
symbols => [ $symbol ],
start_date => (ref $start_date eq 'DateTime') ? $start_date->mdy('/') : DateTime->new($start_date)->mdy('/'),
end_date => (ref $end_date eq 'DateTime') ? $end_date->mdy('/') : DateTime->new($end_date)->mdy('/'),
auto_proxy => 1,
);
$log->info("Starting to download quotes for $symbol for date range: $start_date -> $end_date");
## daily data not hourly or minute
foreach my $row ($fq->quotes) {
my ($sym, $date, $o, $h, $l, $c, $vol) = @$row;
my ($yy, $mm, $dd) = split /\//, $date;
my $epoch = DateTime->new(
year => $yy,
month => $mm,
day => $dd,
hour => 16, minute => 0, second => 0,
time_zone => 'America/New_York',
)->epoch;
push @quotes, pdl($epoch, $o, $h, $l, $c, $vol);
}
$log->info("No. of rows downloaded: " . scalar(@quotes));
$fq->clear_cache;
lib/App/financeta/gui.pm view on Meta::CPAN
our $VERSION = '0.16';
$VERSION = eval $VERSION;
use App::financeta::mo;
use App::financeta::utils qw(dumper log_filter get_icon_path get_file_path);
use Carp ();
use Log::Any '$log', filter => \&App::financeta::utils::log_filter;
use Try::Tiny;
use File::Spec;
use File::HomeDir;
use File::Path ();
use DateTime;
if ($^O !~ /win32/i) {
eval {
require POE;
require POE::Kernel;
POE::Kernel->import({loop => 'Prima'});
require POE::Session;
} or die "Unable to load POE::Loop::Prima";
}
use Prima qw(
Application Buttons MsgBox Calendar ComboBox Notebooks
lib/App/financeta/gui.pm view on Meta::CPAN
if (exists $iref->{params} and exists $iref->{params}->{CompareWith}) {
# ok this is a security.
# we need to download the data for this and store it
my $bar = App::financeta::gui::progress_bar->new(owner => $win, title => 'Downloading...');
my $current = $self->current;
$iref->{params}->{CompareWith} =~ s/\s//g;
$current->{symbol} = $iref->{params}->{CompareWith};
my $tz = $self->timezone;
unless ($current->{start_date}) {
my $sd = $data->at(0, 0); # time in 0th column
my $dt = DateTime->from_epoch(epoch => $sd, time_zone => $tz);
$current->{start_date} = $dt;
}
unless ($current->{end_date}) {
my $ed = $data->at($data->dim(0) - 1, 0); # time in 0th column
my $dt = DateTime->from_epoch(epoch => $ed, time_zone => $tz);
$current->{end_date} = $dt;
}
my ($data2, $symbol2, $csv2) = $self->download_data($bar, $current);
$bar->close if $bar;
return unless (defined $data2 and defined $symbol2);
$log->debug("Successfully downloaded data for $symbol2");
$iref->{params}->{CompareWith} = $symbol2;
$output = $self->indicator->execute_ohlcv($data, $iref, $data2);
} else {
$output = $self->indicator->execute_ohlcv($data, $iref);
lib/App/financeta/gui.pm view on Meta::CPAN
} else {
$log->warn("Buy-sells object is corrupt. Not using.");
$items = $data->transpose->unpdl;
}
} else {
$items = $data->transpose->unpdl;
}
my $tz = $self->timezone;
# reformat
foreach my $arr (@$items) {
my $dt = DateTime->from_epoch(epoch => $arr->[0], time_zone => $tz)->datetime(' ');
$arr->[0] = $dt;
for (my $i = 1; $i < scalar @$arr; ++$i) {
$arr->[$i] = '' if $arr->[$i] =~ /BAD/i;
}
}
$tabsize[0] *= 0.98;
$tabsize[1] *= 0.96;
my $dl = $nt->insert_to_page($pageno, 'DetailedList',
name => "tab_$symbol",
pack => { expand => 1, fill => 'both' },
lib/App/financeta/gui.pm view on Meta::CPAN
my ($data, $symbol, $indicators) = (defined $name) ?
$self->get_tab_data_by_name($win, $name) :
$self->get_tab_data($win);
# in save-as mode do not get historical file name
my ($info, $tname) = (defined $name) ?
$self->get_tab_info_by_name($win, $name) :
$self->get_tab_info($win);
my $saved = $self->get_model($data, $symbol, $indicators);
return unless $saved;
my $tz = $self->timezone;
$saved->{saved_at} = DateTime->now(time_zone => $tz)->iso8601();
$log->debug("Saving the model: ", dumper($saved));
my $mfile;
if ($info and $info->{filename} and not $save_as) {
$mfile = $info->{filename};
$log->info(sprintf "Saving tab %s to %s", ($name ? $name : ''), $mfile);
} else {
my $dlg = Prima::Dialog::SaveDialog->new(
fileName => "$symbol.yml",
filter => [
['financeta files' => '*.yml'],
lib/App/financeta/gui.pm view on Meta::CPAN
directory => $self->datadir,
);
my $mfile = $dlg->fileName if $dlg->execute;
$log->info("requesting file $mfile to be opened");
return unless $mfile;
return unless -e $mfile;
my $saved = YAML::Any::LoadFile($mfile);
return unless $saved;
my $tz = $self->timezone;
my $current = {
start_date => DateTime->from_epoch(epoch => $saved->{start_date}, time_zone => $tz),
end_date => DateTime->from_epoch(epoch => $saved->{end_date}, time_zone => $tz),
symbol => $saved->{symbol},
force_download => 0,
};
$current->{csv} = $saved->{csv} if defined $saved->{csv};
my $bar = App::financeta::gui::progress_bar->new(owner => $win, title => 'Loading...');
my ($data, $symbol, $csv) = $self->download_data($bar, $current);
$log->debug("Loading the data into tab");
$saved->{csv} = $csv if defined $csv;
# overwrite the filename for saving
if (defined $saved->{filename} and $mfile ne $saved->{filename}) {
lib/App/financeta/gui/security_wizard.pm view on Meta::CPAN
use 5.10.0;
use App::financeta::mo;
use App::financeta::utils qw(dumper log_filter);
use Log::Any '$log', filter => \&App::financeta::utils::log_filter;
use Prima qw(
Application Buttons MsgBox Calendar Label InputLine ComboBox
sys::GUIException Utils
);
use Try::Tiny;
use DateTime;
use Browser::Open ();
$|=1;
has owner => undef;
has gui => (required => 1);
has wizard => ( builder => '_build_wizard' );
sub run {
my $self = shift;
lib/App/financeta/gui/security_wizard.pm view on Meta::CPAN
font => { height => 14, style => fs::Bold },
);
$w->insert(
Calendar => name => 'cal_start',
useLocale => 1,
size => [ 220, 200 ],
origin => [ 20, $sz_y - 440 ],
font => { height => 16 },
onChange => sub {
my $cal = shift;
$gui->current->{start_date} = DateTime->new(
year => 1900 + $cal->year(),
month => 1 + $cal->month(),
day => $cal->day(),
time_zone => $gui->timezone,
);
},
);
$w->insert(
Label => text => 'Select End Date',
name => 'label_enddate',
lib/App/financeta/gui/security_wizard.pm view on Meta::CPAN
font => { height => 14, style => fs::Bold },
);
$w->insert(
Calendar => name => 'cal_end',
useLocale => 1,
size => [ 220, 200 ],
origin => [ $sz_x / 2, $sz_y - 440 ],
font => { height => 16 },
onChange => sub {
my $cal = shift;
$gui->current->{end_date} = DateTime->new(
year => 1900 + $cal->year(),
month => 1 + $cal->month(),
day => $cal->day(),
time_zone => $gui->timezone,
);
},
);
$w->insert(
CheckBox => name => 'chk_force_download',
text => 'Force Download',
lib/App/financeta/gui/security_wizard.pm view on Meta::CPAN
font => { height => 16, style => fs::Bold },
onClick => sub {
my $btn = shift;
my $owner = $btn->owner;
$gui->current->{source_index} = $owner->input_source->focusedItem;
$log->info("Selected input source index: " . $gui->current->{source_index});
$gui->current->{symbol} = $owner->input_symbol->text;
$log->info("Selected input symbol: " . $gui->current->{symbol});
unless (defined $gui->current->{start_date}) {
my $cal = $owner->cal_start;
$gui->current->{start_date} = DateTime->new(
year => 1900 + $cal->year(),
month => 1 + $cal->month(),
day => $cal->day(),
time_zone => $gui->timezone,
);
}
unless (defined $gui->current->{end_date}) {
my $cal = $owner->cal_end;
$gui->current->{end_date} = DateTime->new(
year => 1900 + $cal->year(),
month => 1 + $cal->month(),
day => $cal->day(),
time_zone => $gui->timezone,
);
}
},
);
return $w;
}
lib/App/financeta/gui/tradereport.pm view on Meta::CPAN
use strict;
use warnings;
use 5.10.0;
our $VERSION = '0.16';
$VERSION = eval $VERSION;
use App::financeta::mo;
use App::financeta::utils qw(dumper log_filter);
use Log::Any '$log', filter => \&App::financeta::utils::log_filter;
use File::HomeDir;
use DateTime;
if ($^O !~ /win32/i) {
eval {
require POE;
require POE::Kernel;
POE::Kernel->import({loop => 'Prima'});
require POE::Session;
} or die "Unable to load POE::Loop::Prima";
}
#use Prima qw(Application DetailedList ScrollWidget MsgBox StdDlg);
use Prima qw(
lib/App/financeta/gui/tradereport.pm view on Meta::CPAN
return unless defined $buysells;
my $longs = $buysells->{longs};
my $shorts = $buysells->{shorts};
my $qty = $buysells->{quantity};
my @items = ();
my $tz = $self->parent->timezone;
my $grosspnl = $buysells->{longs_pnl} + $buysells->{shorts_pnl};
if (defined $longs and not $longs->isnull and not $longs->isempty) {
my $longitems = $longs->transpose->unpdl;
foreach my $arr (@$longitems) {
my $dt1 = DateTime->from_epoch(epoch => $arr->[0], time_zone => $tz)->ymd('-');
my $dt2 = DateTime->from_epoch(epoch => $arr->[2], time_zone => $tz)->ymd('-');
my $pnl = sprintf "%0.02f", (($arr->[3] - $arr->[1]) * $qty);
my $row = [ $dt1, 'BUY', $arr->[1], $qty, $dt2, 'SELL', $arr->[3], $qty, $pnl ];
push @items, $row;
}
}
if (defined $shorts and not $shorts->isnull and not $shorts->isempty) {
my $shortitems = $shorts->transpose->unpdl;
foreach my $arr (@$shortitems) {
my $dt1 = DateTime->from_epoch(epoch => $arr->[0], time_zone => $tz)->ymd('-');
my $dt2 = DateTime->from_epoch(epoch => $arr->[2], time_zone => $tz)->ymd('-');
my $pnl = sprintf "%0.02f", (($arr->[1] - $arr->[3]) * $qty);
my $row = [ $dt1, 'SELL', $arr->[1], $qty, $dt2, 'BUY', $arr->[3], $qty, $pnl];
push @items, $row;
}
}
$self->main->tradereport_sheet->close;
$self->main->tradereport_label->close;
$self->_create_sheet($self->main, \@items);
$self->_create_label($self->main, $grosspnl);
$self->main->show;
share/testpdl.pl view on Meta::CPAN
#!/usr/bin/env perl
use strict;
use warnings;
use PDL;
use PDL::NiceSlice;
use PDL::Finance::TA;
use PDL::Graphics::Gnuplot;
use JSON::XS qw(decode_json);
use LWP::UserAgent;
use DateTime;
use Try::Tiny;
use Path::Tiny;
sub get_data($) {
my $symbol = shift;
my $filename = lc "$symbol.json";
my $content;
my $qdata;
my $url = sprintf("https://api.gemini.com/v2/candles/%s/%s", lc $symbol, '1day');
if (-e $filename) {
share/testpdljs.pl view on Meta::CPAN
#!/usr/bin/env perl
use strict;
use warnings;
use PDL;
use PDL::NiceSlice;
use PDL::Finance::TA;
use JSON::XS qw(decode_json encode_json);
use LWP::UserAgent;
use DateTime;
use Try::Tiny;
use Path::Tiny;
use Template;
use Browser::Open;
sub get_data($) {
my $symbol = shift;
my $filename = lc "$symbol.json";
my $content;
my $qdata;