> ## Documentation Index
> Fetch the complete documentation index at: https://docs.arbitragem-crypto.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Criar ou Atualizar Calculadora

> Salva os dados de entrada de uma posição de arbitragem spot-futuro (upsert por email + ticker)

## 📖 Descrição

Endpoint que **cria ou atualiza** (upsert) os dados de entrada de uma posição de arbitragem spot-futuro na Calculadora. Se já existir uma entrada para o par `email + ticker`, ela é sobrescrita com os novos valores. Os dados de entrada são o ponto de referência para o cálculo do PNL em tempo real.

<Callout title="Passo 1 da Calculadora" icon="info-circle" color="blue">
  Este endpoint é o primeiro passo — registrar a posição de entrada. Depois de salvo, use `GET /v1/calculators/stream` para monitorar o PNL em tempo real.
</Callout>

***

## 🛠️ Requisição

### Método

`POST`

### URL

```plaintext theme={null}
/v1/calculators
```

### Request Body

| Campo             | Tipo   | Obrigatório | Descrição                                  |
| ----------------- | ------ | ----------- | ------------------------------------------ |
| `email`           | string | Sim         | Email do usuário                           |
| `ticker`          | string | Sim         | Par de trading (ex: `BTC-USDT`)            |
| `entrySpotValue`  | float  | Sim         | Preço de entrada no mercado Spot           |
| `entryShortValue` | float  | Sim         | Preço de entrada no mercado Futuro (short) |
| `entrySpotQty`    | float  | Sim         | Quantidade comprada no Spot                |
| `entryFuturesQty` | float  | Sim         | Quantidade vendida nos Futuros             |

### Exemplo de Requisição

```bash theme={null}
curl -X POST http://localhost:8080/v1/calculators \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "ticker": "BTC-USDT",
    "entrySpotValue": 83000.00,
    "entryShortValue": 83150.00,
    "entrySpotQty": 0.1,
    "entryFuturesQty": 0.1
  }'
```

***

## 📤 Resposta

### Exemplo de Resposta (200 OK)

```json theme={null}
{
  "id": "507f1f77bcf86cd799439011",
  "email": "user@example.com",
  "ticker": "BTC-USDT",
  "entrySpotValue": 83000.00,
  "entryShortValue": 83150.00,
  "entrySpotQty": 0.1,
  "entryFuturesQty": 0.1,
  "entrySpotTotalValue": 8300.00,
  "entryFuturesTotalValue": 8315.00,
  "entrySpread": 150.00,
  "entrySpreadPercentage": 0.18,
  "timestamp": 1743595200000
}
```

### Campos da Resposta

| Campo                    | Tipo   | Descrição                                 |
| ------------------------ | ------ | ----------------------------------------- |
| `id`                     | string | ID da entrada no MongoDB                  |
| `email`                  | string | Email do usuário                          |
| `ticker`                 | string | Par de trading                            |
| `entrySpotValue`         | float  | Preço spot de entrada                     |
| `entryShortValue`        | float  | Preço futuro de entrada                   |
| `entrySpotQty`           | float  | Quantidade spot                           |
| `entryFuturesQty`        | float  | Quantidade futuro                         |
| `entrySpotTotalValue`    | float  | `entrySpotValue × entrySpotQty`           |
| `entryFuturesTotalValue` | float  | `entryShortValue × entryFuturesQty`       |
| `entrySpread`            | float  | `entryShortValue − entrySpotValue`        |
| `entrySpreadPercentage`  | float  | `(entrySpread / entrySpotValue) × 100`    |
| `timestamp`              | int64  | Timestamp de criação (milissegundos Unix) |

***

## 📝 Códigos de Resposta

<Callout type="success">
  **200 OK**: Posição criada ou atualizada com sucesso. Retorna o objeto completo com spread calculado.
</Callout>

<Callout type="warning">
  **400 Bad Request**:

  * `Invalid request body`: JSON malformado
  * `email is required`: Campo email ausente
  * `ticker is required`: Campo ticker ausente
</Callout>

<Callout type="error">
  **500 Internal Server Error**: `Failed to create or update calculator` — Erro ao persistir no MongoDB.
</Callout>

***

## 🔁 Comportamento de Upsert

O endpoint verifica se já existe uma entrada para `email + ticker`:

* **Não existe** → cria um novo documento
* **Já existe** → atualiza todos os campos de valor/quantidade

Isso garante que cada usuário tenha **apenas uma posição por par de trading**, facilitando o rastreamento via stream.

***

## 🔍 Fluxo Completo da Calculadora

```
1. POST /v1/calculators          → Registra dados de entrada (este endpoint)
2. GET  /v1/calculators/stream   → Monitora PNL em tempo real (SSE)
3. POST /v1/calculators/process  → Consulta pontual de PNL (alternativa ao stream)
```
