Skip to content

Instantly share code, notes, and snippets.

@lucashmsilva
Last active January 11, 2024 13:26
Show Gist options
  • Save lucashmsilva/9f4596f2924ac5c1eb0721c2c41dc257 to your computer and use it in GitHub Desktop.
Save lucashmsilva/9f4596f2924ac5c1eb0721c2c41dc257 to your computer and use it in GitHub Desktop.
API para criar a função TESOURODIRETO Google Sheets
/*
* @return Retorna a cotação atual de um título específico do Tesouro Direto Junto com a taxa anual de retorno
* @customfunction
**/
function TESOURODIRETO(bondName) {
let srcURL = "https://www.tesourodireto.com.br/json/br/com/b3/tesourodireto/service/api/treasurybondsinfo.json";
let jsonData = UrlFetchApp.fetch(srcURL);
let parsedData = JSON.parse(jsonData.getContentText()).response;
for(let bond of parsedData.TrsrBdTradgList) {
let currBondName = bond.TrsrBd.nm;
if (currBondName === bondName)
return [bond.TrsrBd.untrRedVal, bond.TrsrBd.anulInvstmtRate]; // créditos ao @figueiredods por ter encontrado o campo que retorna a taxa correta
}
throw new Error("Not Found");
}
/*
* @return Retorna a cotação atual de um título específico do Tesouro Direto
* @customfunction
**/
function TESOURODIRETO(bondName) {
let srcURL = "https://www.tesourodireto.com.br/json/br/com/b3/tesourodireto/service/api/treasurybondsinfo.json";
let jsonData = UrlFetchApp.fetch(srcURL);
let parsedData = JSON.parse(jsonData.getContentText()).response;
for(let bond of parsedData.TrsrBdTradgList) {
let currBondName = bond.TrsrBd.nm;
if (currBondName === bondName)
return bond.TrsrBd.untrRedVal;
}
throw new Error("Not Found");
}
@maxpjr
Copy link

maxpjr commented Jul 9, 2021

Muito bom, excelente!

Por acaso você não teria uma versão para o Excel?

@Idgpol
Copy link

Idgpol commented Sep 30, 2021

Olá... desculpe a 'ignorancia'... como e onde usar esse código ? Fv passar receita de bolo. No sentido 'geral', 'mecho' com o que já esta 'pronto' e adequo a minha necessidade. Só preciso do ponta pé inicial..... Se a roda está feita... apenas, se der, coloco uma tinta do gosto. Grato pela atenção. Chegeui aqui para entender e, acrescentar no meu home broker.

@lucashmsilva
Copy link
Author

Muito bom, excelente!

Por acaso você não teria uma versão para o Excel?

Olá @maxpjr! Cara, para Excel eu vou ficar devendo... Talvez seja possível fazer isso "traduzindo" para VBA, mas eu não conheço nada de programação dentro do Excel. Talvez alguém aqui na thread possa ajudar...

@lucashmsilva
Copy link
Author

lucashmsilva commented Sep 30, 2021

Olá... desculpe a 'ignorancia'... como e onde usar esse código ? Fv passar receita de bolo. No sentido 'geral', 'mecho' com o que já esta 'pronto' e adequo a minha necessidade. Só preciso do ponta pé inicial..... Se a roda está feita... apenas, se der, coloco uma tinta do gosto. Grato pela atenção. Chegeui aqui para entender e, acrescentar no meu home broker.

Olá @Idgpol!
Para te ajudar a entender melhor o que esse script faz e como e onde utilizar ele, recomendo dar uma olhada nesse post que fiz no Reddit. Lá tem um passo a passo e uma descrição do código. Se ainda tiver alguma dúvida, fique a vontade para enviar aqui ou comentar lá no post do Reddit.

@Idgpol
Copy link

Idgpol commented Oct 1, 2021 via email

@lucashmsilva
Copy link
Author

@Idgpol, pode dar mais detalhes do erro que esta acontecendo? Aqui nas planilhas que uso, a função tem funcionado normalmente...

@jairon0209
Copy link

Boa tarde, estava procurando como obter todas as atualizações do NTN-B Principal 2045 do TD, daí cheguei aqui.

Como ou onde encontro a lista com o histórico do preço dos títulos? A maioria dos sites, inclusive do TD, só apresenta um valor diário, mas no intraday ocorrem variações (em torno das 9h/11h/13h/15h), daí preciso desses valores intraday.
Obs: nunca usei nada de API.

Grato pela ajuda

@lucashmsilva
Copy link
Author

lucashmsilva commented Oct 7, 2021

Boa tarde, estava procurando como obter todas as atualizações do NTN-B Principal 2045 do TD, daí cheguei aqui.

Como ou onde encontro a lista com o histórico do preço dos títulos? A maioria dos sites, inclusive do TD, só apresenta um valor diário, mas no intraday ocorrem variações (em torno das 9h/11h/13h/15h), daí preciso desses valores intraday. Obs: nunca usei nada de API.

Grato pela ajuda

Olá @ jairon0209! Cara, não sei se vou conseguir te ajudar, pois a fonte da informação que as funções aí retornam é justamente o site do TD...

Se o que vc está precisando é montar um histórico, digamos "de hoje em diante", uma estratégia seria montar um outro código que faz chamadas recorrentes para essa função durante o dia. Com isso vc consegue salvar as diferentes cotações no intraday. Porém, se vc estiver precisando de um histórico completo, do passado até hoje, essa abordagem obviamente não resolve. Nesse caso, talvez exista algum site, tipo aquele Meus Dividendos (acho que esse é o nome) que tenha isso já integrado na plataforma deles.

Se a estratégia de montar o histórico resolver, construimos algo juntos. Dentro do próprio Google sheets é possível agendar a chamada de funções específicas, salvando o resultado na planilha.

@jairon0209
Copy link

Boa tarde, estava procurando como obter todas as atualizações do NTN-B Principal 2045 do TD, daí cheguei aqui.
Como ou onde encontro a lista com o histórico do preço dos títulos? A maioria dos sites, inclusive do TD, só apresenta um valor diário, mas no intraday ocorrem variações (em torno das 9h/11h/13h/15h), daí preciso desses valores intraday. Obs: nunca usei nada de API.
Grato pela ajuda

Olá @ jairon0209! Cara, não sei se vou conseguir te ajudar, pois a fonte da informação que as funções aí retornam é justamente o site do TD...

Se o que vc está precisando é montar um histórico, digamos "de hoje em diante", uma estratégia seria montar um outro código que faz chamadas recorrentes para essa função durante o dia. Com isso vc consegue salvar as diferentes cotações no intraday. Porém, se vc estiver precisando de um histórico completo, do passado até hoje, essa abordagem obviamente não resolve. Nesse caso, talvez exista algum site, tipo aquele Meus Dividendos (acho que esse é o nome) que tenha isso já integrado na plataforma deles.

Se a estratégia de montar o histórico resolver, construimos algo juntos. Dentro do próprio Google sheets é possível agendar a chamada de funções específicas, salvando o resultado na planilha.

Obg por responder!!
Procurei na página https://www.tesourodireto.com.br/json/br/com/b3/tesourodireto/service/api/treasurybondsinfo.json e a informação que preciso seria a "qtnDtTm". Teria como montar uma função TESOURODIRETO2() para retornar esta variável (que é data e hora da atualização) a partir do modelo da função TESOURODIRETO()?
Obg

@lucashmsilva
Copy link
Author

Obg por responder!! Procurei na página https://www.tesourodireto.com.br/json/br/com/b3/tesourodireto/service/api/treasurybondsinfo.json e a informação que preciso seria a "qtnDtTm". Teria como montar uma função TESOURODIRETO2() para retornar esta variável (que é data e hora da atualização) a partir do modelo da função TESOURODIRETO()? Obg

@jairon0209, nesse caso, basta substituir o campo que é usado no script. Da uma olhada como que fica:


/*
* @return Retorna a cotação atual de um título específico do Tesouro Direto
* @customfunction
**/
function LAST_UPDATE_TESOURODIRETO() {
    let srcURL = "https://www.tesourodireto.com.br/json/br/com/b3/tesourodireto/service/api/treasurybondsinfo.json";
    let jsonData = UrlFetchApp.fetch(srcURL);
    let parsedData = JSON.parse(jsonData.getContentText()).response;

    return parsedData.TrsrBondMkt.qtnDtTm; // <------- aqui retornamos para planilha o valor do campo que você encontrou.
}

Como esse é um campo que não é específico para nenhum título, não precisamos filtrar pelo nome da mesma forma que a função original, com isso temos uma simplificada.

Da uma testada ai se é isso mesmo que vc precisa e se vai funcionar.

@jairon0209
Copy link

Obg por responder!! Procurei na página https://www.tesourodireto.com.br/json/br/com/b3/tesourodireto/service/api/treasurybondsinfo.json e a informação que preciso seria a "qtnDtTm". Teria como montar uma função TESOURODIRETO2() para retornar esta variável (que é data e hora da atualização) a partir do modelo da função TESOURODIRETO()? Obg

@jairon0209, nesse caso, basta substituir o campo que é usado no script. Da uma olhada como que fica:


/*
* @return Retorna a cotação atual de um título específico do Tesouro Direto
* @customfunction
**/
function LAST_UPDATE_TESOURODIRETO() {
    let srcURL = "https://www.tesourodireto.com.br/json/br/com/b3/tesourodireto/service/api/treasurybondsinfo.json";
    let jsonData = UrlFetchApp.fetch(srcURL);
    let parsedData = JSON.parse(jsonData.getContentText()).response;

    return parsedData.TrsrBondMkt.qtnDtTm; // <------- aqui retornamos para planilha o valor do campo que você encontrou.
}

Como esse é um campo que não é específico para nenhum título, não precisamos filtrar pelo nome da mesma forma que a função original, com isso temos uma simplificada.

Da uma testada ai se é isso mesmo que vc precisa e se vai funcionar.

@lucashms vc é mto fera!! Vlw msm
Era exatamente o que eu estava precisando.
Com essas duas funções tem como fazer trade no TD bem mais fácil.
Mto obg!

@lucashmsilva
Copy link
Author

Show @jairon0209!! 💸

@vonhauke
Copy link

Olá a todos. Está dando uma diferença em relação ao site do Tesouro. Alguém sabe dizer o motivo? Obrigado.

@vonhauke
Copy link

Entrei no site do meu banco e o preço está batendo. Esse é o preço para venda então. O preço que aparece no site do Tesouro é para compra. Tudo certo então. Valeu pelo trabalho @lucashmsilva e parabéns.

@CBOLIVEIRA1970
Copy link

Oi Lucas blz?
qual script que uso para os titulos do tesouro que ja sairam das cotações, ou seja, aqueles que não são possiveis aplicar dinheiro neles?

@lucashmsilva
Copy link
Author

Oi Lucas blz? qual script que uso para os titulos do tesouro que ja sairam das cotações, ou seja, aqueles que não são possiveis aplicar dinheiro neles?

Olá, @CBOLIVEIRA1970. Cara, até onde me lembro, o script funciona também para títulos não listados para compra. A diferença entre as duas funções, é que uma retorna o valor atual e a taxa e outra retorna o valor atual somente. A fonte de de dados para os dois scripts é a mesma.

@CBOLIVEIRA1970
Copy link

CBOLIVEIRA1970 commented Jan 27, 2023

Oi Lucas, ok vou tentar novamente.
Outra coisa, consegue colocar no script para ele ficar atualizando a cada minuto?

Eu usei este scritp abaixo, onde informa o 1 valor e a 2 taxa atual:

/*

  • @return Retorna a cotação atual de um título específico do Tesouro Direto

  • @customfunction
    **/
    function TESOURODIRETO(bondName,arg) {
    let srcURL = "https://www.tesourodireto.com.br/json/br/com/b3/tesourodireto/service/api/treasurybondsinfo.json";
    let jsondata = UrlFetchApp.fetch(srcURL);
    let parsedData = JSON.parse(jsondata.getContentText()).response;

    for(let bond of parsedData.TrsrBdTradgList) {
    let currBondName = bond.TrsrBd.nm;
    if (currBondName === bondName && arg === 1)
    return [bond.TrsrBd.untrInvstmtVal];
    if (currBondName === bondName && arg === 2)
    return [bond.TrsrBd.anulInvstmtRate];
    }
    throw new Error("Not Found");
    }

abraço, Claudio

@lucashmsilva
Copy link
Author

@CBOLIVEIRA1970 qual título você está procurando?

Sobre a atualização, no script, pela forma que o Google Sheets funciona não tem como. Porém existe um outro recurso, do próprio Sheets, onde é possível criar algumas automações. Pesquise por App Scripts Triggers. Eu particularmente nunca usei, mas parece ser o que você está buscando. Com essa ferramenta, você agenda ações dentro das planilhas através de scripts. Só lembrando que toda vez que você carrega a planilha a função executa automaticamente, puxando o valor mais atual.

@CBOLIVEIRA1970
Copy link

OI Lucas, valeu obrigado pela ajuda!

@Tiagoalvesds
Copy link

Boa tarde, @lucashmsilva
Sou iniciante no google sheets, segui os passos no (https://www.reddit.com/r/investimentos/comments/hpl8j9/fun%C3%A7%C3%A3o_tesourodierto_no_google_sheets/), e após executar o script não estou conseguindo chamar a função na planilha.(Erro Função desconhecida).#NOME?
Pode me ajudar?

@lucashmsilva
Copy link
Author

Olá @Tiagoalvesds, pode acessar essa página [1] e me mostrar como está ai pra você?
1

Deve estar parecido com isso aqui:
2

@Tiagoalvesds
Copy link

Olá! aparece assim...

script

@lucashmsilva
Copy link
Author

@Tiagoalvesds apague toda a linha 1 e a linha 18. Daí salve em implantar e depois volte pra planilha e tente usar a função de novo.

@Tiagoalvesds
Copy link

implantei...mas ao pedir para rodar ele apareceu esse erro abaixo.. é normal?
image

@lucashmsilva
Copy link
Author

Certo, mas agora esse erro não é por um erro na função em si, mas sim porque você está usando no local errado.

Para usar a função você deve voltar à planilha e chamar a funciona como uma função padrão. Dessa forma:
image
Igual se faz no Excel. A diferença é que a função foi criada por você.

@Tiagoalvesds
Copy link

Opa! agora foi Lucas. obrigado! Só está aparecendo um número desconhecido de 6,24 e 6,34. vide exemplo abaixo.
image

@lucashmsilva
Copy link
Author

@Tiagoalvesds, da uma olhada nesse segundo script. Ele retorna somente o valor do título que é passado na função. Pode só copiar o código e substituir todo o código que você colocou lá. Vai ficar igual ao código do print que mandei na primeira resposta que mandei pra você.

Esse número que você está vendo ai é a taxa anual do título, além do valor.

@Tiagoalvesds
Copy link

@lucashmsilva , deu certo e funciona perfeitamente! Obrigado! Notei que a cotação puxada é a de resgate, teria como adicionar uma linha e/ou função que puxa a cotação de compra?

@lucashmsilva
Copy link
Author

lucashmsilva commented Feb 25, 2023

@Tiagoalvesds , cara teria que analisar o retorno desses dados no site no TD para descobrir qual campo é a cotação de compra para só então adaptar o código. Hoje em dia não me lembro muito bem, mas não deve ser difícil descobrir o campo. A fonte de dados é essa: json b3

@andretc
Copy link

andretc commented Aug 22, 2023

Fiz uma melhoria pra cachear a response do tesouro pq as vezes dá erro por chamar vezes seguidas :)

var cache = CacheService.getScriptCache();

function TESOURODIRETO(bondName, argumento = "r") {
  var tesouro = getCachedTesouro();

  if (bondName == "tesouro-selic-2027")
      bondName = "Tesouro Selic 2027";

  if (bondName == "tesouro-selic-2029")
    bondName = "Tesouro Selic 2029";

  if (bondName == "tesouro-prefixado-2025")
    bondName = "Tesouro Prefixado 2025";

  if (!tesouro) {
    Logger.log("No cached tesouro info found");
    updateTesouroCache();
  }

  tesouro = getCachedTesouro();

  for (let bond of tesouro.TrsrBdTradgList) {
    console.log(bond);
    let currBondName = bond.TrsrBd.nm;
    if (currBondName.toLowerCase() === bondName.toLowerCase())
      if (argumento == "r")
        return bond.TrsrBd.untrRedVal;
      else
        return bond.TrsrBd.untrInvstmtVal;
  }

  return 0;
}

function getCachedTesouro() {
  var cached = cache.get("tesouro");
  if (cached) {
    try {
      var tesouro = JSON.parse(cached).response;
      return tesouro;
    } catch (e) {
      Logger.log("Error while parsing tesouro from cache");
    }
  }
}

function updateTesouroCache() {
  Logger.log("Updating tesouro cached information");

  var response = UrlFetchApp.fetch("https://www.tesourodireto.com.br/json/br/com/b3/tesourodireto/service/api/treasurybondsinfo.json");
  var content = response.getContentText();
  
  try {
    var data = JSON.parse(content);
    
    var cachedTesouro = {};
    cachedTesouro["tesouro"] = JSON.stringify(data)
    cache.putAll(cachedTesouro);

  } catch (e) {
    Logger.log("Error while parsing response from tesouro: " + content);
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment