OptiNod 아카데미

룩어헤드와 리페인팅 — 신호를 알 수 있었던 시점을 확인하세요

변하는 실시간 값, 상위 시간대 미확정값, 과거 위치 표시와 미래 누수를 구분합니다. 차트 화살표의 위치보다 신호를 처음 알 수 있었던 시점을 검증합니다.

화살표가 그려진 봉과 그 화살표를 처음 알 수 있었던 시점을 따로 기록하세요.


리페인팅은 과거와 실시간에서 계산이나 표시가 다르게 나타나는 현상을 넓게 가리킵니다. 진행 중인 봉의 가격에 따라 RSI나 이동평균이 바뀌는 일도 여기에 포함됩니다. 모든 변화가 오류이거나 기만인 것은 아닙니다. 문제는 사용자가 이해한 진입 규칙과 실제로 이용할 수 있었던 정보가 다른 경우입니다. TradingView 리페인팅 정의


룩어헤드 편향은 그중에서도 판단 당시 알 수 없었던 미래 정보를 과거 계산에 넣는 오류입니다. 신호가 잠깐 나타났다 사라지는 현상, 며칠 뒤 확인된 고점을 과거 봉에 표시하는 동작, 미래의 최종 가격을 미리 쓰는 오류는 서로 구분해야 합니다. 같은 처방으로 모두 해결되지는 않습니다.


따라서 승률이 높거나 화살표가 고점에 정확히 놓였다는 이유만으로 정상 또는 오류라고 판단하지 않습니다. 어떤 값이 언제 확정되고, 그 값이 신호와 주문에 언제 사용되는지 확인합니다. 이 글의 예시는 작동 원리를 설명하는 조건이며, 검증을 마친 수익 전략이나 실제 거래 결과가 아닙니다.


과거 차트의 표시 위치와 실시간에 신호를 알 수 있었던 시점을 비교하는 개념도
과거 차트의 표시 위치와 실시간에 신호를 알 수 있었던 시점을 비교하는 개념도

진행 중인 봉의 변화는 미래 정보와 다릅니다


현재 봉의 고가·저가·현재 가격은 봉이 닫히기 전까지 바뀔 수 있습니다. 그 값으로 계산하는 교차 조건도 잠시 참이었다가 거짓으로 돌아갈 수 있습니다. 당시 현재 가격을 읽었다는 이유만으로 미래 누수는 아닙니다. 다만 나중에 남은 OHLC만으로는 그 중간 상태를 모두 재현할 수 없습니다.


지표는 일반적으로 실시간 가격 업데이트마다 다시 계산합니다. 전략은 기본적으로 봉 마감에 계산하며, calc_on_every_tick 옵션을 사용하면 실시간 계산 방식이 달라집니다. 이 전략 옵션을 모든 지표의 공통 설정처럼 설명하면 안 됩니다. 실시간 틱 계산 전략의 행동을 종가 데이터만으로 동일하게 재현한다고 가정하지 마세요. 실행과 봉 상태


종가 확정 신호가 필요한 경우에는 현재 차트의 barstate.isconfirmed 조건을 확인합니다. 그러나 이는 그 차트 봉의 마감 확인입니다. 다른 시간대의 미확정값까지 확정시키거나 과거 위치 표시를 고치지 않습니다. 봉 중간 신호를 의도적으로 쓰는 방식도 가능하지만, 별도의 실시간 기록과 검증 기준이 필요합니다.


예제 1 · 현재 가격과 차트 봉 확정값 (Pine v6)


입력은 없습니다. 일반 5분봉에서 주황색 Current close와 초록색 Confirmed close 점을 비교합니다. 열린 봉의 주황색 선은 현재 가격에 따라 움직이고, 초록색 점은 그 차트 봉의 마감 업데이트에서 표시하도록 설계했습니다. 과거 봉에서는 모두 확정값이므로 두 값이 같습니다. 봉 중간 값의 변화는 실제 업데이트를 기록해야 보입니다.


//@version=6
indicator("OptiNod - Open bar and confirmed close", overlay=true)
// Layout: Minimal Overlay. Educational indicator; no orders or alerts.
float confirmedClose = barstate.isconfirmed ? close : na
plot(close, "Current close", color=#f59e0b, linewidth=2)
plot(confirmedClose, "Confirmed close", color=#10b981, linewidth=2, style=plot.style_circles)

lookahead 설정은 참조하는 시간대와 표현식을 함께 봅니다


낮은 시간대 차트에서 아직 마감되지 않은 높은 시간대 봉의 최종 값을 과거의 이른 봉에 배치하면 미래 누수가 생깁니다. 예를 들어 한 주가 끝나야 알 수 있는 그 주의 최종 고가를 월요일 판단에 미리 쓰는 방식입니다. 날짜나 실제 자산 가격을 붙이지 않아도, 정보가 언제 존재했는지로 오류를 판별할 수 있습니다.


lookahead_on이라는 이름만 검색해 발견한 모든 호출을 오류라고 판단하면 안 됩니다. 높은 시간대의 현재 표현식을 오프셋 없이 요청하는 경우와, 이미 끝난 높은 시간대 봉을 요청하는 경우는 다릅니다. 같은 시간대 또는 낮은 시간대 요청도 따로 검토해야 합니다. 다른 시간대 데이터와 lookahead


반대로 기본값 lookahead_off를 사용한다고 높은 시간대 값이 항상 확정되는 것은 아닙니다. 과거 봉에서의 배치와 실시간의 진행 중 HTF 값은 다를 수 있습니다. 새로고침 전후가 같은지 확인하려면 요청 시간대와 그 값이 확정되는 시점까지 봐야 합니다.


상위 시간대의 최종 값을 과거에 너무 일찍 배치하면 생기는 미래 누수 개념도
상위 시간대의 최종 값을 과거에 너무 일찍 배치하면 생기는 미래 누수 개념도

확정 HTF 값은 직전 봉과 배치 옵션을 한 쌍으로 다룹니다


확정된 상위 시간대 데이터만 쓰려는 경우 공식 문서는 요청 표현식의 이전 봉 값인 expression[1]과 barmerge.lookahead_on을 함께 사용하는 방식을 설명합니다. [1]은 request.security()가 평가하는 상위 시간대 표현식에 적용되어야 합니다. 반환된 낮은 시간대 시리즈를 나중에 한 봉 미루는 것과 같지 않습니다. 확정 HTF 요청 방식


이 글에서 다루는 방식은 요청 시간대가 차트보다 엄격히 높은 경우로 한정합니다. 같은 시간대나 낮은 시간대 입력은 별도 처리하거나 거부해야 합니다. 이전 HTF 봉을 쓰므로 진행 중인 HTF 봉의 최신 움직임에 반응하지 않는 대가가 있습니다. 이것이 성과 개선이나 모든 종류의 리페인팅 제거를 보장하지는 않습니다.


barstate.isconfirmed를 차트 진입 조건에 붙이는 것만으로 HTF 값은 확정되지 않습니다. 이를 request.security() 안에 넣는 것으로 대신할 수도 없습니다. 차트 봉과 요청 봉의 확정 여부를 각각 설계하세요. barstate.isconfirmed의 적용 한계


예제 2 · 직전 확정 HTF 종가 (Pine v6)


일반 5분봉, 입력 상위 시간대=60으로 사용합니다. 초록색 계단은 직전 1시간봉 종가를 새 1시간 구간부터 쓰도록 설계했습니다. [1]은 요청 안의 1시간 문맥에 적용되고, lookahead_on은 이미 확정된 값을 그 구간 시작부터 배치합니다. 미래의 현재 1시간봉 종가를 읽는 방식이 아닙니다. 같은 시간대나 더 낮은 입력은 오류로 거부합니다. 진행 중인 1시간봉의 최신 움직임을 포기하는 대가가 있으며, 데이터 수정이나 다른 코드의 과거 위치 표시까지 해결하지는 않습니다.


//@version=6
indicator("OptiNod - Previous confirmed HTF close", overlay=true)
// Layout: Minimal Overlay. Educational indicator; no orders or alerts.
string higherTimeframe = input.timeframe("60", "상위 시간대", tooltip="차트보다 큰 시간대만 사용합니다. 5분 차트에서는 60분을 선택합니다.")
if timeframe.in_seconds(higherTimeframe) <= timeframe.in_seconds()
    runtime.error("Choose a timeframe strictly higher than the chart.")
float confirmedHigherClose = request.security(syminfo.tickerid, higherTimeframe, close[1], gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_on)
plot(confirmedHigherClose, "Previous confirmed HTF close", color=#10b981, linewidth=2, style=plot.style_stepline)

실행에서 확인한 결과와 범위 — Pine v6의 두 예제는 TradingView Pine Editor에서 컴파일하고 차트에 실행했습니다. 일반 캔들 OANDA:EURUSD 5분봉의 짧은 실시간 관측에서 예제 1의 현재 가격은 1.12886, 차트 봉 확정값은 아직 표시되지 않았습니다. 별도로 실행한 예제 2에서는 현재 5분봉 가격 1.12892와 직전 확정 1시간봉 종가 1.12912가 달랐고, 과거 차트에도 초록색 계단이 표시됐습니다. 과거 AAPL 일봉의 마감된 봉에서 예제 1의 두 값은 모두 333.02였습니다. 이 숫자는 해당 관측값이며 거래 조건이나 고정 입력이 아닙니다.


이 확인은 차트 실행과 짧은 실시간 관측까지입니다. 5분봉 전체와 1시간 경계 전후를 연속 추적하지 않았으므로, 재시작 전후의 동일성이나 모든 시장에서의 동작을 검증한 결과로 읽지 마세요. 다음 검사는 같은 소스·입력·시장·데이터 범위를 고정한 채 실제 마감과 HTF 경계를 기록하고 재실행 결과를 대조하는 것입니다.


과거에 그린 피벗은 그 봉에서 알 수 있었던 신호가 아닙니다


오른쪽 두 봉이 필요한 피벗을 예로 들면, 후보 봉 뒤에 두 봉이 생겨 조건이 확인된 시점과 피벗 후보 봉의 시점은 다릅니다. 마커를 두 봉 전으로 옮겨 그리면 모양은 이해하기 쉽지만, 그때 이미 진입할 수 있었다는 뜻은 아닙니다. 피벗을 쓰는 주문은 확인 시점 이후에 평가해야 합니다.


ZigZag의 마지막 선분이나 최근 스윙을 기준으로 움직이는 자동 되돌림선도 확정 전에는 달라질 수 있습니다. 확정 규칙은 구현마다 다릅니다. 특정 자산의 고점이 며칠 뒤에 확정됐다고 말하려면 당시 설정과 실제 기록이 필요합니다. 도구 이름이나 높은 승률만으로 미래 누수를 단정하지 않습니다.


음수 플롯 오프셋은 그림의 위치를 과거로 옮기는 기능이며 미래 데이터를 읽는 연산과 다릅니다. Pine의 히스토리 참조 연산자는 이전 봉을 참조하는 도구입니다. 유효하지 않은 음수 히스토리 참조를 정상적인 미래 데이터 접근 문법처럼 예시로 제시해서는 안 됩니다. 소스에서는 표시 위치와 계산에 사용한 정보의 시각을 각각 점검하세요. 히스토리 참조 연산자


가격 변화에 따라 달라지는 마지막 스윙과 확인 시점의 차이를 보여주는 개념도
가격 변화에 따라 달라지는 마지막 스윙과 확인 시점의 차이를 보여주는 개념도

알림과 주문의 시점은 차트 표시에서 따로 확인합니다


봉 마감 기반 규칙이라면 알림도 그 규칙에 맞춰 설정해야 합니다. 다만 alert() 호출의 빈도, alertcondition()으로 만든 알림의 설정, 전략의 주문 체결 알림은 서로 다릅니다. “봉 마감마다 한 번”이라는 설정이 모든 알림에 일괄 적용된다고 가정하지 않습니다. 실행 중인 알림이 사용하는 소스와 입력값도 확인합니다. TradingView 알림 문서


현재 차트의 마감에 맞춘 알림도 진행 중인 HTF 값으로 만든 조건이라면 나중에 달라질 수 있습니다. 알림 빈도 설정은 데이터 확정 규칙을 대신하지 않습니다. 알림이 발송됐다는 사실 또한 실제 주문이 접수·체결됐다는 증거와 구분합니다.


신호가 확정된 봉의 종가에서 주문이 체결된 것으로 보인다고 즉시 룩어헤드라고 판단하지 않습니다. 전략의 체결 옵션과 주문 유형을 먼저 확인합니다. 시뮬레이션 체결 방식이 실제 전달 지연과 거래 가능 가격을 반영하는지는 백테스트와 실전 비교에서 별도로 점검합니다.


새로고침 전후 비교에는 같은 데이터 조건이 필요합니다


과거 봉도 데이터 공급자의 수정, 주식 분할 등 조정, 로딩된 이력의 시작점 변화로 달라질 수 있습니다. “마감된 봉은 영원히 바뀌지 않는다”는 전제로 코드만 의심하면 원인을 놓칩니다. 같은 소스 버전·입력값·거래소·계약·일반 캔들·시간봉·세션·데이터 범위로 비교하세요. 데이터 변화에 따른 리페인팅


확정 시점 검증 조건 — 일반 5분봉과 1시간 HTF를 선택하고, 1시간 경계 전후의 실제 업데이트를 관찰합니다. 신호를 진입 판단에 쓰기 시작하는 시점은 사전에 정한 확인 조건을 통과한 뒤입니다. 이 시험은 주문을 내지 않습니다. 실시간 기록을 수집할 수 없거나 소스·설정·데이터가 바뀌면 비교를 중단하고, 원인별 검증을 무효로 표시합니다.


실시간 관찰 중에는 시각과 시간대, 차트 봉 시각, HTF 구간, 값과 신호, 최초 표시 위치를 기록합니다. 봉이 닫힌 뒤 같은 위치를 확인하고, 다시 불러온 결과와 대조합니다. 화면 녹화·스크린샷과 알림 로그는 서로 보완할 수 있지만, 알림이 없는 장중 상태까지 알림 로그만으로 복원할 수는 없습니다.


당시 관찰 기록과 재실행된 차트를 대조하는 검증 개념도
당시 관찰 기록과 재실행된 차트를 대조하는 검증 개념도

승률 대신 확인 가능한 동작을 검수 기준으로 삼습니다


  • 실시간의 변하는 값, 차트 봉 확정값, HTF 확정값을 구분했습니다.
  • HTF 요청의 표현식·오프셋·lookahead·시간대 제한을 함께 검토했습니다.
  • 피벗·ZigZag의 표시 봉과 실제 확인 봉을 각각 기록했습니다.
  • 알림 유형·빈도·실행 중인 설정과 주문 체결 기록을 구분했습니다.
  • 소스와 데이터 조건을 고정한 실시간 관찰 기록을 새로고침 결과와 비교했습니다.

Bar Replay는 과거 시퀀스와 표시 지연을 살펴보는 보조 도구입니다. Strategy Tester CSV는 해당 시뮬레이션의 거래 기록입니다. 둘만으로 당시의 모든 실시간 틱과 신호를 증명할 수 없습니다. 실제 TradingView 컴파일, 차트 실행, 실시간 관찰을 아직 수행하지 않은 예제는 검증 완료 코드로 취급하지 마세요. “non-repainting”이라는 문구나 특정 승률을 통과 기준으로 삼기보다, 어떤 시점에 어떤 정보로 신호가 생겼는지 설명할 수 있는 기록을 남기세요.

내 백테스트 결과 점검하기

최적화 결과 CSV나 TradingView 전략 거래 목록을 올리면 성과 지표와 강건성 점검 결과를 함께 보여 줍니다. 로그인하지 않아도 분석할 수 있습니다.

내 결과 파일 분석하기 분석 예시 먼저 보기