Módulo 08 AdmTech · Computação · Semana 10 · 16/12/2026
| Bloco | Minutos | Tema | Interação que fecha o bloco |
|---|---|---|---|
| Daily | 15 | O que fiz, o que vou fazer, impedimentos | módulo de cada entrega e chave fora do repositório |
| 1 | 0 a 15 | Resgate da Aula 05 e onde o otimizador roda | Peer Instruction |
| 2 | 15 a 30 | Cliente, servidor, HTTP, JSON e o contrato | previsão do status no montador |
| 3 | 30 a 45 | FastAPI ao vivo, Pydantic e cache | que erro para um ticker que não existe |
| 4 | 45 a 60 | A API testada com TestClient | dupla no notebook, seções 3 e 4 |
| 5 | 60 a 75 | O componente React e o CORS | escolha coletiva: navegador ou servidor |
| 6 | 75 a 90 | O LLM chamado pelo backend | que número conferir por código |
| 7 | 90 a 105 | Quiz e amarração com a Sprint 5 | quiz de três perguntas |
Horários de relógio a confirmar na Adalove; os blocos contam do fim da daily.
Módulo 08 AdmTech · Aula 06 · Sprint 5
2
A Aula 05 deixou pronto o teste fora da amostra das duas carteiras ótimas e a medida de estabilidade dos pesos entre janelas. Hoje cada entrega vira um módulo que a API importa.
| Entrega | Módulo no backend do exemplo | O que a API usa |
|---|---|---|
| A1 | carteira/dados.py | Adj Close e CDI, com a lacuna isolada preenchida pelo último preço (ADR-009) |
| A2 | carteira/metricas.py | retornos na janela comum dos tickers pedidos e métricas anualizadas por 252 |
| A3 | módulo de Monte Carlo do grupo | rota de simulação, a cargo do grupo |
| A4 | carteira/otimizador.py | variância mínima, máximo Sharpe e fronteira de 50 pontos |
| Aula 05 | validação do grupo | teste fora da amostra e estabilidade, a cargo do grupo |
Um gestor do parceiro digita tickers numa tela. O otimizador roda no navegador ou no servidor?
Módulo 08 AdmTech · Aula 06 · Sprint 5 · [1] [2]
3
O gestor digita cinco tickers e clica em Otimizar. Onde o otimizador deve rodar?
Módulo 08 AdmTech · Aula 06 · Sprint 5 · [3]
4
Antes de tocar: anote em qual das três caixas um pedido com ticker repetido para.
Módulo 08 AdmTech · Aula 06 · Sprint 5 · [2]
6
| Rota | Entrada | Sucesso | Erros do contrato |
|---|---|---|---|
GET /ativos | nenhuma | 200, tickers da base | nenhum |
POST /carteiras/otimizar | 2 a 15 tickers, início, fim, taxa opcional | 200, ativos, duas carteiras e fronteira | 404 ticker fora da base; 422 entrada inválida |
POST /carteiras/interpretar | o mesmo pedido | 200, texto e checagem de presença de cada número | 404, 422; 503 sem chave; 502 provedor |
POST /carteiras/exportar | o mesmo pedido | 200, CSV com os pesos | 404, 422 |
Este contrato vai para o SPEC.md antes de dividir o trabalho: frontend e backend passam a andar em paralelo.
Módulo 08 AdmTech · Aula 06 · Sprint 5 · [2] [8]
7
Cada dupla anota o status previsto antes de clicar em Enviar. Respostas gravadas da API de exemplo, sem chave do LLM.
Módulo 08 AdmTech · Aula 06 · Sprint 5 · [2]
8
/docsfrom carteira import dados, pipeline
class PedidoCarteira(BaseModel):
tickers: list[str] = Field(min_length=2,
max_length=15)
inicio: date = date(2019, 1, 1)
fim: date = date(2026, 8, 31)
# + taxa opcional e validador de repetição
@lru_cache(maxsize=64)
def _calcular(tickers, inicio, fim, rf):
try:
return Resultado(**pipeline.calcular(
tickers, inicio, fim, rf))
except dados.TickerDesconhecido as erro:
raise HTTPException(404, "Ticker fora ...")
@app.post("/carteiras/otimizar")
def otimizar(pedido: PedidoCarteira) -> Resultado:
return _calcular(tuple(pedido.tickers), ...)
| Rota | nome da operação do gestor, /carteiras/otimizar |
| Pydantic | recusa a entrada errada com 422, antes de qualquer cálculo |
| Importa | pipeline.calcular não sabe de HTTP e serve também ao notebook |
/docs | documentação gerada dos mesmos modelos, para testar no navegador |
Módulo 08 AdmTech · Aula 06 · Sprint 5 · [2] [5]
10
Antes de tocar: cada pedido novo calcula 52 carteiras no otimizador. Em quais dos cinco pedidos o servidor com cache volta a calcular?
Módulo 08 AdmTech · Aula 06 · Sprint 5 · [2]
11
Que erro a API deve devolver para um ticker que não existe: 404, recurso fora da base, ou 422, entrada inválida? Cada dupla escolhe e justifica pelo contrato antes de revelar.
| Status | Quem detecta | Exemplo | O que o gestor lê |
|---|---|---|---|
| 422 | Pydantic, antes do cálculo | um ticker só; início depois do fim | escolha ao menos dois ativos e um período válido |
| 404 | o coletor, ao procurar o ticker | XPTO3 | algum ativo não está na base (XPTO3) |
| 503 | a rota de interpretação | servidor sem OPENROUTER_API_KEY | os números da carteira continuam válidos |
| 502 | a rota de interpretação | o provedor do LLM não respondeu | os números da carteira continuam válidos |
O exemplo adota 404 e registra a escolha no SPEC.md; 422 também é defensável, desde que o contrato diga qual e mantenha o mesmo corpo de erro. Um 500 fica fora do contrato: é exceção sem tratamento, defeito do grupo.
Módulo 08 AdmTech · Aula 06 · Sprint 5 · [8]
12
XPTO3 (célula c).Checagem aos 6 min: a seção 4 passou e o caso da dupla está escrito, ainda sem rodar. Debrief: uma dupla por caminho mostra o status obtido, e a turma confronta o do XPTO3 com o contrato do slide 12.
Abrir o notebook da Aula 06 no Colab
Módulo 08 AdmTech · Aula 06 · Sprint 5
13
fetch, carregamento, erro e o gráficoconst [carregando, setCarregando] = useState(false);
const [erro, setErro] = useState(null);
const [resultado, setResultado] = useState(null);
async function aoOtimizar(evento) {
evento.preventDefault();
setCarregando(true);
setErro(null);
try {
setResultado(await otimizar(pedido()));
} catch (e) {
setResultado(null);
setErro(e.message); // já traduzida em api.js
} finally {
setCarregando(false);
}
}
useState | cada mudança de estado redesenha a tela |
api.js | todo o fetch num arquivo; 404 vira "algum ativo não está na base" |
| Carregando | o botão vira "Calculando..." e não aceita outro clique |
| CORS | React em localhost:5173, API em 127.0.0.1:8000: sem o middleware, o navegador descarta a resposta |
Módulo 08 AdmTech · Aula 06 · Sprint 5 · [2] [3] [6]
15
1. A chave do LLM
2. O cálculo da fronteira
3. O gráfico da fronteira
4. A validação da entrada
Cada dupla decide antes do clique. A sala vota em cada item.
Módulo 08 AdmTech · Aula 06 · Sprint 5
16
"maximo_sharpe": {
"pesos_pct": {
"PETR4": 23.33,
"WEGE3": 25.02,
"IVVB11": 51.64
},
"retorno_anual_pct": 26.9,
"volatilidade_anual_pct": 19.13,
"sharpe": 0.91
},
"taxa_livre_risco_pct": 9.51,
"inicio_janela": "2019-01-03",
"pregoes": 1907
| Chave | OPENROUTER_API_KEY no ambiente do backend; .env fora do git |
| Contexto | o JSON de /carteiras/otimizar, em porcentagem; pregoes conta os retornos diários da janela comum dos 5 tickers, que começa em inicio_janela |
| Regras | usar só esses números, declarar limitações, não prometer retorno |
| Modelo | LLM_MODELO no ambiente: trocar de modelo muda custo por token e texto |
| Saída | o texto volta com a checagem de presença de cada número citado |
Módulo 08 AdmTech · Aula 06 · Sprint 5 · [4] [7]
18
Que número desse texto o grupo consegue conferir por código? Marquem à mão antes de clicar.
Módulo 08 AdmTech · Aula 06 · Sprint 5 · [4]
19
| Trecho | Erro plantado | Verificação de presença | Valor certo |
|---|---|---|---|
| 17,13% | volatilidade alterada | acusa: não existe no JSON | 19,13% |
| 30,00% | promessa de retorno | acusa: não existe no JSON | nenhum: o JSON não tem futuro |
| 0,16 | ativo trocado | aprova: existe, no IVVB11 | o IVVB11 diversifica mais, com 0,16; VALE3 tem 0,32 |
10 dos 12 números passam na verificação de presença, e 9 estão certos. A presença, sem conferir ativo, unidade nem período, deixa passar o 0,16, e a origem devolvida mostra o erro.
Módulo 08 AdmTech · Aula 06 · Sprint 5 · [4]
20
1. O pedido traz só a PETR4. Que status a API devolve?
2. Onde mora a OPENROUTER_API_KEY?
3. Que campo da verificação mostra o ativo trocado?
Módulo 08 AdmTech · Aula 06 · Sprint 5
21
| Seção | O que entrega |
|---|---|
| 1 e 2 | Os dados e os módulos das sprints numa função calcular sem HTTP |
| 3 e 4 | A API no notebook e os casos 200, 422 e do ticker inexistente com TestClient |
| 5 | O cache contando os problemas de otimização por pedido |
| 6 e 7 | O prompt com os números reais, a chamada opcional e o verificador |
| 8 | Desafio do A5: rota de métricas para pesos informados, com 422 para pesos que não somam 1 |
Notebook no GitHub · Abrir no Colab · Exemplo com backend e frontend
Módulo 08 AdmTech · Aula 06 · Sprint 5
22
| Critério do barema | Peso | O que hoje já adiantou |
|---|---|---|
| Operabilidade por não programador | 25% | estado de carregamento e erro traduzido para o gestor |
| Integração do pipeline | 10% | API que importa os módulos, com cache da mesma consulta |
| Qualidade da interpretação por LLM | 25% | prompt com os números reais e o verificador de números |
| Exportação e estabilidade | 5% | rota de CSV e limite de 15 ativos no Pydantic |
| Especificação e documentação | 15% | contrato da API no SPEC.md; README com fastapi dev e npm run dev |
| ADRs, nota individual | 20% | divisão entre frontend e backend, rotas e desenho do prompt |
A5 vale 2 pontos. /backend e /frontend separados, .env.example sem chave. Review da Sprint 5 em 18/12/2026, que fecha o módulo.
Módulo 08 AdmTech · Aula 06 · Sprint 5 · barema do REVISAO-LBL08-COMPUTACAO.md, Artefato 5 · [9]
23
Módulo 08 AdmTech · Aula 06 · Sprint 5
24