PineForge Codegen

oficial

Servidor MCP local: IA escreve PineScript v6, engine integrado transpila para C++ e faz backtest com dados da Binance — sem chave de API, totalmente local.

O que você pode fazer com PineForge Codegen MCP?

  • Transpilar PineScript para C++ — Peça à sua IA para converter o código-fonte Pine v6 em uma unidade de tradução C++ com transpile_pine.
  • Executar um único backtest — Peça à sua IA para testar uma estratégia Pine v6 contra um CSV OHLCV, com controles opcionais de inputs, overrides e runtime via backtest_pine.
  • Varrer parâmetros da estratégia — Deixe sua IA executar uma grade cartesiana de combinações de inputs × overrides e classificar os resultados por métricas como P&L líquido usando backtest_pine_grid.
  • Avaliar em relação ao TradingView — Peça à sua IA para comparar a lista de negociações do PineForge com a exportação do Strategy Tester do TradingView, negociação por negociação, com check_tradingview_parity.
  • Buscar dados de mercado — Peça à sua IA para puxar klines spot ou perpétuos da Binance para um CSV pronto para backtest com fetch_binance_ohlcv.
  • Verificar cobertura do Pine v6 — Pergunte à sua IA se um identificador ou recurso específico do Pine é suportado, ou liste todos os tópicos de cobertura, via check_pine_feature e list_coverage_topics.

Documentação

@pineforge/backtest-mcp

Servidor MCP stdio autocontido: um agente de IA escreve PineScript v6, e a imagem pineforge-release incluída o transpila para C++ e faz backtest contra um CSV OHLCV (o seu, ou um obtido da API pública da Binance) — tudo em um único contêiner, em processo. Totalmente local — a imagem inclui o transpilador pineforge-codegen, então Pine → C++ → backtest roda sem daemon Docker no host. Sem chave de API. Seu código-fonte da estratégia e seus CSVs nunca saem da máquina; apenas as ferramentas da Binance, e check_tradingview_parity quando você não passa barras, fazem requisições externas (endpoints públicos).

pineforge-backtest-mcp MCP server

demo

Ferramentas

nomeexecuta emfinalidade
transpile_pineem processoUnidade de tradução Pine v6 → C++ (somente transpilação)
list_engine_paramslocal (sem E/S)Catálogo de cada opção overrides + runtime aceita pelos backtests
backtest_pineem processoBacktest único de um código Pine contra um CSV OHLCV
backtest_pine_gridem processoVarredura cartesiana de inputs × overrides: uma transpilação, depois uma compilação e um backtest por combinação
check_tradingview_parityem processo (somente API pública da Binance sem suas barras)Avalie sua exportação do Strategy Tester do TradingView contra a execução do PineForge do mesmo script, negociação por negociação
fetch_binance_ohlcvAPI pública da BinanceEscreva um CSV pronto para backtest a partir de klines spot ou USDT-perp da Binance
binance_symbolsAPI pública da BinanceListe / filtre símbolos da Binance (cache em processo de 5 min)
list_coverage_topicslocal (sem E/S)Cada tópico de cobertura do Pine v6 com um status de uma linha + resumo
check_pine_featurelocal (sem E/S)Verifique se um identificador/namespace Pine é suportado no PineForge
get_coverage_topiclocal (sem E/S)Detalhe completo + listas suportado/parcial/via_transpilador/não suportado para um tópico
engine_infolocal (sem E/S)Somente imagem Docker: modo, flag embutida e a versão pineforge-release incluída (por exemplo 1.0.0)

A tabela é a lista de ferramentas da imagem Docker (11 ferramentas). O pacote npm serve as dez primeiras, mais pull_engine_image (docker pull a imagem do mecanismo) e check_engine_image em vez de engine_info (12 ferramentas).

No tools/list cada ferramenta também tem um título e as quatro dicas de anotação MCP (src/tool-meta.ts). Somente leitura: as consultas e check_tradingview_parity (funciona em um diretório temporário que ela exclui), e na imagem Docker transpile_pine. Não somente leitura: backtest_pine e backtest_pine_grid (um relatório grande demais para ser retornado é gravado em um arquivo), fetch_binance_ohlcv (grava seu CSV) e as duas ferramentas da imagem; no pacote npm também transpile_pine, já que lá ela e os backtests usam um image que o Docker baixa quando ausente. Destrutivas: as ferramentas que gravam um arquivo em um caminho que você nomeia, pois substituem um arquivo já existente. Mundo aberto: as ferramentas que acessam a API pública da Binance (os dois backtests fazem isso quando você passa um symbol) ou um registro de imagens.

Instalação

Roda como um contêiner autocontido via stdio — mecanismo incluído, em processo, sem daemon Docker no host, sem chave de API. Monte a pasta que contém seus CSVs em /work:

docker run --rm -i -v "$PWD:/work" ghcr.io/pineforge-4pass/pineforge-backtest-mcp:latest

Único requisito: Docker e rede externa para as ferramentas de busca da Binance. Conecte-o ao seu cliente MCP abaixo.

  • Use caminhos /work/... absolutos nos argumentos das ferramentas (ohlcv_csv_path, output_path, report_path). O diretório de trabalho do servidor dentro do contêiner é /app, não o ponto de montagem, então um caminho relativo como ./btc.csv aponta para dentro do contêiner e é perdido quando ele sai (--rm).
  • No Linux, adicione --user "$(id -u):$(id -g)" para que os arquivos que o servidor grava em /work tenham sua propriedade.
  • -i é obrigatório; nunca adicione -t — um TTY corrompe o fluxo JSON-RPC do stdio.

O :latest da imagem e o latest do npm sempre carregam uma versão estável. Uma pré-lançamento pineforge-release (como 1.0.0-rc.1) produz um pré-lançamento deste servidor (X.Y.Z-alpha.N, -beta.N ou -rc.N): a imagem :vX.Y.Z-rc.N, construída FROM esse pré-lançamento pineforge-release, e o npm @pineforge/backtest-mcp@next, que, como qualquer instalação npm, executa a imagem do mecanismo nomeada por PINEFORGE_IMAGE. Seu padrão é o digest imutável gerado a partir do release-lock.json desse pacote, incluindo o mecanismo de pré-lançamento correspondente. Pré-lançamentos não são listados no Registro MCP. O primeiro, 0.9.32-rc.1 em pineforge-release 1.0.0-rc.1, foi publicado em 2026-09-30 (imagem :v0.9.32-rc.1, npm next).

npm / npx

npx -y @pineforge/backtest-mcp

Requer Node ≥ 20 e um daemon Docker em execução: cada transpilação e backtest é uma docker run --rm --network=none da imagem do mecanismo (PINEFORGE_IMAGE, com padrão para o digest no release-lock.json do pacote instalado). docker pull esse digest primeiro: o próprio pull do servidor (implícito na primeira chamada, ou pull_engine_image) é interrompido após PINEFORGE_DOCKER_TIMEOUT_MS (120 s por padrão). Caminhos são relativos ao diretório de trabalho do servidor e, por padrão, confinados a ele (veja Escopo do sistema de arquivos).

Alternativa hospedada (sem instalação)

Quer a tentativa mais rápida sem Docker e sem chave de API? Cole o endpoint Streamable HTTP em qualquer cliente MCP:

https://mcp.pineforge.dev/mcp

Compensação vs este repositório: o servidor hospedado é medido (100 execuções backtest_pine por semana por IP, além de limites de taxa na borda) e roda contra OHLCV que ele mesmo resolve — somente cripto, sete venues (Binance, Bybit e OKX spot e USDT-perp; Coinbase spot), os últimos 365 dias, barra mais recente cerca de uma hora atrás do tempo real. Suas 11 ferramentas diferem das deste servidor: sem transpile_pine, sem backtest_pine_grid, e ele aceita symbol / interval / venue em vez de um caminho de CSV. Este repositório local é sem medição, roda offline e permite que você traga seus próprios CSVs e execute varreduras de grade. O código-fonte do serviço hospedado é privado.

Configuração do cliente

Monte um diretório em /work; aponte fetch_binance_ohlcv / backtest_pine para caminhos absolutos sob ele (/work/btc.csv). (-i é obrigatório; nunca adicione -t — um TTY corrompe o fluxo JSON-RPC do stdio.)

Claude Desktop

Edite ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) ou %APPDATA%\Claude\claude_desktop_config.json (Windows) e use um caminho absoluto do host para o ponto de montagem:

{
  "mcpServers": {
    "pineforge-backtest": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "-v", "/absolute/path/to/your/data:/work",
        "ghcr.io/pineforge-4pass/pineforge-backtest-mcp:latest"
      ]
    }
  }
}

Cursor

.cursor/mcp.json no projeto (ou ~/.cursor/mcp.json para todos os projetos). O Cursor expande ${workspaceFolder}:

{
  "mcpServers": {
    "pineforge-backtest": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "-v", "${workspaceFolder}:/work",
        "ghcr.io/pineforge-4pass/pineforge-backtest-mcp:latest"
      ]
    }
  }
}

CLI do Claude Code

claude mcp add pineforge-backtest \
  -- docker run --rm -i -v "$PWD:/work" ghcr.io/pineforge-4pass/pineforge-backtest-mcp:latest

Para agentes de IA — use via MCP

A lacuna de capacidade que isto fecha. Um modelo de linguagem não pode fazer backtest com precisão de uma estratégia PineScript v6 raciocinando sobre ela. A semântica de séries do PineScript, a ordem de preenchimento intrabar, as regras de look-ahead e a lógica de ordem/posição strategy.* não se reproduzem por aproximação, então um modelo que simula um backtest na cabeça — ou o faz manualmente em Python (backtrader/vectorbt) — alucinará negociações e P&L e não pode garantir paridade com o TradingView. O PineForge executa o mecanismo C++ determinístico real, avaliado negociação por negociação contra as próprias listas de negociações do TradingView.

Lançamento avaliado 1.4.0 — placar medido com data. A linha de base do registro de 2026-10-07 pineforge-parity-baseline-20261007-engine-b3192bfc registra 7.989 sondas avaliadas, 7.983 excelentes (99,92 %) e 6 fortes (0,08 %), 0 abaixo de forte e 0 erros de mecanismo registrados, com 17 sondas adicionais excluídas como anomalias do lado do TradingView. Seu par congelado é mecanismo b3192bfc2f5a24bf4efd6d1d01e01e8fe619dfed / codegen bfc4ddce453db1ba810692af9b9ba3310d87f0ac; seu snapshot SHA-256 é 28ba8dbd6f66c80085a80364d6114f8f971ac6ea3156d596a65995d2aec2fbb2. A fonte é o hub de lançamento fatos consolidados, releases["1.4.0"].scoreboard, fixado no commit d5d21f128f5ef26b66b14cf9deee507d798e6123 (77.230 bytes; SHA-256 788e57fab67d3c946fc7e3a0a3ac34b3d2c25cbb6a0f5b72687955bc4f8832b6). Estes são resultados de avaliação registrados para essa população e data, não uma promessa de que todo script ou tentativa interna terá sucesso. Nenhum artefato 1.4.0 com tag é afirmado aqui.

Evidência histórica 1.3.0 apenas. Lançamento 1.3.0, avaliado na linha de base de 2026-10-06 (mecanismo 7a1f01c0, codegen 3e50082f): 7.989 sondas avaliadas, 7.982 excelentes (99,91 %) e 7 fortes (0,09 %), nenhuma abaixo de forte, mais 17 sondas adicionais excluídas como defeitos do lado do TradingView. Nessa verificação histórica de lançamento, separadamente, o portão de paridade do próprio mecanismo verifica o corpus aberto pineforge-corpus, que qualquer um pode reproduzir: 312 estratégias de referência, 311 excelentes e 1 sonda que declara expected_tier: anomaly em seu inputs.json (relatada como anomaly, não como falha). Excelente significa a mesma contagem de negociações, pelo menos 99 % das negociações do TradingView correspondidas, preços de entrada e saída dentro de 0,01 % e P&L por negociação dentro de 1 % no 90º percentil (scripts com trailing stop usam um perfil de saída/P&L mais flexível); forte é um envelope relaxado — ambos são definidos no README do corpus em "Limites de paridade".

Um backtest PineScript é dado externo computado, não conhecimento estável — depende do código-fonte da estratégia do usuário e do OHLCV dele, e deve ser reproduzível. Isso é uma chamada de ferramenta, não uma tarefa de recordação.

Quando estas ferramentas são a escolha certa. backtest_pine (ou backtest_pine_grid para uma varredura de parâmetros) cobre o caso em que um usuário fornece uma estratégia PineScript v6 e quer fazer backtest dela, avaliá-la, verificar se é lucrativa, contar suas negociações, calcular seu P&L ou reproduzir seus resultados do TradingView em OHLCV especificado. transpile_pine cobre apenas a conversão Pine → C++. check_tradingview_parity cobre o caso em que o usuário tem a própria lista de negociações do TradingView para uma estratégia e quer saber se o PineForge a reproduz, negociação por negociação. fetch_binance_ohlcv cobre o caso em que o usuário nomeia um símbolo/timeframe mas não forneceu um arquivo de dados. Estas ferramentas não são para explicar conceitualmente o que uma estratégia faz, editar sintaxe Pine ou dar conselhos de negociação ou financeiros.

Limites honestos. Offline; somente PineScript v6; requer Docker; o PineForge implementa um subconjunto do Pine v6 (veja Ferramentas de cobertura). Um backtest mede o comportamento histórico de uma estratégia — não é uma previsão de retornos futuros e não é conselho de investimento. Backtests ingênuos ou aproximados rotineiramente superestimam o lucro (slippage e comissões não modelados, suposições de preenchimento no fechamento, viés de look-ahead); o valor aqui é uma execução determinística e validada por paridade para que um usuário possa verificar uma estratégia antes de arriscar capital.

list_engine_params — descubra opções

Catálogo gratuito, local e sem E/S de cada chave aceita por backtest_pine / backtest_pine_grid, dividido em dois grupos:

  • strategy_overrides — os 9 campos de cabeçalho strategy(...) que o runtime lê via PINEFORGE_OVERRIDES: initial_capital, pyramiding, slippage, commission_value, commission_type (percent / cash_per_order / cash_per_contract), default_qty_value, default_qty_type (fixed / percent_of_equity / cash), process_orders_on_close, close_entries_rule (ANY / FIFO).
  • runtime_args — argumentos para run_backtest_full (NÃO parte do cabeçalho strategy()): input_tf, script_tf, bar_magnifier, magnifier_samples, magnifier_dist (uniform / cosine / triangle / endpoints / front_loaded / back_loaded).

Cada entrada é {key, type, enum?, description}. Chame isto primeiro para aprender o que o mecanismo aceita antes de compor uma solicitação backtest_pine.

Exemplo backtest_pine

{
  "source": "//@version=6\nstrategy(\"sma cross\")\n...",
  "ohlcv_csv_path": "/work/btcusdt_15m_7d.csv",

  // Optional: the instrument of the CSV (see "The instrument" below). Either a
  // Binance symbol, or your own values; a CSV from fetch_binance_ohlcv needs neither.
  "symbol":  "BTCUSDT",            // + "market": "spot" (default) | "usdt_perp"
  "syminfo": { "qty_step": 0.00001, "mintick": 0.01 },   // goes over what `symbol` or the sidecar gives

  // Optional: override Pine input.*() values without touching the source.
  // Keys = the second arg of input.*(...) (e.g. "Fast Length").
  "inputs":    { "Fast Length": 8, "Slow Length": 21 },

  // Optional: override strategy(...) header fields. Each key is typed —
  // call list_engine_params for the catalog.
  "overrides": {
    "initial_capital":    100000,
    "default_qty_type":   "percent_of_equity",
    "default_qty_value":  10,
    "commission_type":    "percent",
    "commission_value":   0.04,
    "slippage":           2,
    "pyramiding":         0,
    "process_orders_on_close": true,
    "close_entries_rule": "ANY"
  },

  // Optional: engine runtime args (NOT strategy() header). Use script_tf
  // to aggregate the input CSV into a coarser strategy timeframe — the
  // engine REJECTS script_tf finer than input_tf, and the tool call then
  // fails (isError; "engine backtest failure (exit 4)" in the Docker image).
  "runtime": {
    "input_tf":          "15",
    "script_tf":         "60",
    "bar_magnifier":     true,
    "magnifier_samples": 8,
    "magnifier_dist":    "endpoints"
  },

  // Optional: where to write the full JSON report if it is too large to
  // return inline (see below). In Docker use an absolute path under /work.
  "report_path": "/work/report.json"
}

inputs é encaminhado como a variável de ambiente PINEFORGE_INPUTS para o mecanismo, overrides como PINEFORGE_OVERRIDES, e cada campo runtime como uma variável de ambiente PINEFORGE_INPUT_TF / PINEFORGE_SCRIPT_TF / PINEFORGE_BAR_MAGNIFIER / PINEFORGE_MAGNIFIER_SAMPLES / PINEFORGE_MAGNIFIER_DIST separada. Vazio / não definido → padrões de strategy.pine, com input_tf detectado automaticamente a partir da lacuna entre as duas primeiras linhas do CSV.

O instrumento

O mecanismo executa uma estratégia no tamanho do lote do instrumento (qty_step) e no tamanho do tick (mintick). Sem um tamanho de lote, uma ordem de 100% do patrimônio pode ultrapassar a margem por pouco, e o mecanismo registra uma linha minúscula de chamada de margem de sub-lote (por exemplo, 2.6e-08 BTC, entrada igual à saída) que o TradingView não registra. Portanto, backtest_pine (e backtest_pine_grid, e check_tradingview_parity) aplica o instrumento ao mecanismo antes da execução, por meio de sua ABI C: qty_step e mincontract (o tamanho do lote), mintick, pointvalue, type, currency, basecurrency. ticker, tickerid, fuso horário e sessão não são aplicados (o mecanismo mantém seus padrões). De onde vem:

  1. symbol (+ market: spot ou usdt_perp; padrão: o mercado registrado no sidecar do CSV quando ele nomeia o mesmo símbolo, então um perpétuo buscado permanece um perpétuo, caso contrário spot, e então o resultado diz isso: market not given: spot assumed for <SYMBOL> (pass market "usdt_perp" for a USD-M perpetual); a market que discorda do sidecar é usado, e o resultado diz para qual o CSV foi buscado). Em uma frase: O tamanho do lote é a própria leitura do TradingView para o símbolo, de uma tabela medida fornecida com este servidor (o LOT_SIZE.stepSize da Binance apenas para um símbolo que o TradingView não lista; o usual 0.001 do TradingView para uma listagem mais recente que a tabela); o tamanho do tick e as moedas vêm do exchangeInfo público da Binance (ou do sidecar ao lado de um CSV buscado por fetch_binance_ohlcv). O tamanho do lote tem três níveis, pelo que a tabela (veja abaixo) sabe do símbolo:

    1. uma leitura na tabela (o caso usual): a própria do TradingView, sem aviso de proveniência;
    2. um símbolo que a tabela lista como não no TradingView (not_on_tv): o LOT_SIZE.stepSize da Binance, o único que existe, e o aviso lot size for <label> is the exchange's lot step, not a TradingView reading: order quantities may differ from TradingView's;
    3. qualquer outro símbolo que a Binance lista (uma listagem mais recente que a tabela): o usual 0.001 do TradingView, e o aviso lot size for <label> is TradingView's usual default (0.001), not a reading for this symbol (a listing newer than the readings): order quantities may differ from TradingView's (<label> é por exemplo Binance spot BTCUSDT). Um mercado para o qual a tabela não tem tamanho de lote usual assume o passo da Binance, como em 2.

    Sem o registro da Binance para o símbolo (ela não o lista, ou a Binance não pode ser alcançada) e sem leitura na tabela, não há tamanho de lote: o instrumento não é resolvido (abaixo), nunca uma grade inventada. O tamanho do tick é o PRICE_FILTER.tickSize do símbolo e as moedas são seus quoteAsset e baseAsset, lidos do exchangeInfo público da Binance (uma solicitação, em cache por 5 minutos); o valor do ponto é 1 e o tipo crypto.

  2. Sem um symbol, o sidecar <csv path>.instrument.json que fetch_binance_ohlcv escreve ao lado de cada CSV que busca (seu resultado instrument o mostra). Ele é ignorado, com o motivo no resultado, se o CSV mudou desde então (sua primeira ou última barra, ou seu conteúdo).

  3. syminfo: seus próprios valores, para um CSV de qualquer outro instrumento: qty_step, mincontract, mintick, pointvalue, type, currency, basecurrency. Eles se sobrepõem ao que symbol ou o sidecar fornece, e sem ambos eles são o instrumento inteiro. Forneça qty_step (ou mincontract; cada um assume o padrão do outro) e, como o tick padrão do mecanismo é 0.01, mintick (o resultado avisa quando está ausente).

O que foi aplicado está no applied_runtime.syminfo do relatório e, portanto, em fingerprint.provenance.runtime: uma execução sem grade e uma com grade nunca compartilham uma impressão digital. Seu source.kind diz de onde vem o tamanho do lote: tradingview (uma leitura na tabela), exchange (da Binance, para um símbolo que o TradingView não lista), default (o usual 0.001 do TradingView, para uma listagem mais recente que a tabela) ou user (syminfo, com source.base nomeando o que ele sobrepôs); exchange e default vêm com o aviso de proveniência acima. Não resolvido significa que nenhum tamanho de lote foi encontrado (sem symbol, syminfo ou sidecar, sem registro da Binance para um símbolo para o qual a tabela não tem leitura, ou um símbolo que nenhum tem): a execução ainda prossegue com os padrões do mecanismo (sem grade de lote, tick 0.01 a menos que syminfo forneça um) e o resultado começa com uma entrada warnings (instrument grid unavailable for ... : order quantity is not floored to a lot size, so the run can contain sub-lot margin-call rows that TradingView does not book). Se o instrumento não resolvido não tem mais nada que o mecanismo possa receber (sem tick, sem moeda), nada é aplicado: a execução é a própria da imagem, seu relatório não tem applied_runtime.syminfo, e warnings diz no instrument was applied: the engine ran with its defaults; caso contrário, applied_runtime.syminfo lê {"resolved": false, "reason": ...} ao lado do que pôde ser aplicado.

Uma execução nunca é recusada, e nunca falha, por falta de um instrumento. O instrumento chega ao mecanismo por meio de uma sobreposição por execução do prefixo do mecanismo (links simbólicos para ele). Se a sobreposição não puder ser construída (um host que não pode vincular o prefixo, como Windows, ou qualquer erro ao construí-la), ou a execução do contêiner falhar com uma mensagem nomeando a sobreposição (um layout de prefixo que a sobreposição não espelha, uma pasta que o Docker não pode montar), a execução prossegue sem o instrumento (no segundo caso, mais uma vez, sem ele) e warnings diz the instrument could not be applied (<reason>); the engine ran with its defaults.

O que o mecanismo relata, e o que seus trades mostram. Uma imagem cujo run_json.py não tem apply_syminfo executa como está: seu relatório não tem applied_runtime.syminfo, e o resultado diz isso. Uma imagem cuja biblioteca do mecanismo é anterior à grade de lotes a executa e a ignora, enquanto applied_runtime.syminfo relata que ela foi aplicada (a biblioteca aceita a chamada): quando as quantidades de trade não são múltiplos do tamanho de lote relatado, o resultado diz the engine reported the lot size applied, but N of M trade quantities are not multiples of it (an older engine ignores it) (uma marca de fim de intervalo isolada não é contada). A verificação vê apenas quantidades: ela não pode distinguir um mecanismo mais antigo de uma estratégia cujas saídas parciais não são limitadas ao tamanho do lote, o que não foi verificado aqui.

O tamanho do lote do TradingView, não o da exchange. O syminfo.mincontract do TradingView é dado próprio do TradingView, não um campo da Binance, e é para isso que o TradingView limita uma ordem. Medido no TradingView para cada símbolo da Binance que ele lista (2026-10-03: 1.366 spot e 523 USD-M), difere do LOT_SIZE.stepSize para 1.188 símbolos spot e 510 USD-M (o passo da Binance é igual ao do TradingView para apenas 13% dos símbolos spot e 2,5% dos USD-M). O usual 0.001 do TradingView é o que ele lê para 90,6% dos símbolos spot (1.237 de 1.366) e 97,5% dos USD-M (510 de 523), enquanto o passo da Binance é frequentemente 1 ou 0,1: USD-M BTCUSDT é 0,000001 no TradingView e 0,001 na Binance, então limitar ao passo da Binance encolheria uma posição de 10.000 USDT em até cerca de 1,2%. O tamanho do tick correspondeu ao syminfo.mintick do TradingView para cada símbolo medido.

Um símbolo fora da tabela é uma de duas coisas, e a tabela diz qual. Ela também lista, por mercado, os símbolos que a Binance tem e o TradingView não (18 spot, 1 USD-M: not_on_tv), e o tamanho de lote usual do TradingView onde pelo menos 80% das leituras daquele mercado são ele (ambos os mercados hoje: defaults). Um símbolo na lista not_on_tv assume o passo da Binance (nível 2); qualquer outro símbolo fora da tabela é uma listagem mais recente que as leituras e assume 0.001 (nível 3), o valor mais provável lá do que o passo da Binance; ambos dizem isso em warnings. Uma tabela sem as duas listas (uma mais antiga, ou PINEFORGE_TV_GRID apontando para uma) não tem nenhuma, então um símbolo fora dela assume o passo da Binance com o aviso exchange. De qualquer forma, passe syminfo.qty_step (leia syminfo.mincontract do gráfico dele) para definir o tamanho do lote você mesmo: um tamanho de lote que você fornece é seu, mesmo quando é igual ao padrão ou ao passo da Binance, e o aviso desaparece.

Retorna o JSON do relatório da imagem standalone pineforge-release (engine, input, summary, trades, metrics, equity_curve, fingerprint, applied_inputs, applied_overrides, applied_runtime, diagnostics, elapsed_seconds) mais um bloco _meta, inline quando serializa em no máximo 200.000 bytes:

{
  "engine": "pineforge",
  "summary": { "total_trades": 49, "net_pnl": -190.85, ... },
  "applied_inputs":    { "Fast Length": "8", "Slow Length": "21" },
  "applied_overrides": { "default_qty_value": "5" },
  "applied_runtime":   { "input_tf": "15", ..., "syminfo": { "resolved": true, "qty_step": 0.00001, ... } },
  "trades": [ ... ],
  "equity_curve": [ ... ],
  "elapsed_seconds": 0.0042,
  "_meta": { "strategy_cpp_bytes": 5079, "image": "local" }   // npm/npx: the engine image name
}

Uma execução longa (3.000 barras horárias são suficientes) não cabe em um resultado de ferramenta MCP. Então o relatório completo é escrito em report_path — padrão pineforge-backtest-<timestamp>.json no diretório de trabalho do servidor — e a ferramenta retorna um resultado compacto em vez disso:

{
  "summary": { ... }, "applied_inputs": { ... }, "applied_overrides": { ... }, "applied_runtime": { ... },
  "elapsed_seconds": 0.0008, "total_trades": 73,
  "report_path": "...", "report_path_in_container": "/work/report.json",
  "truncated": true, "note": "...", "_meta": { ... }
}

Na imagem Docker, sempre passe um report_path absoluto sob /work: o arquivo então cai na sua pasta montada. Sem ele, o relatório é escrito sob /app, dentro do contêiner, e desaparece com ele. (report_path e o texto note são calculados relativos ao diretório de trabalho do contêiner, então confie no arquivo que você encontra em sua pasta montada, não nessas strings.) O limite inline é PINEFORGE_MAX_INLINE_BYTES.

Para obter um caminho de host absoluto correto de volta em report_path, execute o servidor com /work como seu diretório de trabalho e forneça a ele o lado do host da montagem em PINEFORGE_HOST_WORKDIR. O entrypoint da imagem é um caminho relativo a /app, então isso exige um --entrypoint explícito; caminhos de ferramenta relativos então resolvem dentro da montagem também:

docker run --rm -i -v "$PWD:/work" -w /work -e PINEFORGE_HOST_WORKDIR="$PWD" \
  --entrypoint node ghcr.io/pineforge-4pass/pineforge-backtest-mcp:latest /app/dist/index.local.js

Com o docker run simples de Install (diretório de trabalho /app), PINEFORGE_HOST_WORKDIR ainda torna report_path absoluto, mas errado: ele é unido com o caminho do relatório relativo a /app.

backtest_pine_grid — varredura de parâmetros

Transpila o código-fonte Pine uma vez (localmente, no contêiner), então compila e executa esse C++ para cada combinação no produto cartesiano de inputs × overrides: cada combinação é uma nova compilação g++ da mesma unidade de tradução, então seu backtest. Retorna uma lista classificada mais a entrada principal sob best.

{
  "source": "//@version=6\nstrategy(\"macd\")\n...",
  "ohlcv_csv_path": "/work/btcusdt_15m_7d.csv",

  // Each axis is {key: list-of-values}. All combinations are tried.
  "inputs": {
    "Fast Length": [8, 12, 19],
    "Slow Length": [21, 26, 39]
  },
  "overrides": {
    "default_qty_value": [1, 5],
    "commission_value":  [0.04]
  },

  // Optional knobs:
  "fixed_inputs":     { "Source": "close" },   // applied to every combo
  "fixed_overrides":  {},                      // typed strategy() overrides
  "runtime":          { "input_tf": "15",      // engine runtime args, fixed
                        "script_tf": "60" },   // across the sweep
  "max_combinations": 64,                      // default 64, at most 1024; a bigger grid is an error
  "concurrency":      2,                       // parallel runs: default 1, at most 8
  "include_trades":   false,                   // default false: omit per-trade lists
  "sort_by":          "net_pnl",               // net_pnl (default) | win_rate_pct | max_drawdown | total_trades
  "report_path":      "/work/grid.json"        // where an oversized sweep is written
}

O resultado tem total_combinations, succeeded, failed, sort_by, best, e results (execuções bem-sucedidas classificadas por sort_by, descendente, então falhas). Uma varredura grande demais para retornar inline é escrita em report_path e a ferramenta retorna best, os 10 principais em top_results, results_truncated e report_path.

check_tradingview_parity — avalie seus resultados do TradingView

Dê a ele um script Pine v6 e a exportação do Strategy Tester do próprio TradingView para ele. Ele executa o script no mesmo mercado e janela e avalia as duas listas de trades trade por trade com scripts/verify_corpus.py do pineforge-engine v1.2.0 (sha256 431452ecddc8184937951ddf9a4c5f29029731237301967b5b480800be6fd1a6), byte-idêntico no v1.3.0 e no candidato congelado 1.4.0. O pino do avaliador e a pontuação não são alterados. O harness de execução scripts/run_strategy.py vendido separadamente agora é copiado byte por byte do candidato de engine 1.4.0 congelado (SHA-256 36f7cf77e0b6355ce03f5d251c7c414f22be7da81ae4743a769f0527f06904d0). Comparado ao antigo vendor v1.2.0/v1.3.0, ele adiciona tratamento estável de código de falha/argumentos, detecção de status com falha para texto de erro vazio e serialização de string de override do Docker. Os bytes do avaliador e da derivação de feed permanecem inalterados nos hashes do vendor. Identidade exata de arquivos e testemunhas de regressão focadas não são uma prova de paridade de corpus do engine nativo.

A CLI do harness imprime o código de falha do engine, mas a ferramenta de paridade ainda não retorna esse código; esta é uma limitação conhecida na 1.4.0.

Evidência histórica de interface, não uma re-execução do corpus 1.4.0: verificado contra o pineforge-corpus aberto em a35c7c4, no engine v1.1.0 e codegen c5d97ee5: o núcleo de avaliação retorna o nível publicado para todas as 309 sondas que o portão do corpus avalia, e a própria ferramenta, chamada via stdio com apenas as entradas abaixo, retorna-o para uma amostra estratificada de 30.

{
  "pine": "//@version=6\nstrategy(\"my strategy\")\n...",
  // The "List of trades" CSV as TradingView exports it, or the Strategy Tester
  // XLSX report base64-encoded (it starts with UEsDB).
  "tradingview_trades": "Trade number,Type,Date and time,Signal,Price USDT,...",
  "symbol": "BINANCE:ETHUSDT.P",          // TradingView ticker
  "timeframe": "15",                      // TradingView resolution: 1, 5, 15, 60, 240, 1D, ...
  "range_start": "2025-04-01T00:00:00Z",  // first bar TradingView computed (UTC unless an offset is given)
  "chart_timezone": "Asia/Taipei",        // the timezone TradingView printed the trade times in

  // Optional:
  "range_end": "2025-10-01T00:00:00Z",    // default: the export's last row
  "inputs": { "Fast Length": 8 },         // TradingView's Inputs tab, as in backtest_pine
  "strategy_overrides": { "commission_value": 0.04 },  // TradingView's Properties tab (list_engine_params)
  "runtime": { "bar_magnifier": true },   // list_engine_params runtime args
  "max_mismatches": 10,                   // mismatching trades to list: default 10, at most 50
  "ohlcv_csv_path": "/work/eth_15m.csv",  // or "ohlcv_csv": "<CSV text>": your own bars
  "syminfo": { "qty_step": 0.001 }        // the instrument's own values, as in backtest_pine
}
entradanotas
pinecódigo-fonte Pine v6, no máximo 256 KiB
tradingview_tradestexto CSV "Lista de negociações" (colunas Trade number, Type, Date and time, uma coluna Price), ou o relatório XLSX como base64
symbolticker TradingView; obrigatório, a menos que o XLSX o declare ou você passe barras
timeframeresolução TradingView; obrigatória, a menos que o XLSX a declare
range_startdata ISO 8601 ou datetime da primeira barra do backtest; obrigatório, a menos que o XLSX o declare
range_endopcional; padrão: a última linha da exportação (o resultado assim o diz)
chart_timezonenome IANA do fuso horário em que os horários das negociações são impressos (offsets estilo UTC+8 são aceitos); obrigatório, a menos que a exportação o declare; a configuração "Exchange" do TradingView não é adivinhada
inputs, strategy_overrides, runtimeopcionais, as mesmas chaves que backtest_pine
max_mismatchesopcional, padrão 10, no máximo 50
syminfoopcional: os valores próprios do instrumento (qty_step, mintick, ...), como em backtest_pine; eles se sobrepõem ao que o ticker resolve e são o instrumento inteiro para um mercado diferente da Binance
ohlcv_csv / ohlcv_csv_pathsuas barras, para que qualquer mercado funcione: timestamp,open,high,low,close,volume (ms epoch) ou exportação de gráfico do TradingView time,open,high,low,close,Volume (segundos epoch ou ISO 8601); caminhos seguem as regras backtest_pine
magnifier_ohlcv_csv / magnifier_ohlcv_csv_pathbarras de 1 minuto opcionais para um ampliador de barras declarado, cobrindo da abertura da primeira barra do gráfico até o fechamento da última barra do gráfico; mesmos formatos, limites e regras de caminho que ohlcv_csv / ohlcv_csv_path

Limites (recusados com um erro simples acima deles):

o quêlimite
pine262.144 bytes (256 KiB) de UTF-8
tradingview_trades33.554.432 caracteres (32 × 1024²) como passado; a lista de negociações que o avaliador lê (o CSV, ou aquele reconstruído do XLSX) no máximo 32 MiB de UTF-8 e 400.000 linhas
relatório XLSXcada parte descompactada no máximo 64 MiB, todas as partes juntas no máximo 128 MiB; uma planilha no máximo 400.000 linhas e 256 colunas; as planilhas lidas (Lista de negociações e Propriedades) no máximo 8.000.000 de células juntas, contando as células vazias dentro de cada linha; no máximo 2.000.000 de strings compartilhadas
ohlcv_csv67.108.864 caracteres (64 × 1024²)
ohlcv_csv_pathsem limite de tamanho (uma exportação de gráfico do TradingView é convertida em memória)
busca Binance100.000 barras de gráfico e ampliador combinadas
tempo de execuçãoPINEFORGE_PARITY_TIMEOUT_MS, padrão 600.000 ms para transpilação, compilação, backtest e avaliação juntos

Não há cota nem janela de histórico aqui: o intervalo é limitado apenas pelas barras que você passa, ou pela busca Binance de 100.000 barras.

Barras. Suas ohlcv_csv / ohlcv_csv_path quando fornecidas. Caso contrário, BINANCE:<SYMBOL> é buscado como klines spot da Binance e BINANCE:<SYMBOL>.P como klines perpétuas USDT-M, da API pública, no máximo 100.000 barras. Qualquer outro símbolo sem barras é um erro que as solicita. Scripts que declaram use_bar_magnifier = true também buscam barras de 1 minuto até o fechamento da última barra do gráfico, contadas no mesmo limite, quando o gráfico é um que o harness amplia (mais grosso que 1 minuto, no máximo 1 dia) e runtime.bar_magnifier não é false. Com suas próprias barras, opcionalmente passe magnifier_ohlcv_csv / magnifier_ohlcv_csv_path; se o script declarar o ampliador, mas rodar sem um, o resultado avisa que os fills dentro das barras podem diferir dos do TradingView.

Instrumento. A execução aplica o tamanho de lote e o tamanho de tick do instrumento, como backtest_pine faz: para BINANCE:<SYMBOL> e BINANCE:<SYMBOL>.P, o próprio tamanho de lote do TradingView da tabela fornecida (o LOT_SIZE.stepSize da Binance para um símbolo que o TradingView não lista, o usual 0,001 do TradingView para uma listagem mais nova que a tabela, cada um com um aviso) e o tamanho de tick do exchangeInfo da Binance; com suas próprias barras e sem ticker, o sidecar ao lado do arquivo de barras; qualquer outra exchange precisa de syminfo. Sem um tamanho de lote o engine não aplica piso a nenhuma ordem, pode registrar linhas de chamada de margem sub-lote que o TradingView não registra, e as listas de negociações então pareiam pior: o resultado avisa. O resultado mostra o que foi aplicado sob applied_instrument (e em uma linha de texto, Instrument: ...); o mesmo instrumento vai para o núcleo de avaliação como chave de solicitação instrument.

Relatório XLSX. A planilha "Lista de negociações" é lida como o CSV seria (datas do Excel tornam-se YYYY-MM-DD HH:MM). A planilha "Propriedades" fornece o símbolo, o timeframe, o intervalo de datas, o capital inicial, o tamanho da ordem, o pyramiding, a comissão, o slippage e as opções de fill que ela declara; você pode passar as mesmas configurações explicitamente, mas um valor que discorde da exportação é um erro nomeando ambos. Entradas de estratégia listadas na exportação são relatadas, não aplicadas: passe inputs para qualquer uma que você alterou. O TradingView não documenta este layout, então nomes de planilhas e chaves são correspondidos de forma flexível e chaves desconhecidas são ignoradas.

Resultado. Um bloco de texto simples e os mesmos dados como JSON (structuredContent): o nível e o que ele significa, cada verificação com seu valor e limites, quantas negociações corresponderam e quantas são apenas do TradingView ou apenas do PineForge, as primeiras incompatibilidades lado a lado com uma dica onde os dados mostram uma (borda da janela, uma posição aberta no final do intervalo, tamanho, comissão ou slippage, fuso horário), uma verificação de fuso horário, a janela e as versões do engine, codegen e avaliador. Negociações pareiam quando têm a mesma direção, uma entrada dentro de uma hora e um preço de entrada dentro de $3. Se a maioria das negociações correspondidas estiver no mesmo offset não zero, ou outro fuso horário corresponder claramente a mais negociações, o resultado assim o diz; o nível permanece o do fuso horário que você forneceu.

Níveis, como verify_corpus.py v1.2.0 os avalia. Contagem Δ é |TradingView − PineForge| / max(TradingView, PineForge) negociações; os valores p90 são percentis 90 de diferenças relativas por negociação sobre negociações correspondidas; cobertura é negociações correspondidas sobre todas as negociações fechadas do TradingView.

nívelregra
excelentecontagens de negociações iguais; cobertura ≥ 99 % ou no máximo 1 negociação não correspondida; p90 do preço de entrada < 0,01 %; p90 do preço de saída < 0,01 % (perfil de produção: < 0,05 %); p90 de P&L < 1 % (perfil de produção: < 100 %); onde o TradingView mostra várias entradas em um horário e preço, o PineForge tem tantas
fortecobertura ≥ 95 % ou no máximo 1 negociação não correspondida; contagem Δ < 6 %; p90 do preço de entrada < 0,1 %; p90 do preço de saída < 0,5 %; p90 de P&L < 100 %
moderadocobertura ≥ 75 % e pelo menos 90 % das negociações do TradingView correspondidas
fracopelo menos uma negociação correspondida
mínimonenhuma negociação correspondida

O perfil de produção se aplica quando o script define trail_points, trail_offset ou trail_price em strategy.exit; todo outro script é avaliado no perfil estrito. Método: https://pineforge.dev/en/methodology/.

Retenção. Tudo roda na sua máquina; dados de mercado são buscados da Binance apenas quando você não passa barras. O script e a lista de negociações, e barras que tiveram que ser convertidas ou buscadas, vão para pastas temporárias que são excluídas quando a verificação termina. Com npm/npx a verificação roda na imagem do engine (docker run --network=none, o núcleo de avaliação e suas barras montados somente leitura).

fetch_binance_ohlcv — puxar dados de mercado

Escreve um CSV pronto para backtest (cabeçalho timestamp,open,high,low,close,volume, timestamp = horário de abertura em ms UNIX UTC) dos endpoints públicos da Binance. Sem autenticação necessária. Solicitações > 1000 barras são paginadas automaticamente. output_path segue as mesmas regras que ohlcv_csv_path: no Docker use um caminho absoluto sob /work; com npx ele deve permanecer dentro do diretório de trabalho, a menos que PINEFORGE_ALLOW_ANYWHERE=1.

{
  "symbol":      "BTCUSDT",
  "interval":    "15m",          // 1s (spot only), 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M
  "market":      "spot",         // default; or "usdt_perp" for USDT-margined perpetual futures
  "limit":       672,            // total bars: default 1000, at most 100000; > 1000 paginates
  "output_path": "/work/btcusdt_15m_7d.csv"
  // Optional: "start_time" / "end_time" in UNIX ms UTC.
}

Ele também escreve <output_path>.instrument.json: o instrumento do símbolo (tamanho de lote do TradingView da tabela fornecida, o da Binance para um símbolo que o TradingView não lista, o usual 0,001 do TradingView para uma listagem mais nova que a tabela; o tamanho de tick e moedas do exchangeInfo público da Binance), que backtest_pine e check_tradingview_parity captam (veja O instrumento); o resultado instrument e instrument_path o mostram. Se o exchangeInfo não puder ser lido, o CSV ainda é escrito, instrument diz o porquê e uma entrada warnings diz o que passar para backtest_pine.

binance_symbols — descobrir / validar símbolos

Retorna a lista de símbolos disponíveis na API pública da Binance para busca de OHLCV. Cache de 5 min no processo. Use isso para validar um símbolo antes de chamar fetch_binance_ohlcv.

{
  "market":        "usdt_perp",   // required: "spot" or "usdt_perp"
  "query":         "BTC",         // case-insensitive substring match
  "quote_asset":   "USDT",
  "base_asset":    "BTC",
  "status":        "TRADING",
  "contract_type": "PERPETUAL",   // futures-only filter
  "limit":         50             // default 200, at most 2000
}

Ferramentas de cobertura

O PineForge implementa um subconjunto do Pine v6, então verifique antes de escrever ou portar uma estratégia:

  • list_coverage_topics — cada tópico de cobertura com um status (supported, partial, unsupported, via_transpiler) e um resumo, além da legenda.
  • get_coverage_topic { "topic": "ta" } — as listas completas de supported / partial / via_transpiler / unsupported para um id de tópico (por exemplo ta, strategy_orders, request_security).
  • check_pine_feature { "feature": "ta.supertrend" } — um identificador ou namespace: supported / partial / unsupported / via_transpiler / not_found, com uma nota que cita a entrada do catálogo. Plots, tabelas e alertas (plot, bgcolor, table, alert) são aceitos e não têm efeito; objetos line, box e label são dados que a estratégia pode ler de volta.

Cada status descreve o que um backtest através deste servidor pode fazer. O servidor não instala barras de outros símbolos, dados de solicitação gravados ou fontes de bibliotecas Pine, então onde o engine suporta mais, a entrada assim o diz: request.security em outro símbolo, por exemplo, é suportado pelo engine, mas aqui uma solicitação cujo valor pode alcançar uma negociação interrompe a execução.

O catálogo embutido é carimbado engine v1.4.0 + codegen 1.4.0 (2026-10-08) em coverage_version. Esta é uma auditoria limitada voltada para lançamento do par congelado, não um novo teste de cada entrada do catálogo. Inventário histórico e limitações não resolvidas permanecem; barras de outros símbolos, solicitações gravadas e fontes de bibliotecas ainda não são fornecidas por este servidor.

As asserções diretamente afetadas citam testemunhas de código-fonte candidatas:

  • As formas numéricas de ponto flutuante matrix.sum matriz/matriz e matriz/escalar, métodos e palavras-chave id1/id2 são cobertas por testemunhas de sobrecarga de matriz; isso não reivindica aritmética para matrizes bool/string/color/UDT.
  • Os bindings testados localmente de histórico ausente e matriz float/int preservam na; testemunhas de histórico ausente e testemunhas de palavra-chave/callable limitadas mantêm explícitas a cópia vazia de callable, o histórico de função-local/parâmetro e os limites de mapa de histórico.
  • pineforge.h tem 81 declarações PF_API: 64 implementações em runtime e 17 declarações geradas, além de quatro exportações de recibos gerados fora desse cabeçalho. Os dois getters de runtime adicionados expõem código/args de falha; PF_ABI_VERSION permanece 4.
  • O manifesto de entrada publica supported e padrões, escolhas e limites respaldados por descritores (testemunhas de manifesto, acordo de recibos e limites conhecidos). Uma lista de opções vazia não é um sinalizador não suportado, e expressões computadas, codificações de cor e padrões dependentes de fuso horário não são garantidos como iguais aos valores nativos de recibos. O backtest de imagem de lançamento usa setters verificados quando a biblioteca expõe o protocolo completo; o harness de paridade legado e o fallback de biblioteca legada não estabelecem a mesma aplicação. Os metadados de layout de UI ainda são inertes.

O catálogo de runtime histórico permanece como referência geral; nenhum total de inventário histórico é reescrito.

Escopo do sistema de arquivos

Com npx, os caminhos de OHLCV, saída e relatório devem estar dentro do diretório de trabalho atual do processo do servidor MCP por padrão. A verificação é executada no caminho resolvido: segmentos .. e links simbólicos são resolvidos primeiro, então nenhum pode apontar para fora dele, e um link simbólico cujo alvo não existe é recusado. Um arquivo de dados ou pasta vinculada ao diretório de trabalho a partir de fora dele é, portanto, recusado também. Substitua com:

export PINEFORGE_ALLOW_ANYWHERE=1

A imagem Docker define PINEFORGE_ALLOW_ANYWHERE=1 por conta própria (o contêiner é o sandbox), então qualquer caminho é aceito lá — use caminhos /work/... absolutos.

Outras variáveis de ambiente

varpadrãopropósito
PINEFORGE_IMAGEDigest imutável do release-lock.json instaladonpm/npx apenas: imagem do motor (runtime + codegen empacotado) usada para transpile + backtest
PINEFORGE_ALLOW_ANYWHERE0 (1 na imagem Docker)Permitir caminhos de OHLCV / saída / relatório fora do cwd
PINEFORGE_DOCKER_TIMEOUT_MS120000Kill forçado para cada execução do motor e para docker pull
PINEFORGE_MAX_INLINE_BYTES200000Maior relatório retornado inline; os maiores são gravados em report_path
PINEFORGE_PARITY_TIMEOUT_MS600000Limite de tempo de uma execução de check_tradingview_parity (transpile, compile, backtest, avaliação)
PINEFORGE_BINANCE_TIMEOUT_MS20000Limite de tempo de cada solicitação à Binance (página de klines, exchangeInfo); um backtest com um symbol que não consegue alcançar a Binance ainda é executado, sem uma grade de lotes, e informa isso
PINEFORGE_BINANCE_SPOT_URL / PINEFORGE_BINANCE_FAPI_URLhttps://api.binance.com / https://fapi.binance.comURLs base das APIs públicas spot e USD-M da Binance (klines, exchangeInfo): um espelho ou proxy onde api.binance.com não é alcançável
PINEFORGE_TV_GRIDnão definidoCaminho para uma tabela de tamanho de lote feita por scripts/sync-tv-grid.mjs, usada em vez da fornecida (src/tv-grid.generated.json)
PINEFORGE_HOST_WORKDIRnão definidoDocker: o diretório do host montado em /work; quando definido, report_path é um caminho absoluto do host — correto apenas quando o servidor é executado com /work como seu diretório de trabalho (veja o final do exemplo backtest_pine)

Com Docker, passe-os como -e NAME=value.

Desenvolver

npm ci
npm run build     # tsc; also writes the gitignored src/version.ts
npm test

A tabela de tamanho de lote do TradingView (src/tv-grid.generated.json) é gerada, não editada. Quando as medições do TradingView são atualizadas (uma tabela de esquema pineforge-tv-syminfo-receipts/v1 com o próprio mincontract do TradingView por símbolo), regenere-a com um comando e confirme o resultado:

node scripts/sync-tv-grid.mjs <path to tv-grid-table.json>

Ela mantém apenas os dois locais da Binance: o mincontract de cada símbolo, a lista de not_on_tv do local, e por mercado o tamanho de lote usual do TradingView (0.001, com a parcela de leituras que são isso e sua contagem, apenas quando essa parcela é de pelo menos 0.80). Ela escreve símbolos ordenados um por linha, registra o generated_utc da tabela e sha256 e seu próprio hash de conteúdo (que cobre as leituras, as listas e os padrões), e recusa uma tabela que não está completa, não tem lista de not_on_tv para nenhum dos locais da Binance (uma vazia é aceitável), ou tem um valor fora de 1e-12..1e12. A mesma tabela dá os mesmos bytes; PF_TV_GRID_SOURCE=<path to the table> npm test também verifica que o arquivo confirmado foi feito a partir dela.

Para construir a imagem, use o digest e a versão da imagem confirmados juntos:

docker build -f docker/Dockerfile \
  --build-arg "PINEFORGE_RELEASE_IMAGE=$(node -p "const l=require('./release-lock.json'); l.image.repository+'@'+l.image.digest")" \
  --build-arg "PINEFORGE_RELEASE_VERSION=$(node -p "require('./release-lock.json').release_version")" \
  --build-arg "PINEFORGE_SOURCE_SHA=$(git rev-parse HEAD)" \
  -t pineforge-backtest-mcp .

A distribuição automática usa PRs de atualização respaldados por manifesto e a verificação obrigatória de release/ready. Veja o runbook da cadeia de lançamento offline para fixtures de CI, configurações de repositório, recibos e restauração de canal.

Licença

Este servidor é licenciado sob MIT (LICENSE). A imagem também inclui pineforge-engine (Apache-2.0) e o transpilador pineforge-codegen (fonte disponível sob a PineForge Source License 1.2 do codegen 1.3.0: gratuito para uso não comercial e para Trading Pessoal; gestão de investimentos que não seja Trading Pessoal, e outro Uso Comercial, requer uma licença comercial. Negociar uma conta que uma empresa de trading proprietário ou programa de trader financiado fornece ou aloca, incluindo uma conta de desafio, avaliação ou simulada, não é Trading Pessoal, e o capital nela, real ou simulado, é capital de investimento). Versões anteriores mantêm a licença sob a qual foram publicadas: codegen 1.2.0 a PineForge Source License 1.1, e 1.1.0 e anteriores os termos PolyForm Noncommercial com os quais foram distribuídas. O LICENSE do codegen é o texto controlador. Veja LEGAL.md.