본문 바로가기

LLM

LLM 기반 비트코인 자동매매 시스템

 

 

프로젝트 개요

프로젝트의 주요 기능은 다음과 같습니다.

  • 실시간 시세 데이터 수집 및 차트 구성
    Upbit API를 이용해 일봉, 주봉, 1시간봉, 10분봉 등 다양한 간격의 데이터를 수집하고, SQLAlchemy를 통해 SQLite 데이터베이스에 저장하여 이후 분석 및 차트에 활용했습니다.
  • 자동매매 로직 및 기술적 지표 계산
    단순 이동평균(SMA), RSI, EMA 등 다양한 기술적 지표를 계산하여 매매 신호를 분석하였으며, 이를 기반으로 매수/매도/홀드 결정을 내렸습니다.
  • LLM 기반의 의사결정 지원
    Google Gemini API를 활용하여, 실시간 시세 데이터와 기술적 지표들을 종합한 프롬프트를 생성하고, LLM의 응답으로 매매 결정을 도출하였습니다.
    또한, 거래 후에는 간단한 반성(reflection) 프롬프트를 보내어 거래의 개선점을 피드백 받도록 구성했습니다.
  • 웹 대시보드
    Flask와 Jinja2 템플릿, 그리고 Chart.js를 이용하여 실시간 거래 데이터와 차트, 거래 내역을 시각화한 대시보드를 제공하였습니다.

기술 스택 및 주요 라이브러리

  • Flask: 웹 서버 및 API 라우팅, 대시보드 템플릿 렌더링
  • SQLAlchemy: ORM을 이용한 SQLite 데이터베이스 관리
  • Requests & JWT: Upbit API와의 통신 및 인증 처리
  • Google Gemini API: LLM 기반 매매 의사결정 및 거래 반성 피드백
  • Chart.js, Moment.js, Bootstrap: 대시보드의 프론트엔드 시각화 및 UI 구성

주요 구현 내용

프로젝트는 크게 12개의 섹션으로 나뉩니다.

  1. 환경 및 설정: Upbit, Gemini API의 API 키와 서버 URL 설정, 거래 간격, 최소 주문 금액, 데이터 카운트 등을 정의했습니다.
  2. 데이터베이스 모델 정의: 거래 내역(Trade), 시세 데이터(Candle), 포지션(Position) 테이블을 SQLAlchemy ORM으로 정의하고 초기화하는 함수를 구현했습니다.
  3. Upbit API 연동: JWT를 이용한 인증, 잔액 조회, 시세 정보, 캔들 데이터, 주문(매수/매도) 실행 등 Upbit API와 통신하는 함수들을 작성했습니다.
  4. 기술적 지표 계산: SMA, RSI, EMA 등 기본적인 기술적 지표들을 계산하여 매매 판단에 활용할 수 있도록 구현했습니다.
  5. LLM 의사결정 및 반성: Gemini API를 통해 생성된 프롬프트를 바탕으로 매매 결정을 받고, 거래 후에는 간단한 거래 반성을 받아서 개선 포인트를 도출하도록 했습니다.
  6. 주문 체결 확인: 주문 상태를 주기적으로 확인하여 체결 완료, 취소 등의 상태를 업데이트합니다.
  7. 포지션 종료 처리: 매도 주문 후 포지션을 종료하고, 거래 손익을 계산합니다.
  8. 메인 트레이딩 로직: 위의 기능들을 종합하여 주기적으로 거래 사이클을 돌리며, 실시간으로 매매 신호를 판단하고 주문을 실행합니다.
  9. API 라우트: 차트 데이터 및 수익 정보(API)를 제공하여 대시보드와 연동합니다.
  10. 웹 대시보드: 거래 내역, 현재 포지션, 총 수익률 등을 시각화한 웹 페이지를 구현했습니다.
  11. 백그라운드 스레드로 거래 실행: Flask 서버와 동시에 백그라운드에서 트레이딩 루프를 실행하도록 스레드를 구성했습니다.
  12. 프로그램 시작: 초기 자본 설정과 DB 초기화를 진행한 후, 서버를 실행합니다.

구현하면서 배운 점

  • API 연동과 보안
    Upbit API의 JWT 인증 과정을 직접 구현하면서, 보안 토큰 생성 및 관리의 중요성을 깨달았습니다. 특히, 실제 거래 환경에서는 API 키와 시크릿 관리가 매우 중요함을 다시 한번 확인했습니다.
  • LLM을 활용한 의사결정
    Gemini API를 통해 매매 결정을 내리도록 한 부분은 매우 흥미로웠습니다. 데이터 기반의 프롬프트 설계와 LLM의 응답 포맷 파싱, 최소 거래 비율 보정 등 세세한 부분을 고려하면서 LLM을 실제 거래 시스템에 접목시키는 경험을 얻었습니다.
  • 멀티스레딩과 Flask의 조화
    Flask 서버와 별도로 트레이딩 루프를 백그라운드 스레드로 실행하면서, 동시성 문제와 자원 공유에 대해 신경 쓰게 되었습니다. 데이터베이스 세션 관리와 예외 처리, 주기적인 API 호출 등을 조율하는 과정에서 많은 학습이 있었습니다.
  • 프론트엔드와 백엔드의 통합
    Chart.js, Moment.js, Bootstrap을 이용한 대시보드 구축을 통해 실시간 데이터를 시각화하는 방법과, Flask API 라우트를 통해 프론트엔드와 백엔드를 통합하는 경험을 쌓았습니다.

구현하면서 어려웠던 점

  • API 호출 실패 및 에러 핸들링
    Upbit API와 Gemini API 모두 실시간 데이터를 주고 받다 보니, 네트워크 오류나 API 제한에 걸리는 경우가 발생했습니다. 이러한 에러 상황에 대해 로그를 남기고, 재시도 로직을 구현하는 부분이 도전적이었습니다.
  • LLM 응답 파싱의 불확실성
    LLM이 항상 예상한 형식대로 응답하지 않을 때가 있어, 정규표현식 등을 활용하여 안정적으로 파싱하는 로직을 추가로 구현했습니다. 특히, 최소 거래 금액 및 퍼센티지 보정 로직과 연동하는 부분에서 난항이 있었습니다.
  • 동시성 및 데이터 동기화 문제
    트레이딩 루프와 Flask 서버가 동시에 DB에 접근할 때, 세션 관리와 데이터 정합성을 유지하는 것이 중요한 과제였습니다. 이를 위해 SQLAlchemy 세션을 적절히 생성하고 종료하는 패턴을 확립하는 데 많은 고민이 있었습니다.

마치며

이번 프로젝트를 통해 단순한 거래 봇을 넘어, 인공지능을 접목한 의사결정 시스템을 구현하는 방법과, API 연동, 데이터 시각화, 멀티스레딩 등 다양한 기술을 경험할 수 있었습니다. 물론 구현 과정에서 예기치 않은 오류와 여러 난관이 있었지만, 이를 극복하면서 전체적인 시스템 디자인과 안정성에 대해 깊이 고민할 수 있는 좋은 기회가 되었습니다.

 

앞으로 단순히 BUY, SELL, HOLD 가 아닌 로봇에 대한 action을 LLM을 이용 구현하는 프로잭트를 진행하고 싶습니다.