# Diário Operebem: API pública v1

> API somente leitura para consultar os dados da conta vinculada a uma API Key.

Documentação visual: https://diario.operebem.com.br/docs/api
Versão Markdown: https://diario.operebem.com.br/docs/api.md
Índice para agentes e LLMs: https://diario.operebem.com.br/llms.txt
Base URL: https://diario.operebem.com.br/api/v1

## Visão geral

- Todos os endpoints usam o método GET e retornam JSON.
- A resposta de sucesso usa o envelope `{ "success": true, "data": ... }`.
- Datas e horários são serializados em ISO 8601/RFC 3339.
- A chave consulta somente a conta à qual está vinculada.
- A API é exclusiva para contas com plano PRO.

## Autenticação

Envie uma API Key em um dos headers abaixo em todas as requisições:

- `Authorization: Bearer opb_sua_api_key`
- `X-API-Key: opb_sua_api_key`

As chaves novas usam o formato `opb_` seguido de 64 caracteres hexadecimais. Chaves legadas no formato `diario_live_` continuam aceitas. Gere e revogue a chave na área Contas do Diário. Nunca coloque a chave em parâmetros de URL, código público ou logs.

## Limites e headers

- 4 requisições por minuto por API Key.
- 50 requisições por dia UTC por API Key.
- Após autenticação e verificação da quota, as respostas incluem `X-RateLimit-Limit-Minute`, `X-RateLimit-Remaining-Minute`, `X-RateLimit-Limit-Day` e `X-RateLimit-Remaining-Day`.
- Falhas de chave/tier podem não incluir os contadores. Erros de parâmetros também consomem quota; não faça retries automáticos.
- As consultas paginadas retornam uma página por chamada; use pagination.hasNext e page para continuar dentro da quota.
- O preflight CORS usa `OPTIONS` e retorna `204` quando a requisição traz `Origin`.

## Endpoints

## GET /account
Retorna a conta vinculada à chave, as estatísticas básicas e o primeiro e o último registro de atividade.

Parâmetros: nenhum.

Campos de resposta:
- `account.id, name, broker, brokerLogo, platform, currency, accountNumber, server, isDemo, isActive, initialBalance, createdAt`
- `stats.totalTrades, winningTrades, losingTrades, winRate, netProfit, currentBalance, currency`
- `activity.firstTradeAt, lastTradeAt`

Exemplo de resposta:
```json
{
  "success": true,
  "data": {
    "account": {
      "id": "01990000-0000-7000-8000-000000000001",
      "name": "Conta de exemplo",
      "broker": null,
      "brokerLogo": null,
      "platform": null,
      "currency": "USD",
      "accountNumber": null,
      "server": null,
      "isDemo": false,
      "isActive": true,
      "initialBalance": 1000,
      "createdAt": "2026-01-01T00:00:00.000Z"
    },
    "stats": {
      "totalTrades": 3,
      "winningTrades": 1,
      "losingTrades": 1,
      "winRate": 33.33,
      "netProfit": 15,
      "currentBalance": 1015,
      "currency": "USD"
    },
    "activity": {
      "firstTradeAt": "2026-09-06T10:00:00.000Z",
      "lastTradeAt": "2026-09-06T12:10:00.000Z"
    }
  }
}
```

## GET /trades
Lista as operações da conta com paginação, filtros de ativo, tipo, resultado, período e ordenação.

Parâmetros:
- `page`: Inteiro positivo entre 1 e 1.000.000. Padrão: 1.
- `limit`: Inteiro positivo entre 1 e 100. Padrão: 50.
- `symbol`: Ativo exato, por exemplo WINQ26 ou EURUSD.
- `type`: Tipo da operação, por exemplo BUY ou SELL.
- `result`: Resultado exato: win, loss ou breakeven.
- `startDate`: Início pela abertura do trade: YYYY-MM-DD em UTC ou timestamp RFC 3339 com segundos e fuso. Datas impossíveis são rejeitadas.
- `endDate`: Fim pela abertura do trade: YYYY-MM-DD inclui o dia UTC inteiro; timestamp RFC 3339 com segundos e fuso mantém o instante exato.
- `sortBy`: Campo: openTime, closeTime, profit, volume ou symbol. Padrão: openTime.
- `sortOrder`: Ordem: asc ou desc. Padrão: desc.

Campos de resposta:
- `trades[].id, ticket, symbol, type, volume, openPrice, closePrice, openTime, closeTime, profit, commission, swap, sl, tp, durationSeconds, profitPercent, strategy`
- `pagination.page, limit, total, totalPages, hasNext, hasPrev`

Exemplo de resposta:
```json
{
  "success": true,
  "data": {
    "trades": [
      {
        "id": "01990000-0000-7000-8000-000000000002",
        "ticket": null,
        "symbol": "ATIVO_EXEMPLO",
        "type": "BUY",
        "volume": 1,
        "openPrice": 10,
        "closePrice": 11,
        "openTime": "2026-09-06T12:00:00.000Z",
        "closeTime": "2026-09-06T12:10:00.000Z",
        "profit": 0,
        "commission": 0,
        "swap": 0,
        "sl": null,
        "tp": null,
        "durationSeconds": 600,
        "profitPercent": null,
        "strategy": null
      },
      {
        "id": "01990000-0000-7000-8000-000000000003",
        "ticket": null,
        "symbol": "ATIVO_EXEMPLO",
        "type": "BUY",
        "volume": 1,
        "openPrice": 10,
        "closePrice": 11,
        "openTime": "2026-09-06T11:00:00.000Z",
        "closeTime": "2026-09-06T11:10:00.000Z",
        "profit": -5,
        "commission": 0,
        "swap": 0,
        "sl": null,
        "tp": null,
        "durationSeconds": 600,
        "profitPercent": null,
        "strategy": null
      },
      {
        "id": "01990000-0000-7000-8000-000000000004",
        "ticket": null,
        "symbol": "ATIVO_EXEMPLO",
        "type": "BUY",
        "volume": 1,
        "openPrice": 10,
        "closePrice": 11,
        "openTime": "2026-09-06T10:00:00.000Z",
        "closeTime": "2026-09-06T10:10:00.000Z",
        "profit": 20,
        "commission": 0,
        "swap": 0,
        "sl": null,
        "tp": null,
        "durationSeconds": 600,
        "profitPercent": null,
        "strategy": null
      }
    ],
    "pagination": {
      "page": 1,
      "limit": 50,
      "total": 3,
      "totalPages": 1,
      "hasNext": false,
      "hasPrev": false
    }
  }
}
```

## GET /stats
Retorna métricas de trades (profit bruto), sequências, duração e visão financeira da conta. Campos permanecem presentes na conta vazia. profitFactor pode ser o texto Infinity quando há ganho sem perda; currentBalance inclui custos e lançamentos confirmados.

Parâmetros: nenhum.

Campos de resposta:
- `currency, totalTrades, winningTrades, losingTrades, winRate, profitFactor, totalProfit, averageWin, averageLoss`
- `maxWinStreak, maxLossStreak, averageTradeDuration (alias em segundos), averageTradeDurationSeconds, averageTradeDurationMinutes, bestDay, worstDay`
- `totalDeposits, totalWithdrawals, currentBalance, netFlow`

Exemplo de resposta:
```json
{
  "success": true,
  "data": {
    "currency": "USD",
    "totalTrades": 3,
    "winningTrades": 1,
    "losingTrades": 1,
    "winRate": 33.33,
    "profitFactor": 4,
    "totalProfit": 15,
    "averageWin": 20,
    "averageLoss": 5,
    "maxWinStreak": 1,
    "maxLossStreak": 1,
    "averageTradeDuration": 600,
    "averageTradeDurationSeconds": 600,
    "averageTradeDurationMinutes": 10,
    "bestDay": {
      "date": "2026-09-06",
      "profit": 15
    },
    "worstDay": {
      "date": "2026-09-06",
      "profit": 15
    },
    "totalDeposits": 0,
    "totalWithdrawals": 0,
    "currentBalance": 1015,
    "netFlow": 0
  }
}
```

## GET /analytics/summary
Consolida métricas básicas, risco, saldo, atividade e, por padrão, performance por dimensão.

Parâmetros:
- `startDate`: Início pela abertura do trade: YYYY-MM-DD em UTC ou timestamp RFC 3339 com segundos e fuso. Datas impossíveis são rejeitadas.
- `endDate`: Fim pela abertura do trade: YYYY-MM-DD inclui o dia UTC inteiro; timestamp RFC 3339 com segundos e fuso mantém o instante exato.
- `includePerformance`: Booleano true ou false. Padrão: true; quando false, omite data.performance e evita seu cálculo.

Campos de resposta:
- `account.id, name, broker, brokerLogo, platform, currency`
- `basic.totalTrades, winningTrades, losingTrades, breakEvenTrades, winRate, totalProfit, totalLoss, netProfit, averageProfit, averageLoss, averageTrade, profitFactor, bestTrade, worstTrade, expectancy`
- `risk.sharpeRatio, sortinoRatio, maxDrawdown, maxDrawdownPercent, recoveryFactor, calmarRatio, consecutiveWins, consecutiveLosses, currentStreak`
- `balance.initial, current, netProfit, grossTradingResult, tradeCharges, netTradingResult, contributedCapital, capitalReturnPercent, growthPercent, twrPercent, annualizedReturn, annualizedTwrPercent, currency`
- `activity.totalTrades, tradingDays, firstTradeAt, lastTradeAt`
- `performance.symbol, dayOfWeek, hour, session, month (quando includePerformance=true)`

Exemplo de resposta:
```json
{
  "success": true,
  "data": {
    "account": {
      "id": "01990000-0000-7000-8000-000000000001",
      "name": "Conta de exemplo",
      "broker": null,
      "brokerLogo": null,
      "platform": null,
      "currency": "USD"
    },
    "basic": {
      "totalTrades": 3,
      "winningTrades": 1,
      "losingTrades": 1,
      "breakEvenTrades": 1,
      "winRate": 33.33,
      "totalProfit": 20,
      "totalLoss": 5,
      "netProfit": 15,
      "averageProfit": 20,
      "averageLoss": 5,
      "averageTrade": 5,
      "profitFactor": 4,
      "bestTrade": 20,
      "worstTrade": -5,
      "expectancy": 5
    },
    "risk": {
      "sharpeRatio": 7.35,
      "sortinoRatio": 15.87,
      "maxDrawdown": 5,
      "maxDrawdownPercent": 0.49,
      "recoveryFactor": 3,
      "calmarRatio": 46559.67346938776,
      "consecutiveWins": 1,
      "consecutiveLosses": 1,
      "currentStreak": -1
    },
    "balance": {
      "initial": 1000,
      "current": 1015,
      "netProfit": 15,
      "grossTradingResult": 15,
      "tradeCharges": 0,
      "netTradingResult": 15,
      "contributedCapital": 1000,
      "capitalReturnPercent": 1.5,
      "twrPercent": 1.5,
      "annualizedTwrPercent": 22814.24,
      "growthPercent": 1.5,
      "annualizedReturn": 22814.24,
      "currency": "USD"
    },
    "activity": {
      "totalTrades": 3,
      "tradingDays": 1,
      "firstTradeAt": "2026-09-06T10:00:00.000Z",
      "lastTradeAt": "2026-09-06T12:00:00.000Z"
    },
    "performance": {
      "symbol": {
        "ATIVO_EXEMPLO": {
          "trades": 3,
          "wins": 1,
          "losses": 1,
          "winRate": 33.33,
          "profit": 15,
          "avgProfit": 5
        }
      },
      "dayOfWeek": {
        "Domingo": {
          "trades": 3,
          "wins": 1,
          "losses": 1,
          "winRate": 33.33,
          "profit": 15,
          "avgProfit": 5
        }
      },
      "hour": {
        "10:00": {
          "trades": 1,
          "wins": 1,
          "losses": 0,
          "winRate": 100,
          "profit": 20,
          "avgProfit": 20
        },
        "11:00": {
          "trades": 1,
          "wins": 0,
          "losses": 1,
          "winRate": 0,
          "profit": -5,
          "avgProfit": -5
        },
        "12:00": {
          "trades": 1,
          "wins": 0,
          "losses": 0,
          "winRate": 0,
          "profit": 0,
          "avgProfit": 0
        }
      },
      "session": {
        "Londres (08-16 UTC)": {
          "trades": 3,
          "wins": 1,
          "losses": 1,
          "winRate": 33.33,
          "profit": 15,
          "avgProfit": 5
        }
      },
      "month": {
        "2026-09": {
          "trades": 3,
          "wins": 1,
          "losses": 1,
          "winRate": 33.33,
          "profit": 15,
          "avgProfit": 5
        }
      }
    }
  }
}
```

## GET /analytics/equity-curve
Retorna patrimônio, resultado operacional líquido, TWR e seus drawdowns por operação ou período agregado.

Parâmetros:
- `startDate`: Início pela abertura do trade: YYYY-MM-DD em UTC ou timestamp RFC 3339 com segundos e fuso. Datas impossíveis são rejeitadas.
- `endDate`: Fim pela abertura do trade: YYYY-MM-DD inclui o dia UTC inteiro; timestamp RFC 3339 com segundos e fuso mantém o instante exato.
- `granularity`: Agregação em UTC: trade, day, week (segunda a domingo) ou month. Padrão: trade; a curva também contém eventos financeiros.

Campos de resposta:
- `equityCurve[].date, equity, drawdown, operationalResult, operationalDrawdown, returnPercent, drawdownPercent, profit`
- `summary.initialBalance, finalBalance, peak, trough, maxDrawdown, maxDrawdownPercent, grossTradingResult, tradeCharges, netTradingResult, contributedCapital, capitalReturnPercent, twrPercent, annualizedTwrPercent, totalPoints, granularity, currency`

Exemplo de resposta:
```json
{
  "success": true,
  "data": {
    "equityCurve": [
      {
        "date": "2026-09-06",
        "occurredAt": "2026-09-06T10:10:00.000Z",
        "equity": 1020,
        "drawdown": 0,
        "drawdownPercent": 0,
        "profit": 20,
        "operationalResult": 20,
        "operationalDrawdown": 0,
        "returnPercent": 2
      },
      {
        "date": "2026-09-06",
        "occurredAt": "2026-09-06T11:10:00.000Z",
        "equity": 1015,
        "drawdown": 5,
        "drawdownPercent": 0.49,
        "profit": -5,
        "operationalResult": 15,
        "operationalDrawdown": 5,
        "returnPercent": 1.5
      },
      {
        "date": "2026-09-06",
        "occurredAt": "2026-09-06T12:10:00.000Z",
        "equity": 1015,
        "drawdown": 5,
        "drawdownPercent": 0.49,
        "profit": 0,
        "operationalResult": 15,
        "operationalDrawdown": 5,
        "returnPercent": 1.5
      }
    ],
    "summary": {
      "initialBalance": 1000,
      "finalBalance": 1015,
      "peak": 1020,
      "trough": 1000,
      "maxDrawdown": 5,
      "maxDrawdownPercent": 0.49,
      "grossTradingResult": 15,
      "tradeCharges": 0,
      "netTradingResult": 15,
      "contributedCapital": 1000,
      "capitalReturnPercent": 1.5,
      "growthPercent": 1.5,
      "twrPercent": 1.5,
      "annualizedReturn": 22814.24,
      "annualizedTwrPercent": 22814.24,
      "totalPoints": 3,
      "granularity": "trade",
      "currency": "USD"
    }
  }
}
```

## GET /analytics/performance
Agrupa o resultado por ativo, dia da semana, hora, sessão ou mês. Sem dimension, retorna todas as dimensões e meta; com dimension, retorna somente a dimensão escolhida.

Parâmetros:
- `startDate`: Início pela abertura do trade: YYYY-MM-DD em UTC ou timestamp RFC 3339 com segundos e fuso. Datas impossíveis são rejeitadas.
- `endDate`: Fim pela abertura do trade: YYYY-MM-DD inclui o dia UTC inteiro; timestamp RFC 3339 com segundos e fuso mantém o instante exato.
- `dimension`: Filtro opcional: symbol, dayOfWeek, hour, session ou month.

Campos de resposta:
- `data.symbol, dayOfWeek, hour, session, month (cada chave contém trades, wins, losses, winRate, profit e avgProfit)`
- `meta.tradesAnalyzed, meta.dateRange.from, meta.dateRange.to (quando dimension não é informado; datas null se vazio)`

Exemplo de resposta:
```json
{
  "success": true,
  "data": {
    "symbol": {
      "ATIVO_EXEMPLO": {
        "trades": 3,
        "wins": 1,
        "losses": 1,
        "winRate": 33.33,
        "profit": 15,
        "avgProfit": 5
      }
    },
    "dayOfWeek": {
      "Domingo": {
        "trades": 3,
        "wins": 1,
        "losses": 1,
        "winRate": 33.33,
        "profit": 15,
        "avgProfit": 5
      }
    },
    "hour": {
      "10:00": {
        "trades": 1,
        "wins": 1,
        "losses": 0,
        "winRate": 100,
        "profit": 20,
        "avgProfit": 20
      },
      "11:00": {
        "trades": 1,
        "wins": 0,
        "losses": 1,
        "winRate": 0,
        "profit": -5,
        "avgProfit": -5
      },
      "12:00": {
        "trades": 1,
        "wins": 0,
        "losses": 0,
        "winRate": 0,
        "profit": 0,
        "avgProfit": 0
      }
    },
    "session": {
      "Londres (08-16 UTC)": {
        "trades": 3,
        "wins": 1,
        "losses": 1,
        "winRate": 33.33,
        "profit": 15,
        "avgProfit": 5
      }
    },
    "month": {
      "2026-09": {
        "trades": 3,
        "wins": 1,
        "losses": 1,
        "winRate": 33.33,
        "profit": 15,
        "avgProfit": 5
      }
    }
  },
  "meta": {
    "tradesAnalyzed": 3,
    "dateRange": {
      "from": "2026-09-06T10:00:00.000Z",
      "to": "2026-09-06T12:00:00.000Z"
    }
  }
}
```

## Códigos de erro

- `400`: INVALID_QUERY: parâmetro ausente, inválido ou fora das opções aceitas.
- `401`: MISSING_API_KEY, INVALID_API_KEY_FORMAT, INVALID_API_KEY, API_KEY_REVOKED ou API_KEY_EXPIRED.
- `403`: TIER_DOWNGRADED: conta sem plano PRO. O preflight sem Origin também é recusado.
- `404`: ACCOUNT_NOT_FOUND: conta vinculada não encontrada.
- `429`: RATE_LIMIT_EXCEEDED: limite por minuto ou por dia excedido.
- `500`: INTERNAL_ERROR: falha interna ao consultar ou calcular os dados.
- `503`: ENTITLEMENT_UNAVAILABLE: não foi possível revalidar o plano; Retry-After informa a espera.
