Aula 4 • Projeto 5 • Adm Tech
Funções Financeiras em Python: VPL, TIR e Visualizações

Implementando cálculos financeiros na mão e visualizando com Plotly e Gradio

💰 VPL 📈 TIR 📊 Plotly 🌐 Gradio
Prof. Afonso Brandão • 2 horas • 2026
💰 Bloco 1: Funções Financeiras em Python
Implementação

VPL: Valor Presente Líquido

def calcular_vpl(fluxos_caixa: list[float], taxa_desconto: float) -> float:
  vpl = 0
  for t, fluxo in enumerate(fluxos_caixa):
    vpl += fluxo / ((1 + taxa_desconto) ** t)
  return vpl

fluxos = [-500000, 130000, 150000, 175000, 200000, 215000]
taxa = 0.14
vpl = calcular_vpl(fluxos, taxa)
print(f"VPL: R$ {vpl:,.2f}")
🔍 Newton-Raphson: a ideia por trás da TIR
Conceito

Como encontrar a raiz de uma função?

A TIR é a taxa r que faz o VPL ser igual a zero — ou seja, é a raiz da função VPL(r) = 0. O método de Newton-Raphson encontra essa raiz de forma iterativa e muito rápida.

Fórmula de atualização:

x₁ = x₀ − f(x₀) / f'(x₀)

Aplicado à TIR:
taxa_nova = taxa − VPL(taxa) / VPL'(taxa)

Como funciona passo a passo

  1. Chuta uma taxa inicial (ex: 10%).
  2. Calcula o VPL nessa taxa.
  3. Calcula a derivada do VPL em relação à taxa.
  4. Atualiza a taxa usando a fórmula acima.
  5. Repete até a variação ser menor que a tolerância (ex: 0,000001).

⚡ Por que é rápido?

A curva do VPL é suave. A reta tangente aponta quase direto para a raiz — converge em geral em menos de 10 iterações.

⚠️ Limitações

  • Depende de um bom chute inicial.
  • Quebra se a derivada for zero.
  • Fluxos com múltiplas trocas de sinal podem ter múltiplas TIRs.
Analogia: imagine que você quer saber onde uma estrada cruza o nível do mar. Você está num ponto qualquer, olha a inclinação do terreno e projeta em linha reta até o nível zero — esse ponto é seu próximo palpite. Repita e chegue rapidamente ao cruzamento real.
📐 Newton-Raphson: Fórmula e Convergência
Visualização

Fórmula geral

xn+1 = xn f(xn) f′(xn)

Aplicada à TIR

f(r)  =  ∑ Ft / (1+r)t = 0
f′(r) = −∑ t · Ft / (1+r)t+1

rn+1 = rn VPL(rn) VPL′(rn)

Convergência visual

Partindo de x₀=35%, converge para a TIR em apenas 2 iterações.

📈 TIR: Taxa Interna de Retorno
Implementação

TIR com Método de Newton-Raphson

def calcular_tir(fluxos_caixa: list[float], chute_inicial: float = 0.1, tolerancia: float = 1e-6, max_iter: int = 100) -> float:
  taxa = chute_inicial
  for _ in range(max_iter):
    vpl = sum(f / ((1 + taxa) ** t) for t, f in enumerate(fluxos_caixa))
    derivada = sum(-t * f / ((1 + taxa) ** (t + 1)) for t, f in enumerate(fluxos_caixa) if t > 0)
    if abs(derivada) < 1e-10:
      break
    nova_taxa = taxa - vpl / derivada
    if abs(nova_taxa - taxa) < tolerancia:
      return nova_taxa
    taxa = nova_taxa
  return taxa

tir = calcular_tir(fluxos)
print(f"TIR: {tir*100:.2f}% a.a.")
⏱️ Payback: Fórmula e Visualização
Conceito

Payback Simples

Encontre T tal que:
t=1T Ft ≥ |F0|

PB = (T−1) + |F0| − ∑T-1 Ft FT

Payback Descontado

Mesma ideia, mas com fluxos trazidos a valor presente:

PBD = (T−1) + |F0| − ∑T-1 Ft/(1+r)t FT / (1+r)T

O descontado demora mais, pois cada fluxo vale menos hoje — exigindo mais períodos para recuperar o investimento.

Fluxo acumulado × tempo

Dados: investimento R$500k, fluxos: 130k 150k 175k 200k 215k — taxa 14% a.a.

⏱️ Payback: Simples e Descontado
Implementação

Funções de Payback

def calcular_payback_simples(fluxos_caixa: list[float]) -> float:
  investimento_inicial = -fluxos_caixa[0]
  acumulado = 0
  for t in range(1, len(fluxos_caixa)):
    acumulado += fluxos_caixa[t]
    if acumulado >= investimento_inicial:
      retorno_parcial = investimento_inicial - (acumulado - fluxos_caixa[t])
      fracao = retorno_parcial / fluxos_caixa[t]
      return (t - 1) + fracao
  return float('inf')

def calcular_payback_descontado(fluxos_caixa: list[float], taxa_desconto: float) -> float:
  investimento_inicial = -fluxos_caixa[0]
  acumulado = 0
  for t in range(1, len(fluxos_caixa)):
    fluxo_descontado = fluxos_caixa[t] / ((1 + taxa_desconto) ** t)
    acumulado += fluxo_descontado
    if acumulado >= investimento_inicial:
      retorno_parcial = investimento_inicial - (acumulado - fluxo_descontado)
      fracao = retorno_parcial / fluxo_descontado
      return (t - 1) + fracao
  return float('inf')
📊 Exemplo Completo de Uso
Aplicação

Integrando todas as funções

investimento_inicial = -500000
fluxos_projetados = [130000, 150000, 175000, 200000, 215000]
fluxos_completos = [investimento_inicial] + fluxos_projetados
taxa_minima = 0.14

vpl = calcular_vpl(fluxos_completos, taxa_minima)
tir = calcular_tir(fluxos_completos)
payback_simples = calcular_payback_simples(fluxos_completos)
payback_descontado = calcular_payback_descontado(fluxos_completos, taxa_minima)

print(f"VPL: R$ {vpl:,.2f}")
print(f"TIR: {tir*100:.2f}% a.a.")
print(f"Payback Simples: {payback_simples:.2f} anos")
print(f"Payback Descontado: {payback_descontado:.2f} anos")

if vpl > 0 and tir > taxa_minima:
  print("✓ Projeto VIÁVEL")
else:
  print("✗ Projeto INVIÁVEL")
📊 Visualização com Plotly
Gráficos Interativos

Gráficos de Fluxo de Caixa e Sensibilidade

import plotly.graph_objects as go

def plotar_barras_fluxos(fluxos_caixa: list[float]):
  periodos = list(range(len(fluxos_caixa)))
  cores = ['#ff4545' if f < 0 else '#89cea5' for f in fluxos_caixa]

  fig = go.Figure()
  fig.add_trace(go.Bar(
    x=periodos,
    y=fluxos_caixa,
    marker_color=cores,
    text=[f'R$ {f:,.0f}' for f in fluxos_caixa],
    textposition='outside'
  ))
  fig.update_layout(
    title='Fluxos de Caixa por Período',
    xaxis_title='Período (anos)',
    yaxis_title='Fluxo de Caixa (R$)',
    showlegend=False
  )
  return fig

def plotar_sensibilidade_vpl(fluxos_caixa: list[float], taxa_min: float = 0, taxa_max: float = 0.30):
  taxas = [i/100 for i in range(int(taxa_min*100), int(taxa_max*100)+1, 1)]
  vpls = [calcular_vpl(fluxos_caixa, t) for t in taxas]

  fig = go.Figure()
  fig.add_trace(go.Scatter(
    x=taxas,
    y=vpls,
    mode='lines',
    line=dict(color='#2e2640', width=3)
  ))
  fig.add_hline(y=0, line_dash="dash", line_color="red")
  fig.update_layout(
    title='Sensibilidade do VPL à Taxa de Desconto',
    xaxis_title='Taxa de Desconto (%)',
    yaxis_title='VPL (R$)',
    hovermode='x unified'
  )
  return fig

fig1 = plotar_barras_fluxos(fluxos_completos)
fig1.show()

fig2 = plotar_sensibilidade_vpl(fluxos_completos)
fig2.show()
🛠️ App Completo com Gradio
Implementação

Interface para cálculo de VPL e TIR

!pip install gradio -q
import gradio as gr

def analisar_investimento(fluxos_texto, taxa):
  try:
    fluxos = [float(x.strip()) for x in fluxos_texto.split(',')]
    if len(fluxos) < 2:
      return "Erro: Mínimo 2 fluxos necessários", "", ""

    vpl = calcular_vpl(fluxos, float(taxa))
    tir = calcular_tir(fluxos)
    payback = calcular_payback_descontado(fluxos, float(taxa))

    resultado = f"VPL: R$ {vpl:,.2f}\nTIR: {tir*100:.2f}% a.a.\nPayback: {payback:.2f} anos"
    decisao = "✓ VIÁVEL" if vpl > 0 else "✗ INVIÁVEL"

    return resultado, decisao, plotar_barras_fluxos(fluxos)
  except Exception as e:
    return f"Erro: {e}", "", None

demo = gr.Interface(
  fn=analisar_investimento,
  inputs=[
    gr.Textbox(label="Fluxos de Caixa (separados por vírgula)",
               value="-500000, 130000, 150000, 175000, 200000, 215000"),
    gr.Number(label="Taxa de Desconto (%)", value=14)
  ],
  outputs=[
    gr.Textbox(label="Resultados"),
    gr.Textbox(label="Decisão"),
    gr.Plot(label="Visualização")
  ],
  title="Análise de Investimento - VPL/TIR"
)
demo.launch(share=True)
🚀 Publicação no Colab
Deploy

Como compartilhar o app

  1. Executar célula com `demo.launch(share=True)`.
  2. Aguardar geração do link público.
  3. Enviar link para colegas testarem com outros fluxos.
  4. Coletar feedback e melhorar validações.

Limitação: link temporário; para produção real, usar Hugging Face Spaces ou outro host.

🔄 Recapitulação
Resumo

Conteúdo da aula

1) Funções financeiras manuais (VPL, TIR, Payback) →
2) Visualizações com Plotly →
3) App interativo com Gradio
📚 Material Complementar
Recursos

Para aprofundar depois da aula

  • Documentação Plotly: gráficos interativos em Python.
  • Documentação Gradio: componentes e deploy.
  • Métodos numéricos: Newton-Raphson para cálculo de raízes.
  • Matemática financeira: VPL, TIR, Payback e aplicações.
  • Extensão: integrar com dados reais via API ou banco de dados.
📝 Atividade Ponderada em Sala
1 hora

Aplicação prática de VPL e TIR em Python

Aplicar conceitos de Valor Presente Líquido (VPL) e Taxa Interna de Retorno (TIR) em Python, comparando os resultados obtidos com os de uma planilha (Excel ou Google Sheets). O aluno deverá construir um estudo de caso prático, implementar funções reutilizáveis e interpretar os resultados em termos de decisão de investimento.

Base obrigatória: utilizar como ponto de partida o notebook da aula passada.

Dados: utilizar dados reais do parceiro; pode ser de apenas uma BU.

Entregáveis

  • Repositório no GitLab.
  • Pasta `ponderadas` dentro da pasta com seu nome.
  • Somente um arquivo `.ipynb` com a implementação.
  • O próprio notebook deve estar em formato de documentação (texto + código + interpretação).
  • Fazer no Colab, baixar como `.ipynb` e subir o arquivo no repositório.
  • Criar o repositório manualmente e fazer upload manual do arquivo.
  • Entregável final: link do repositório no GitLab.

Ir além (opcional)

Construir um frontend simples com Gradio para upload do arquivo e visualização dos resultados.

Tempo em sala: 1h para desenvolvimento e entrega.

Notebook de Exemplo (Colab)