NOONOO TRADING봇에서 시작하기

지표 워밍업 — 봇을 켠 직후에 낸 주문이 가장 위험한 이유

봇을 켜면 코드는 곧바로 돌기 시작합니다. 그런데 지표는 아직 준비되지 않았습니다. 이동평균도 ATR도 과거 봉을 먹고 계산되는데, 방금 켠 봇에는 그 과거가 없습니다. 이 상태에서 나가는 첫 몇 건이 이상하게 자주 깨지는 이유가 여기에 있습니다.

지표는 과거 봉을 먹고 산다

기간 200짜리 이동평균은 이름 그대로 최근 200개의 종가가 있어야 값이 나옵니다. 봉이 50개뿐이면 200봉 평균은 계산할 수 없습니다. 여기까지는 누구나 압니다. 문제는 그다음입니다. 많은 라이브러리가 봉이 모자라도 숫자를 돌려줍니다. 있는 것만으로 평균을 내서 값을 줍니다.

그래서 화면에는 이동평균선이 그려지고, 조건문은 통과하고, 주문은 나갑니다. 어디에도 오류가 뜨지 않습니다. 봇이 준비되지 않았다는 사실을 아무도 모르는 채로 매매가 시작됩니다.

이 문제는 봇을 처음 켤 때만 생기는 것이 아닙니다. 코드를 고쳐 배포할 때마다, 정전이 날 때마다, 프로그램이 죽어서 다시 뜰 때마다 반복됩니다. 봇 재시작이 포지션 기억을 잃는 문제라면, 이쪽은 지표 기억을 잃는 문제입니다.

필요한 봉 수는 기간 숫자와 다르다

단순이동평균(SMA)은 계산이 명확합니다. 기간 200이면 200봉이 있어야 하고, 200봉이 모이는 순간부터 정확한 값이 나옵니다. 그런데 실제로 많이 쓰는 지표는 이렇게 딱 떨어지지 않습니다.

지수이동평균(EMA)은 과거를 잘라내지 않고 가중치를 점점 줄여가며 계속 반영합니다. 끝이 없다는 뜻입니다. 그래서 "몇 봉이면 충분한가"는 초기값의 영향이 얼마나 줄었느냐로 봐야 합니다.

EMA200이 안정되는 봉 수

평활계수 α = 2 ÷ (200 + 1)
  = 0.00995

n봉 뒤 초기값이 남은 비율
  (1 − α)ⁿ

이 값이 1% 아래로 내려가려면
  0.99005ⁿ < 0.01
  n = ln(0.01) ÷ ln(0.99005)
  = 4.605 ÷ 0.01
  ≈ 461봉

─────────────
기간은 200인데 필요한 봉은 461개다

기간 숫자의 두 배가 넘습니다. 200봉만 채우고 "이제 준비됐다"고 판단하면, 그때의 EMA200에는 처음 넣은 값의 영향이 아직 13% 정도 남아 있습니다. 처음 넣은 값이 보통 첫 봉의 종가이거나 0이므로, 그만큼 선이 엉뚱한 자리에 있습니다.

ATR과 RSI도 같은 구조입니다. 이 둘은 대개 와일더 방식으로 평활하는데, 평활계수가 기간 분의 1입니다.

ATR(14)·RSI(14)가 안정되는 봉 수

평활계수 α = 1 ÷ 14 = 0.0714

초기값 영향이 1% 아래로
  0.92857ⁿ < 0.01
  n = 4.605 ÷ 0.0741
  ≈ 63봉

14봉으로 계산을 시작하면
  초기값 영향이 35% 남아 있다

─────────────
기간 14, 필요한 봉 63개

ATR은 손절 폭이나 포지션 크기를 정하는 데 쓰는 경우가 많습니다. ATR이 실제보다 작게 나오면 손절을 너무 가깝게 잡게 되고, 크게 나오면 수량을 너무 줄이거나 늘리게 됩니다. ATR 값 하나가 틀리면 그 뒤의 계산이 전부 틀립니다.

가장 긴 것 하나가 전체를 결정한다

전략이 지표를 여러 개 쓰면, 준비 완료 시점은 가장 늦게 준비되는 지표가 결정합니다. 하나라도 덜 채워져 있으면 그 조건식은 믿을 수 없습니다.

필요 봉 수 산정 (가정)

쓰는 지표
  EMA200  → 461봉
  ATR(14)  → 63봉
  거래량 60봉 평균 → 60봉

가장 긴 것
  461봉

여유 1.2배
  461 × 1.2 ≈ 554봉

봉 주기로 환산하면
  1분봉  554분 = 9.2시간
  5분봉  2,770분 = 46시간

─────────────
5분봉 전략은 이틀 가까이 준비해야 한다

5분봉으로 46시간이면, 켜 놓고 기다리는 방식으로는 감당이 안 됩니다. 일주일에 두 번만 재배포해도 봇은 거의 항상 준비 중인 상태가 됩니다. 그래서 켜고 기다리는 것이 아니라 기동할 때 과거 봉을 받아와 채우는 방식으로 가야 합니다. 대부분의 거래소가 과거 봉 조회를 지원합니다. 요청 단위와 한도는 거래소 API 연동 가이드 쪽에 정리돼 있습니다.

덜 채워진 지표가 조건을 뒤집는다

"조금 부정확한 정도면 괜찮지 않나" 싶지만, 조건식은 대소 비교라서 조금만 어긋나도 결과가 통째로 바뀝니다.

창 길이가 평균값을 바꾸는 폭 (가정)

가격이 1봉당 +0.02%씩 오르는 구간
현재가  $100.00

평균은 창 중앙쯤에 놓인다
  SMA50  = 현재가 − 0.02% × 24.5
    = $99.51
  SMA200 = 현재가 − 0.02% × 99.5
    = $98.01

차이
  0.02% × 75 = 1.5%

가격이 $99.00일 때
  50봉짜리 기준  가격 < 평균 → 숏 조건
  200봉짜리 기준 가격 > 평균 → 롱 조건

─────────────
같은 순간에 방향이 정반대로 나온다

봉이 50개뿐인 봇은 스스로 "200봉 평균"이라고 부르는 값을 계산하지만, 실제로는 50봉 평균입니다. 그리고 그 값으로 반대 방향에 진입합니다. 오류 메시지는 없습니다. 이동평균선이 무엇을 재는 도구인지와 무관하게, 재는 창이 다르면 다른 지표입니다.

추세가 강할수록 차이가 커진다는 점도 중요합니다. 위 계산에서 봉당 상승률이 0.04%면 차이는 3%가 됩니다. 조용한 장에서는 티가 안 나다가 큰 추세가 시작될 때 가장 크게 틀리는 구조입니다.

준비될 때까지는 주문을 내지 않는다

해결 방법 자체는 단순합니다. 지표가 준비됐는지를 숫자로 판정하고, 준비 전에는 신규 진입을 막습니다.

기동 절차

① 필요 봉 수를 계산해 상수로 박는다
  위 예시라면 554

② 기동 시 과거 봉을 받아 채운다
  554개보다 적게 받아지면 실패로 처리

③ 실제 보유 봉 수를 센다
  받아진 개수 ≥ 554 인지 확인

④ 준비 전이면 신규 진입만 차단
  보유분 손절·익절은 그대로

⑤ 준비 완료를 로그에 한 줄 남긴다
  몇 봉으로 시작했는지 같이

─────────────
③을 빼면 나머지가 다 무의미해진다

④가 킬 스위치의 신규 차단 단계와 같은 동작이라는 점을 이용하면 구현이 간단해집니다. 준비가 안 됐으면 스위치가 내려간 것과 같은 상태로 두면 됩니다. 다만 이때 보유 포지션의 손절까지 같이 끄면 안 됩니다. 손절은 지표가 아니라 가격으로 판단하므로 워밍업과 무관하게 살려 둡니다.

③을 실제로 세는 것이 핵심입니다. 과거 봉 요청은 조용히 적게 돌아올 때가 많습니다. 거래소가 한 번에 주는 개수에 상한이 있거나, 상장한 지 얼마 안 된 종목이라 과거가 아예 없거나, 그 구간에 결측이 있는 경우입니다. 받아온 개수를 세지 않으면 300개만 받아 놓고 준비 완료라고 판단합니다. 받아온 데이터에 구멍이 있는지 보는 방법은 백테스트 가격 데이터 품질 쪽에 있습니다.

백테스트에서는 잘 안 보인다

이 문제가 오래 살아남는 이유가 있습니다. 백테스트에서는 잘 드러나지 않기 때문입니다. 대개 데이터를 통째로 불러온 뒤 처음부터 끝까지 훑는 구조라, 워밍업 구간이 전체의 아주 작은 부분입니다. 3년치 데이터에서 앞의 554봉은 성적에 거의 영향을 주지 않습니다.

반면 실전에서는 재시작할 때마다 워밍업이 다시 시작됩니다. 백테스트에서는 한 번뿐이던 구간이 실전에서는 수십 번 반복됩니다. 백테스트와 실전 성적이 벌어지는 원인 중 조용한 축이 이것입니다. 백테스팅 단계에서 이 차이를 보려면, 재시작을 흉내 내서 구간을 잘라 돌려보는 방법이 있습니다.

정리

봇은 켜자마자 돌지만 지표는 준비되지 않았다
라이브러리는 봉이 모자라도 숫자를 돌려준다
그래서 오류 없이 잘못된 값으로 매매가 시작된다
SMA200은 200봉이면 되지만 EMA는 다르다
EMA200은 초기값 영향 1% 기준 약 461봉이 필요하다
200봉 시점에도 초기값 영향이 13% 남아 있다
ATR(14)·RSI(14)는 14봉이 아니라 약 63봉이다
14봉 시점의 초기값 영향은 35%다
준비 시점은 가장 긴 지표가 결정한다
여유 1.2배를 얹으면 554봉, 5분봉이면 46시간이다
그래서 기다리지 말고 과거 봉을 받아 채운다
50봉 평균과 200봉 평균은 추세 구간에서 1.5% 벌어진다
그 차이로 롱 조건과 숏 조건이 뒤집힌다
받아온 봉 개수를 반드시 세고 판정한다
준비 전에는 신규만 막고 손절은 살려 둔다

한 줄로 줄이면 이렇습니다. 봇이 켜졌다는 것과 봇이 준비됐다는 것은 다릅니다. 그 둘을 같은 것으로 취급하는 코드가 재시작할 때마다 조용히 손실을 만듭니다.

주의

본문의 EMA200 평활계수 0.00995와 필요 봉 수 461개, 200봉 시점의 잔여 영향 13%, ATR·RSI(14)의 평활계수 0.0714와 63봉·잔여 35%, 여유 1.2배와 554봉, 1분봉 9.2시간·5분봉 46시간, 봉당 상승률 0.02%와 SMA50 $99.51·SMA200 $98.01·차이 1.5%, 가격 $99.00에서 방향이 갈리는 예시 같은 수치는 워밍업 길이를 산정하는 계산 구조를 보여주기 위한 가정 예시입니다. "초기값 영향 1% 이하"라는 기준 자체가 임의로 정한 선이며, 더 엄격하게 잡으면 필요한 봉 수는 더 늘어납니다. 지표의 초기값 처리 방식은 라이브러리마다 달라(첫 값을 단순평균으로 잡는 구현도 있습니다) 실제 수렴 속도가 위 계산과 다를 수 있으므로, 쓰는 라이브러리의 문서와 코드를 직접 확인하십시오. 평균이 창 중앙에 놓인다는 계산은 가격이 일정한 기울기로 움직인다는 가정에서만 성립하며 실제 시세에서는 다릅니다. 워밍업을 제대로 맞춘다고 해서 전략이 수익을 내지는 않습니다. 이 글은 자동매매 구현에 대한 설명이며 특정 종목·방향이나 진입·청산 시점을 권유하지 않습니다. 암호화폐 거래는 원금 전액을 잃을 수 있고 레버리지를 쓰면 손실이 증거금을 넘을 수도 있습니다. 투자 판단과 그 결과는 본인 책임입니다.

NOONOO TRADING 무료 채팅방에서 실시간 트레이딩을 같이 보세요.

봇에서 시작하기

📈 OKX 신규 가입 시 거래 수수료 할인

OKX 수수료 할인 가입 →