Cuando dos motores Pine discrepan: validación cruzada PineForge vs PyneCore
Cada release pasa un barrido de paridad frente a TradingView y PyneCore. Así salen los números del último barrido y por qué un segundo motor «amigo» es la mejor herramienta de depuración que tenemos.
Hay dos motores Pine «de verdad» fuera de TradingView que conocemos bien: el nuestro y PyneCore. PyneSys transpila Pine a Python con PyneComp; PyneCore es el runtime abierto que ejecuta el resultado. Otro lenguaje, otro runtime, mismo Pine en origen.
Usamos PyneCore como segundo oráculo. Cada release de PineForge pasa el barrido de paridad contra el CSV «List of Trades» de TradingView y contra la salida de PyneCore. Cuando los tres coinciden en los trades, nos creemos el resultado. Cuando dos sí y uno no, casi siempre el fallo está en el disidente — muchas veces en nosotros.
Aquí van los números del último barrido público.
El corpus
50 estrategias de referencia en el barrido que publicamos (el corpus grande de ~167 entradas es interno; este subconjunto es el que va al informe de comparación). Para cada una:
- PyneComp → Python → PyneCore sobre el OHLCV canónico
- PineForge codegen → C++ →
pineforge-enginesobre el mismo OHLCV - Ambos se comparan con el export CSV de TradingView, recortado a
[ventana OHLCV] ∩ [ventana entradas TV] ∩ [ventana entradas motor] - Grado de coincidencia en escala de 5 niveles (excelente / fuerte / moderada / débil / mínima)
El titular
De las 50, 47 comparten el mismo nivel en PineForge y PyneCore. Las dos máquinas marcan excelente (≥95 % de trades frente al CSV de TV) en 47; PineForge cae a fuerte en 2 de esas por cómo contabilizamos deltas de código frente al TV export — detalle de contabilidad, no de ejecución.
Las 3 que discrepan por nivel son curiosas: en todas PineForge queda por encima.
El caso gordo
49-partial-exit-qty-percent es el abismo. La estrategia usa strategy.exit(qty_percent=...) para ir deshaciendo trozos de posición en profit-take en bucle.
TV trades (raw, in-window): 725
PineForge engine trades: 852 → 725 in-window → 725 matched (100% of TV)
PyneCore engine trades: 3297 → 2805 in-window → 582 matched (80.3% of TV)PyneCore dispara ~74 % más trades que TV en recuento bruto; PineForge queda en 0 % de delta de conteo tras alinear ventanas.
PineForge: count_delta 0.0000% · entry p90 0.0000% · exit p90 0.0004% · PnL p90 0.1321%
PyneCore : count_delta 74.1533% · entry p90 0.0000% · exit p90 1.0376% · PnL p90 (high)Las entradas cuadran al pixel (p90 0 % en ambos). La pelea es de salidas: PyneCore parece re-disparar ciclos de salida parcial donde TV ya dio por cerrado el mandato de qty_percent.
No es un veredicto moral sobre PyneCore: es un vértice feo de la semántica de strategy.exit(), y nosotros lo molimos hasta cuadrar con TV tras verlo en el barrido. El juego del bug va en ambos sentidos — más de una vez PyneCore y TV coincidieron cuando nosotros no.
Las otras dos
06-liquidity-sweep y 07-scalping-strategy son la misma forma en menor magnitud: entradas alineadas al 100 %, salidas con deriva ~1–2 puntos porcentuales en PyneCore frente a <0.05 % en PineForge. Trails y fills parciales son donde la referencia de Pine está menos documentada; todo motor tiene que inferir comportamiento observable.
API de compilación PyneSys
PyneSys expone la compilación por HTTP:
curl -X POST https://api.pynesys.io/compiler/compile \
-H "Authorization: Bearer pyne_..." \
--data-urlencode 'script=//@version=6
strategy("ma cross", overlay=true)
if ta.crossover(close, ta.sma(close, 20))
strategy.entry("L", strategy.long)'La respuesta es Python pensado para pynecore:
"""
@pyne
This code was compiled by PyneComp v6.0.31 — the Pine Script to Python compiler.
Run with open-source PyneCore: https://pynecore.org
Compile Pine Scripts online at PyneSys: https://pynesys.io
"""
from pynecore.lib import close, script, strategy, ta
@script.strategy("ma cross", overlay=True)
def main():
if ta.crossover(close, ta.sma(close, 20)):
strategy.entry('L', strategy.long)
if __name__ == "__main__":
from pynecore.standalone import run
run(__file__)Lo guardas, pip install pynecore, apuntas al mismo CSV OHLCV y tienes segunda salida para comparar con PineForge.
Para qué sirve
Un solo motor que dice «12,4 % en esta ventana» solo afirma eso: que él lo cree. Sin contraste, te lo tragas o no.
Dos motores independientes con el mismo script y mismos datos es evidencia fuerte. Si discrepan, la discrepancia es hipótesis: bug en uno, ambigüedad semántica, o datos con arista que nadie contempló. Las tres cosas importan antes de arriesgar pasta real.
Lo que este post no cubre
- Deriva a nivel indicador. Otro informe mide acuerdo indicador a indicador entre PineForge, PyneCore y TV; vive en
benchmarks/results/indicator_comparison.mddel repo del motor. - Las ~110 estrategias del corpus interno que no están en el barrido público. Ahí viven UDT,
request.securityen serie, grupos OCA… Cuando publiquemos metodología completa, otro artículo.
Hazlo tú
- Clave API gratuita PineForge
- Clave PyneSys
- Elige un Pine, corre ambas tuberías sobre el mismo CSV, diff de listas de trades.
Dos motores, un fuente, tres lecturas. Si todas cuadran, adelante. Si no, mejor enterarte antes que mover capital.