Uname: Linux web3.us.cloudlogin.co 5.10.226-xeon-hst #2 SMP Fri Sep 13 12:28:44 UTC 2024 x86_64
Software: Apache
PHP version: 8.1.31 [ PHP INFO ] PHP os: Linux
Server Ip: 162.210.96.117
Your Ip: 3.129.23.169
User: edustar (269686) | Group: tty (888)
Safe Mode: OFF
Disable Function:
NONE

name : TesouroDireto.pm
#!/usr/bin/perl -w
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
#    02110-1301, USA
#
#
# $Id: $

package Finance::Quote::TesouroDireto;
require 5.10.1;

use strict;
use warnings;

use constant DEBUG => $ENV{DEBUG};
use if DEBUG, 'Smart::Comments';

use LWP::UserAgent;
use HTTP::Request::Common;
use JSON;

our $VERSION = '1.52'; # VERSION

sub methods { return (tesouro_direto => \&tesouro); }
sub labels { return (tesouro_direto => [qw/exchange date isodate symbol name price last method currency/]); }

sub tesouro
{
  my $quoter = shift;
  my @funds = @_;
  return unless @funds;

  my $ua = $quoter->user_agent;

  # Bad stuff to get around bad cert and ssl confs
  $ua->ssl_opts(verify_hostname => 0, SSL_verify_mode => 0, SSL_cipher_list => 'DEFAULT:!DH');

  my (%fundsymbol, %fundhash, @q, %info);

  # create hash of all funds requested
  foreach my $fund (@funds)
  {
      $fundhash{$fund} = 0;
  }

  my $url = "https://www.tesourodireto.com.br/json/br/com/b3/tesourodireto/service/api/treasurybondsinfo.json";
  my $response = $ua->request(GET $url);

  if ($response->is_success) {

    my $data = decode_json($response->content)->{'response'};
    my $quote_date = substr($data->{'TrsrBondMkt'}{'qtnDtTm'},0,10);
    my @bounds_list = @{$data->{'TrsrBdTradgList'}};

    foreach(@bounds_list) {

      my $quote_name = $_->{'TrsrBd'}{'nm'};

      if (exists $fundhash{$quote_name})
      {
        $fundhash{$quote_name} = 1;

        $info{$quote_name, "exchange"} = "Tesouro Direto";
        $info{$quote_name, "name"}     = $quote_name;
        $info{$quote_name, "symbol"}   = $quote_name;
        $info{$quote_name, "price"}    = $_->{'TrsrBd'}{'untrRedVal'};
        $info{$quote_name, "last"}     = $_->{'TrsrBd'}{'untrRedVal'};
	      $quoter->store_date(\%info, $quote_name, {isodate => $quote_date});
        $info{$quote_name, "method"}   = "tesouro_direto";
        $info{$quote_name, "currency"} = "BRL";
        $info{$quote_name, "success"}  = 1;
      }
    }

    # check to make sure a value was returned for every fund requested
    foreach my $fund (keys %fundhash)
    {
      if ($fundhash{$fund} == 0)
      {
        $info{$fund, "success"}  = 0;
        $info{$fund, "errormsg"} = "No data returned";
      }
    }
  }
  else
  {
    foreach my $fund (@funds)
    {
      $info{$fund, "success"}  = 0;
      $info{$fund, "errormsg"} = "HTTP error";
    }
  }

  ### result: %info

  return wantarray() ? %info : \%info;
}


1;

=head1 NAME

Finance::Quote::TesouroDireto - Obtain quotes for Brazilian government bounds

=head1 SYNOPSIS

    use Finance::Quote;
    $q = Finance::Quote->new;

    %stockinfo = $q->fetch("tesouro_direto", "Tesouro IPCA+ 2045");

=head1 DESCRIPTION

This module obtains quotes for Brazilian government bounds, obtained from
https://www.tesourodireto.com.br/titulos/precos-e-taxas.htm

=head1 LABELS RETURNED

The following labels may be returned by Finance::Quote::TesouroDireto:
exchange, name, symbol, date, price, last, method, currency.

=head1 SEE ALSO

=cut
© 2025 GrazzMean