Finance-IG

 view release on metacpan or  search on metacpan

script/igdisp.pl  view on Meta::CPAN

#!/usr/bin/env perl
use FindBin;
use lib $FindBin::RealBin."/../lib";
use lib $FindBin::RealBin."/../..";

use Finance::IG; 
use Getopt::Std; 
use Time::Piece; 
use strict; 
no strict 'refs';
use warnings; 


my %opt; 

my @credentials=(
               $FindBin::RealBin.'/../../credentials.pl' , 
               $FindBin::RealBin.'/../credentials.pl', 
               $FindBin::RealBin.'/credentials.pl', 
               './credentials.pl', 
               $ENV{HOME}.'/.config/IG/credentials.pl', 
             ); 

our $VERSION=0.103; 
######### code for multiiple -n x arguments treat as single joined with |. Not handled with getopts. 
$opt{n}=[]; 
for my $i (0..$#ARGV)
{ 
   next if (!defined $ARGV[$i]); 
   if ($ARGV[$i] eq '-n')
   { 
       push(@{$opt{n}},$ARGV[$i+1]); 
       $ARGV[$i]=$ARGV[$i+1]=undef; 
       $i+=2; 
   } 
   elsif ($ARGV[$i]=~s/^-n//)
   { 
     push(@{$opt{n}},$ARGV[$i]); 
     $ARGV[$i++]=undef; 
   } 
} 
@ARGV=grep { defined $_ } @ARGV; 
die "-n requires an argument, not provided" if (0<grep { !defined $_  } @{$opt{n}}) ; 
$opt{n}=join('|',@{$opt{n}}); 
$opt{n} or delete $opt{n}; 
$opt{a}=1; 
#########

getopts('ra:c:eotf:FNhn:s:SO:g:v:', \%opt) or help("Aborted! -h for help "); 

my $ig; 
# IG Credentials needed. 
# You can add them to enviroment variables as bellow or 
# directly hardcode them below. 
# It can be useful to have a demo account to, this should be a seperate instance of the 
# object. 

my $capital; # hardcode your capital here if you want. 

$opt{c}.='/credentials.pl' if ($opt{c} and ! -f $opt{c}); 
unshift(@credentials,$opt{c}) if ($opt{c}); 

if ($opt{e})
{ 
  if ($ENV{IGUSER} and $ENV{IGPASS} and $ENV{IGAPIKEY}) 
  { 
    print "Environment variables IGUSER, and IGPASS. and IGAPIKEY 
are all set and accessible so will use those.\n"; 
    exit 1; 
  } 
  
  print "IGUSER is missing\n" if (!$ENV{IGUSER}); 
  print "IGPASS is missing\n" if (!$ENV{IGPASS}); 
  print "IGAPIKEY is missing\n" if (!$ENV{IGAPIKEY}); 

} 
   
if ($ENV{IGUSER} and $ENV{IGPASS} and $ENV{IGAPIKEY}) 
{ 
    $ig=Finance::IG->new(
                username=> $ENV{IGUSER}, 
                password=> $ENV{IGPASS}, 
                apikey=>   $ENV{IGAPIKEY}, 
                isdemo=>0, 
                col=>0, 
   ); 
} 
else
{ 
#  eval { require $FindBin::RealBin.'/../../credentials.pl' } or 
#  eval { require $FindBin::RealBin.'/../credentials.pl' } or 
#  eval { require $FindBin::RealBin.'/credentials.pl' } or 
#  eval { require './credentials.pl' } or 

  my $reqok=0; 
  map { $reqok ||=eval { require $_ } } @credentials; 

  
  $reqok or die "Need a credentials.pl file, looks something like this but contains actual metrobank login credentials: 
     sub cred
     { 
        return  { 
                   username=>'',      # Your ig username 
                   password=>'',      # Your ig password
                   apikey=>'' ,       # Your ig apikey
                } 
     }; 
     1; 

You can alternatively use 3 environment variables named IGUSER,IGPASSWORD, IGAPIKEY. 
The credentials file is searched for in the following paths: 
@credentials
You can also use -c path or file. 
" ;
    $ig=Finance::IG->new(cred(),isdemo=>0,col=>0); 

    # This hack allows you to set your starting  capital in the credentials file if you wish 
    my %x=cred(); 
    $capital//=$x{capital}; 
} 

if ($opt{e})
{ 
  my ($e)=grep { m/credentials/ }  keys %INC; 
  $e=~s#/[^/]+/\.\.##g; 
  $e=~s#/[^/]+/\.\.##g; 
  print "credentials.pl from : ".$e."\n"; 
  exit; 
} 

# map { $ENV{$_}//='' } qw(IGUSER IGPASS IGAPIKEY); # empty allowed but caught, undef not allowed
#$ig=Finance::IG->new(
#                username=> $ENV{IGUSER}, 
#                password=> $ENV{IGPASS}, 
#                apikey=>   $ENV{IGAPIKEY}, 
#                isdemo=>0, 
#); 

die "missing credentials username, try setting the environment variable IGUSER" if ($ig->username eq ''); 
die "missing credentials password, try setting the environment variable IGPASS" if ($ig->username eq ''); 
die "missing credentials apikey, try setting the environment variable IGAPIKEY" if ($ig->username eq ''); 
my $sortlist; 

# -o auto-generate a time based file and use this to send output to 
# t display headers every 10 lines 
# n no headers 
# f n : use format number 
# h help
# g grep  
# S print NO summary line 
# s sort list 
# sort list can be 
# a comma seperated list of fields each with an optional minus sign eg 
#   -s'-profitpc,instrumentName'   sorts by profit highest first, and if the same, then orders by name 
#   Here the following can be used as abbreviations 
#  n instrumentName
#  o open => level
#  b bid 
#  v value => atRisk 
#  p profitpe
# if no commas 
#  or a comma seperated list of elements, each of which may be optionally started with - for reverse sort
#  the above abbrevs may be used. default is -p,n or -profitpc,instrumentName or -pn 

if (exists $opt{s} and defined $opt{s}) 
{ 
   my @list; 
   if ($opt{s}=~m/^[-nobvp]+$/)
   {
     @list=split(//,$opt{s}); 
   } 
   else
   { 
     @list=split(/,/,$opt{s}); 
     @list=map { s/^-//?('-',$_):$_ } @list; 
   } 
   for (@list)
   { 
       $_='instrumentName' if ($_ eq 'n');  
       $_='level'          if ($_ eq 'o');  
       $_='bid'            if ($_ eq 'b');  
       $_='atrisk'         if ($_ eq 'v');  
       $_='profitpc'       if ($_ eq 'p');  
   } 
   map { ($list[$_] eq '-') and  $list[$_+1]='-'.$list[$_+1]; } (0..$#list); 
   @list=grep { $_ ne '-' } @list; 
   $sortlist=\@list; 
}

my $gel; 
my $maskint; 
if ($opt{O})
{ 
   $gel=1; # default is date must be greater than specified. 
   if ($opt{O}=~s/^([-\+=><])//) 
   { 
     $gel=-1 if ($1 eq '-' or $1 eq '<'); 
     $gel=1  if ($1 eq '+' or $1 eq '>'); 
     $gel=0  if ($1 eq '='); 
   } 
   $opt{O}=~s#/#-#g; 

script/igdisp.pl  view on Meta::CPAN

  {
        local $SIG{__WARN__} = sub {$warning = shift};
        $t1=Time::Piece->strptime($t1,$f) if (ref($t1) ne 'Time::Piece'); 
        $t2=Time::Piece->strptime($t2,$f) if (ref($t2) ne 'Time::Piece'); 
  } 
  return $t1==$t2 if ($gel==0); 
  return $t1<=$t2 if ($gel==-1); 
  return $t1>=$t2; # if ($gel==1); 
} 
sub expression
{ 
  my ($expr,$position)=@_; 
  my $eval; 

  # the expression consists of lines like 
  # $held>100 and $dailyp>0.1 
  # the  evaluated value is returned by the function
  # is important to substitute variables longest first so profitpc is done before profit 
  for my $key (sort { length($b) <=> length($a) } keys %$position) 
  { 
    my $x=$position->{$key}; 
    if (defined($x))
    { 
      $x=~s/[%£]//g; 
      $x=~s/ av// if ($key eq 'dailyp'); 
      $expr=~s/\$$key/$x/g; 
    } 
    else
    { 
      $expr=~s/\$$key/undef/g; 
    } 
  } 
  $eval=eval  $expr ; 
  # print "$position->{instrumentName} => $eval\n"; 
  return $eval ; 
} 
sub help
{ my ($mess)=@_; 
# -o auto-generate a time based file and use this to send output to 
# t display headers every 10 lines 
# n no headers 
# f n : use format number 
# h help
# g grep  
# s print NO summary line 

   my $name=$0; 
   $name=~s#^.*/([^/]+)$#$1#; 
   print "$mess\n" if (defined $mess and length($mess)>1);  
   print "$name Version $VERSION\n"; 
   print "
This program is both an example of usage and a practical utility in its own right. 

It will print out your spreadbet positions in IG in various ways using your 
username, password and apikey. These can be supplied in a cedentials.pl file in the script directory
or 1 or 2 directories up or the current directory. Or you can set
the environment variables IGPASS, IGUSER, IGAPIKEY.  

The default display is decending order of percent profit.  Various formats are possible. 
-a n aggregate 1 (default) , nonaggregate 0 = show individual holdings
-e explain where credentials for login are coming from, then exit. 
-o Send output to an autogenerated, time based file. 
-f n use one of the inbuilt formats 1 to 5. Or provide the format to use. 
-F print the current format and exit .  
-h this message and exit
-n xxx use xxx as a pattern in name to grep for particular positions. Can use | for or. (Must be quoted) 
   multipl -n allowed. 
-S print no summary line. 
-N toggle printing of headers. 
-t print title lines every 10 lines. 
-s x Sort output by x where x is a comma seperated list of fields
   optionaly preceded by a minus (for reverse sort). Common fields
   can be abrievated by the following single letter abbreviations, 
     n instrumentName
     o level (opening price for position)
     b bid 
     v atRisk (value atRisk in a position) 
     p profitpe (percentage profit. ) 
   The default could be written in any of the following ways:   
     -s-profitpc,instrumentName or -s-pn or -s-p,n
   It sorts by decending order of profit and where this is the 
   same, orders by name. Case is significant.  
-O [+-=]date[time] Show only positions held Opened later or equal  (+) equal to (-) 
   or earlier or equal (-) than the given date or datetime, eg 
   -O 2020/11/05 or -O 2020/11/05T15:00:00
   Equal to means with ref to the format so that 
   2020/11/05 means the days are equal while 2020/11 means amy time that month 
-g x print only tradeable (x=t) or non-tradable (x=n) positions 
-v exp Evaluate expression and print if true. Example expressions (format id perl format) 
   '\$dailyp> 0.1 and \$held>100' means daily profit more than 0.1% and held for more than 100 days
   Any variable (full list below) can be used 
"; 
exit 1 if (defined $mess and length($mess)>1); 
print "\n A complete list of fields in a position is as follows. Some of these 
are IG things, and some are calculated: 

    bid
    contractSize
    controlledRisk
    createdDate
    createdDateUTC
    currency
    dailyp                profit in % per day averaged over holding time 
    dealId
    dealReference
    delayTime
    direction
    epic
    expiry
    held                  days held 
    high
    instrumentName
    instrumentType
    limitedRiskPremium
    limitLevel
    lotSize
    low
    marketStatus
    netChange
    offer
    percentageChange



( run in 0.625 second using v1.01-cache-2.11-cpan-84e82930d8c )