트레이딩 봇의 소프트웨어 아키텍처

자동매매를 처음 볼 때 사람의 시선은 대개 전략으로 먼저 향한다. 어떤 지표를 쓰는지, 언제 진입하고 언제 청산하는지, 백테스트 곡선이 얼마나 좋아 보이는지가 먼저 눈에 들어온다. 그런데 실전으로 조금만 가까이 가면 질문이 바뀐다. 이 전략은 어떤 구조 위에서 실행되고 있고, 그 구조는 지연과 장애와 운영 실수를 얼마나 잘 견디는가?

이 지점에서 등장하는 게 아키텍처다. 이름만 들으면 거창한 설계도처럼 느껴질 수 있지만, 실전에서 아키텍처는 훨씬 현실적인 문제에 가깝다. 데이터가 늦게 들어오면 어떻게 할지, 주문이 일부만 체결되면 무엇을 기준으로 상태를 맞출지, 서버가 재시작되면 어디서부터 다시 살아날지, 보호주문이 비면 누가 먼저 알아차릴지를 정하는 구조다. 전략이 “무엇을 할까”를 말해준다면, 아키텍처는 그 판단이 실제 시간과 실제 계좌 위에서 어떻게 살아남을지를 결정한다.

그래서 이 글에서는 트레이딩 봇을 단순히 매수·매도 규칙의 묶음으로 보지 않고, 여러 층이 서로 다른 책임을 나눠 가진 운영 시스템으로 다시 정리해보려 한다. 핵심은 어렵지 않다. 좋은 전략이 있어도 구조가 약하면 실전에서는 쉽게 어긋난다. 반대로 전략이 아주 화려하지 않아도 구조가 분명하면 시스템은 훨씬 더 오래, 더 안정적으로 반복될 수 있다.

좋은 전략과 좋은 봇은 같은 말이 아니다

이 차이부터 먼저 분리해서 보는 편이 좋다. 좋은 전략은 진입과 청산 규칙이 분명하고, 특정한 시장 조건에서 기대수익을 만들 가능성이 있다. 하지만 좋은 봇은 거기서 멈추지 않는다. 캔들이 늦게 들어와도, 거래소 응답이 밀려도, 주문이 부분 체결돼도, 서버가 재시작돼도, 운영자가 자는 동안에도 시스템이 크게 어긋나지 않아야 한다.

그럼 아키텍처는 정확히 어디까지일까? 생각보다 범위가 넓다. 전략은 “무엇을 할지”를 정하지만, 아키텍처는 그 판단이 어떤 순서로 실행되고, 어떤 상태를 기준으로 기록되며, 실패했을 때 어떻게 복구되고, 사람이 어디에서 확인하고 개입할지를 정한다. 그래서 트레이딩 봇의 아키텍처를 본다는 건 전략 코드만 읽는 일이 아니라, 데이터 흐름과 상태 소유권과 주문 처리와 운영 계층까지 함께 보는 일에 가깝다.

이 관점이 생기면 봇이 다르게 보이기 시작한다. 더 이상 지표 몇 개를 엮은 스크립트가 아니라, 시장 데이터를 받아 판단하고, 주문을 실행하고, 상태를 맞추고, 사람에게 설명 가능한 형태로 남기는 하나의 시스템처럼 보인다. 실전 자동매매에서 중요한 시선도 바로 그 두 번째 시선이다.

트레이딩 봇은 네 층으로 움직인다

트레이딩 봇의 구조는 복잡해 보여도 크게 네 층으로 나눠 생각하면 훨씬 선명해진다. 먼저 리서치 계층에서는 전략 가설을 세우고, 지표와 파라미터를 시험하고, 백테스트로 아이디어를 검증한다. 여기서는 “이 아이디어가 통할까?”를 묻는다.

그다음은 실행 계층이다. 시장 데이터를 수집하고, 봉이 확정됐는지 확인하고, 특징값을 계산하고, 전략 판단을 내리고, 리스크 체크를 거쳐 실제 주문을 보내고, 체결 결과를 반영한다. 여기서는 “이 아이디어를 지금, 실제 시장에서, 어떤 순서로 실행할까?”를 다룬다.

세 번째는 운영 계층이다. 시스템 기동과 재시작, 로그, 알림, 생존 신호, 장애 감시, 배포, 롤백, 리포트가 여기에 들어간다. 많은 초보자는 이 부분을 부수적인 편의 기능처럼 보지만, 실전에서는 오히려 이 계층이 시스템 신뢰도를 크게 좌우한다. 전략은 멀쩡한데 프로세스가 죽었고 아무도 모른다면, 그 봇은 좋은 전략을 가졌더라도 좋은 시스템은 아니다.

마지막은 사람이 읽는 인터페이스 계층이다. 텔레그램, CLI, 대시보드, 리포트처럼 운영자가 상태를 확인하고 필요할 때 개입하는 표면이 여기에 있다. 트레이딩 봇에 화려한 웹 화면이 없더라도 이 계층은 분명 존재한다. 자동매매에서는 화면의 화려함보다, 사람이 시스템 상태를 얼마나 빠르고 명확하게 읽을 수 있는가가 훨씬 중요하다.

이 네 층을 하나로 묶어보면 이렇게 정리할 수 있다. 리서치는 아이디어를 만들고, 실행 계층은 그 아이디어를 시장으로 보내고, 운영 계층은 시스템을 살아 있게 만들고, 인터페이스 계층은 사람과 시스템 사이의 통로를 만든다. 전략은 이 구조의 핵심이지만, 구조 전체는 아니다.

실전에서는 상태를 나눠서 가져야 시스템이 덜 어긋난다

트레이딩 봇을 어렵게 만드는 건 계산식보다 상태다. 어떤 봉이 확정됐는지, 어떤 주문이 아직 살아 있는지, 실제 포지션 수량이 얼마인지, 보호주문이 존재하는지, 트레일링이 어디까지 올라왔는지 같은 정보는 계속 바뀐다. 그리고 이 상태들이 서로 어긋나는 순간, 전략 수식이 맞는지 틀린지보다 더 큰 문제가 생긴다.

그래서 좋은 아키텍처는 상태를 한 덩어리로 두지 않는다. 최소한 네 가지는 분리해서 보는 편이 좋다. 시장 상태, 전략 상태, 주문 상태, 포지션 상태다. 시장 상태는 캔들, 체결, 호가, 변동성처럼 바깥에서 들어오는 관측값이다. 전략 상태는 지금이 진입 대기인지, 보유 중인지, 어떤 레짐으로 해석하는지 같은 내부 판단이다. 주문 상태는 주문 요청, 대기, 부분 체결, 취소, 거절처럼 거래소와 주고받는 상호작용의 기록이다. 포지션 상태는 실제 보유 수량, 평균 단가, 미실현 손익처럼 계좌 현실에 가까운 정보다.

왜 이렇게까지 나눠야 할까? 예를 들어 내부 로직은 이미 포지션이 정리됐다고 믿는데, 거래소에는 일부 수량이 남아 있을 수 있다. 반대로 전략은 아직 진입 전이라고 생각하지만, 주문 계층에서는 이미 주문이 나가 있는 상태일 수도 있다. 이런 어긋남은 처음에는 작아 보여도, 시간이 지나면 보호주문 누락, 잘못된 중복 진입, 포지션 계산 오류로 이어질 수 있다.

여기서 꼭 필요한 개념이 하나 더 있다. 최종 기준(source of truth)을 어디에 둘 것인가다. 특히 체결 수량과 실제 포지션에 관해서는 내부 캐시보다 거래소가 최종 기준에 가깝다. 내부 상태는 빠른 판단을 위해 필요하지만, 실전에서는 반드시 주기적으로 외부 현실과 다시 맞춰야 한다. 실전 운영에서 무서운 건 계산 실수 하나보다, 내부가 믿는 현실과 실제 계좌 현실이 조용히 벌어지는 상태다.

운영 계층이 없으면 전략은 실전으로 못 간다

이제 많은 사람이 뒤늦게 중요성을 체감하는 층으로 가보자. 바로 운영 계층이다. 개발 단계에서는 전략 로직이 거의 전부처럼 느껴지지만, 라이브로 가면 운영 계층이 사실상 전략의 생존 장치가 된다. 시스템을 켜고, 죽으면 다시 살리고, 문제가 생기면 알리고, 무슨 일이 있었는지 기록하고, 이상한 배포가 나가면 되돌릴 수 있어야 한다.

이 층을 설명할 때 종종 운영 하네스(harness)라는 말을 쓴다. 쉽게 말하면 전략 엔진을 실제로 굴릴 수 있게 만드는 운전석이다. 여기에는 프로세스 제어, 로그, 생존 신호, 멈춤 감시(watchdog), 텔레그램 상태 조회, 설정 분리, 테스트, 롤백, 리포트가 들어간다. 이름은 기술적이지만 질문은 아주 현실적이다. 문제가 생겼을 때 누가 먼저 알고, 어디를 보면 되고, 어떻게 되돌릴 수 있는가?

예를 들어 전략은 멀쩡한데 1분 보호 루프만 멈췄다고 해보자. 겉보기에 프로세스는 살아 있어도, 실제 리스크 관리 기능은 죽어 있을 수 있다. 또는 손절(SL)과 익절(TP) 주문이 비었는데 알림이 없다면, 그 시스템은 좋은 진입 규칙을 가졌더라도 실전용 구조라고 부르기 어렵다. 실전 자동매매에서 자주 무서운 건 화려한 버그보다, 조용히 망가졌는데 아무도 모르는 상태다.

그래서 운영 계층은 편의 기능이 아니라 리스크 관리 계층으로 보는 편이 더 정확하다. 좋은 운영 구조가 있으면 장애를 빨리 발견하고, 복구 시간을 줄이고, 같은 실수를 다시 재현해 분석할 수 있다. 반대로 운영 구조가 약하면 전략 자체는 괜찮아도 라이브 환경에서 결과가 거칠어질 수밖에 없다.

좋은 봇은 더 영리하기보다 경계가 분명한 봇이다

트레이딩 봇도 넓게 보면 에이전트다. 시장을 읽고, 내부 규칙으로 판단하고, 주문이라는 행동으로 반응한다. 하지만 여기서 중요한 건 얼마나 똑똑해 보이느냐보다, 그 자율성이 어디까지 허용되는가다. 트레이딩에서는 잘못된 자율성이 곧바로 자본 손실로 이어질 수 있기 때문이다.

그래서 실전 봇은 대개 의도적으로 더 제한된 자율성 위에서 움직인다. 정해진 규칙 안에서 진입과 청산을 하고, 미리 허용된 범위 안에서만 파라미터를 조정하고, 정해진 리스크 한도를 넘지 않도록 제한한다. 반대로 전략 자체를 실시간으로 바꾸거나, 새로운 필터를 스스로 채택하거나, 사람 승인 없이 위험 한도를 늘리는 쪽은 대부분 너무 위험하다.

이 지점에서 중요한 건 가드레일이다. 포지션 상한, safe mode, kill switch, 상태 정합성 검사, 사람 승인 없는 전략 변경 금지 같은 장치가 여기에 속한다. 왜 이런 장치가 필요할까? 많은 초보자는 더 영리한 봇이 더 좋은 봇이라고 느끼지만, 실전에서는 오히려 더 예측 가능한 봇이 더 안전한 봇인 경우가 많다. 운영자는 시스템이 무엇을 할 수 있는지뿐 아니라, 무엇을 절대 하지 못하는지도 알아야 안심할 수 있다.

사람이 읽는 인터페이스 계층도 결국 이 경계를 돕는다. 텔레그램 명령, CLI, 대시보드, 리포트는 단순한 편의 UI가 아니다. 시스템 상태를 사람이 빠르게 읽고, 필요하면 개입하고, 사후에 설명할 수 있게 만드는 표면이다. 자동화는 사람을 완전히 지우는 기술이 아니라, 사람의 개입 지점을 더 명확하게 만드는 기술에 가까운 경우가 많다.

좋은 아키텍처는 실패 모드를 기준으로 평가해야 한다

정상 상황에서는 웬만한 구조가 다 그럴듯해 보인다. 차이는 실패 시점에 드러난다. 그래서 트레이딩 봇의 아키텍처를 볼 때는 “얼마나 멋진 구조인가?”보다 “어떤 실패를 어디서 좁혀두었는가?”를 먼저 보는 편이 낫다.

대표적인 실패 모드는 몇 가지로 정리할 수 있다. 첫째는 오래된 데이터 읽기(stale data)다. 아직 확정되지 않은 봉을 확정된 것처럼 읽거나, 지연된 입력을 정상으로 오해하는 상황이다. 둘째는 상태 표류(state drift)다. 내부가 믿는 포지션 상태와 실제 거래소 포지션이 벌어지는 문제다. 셋째는 보호 공백(protection gap)이다. 포지션은 살아 있는데 보호주문이나 감시가 비어 있는 상태를 말한다. 마지막은 침묵 장애(silent failure)다. 프로세스나 서브루프가 죽었는데도 알림이 오지 않아 운영자가 한참 뒤에야 문제를 알게 되는 경우다.

이 네 가지는 모두 다른 층에서 생기지만, 운영자가 체감하는 위험은 비슷하다. 시스템이 내가 믿는 현실과 달라지는 순간이 생기는 것이다. 그래서 좋은 아키텍처는 실패를 완전히 없애겠다고 약속하지 않는다. 대신 실패가 생겨도 빨리 드러나게 하고, 피해 범위를 좁히고, 복구 경로를 미리 만들어 둔다. 실전에서 신뢰할 수 있는 시스템은 완벽한 시스템이 아니라, 어디서 어떻게 틀어질 수 있는지 알고 있는 시스템에 더 가깝다.

이 관점에서 보면 왜 아키텍처 이야기는 공개 가능하고, 구체적 알파는 비공개로 둘 수 있는지도 자연스럽게 이해된다. 실행 순서를 어떻게 나누는지, 상태를 어떻게 분리하는지, 운영 계층을 어떻게 붙이는지는 재사용 가능한 구조적 지식이다. 반면 세부 파라미터와 필터 조합과 신호 우선순위는 edge와 직접 맞닿아 있다. 결국 공개와 비공개의 건강한 경계는 여기에서 생긴다. 구조는 공유할 수 있지만, 알파의 핵심은 분리해서 지킬 수 있다.

마무리

트레이딩 봇의 소프트웨어 아키텍처를 이해한다는 건 코드를 예쁘게 나눈다는 뜻이 아니다. 데이터가 어떻게 들어오고, 판단이 어떤 순서로 실행되고, 주문이 어떤 계층을 거쳐 나가고, 상태가 어디에서 확정되며, 장애가 났을 때 누가 먼저 알아차리는지를 함께 본다는 뜻이다.

전략만 보면 봇은 똑똑한 계산기처럼 보인다. 하지만 아키텍처까지 보면 봇은 하나의 운영 시스템으로 보이기 시작한다. 그리고 실전 자동매매에서 중요한 건 바로 그 두 번째 시선이다. 좋은 전략이 기회를 만든다면, 좋은 아키텍처는 그 기회를 실제 시장에서 반복 가능하고 설명 가능하고 운영 가능한 시스템으로 바꿔준다.

댓글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다