Persano commited on
Commit
499d9a9
·
verified ·
1 Parent(s): b1b3b21

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +142 -0
app.py ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ os.environ['FONTCONFIG_PATH'] = '/tmp/fontconfig'
3
+ os.makedirs('/tmp/fontconfig', exist_ok=True)
4
+
5
+ from flask import Flask, render_template, request, send_file
6
+ import matplotlib.pyplot as plt
7
+ import pandas as pd
8
+ import io
9
+ import base64
10
+ from matplotlib.ticker import FuncFormatter
11
+ from xhtml2pdf import pisa
12
+ from datetime import datetime
13
+
14
+ app = Flask(__name__)
15
+
16
+ def formatar_brl(valor):
17
+ return f"R$ {valor:,.2f}".replace(",", "X").replace(".", ",").replace("X", ".")
18
+
19
+ def gerar_analise(investimentos_finais, capital):
20
+ melhor = max(investimentos_finais, key=investimentos_finais.get)
21
+ valor_melhor = investimentos_finais[melhor]
22
+ retorno_pct = ((valor_melhor - capital) / capital) * 100
23
+ return f"""
24
+ Após análise dos cenários projetados para 5 anos, o investimento <strong>{melhor}</strong> apresenta o melhor desempenho,
25
+ com um valor final estimado de <strong>{formatar_brl(valor_melhor)}</strong>, equivalente a um retorno de <strong>{retorno_pct:.1f}%</strong>.
26
+ """
27
+
28
+ @app.route("/", methods=["GET", "POST"])
29
+ def index():
30
+ if request.method == "POST":
31
+ capital = float(request.form["capital"])
32
+ studio_ret = float(request.form["studio_ret"])
33
+ valorizacao = float(request.form["valorizacao"])
34
+ franquia_ret = float(request.form["franquia_ret"])
35
+ acoes_ret = float(request.form["acoes_ret"])
36
+ renda_fixa = float(request.form["renda_fixa"])
37
+ inflacao = float(request.form["inflacao"])
38
+
39
+ anos = list(range(1, 6))
40
+
41
+ studio = [capital * ((1 + studio_ret / 100) ** (12 * ano)) for ano in anos]
42
+ franquia = [capital + (franquia_ret * ano) for ano in anos]
43
+ acoes = [capital * ((1 + acoes_ret / 100) ** ano) for ano in anos]
44
+ renda_fixa_valores = [capital * ((1 + renda_fixa / 100) ** ano) for ano in anos]
45
+ ajustado_inflacao = [valor / ((1 + inflacao / 100) ** ano) for valor, ano in zip(studio, anos)]
46
+
47
+ df = pd.DataFrame({
48
+ "Ano": anos,
49
+ "Studio": studio,
50
+ "Franquia": franquia,
51
+ "Ações": acoes,
52
+ "Renda Fixa": renda_fixa_valores,
53
+ "Studio c/ Inflação": ajustado_inflacao
54
+ })
55
+
56
+ investimentos_finais = {
57
+ "Studio": studio[-1],
58
+ "Franquia": franquia[-1],
59
+ "Ações": acoes[-1],
60
+ "Renda Fixa": renda_fixa_valores[-1],
61
+ }
62
+
63
+ plt.figure(figsize=(8, 5))
64
+ plt.plot(anos, studio, label="Studio", marker="o")
65
+ plt.plot(anos, franquia, label="Franquia", marker="o")
66
+ plt.plot(anos, acoes, label="Ações", marker="o")
67
+ plt.plot(anos, renda_fixa_valores, label="Renda Fixa", marker="o")
68
+ plt.plot(anos, ajustado_inflacao, label="Studio c/ Inflação", linestyle="--", marker="o")
69
+ plt.title("Projeção de Investimentos")
70
+ plt.xlabel("Ano")
71
+ plt.ylabel("Valor (R$)")
72
+ plt.legend()
73
+ plt.grid(True)
74
+ plt.gca().yaxis.set_major_formatter(FuncFormatter(lambda x, _: f"R${x:,.0f}".replace(",", ".")))
75
+ plt.tight_layout()
76
+
77
+ buf = io.BytesIO()
78
+ plt.savefig(buf, format="png")
79
+ buf.seek(0)
80
+ grafico_base64 = base64.b64encode(buf.getvalue()).decode("utf-8")
81
+ buf.close()
82
+ plt.close()
83
+
84
+ df_formatado = df.copy()
85
+ for col in df.columns[1:]:
86
+ df_formatado[col] = df_formatado[col].apply(formatar_brl)
87
+ tabela = df_formatado.to_html(index=False, classes="table table-striped table-sm", border=0)
88
+
89
+ analise_final = gerar_analise(investimentos_finais, capital)
90
+
91
+ resumo = []
92
+ for nome, valor_final in investimentos_finais.items():
93
+ retorno_abs = valor_final - capital
94
+ retorno_pct = (retorno_abs / capital) * 100
95
+ resumo.append({
96
+ "Investimento": nome,
97
+ "Valor Final": formatar_brl(valor_final),
98
+ "Retorno Absoluto": formatar_brl(retorno_abs),
99
+ "Retorno (%)": f"{retorno_pct:.1f}%"
100
+ })
101
+ resumo.sort(key=lambda x: float(x["Retorno (%)"].replace("%", "").replace(",", ".")), reverse=True)
102
+
103
+ comentario_extra = ""
104
+ if len(resumo) > 1:
105
+ diferenca_pct = float(resumo[0]["Retorno (%)"].replace("%", "").replace(",", ".")) - \
106
+ float(resumo[1]["Retorno (%)"].replace("%", "").replace(",", "."))
107
+ if diferenca_pct < 5:
108
+ comentario_extra = f"""
109
+ Apesar do <strong>{resumo[0]['Investimento']}</strong> ter se destacado, a diferença em relação ao segundo colocado
110
+ (<strong>{resumo[1]['Investimento']}</strong>) foi de apenas {diferenca_pct:.1f} pontos percentuais.
111
+ Isso indica que ambas as estratégias podem ser consideradas, dependendo do perfil de risco e objetivos do investidor.
112
+ """
113
+
114
+ return render_template(
115
+ "index.html",
116
+ capital=capital,
117
+ studio_ret=studio_ret,
118
+ valorizacao=valorizacao,
119
+ franquia_ret=franquia_ret,
120
+ acoes_ret=acoes_ret,
121
+ renda_fixa=renda_fixa,
122
+ inflacao=inflacao,
123
+ anos=anos,
124
+ tabela=tabela,
125
+ grafico=grafico_base64,
126
+ investimento_mais_valorizado=resumo[0]["Investimento"],
127
+ valor_mais_alto=resumo[0]["Valor Final"],
128
+ analise_final=analise_final,
129
+ comentario_extra=comentario_extra,
130
+ resumo=resumo
131
+ )
132
+
133
+ return render_template("index.html")
134
+
135
+ @app.route("/download_pdf", methods=["POST"])
136
+ def download_pdf():
137
+ # Idem lógica do index() para calcular dados e gerar PDF
138
+ # ... (mantido o mesmo código da função anterior)
139
+ return send_file(pdf, mimetype="application/pdf", as_attachment=True, download_name="relatorio_simulacao.pdf")
140
+
141
+ if __name__ == '__main__':
142
+ app.run(host='0.0.0.0', port=7860, debug=True)