# EliteXCharts — formato do indicador customizado (referência completa)

Esta página foi escrita para uma IA ler e montar um arquivo de indicador que funcione. Passe o link para ela, descreva o indicador
que você quer e importe o `.json` que ela devolver na EliteXCharts: **Indicadores** (cabeçalho do gráfico) → **Importar indicador**
(rodapé da janela). Ele passa a aparecer na categoria **Customizados**. Importar de novo um arquivo com o mesmo `id` atualiza o
indicador.

Versão em inglês: https://elitexcharts.com/docs/custom-indicators.md · Manual para pessoas: https://elitexcharts.com/pt/docs/#indicadores-customizados

## 1. O que é o arquivo

- Um objeto JSON **declarativo**: descreve o que calcular e como pintar. Nunca executa código, então não mexe em arquivos, contas
  nem na rede.
- Aceita comentários (`//`, `/* */`) e vírgula sobrando no fim. Os nomes dos campos não diferenciam maiúscula de minúscula.
- O indicador é desenhado **por cima das velas do preço** (linhas, preenchimento de banda e cor das velas). Indicador customizado
  não tem painel separado.
- Arquivo inválido é **recusado na importação**, com o motivo; nunca quebra um gráfico.

## 2. Campos do topo

| Campo | Obrigatório | Significado |
|---|---|---|
| `schema` | sim | Tem de ser `1`. |
| `name` | sim | Nome que aparece na plataforma. |
| `id` | recomendado | Identificador fixo (`"meu-indicador"`). Importar de novo o mesmo `id` atualiza. |
| `version`, `author`, `description` | não | Aparecem no "Sobre" do indicador. |
| `inputs` | não | Configurações que o usuário muda (seção 3). |
| `series` | não | O cálculo (seção 4). |
| `plots` | não | Séries desenhadas como linha (seção 5). |
| `fill` | não | Preenchimento entre duas séries (seção 5). |
| `candleColors` | não | Regras que pintam as velas (seção 6). |
| `requires` | não | Indicadores nativos de que ele depende (seção 7). |
| `source` | não | Calcular em outro tempo gráfico, como padrão (seção 8). |

O arquivo tem de desenhar alguma coisa: pelo menos um `plots` **ou** uma regra em `candleColors`.

## 3. `inputs` — a tela de configuração

Cada input vira uma linha na configuração do indicador. Em qualquer lugar do arquivo, o texto `"$id"` lê o valor atual do input.

| Campo | Significado |
|---|---|
| `id` | Obrigatório. Usado como `"$id"`. |
| `type` | `"int"` (inteiro) · `"number"` (com decimais) · `"color"` (`"#rrggbb"`) · `"bool"` (caixinha). Outro tipo é recusado. |
| `label` | O que o usuário vê. |
| `default` | Valor inicial (número, `"#rrggbb"` na cor, `true`/`false` no bool). |
| `min`, `max`, `step` | Limites do controle numérico. **Padrão: `min` 0, `max` 1000, `step` 1** — defina o `max` quando o valor puder passar de 1000. |

## 4. `series` — o cálculo

Os passos rodam **em ordem**, e cada um só pode usar fontes base ou séries definidas **antes** dele (não dá pra criar ciclo).
Cada passo vira uma série com nome, com um valor por vela.

Fontes base, sempre disponíveis: `open`, `high`, `low`, `close`, `volume`, `hl2`, `hlc3`, `ohlc4`.

| `fn` | Parâmetros | Resultado |
|---|---|---|
| `src` | `src` | Cópia de uma fonte ou série. |
| `sma`, `ema`, `rma` | `src`, `len` | Média simples, exponencial e a de Wilder. |
| `stdev` | `src`, `len` | Desvio padrão de `len` barras. |
| `highest`, `lowest` | `src`, `len` | Maior / menor valor de `len` barras. |
| `atr` | `len` | Average True Range das velas. |
| `rsi` | `src` (padrão `close`), `len` | RSI (Wilder). |
| `add`, `sub`, `mul`, `div`, `max`, `min` | `a`, `b` | Conta valor a valor. `div` por zero dá vazio. |
| `abs` | `src` | Valor absoluto. |
| `shift` | `src`, `len` | O valor de `len` barras atrás. |

O que mais derruba arquivo gerado:
- **Dentro de `series`, todo valor é texto**: `"len": "20"`, `"b": "2"`, `"len": "$periodo"`. Número sem aspas (`"len": 20`) faz a
  importação falhar.
- Os operandos (`src`, `a`, `b`) aceitam id de série, fonte base, número entre aspas ou input (`"$mult"`).
- Sem `len` = 14.
- As barras de aquecimento (sem histórico suficiente) ficam vazias: nada é desenhado nelas e nenhuma condição casa nelas.
- Limites: 64 séries e 32 regras de cor por indicador.

## 5. `plots` e `fill`

```json
"plots": [ { "series": "basis", "color": "$corMedia", "width": "$espessura", "dash": "solid", "label": "Média" } ],
"fill":  { "from": "upper", "to": "lower", "color": "$corBanda", "alpha": 0.07 }
```

- `plots[].series` precisa ser uma série que existe. `color` é `"#rrggbb"` ou `"$input"`; `width` é número ou `"$input"`; `dash` é
  `"solid"`, `"dash"` ou `"dot"`.
- `fill.from` / `fill.to` precisam existir; `alpha` (0 a 1) é número ou `"$input"`.
- Fora das `series` (plots, fill, inputs, comparações), número é número JSON normal, sem aspas.

## 6. `candleColors` — pintando as velas

As regras são lidas de cima pra baixo e **a primeira que casar vence**. Uma regra com `"else": true` pega todas as velas restantes.

```json
"candleColors": [
  { "when": { "all": [ "isUp",   { "lt": [ "low",  "lower" ] } ] }, "color": "$corAlta" },
  { "when": { "all": [ "isDown", { "gt": [ "high", "upper" ] } ] }, "color": "$corBaixa" },
  { "else": true, "color": "$corResto" }
]
```

Cada regra: `when` (uma condição) ou `else: true`, `color` (`"#rrggbb"` ou `"$input"`) e, se quiser, `"wicks": false` pra pintar só
o corpo (a sombra fica na cor do tema; o padrão `true` pinta os dois).

Condições:
- **Palavras:** `"isUp"`, `"isDown"` (direção da vela) · `"isReversal"`, `"isReversalUp"`, `"isReversalDown"` (a vela mudou de
  direção em relação à anterior; no Renko, o primeiro tijolo do outro lado) · `"hasBuyBigTrade"`, `"hasSellBigTrade"`,
  `"hasBigTrade"` (caiu uma bolha do Big Trades nesta vela; precisa do `requires`, seção 7) · `"always"`.
- **Comparações:** `{ "lt": [x, y] }`, `gt`, `lte`, `gte`, `eq` — dois operandos, cada um id de série, fonte base, número ou
  `"$input"`. Se um lado estiver vazio (aquecimento), a comparação é falsa. O `eq` compara com tolerância de 1e-9.
- **Lógica:** `{ "all": [ … ] }` (e), `{ "any": [ … ] }` (ou), `{ "not": condição }`.
- Palavra desconhecida vale falso.

Pra comparar com "a vela anterior", monte a série com `shift` (ex.: `{ "id": "fechAnterior", "fn": "shift", "src": "close", "len": "1" }`).

## 7. `requires` — usando um indicador nativo

As condições de big trade precisam do **Big Trades** nativo ligado. Declare e a plataforma liga quando o indicador é adicionado:

```json
"requires": { "bigTrades": { "minVolume": 75, "windowMs": 10 } }
```

`minVolume` (contratos, piso 20, padrão 75) e `windowMs` (padrão 10). Se o Big Trades já estiver no gráfico com um mínimo maior, a
plataforma baixa o mínimo pra não perder bolha; o resto da configuração do Big Trades do usuário nunca é trocado. O `days` é aceito
por compatibilidade e não tem efeito (o Big Trades cobre o período inteiro do gráfico).

## 8. `source` — calcular em outro tempo gráfico (multi-tempo)

Um indicador customizado pode ser **calculado em outro tipo ou tempo gráfico** e desenhado no gráfico atual, o mesmo recurso dos
indicadores nativos. Exemplo: operar no Renko 14 com o indicador calculado no Renko 44.

```json
"source": { "type": "renko", "param": 44, "smooth": true }
```

| Campo | Significado |
|---|---|
| `type` | `"chart"` (padrão: o gráfico atual) · `"candle"` (tempo; `"time"` também vale) · `"renko"` · `"tick"`. O Delta só existe na tela. |
| `param` | `candle`: **minutos** (5 = velas de 5 min, 60 = de 1 hora) · `renko`: **tamanho do tijolo em ticks** · `tick`: **ticks por vela**. Padrão 120. |
| `smooth` | `true` (padrão): as linhas são interpoladas entre os fechamentos da fonte · `false`: degraus, o valor fica parado até a vela da fonte fechar. |

Como funciona:
- O `source` é só o **padrão** de quem escreveu. O usuário troca quando quiser em **Fonte do cálculo**, na configuração do indicador
  no gráfico; um selo amarelo ("◄ Renko 44", "◄ 5min") mostra a fonte na legenda.
- **Tudo é calculado nas velas da fonte**: cada série, cada comparação e cada regra de cor. Depois o resultado vem pro gráfico da
  tela. A cor nunca é interpolada: cada vela da tela pega a cor da vela da fonte que a contém.
- **Histórico:** o usuário não precisa ter aberto aquele tempo gráfico antes. A sessão de hoje é montada com os mesmos ticks da
  Rithmic que o gráfico já carregou; os dias anteriores vêm prontos do servidor de histórico da plataforma (no produto da própria
  fonte, para os mesmos dias que o gráfico carregou). Se o servidor ainda estiver montando esse produto, a legenda mostra o andamento
  e o indicador refaz o cálculo quando ele chega. Precisa de conta Rithmic conectada. No Replay a fonte usa só os ticks do replay.
- **Ao vivo:** depois da primeira carga, só os ticks novos entram na série da fonte; o histórico não é recalculado a cada negócio.
- **Quando não usar:** se a lógica depende do que acontece *dentro* da vela (volume, delta, agressão), um tempo maior muda o
  significado do número. Nesse caso, prefira o gráfico atual.

## 9. Exemplos completos

Os três exemplos abaixo são os mesmos da versão em inglês (https://elitexcharts.com/docs/custom-indicators.md), com os textos em
português. Todos passam na validação da importação.

### Bollinger 20/2 que pinta o rompimento da banda

```json
{
  "schema": 1,
  "id": "elitex-bollinger",
  "name": "EliteXBollinger",
  "version": "1.0.0",
  "description": "Bollinger 20/2 que pinta o candle quando ele rompe uma banda.",
  "inputs": [
    { "id": "period", "type": "int",    "label": "Período",          "default": 20, "min": 2,   "max": 400, "step": 1 },
    { "id": "mult",   "type": "number", "label": "Desvios (múltiplo)", "default": 2,  "min": 0.5, "max": 5,   "step": 0.1 },
    { "id": "colUp",      "type": "color", "label": "Rompeu a banda de baixo", "default": "#22c55e" },
    { "id": "colDown",    "type": "color", "label": "Rompeu a banda de cima",  "default": "#ef4444" },
    { "id": "colNeutral", "type": "color", "label": "As outras velas",         "default": "#7a7a85" },
    { "id": "colMid",  "type": "color",  "label": "Linha média", "default": "#f5a623" },
    { "id": "colBand", "type": "color",  "label": "Bandas",      "default": "#4a90e2" },
    { "id": "bandW",   "type": "number", "label": "Espessura",   "default": 1, "min": 0.5, "max": 6, "step": 0.5 }
  ],
  "series": [
    { "id": "basis", "fn": "sma",   "src": "close", "len": "$period" },
    { "id": "dev",   "fn": "stdev", "src": "close", "len": "$period" },
    { "id": "devx",  "fn": "mul",   "a": "dev",     "b": "$mult" },
    { "id": "upper", "fn": "add",   "a": "basis",   "b": "devx" },
    { "id": "lower", "fn": "sub",   "a": "basis",   "b": "devx" }
  ],
  "plots": [
    { "series": "basis", "color": "$colMid",  "width": "$bandW" },
    { "series": "upper", "color": "$colBand", "width": "$bandW" },
    { "series": "lower", "color": "$colBand", "width": "$bandW" }
  ],
  "fill": { "from": "upper", "to": "lower", "color": "$colBand", "alpha": 0.07 },
  "candleColors": [
    { "when": { "all": [ "isUp",   { "lt": [ "low",  "lower" ] } ] }, "color": "$colUp" },
    { "when": { "all": [ "isDown", { "gt": [ "high", "upper" ] } ] }, "color": "$colDown" },
    { "else": true, "color": "$colNeutral" }
  ]
}
```

### Reversão de Renko contra um big trade (só cor, sem linha)

```json
{
  "schema": 1,
  "id": "elitex-reversal-flow",
  "name": "EliteXReversalFlow",
  "requires": { "bigTrades": { "minVolume": 75, "windowMs": 10 } },
  "inputs": [
    { "id": "colDown",    "type": "color", "label": "Reversão de baixa com compra grande", "default": "#ef4444" },
    { "id": "colUp",      "type": "color", "label": "Reversão de alta com venda grande",   "default": "#22c55e" },
    { "id": "colNeutral", "type": "color", "label": "As outras velas",                     "default": "#7a7a85" }
  ],
  "candleColors": [
    { "when": { "all": [ "isReversalDown", "hasBuyBigTrade"  ] }, "color": "$colDown" },
    { "when": { "all": [ "isReversalUp",   "hasSellBigTrade" ] }, "color": "$colUp" },
    { "else": true, "color": "$colNeutral" }
  ]
}
```

### Multi-tempo: afastamento da média do Renko 44 pintando as velas do gráfico da tela

```json
{
  "schema": 1,
  "id": "esticado-r44",
  "name": "Esticado da média do Renko 44",
  "description": "Pinta a vela quando o preço está mais de X% longe da média de 25 do Renko 44.",
  "source": { "type": "renko", "param": 44, "smooth": true },
  "inputs": [
    { "id": "len",  "type": "int",    "label": "Período da média", "default": 25, "min": 2, "max": 400 },
    { "id": "pct",  "type": "number", "label": "Distância (%)",    "default": 0.2, "min": 0.01, "max": 5, "step": 0.01 },
    { "id": "colAbove", "type": "color", "label": "Esticado em cima", "default": "#7c3aed" },
    { "id": "colBelow", "type": "color", "label": "Esticado embaixo", "default": "#c6f24e" },
    { "id": "colRest",  "type": "color", "label": "As outras velas",  "default": "#8b8b95" }
  ],
  "series": [
    { "id": "ma",    "fn": "sma", "src": "close", "len": "$len" },
    { "id": "frac",  "fn": "div", "a": "$pct",  "b": "100" },
    { "id": "dist",  "fn": "mul", "a": "ma",    "b": "frac" },
    { "id": "upper", "fn": "add", "a": "ma",    "b": "dist" },
    { "id": "lower", "fn": "sub", "a": "ma",    "b": "dist" }
  ],
  "plots": [
    { "series": "ma",    "color": "#3b82f6", "width": 1.6 },
    { "series": "upper", "color": "#7c3aed", "width": 1, "dash": "dash" },
    { "series": "lower", "color": "#c6f24e", "width": 1, "dash": "dash" }
  ],
  "candleColors": [
    { "when": { "gte": [ "high", "upper" ] }, "color": "$colAbove" },
    { "when": { "lte": [ "low",  "lower" ] }, "color": "$colBelow" },
    { "else": true, "color": "$colRest" }
  ]
}
```

## 10. Conferência antes de devolver o arquivo

1. `"schema": 1` e um `name`.
2. Cada passo de `series` usa uma `fn` conhecida e só usa fontes base, séries anteriores, números ou `"$inputs"`.
3. Todo valor dentro de `series` é **texto** (`"len": "20"`).
4. Todo `plots[].series` e `fill.from/to` existe.
5. Pelo menos um `plots` ou uma regra de `candleColors`; a última regra de cor costuma ser `{ "else": true, … }`.
6. Os inputs usam `int`, `number`, `color` ou `bool`, e os numéricos definem `max` quando passam de 1000.
7. `source.type` é `chart`, `candle`, `renko` ou `tick`; `param` é minutos / ticks do tijolo / ticks por vela.
8. No máximo 64 séries e 32 regras de cor.
