Finance-IG

 view release on metacpan or  search on metacpan

lib/Finance/IG.pm  view on Meta::CPAN

#
# Return a ref to an array of positions. Each position is  
# a variable structure deep hash 
#
##########################################################################
sub positions
{
   my ($self) = shift;

   my $headers =    {
                       'Content-Type' => 'application/json; charset=UTF-8',
                       'Accept' =>  'application/json; charset=UTF-8',
                       VERSION => 2,
                       #   'IG-ACCOUNT-ID'=> $accountid, 
                       CST=>$self->CST,
                       'X-SECURITY-TOKEN'=> $self->XSECURITYTOKEN,
                       'X-IG-API-KEY'=> $self->apikey,
                    };
    #my $jheaders=JSON->new->canonical->encode($headers); # for debug 

    my $client = REST::Client->new();
    $client->setHost($self->_url);
    #my $r;
#    $headers->{VERSION}=2;
    #$r=$client->GET (
    $client->GET (    '/positions',
                      $headers
                    );
    my $resp=decode_json($client->responseContent());

    my $positions=[];
    @$positions=@{$resp->{positions}};

    return $positions;
}
# example of the structure of a position
# Regeneron Pharmaceuticals Inc, 0.06
# {
#    "position" : {
#       "trailingStopDistance" : null,
#       "size" : 0.06,
#       "limitedRiskPremium" : null,
#       "stopLevel" : 50128,
#       "direction" : "BUY",
#       "level" : 50303,
#       "dealReference" : "6XQESB1E506WW334",
#       "controlledRisk" : false,
#       "currency" : "GBP",
#       "contractSize" : 1,
#       "createdDateUTC" : "2020-04-03T14:26:07",
#       "trailingStep" : null,
#       "createdDate" : "2020/04/03 15:26:07:000",
#       "limitLevel" : null,
#       "dealId" : "DIAAAAEL2T7AEAS"
#    },
#    "market" : {
#       "lotSize" : 1,
#       "marketStatus" : "EDITS_ONLY",
#       "instrumentType" : "SHARES",
#       "expiry" : "DFB",
#       "streamingPricesAvailable" : false,
#       "instrumentName" : "Regeneron Pharmaceuticals Inc",
#       "offer" : 60261,
#       "delayTime" : 0,
#       "updateTime" : "20:59:56",
#       "high" : 61455,
#       "percentageChange" : -2.01,
#       "netChange" : -1236,
#       "low" : 59886,
#       "bid" : 60261,
#       "updateTimeUTC" : "19:59:56",
#       "scalingFactor" : 1,
#       "epic" : "UC.D.REGN.DAILY.IP"
#    }
# }
#####################################################################
# Aggregate an array of positions into an array of unique 
# positions with 1 element per instrument, Items will be combined
# where more than one position is combined, in a field dependent way. 
# for exeample sizes will be added as will be profit
# a reference to an array is expected and a reference to a new array
# returned. 
#####################################################################

=head2 agg - aggregate positions into a flattened 1 element per instrument form. 

Parameters 

  1 Reference to an array of positions
  2 (Optional) Ref to an array of keys to sort on 

agg does three things actually. First, it joins together multiple positions of the same instrument, 
generating sensible values for things like profit/loss and size

Second, it performs some flattening of the deep structure for a position which comes from IG. 

Third it sorts the result. The default sort order I use is -profitpc instrumentName, but  
you can provide a 2rd parameter,  a reference to an array of items to sort by. 
Each item can optionally be preceeded by - to reverse the prder. If the first item equates equal, then 
the next item is used. 

=cut
#####################################################################
sub agg
{
  my ($self,$positions,$sortlist)=@_;
  my %totals;  # aggregated totals as arrays of individuals. 

  $self->flatten($positions, [qw/market position/]);
  for my $position (@$positions)
  {

   my $json = JSON->new;
   $position->{size}=-abs($position->{size}) if ($position->{direction} eq 'SELL'); 
#   $position->{size}= -abs($position->{size}) if ($position->{direction}//'' ne 'BUY'); 
   $position->{profit}=($self->fetch($position,'bid')-$self->fetch($position,'level'))*$self->fetch($position,'size');
     $position->{profitpc}=int(0.5+1000*$position->{profit}/($position->{level}*abs($position->{size})))/10;

   $position->{held}=Time::Piece->strptime($position->{createdDateUTC},"%Y-%m-%dT%H:%M:%S")  or die "strptime failed for ".$position->{createdDateOnly}; 
   $position->{held}=(gmtime()-$position->{held})/(24*3600); 
   $position->{held}=int($position->{held}*10+0.5)/10; 



( run in 0.568 second using v1.01-cache-2.11-cpan-524268b4103 )