crypto-trading-arena 설치부터 실전까지 — LLM 넷을 같은 봉 앞에 세워 놓고 누가 무엇을 사는지 보기
카프카까지 직접 세워 LLM 네 개를 같은 봉 앞에 앉히고, 같은 미션을 세 번 던져 판단이 얼마나 흔들리는지 재고, 그 판단을 weltiq 슬롯으로 옮겨 수수료가 6배 갈라지는 것을 확인한 기록입니다.
23편 — 트레이딩 아레나: LLM 넷을 같은 봉 앞에 세워 놓고 누가 무엇을 사는지 보기이 글의 완료 조건: 독자는 여러 LLM 이 같은 봉을 보고 서로 다른 매매 판단을 내는 화면을 띄우면 성공입니다.
| 하는 일 | LLM 여러 개를 같은 실시간 시세·같은 봉 앞에 세우고, 각자 페이퍼 지갑으로 사고팔게 한 뒤 한 화면에서 비교합니다 |
| 맞는 사람 | 모델을 고르기 전에 "얘들이 같은 자료를 보고 정말 다르게 구는가"를 자기 눈으로 보고 싶은 사람 |
| 안 맞는 사람 | 지금 뭘 살지 결론 하나만 받고 싶은 사람. 이 도구는 대회장이지 조언자가 아닙니다 |
| 이 글의 결과물 | 에이전트 4개가 각자 잔고·포지션·체결 이력을 들고 있는 대시보드 한 화면 |
| 준비물·비용 | 코드 0원(Apache-2.0) / 모델 유료 API 키 1개 — 이 검증은 네 모델 합쳐 약 $1.06 / 시세 0원(Binance 공개 API, 키 불필요) / weltiq 는 붙일 때만 무료 플랜 |
| 시간·난도 | 브로커 세우기 포함 40분. 난도 중상 — 터미널 창 네 개를 동시에 띄우고 config.json 을 직접 고칩니다 |
| weltiq 와의 관계 | 통합 실험. 판단은 붙지만 수량과 시점은 사람이 다시 씁니다 |
| 검증 환경·날짜 | 2026-09-22 · macOS 15 (Apple Silicon) · Python 3.13 · Binance 현물 |
| 고지 | 필자는 weltiq 와 제휴 관계로 이 글을 씁니다. 도구 평가는 실측만 싣습니다 |
1. 이게 뭔가요
시장 데이터를 한 군데서 받아 여러 에이전트에게 똑같이 뿌리고, 각 에이전트가 자기 LLM 으로 판단해서
매수·매도·계산기·잔고 조회 도구를 부르는 구조입니다. 지갑은 도구 쪽 프로세스가 하나로 들고 있어서
누가 언제 얼마에 샀는지가 한 표에 모입니다.
핵심은 공정성 장치입니다. 봉을 만드는 곳이 한 곳이고, 그 한 곳이 만든 문장이 모든 에이전트에게 같은 글자로 갑니다. 에이전트마다 자기가 데이터를 긁지 않습니다. 그래서 "모델이 달라서 다른 결론이 나왔다"를 말할 수 있습니다.
| 저장소 | ryan-yuuu/crypto-trading-arena (GitHub) |
| 별 · 포크 | 128 · 40 |
| 라이선스 | Apache-2.0 |
| 마지막 커밋 | 2026-07-08 — 두 달 반 조용합니다 |
| 자체 테스트 | 139개 통과. 저장소가 미해결 버그 22개를 문서로 공개하고 그중 7개를 "일부러 실패로 고정"해 뒀습니다 |
| 시세 | Binance 현물 또는 Coinbase. 선물 경로 없음 |
미해결 버그를 목록으로 걸어 두는 저장소는 흔치 않습니다. 이 글에서 조심해야 할 대목도 대부분 그 목록에 이미 적혀 있었습니다.
2. 설치 — 검증된 한 경로
메시지 브로커(Kafka) 하나가 꼭 필요합니다. README 는 도커를 쓰라고 하는데, 도커가 없는 기계에서는 Homebrew 로 Kafka 를 직접 세우면 됩니다. 이 경로로 검증했습니다.
# 1) 브로커
brew install kafka # JDK 포함, 4분
cat > server.properties <<'EOF'
process.roles=broker,controller
node.id=1
controller.quorum.bootstrap.servers=localhost:9243
listeners=PLAINTEXT://localhost:9242,CONTROLLER://localhost:9243
advertised.listeners=PLAINTEXT://localhost:9242
inter.broker.listener.name=PLAINTEXT
controller.listener.names=CONTROLLER
listener.security.protocol.map=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1
log.dirs=/tmp/arena-kafka
EOF
kafka-storage format -t $(kafka-storage random-uuid) -c server.properties --standalone
kafka-server-start server.properties &
# 2) 도구
git clone https://github.com/ryan-yuuu/crypto-trading-arena && cd crypto-trading-arena
uv sync
cp config.example.json config.json # 모델·키·심볼·수수료를 여기서 고칩니다
export OPENROUTER_API_KEY=... # config.json 이 ${...} 로 참조하는 이름과 같게
config.json 에서 세 군데를 고쳤습니다.
"trading": {
"exchange": "binance",
"binance_symbols": ["BTCUSDT", "ETHUSDT", "SOLUSDT"],
"fees": { "taker_bps": 60 }
}
그리고 창 네 개(또는 백그라운드 네 개)로 띄웁니다.
uv run python -m exchanges.binance --bootstrap-servers localhost:9242
uv run python -m deploy.tools_and_dashboard --bootstrap-servers localhost:9242
uv run python -m deploy.response_viewer --bootstrap-servers localhost:9242
uv run python -m deploy.agent --from-config <이름> --strategy default \
--bootstrap-servers localhost:9242 # 모델 수만큼
막히는 자리
| 증상 | 원인 | 넘어가는 법 |
|---|---|---|
You cannot specify controller.quorum.voters and format the node with --standalone |
Kafka 4.x 는 동적 쿼럼 | controller.quorum.voters 대신 controller.quorum.bootstrap.servers |
시세 커넥터가 Environment variable 'OPENROUTER_API_KEY' is not set 로 죽음 |
시세 커넥터는 모델 키가 전혀 필요 없는데도 설정 파일 전체를 해석합니다. 게다가 이 프로세스만 .env 를 안 읽습니다 |
실행 전에 export 로 환경에 넣어 줍니다 |
| Coinbase 로 띄웠는데 에이전트가 봉을 못 봄 | 저장소가 공개한 미해결 버그(우선순위 높음) — Coinbase 쪽 커넥터에 봉 저장소가 연결돼 있지 않습니다 | Binance 로 띄웁니다. 이 글의 결과는 전부 Binance 입니다 |
| 대시보드가 깨져 보임 | 터미널 폭 | 170칸 이상으로 넓히거나 COLUMNS=170 |
3. 첫 결과 — 이렇게 나오면 성공
에이전트를 넷 띄우고 10분쯤 두면 이런 화면이 됩니다. 네 모델이 같은 시각·같은 봉을 받았는데 행동이 다릅니다.
에이전트 4개의 잔고·포지션·체결 이력. 같은 11번의 시세 갱신을 받았는데 gemini 는 10번 체결했고 haiku 와 gpt-5-nano 는 한 번도 주문하지 않았습니다.
이 화면이 뜨면 성공입니다. 읽는 법은 이렇습니다.
- 위쪽 상자 넷 = 에이전트별 총자산·포지션 수·거래 수·낸 수수료
- 왼쪽 표 = 종목별 수량·평단·평가금액·손익
- 오른쪽 표 = 체결 이력. 맨 오른쪽 칸은 시세가 나간 순간부터 체결까지 걸린 초입니다(빠른 모델 2.6초, 느린 모델 23초)
- 아래 = 총자산 곡선
같은 봉을 보고 무슨 생각을 했는지는 별도 창에서 원문으로 볼 수 있습니다.
deepseek 이 세 종목을 분석한 뒤 "60bp 수수료 때문에 신규 진입을 조심해야 한다"고 적은 대목
4. 제일 잘 쓰는 법 — 수수료 한 줄을 바꿔 보기
이 도구가 다른 다중 에이전트 실험과 갈리는 자리는 수수료를 판단 입력으로 준다는 것입니다. 매 틱 에이전트에게 가는 문장 맨 앞에 이런 줄이 붙습니다.
A taker fee of 60 bps (0.60%) is charged on every fill (both buys and sells).
Factor this into your sizing and P&L targets — a round-trip costs 120 bps.
config.json 의 taker_bps 를 0 으로 바꾸면 같은 자리가 Trading is fee-free in this deployment. 로 바뀝니다.
그래서 다른 조건을 전부 고정하고 이 한 줄만 바꿔 두 판을 돌려 봤습니다.
4-1. 실시간 두 판 — 같은 에이전트 넷, 각각 11번의 시세 갱신
| 수수료 60bp | 수수료 0bp | |
|---|---|---|
| 체결 | 12건 | 43건 |
| 주문한 에이전트 | 2 / 4 | 4 / 4 |
| 체결 명목액 | $169,332 | $1,439,744 (8.5배) |
| 낸 수수료 | $1,016 | $0 |
60bp 판에서 한 번도 주문하지 않았던 두 모델(haiku·gpt-5-nano)이 0bp 판에서는 둘 다 주문했습니다.
수수료를 0으로 바꾼 뒤의 같은 화면. 네 에이전트가 모두 거래했고 "Fees paid"는 전부 $0.00 입니다.
4-2. 같은 봉으로 다시 — 60회 재생
두 판은 시장 시각이 다릅니다. 그래서 커넥터가 실제로 내보낸 프롬프트 하나를 그대로 떠서 수수료 문장만 바꿔 같은 도구·같은 계좌 초기값으로 10번씩 재생했습니다. 시장은 완전히 고정됩니다.
| 모델 | 60bp 에서 주문한 회차 | 0bp 에서 주문한 회차 |
|---|---|---|
| deepseek-v3.2 | 1 / 10 | 5 / 10 |
| gemini-3.1-flash-lite | 8 / 10 | 6 / 10 |
| gpt-5-nano | 0 / 10 | 2 / 10 |
| 합계 체결액 | $156,392 | $462,480 (3.0배) |
결론은 달라집니다. 다만 모델마다 다릅니다. 두 모델은 수수료를 없애면 확실히 손이 커지고, gemini-flash-lite 는 오히려 반대로 움직였습니다 — 수수료가 붙어 있든 없든 비슷하게 칩니다. 그리고 실시간 60bp 판에서 그 모델이 어떻게 됐는지가 첫 화면에 그대로 나옵니다: 10번 체결해서 수수료로만 $1,004 를 내고 총자산이 $99,065 가 됐습니다.
즉 이 도구로 알 수 있는 것은 "이 전략이 수수료를 이기는가"가 아니라 "이 모델이 수수료를 보고 있기는 한가" 입니다. 모델 고르기에는 이쪽이 더 쓸모 있습니다.
4-3. 하기 전에 알아 둘 것 두 가지
기본 요율이 시세를 준 거래소와 다릅니다. 설정 파일 기본값 60bp 는 Coinbase 기본 티어이고, 이 글이 봉을 받은 Binance 현물은 10bp 입니다. 기본값 그대로 Binance 로 돌리면 실제의 6배를 뭅니다. 수수료 실험을 할 거면 여기부터 맞추십시오.
수량은 소수 첫째 자리까지만 받습니다. BTC 기준 실측입니다.
0.05 BTC 거절 0.09 BTC 거절 0.15 BTC 거절
0.1 BTC 통과 0.2 BTC 통과
주문이 막히는 것은 아니지만, $100,000 계좌에서 BTC 포지션은 8.6% 단위로만 조절됩니다.
"자본의 2%만 건다"가 BTC 에는 불가능합니다. 실제로 deepseek 은 100000 * 0.02 를 계산해 $2,000 을 뽑아 놓고
BTC 를 포기하고 SOL 로 갔습니다.
5. weltiq 로 옮기기 — 통합 실험
weltiq 준비 (전 편 공통): 가입({{CTA_URL}}) → 마이 → 연결 관리에서 키 발급 →
claude mcp add weltiq https://weltiq.ai/mcp --header "Authorization: Bearer <키>"
이 도구는 "비트코인을 거래해서 수익을 내줘, 그리고 왜 그렇게 했는지 설명해줘"라고 시키면 방향·수량·목표가·무효화 가격을 한 번에 냅니다. 같은 미션을 세 번 던진 결과입니다.
| 회차 | 판단 | 목표가 | 무효화 |
|---|---|---|---|
| 1 | BTC 매수 0.5 | 85,845 | 85,400 |
| 2 | BTC 매수 1.1 | 87,290 | −2% |
| 3 | BTC 매수 1.1 | 86,800~87,000 | — |
방향은 세 번 다 같았고, 수량은 0.5~1.1 로 두 배 넘게 벌어졌습니다. 2회차가 목표가를 뽑은 방식이 이 도구답습니다 — "왕복 수수료 120bp 를 넘기면서 1~2% 남기려면 $85,532 × 1.021 = $87,290".
1회차 판단을 weltiq 슬롯으로 옮기면 다섯 단계입니다.
- 규칙 문서로 씁니다. 진입
close > 85400, 지정가 청산85845, 보호 손절 0.5%, 수량 0.1 POST /v1/strategy-rules로 제출하면 문서가 한 줄로 되읽어 옵니다 —진입: (close > 85400) → 진입 long E · True → 가격 조건 청산 (limit=85845) → 청산: 보호 손절 0.5%POST /v1/ai/thesis로 왜 그렇게 판단했는지를 사람 말로 함께 냅니다. 근거 없이는 슬롯이 안 만들어집니다POST /v1/containers로 슬롯을 만듭니다. 중지 조건(최대 손실·시간 한도)이 필수입니다- 체결을 확인하고 정지·삭제합니다
이날 결과입니다.
| 매수 | 0.1 BTC @ 85,483.07 · 수수료 $8.55 |
| 매도(정지 청산) | 0.1 BTC @ 85,471.36 · 수수료 $8.55 |
| 실현 손익 | −$1.17 |
| 수수료 합 | $17.10 |
| 순 | −$18.27 (−0.18%), 14분 |
옮겨지지 않는 것
- 수량. 0.5 BTC 는 $43,000 입니다. 이 계좌 잔고가 10,000 이라 0.1 로 줄였습니다
- 시점. 도구의 판단은 "지금 시장가로 산다"인데 규칙은 조건이 참인 동안 계속 유효합니다. "지금"을 조건으로 바꾸는 순간 의미가 달라집니다
- 그래서 이 슬롯은 도구 판단을 그대로 옮긴 것이 아니라 도구가 낸 세 숫자로 필자가 다시 쓴 규칙입니다
저쪽 수익률을 그대로 쓰면 안 되는 이유
같은 왕복 거래를 두 장부가 이렇게 계산했습니다.
| 아레나 페이퍼 지갑 | weltiq 슬롯 | |
|---|---|---|
| 요율 | 60bp (설정 기본값) | 10bp (Binance 현물 실제) |
| 왕복 수수료 | $102.64 | $17.10 |
같은 판단·같은 시장인데 비용이 6배 다릅니다. 게다가 저장소 스스로 장부 문제 세 건을 미해결로 적어 놨습니다 — 그중 하나는 "실현 손익은 청산 수수료를 빼는데 미실현 손익은 안 뺀다"입니다. 두 수를 더하면 안 됩니다. 이 도구는 판단을 재는 데 쓰고, 성적은 판단을 옮긴 쪽에서 재는 것이 맞습니다.
6. 써 보니
좋았던 것
- 공정성 장치가 진짜입니다. 봉을 한 곳에서 만들어 같은 글자로 뿌립니다. 모델 비교 실험의 전제가 코드에 있습니다
- 수수료가 판단 입력입니다. 한 줄 바꿔 두 판을 돌리는 실험이 그대로 됩니다. 이런 스위치가 있는 도구가 드뭅니다
- 미해결 버그를 목록으로 공개하고 테스트에 고정해 뒀습니다. 어디를 믿으면 안 되는지 미리 알 수 있습니다
- 화면이 좋습니다. 잔고·체결·판단 원문이 따로 뜨고, 체결 지연 초까지 보여 줍니다
아쉬운 것
- 브로커가 꼭 필요합니다. 도커든 Homebrew 든 메시지 브로커 없이는 한 줄도 안 돕니다
- Coinbase 쪽은 봉이 안 갑니다. 선택지가 사실상 Binance 하나입니다
- 기다릴 수가 없습니다. 3회차 미션에서 도구는 "1.5~2% 반등을 기다렸다가 판다"고 써 놓고 같은 호출 안에서 즉시 팔아 $1,129 를 수수료로만 잃었습니다. 한 번의 호출이 하나의 에피소드라 "기다린다"를 집행할 자리가 없습니다
- 확신도를 안 냅니다. 판단마다 0~100 을 받고 싶으면 프롬프트를 고쳐야 합니다
- 수량 소수 첫째 자리 제한(§4-3)
- 마지막 커밋이 두 달 반 전입니다
비용
| 코드·시세 | 0원 |
| 모델 | 이 검증 전체 약 $1.06 (네 모델, 실시간 88회 호출 + 재생 63회) |
| 틱 하나당 | 저렴한 모델 기준 $0.001~0.01, 에이전트당 |
| weltiq | 무료 플랜으로 슬롯 3개 |
7. 다음 행동
모델을 고르는 중이라면 이 도구를 모델 성향 계측기로 쓰십시오. 수익률 순위가 아니라 "수수료를 보는가 / 기다릴 줄 아는가 / 한 번에 얼마를 거는가"를 보면 값이 나옵니다. 그 뒤에 남는 질문은 하나입니다 — 판단은 받았는데, 이걸 24시간 누가 지키고 있나.
다음 편은 같은 질문을 반대쪽에서 봅니다. 여럿을 세우는 대신 하나에게 오래 맡기는 도구입니다.
weltiq 준비 — 3줄
- 가입: {{CTA_URL}}
- 마이 → 연결 관리에서 키 발급
claude mcp add weltiq https://weltiq.ai/mcp --header "Authorization: Bearer <키>"판단을 규칙으로 적어 내면 실시간 봉 위에서 모의로 돌려 주고, 체결·수수료·슬리피지를 원장으로 남겨 줍니다. 모의 전용입니다.
검증 기록 전문(설치 우회 과정·미션 3회 원문·수수료 A/B 60회 원문·결함 목록)은
reports/a/23-crypto-trading-arena/ 에 있습니다.