ONCE AI PUBLISHING디지털 핸드북 시리즈 #01
CHAPTER 10

암호화폐 자동매매 정책을 학습한 VLM

5년치 캔들 데이터로 정책을 만들고, 차트 이미지를 보는 모델로 검증하기

왜 VLM인가

트레이딩 데이터는 숫자이지만, 사람이 시장을 볼 때는 차트를 본다. 캔들, 이동평균, 거래량, MACD, RSI가 한 화면에 놓이면 숫자 표보다 훨씬 빠르게 구조를 파악할 수 있다. 이 장의 아이디어는 바로 그 지점에서 출발한다. 정책은 숫자로 만들고, 모델은 차트 이미지로 그 정책을 배우게 한다.

red 프로젝트는 이 구조를 실험한다. DB에서 캔들 데이터를 가져오고, 이상 구간 라벨을 만들고, 정책 문서의 원칙을 teacher 로짓으로 근사한 뒤, 최종적으로 차트 PNG를 입력받아 매도, 매수, 유지 중 하나를 출력하는 정책 모델을 학습한다.

전체 파이프라인

5년치 ETH/KRW 캔들 DB
  -> 지표 계산: MA20, MA60, MA120, MACD, RSI, 거래량
  -> 극단 라벨: crash, surge, price_spike, volume_spike, pattern_anomaly
  -> 정책 teacher: policy.md 규칙을 매도/매수/유지 로짓으로 변환
  -> ACTION CSV: 0=매도, 1=매수, 2=유지
  -> 차트 PNG 생성
  -> VLM형 PNG 정책 학습
  -> 모의 포트폴리오 검증

프로젝트 구성

파일

역할

Market.py

MySQL 캔들 데이터를 읽고 보조지표와 이상탐지 기능을 제공한다.

config/policy.md

거래 비용, 이동평균, 수렴/발산, 급등락, MACD 기준을 자연어 정책으로 적는다.

build_market_extreme_labels.py

과거 캔들 전체에 crash, surge, volume_spike 같은 극단 라벨을 붙인다.

build_action_from_labels.py

극단 라벨과 teacher 정책을 매도/매수/유지 ACTION CSV로 바꾼다.

lib/rl_policy_teacher.py

policy.md를 수치 규칙으로 근사해 teacher logits를 만든다.

train_png_policy_from_action_csv.py

차트 PNG와 ACTION CSV를 이용해 PNG->액션 정책을 교차엔트로피로 학습한다.

PngToStatus.py

차트 이미지를 CNN으로 읽고 포트폴리오 상태 특징과 합쳐 3개 액션 로짓을 낸다.

lib/png_status_vision_viewer.py

학습된 PNG 정책을 뷰어에 연결하고 액션 CSV와의 일치율, 모의 수익률을 확인한다.

1단계: 5년치 데이터 준비

암호화폐는 24시간 거래되므로 데이터의 양이 빠르게 커진다. 1분봉 기준 5년이면 약 260만 개 이상의 봉이 생길 수 있다. 이 프로젝트는 Market.get_data()를 통해 DB에서 과거 캔들을 읽고, open, high, low, close, volume을 기본으로 사용한다. 그 위에 MA20, MA60, MA120, MACD, RSI 같은 보조지표를 붙인다.

프로젝트에 현재 생성된 캐시 기준으로 market_extreme_labels.csv는 788,824개 봉을 포함한다. 책에서는 이 파일을 5년치 데이터 구축 방법의 축소 예시로 설명하고, 실제 5년 전체 데이터에서는 같은 과정을 더 긴 기간에 반복한다고 쓰면 자연스럽다.

데이터 요소

이유

OHLCV

가격의 움직임과 거래량을 나타내는 기본 재료다.

MA20/60/120

단기, 중기, 장기 추세와 수렴/발산을 판단한다.

MACD

추세의 방향과 모멘텀 잔량을 본다.

RSI

과열과 침체 정도를 보조적으로 확인한다.

이상 라벨

급락, 급등, 가격 급변, 거래량 급증, 패턴 이상을 정책에 반영한다.

2단계: 극단 구간 라벨 만들기

build_market_extreme_labels.py는 각 봉을 돌면서 AdvancedAnomalyDetector를 실행한다. 최근 50개 봉을 기준으로 가격 급변, 거래량 급증, IsolationForest 패턴 이상, 지지선 이탈, 저항선 돌파 같은 신호를 계산한다. 결과는 ext_crash_signal, ext_surge_signal, ext_price_spike, ext_volume_spike, ext_pattern_anomaly 같은 컬럼으로 저장된다.

python build_market_extreme_labels.py

# 출력
# cache/market_extreme_labels.csv
# rows=788,824

현재 라벨 분포

개수

normal

701,266

volume_spike

51,744

price_spike

20,110

pattern_anomaly

15,597

surge

54

crash

51

crash_surge_conflict

2

3단계: 정책 문서를 teacher로 바꾸기

config/policy.md에는 사람이 이해하는 매매 원칙이 적혀 있다. 예를 들어 왕복 수수료를 고려해 1% 미만의 얕은 익절을 피하고, 장대 양봉은 매수 쪽으로, 장대 음봉은 매도 쪽으로 본다. MA20, MA60, MA120의 수렴과 발산, MA60의 방향, 고점 수렴 리스크, MACD 모멘텀도 함께 본다.

이 자연어 정책은 그대로 학습에 넣을 수 없으므로 rl_policy_teacher.py가 수치 규칙으로 근사한다. 각 봉에서 매도, 매수, 유지 세 액션에 점수를 주고, 가장 높은 점수를 teacher 행동으로 삼는다. 이 방식은 LLM이 무작정 결정하게 하는 것보다 재현성이 좋고, 왜 그런 액션이 나왔는지 설명하기 쉽다.

정책 원칙

teacher 로짓에서의 근사

장대 양봉

매수 점수를 크게 올리고 유지 점수를 낮춘다.

장대 음봉

매도 점수를 크게 올리고 무포지션 매수를 억제한다.

수수료 1% 미만

보유 중 얕은 이익에서는 성급한 매도를 억제한다.

MA60 하향

매수 점수를 낮추고 매도와 유지를 높인다.

고점 부근 MA 수렴

신규 매수를 낮추고 관망 또는 매도 쪽을 높인다.

crash/surge 라벨

crash는 매도, surge는 매수 쪽 점수를 보강한다.

4단계: ACTION CSV 만들기

build_action_from_labels.py는 라벨 CSV를 읽고 ACTION CSV를 만든다. 액션은 0=매도, 1=매수, 2=유지다. regime 모드는 crash와 surge 같은 레짐만 보고 단순 매핑하고, teacher 모드는 policy.md를 근사한 teacher logits의 argmax를 사용한다. --walk 옵션을 켜면 모의 포트폴리오 상태를 봉마다 갱신하면서 정책을 만든다.

python build_action_from_labels.py \
  -o cache/ACTION_from_labels_teacher.CSV \
  --mode teacher \
  --walk

python build_action_from_labels.py \
  -o cache/ACTION_repaired.CSV \
  --mode teacher \
  --walk \
  --repair-pnl skip-buy

현재 보정된 ACTION_repaired.CSV는 788,824행이며, 매도 148개, 매수 489개, 유지 788,187개로 구성된다. 대부분의 시간은 거래하지 않는다는 뜻이다. 자동매매에서 좋은 정책은 자주 사고파는 정책이 아니라, 위험한 구간을 피하고 필요한 순간에만 행동하는 정책이어야 한다.

5단계: 정책을 VLM형 모델에 학습하기

train_png_policy_from_action_csv.py는 ACTION CSV를 teacher로 삼아 차트 PNG를 보는 정책을 학습한다. 실제 거대 VLM 전체를 미세조정하는 대신, 프로젝트에서는 차트 이미지를 보는 작은 CNN 기반 시각 정책망을 사용한다. 구조상 역할은 VLM의 시각 판단 헤드와 같다. 이미지를 보고 매도, 매수, 유지 중 하나를 고른다.

입력은 차트 PNG와 사이드 특징이다. 사이드 특징은 현재 포지션 보유 여부, 미실현 손익, 현금 비율 3개다. 차트만 보면 같은 가격 구조라도 현재 보유 중인지 아닌지를 알 수 없기 때문에 이 보조 정보가 필요하다.

입력

설명

차트 PNG

캔들, 이동평균, 거래량, 보조지표가 그려진 화면 이미지다.

in_position

현재 코인을 보유 중인지 여부다.

unrealized_pnl

보유 중일 때 매수가 대비 미실현 손익이다.

cash_ratio

전체 평가액 중 현금 비율이다.

target action

ACTION CSV의 0, 1, 2 라벨이다.

python train_png_policy_from_action_csv.py \
  --actions cache/ACTION_repaired.CSV \
  --out cache/png_status_policy_action_repaired.pt \
  --epochs 8 \
  --stride 3 \
  --max-samples 12000

학습 기록

값

샘플 수

12,000

입력 해상도

96 x 192

hidden dimension

256

epoch

8

CE loss

1 epoch 0.01693 -> 8 epoch 0.00075

체크포인트

cache/png_status_policy_action_repaired.pt

6단계: 실제 검증

검증은 세 층으로 나눈다. 첫째, 정책 모방 검증이다. 뷰어에서 PNG 정책의 argmax가 ACTION CSV와 얼마나 맞는지 누적 일치율을 본다. 둘째, 모의 포트폴리오 검증이다. 학습된 정책이 봉을 순서대로 지나가며 실제로 매수와 매도를 실행했을 때 평가액, 매도 승률, 누적 수익률이 어떻게 변하는지 확인한다. 셋째, 사람 검증이다. 차트 브라우저로 해당 봉을 눈으로 확인하며 모델이 매수한 지점과 매도한 지점이 정책 문서의 원칙과 맞는지 본다.

검증 항목

확인할 것

액션 일치율

정책 모델의 argmax가 ACTION_repaired.CSV의 라벨과 일치하는 비율

체결 일치율

실제 포트폴리오 상태에서 실행된 행동이 teacher와 맞는 비율

누적 수익률

초기 자본 대비 최종 평가액 변화

매도 승률

완료된 매수->매도 거래 중 이익 거래 비율

거래 횟수

지나치게 잦은 매매가 아닌지 확인

시각 리뷰

차트상 급등락, 수렴, MA 방향과 모델 행동이 맞는지 확인

python main_llm_db_rl_viewer.py

# 설정
# USE_PNG_STATUS_ACTION_SUPERVISED = True
# PNG_STATUS_SHOW_VS_ACTION_CSV_EVAL = True
# PNG_STATUS_EVAL_ACTION_CSV_PATH = "cache/ACTION_repaired.CSV"

5년치 데이터에서 정책을 만들 때의 분할

5년치 전체 데이터를 한 번에 학습하고 같은 구간에서만 검증하면 좋은 결과가 나와도 믿기 어렵다. 시간 순서가 있는 금융 데이터는 무작위 섞기보다 시간 기준 분할이 중요하다. 예를 들어 앞의 3년은 정책 생성과 학습, 다음 1년은 검증, 마지막 1년은 완전한 홀드아웃 테스트로 둔다.

구간

역할

1~3년차

지표 계산, 극단 라벨 생성, teacher 정책 조정, VLM형 정책 학습

4년차

파라미터 튜닝과 모의 포트폴리오 검증

5년차

마지막 홀드아웃 테스트. 이 구간의 결과는 정책 수정 전에 기록한다.

특히 build_action_from_labels.py의 repair-pnl 옵션은 미래 가격을 참고하는 사후 보정이 포함될 수 있다. 따라서 책에서는 이 기능을 '정책 교정 실험'으로 설명하고, 실전 검증에는 미래를 보지 않는 walk-forward 방식의 정책을 따로 사용해야 한다고 강조해야 한다.

VLM과 LLM의 역할 분리

이 프로젝트에서 VLM형 정책은 차트 이미지를 보고 행동을 고른다. 반면 일반 LLM은 정책 문서, 근거 설명, 거래 회고, 오류 분석에 더 잘 맞는다. 즉, VLM은 보는 모델이고 LLM은 말로 정리하는 모델이다. 둘을 같은 위치에 두면 판단이 흔들리기 쉬우므로 역할을 나누는 편이 안전하다.

모델

역할

VLM형 정책

차트 PNG와 포트폴리오 상태를 보고 매도/매수/유지 로짓을 낸다.

Qwen/Gemma VLM

차트를 보고 참고 의견과 근거를 생성한다. 체결의 유일한 근거로 쓰지 않는다.

LLM

정책 문서 요약, 학습 로그 해석, 매매 회고, 리스크 설명을 맡는다.

규칙 엔진

수수료, 최소 보유 봉, 손절 제한, 위험 구간 차단 같은 안전 장치를 담당한다.

실전 연결 전 안전 장치

  • 실거래 전에 반드시 모의 포트폴리오와 홀드아웃 데이터 검증을 통과해야 한다.
  • API 키와 계좌 정보는 코드에 넣지 않고 private 설정과 환경변수로 분리한다.
  • 하루 최대 손실, 1회 최대 주문 금액, 연속 손실 중지 조건을 코드로 강제한다.
  • VLM 출력은 매수 권유가 아니라 정책 신호로 기록하고, 모든 체결은 로그로 남긴다.
  • 수익률만 보지 말고 최대 낙폭, 거래 빈도, 수수료 후 손익, 슬리피지를 함께 본다.
  • 사후 보정으로 만든 ACTION은 실전 성능으로 착각하지 않는다.

마무리

이 장의 핵심은 'VLM이 차트를 보고 바로 돈을 번다'가 아니다. 좋은 구조는 먼저 정책을 만든다. 그 정책을 과거 데이터에서 검증한다. 그다음 차트 이미지를 보는 모델이 정책을 따라 하게 학습한다. 마지막으로 다시 시간 순서대로 검증한다. 이렇게 하면 VLM은 감으로 매매하는 모델이 아니라, 사람이 정의한 정책을 시각적으로 실행하는 모델이 된다.

연습 문제

  • market_extreme_labels.csv의 라벨 분포를 다시 계산하고 crash와 surge 구간의 차트를 직접 확인해 보자.
  • teacher 모드와 regime 모드로 ACTION CSV를 각각 만들고 매수/매도 횟수를 비교해 보자.
  • ACTION_repaired.CSV 없이 teacher 원본 CSV로 PNG 정책을 학습하면 loss와 모의 수익률이 어떻게 달라지는지 비교해 보자.
  • 5년치 데이터를 3년/1년/1년으로 나누는 walk-forward 검증 스크립트를 설계해 보자.
  • VLM의 판단 근거와 teacher 정책이 충돌하는 구간을 찾아 정책 문서를 개선해 보자.
CHAPTER 10 · 암호화폐 자동매매 정책을 학습한 VLM1 / 1
책장을 누르거나 좌우로 밀어 넘기기
CHAPTER 10

암호화폐 자동매매 정책을 학습한 VLM

댓글 0

아직 댓글이 없습니다.