App-financeta

 view release on metacpan or  search on metacpan

Build.PL  view on Meta::CPAN

        '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',

META.json  view on Meta::CPAN

            "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",

META.yml  view on Meta::CPAN

    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;



( run in 0.392 second using v1.01-cache-2.11-cpan-05444aca049 )