Pine Script v5 (indicator)
삼성전자와 SK하이닉스 차트에 "지금 사라, 지금 팔아라"를 글자로 찍어 주고 휴대폰으로 알림을 보내 달라는 요청이었습니다. 이동평균 골든크로스에 RSI/MFI 복합 오실레이터와 거래량 급증을 얹은 신호 지표인데, 명세서 그대로 만든 첫 버전은 신호가 거의 뜨지 않았습니다. 그걸 어떻게 풀었는지가 이 페이지의 절반입니다. 2026년 7월 납품, 이후 ATR 트레일링 청산과 프리셋 6종으로 확장.
| 구분 | 조건 | 납품 기본값 |
|---|---|---|
| 매수 (AND) | 단기 SMA5가 장기 SMA20을 상향 교차한 뒤 N봉 이내에 RSI/MFI 복합 오실레이터가 밴드 안에 있고, (선택) 거래량이 20봉 평균의 1.5배 | N=5 · 밴드 30~60 · 거래량 OFF |
| 매도 (OR) | 데드크로스 또는 복합 오실 70 이상 즉시 청산 | 토글 (기본 OFF) |
| 청산 기본 | ATR(14) × 3.0 트레일링 스탑. 고점을 따라 위로만 조여지는 래칫 | 기본 ON |
| 표시 | BUY/SELL 텍스트 라벨(크기·색 입력 가능), 우측 상단 현재값 표 | |
| 알림 | alert() 통합 + alertcondition() 개별, 빈도 선택 입력 | 봉 마감 시 1회 |
RSI/MFI 복합 오실레이터는 고객이 쓰던 커뮤니티 지표와 같은 개념(RSI와 MFI를 가중 블렌딩한 뒤 이동평균으로 스무딩)을 직접 구현했습니다.
남의 코드를 복제하지 않았고, 헤더 주석에 그 방침을 남겨 뒀습니다. 지표 안에 포지션 상태머신(inPos / posHigh / posTrail)을 두어
"매도는 매수 이후에만", 트레일 래칫, 신호 최소 간격을 한 블록에서 처리합니다. strategy가 아니라 indicator라 이걸 직접 관리해야 합니다.
1차 납품본은 명세 그대로였습니다. 골든크로스 동일 봉에서 오실레이터 30~50 그리고 거래량 1.5배. 실제 종목 5분·15분·60분봉에 올리면 매수 신호가 사실상 없습니다. 세 조건이 같은 봉에서 동시에 맞을 확률은 각 조건 발생률의 곱이고, 상담 자리에서 곱셈을 한 사람은 없었습니다. "골든크로스는 좋다", "RSI 30~50이 진입 구간이다", "거래량 급증이 좋다"는 각각 맞는 말인데, 교집합이 거의 공집합이었던 겁니다.
핵심은 "골든크로스 유효 봉수 N"이라는 시간 창이었습니다. 동시 충족을 "N봉 안에 순차 충족"으로 바꾸면 곱셈 붕괴가 사라집니다. 밴드는 30~60으로 넓히고, 거래량 조건은 기본 꺼짐으로, 반대로 신호가 너무 많을 때 거를 추세·모멘텀·휩소 필터는 전부 기본 꺼짐 토글로 얹었습니다. 명세 로직은 토글 조합으로 100% 복원됩니다. 그래야 "명세대로 안 했다"는 얘기가 안 나옵니다.
그런데 조건을 풀면 이번엔 "신호가 많다, 어느 값이 맞느냐"로 문제가 뒤집힙니다. 초보 고객은 파라미터를 읽고 고를 근거가 없습니다. 그래서 삼성전자·SK하이닉스 실데이터로 5·15·60분봉을 돌려 종목 × 시간봉 프리셋 6종을 만들고, 드롭다운 하나로 적용되게 했습니다. 설명서에는 표본 구간과 비용 가정(0.25%), 과최적화 경고를 프리셋 표 옆에 같이 적었습니다. 이 페이지에는 그 성적표를 싣지 않습니다.
// 프리셋 → 유효 파라미터 간접층 (Pine에 dict가 없어서 나온 형태) pi = preset == "삼성전자 5분" ? 1 : preset == "삼성전자 15분" ? 2 : ... : 0 eFast = pi == 1 ? 5 : pi == 2 ? 5 : inFast // 단기 MA eSlow = pi == 1 ? 20 : pi == 2 ? 20 : inSlow // 장기 MA eBhi = pi == 1 ? 60 : pi == 2 ? 62 : inBandHi // 오실 상단 eUseTrail = pi > 0 ? true : inUseTrail // 프리셋은 전부 ATR 트레일 // 로직은 입력값이 아니라 e* 만 본다. 프리셋 추가 = ternary 한 줄.
plotshape가 아니라 label.new — plotshape의 text·size는 상수만 받아서 고객이 크기를 못 바꿉니다. 라벨 크기·색을 입력으로 열려면 label이 유일합니다.ta.*를 조건부로 호출하면 내부 히스토리가 어긋납니다. SMA/EMA/WMA/RMA를 매 봉 다 계산하고 ternary로 선택합니다.indicator(timeframe=…)와 alert()는 같이 못 쓴다 — 추가 작업으로 고객이 쓰던 다른 오픈소스 지표에 알림을 얹었는데, 원본 선언에 timeframe=""가 있어 첫 컴파일이 실패했습니다. 빈 문자열은 기본값과 같은 의미라 인자를 지우면 동작 변화 없이 해결됩니다.alert() 알림은 생성 창에 빈도 선택이 안 뜬다 — 고객이 "봉마다 / 봉 마감 시 선택이 없다"고 물어 무상 보완했습니다. 통합 알림을 넣을 때는 빈도를 input으로 같이 주는 게 맞습니다.실시간 국내주식 데이터는 유료 플랜과 KRX 데이터 구독이 필요합니다. 지표 자체는 설치 없이 웹·앱에서 돕니다.
알림 웹훅을 증권사 API로 받으면 됩니다. 그 구조로 만든 사례가 주도주 스크리닝 + 트레이딩뷰 웹훅 자동매매이고, 원리는 트레이딩뷰 웹훅 자동매매 가이드에 있습니다. 다만 이 건은 고객이 직접 매매하겠다고 해서 신호까지만 만들었습니다.
보장 못 합니다. 과거 몇 달 표본에서 나온 출발점일 뿐이고, 설명서에도 과최적화 경고를 같이 적었습니다. 그래서 값을 전부 입력으로 열어 두었습니다.
"이 조건에 이 조건을 더해서"까지만 말씀하셔도 됩니다. 조건 조합의 동시 발생 횟수는 저희가 먼저 세어 봅니다.
알고랩이 24시간 빠르게 답변드립니다.