Persano commited on
Commit
bc9518e
·
verified ·
1 Parent(s): 8343444

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +248 -0
app.py ADDED
@@ -0,0 +1,248 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import io
3
+ import base64
4
+ import pandas as pd
5
+ import matplotlib.pyplot as plt
6
+ from flask import Flask, render_template, request, send_file
7
+ from matplotlib.ticker import FuncFormatter
8
+ from xhtml2pdf import pisa
9
+ from datetime import datetime
10
+ import openai
11
+
12
+ app = Flask(__name__)
13
+
14
+ openai.api_key = os.getenv("OPENAI_API_KEY")
15
+
16
+ def formatar_brl(valor):
17
+ return f"R$ {valor:,.2f}".replace(",", "X").replace(".", ",").replace("X", ".")
18
+
19
+ def data_por_extenso(dt):
20
+ meses = {
21
+ "January": "janeiro",
22
+ "February": "fevereiro",
23
+ "March": "março",
24
+ "April": "abril",
25
+ "May": "maio",
26
+ "June": "junho",
27
+ "July": "julho",
28
+ "August": "agosto",
29
+ "September": "setembro",
30
+ "October": "outubro",
31
+ "November": "novembro",
32
+ "December": "dezembro"
33
+ }
34
+ dia = dt.day
35
+ mes = meses[dt.strftime("%B")]
36
+ ano = dt.year
37
+ return f"São Paulo, {dia} de {mes} de {ano}"
38
+
39
+ def gerar_analise_ia(investimentos_finais, capital, patrimonio_studio_final):
40
+ prompt = f"""
41
+ Faça uma análise profissional e detalhada em linguagem clara e acessível sobre os seguintes dados financeiros:
42
+ - Capital inicial: R$ {capital:,.2f}
43
+ - Valor patrimonial final do Studio: R$ {patrimonio_studio_final:,.2f}
44
+ - Investimentos finais após 5 anos:
45
+ """
46
+ for nome, valor in investimentos_finais.items():
47
+ prompt += f" - {nome}: R$ {valor:,.2f}\n"
48
+
49
+ prompt += """
50
+ Destaque qual foi o melhor investimento, o retorno percentual sobre o capital, e comente sobre possíveis estratégias e perfis de risco.
51
+ Use uma linguagem formal, com parágrafos claros e destaque para o investimento com maior retorno.
52
+ """
53
+
54
+ resposta = openai.ChatCompletion.create(
55
+ model="gpt-4o",
56
+ messages=[
57
+ {"role": "system", "content": "Você é um analista financeiro experiente."},
58
+ {"role": "user", "content": prompt}
59
+ ]
60
+ )
61
+ return resposta.choices[0].message.content
62
+
63
+ def render_pdf(template_src, context_dict):
64
+ html = render_template(template_src, **context_dict)
65
+ result = io.BytesIO()
66
+ pisa_status = pisa.CreatePDF(io.StringIO(html), dest=result)
67
+ if not pisa_status.err:
68
+ result.seek(0)
69
+ return result
70
+ return None
71
+
72
+ @app.route("/", methods=["GET", "POST"])
73
+ def index():
74
+ if request.method == "POST":
75
+ capital = float(request.form["capital"])
76
+ studio_ret = float(request.form["studio_ret"])
77
+ valorizacao = float(request.form["valorizacao"])
78
+ franquia_ret = float(request.form["franquia_ret"])
79
+ acoes_ret = float(request.form["acoes_ret"])
80
+ renda_fixa = float(request.form["renda_fixa"])
81
+ inflacao = float(request.form["inflacao"])
82
+
83
+ anos = list(range(1, 6))
84
+
85
+ patrimonio_studio = [capital * ((1 + valorizacao / 100) ** ano) for ano in anos]
86
+ renda_acumulada_studio = [capital * (((1 + studio_ret / 100) ** (12 * ano)) - 1) for ano in anos]
87
+ studio_total = [p + r for p, r in zip(patrimonio_studio, renda_acumulada_studio)]
88
+
89
+ franquia = [capital + (franquia_ret * ano) for ano in anos]
90
+ acoes = [capital * ((1 + acoes_ret / 100) ** ano) for ano in anos]
91
+ renda_fixa_valores = [capital * ((1 + renda_fixa / 100) ** ano) for ano in anos]
92
+
93
+ dados = {
94
+ "Ano": anos,
95
+ "Studio (Patrimônio + Renda)": studio_total,
96
+ "Franquia": franquia,
97
+ "Ações": acoes,
98
+ "Renda Fixa": renda_fixa_valores
99
+ }
100
+ df = pd.DataFrame(dados)
101
+
102
+ investimentos_finais = {
103
+ "Studio (Patrimônio + Renda)": studio_total[-1],
104
+ "Franquia": franquia[-1],
105
+ "Ações": acoes[-1],
106
+ "Renda Fixa": renda_fixa_valores[-1],
107
+ }
108
+
109
+ plt.figure(figsize=(8, 5))
110
+ plt.plot(anos, studio_total, label="Studio (Patrimônio + Renda)", marker="o")
111
+ plt.plot(anos, franquia, label="Franquia", marker="o")
112
+ plt.plot(anos, acoes, label="Ações", marker="o")
113
+ plt.plot(anos, renda_fixa_valores, label="Renda Fixa", marker="o")
114
+ plt.title("Projeção de Investimentos (5 anos)")
115
+ plt.xlabel("Ano")
116
+ plt.ylabel("Valor (R$)")
117
+ plt.legend()
118
+ plt.grid(True)
119
+ plt.gca().yaxis.set_major_formatter(FuncFormatter(lambda x, _: f"R${x:,.0f}".replace(",", ".")))
120
+ plt.tight_layout()
121
+
122
+ buf = io.BytesIO()
123
+ plt.savefig(buf, format="png")
124
+ buf.seek(0)
125
+ grafico_base64 = base64.b64encode(buf.getvalue()).decode("utf-8")
126
+ buf.close()
127
+ plt.close()
128
+
129
+ df_formatado = df.copy()
130
+ for col in df.columns:
131
+ if col != "Ano":
132
+ df_formatado[col] = df_formatado[col].apply(formatar_brl)
133
+ tabela = df_formatado.to_html(index=False, classes="table table-striped table-sm text-end", border=0)
134
+
135
+ analise_final = gerar_analise_ia(investimentos_finais, capital, patrimonio_studio[-1])
136
+
137
+ return render_template(
138
+ "index.html",
139
+ capital=capital,
140
+ tabela=tabela,
141
+ grafico=grafico_base64,
142
+ analise_final=analise_final
143
+ )
144
+
145
+ return render_template("index.html")
146
+
147
+ @app.route("/gerar-pdf", methods=["POST"])
148
+ def gerar_pdf():
149
+ capital = float(request.form["capital"])
150
+ studio_ret = float(request.form["studio_ret"])
151
+ valorizacao = float(request.form["valorizacao"])
152
+ franquia_ret = float(request.form["franquia_ret"])
153
+ acoes_ret = float(request.form["acoes_ret"])
154
+ renda_fixa = float(request.form["renda_fixa"])
155
+ inflacao = float(request.form["inflacao"])
156
+
157
+ anos = list(range(1, 6))
158
+
159
+ patrimonio_studio = [capital * ((1 + valorizacao / 100) ** ano) for ano in anos]
160
+ renda_acumulada_studio = [capital * (((1 + studio_ret / 100) ** (12 * ano)) - 1) for ano in anos]
161
+ studio_total = [p + r for p, r in zip(patrimonio_studio, renda_acumulada_studio)]
162
+
163
+ franquia = [capital + (franquia_ret * ano) for ano in anos]
164
+ acoes = [capital * ((1 + acoes_ret / 100) ** ano) for ano in anos]
165
+ renda_fixa_valores = [capital * ((1 + renda_fixa / 100) ** ano) for ano in anos]
166
+
167
+ dados = {
168
+ "Ano": anos,
169
+ "Studio (Patrimônio + Renda)": studio_total,
170
+ "Franquia": franquia,
171
+ "Ações": acoes,
172
+ "Renda Fixa": renda_fixa_valores
173
+ }
174
+ df = pd.DataFrame(dados)
175
+
176
+ investimentos_finais = {
177
+ "Studio (Patrimônio + Renda)": studio_total[-1],
178
+ "Franquia": franquia[-1],
179
+ "Ações": acoes[-1],
180
+ "Renda Fixa": renda_fixa_valores[-1],
181
+ }
182
+
183
+ # Premissas formatadas
184
+ premissas = {
185
+ "Capital Inicial": formatar_brl(capital),
186
+ "Retorno Mensal Studio (%)": f"{studio_ret:.2f}%",
187
+ "Valorização Anual Studio (%)": f"{valorizacao:.2f}%",
188
+ "Retorno Anual Franquia (R$)": formatar_brl(franquia_ret),
189
+ "Retorno Anual Ações (%)": f"{acoes_ret:.2f}%",
190
+ "Retorno Anual Renda Fixa (%)": f"{renda_fixa:.2f}%",
191
+ "Inflação Anual (%)": f"{inflacao:.2f}%"
192
+ }
193
+
194
+ # Destacar melhor investimento na tabela
195
+ melhor_investimento = max(investimentos_finais, key=investimentos_finais.get)
196
+
197
+ df_formatado = df.copy()
198
+ for col in df.columns:
199
+ if col != "Ano":
200
+ df_formatado[col] = df_formatado[col].apply(formatar_brl)
201
+ if col == melhor_investimento:
202
+ df_formatado[col] = df_formatado[col].apply(lambda v: f'<strong style="color:green">{v}</strong>')
203
+
204
+ tabela_html = df_formatado.to_html(index=False, classes="tabela", escape=False, border=0)
205
+
206
+ analise_final_ia = gerar_analise_ia(investimentos_finais, capital, patrimonio_studio[-1])
207
+
208
+ data_hoje = data_por_extenso(datetime.now())
209
+
210
+ context = {
211
+ "capital": capital,
212
+ "grafico": base64.b64encode(plot_grafico(anos, studio_total, franquia, acoes, renda_fixa_valores)).decode("utf-8"),
213
+ "tabela": tabela_html,
214
+ "analise_final": analise_final_ia,
215
+ "premissas": premissas,
216
+ "data_hoje": data_hoje
217
+ }
218
+
219
+ pdf = render_pdf("relatorio.html", context)
220
+ if pdf:
221
+ return send_file(pdf, mimetype="application/pdf", as_attachment=True, download_name="relatorio_investimento.pdf")
222
+ else:
223
+ return "Erro ao gerar PDF", 500
224
+
225
+ def plot_grafico(anos, studio_total, franquia, acoes, renda_fixa_valores):
226
+ plt.figure(figsize=(8, 5))
227
+ plt.plot(anos, studio_total, label="Studio (Patrimônio + Renda)", marker="o")
228
+ plt.plot(anos, franquia, label="Franquia", marker="o")
229
+ plt.plot(anos, acoes, label="Ações", marker="o")
230
+ plt.plot(anos, renda_fixa_valores, label="Renda Fixa", marker="o")
231
+ plt.title("Projeção de Investimentos (5 anos)")
232
+ plt.xlabel("Ano")
233
+ plt.ylabel("Valor (R$)")
234
+ plt.legend()
235
+ plt.grid(True)
236
+ plt.gca().yaxis.set_major_formatter(FuncFormatter(lambda x, _: f"R${x:,.0f}".replace(",", ".")))
237
+ plt.tight_layout()
238
+
239
+ buf = io.BytesIO()
240
+ plt.savefig(buf, format="png")
241
+ buf.seek(0)
242
+ img_bytes = buf.getvalue()
243
+ buf.close()
244
+ plt.close()
245
+ return img_bytes
246
+
247
+ if __name__ == "__main__":
248
+ app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 7860)))