본문으로 건너뛰기

두 Pine 엔진이 엇갈릴 때: PineForge와 PyneCore 교차 검증

약 9분 읽기

TradingView 옆에 PyneCore를 두 번째 기준 엔진으로 두는 방법, 2026년 5월 스윕이 보여 준 결과, 그리고 우호적인 두 번째 엔진이 우리가 가진 가장 쓸모 있는 디버깅 도구인 이유를 설명합니다.

이 글의 수치는 2026년 5월 5일에 측정한 값이며 당시 그대로 두었습니다. 최신 결과는 패리티 측정 방법에서 확인하세요.

2026년 5월 기준으로 우리가 아는, TradingView 플랫폼 밖에서 Pine 전략을 백테스트하는 엔진은 두 개였습니다. 우리 엔진과 PyneCore입니다. PyneSys의 PyneComp가 Pine을 Python으로 트랜스파일하고, 오픈 소스 Python 런타임인 PyneCore가 그 결과를 실행합니다. 언어도 런타임도 다르지만, 원본은 같고 지켜야 할 API 정의도 같습니다.

우리는 PyneCore를 두 번째 기준 오라클로 씁니다. 2026년 5월에는 TradingView의 “거래 목록(List of Trades)” 내보내기와 PyneCore의 실행 결과, 양쪽 모두를 대상으로 패리티 스윕을 돌렸습니다. 셋이 한 전략의 거래에 대해 모두 일치하면 그 결과를 믿습니다. 둘이 일치하고 하나가 어긋나면, 어긋난 쪽부터 들여다봅니다.

이 글은 그 스윕의 숫자가 어땠는지 보여 줍니다. 현재 비교 결과, 즉 엔진 저장소가 2026-09-29에 두 엔진을 맞붙인 비교는 비교 페이지에 있습니다(v1.0.0에 포함된 엔진 커밋 35db01c8에서 측정).

코퍼스

공개 스윕에는 참조 전략 50개가 들어 있었습니다(더 큰 162개 전략 코퍼스는 당시 비공개였고, 거래 비교 리포트, 즉 엔진 커밋 7e526c1a의 benchmarks/results/trade_comparison.md에 공개한 것이 이 부분집합이었습니다). 각 전략은 다음 과정을 거쳤습니다.

  • PyneComp로 Python으로 컴파일하고, 기준 OHLCV에서 PyneCore로 실행
  • PineForge codegen으로 C++로 컴파일하고, 같은 OHLCV에서 pineforge-engine으로 실행
  • 두 결과를 TradingView CSV 내보내기와 diff. 비교 구간은 [OHLCV span] ∩ [TV entry span] ∩ [engine entry span]로 잘라 냄
  • 5단계 척도(excellent / strong / moderate / weak / minimal)에 따라 일치도 등급 부여

핵심 결과

스윕한 50개 전략 중 47개는 PineForge와 PyneCore에서 같은 등급을 받았습니다. 두 엔진 모두 45개에서 excellent, 2개에서 strong을 받았습니다. 이 2개(13-parabolic-asr, 17-bos-curv)에서는 두 엔진이 같은 거래를 만들었고, 거래 수는 두 엔진 모두 TV와 1.8~2.8% 차이가 났습니다. 당시 기준에서 excellent는 거래 수 차이 1% 미만, 진입가·청산가 p90 0.01% 미만, P&L p90 1% 미만(trail_* 청산에는 청산가와 P&L 한도를 더 느슨하게 적용), 그리고 비교 구간 안 TV 거래의 95% 이상 매칭을 뜻했습니다.

등급이 엇갈린 3개는 흥미로운 사례입니다. 3개 모두 PineForge 쪽 등급이 더 높습니다.

전략PineForgePyneCore비고
49-partial-exit-qty-percentexcellentweakPyneCore가 청산 체결을 과다 생성
06-liquidity-sweepexcellentmoderatePyne 쪽 청산 타이밍 드리프트
07-scalping-strategyexcellentmoderatePyne 쪽 PnL p90 높음, 진입은 일치

가장 흥미로운 사례

가장 큰 차이를 보인 건 49-partial-exit-qty-percent입니다. 이 전략은 익절할 때 strategy.exit(qty_percent=...)로 포지션 일부를 덜어 내고, 이 사이클을 반복합니다. 전부 청산하고, 다시 진입하고, 또 일부 청산하는 식입니다. 테스트 구간 전체 결과는 다음과 같습니다.

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의 거래 수 차이(count delta)는 74%입니다. 하네스는 그 차이를 두 거래 수 중 큰 쪽으로 나누며, 여기서 큰 쪽은 비교 구간 안의 PyneCore 거래 2,805건입니다(TV는 725건). PineForge는 0%입니다. p90 지표를 보면 다음과 같습니다.

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)

풀어 말하면, TV 거래와 짝지어지는 거래에서는 두 엔진 모두 TV와 같은 가격에 진입합니다(entry p90이 둘 다 0%). 다만 PyneCore는 TV 거래 725건 중 582건만 짝을 찾습니다. 어긋나는 건 청산입니다. 같은 전략에 대해 PyneCore는 TradingView보다 거래를 대략 4배 많이 만듭니다(비교 구간 안에서 2,805건 대 725건). 같은 qty_percent 절이 TV의 주문 처리기가 완료로 보기 전에 다시 활성화되면서, 부분 청산 사이클이 과하게 발동했을 가능성이 가장 높습니다.

PyneCore의 품질을 평가하려는 게 아닙니다. Pine strategy.exit() 의미론의 코너 케이스일 뿐입니다. 이 비교는 양방향으로 작동합니다. PyneCore는 TV와 일치하는데 PineForge가 어긋난다면, 버그는 우리 쪽에 있습니다.

나머지 두 개

06-liquidity-sweep와 07-scalping-strategy는 같은 유형이 더 작은 규모로 나타난 경우입니다. 둘 다 진입 정렬은 100%이고, 청산가 p90 드리프트는 PyneCore가 1.65%(06)와 0.48%(07), PineForge가 0.0005%와 0.029%입니다. 트레일 방식의 청산과 부분 체결 의미론은 Pine 레퍼런스 구현에서 문서화가 가장 부족한 영역이라, 두 엔진 모두 관찰 가능한 거래 동작에서 이를 역으로 알아내야 합니다.

PyneCore 컴파일 API 호출하기

PyneSys는 컴파일 단계를 api.pynesys.io에서 HTTP로 제공합니다. curl로 바로 호출할 수 있습니다.

curl -X POST https://api.pynesys.io/compiler/compile \
  -H "Authorization: Bearer $PYNESYS_API_KEY" \
  --data-urlencode 'script=//@version=6
strategy("ma cross", overlay=true)
if ta.crossover(close, ta.sma(close, 20))
    strategy.entry("L", strategy.long)'

응답은 오픈 소스 pynecore 런타임용 Python 파일입니다. 아래는 2026년 5월 당시의 응답입니다. 최신 PyneComp 릴리스는 헤더에 자기 버전을 적고, 파일에 @pyne edge 표시를 붙입니다.

"""
@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__)

이 코드를 Python 파일로 저장하고 pip install pynesys-pynecore로 설치한 뒤 OHLCV를 지정하면, PineForge와 diff할 두 번째 엔진의 출력을 얻을 수 있습니다.

이게 왜 중요한가

백테스트 엔진 하나가 “이 전략은 테스트 구간에서 12.4% 수익”이라고 보고하면, 그 보고가 알려 주는 건 딱 하나입니다. 그 엔진이 그런 결과를 주장한다는 것. 비교할 대상이 없으면 엔진의 말을 그대로 믿을 수밖에 없습니다.

독립적인 두 엔진이 같은 스크립트에서 같은 결과를 보고한다면 훨씬 강한 증거입니다. 둘이 어긋나면 그 불일치 자체가 가설이 됩니다. 한쪽에 버그가 있거나, Pine 의미론의 코너 케이스가 모호하거나, 테스트 데이터에 두 엔진 모두 처리하지 못하는 엣지 조건이 있다는 것이죠. 셋 다 알아 둘 가치가 있습니다.

우리는 PyneCore를 이렇게 활용합니다. 지금은 엔진 저장소의 벤치마크가 같은 200개 전략에서 PineForge와 PyneCore를 TradingView 기준으로 채점합니다(PineForge는 PyneSys 컴파일러가 소스를 거부하는 전략 하나를 더 돌립니다). 실제 돈을 걸 전략을 내놓으려 한다면, 여러분도 두 번째 엔진을 쓰는 게 좋습니다.

이 글에서 다루지 않는 것

  • 지표 단위 드리프트. 별도 리포트에서 PineForge, PyneCore, PineTS의 지표별 값을 비교합니다. TradingView 대비가 아니라 엔진끼리의 비교입니다. 엔진 저장소의 benchmarks/results/indicator_comparison.md에 있습니다.
  • 당시 내부 코퍼스에 있던, 공개 스윕에 포함되지 않은 나머지 ~110개 전략. 이 전략들은 UDT 메서드, 멀티 타임프레임 조회, OCA 청산 그룹 같은 Pine 코너 케이스를 시험했습니다. 방법론은 그 뒤 방법론 페이지에 공개했습니다.

교차 검증 패턴 직접 해 보기

엔진 둘, 소스 하나, 비교할 출력 셋. 모두 일치하면 출시하세요. 어긋난다면, 실제 돈이 걸리기 전에 쓸모 있는 걸 하나 배운 것입니다.