같은 Pine 스크립트를 돌린 두 백테스트가 센트 단위까지 맞는 일은 드뭅니다. 그래서 ‘TradingView와 일치한다’는 말은 무엇을 비교하고 어디까지를 가깝다고 보는지 밝히기 전에는 의미가 없습니다. 채점하는 백테스트 하나가 무엇인지, 그 트레이드를 TradingView의 트레이드와 어떻게 짝짓는지, 다섯 등급이 각각 무엇을 요구하는지, 코드 변경은 어떻게 판단하는지 설명합니다.
TradingView와 일치한다고 말하는 백테스터는 많습니다. 하지만 같은 Pine 스크립트를 돌린 두 백테스트가 센트 단위까지 맞는 일은 거의 없으니, 무엇을 비교했고 어느 정도를 가깝다고 보는지 알기 전에는 그 말에 큰 의미가 없습니다. PineForge 스코어보드는 백테스트 7,989개에 각각 다섯 단어 중 하나를 붙이고, 그중 7,905개가 “excellent”입니다. 이 글에서는 이 단어와 나머지 네 단어가 무슨 뜻인지 설명합니다.
백테스트 하나, 트레이드 목록 하나
채점 단위는 프로브입니다. 프로브란 “TradingView에서 트레이드 목록과 함께 내보낸 전략을 같은 봉 위에서 트레이드 하나하나 다시 재생한 것”입니다(codegen README). 스크립트는 자체 입력값과 기본값을 그대로 쓰고, 등급은 두 트레이드 목록을 비교해서 매깁니다. 하나는 TradingView의 목록, 다른 하나는 PineForge가 같은 봉으로 만든 목록입니다.
스크립트 하나가 여러 종목에서 각각 프로브가 될 수 있습니다. 7,989개는 공개 코퍼스 전략 312개 중 309개와, TradingView 스크립트 741개로 만든 프로브 7,680개를 합친 것입니다. 프로브는 종목 9개(크립토, 미국 선물과 주식, 인도 지수, 통화쌍, 금)에 걸쳐 있고, 종목마다 15분봉과 일봉으로 돌립니다(스코어보드).
트레이드 짝짓기
채점기는 공개 스크립트 하나, verify_corpus.py입니다. 이 스크립트는 TradingView 트레이드마다 짝이 될 PineForge 트레이드를 찾습니다. 방향이 같고, 진입 시각이 TradingView의 진입과 1시간 이내이며, 진입가 차이가 그 종목의 가격 단위로 3.00 이내인 트레이드 중에서, 아직 짝이 정해지지 않은 가장 가까운 트레이드를 고릅니다(짝짓기, 허용 범위). 그런 다음 두 가지를 잽니다. TradingView 목록을 얼마나 재현했는지, 그리고 재현한 트레이드가 얼마나 가까운지입니다.
앞의 것을 커버리지라고 부르며, 두 목록이 겹치는 구간만이 아니라 청산된 TradingView 트레이드 전체를 기준으로 셉니다. 이유는 코드에 적혀 있습니다. 다른 지표는 매칭 결과가 스스로 정하는 구간 안에서 계산하기 때문에, “이 게이트가 없으면 거의 아무것도 재현하지 못한 실행이 우연히 재현한 작은 조각만으로 최상위 등급을 받을 수 있다(프로덕션에서 관찰됨: 실제 커버리지 0.9%에서 ‘excellent’)”는 것입니다(채점기). 커버리지가 게이트가 되자 코퍼스 전략 두 개가 moderate로 내려갔습니다. 각각 TradingView 트레이드 224건 중 209건, 241건 중 228건을 재현했는데, 예전 구간 방식이 가리고 있던 차이였습니다.
다섯 단어
| 등급 | 재현한 TradingView 트레이드 | 트레이드 수 | 진입가, 청산가(p90) | P&L(p90) |
|---|---|---|---|---|
| excellent | ≥ 99% | 동일하며, 정확히 같은 시각, 가격, 방향에 TradingView가 서로 다른 진입 Signals를 둘 이상 표시하는 경우, 엔진도 그 지점에 같은 수의 서로 다른 진입을 표시함(개별 진입 식별) | 0.01% 이내 | 1% 이내 |
| strong | ≥ 95% | 6% 이내 | 0.1%, 0.5% | 100% 이내 |
| moderate | ≥ 75%, 겹치는 구간 안에서는 ≥ 90% | |||
| weak | 1건 이상 | |||
| minimal | 없음 |
“p90”은 트레이드 열 건 중 아홉 건이 적어도 그만큼 가깝다는 뜻입니다(임계값, 등급 사다리). 짝을 찾지 못한 TradingView 트레이드가 많아야 1건인 목록은 excellent와 strong의 커버리지 기준을 통과하므로, 짧은 내보내기의 가장자리에 걸린 트레이드 하나 때문에 등급을 잃지는 않습니다. excellent는 트레이드 수 차이를 전혀 허용하지 않습니다. 코드에 적힌 이유는 이렇습니다. “비율 기준은 큰 전략에서 빠지거나 더 생긴 트레이드 수십 건을 가릴 수 있다”(채점기). 트레일링 스톱으로 청산하는 전략은 청산가 0.05% 이내, P&L 100% 이내라는 더 느슨한 기준으로 채점합니다. 트레일이 봉 안 어디에서 체결되는지는 TradingView의 봉 내부 가격 경로에 달려 있기 때문입니다(채점기).
최악의 트레이드는 출력만 하고 채점하지 않는다
등급은 최악의 트레이드가 아니라 90번째 백분위수를 봅니다. 그 이유를 공개 전략 하나가 보여 줍니다. 다음은 order-harbor-stop-limit-01에 대한 채점기 출력을 줄인 것입니다.
Matched: 471 (100.0% of TV)
Count delta: 0.0000% (OK; abs=0)
PnL p90 delta: 0.0381% (OK)
-- report-only (not gated; MAE/MFE are intrabar-path-limited) --
Entry/Exit/PnL p100: 0.0011% / 0.0084% / 4.9658%
-> excellent
등급 바로 앞의 숫자를 보세요. 트레이드 하나의 P&L이 5% 가까이 어긋납니다. 최악의 트레이드를 보여 달라고 하면(--show-diffs 3) 채점기는 이 트레이드에서 TradingView는 1,970.36에, PineForge는 1,970.35에 진입했다고 알려 줍니다. 약 51센트를 잃은 트레이드입니다. 약 2.5단위에서 1센트 차이면 2.5센트이고, 2.5센트는 51센트 손실의 5%입니다. 최악의 트레이드로 등급을 매긴다면 진입 한 번의 1센트 때문에 이 전략은 excellent를 받지 못합니다. 백분위수 기준은 이 전략을 통과시키고, 리포트에는 여전히 그 이상치가 나옵니다.
변경을 판단하는 방법
등급은 지금 상태의 코드를 설명합니다. 변경은 그것이 무엇을 움직이는지로 판단합니다. 같은 프로브를 변경 전후로 채점하고, 규칙은 하드 서피스(hard surface)에서 회귀가 없을 것을 요구합니다. 그 밖의 모든 종목과 타임프레임에서는 excellent 밴드와 excellent+strong 밴드, 두 밴드를 합친 점수를 봅니다. 점수가 0보다 크면 통과하되, 한 등급 넘게 떨어져 밴드를 벗어난 프로브가 없어야 합니다. 나빠진 것이 하나도 없다면 점수가 정확히 0이어도 통과합니다(README).
밴드를 두 개 두는 것은 한쪽이 놓치는 이동을 다른 쪽이 잡기 때문입니다. strong에서 excellent로 올라간 전략은 첫 번째 개수만 바꾸고, moderate에서 strong으로 올라간 전략은 두 번째 개수만 바꿉니다. 9월의 한 변경은 프로브 32개를 excellent로 올렸습니다. 그중 두 개는 원래 strong 아래였기 때문에 두 밴드에서 모두 집계됐고, 이 변경은 내려간 프로브 하나 없이 +34를 기록했습니다. 하드 서피스는 15분봉 ETH 레인으로, 공개 코퍼스 전략 309개를 포함한 프로브 1,009개입니다. 변경이 다른 곳에서 무엇을 얻든, 여기서는 어떤 프로브도 떨어지면 안 됩니다.
아무것도 움직이지 않을 때
좋은 변경 중에도 아무것도 움직이지 않는 변경이 많습니다. 리팩터링, 새 API, 세트 안의 어떤 전략도 닿지 않는 경우를 고치는 수정 같은 것들입니다. 문서만 바꾸는 변경은 스윕이 필요 없습니다(예시). 밴드에 들어가거나 밴드에서 나가는 프로브가 없는 코드 변경은 점수가 0이고, README 규칙에 따르면 나빠진 것이 하나도 없는 한 통과합니다. 등급이 전혀 바뀌지 않았다면 “no-improve-no-regression”(개선도 회귀도 없음) 표시가 붙고, weak에서 moderate로 올라간 전략처럼 두 밴드가 잡지 못하는 곳에서 나아진 것이 있다면 “improved”(개선됨) 표시가 붙습니다. 다만 점수가 0이어도 나빠진 것이 숨어 있을 수 있고, 그러면 변경은 실패합니다. 두 밴드보다 아래에서 프로브 하나가 moderate에서 minimal로 떨어진 경우나, 한 프로브의 하락이 다른 프로브의 상승을 상쇄한 경우가 그렇습니다.
이런 변경에서는 이동 0이 기대하는 결과입니다. 하지만 다섯 단어는 눈금이 거칠어서, 이동이 0이라고 해서 다른 것이 하나도 바뀌지 않았다는 증명은 되지 않습니다. 그래서 엔진 CI는 공개 코퍼스에서 엔진이 만드는 모든 트레이드 목록의 해시도 고정해 둡니다. 전략 하나의 슬리피지를 1틱 바꾸면 “verify_corpus.py가 여전히 excellent=311, strong=0, anomaly=1을 보고하는 동안에도 그 전략의 트레이드와 기준선 해시가 움직입니다”(CI 문서).
실무에서 기억할 것
- 갤러리 페이지의 “excellent”는 트레이드 수가 TradingView와 같고, TradingView 트레이드를 99% 이상 재현했으며, 열 건 중 아홉 건의 가격과 P&L이 표의 기준 안에 든다는 뜻입니다. “excellent”에서는 정확히 같은 시각, 가격, 방향에 TradingView가 서로 다른 진입 Signals를 둘 이상 표시하는 경우, 엔진도 그 지점에 같은 수의 서로 다른 진입을 표시합니다(개별 진입 식별). 갤러리 전략은 TradingView 쪽 이상 사례로 지정된 하나를 빼면 모두 excellent이고, “strong”은 비공개 테스트에만 있습니다.
- 직접 만든 백테스터를 TradingView와 비교한다면 같은 방식으로 비교하세요. 트레이드는 진입 기준으로 짝짓고, 커버리지는 TradingView 트레이드 전체를 기준으로 세고, 최악의 트레이드가 아니라 백분위수를 보세요.
- 공개된 부분은 직접 다시 돌려 볼 수 있습니다. README의 명령어로 코퍼스 전략 312개를 빌드하고, 실행하고, 채점합니다. 비공개 테스트는 공개되지 않은 스크립트를 우리가 직접 측정한 것으로, 대부분 TradingView 약관에 따라 비공개로 두는 커뮤니티 스크립트입니다.
등급은 1.0.0 릴리스에 포함된 엔진과 codegen 코드로 2026-09-29에 측정했습니다. 2026-10-02에 릴리스된 엔진과 codegen 1.0.1의 코드도 같은 프로브 7,989개로 채점했고, 등급이 바뀐 프로브는 없었습니다.
다음으로 볼 곳
- 패리티를 측정하는 방법: 현재 결과와 그 출처.
- 갤러리 둘러보기: 코퍼스 전략마다 등급과 두 트레이드 목록을 함께 보여 줍니다.
- 마진 패리티 이야기: 전략이 excellent가 아닐 때 채점기 출력이 어떻게 보이는지, 그리고 한 전략의 원인을 어떻게 추적했는지.