새벽에 스크립트를 다 돌려놓고 결과 표를 열었는데 신호가 일곱 개뿐이었다. 일곱 개로 무슨 얘기를 할 수 있을까 싶어서 한참 그냥 앉아 있었다.

52주 신고가/신저가(52 Week High/Low)에는 계산식이랄 게 거의 없다. “지금 이 가격이 지난 1년 중 가장 높은가, 가장 낮은가"만 보면 끝이다. 그런데도 오래 살아남았다. 계산이 단순한 만큼 시장 참여자 전원이 같은 숫자를 보고 있기 때문이다. RSI나 MACD는 파라미터에 따라 사람마다 다른 값을 보지만, “52주 신고가"는 증권사 HTS든 블룸버그든 거의 똑같이 뜬다. 그래서 이 지표가 재는 건 계산보다 심리 쪽이다. 신고가를 찍으면 추세추종 매수세가 붙고, 신저가를 찍으면 손절 물량과 저가매수 물량이 동시에 몰린다. 방향은 그때그때 다르다.

52주 신고가는 원래 개인 트레이더보다 기관 스크리너 쪽에서 먼저 자리 잡은 개념이다. 미국의 IBD(Investor’s Business Daily)가 “신고가 리스트"를 매일 뽑아 배포하는 게 대표적이고, 국내 HTS의 “신고가·신저가 종목” 탭도 같은 계보다. 논리는 간단하다. 시장 전체가 조정을 받는 와중에도 신고가를 새로 쓰는 종목은 그만큼 매수 주체가 강하다는 뜻이고, 반대로 시장이 오르는데도 신저가를 쓰는 종목은 뭔가 개별 악재를 흡수하고 있다는 뜻이다. 이 논리에는 “정상적으로 우상향하는 시장"이라는 전제가 깔려 있다. 변동성이 극단으로 치솟는 구간에서는 이야기가 달라진다.

대상은 SK스퀘어(402340)다. 고른 이유는 단순하다. 최근 석 달 사이에 52주 신고가를 실제로 경신한 뒤, 두 달도 안 돼 고점 대비 반토막 넘게 빠졌다가, 다시 반등하는 구간을 통째로 갖고 있기 때문이다. 신고가/신저가 지표가 “맞을 때"와 “틀릴 때"를 한 종목, 한 구간 안에서 전부 볼 수 있는 흔치 않은 케이스다. 공교롭게도 SK스퀘어는 SK하이닉스 지분을 들고 있는 지주회사 성격이 짙어서, 반도체 업황 기대와 지주사 NAV 할인율 논쟁이 겹치며 주가가 유독 크게 흔들리는 종목이기도 하다. 이런 배경 때문인지 이번 관측 구간 동안 언론에 “52주 신고가”, “급락”, “황제주 몰락” 같은 제목이 번갈아 등장했다. 지표 하나로 시장 심리가 롤러코스터를 타는 걸 보여주기엔 더할 나위 없는 사례였다.

이 글의 데이터 범위
종목  SK스퀘어(402340), 코스피
기간  2026-05-22 ~ 2026-08-14 (58거래일)
기준  일봉 종가(Close) 기준, 수정주가 미적용
출처  stockanalysis.com KRX 402340 일봉 히스토리
 
주의  실제 "52주"(약 252거래일)에는 못 미치는 표본이다.
    아래 모든 계산은 이 58거래일을 최대 창(window)으로 삼는다.

원래대로면 52주 신고가는 252거래일치 데이터로 봐야 맞다. 이번에 확보한 시세는 58거래일이 전부였다(수집 과정은 본론에 적는다). 그래서 이 글의 “52주 신고가"는 엄밀히 말해 “가용한 최대 구간 신고가"의 근사치다. 부족한 데이터를 숨기고 그럴듯하게 포장하느니 앞에 적어두는 편이 낫다고 봤다. 솔직히 이것 때문에 글을 접을까도 했다.

아래 계산은 전부 지나간 봉을 사후에 훑은 것이다. 같은 판단을 실시간으로 할 수 있었다는 얘기는 어디에도 없다.

지표 정의: 신고가/신저가를 숫자로 만들기

52주 신고가/신저가는 이름 그대로다. 오늘 종가가 최근 N거래일 종가 중 최고치면 “신고가”, 최저치면 “신저가"다. 수식으로 쓰면 이렇다.

계산식
RollingHigh_N(t)  = max( Close[t-N+1 : t+1] )
RollingLow_N(t)   = min( Close[t-N+1 : t+1] )
 
신고가 신호       Close[t] >= RollingHigh_N(t)
신저가 신호       Close[t] <= RollingLow_N(t)
 
구간 내 위치%     ( Close[t] - RollingLow_N(t) )
            / ( RollingHigh_N(t) - RollingLow_N(t) ) * 100

N은 252(1년)가 정석이다. 국내 매체가 흔히 쓰는 “52주 신고가"도 이 값이다. numpy로 직접 롤링 최대/최소를 구현했고(라이브러리 함수는 쓰지 않았다), 종가 기준으로 계산했다. 고가/저가(H/L) 기준으로 하면 변동성이 더 크게 잡히는데, 실전에서 매매 신호로 쓰기엔 종가 기준이 더 잡음이 적어서 이쪽을 기본으로 택했다.

실제로 두 기준의 차이도 이번 표본에서 꽤 컸다. 종가 기준 최고가는 6월 22일의 1,970,000원이지만, 장중 고가 기준으로는 6월 23일 2,189,000원까지 찍혔다. 저가 쪽도 같다. 종가 기준 최저는 7월 30일 799,000원인데, 장중 저가 기준으로는 7월 29일 768,000원이 더 낮다. 종가와 고저가 사이에 적게는 4.04%(저점), 많게는 11.12%(고점)의 괴리가 있었다. 장중 기준으로 지표를 짜면 신호가 하루 더 일찍, 더 극단적인 값에서 뜬다. 어느 쪽이 “옳다"기보다는, 체결 기준(종가)으로 볼지 스침 기준(고저가)으로 볼지의 선택 문제다. 이 글은 종가로 통일했다.

파라미터를 왜 20/40/58로 바꿨나

원래 계획은 60일/120일/252일 세 구간을 비교하는 거였다. 무산됐다. stockanalysis.com에서 받아온 일봉이 58거래일(2026-05-22~08-14)에서 끊겼다. 사이트의 히스토리 테이블은 “Page 1 of 3"라고 표시하는데, 실제로는 자바스크립트 클라이언트 페이지네이션이라 URL 파라미터(?p=, ?range=, ?page=)를 어떻게 바꿔도 서버는 같은 첫 페이지만 돌려줬다. 그나마 건진 게 캐시다. 서로 다른 시점(8월 4일 장중 vs 8월 14일 마감 후)에 걸린 두 번의 요청에서 우연히 5월 22일까지의 데이터가 딸려 왔고, 두 요청의 값이 소수점까지 같아서 쓰기로 했다. 그래서 60/120/252일 대신 20일(약 1개월)·40일(약 2개월)·58일(표본 전체)로 바꿔 민감도를 봤다. 252일에 한참 못 미치니 “진짜 52주 신고가"라 부르기는 어렵다. 그래도 창이 짧아질수록 신호가 얼마나 과민해지는지는 이 세 구간으로도 드러난다.

실제 값: 6월의 신고가, 7월의 반토막

전체 그림부터.

SK스퀘어 일봉 개요

58거래일 동안 종가는 5월 22일 1,185,000원에서 시작해 6월 22일 1,970,000원(구간 내 최고 종가)까지 66.24% 뛰었다. 장중 최고가는 6월 23일의 2,189,000원이다. 이후 7월 30일 종가 799,000원(구간 내 최저 종가)까지 고점 대비 -59.44% 빠졌고, 장중 최저가는 7월 29일 768,000원이었다. 8월 14일 종가는 1,154,000원으로, 저점 대비 +44.43% 반등한 상태로 이 글의 관측 구간이 끝난다.

수집한 시세는 일봉 안에서 앞뒤를 맞춰봤다. 6월 23일은 시가 1,972,000원에 열려 장중 2,189,000원까지 올랐다가 종가 1,832,000원으로 끝났다. 고가에서 종가까지 -16.31%, 전일 종가 1,970,000원 대비로는 -7.01%다. 사상 최고가를 새로 쓴 당일에 상승분을 전부 반납했다는 뜻이다. 7월 13일은 전일(7월 10일) 종가 1,409,000원에서 1,161,000원으로 -17.60% 마감했다. 8월 4일은 저가 999,000원, 고가 1,096,000원, 종가 1,060,000원으로 하루 변동폭이 종가의 9.15%였다. 한 종목의 일봉이 이 정도로 벌어지는 구간이었다.

거래량을 겹쳐 보면 이 구간의 성격이 더 뚜렷해진다. 58거래일 중 거래량이 가장 많았던 날은 6월 23일(2,537,921주)이다. 하필 신고가를 찍고 무너진 그날이다. 반대로 8월 10일(410,006주)과 8월 11일(473,242주)은 표본 내 최저 거래량 구간으로, 급락 뒤 관망세가 짙어졌던 시점과 겹친다. “거래량을 동반한 신고가는 위험하고, 거래량이 마른 뒤의 바닥은 진짜에 가깝다"는 경험칙이 이번에도 어긋나지 않았다.

20일 창으로 본 신고가/신저가선

52주 신고가/신저가 프록시

N=20으로 그리면 신호가 두 국면에서만 나온다. 6월 22일 한 번의 신고가, 그리고 7월 13일부터 30일까지 총 여섯 번의 신저가(정확히는 그중 마지막 다섯 개가 40일 창에서도 재현된다). 20거래일 창이 처음 유효해지는 시점(6월 22일)이 하필 이 표본의 최고점과 겹치는 바람에, “창이 열리자마자 신고가"라는 다소 극단적인 그림이 됐다. 이건 표본이 짧아서 생기는 왜곡이다. 종목의 성격과는 상관이 없다.

위치(%)로 다시 본다. 감이 더 잘 온다.

구간 내 위치 오실레이터

6월 22일 100%(신고가)에서 출발해 7월 30일 0%(신저가)까지 거의 일직선으로 내려갔다가, 8월 초 한 차례 반등(8/5, 52.46%)한 뒤 다시 20%대로 눌리고, 8월 14일 78.19%까지 재차 튀어 오른다. 위치 지표만 보면 “롤러코스터"라는 말이 딱 맞는다.

2026-08-14 현재 값 (N=20)
종가          1,154,000원
20일 최고종가  1,253,000원 (2026-07-21 기록, 창 안에 유효)
20일 최저종가  799,000원 (2026-07-30 기록, 창 안에 유효)
구간 내 위치  78.19%
 
50~100%: 상단 근접 20~50%: 중립 0~20%: 하단 근접

신호 전수: 맞은 것과 틀린 것

N=20 기준으로 잡히는 신호는 총 7개다. 각 신호가 나온 뒤 5거래일 후 종가가 유리한 방향으로 움직였는지를 “적중” 기준으로 삼았다. 신고가 신호는 5일 뒤 더 올랐으면 적중, 신저가 신호는 5일 뒤 더 올랐으면(반등했으면) 적중이다.

신호 발생 후 5거래일 수익률

6월 22일, 신고가 (종가 1,970,000원) → 5거래일 후(6/29) 1,640,000원, -16.75%. 오답. 신고가를 찍은 바로 다음 날(6/23) 종가가 1,832,000원으로 -7.01% 밀리며 무너지기 시작한 자리다. 전형적인 “신고가 직후 급락"형 함정.

  • 7월 13일, 신저가 (종가 1,161,000원) → 7/21 1,253,000원, +7.92%. 정답.
  • 7월 24일, 신저가 (종가 1,109,000원) → 7/31 1,038,000원, -6.40%. 오답. 반등은커녕 더 밀렸다.
  • 7월 27일, 신저가 (종가 1,096,000원) → 8/3 1,025,000원, -6.48%. 오답. 이틀 연속 “신저가 찍고 더 빠짐” 패턴.
  • 7월 28일, 신저가 (종가 925,000원) → 8/4 1,060,000원, +14.59%. 정답.
  • 7월 29일, 신저가 (종가 850,000원) → 8/5 1,119,000원, +31.65%. 정답. 이 구간에서 가장 강한 반등.
  • 7월 30일, 신저가 (종가 799,000원, 구간 내 최저) → 8/6 970,000원, +21.40%. 정답.

7개 신호 중 4승 3패(57.14%)다. 신고가 신호는 1전 1패, 신저가 신호는 4승 2패. 7개로 통계를 말할 수는 없다. 그래도 이 구간에서 “신고가 추격매수"보다 “신저가 저가매수"가 더 잘 먹힌 건 사실이다. 7월 24일과 27일 두 번의 오답이 보여주듯 신저가라고 무조건 반등하지도 않는다. 진짜 바닥(7/30)이 오기 전까지 “가짜 바닥"이 최소 두 번 있었다.

파라미터 민감도: 창을 늘리면 신호가 사라진다

창 길이별 신고가/신저가선 비교

창 길이별 신호 발생 빈도

창 길이별 신호 발생 횟수
N=20일  신고가 1회 · 신저가 6회 (총 7회)
N=40일  신고가 0회 · 신저가 5회 (총 5회)
N=58일  신고가 0회 · 신저가 0회 (표본 마지막 날만 유효, 조건 미충족)

N을 40으로 늘려봤다. 7월 13일 신저가 신호(가장 먼저 나온, 그리고 유일하게 적중한 축에 드는 신호)가 사라진다. 창이 넓어지면서 7월 13일의 1,161,000원이 “40일 중 최저"가 아니게 되기 때문이다. N=58, 즉 표본 전체를 창으로 쓰면 신호가 아예 0개다. 창이 표본 크기와 같아지는 순간, 마지막 거래일 딱 하루만 조건이 성립할 수 있는데 그 하루(8/14, 종가 1,154,000원)는 최고치도 최저치도 아니었다. 이건 이 지표의 근본적인 약점을 보여준다. 창을 늘릴수록 지표는 “안정"되는 대신 “무뎌진다.” 진짜 252일 창을 썼다면 이번 급등락 전체가 그저 “장기 신저가 근처에서 오르내리는 잡음"으로 뭉개져 보였을 수도 있다. 짧은 창이 과민하다면, 긴 창은 둔감하다. 이 트레이드오프에 정답은 없고, 어느 쪽을 감수할지는 매매 스타일이 정한다.

52주 신고가/신저가라는 이름값에 비해 이 지표는 창 길이에 놀랄 만큼 예민하다. 국내 매체가 “52주 신고가"라고 단정해 보도할 때 그 뒤에는 252거래일이라는 고정된 기준이 깔려 있다. 어떤 스크리너가 임의로 200일이나 300일을 쓴다면, 같은 종목의 같은 날짜에 대해 신고가 판정이 통째로 뒤집힐 수 있다. 이 글에서 20일과 40일 사이에 신호 개수가 7개에서 5개로, 40일과 58일 사이에 5개에서 0개로 뚝뚝 떨어진 게 그 증거다. 창 길이를 무심코 넘기고 “52주 신고가"라는 헤드라인만 보면, 그 헤드라인을 만든 기준을 모른 채 신호를 받아들이게 된다.

이 지표를 봇 게이트에 넣을까

지금 운영 중인 업비트 자동매매 봇의 진입 게이트에는 넣지 않기로 했다. 이유는 세 가지다.

첫째, 이 지표는 방향을 알려주지 않는다. 신고가가 추세 지속 신호일 수도, 이번 6월 22일처럼 소진 신호일 수도 있다는 게 이번 데이터로 다시 확인됐다. 게이트는 “걸러내는” 역할을 해야 하는데, 이 지표 혼자서는 걸러내는 방향을 정할 수 없다.

둘째, 반응 속도와 표본 크기의 트레이드오프가 봇의 4슬롯 운용과 안 맞는다. 짧은 창은 신호가 잦지만 가짜가 섞이고(7/24, 7/27 오답), 긴 창은 신호가 아예 안 나온다(N=58에서 0회). 봇은 하루에도 여러 번 종목을 스캔해야 하는데, 이렇게 극단적으로 갈리는 파라미터는 안정적인 슬롯 배분과 상성이 나쁘다.

셋째, 이미 쓰고 있는 과매도 눌림목 로직과 개념이 겹친다. RSI·저점근접 게이트가 사실상 “단기 신저가 근처에서 반등을 노린다"는 이번 신저가 신호의 아이디어를 이미 담당하고 있다. 여기에 52주 신고가/신저가를 그대로 얹으면 같은 신호를 두 번 세는 꼴이 된다. 대신, 신고가 돌파 직후 거래량이 급증하며 되밀리는 패턴(6/23의 253만주 거래량 급락)을 걸러내는 필터로 참고할 여지는 있어 보인다. 다음에 거래량 지표를 다룰 때 이어서 검증해볼 생각이다.

결론이랄 것도 없는 정리

세 가지가 남았다.

신고가는 그날의 사실일 뿐이다. 6월 22일의 신고가는 상승의 확인이 아니었다. 소진의 신호였다. 지표가 “신고가"라고 말해주는 건 오늘 가격이 최근 구간에서 가장 높다는 사실뿐이고, 내일에 대해서는 침묵한다.

신저가는 두 번 속인 뒤에야 진짜였다. 7월 24일과 27일의 신저가는 하락의 중간 기착지였다. 진짜 바닥(7/30)이 오기까지 시장은 저가매수를 두 번 배신했다. 신저가에서 무조건 사는 전략은 이 배신을 견딜 자금과 인내를 요구한다.

창을 늘린다고 지표가 정직해지지는 않는다. N=58에서 신호가 0개였다는 사실은 “긴 창이 더 신뢰할 만하다"는 통념에 균열을 낸다. 긴 창은 둔감하다. 무엇을 놓치고 무엇을 잡을지는 창 길이를 정하는 사람이 결정한다. 지표 자체의 객관성과는 별개다.

윌리엄 오닐은 CANSLIM 전략에서 “최고의 주식은 신고가를 경신하면서 계속 신고가를 경신한다"고 했다. 싸다고 사지 말고 강한 종목이 더 강해지는 자리에서 사라는 얘기다. 원론적으로 맞다. 실제로 강세장을 이끄는 종목들은 신고가 부근에서 계속 신고가를 새로 쓴다. 하지만 이번 SK스퀘어의 6월 22일은 그 반대편 사례였다. “신고가를 경신하면서 계속 신고가를 경신하는” 종목과 “신고가를 찍고 바로 꺾이는” 종목을 지표 하나만으로는 구분할 수 없다는 게 이번 데이터가 준 교훈이다. 오닐의 말을 실전에 옮기려면 신고가 자체와 함께 그것을 지지하는 거래량, 그 뒤의 되돌림 폭까지 같이 봐야 한다. 그 작업은 이번 글에서 못 했다.

이번 58거래일은 “지표를 믿는다"는 말이 얼마나 애매한 표현인지 다시 확인시켜준 구간이었다. 신고가 신호를 믿었다면 6월 22일에 사서 5거래일 만에 -16.75%를 봤을 것이고, 신저가 신호를 매번 믿었다면 7월 24일과 27일 두 번의 오답을 버텨야 진짜 반등(7월 28일 이후)까지 도달할 수 있었다. 지표는 진입 타이밍의 후보를 좁혀줄 뿐, 그 신호를 붙잡고 버틸지 손절할지는 결국 손절선과 자금관리의 몫이다. 봇을 만들면서 매번 확인하는 사실이지만, 지표 하나가 매매 규율을 대신해주지는 않는다.

다음 편은 이번 글에서 미뤄둔 숙제다. 거래량이 신고가/신저가의 신뢰도를 얼마나 보정해주는지 다뤄볼 생각이다. 6월 23일의 253만주짜리 거래량 급락과 7월 29일의 강한 반등 거래량을 나란히 놓고 비교해볼 예정이다.

이 글의 모든 수치는 stockanalysis.com에서 수집한 58거래일치 실제 일봉 데이터를 numpy로 직접 계산한 값이고, 손익이나 승률을 임의로 만들어낸 곳은 없다. 매매를 권하려고 쓴 글도 아니다. 지나간 데이터를 계산한 결과일 뿐이라 앞으로의 수익과는 아무 관계가 없다. 그래도 표본이 진짜 52주(252거래일)에 한참 못 미친다는 건 계속 마음에 걸린다. 그 데이터를 어디서 어떻게 구할지, 아직 못 정했다.


약어 풀이

* 이 글에 나온 영어 약어를 풀어 둔다.

  • RSI (Relative Strength Index): 상대강도지수. 일정 기간 평균 상승폭과 평균 하락폭의 비율을 0~100 으로 나타내 과매수·과매도를 재는 모멘텀 오실레이터.
  • MACD (Moving Average Convergence Divergence): 이동평균 수렴·확산. 단기 EMA 와 장기 EMA 의 차이(MACD선)와 그 이동평균(시그널선)으로 추세와 모멘텀을 본다.
  • H/L (High/Low): 고가/저가.
  • HTS (Home Trading System): 홈트레이딩시스템. 증권사가 제공하는 PC 매매 프로그램.
  • NAV (Net Asset Value): 순자산가치. 지주회사가 가진 자산의 시가에서 부채를 뺀 값. 주가가 이보다 낮으면 NAV 할인.
  • IBD (Investor’s Business Daily): 미국의 투자 일간지. 52주 신고가 종목 리스트와 CANSLIM 기법으로 알려져 있다.
  • CANSLIM (C·A·N·S·L·I·M): 윌리엄 오닐의 성장주 선정 기법. 분기 실적(C)·연간 실적(A)·신제품/신고가(N)·수급(S)·주도주(L)·기관 매수(I)·시장 방향(M) 일곱 조건의 머리글자.
  • URL (Uniform Resource Locator): 웹 주소.
  • KRX (Korea Exchange): 한국거래소. 코스피·코스닥을 운영하는 국내 유일의 증권 거래소.