거래소를 옮긴 이유
빗썸에서 쓰던 엔진을 업비트로 옮겼습니다. 업비트 봇이 갑자기 툭 튀어나온 것처럼 보이는 이유가 이겁니다 — 처음부터 만든 게 아니라 이식한 거예요. 그래서 초기 업비트 코드에는 빗썸 시절 흔적이 여기저기 남아 있습니다.
옮긴 이유는 몇 가지가 겹쳤습니다. 종목 수, 유동성, 그리고 API 문서의 친절함. 특히 마지막 게 컸어요. 앞 시대에서 인증 규격 하나 때문에 몇 시간을 태운 경험이 있으니, 문서가 명확한 쪽이 개발 속도에서 유리하다는 걸 알고 있었습니다.
이 시대 이름을 MA봇이라고 붙인 건 진입 판단을 이동평균 교차에 맡겼기 때문입니다. 짧은 이동평균이 긴 이동평균을 위로 뚫으면 산다는, 교과서에 제일 먼저 나오는 그 방식이요.
단기선이 장기선을 위로 교차 → 매수
단기선이 장기선을 아래로 교차 → 매도
--------------------------------------------------
장점 구현이 단순하다 (몇 줄)
판정이 명확하다 (교차했나 안 했나)
→ 봇으로 만들기에 최적
단점 후행 지표다 (이미 오른 뒤에 신호)
횡보장에서 신호가 계속 나온다
--------------------------------------------------
결국 이 단점이 다음 시대의 전략 전환 이유가 된다이동평균을 고른 건 그게 좋아서가 아니라 코드로 옮기기 쉬워서였습니다. 교차했나 안 했나는 부등호 하나로 판정됩니다. 애매한 구간이 없어요. 자동매매를 처음 만들 때 이 성질이 굉장히 매력적입니다. 사람의 해석이 필요한 지표는 봇으로 옮기는 순간 무너지거든요.
봇이 종목을 고르기 시작했습니다
이 시대의 진짜 사건은 이동평균이 아니라 스캔입니다. 그전까지는 제가 종목을 정해주면 봇이 그 종목만 감시했어요. 그런데 남아 있는 가장 이른 버전(v032)에는 이미 “CROSS SCANNING"이라는 문구와 함께 슬롯 UI가 들어 있습니다. 즉 수동 지정에서 자동 스캔으로 넘어간 순간은 v032 이전인데, 그 파일이 안 남아 있습니다. 이 봇 역사에서 가장 아쉬운 공백입니다.
v034에서는 업비트 market/all을 호출해 전 종목을 긁어오는 코드가 확인됩니다. 몇백 개 종목을 매번 훑는 구조로 넘어간 거죠.
이전 내가 종목 지정 → 봇은 그 종목만 감시
문제: 종목 선택이라는 제일 어려운 판단이 여전히 내 몫
이후 market/all 전 종목 조회 → 조건 맞는 것만 추림 → 슬롯에 배치
이때 생긴 개념들이 지금도 그대로 살아 있다:
슬롯 동시에 몇 개까지 들고 갈지 (현재 4개)
블랙리스트 건드리지 않을 종목 목록
상태 저장 봇이 죽었다 살아나도 포지션을 기억이 전환이 왜 결정적이냐면, 제일 어려운 판단을 봇에게 넘긴 것이기 때문입니다. 매매에서 가장 어려운 건 언제 팔지가 아니라 무엇을 살지예요. 종목을 제가 고르는 한, 봇은 제 판단의 실행 도구일 뿐입니다. 감정을 배제하려고 만든 봇인데 가장 감정적인 결정을 제가 하고 있었던 거죠.
스캔으로 넘어가면서 문제의 성격도 바뀝니다. 이전에는 “이 종목을 언제 살까"였는데, 이후에는 “수백 개 중에 어떤 조건을 만족하는 것만 추릴까"가 됩니다. 후자는 규칙으로 쓸 수 있는 문제예요. 지금 봇의 게이트 열 개가 하는 일이 정확히 이 추리기 작업입니다.
슬롯, 블랙리스트, 상태 저장
슬롯, 블랙리스트, 상태 저장. 이 세 가지는 이때 만들어져서 461개 버전을 지나 지금까지 형태만 바뀐 채 살아 있습니다.
슬롯은 앞 시대에서 개념이 나왔지만, 스캔과 만나면서 진짜 역할을 하게 됩니다. 전 종목을 훑으면 조건에 맞는 종목이 수십 개 나올 수 있어요. 그걸 다 사면 안 되니까 상한이 필요합니다. 그리고 상한이 있으면 그다음 질문이 자동으로 따라옵니다 — 어떤 순서로 채울 것인가. 랭킹이라는 개념이 여기서 시작됩니다.
블랙리스트는 더 소박한 장치입니다. 그냥 안 건드릴 종목 목록이에요. 거래량이 지나치게 적거나, 특정 사유로 손대고 싶지 않은 종목을 빼둡니다. 조건으로 거르는 게 정석이지만, 조건으로 표현하기 어려운 판단도 있습니다. 그럴 땐 목록이 답이에요.
상태 저장은 셋 중 가장 중요했습니다.
[ 상태 저장 없음 ]
봇 재시작 → 보유 현황 초기화
→ 이미 들고 있는 종목을 또 산다
→ 슬롯 계산이 어긋난다
→ 손절 기준가를 모른다 (얼마에 샀는지 잊음)
[ 상태 저장 있음 ]
보유 종목 · 진입가 · 진입 시각을 파일로 기록
재시작 시 복원 → 이어서 관리
————————————————–
봇이 죽는 건 예외가 아니라 일상이다
봇이 죽는 건 언제든 일어나는 일이고, 죽었다 살아났을 때 자기가 뭘 들고 있는지 모르면 그때부터 사고가 시작됩니다. 특히 진입가를 잊는 게 치명적이에요. 손절선은 진입가 기준으로 계산되는데, 진입가를 모르면 손절 자체가 불가능합니다. 들고는 있는데 언제 잘라야 할지 모르는 포지션이 되는 거죠.
이 상태 저장이 나중에 훨씬 엄격한 형태로 진화합니다. 봇이 저장한 상태와 거래소가 알려주는 실제 보유 현황을 대조하고, 어긋나면 배포를 막는 규칙으로요. 자기 기억을 기록으로 남기는 단계에서 자기 기억을 외부와 대조하는 단계로 가는 데 시대가 네 개 더 걸립니다.
랭킹이라는, 예상 못 한 문제
슬롯이 네 개인데 조건에 맞는 종목이 스무 개 나오면 어떻게 할까요. 이게 스캔으로 넘어가면서 새로 생긴 문제입니다.
가장 단순한 답은 “먼저 발견한 순서대로"입니다. 그런데 이러면 봇이 종목 목록을 훑는 순서가 곧 매매 결정이 돼버려요. 목록이 알파벳 순이면 알파벳 앞쪽 종목만 사게 됩니다. 아무 근거 없는 편향이죠.
조건 통과 종목 20개 · 빈 슬롯 4개
--------------------------------------------------
[ 발견 순서대로 ] 목록 정렬 방식이 곧 매매 결정
근거 없는 편향
[ 무작위 ] 재현이 안 된다
같은 상황에 다른 결과 → 검증 불가
[ 점수순 ] 조건들을 점수로 합쳐 정렬
→ 재현 가능 · 근거 설명 가능
--------------------------------------------------
다만 점수 산식 자체가 새로운 튜닝 대상이 된다점수순이 맞는데, 여기서 함정이 하나 있습니다. 점수 산식이 그럴듯하다고 좋은 게 아니라는 것이에요. 여러 조건을 가중치로 합쳐 점수를 만들면 논리적으로 보입니다. 그런데 실제 결과와 대조해보면 점수가 높은 종목이 오히려 성적이 나쁜 경우가 나옵니다. 이 시대에는 그걸 확인할 데이터가 없었어요.
나중에 매매기록으로 검증할 수 있게 되고 나서야, 산식 안의 어떤 가점 항목이 반대로 작동하고 있다는 걸 발견합니다. 그럴듯한 논리로 만든 가점이 실제로는 나쁜 종목을 앞으로 끌어올리고 있었던 거죠. 지금 랭킹 산식이 훨씬 단순한 이유입니다. 검증할 수 없는 복잡함은 그냥 위험이더군요.
이동평균을 코드로 옮기면 생기는 것들
교과서에서는 이동평균이 한 줄입니다. 최근 N봉의 평균. 그런데 봇으로 옮기면 교과서에 안 나오는 문제들이 생깁니다.
1. 워밍업
20봉 평균을 쓰려면 최소 20봉이 있어야 한다
신규 상장 종목은 데이터가 부족 → 계산 불가
→ 봉 수 부족 종목은 후보에서 제외
2. 진행 중인 봉
지금 만들어지는 중인 봉을 포함할 것인가
포함하면 판정이 몇 초마다 뒤집힌다
→ 완성된 봉만 사용
3. 교차의 정의
“위로 뚫었다” 를 어떻게 판정하나
직전 봉에서 아래, 이번 봉에서 위 — 한 번만 발동
→ 상태를 기억해야 한다 (조건문 하나로 안 됨)
2번이 특히 중요합니다. 진행 중인 봉을 계산에 넣으면 같은 종목이 몇 초 간격으로 “교차했다 / 안 했다"를 왔다 갔다 합니다. 봇이 그때마다 반응하면 아무것도 못 해요. 완성된 봉만 쓴다는 원칙은 이때 생겨서 지금까지 유지됩니다. 나중에 시장 상황을 판단하는 로직에서도 같은 원칙이 다시 적용돼요.
3번도 은근히 걸립니다. 교차는 순간의 사건인데 봇은 주기적으로 검사합니다. 검사 시점에 이미 교차가 끝나 있으면 놓치고, 교차 상태가 유지되는 동안 매번 검사하면 계속 신호가 납니다. 그래서 직전 상태를 기억해뒀다가 상태가 바뀌는 순간만 잡아야 해요. 지표 계산보다 상태 관리가 더 까다롭다는 걸 이때 배웠습니다.
통신을 다시 만들었습니다
v034 즈음 웹소켓을 도입합니다. 그전까지는 REST로 계속 물어보는 방식이었는데, 종목 수가 늘어나니까 감당이 안 됐어요. 몇백 개 종목을 각각 REST로 조회하면 API 제한에 걸립니다.
[ REST 폴링 ]
봇 → "BTC 얼마?" → 거래소
봇 → "ETH 얼마?" → 거래소
… 종목 수만큼 반복 …
종목이 늘면 요청 수가 비례해서 는다
→ 호출 제한에 걸린다
[ 웹소켓 ]
봇 → “이 종목들 구독할게” → 거래소
거래소 → 값이 바뀔 때마다 밀어준다
연결 하나로 다수 종목을 받는다
————————————————–
대신 새 문제가 생긴다: 연결이 끊기면 조용히 멈춘다
웹소켓은 효율은 좋은데 실패 방식이 고약합니다. REST는 요청이 실패하면 즉시 에러가 돌아오는데, 웹소켓은 연결이 끊긴 채로 조용히 아무것도 안 옵니다. 봇 입장에서는 “값이 안 바뀌는 것"과 “연결이 죽은 것"이 똑같아 보여요. 시장이 조용한 새벽에 연결이 끊기면 몇 시간을 모른 채 지나갑니다.
그래서 연결 상태 추적이 필요해집니다. 마지막으로 데이터를 받은 시각을 기록해두고, 일정 시간 이상 아무것도 안 오면 연결이 죽었다고 판단해서 재연결하는 로직이요. 이 문제는 이후에도 계속 형태를 바꿔가며 돌아옵니다. 3회 재시도, 지수 백오프, 하트비트, 연결 상태 추적 같은 것들이 순서대로 붙어요.
자동매매에서 통신 안정성은 전략만큼 중요한데, 그걸 이 시기에 데이터가 끊길 때마다 배웠습니다. 정확히 말하면 끊긴 걸 몰랐던 경험을 통해 배웠어요. 앞 시대의 “조용한 실패"가 통신 계층에서 다시 나타난 겁니다.
이식이라는 작업의 실체
“엔진을 옮겼다"는 한 문장으로 적었지만, 실제로 해보면 이식은 새로 짜는 것과 크게 다르지 않습니다. 다른 점은 무엇을 만들지 이미 안다는 것뿐이에요.
옮겨지는 것
· 구조 (읽기 → 판단 → 주문)
· 상태 관리 방식
· 화면 배치와 흐름
· 겪어본 실패의 목록 ← 제일 값지다
안 옮겨지는 것
· 인증 코드 (전면 재작성)
· 심볼·호가·최소금액 처리
· 통신 계층 (REST → 웹소켓으로 아예 교체)
· 파라미터 값 (거래소가 다르면 시장도 다르다)
마지막 항목이 은근히 중요합니다. 빗썸에서 쓰던 손절 폭이나 대기 폭을 그대로 가져오고 싶어지는데, 거래소가 다르면 유동성도 변동성도 다릅니다. 같은 -0.5% 대기가 한쪽에서는 자주 채워지고 다른 쪽에서는 거의 안 채워질 수 있어요. 값은 코드가 아니라 시장에 속한 것이라, 이사할 때 같이 안 따라옵니다.
그런데 이때는 그냥 가져왔습니다. 검증할 방법이 없었으니까요. 지금이라면 이관 직후 몇 주 동안은 값을 다시 재는 기간으로 잡았을 겁니다. 이식의 진짜 비용은 코드 작업이 아니라 값을 다시 세우는 시간이더군요.
그리고 옮겨지는 것 중 제일 값진 게 겪어본 실패의 목록이라는 걸 강조하고 싶습니다. 이 시대에 조용한 실패가 훨씬 적었던 건 코드를 잘 짜서가 아니라, 앞 시대에서 어디가 조용히 실패하는지 이미 알고 있었기 때문이에요. 주문 직전에 수량 자릿수를 고정하는 것, 통신 실패를 정상 상황으로 처리하는 것 — 이런 건 처음부터 넣었습니다. 첫 시대에서 배운 것들이니까요.
이식이 남긴 흔적들
거래소를 옮기면서 배운 실무적인 것들도 적어둡니다. 같은 로직이라도 거래소가 바뀌면 손봐야 하는 곳이 정해져 있더군요.
1. 인증 규격 서명 방식 · 헤더 이름 · 유효 시간
2. 심볼 표기 BTC / KRW-BTC / BTC-KRW … 전부 다르다
3. 호가 단위 가격대별 최소 변동폭 규칙
4. 최소 주문 금액 이 아래로는 주문 자체가 거부
5. 수량·금액 표기 소수 자릿수 · 시장가 주문의 인자
6. 호출 제한 초당 · 분당 상한
--------------------------------------------------
이 중 3·4를 놓치면 "조건은 맞는데 주문이 안 나가는" 상태가 된다3번과 4번이 특히 성가셨습니다. 호가 단위는 가격대마다 다릅니다. 어떤 구간에서는 1원 단위로 움직이고 다른 구간에서는 0.1원 단위로 움직여요. 계산한 주문 가격이 그 단위에 안 맞으면 거부됩니다. 최소 주문 금액도 마찬가지예요. 슬롯 예산을 나눴는데 그 금액이 최소 미만이면 주문이 안 나갑니다.
둘 다 앞 시대에서 배운 그 실패 유형입니다 — 조건은 다 맞았는데 주문이 조용히 거부되는 것. 그래서 이 시기에 주문 직전 검사를 붙였습니다. 호가 단위에 맞게 가격을 반올림하고, 최소 금액을 넘는지 확인하고 나서 보냅니다. 지금 봇의 게이트 열 개 중 하나가 호가 단위 검사인 건 이때의 유산이에요.
종목이 늘면 무엇이 늘어나는가
수동 지정에서 전 종목 스캔으로 가면 종목 수만 느는 게 아닙니다. 관리해야 할 것들이 같이 늘어납니다.
데이터 품질 종목마다 봉 개수가 다르다
신규 상장 · 거래 정지 · 데이터 누락
계산 비용 수백 종목 × 지표 여러 개 = 매 주기 부담
주기가 길어지면 신호가 늦는다
중복 진입 같은 종목이 여러 조건에 걸린다
한 종목을 두 슬롯에 넣으면 안 된다
재진입 방금 손절한 종목이 다시 후보로 올라온다
쿨다운이 없으면 같은 자리에서 반복 손절
--------------------------------------------------
마지막 항목이 제일 비쌌다 — 이 시대엔 쿨다운이 없었다재진입 문제가 특히 아팠습니다. 손절한 종목은 대개 가격이 내려간 상태인데, 조건에 따라서는 그게 오히려 매력적으로 보입니다. 그래서 잘라내자마자 다시 사요. 그리고 또 잘립니다. 봇은 규칙대로 하고 있는데 계좌는 같은 종목에서 계속 깎입니다.
이건 개별 조건으로는 못 막습니다. “이 종목을 방금 잘랐다"는 사실은 시장 데이터가 아니라 봇 자신의 이력이니까요. 그래서 진입 판단에 자기 이력을 넣는 로직이 필요해집니다. 지금 봇의 재진입 쿨다운이 그것이고, 이 필요성은 이 시대에 몸으로 확인했습니다.
데이터 품질 문제도 짚어둘 만합니다. 전 종목을 훑으면 반드시 이상한 종목이 섞여 들어옵니다. 봉이 몇 개 없는 신규 상장 종목, 거래가 거의 없어서 봉이 비어 있는 종목 같은 것들이요. 이런 종목에 지표를 계산하면 값이 나오긴 하는데 의미가 없습니다. 계산에 실패하는 것보다 의미 없는 값이 나오는 게 더 위험해요. 지금 봇이 진입 게이트 앞단에서 데이터 충분성부터 검사하는 이유입니다.
매뉴얼을 만들었다는 것의 의미
이 시기에 v057 매뉴얼 PDF를 만들었습니다. 나 혼자 쓰는 봇에 매뉴얼을 만든 게 좀 웃기지만, 그때 이미 봇이 제 머릿속보다 복잡해지기 시작했다는 뜻이기도 합니다.
파라미터가 늘어난다
→ 각 값이 뭘 하는지 기억이 안 난다
→ 문서를 만든다
→ 문서와 코드가 어긋나기 시작한다
→ 코드 자체가 읽히게 만들어야 한다
--------------------------------------------------
현행: 파라미터를 한 모듈에 모으고
각 값 옆에 근거 수치를 주석으로 붙인다
문서가 아니라 코드가 문서 역할을 한다문서를 만들어야 할 만큼 커진 코드는 그다음부터 관리 문제가 됩니다. 그리고 별도 문서는 반드시 코드와 어긋나요. 값을 하나 바꾸고 문서를 안 고치면 그 순간부터 문서가 거짓말을 시작합니다. 나중에 그 거짓말을 믿고 판단하면 사고가 납니다.
지금은 문서를 따로 안 만듭니다. 대신 파라미터를 한 곳에 모아두고, 각 값 옆에 그 값을 정한 근거를 적어둬요. 그리고 커밋 메시지에 시뮬레이션 결과를 같이 넣습니다. 문서가 코드 안에 있으니 어긋날 수가 없습니다. 이 방식에 도달하기까지 매뉴얼 PDF를 만들어보는 경험이 필요했습니다.
사라진 파일에 대하여
이 시대에서 제일 아쉬운 건 v032 이전이 안 남아 있다는 겁니다. 수동 지정에서 자동 스캔으로 넘어가는 그 순간의 코드가 없어요.
v001 ~ v031 없음
이 구간 어딘가에서 스캔이 도입됐다
v032 이미 "CROSS SCANNING" + 슬롯 UI 존재
v034 market/all 전 종목 조회 확인
~ v0xx 보존 48개
--------------------------------------------------
전환의 결과는 남았는데 전환의 과정이 없다왜 없어졌는지는 모릅니다. 폴더를 정리하다 지웠거나, 이관 과정에서 빠졌거나. git이 없던 시절의 대가입니다. 파일을 지우는 데 확인 절차가 없으니까요.
이 공백 때문에 이 시대의 서술에는 추정이 많습니다. 스캔이 어떤 순서로 도입됐는지, 처음에 몇 종목을 훑었는지, 슬롯 개수가 처음부터 넷이었는지 — 전부 v032 시점의 결과물로 역산한 겁니다. 확실한 건 v032에 이미 완성된 형태로 들어 있다는 것뿐이에요.
기록에서 제일 아까운 건 실패한 시도가 사라지는 겁니다. 성공한 결과는 최종 코드에 남지만, 시도했다가 접은 것들은 중간 파일에만 있어요. 그게 사라지면 “왜 이 방식이 아니라 저 방식인가"를 설명할 수 없게 됩니다. 지금 git을 쓰면서 실패한 브랜치도 지우지 않는 이유입니다.
짧지만 결정적이었던 시대
이 시대는 짧습니다. 보존된 게 48개뿐이고 기간도 일주일 남짓이에요. 그런데 하는 일이 명확했습니다 — 빗썸 시절의 “내가 정해준 종목을 봇이 감시한다"에서 “봇이 스스로 고른다"로 넘어가는 다리 역할.
구조 전 종목 스캔 → 조건 필터 → 슬롯 배치
현행 봇의 진입 파이프라인과 동일한 형태
개념 슬롯 · 블랙리스트 · 상태 저장 · 랭킹
넷 다 현재까지 살아 있음
통신 웹소켓 + 연결 상태 추적
이후 재시도·백오프로 계속 보강
숙제 이동평균은 횡보장에서 신호가 너무 많다
→ 다음 시대의 전략 실험으로 이어짐특히 진입 파이프라인의 형태가 여기서 굳었다는 게 큽니다. 지금 봇도 똑같이 동작해요. 전 종목을 훑고, 게이트로 거르고, 남은 후보를 랭킹으로 정렬하고, 빈 슬롯에 배치합니다. 게이트가 하나에서 열 개로 늘고 랭킹 산식이 정교해졌을 뿐, 뼈대는 이 시대의 것입니다.
스캔이 바꾼 개발의 성격
봇이 종목을 고르기 시작하자 개발 작업의 성격 자체가 바뀌었습니다.
[ 수동 지정 ]
· 진입 타이밍 다듬기
· 청산 규칙 다듬기
· 화면 개선
종목 한두 개만 보면 되니 눈으로 검증 가능
[ 스캔 ]
· 거르는 조건 설계
· 순서 정하는 규칙 설계
· 제외 목록 관리
· 호출량·성능 관리
수백 종목을 눈으로 검증할 수 없다 → 로그가 필수
수백 개 종목을 훑기 시작하면 사람이 눈으로 따라갈 수 없습니다. 그러면 로그가 유일한 검증 수단이 돼요. 이 시기부터 “왜 이 종목을 샀나"를 로그에서 역추적하는 작업이 개발의 일부가 됩니다.
그리고 여기서 중요한 습관이 하나 생깁니다. 떨어진 종목도 기록하기. 산 종목만 기록하면 조건이 너무 빡빡한지 헐거운지 알 수 없어요. 조건 A에서 몇 개가 떨어지고 조건 B에서 몇 개가 떨어지는지를 봐야 어느 조건이 실질적으로 작동하는지 압니다.
이 시기에는 이걸 화면에 출력만 하고 파일로 안 남겼습니다. 그래서 나중에 분석은 못 했어요. 그래도 “떨어진 것도 봐야 한다"는 감각 자체는 여기서 생겼고, 다음다음 시대에 스캔 로그로 정식화됩니다.
남은 숙제가 다음 시대를 열었습니다
이동평균의 문제는 이 시기에 이미 보였습니다. 횡보장에서 교차가 계속 일어나거든요. 올랐다 내렸다 하면서 단기선이 장기선을 몇 번씩 넘나듭니다. 그때마다 신호가 나오고, 그때마다 사고, 그때마다 수수료가 나갑니다.
이건 파라미터로 해결이 안 되는 문제입니다. 이동평균 기간을 늘리면 신호는 줄지만 반응이 더 느려져요. 줄이면 반응은 빨라지는데 신호가 더 늘어납니다. 어느 쪽으로 가도 다른 쪽이 나빠지는 구조예요. 이럴 때가 전략 자체를 의심해야 하는 순간이라는 걸 이때는 몰랐습니다. 한동안 더 파라미터를 만졌어요.
그 답답함이 쌓여서 다음 시대의 병렬 실험으로 이어집니다. 하나를 계속 고치는 대신 여러 개를 만들어 비교해보자는 발상이요. 그리고 그 실험에서 나온 결론이 지금 전략의 직계 조상이 됩니다.
이 시대에서 가져갈 세 문장
첫째, 제일 어려운 판단부터 넘겨야 합니다. 자동매매를 만들 때 쉬운 것부터 자동화하고 싶어집니다. 주문 실행, 손절 감시 같은 것들이요. 그런데 정작 감정이 개입하는 자리는 종목 선택입니다. 거기를 사람이 쥐고 있으면 나머지를 아무리 자동화해도 결과는 사람 판단의 복사본이에요.
둘째, 효율을 올리면 새로운 실패 방식이 생깁니다. REST에서 웹소켓으로 가면 호출량은 줄지만 조용히 끊기는 실패가 생깁니다. 최적화는 문제를 없애는 게 아니라 다른 문제로 바꾸는 일에 가깝더군요. 그래서 효율을 올릴 때는 항상 “이제 어떻게 실패하나"를 같이 물어야 합니다.
셋째, 파라미터로 안 풀리면 전략을 의심해야 합니다. 이동평균 기간을 늘려도 줄여도 다른 쪽이 나빠지는 구조였는데, 저는 한동안 더 파라미터를 만졌습니다. 양쪽으로 다 나빠지는 트레이드오프를 만나면 그건 값의 문제가 아니라 접근의 문제라는 신호예요. 이 신호를 읽는 데 시대가 하나 더 걸렸습니다.
일주일, 48개 버전. 봇이 처음으로 저 대신 종목을 고른 시기였습니다. 그때부터 이건 도구가 아니라 봇이 됐다고 생각합니다.