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 )