Pricer de taxas de financiamento da B3 comparadas ao CDI, em quatro estruturas (uma aba cada):
As três primeiras em taxa exp/252, com custos por ponta (emolumentos B3 + corretagem) e comparação com o CDI (curva DI colada + âncora BCB). Backend FastAPI, frontend página única (4 abas).
pip install -r requirements.txt
uvicorn main:app --port 8007 # http://localhost:8007
pytest -q
POST/GET /api/box · /api/box4 · /api/termo · /api/box-offshore (precificam) · GET /api/du (dias
úteis c/ feriados ANBIMA) · GET /api/cdi (CDI spot BCB) · POST /api/curva
(interpola a curva DI) · GET /api/aluguel/{ticker} · GET /api/health. O fallback
GET …?b=<base64> cobre proxies que bloqueiam POST JSON.
Imagem baked (rebuild). Serviço box no compose trading-dashboard, em
box.aitraderhub.com (público, sem import sso — só análise). Deploy: scp para
/opt/box-pricer/ → docker compose build box && up -d box.
Design completo (matemática das 3 estruturas, emolumentos com fontes B3, curva DI,
feriados, convenções e decisões de projeto):
#spec.
Pricer de taxas de financiamento da B3 comparadas ao CDI, em três estruturas (uma aba cada): box de 3 pontas, box de 4 pontas e termo de ação. Cada uma extrai a taxa embutida (a.a., exp/252), decompõe os custos por ponta e compara com o CDI. Backend FastAPI, frontend uma página estática única com 3 abas.
Público em box.aitraderhub.com (sem login — só análise, sem dado sensível).
| Arquivo | Responsabilidade |
|---|---|
box.py |
Box de 3 pontas (ação + call + put): taxa, aluguel implícito, custos, Black. |
box4.py |
Box de 4 pontas (4 opções): financiamento puro, emol próprio da B3. |
termo.py |
Termo de ação: input em CDI+, resolve o preço a termo. |
calendario.py |
Feriados ANBIMA embutidos + dias úteis (base 252). |
di_curve.py |
Curva DI colada + âncora BCB + interpolação exp/252 flat-forward. |
main.py |
FastAPI: endpoints das 3 estruturas + /du /cdi /curva /aluguel /health. |
static/index.html |
Página única, 3 abas, render dos resultados (waterfall + custos + caixa). |
Cada motor é puro (funções sem estado) e testado em tests/.
taxa = (FV/PV)^(252/du) − 1. Decimais anuais (0.13 = 13%).[(1+taxa)^(1/252) − 1] / [(1+cdi)^(1/252) − 1] × 100
(capitalização diária, convenção de pós-fixado). Helper box.pct_of_cdi.(1+taxa)/(1+cdi) − 1 (bps). Helper
box.di_spread_bps. Para o box de 3 pontas dá exatamente −aluguel, pois
(1+box)·(1+aluguel) = (1+cdi).(FV_líq / PV_líq)^(252/du) − 1.fair (sem custos) → financiamento líquido (aplica,
ganha menos) e reversão/tomada all-in (toma, paga mais). O _incr atribui o
a.a. incremental de cada componente partindo do fair.box.py)Ação + call + put, mesmo strike K e vencimento. Modo por aluguel.
+ação −call +put. PV = S + P − C,
FV = K + proventos. Reversora (toma caixa, toma a ação alugada): inverso.taxa_box = (1+cdi)/(1+aluguel) − 1; PV = FV/(1+taxa_box)^(du/252); spread justo
P − C = PV − S. Informe uma perna de tela → a outra sai justa.(1+cdi)/(1+taxa_box) − 1.K) na saída; aluguel BTC
pro-rata du/252 na saída (ver Emolumentos).black_put/paridade; forward do box, vol informada).box4.py)Só opções listadas (sem ação → sem aluguel). Strikes K1 < K2: trava de alta em call
(+C(K1) −C(K2)) + trava de baixa em put (+P(K2) −P(K1)). Payoff trava em K2 − K1.
FV = (K2−K1)·lote; PV = FV/(1+taxa)^(du/252).termo.py)Ação + contrato a termo. Sem opções, sem aluguel/proventos.
taxa_liq = (1+cdi)·(1+spread) − 1 (conversão no front).F. Dependência circular (emol de termo incide sobre
F) em fórmula fechada: FV = (S·lote + A)·G / (1 − b·G), com
G = (1+taxa_liq)^(du/252), A = custos do financiador independentes de F,
b = emol de termo (fração). Guard: 1 − b·G > 0.calendario.py)Feriados nacionais bancários ANBIMA embutidos (arquivo oficial, cobre 2001–2099,
incl. móveis — Carnaval, Sexta-feira Santa, Corpus Christi — e Consciência Negra).
du(inicio, fim) = dias úteis em [inicio, fim) (convenção B3). Usado no du do
vencimento e na conversão PU→taxa dos DI1.
di_curve.py)A B3 fechou o scraping automático (Cloudflare); a curva é colada + âncora no CDI spot do BCB (SGS série 4389, público, sem token).
parse_curva: linhas contrato DI1 (F26…) ou data + taxa %.cdi_para_prazo: âncora do ponto curto no CDI do BCB + vértices colados →
interpolação exponencial flat-forward em DU/252 (convenção B3/ANBIMA):
FC(du) = FC_a·(FC_b/FC_a)^((du−du_a)/(du_b−du_a)), FC_i=(1+r_i)^(du_i/252);
taxa = FC^(252/du) − 1.| Operação | Alíquota | Base | Obs. | Fonte |
|---|---|---|---|---|
| Estratégias BOX (4 pontas) | 0,0390% PF · 0,0300% fundos | valor financeiro (PV) | exercício no venc. isento | B3 |
| Termo de ações | 0,0650% (PF e fundos) | valor da operação a termo | por investidor | B3 |
| À vista (swing) | 0,0300% PF | valor da operação | compra spot do financiador (termo) | B3 |
| Empréstimo de ativos (BTC) | i = clamp(20%·aluguel, 2,5 bps, 70 bps) a.a. |
notional S·lote, pro-rata du/252 |
só o tomador; doador isento | B3 |
Emol de ação 3,0 bps e opção 9,5 bps (sobre o prêmio) — box de 3 pontas. Todos os parâmetros editáveis na UI. Corretagem é da corretora (editável, com devolução). Valores B3 já incluem PIS/COFINS.
| Endpoint | Descrição |
|---|---|
POST /api/box · GET /api/box?b=<b64> |
box 3 pontas |
POST /api/box4 · GET /api/box4?b=<b64> |
box 4 pontas |
POST /api/termo · GET /api/termo?b=<b64> |
termo de ação |
GET /api/du?venc=&hoje= |
dias úteis (feriados ANBIMA) |
GET /api/cdi |
CDI spot do BCB (SGS 4389) |
POST /api/curva |
interpola a curva DI colada no vencimento |
GET /api/aluguel/{ticker} |
aluguel de tela (doador/tomador) via trading-app |
GET /api/health |
healthcheck |
O fallback GET …?b=<base64> existe para proxies corporativos que bloqueiam POST JSON.
tests/test_box.py, test_box4.py, test_termo.py, test_curva.py — motores puros,
casos canônicos (round-trips, custos por ponta, emol correto, waterfall, feriados,
interpolação flat-forward). pytest -q.
F de trás pra
frente) — os boxes seguem com input na taxa fair.