Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Changelog

Todas as mudanças notáveis deste projeto são documentadas aqui.
Formato baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.1.0/);
o projeto segue versionamento pragmático (paper-trading-first, ver ADR-001).

> **Nota sobre histórico:** o histórico detalhado por sprint vive nos
> `docs/roadmap_v1..v6.md` e nas auditorias datadas (`docs/auditoria-*.md`) —
> esses arquivos são **registros históricos** e preservam os números da época
> (ex.: contagens de testes por sprint). A contagem de testes **canônica atual**
> está no README e no TESTING.md.

## [Não lançado]

### Onda 2 — Higiene estrutural (backend + frontend + docs)
- **R5 (Kelly):** fórmula central do Kelly extraída para
`src/risk/position_sizing.full_kelly_fraction`, agora **fonte única** consumida
pelo endpoint `GET /v1/risk/kelly` (que antes reimplementava inline) e por
`KellyCriterion`. `src/risk/` deixa de ser código morto. Contrato da API
inalterado. *Plugar Kelly no sizing real (`SquadOrchestrator._position_quantity`)
permanece como cauda do R5 — ver ADR-006.*
- **R2 (colisões de nome):** classes duplicadas renomeadas por propósito —
`protocols.SquadOrchestrator`→`A2ASquad`, `adaptive_replanner.AdaptivePlanner`→
`AdaptiveReplanner`, `continuous_evaluator.ContinuousEvaluator`→
`AgentPerformanceEvaluator`, `intelligent_forgetting.MemoryStore`→
`RelevanceMemoryStore`.
- **market_data unificado:** o backtest (`engine._build_market_data`) agora computa
um `TechnicalIndicators` real + regime (guarda de warmup), em vez de placeholders
— estratégias dirigidas por indicadores (Grid, MeanReversion) exercitam o mesmo
caminho do live.
- **Frontend (R8, fatia):** utilitário `.kpi-row` (auto-reflow via `auto-fit`)
aplicado às linhas de KPI das telas; **sidebar responsiva** < 960px (lacuna do
briefing). Rollout completo de responsividade/a11y permanece aberto.
- **Docs:** ADR-006 (política de sizing Kelly); `mapeamento-dados.md` §8/§9 e
`arquitetura.md` §12 sincronizados; `CHANGELOG.md`/`CONTRIBUTING.md`/`SECURITY.md`
adicionados; `plano-melhorias.md` atualizado.

### Onda 1 — Correções seguras (mergeada, PR #68)
- **Backend:** `ab_tests.jsonl` agora é JSON válido (`json.dumps`);
`mean_reversion` roteável no regime `sideways`; remoção de dados mortos
(`RiskAgent.max_daily_loss_pct`, `UnifiedOrchestrator.sandbox`/`chain_manager`,
`AgentMemorySystem.short_term`); log em vez de `except: pass` silencioso.
- **Frontend:** erros de mutação → toast (HITL/journal/settings/backtest);
confirmação em 2 etapas ao aprovar/rejeitar ordem; fim da colisão
`STATUS_VARIANT`/`STATUS_LABEL`; limpeza de arquivos/CSS mortos.
- **Docs:** contagem de testes reconciliada (**416 coletados / 408 passam /
8 pulados** sem `DATABASE_URL`); ADR-004 documentado + índice corrigido;
`docs/documentação/` → `docs/data/`; `docs/plano-melhorias.md` criado como fonte
única do backlog.

## Histórico anterior (v1–v6)
Ver `docs/roadmap_v1.md` … `docs/roadmap_v6.md` (correção & verdade → produção
Docker → observabilidade → métricas de domínio → Grafana → backend PostgreSQL
opcional) e `docs/auditoria-criptotrade-2026-06.md` (remediação P0–P3 + Fase 5b).
59 changes: 59 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Contribuindo com o Criptotrade

Obrigado por contribuir! Este guia resume o fluxo de desenvolvimento. Para a
arquitetura, ver `docs/architecture/arquitetura.md` (C4) e
`docs/uml/arquitetura-uml.md` (classes); para o backlog priorizado, ver
`docs/plano-melhorias.md`.

## Princípios inegociáveis

Toda mudança **deve preservar** os invariantes centrais:

1. **Paper-trading-first** — `EXCHANGE_DRY_RUN` é obrigatório; o único caminho
para a exchange roda offline por padrão (ADR-001). Nunca introduza um caminho
de ordem real que rode sem override explícito de ambiente.
2. **HITL fail-closed** — ordens acima do limiar de autonomia exigem aprovação
humana; em produção a API sobe fail-closed sem `API_KEYS`.
3. **Tudo auditável** — decisões e execuções vão para o ledger append-only / event
log XES. Não remova trilha de auditoria.

## Setup

```bash
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
pytest -q # suíte completa (ver contagem no README/TESTING.md)
```

Console React (opcional): `cd docs/design/pages && npm install && npm run build`.

## Fluxo

1. **Branch** a partir de `master`.
2. **Commits** em [Conventional Commits](https://www.conventionalcommits.org/)
(`feat:`, `fix:`, `docs:`, `refactor:`, `test:`, `build:`, `chore:`).
3. **Testes**: adicione/estenda testes em `tests/`. O gate de cobertura da CI é
**72%** (`pyproject.toml`); não o reduza.
4. **Lint**: `ruff check src` (regras E4/E7/E9/F).
5. **CI verde** antes do merge — jobs `test`, `console-build`, `console-e2e`,
`docker-build`, `validate-phases`, `secret-scan`.
6. **PR** contra `master`. Decisões arquiteturais entram como **ADR** em
`docs/adr/` (use `ADR-Template.md`; próximo número livre indicado no
`docs/adr/README.md`).

## Convenções

- **Sem segredos no repo.** `.env` é gitignored; use `.env.example` como
referência. A CI roda `secret-scan` e `scripts/validate_deploy_config.py`.
- **Nomes de classe únicos por propósito** (ver R2 em `arquitetura.md §12`):
evite reintroduzir colisões como dois `SquadOrchestrator`.
- **Reuse antes de criar**: cheque utilitários existentes em `src/core`,
`src/utils` e (no front) `components.jsx` antes de escrever novos.
- **Documentação viva vs. histórica**: atualize os docs de estado atual
(`README`, `TESTING.md`, `mapeamento-dados.md`, `arquitetura.md`,
`plano-melhorias.md`, `CHANGELOG.md`). **Não** reescreva registros datados
(roadmaps por sprint, auditorias) — eles são snapshots históricos.

## Reportando vulnerabilidades

Ver `SECURITY.md`.
48 changes: 48 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Política de Segurança

O Criptotrade é um sistema financeiro (trading de cripto). Levamos segurança a
sério — mesmo em modo paper-trading, uma configuração insegura pode expor a API,
segredos ou, no futuro com trading real, capital.

## Versões suportadas

O projeto está em estágio **paper-trading / alpha**. Apenas o `master` recebe
correções de segurança.

## Reportando uma vulnerabilidade

**Não** abra uma issue pública para vulnerabilidades. Em vez disso:

- Envie um relatório privado por **[GitHub Security Advisories]**
(`Security` → `Report a vulnerability` no repositório), ou
- contate o mantenedor do repositório diretamente.

Inclua: descrição, passos de reprodução, impacto potencial e, se possível, uma
sugestão de correção. Faremos o possível para responder rapidamente e coordenar
uma divulgação responsável após a correção.

[GitHub Security Advisories]: https://docs.github.com/pt/code-security/security-advisories

## Superfície e controles atuais

Controles já implementados (ver `docs/architecture/arquitetura.md §11` e a
auditoria `docs/auditoria-criptotrade-2026-06.md`):

- **Autenticação** por `X-API-Key` (`API_KEYS`), timing-safe
(`secrets.compare_digest`), **fail-closed em produção** (a API recusa subir sem
`API_KEYS` quando `APP_ENV=production`).
- **CORS** travável por `CORS_ORIGINS` (sem `*` em produção — validado na CI por
`scripts/validate_deploy_config.py`).
- **Rate limiting** (`RateLimitMiddleware`, Redis opcional).
- **Headers de segurança** (CSP, HSTS, X-Frame-Options, etc.) via middleware + nginx.
- **Confirmação explícita** (`confirm: true`) para mutações de alto impacto.
- **Sem segredos no repo**: `.env` gitignored; CI roda `secret-scan`.
- **Paper-trading-first**: `EXCHANGE_DRY_RUN` obrigatório; zero rede de corretora
por padrão.

## Boas práticas para operadores

- Gere um `API_KEYS` forte (`openssl rand -hex 32`) e nunca o commite.
- Só vire `EXCHANGE_DRY_RUN=false` como decisão deliberada, após validar a stack
(ver `docs/acaoPendenteDono.md`).
- Mantenha `CORS_ORIGINS` restrito à origem real do console.
57 changes: 57 additions & 0 deletions docs/adr/006-kelly-sizing-policy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# ADR-006: Política de sizing por Kelly (fonte única + cauda de integração)

## Status
🟡 Aceita parcialmente (2026-07-15) — fonte única entregue; sizing ao vivo diferido.

## Contexto
O módulo `src/risk/` (`KellyCriterion`, `PositionSizer`, `CapitalProtections`)
existia **completo e testado, mas morto**: nenhum código de aplicação o
importava. Pior, o endpoint `GET /v1/risk/kelly` **reimplementava o Kelly inline**
(`src/api/routes/risk.py`), com constantes e fórmulas divergentes da biblioteca —
dando a falsa impressão de que o sistema dimensionava posições por Kelly quando, na
verdade, o pipeline de trading (`SquadOrchestrator._position_quantity`) usa
`position_size_pct` fixo. Isto está registrado como **R5** em
`docs/architecture/arquitetura.md §12` e no §8 de `docs/data/mapeamento-dados.md`.

Havia três caminhos possíveis: (a) **deletar** o módulo morto; (b) **unificar**
tornando a biblioteca a fonte única e o endpoint um consumidor; (c) **plugar** o
Kelly no sizing real das ordens.

## Decisão
Adotar (b) agora, de forma **preservadora de contrato**, e diferir (c):

1. A fórmula central do Kelly foi extraída para
`src/risk/position_sizing.full_kelly_fraction(win_rate, avg_win_pct,
avg_loss_pct)` — **fonte única de verdade**. É algebricamente idêntica à forma
anterior (`(p·b − q)/b ≡ p − (1−p)/b`), então **nenhum número da API muda**.
2. `GET /v1/risk/kelly` passa a **delegar** a essa função (removendo a
reimplementação inline). `KellyCriterion.full_kelly()` também a consome. Assim
`src/risk/` deixa de ser código morto.
3. A apresentação do endpoint (Kelly fracionado × 0.25, risco de ruína, limiar de
10 trades para `data_quality:"insufficient"`) é **mantida como está** — é um
endpoint **consultivo** (display), não de execução.

## Diferido (cauda do R5)
- **Plugar `PositionSizer`/`KellyCriterion` no sizing real** de ordens
(`SquadOrchestrator._position_quantity`) muda **o que é negociado** — é uma
mudança de comportamento que exige validação dedicada (backtest comparativo,
revisão de risco) e **não** entra junto de higiene de código.
- **Unificar a apresentação fracionada/ruína** entre endpoint e biblioteca (hoje o
endpoint usa fração crua não-clampada; a lib usa percentual clampado [0.5, 5.0] e
a fórmula clássica de ruína). Decisão de produto sobre qual semântica é canônica.
- **`CapitalProtections`** (limites diário/semanal/mensal com `size_multiplier`)
permanece disponível, ainda não alimentado por P&L do período.

## Consequências
- **Positivas:** remove a duplicação e a falsa impressão; `src/risk/` passa a ser
exercitado pela API; caminho claro para o sizing por Kelly quando houver
validação. Zero mudança observável de contrato/comportamento.
- **Negativas:** o sistema **ainda não dimensiona por Kelly** — o valor pleno do
R5 (sizing dinâmico por edge) fica para a etapa (c). O módulo continua
parcialmente subutilizado (`PositionSizer`/`CapitalProtections`).

## Referências
- `docs/architecture/arquitetura.md §12` (R5), `docs/data/mapeamento-dados.md §8`.
- `src/risk/position_sizing.py`, `src/api/routes/risk.py`,
`src/orchestration/squad_orchestrator.py` (`_position_quantity`).
- `docs/plano-melhorias.md` (R5 — backlog estrutural).
3 changes: 2 additions & 1 deletion docs/adr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ o boilerplate de metodologia que não descrevia o sistema.
| [003](003-persistence-sqlite-wal.md) | Persistência — JSONL (ledger/XES) + SQLite WAL (estado cross-process) | Aceito |
| [004](004-reserved.md) | *Número reservado — não utilizado* (a sequência salta de 003 para 005) | Vago |
| [005](005-scaling-path.md) | Caminho de Escalabilidade — single-host → horizontal (Redis/Postgres opt-in) | Aceita |
| [006](006-kelly-sizing-policy.md) | Política de sizing por Kelly — fonte única (`src/risk`) + endpoint delega; sizing ao vivo diferido | Aceita parcial |

Novos ADRs: copie [`ADR-Template.md`](ADR-Template.md), use o próximo número
sequencial livre (**006** em diante — ver ADR-004) e adicione a linha na tabela acima.
sequencial livre (**007** em diante) e adicione a linha na tabela acima.
10 changes: 5 additions & 5 deletions docs/architecture/arquitetura.md
Original file line number Diff line number Diff line change
Expand Up @@ -598,11 +598,11 @@ graph TB
| # | Severidade | Achado | Recomendação |
|---|---|---|---|
| R1 | 🔴 Alta | **Cluster "BuildToValue" paralelo** (`UnifiedOrchestrator` + planning/routing/consensus/chains/parallel + agentes de engenharia) **não exercitado pelo trading** | Extrair para pacote opcional `src/experimental/` ou remover; medir cobertura real. Reduz superfície e confusão. |
| R2 | 🔴 Alta | **Colisões de nome** (`SquadOrchestrator`×2, `AdaptivePlanner`×2, `ContinuousEvaluator`×2, `MemoryStore`×2, `Guardrail`×2) | Renomear por propósito (ex.: `TradingSquad` vs `A2ASquad`). Evita imports errados. |
| R2 | 🟡 Parcial | **Colisões de nome** (`SquadOrchestrator`×2, `AdaptivePlanner`×2, `ContinuousEvaluator`×2, `MemoryStore`×2, `Guardrail`×2) | 🟢 **Feito (Onda 2):** duplicatas renomeadas por propósito — `A2ASquad`, `AdaptiveReplanner`, `AgentPerformanceEvaluator`, `RelevanceMemoryStore`. **Resta** `Guardrail`×2 (ver R2b/R3). |
| R2b | 🟠 Média | **Duas fundações de agente** (`BaseAgent` async vs `SafeAgentBase` sync) sem ponte | Escolher uma base única ou documentar explicitamente os dois papéis. |
| R3 | 🟠 Média | **Duas políticas de validação de ordem** e **dois modelos de autonomia** (US$ threshold vs trust-score) | Eleger fonte única de política de risco/autonomia. |
| R4 | 🟠 Média | **HITL por polling de SQLite** acopla loop↔API ao arquivo; loop single-instance | Migrar coordenação para **Postgres `LISTEN/NOTIFY`** ou Redis pub/sub → menor latência + caminho para multi-loop. |
| R5 | 🟡 Baixa | **Kelly/proteções prontos mas não plugados** no sizing do pipeline | Ligar `PositionSizer`/`KellyCriterion`/`CapitalProtections` no `SquadOrchestrator._position_quantity`. |
| R5 | 🟡 Parcial | **Kelly/proteções prontos mas não plugados** no sizing do pipeline | 🟢 **Feito (Onda 2, ADR-006):** fórmula central do Kelly virou fonte única (`src/risk.full_kelly_fraction`), consumida pelo endpoint `/v1/risk/kelly` — `src/risk/` não é mais morto. **Resta** plugar no `SquadOrchestrator._position_quantity` (muda o trading — validação dedicada). |
| R6 | 🟡 Baixa | **Namespace `/v1/agents/...` servido por dois routers** (`agents` e `config`) | Consolidar num router único. |
| R7 | 🟡 Baixa | **XES/alerts ainda em JSONL** (ADR-003 deferido) | Concluir migração para SQLite/Postgres quando o volume justificar. |
| R8 | 🟡 Baixa | **Frontend "classic scripts" com globals `window.*`** | Migrar para ES modules + bundler quando o console crescer. |
Expand Down Expand Up @@ -653,10 +653,10 @@ graph TB
```

**Roteiro incremental (sem big-bang):**
1. **Higiene** (R1, R2): isolar/remover o cluster genérico e renomear colisões — baixo risco, alto ganho de clareza.
2. **Consolidação de política** (R3, R5, R6): uma fonte de risco/autonomia; plugar Kelly; unificar rotas de agentes.
1. **Higiene** (R1, R2): 🟡 **R2 renomeações feitas (Onda 2)**; R1 (isolar cluster genérico) ainda aberto.
2. **Consolidação de política** (R3, R5, R6): 🟡 **R5 fonte única do Kelly feita (Onda 2, ADR-006)**; resta plugar no sizing, unificar política de risco/autonomia (R3) e rotas de agentes (R6).
3. **Coordenação** (R4, R7): trocar polling SQLite por `LISTEN/NOTIFY` no Postgres (já suportado pela abstração de DB) e unificar o event store — habilita multi-loop com leader-election.
4. **Frontend** (R8): migrar para ES modules/bundler.
4. **Frontend** (R8): 🟡 **fatia feita (Onda 2)** — `.kpi-row` responsivo + sidebar colapsável < 960px; migração para ES modules/bundler ainda aberta.

Cada passo é independente e preserva o invariante central: **paper-trading-first, HITL fail-closed, tudo auditável no ledger/XES**.

Expand Down
34 changes: 34 additions & 0 deletions docs/auditoria-criptotrade-2026-06.md
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,40 @@ Revisão do código após Fase 5b. **4 achados corrigidos em `remediacao/audit-f
| A-03 | `scripts/migrate_ledger.py:43` | `json.loads()` sem `try/except` abortava migração em linha corrompida, deixando histórico parcialmente importado sem aviso | Baixo | Adicionado `try/except JSONDecodeError` com skip+warn por linha |
| A-04 | `README.md` | Contagem de testes desatualizada (273 → 324, duas ocorrências) | Doc | Atualizado |

### 7.7 Análise & Melhorias — Ondas 1–2 (2026-07-15)

Análise profunda partindo da documentação de mapeamento (`docs/data/mapeamento-dados.md`),
que catalogou anomalias §9 e dados mortos §8 **sem corrigir**. As 9 anomalias foram
verificadas (todas verdadeiras) e uma primeira leva foi corrigida. Fonte única do
backlog: `docs/plano-melhorias.md`.

**Onda 1** (PR #68, baixo risco):

| # | Arquivo | Correção | Sev. |
|---|---------|----------|------|
| O1-1 | `evaluation/ab_testing.py` | `ab_tests.jsonl` gravado como JSON válido (`json.dumps`, não `repr`) | Baixo |
| O1-2 | `analysis/regime_detector.py` | `mean_reversion` roteável no regime `sideways` (era registrada mas nunca emitida) + teste de consistência | Médio |
| O1-3 | `agents/risk_agent.py`, `orchestration/unified_orchestrator.py`, `memory/agent_memory.py` | Remoção de dados mortos (§8): `max_daily_loss_pct`, `sandbox`/`chain_manager`, `short_term`; log em vez de `except: pass` | Baixo |
| O1-4 | `docs/design/pages/*.jsx` | Erros de mutação → toast; confirmação em aprovar/rejeitar; fim da colisão `STATUS_*`; limpeza morta | Médio |
| O1-5 | README/TESTING + ADR-004 + `docs/documentação`→`docs/data` | Contagem de testes reconciliada (**416/408/8**); índice ADR corrigido | Doc |

**Onda 2** (higiene estrutural):

| # | Arquivo | Correção | Sev. |
|---|---------|----------|------|
| O2-1 | `risk/position_sizing.py`, `api/routes/risk.py` | **R5**: fórmula central do Kelly vira fonte única (`full_kelly_fraction`); endpoint delega; `src/risk/` deixa de ser morto (contrato inalterado — ADR-006) | Médio |
| O2-2 | `protocols/`, `planning/`, `evaluation/`, `memory/` | **R2**: colisões de nome renomeadas (`A2ASquad`, `AdaptiveReplanner`, `AgentPerformanceEvaluator`, `RelevanceMemoryStore`) | Baixo |
| O2-3 | `backtest/engine.py` | `market_data` unificado: backtest computa `TechnicalIndicators` real + regime (guarda de warmup) — Grid/MeanReversion não ficam mais inertes | Médio |
| O2-4 | `docs/design/pages/styles.css` + `screen_*.jsx` | **R8 (fatia)**: `.kpi-row` auto-reflow + sidebar responsiva < 960px | Baixo |
| O2-5 | `CHANGELOG.md`, `CONTRIBUTING.md`, `SECURITY.md`, ADR-006, sync de `mapeamento`/`arquitetura`/`uml` | Docs de projeto ausentes criadas; docs vivas sincronizadas | Doc |

**Verificação:** `408 passed / 8 skipped` (cobertura ≥ gate 72%); console `npm run build` OK;
`scripts/validate_deploy_config.py` OK. Invariante central preservado.

**Aberto (backlog em `plano-melhorias.md`):** R1 (isolar cluster BuildToValue),
cauda do R5 (plugar Kelly no sizing real), R3 (unificar política de risco/autonomia),
R6 (rotas de agentes), R8 completo (ES modules + a11y), CandleOut `lo`→`l`.

---

## 8. Anexos
Expand Down
Loading
Loading