clawdtrader 설치부터 실전까지 — 계좌를 읽고 무엇을 몇 주 왜 사는지를 답하는 가장 작은 트레이딩 봇
600줄짜리 LLM 트레이딩 봇을 깔아 계좌와 과거 매매 기억을 읽히고, 기억만 바꿨을 때 판단이 어떻게 달라지는지 재고, 그 판단을 weltiq 규칙으로 옮겨 본 기록입니다.
clawdtrader — 계좌를 읽고 "무엇을 몇 주, 왜"를 답하는 가장 작은 트레이딩 봇이 글의 완료 조건: 독자는 계좌 상태를 읽고 "무엇을 몇 주 사고 왜 그런지"를 답하는 한 사이클을 돌리면 성공입니다.
| 하는 일 | 미국 주식 7종목의 값과 내 페이퍼 계좌, 그리고 과거 매매 기억을 읽어 사다 / 팔다 / 쉬다 중 하나와 종목·주수·이유를 JSON 한 줄로 냅니다 |
| 맞는 사람 | 판단을 내는 봇이 실제로 어떻게 생겼는지 200줄짜리 코드로 통째로 읽고 싶은 사람. 기억을 넣었다 뺐다 하며 판단이 어떻게 흔들리는지 직접 재 보려는 사람 |
| 안 맞는 사람 | 켜 두면 알아서 도는 완제품을 찾는 사람. 진입가·손절가 같은 가격 수준을 받고 싶은 사람 (이 도구는 안 냅니다). 암호화폐를 하려는 사람 |
| 이 글의 결과물 | {"action": "BUY", "symbol": "NVDA", "quantity": 30, "reason": "..."} 한 줄과, 같은 조건에서 기억만 바꿨을 때 그 줄이 어떻게 달라지는지 적은 표 |
| 준비물·비용 | 코드 0원(MIT) · 모델 한 판 $0.0001(gpt-4o-mini 기준, 20판에 $0.002) · 시세 0원(Alpaca 무료 IEX) · Alpaca 페이퍼 계좌 무료 · weltiq 는 별도 |
| 시간·난도 | 설치 5분 · 첫 판단까지 10분 · 난도 하 (venv 를 만들고 환경변수를 넣을 수 있으면 됩니다) |
| weltiq 와의 관계 | 비교합니다. 이 도구의 판단을 weltiq 규칙으로 옮기는 것까지는 됐지만, 검증한 날 미국장이 닫혀 있어 체결은 확인하지 못했습니다 (5절) |
| 검증 환경·날짜 | 2026-09-22 (KST) · macOS · Python 3.14 · 저장소 seetinc10/clawdtrader 2026-05-13 판 · Alpaca 페이퍼 |
| 제휴 고지 | 필자는 weltiq 의 제휴 기고자입니다. 이 글의 도구는 weltiq 와 무관한 제3자 오픈소스이며, 아래 수치는 모두 필자가 직접 돌려 얻은 것입니다. |
1. 이게 뭔가요
clawdtrader 는 "LLM 에게 계좌를 보여 주고 주문을 시키면 어떻게 되는가"를 가장 얇게 구현한 물건입니다. 명령줄 실행기 live_trader.py 는 60초마다 이 일을 합니다 — 장이 열렸는지 확인하고, 7개 종목의 최근 값을 받아 오고, 계좌와 보유 종목을 문장으로 만들고, 과거 매매 기억을 같은 문장에 붙여 모델에게 던지고, 돌아온 JSON 한 줄을 주문으로 바꿉니다.
재미있는 자리는 기억입니다. 이 도구는 매매 결과를 data/memory/ 의 JSONL 파일 넷에 쌓고, 다음 판단의 프롬프트 맨 앞에 그걸 그대로 끼워 넣습니다. 종목별 승패, 최근 손실 세 건, 저장해 둔 전략 문장이 순위가 매겨져 들어갑니다. 그래서 이 도구는 판단기이자 동시에 되먹임 실험 장치입니다. 4절이 그 이야기입니다.
| 저장소 | github.com/seetinc10/clawdtrader · MIT · 별 5개 |
| 최근 커밋 | 2026-05-13 |
| 언어·크기 | Python. 실제로 도는 명령줄 경로는 약 600줄 |
| 시장 | 미국 주식만. Alpaca 페이퍼 (현물 주식이며 선물·암호화폐 경로는 코드에 아예 없습니다) |
| 모델 | OpenAI 호환 아무거나. 기본값 gpt-4o-mini |
먼저 알아야 할 것 하나. README 는 이 도구를 실제보다 두 배쯤 크게 소개합니다. 4단계 역할 분담 파이프라인(정찰→논거→위험→집행), ATR 기반 브래킷 주문, S&P 500 스캐너, 뉴스 블록, 지표 블록, 94개 테스트 — 이 기능들을 담은 파일이 저장소에 없습니다. 그 기능을 쓰는 화면판(live_trader_gui.py)은 불러오기 단계에서 멈춥니다. 없는 모듈 3개(tools/alpaca_news.py, tools/live_indicators.py, tools/risk_rails.py)와 없는 함수 7개를 부르고, 테스트는 94개가 아니라 17개입니다.
깎으려고 적는 게 아닙니다. 실제로 도는 명령줄 경로는 깔끔하고, 이 글이 재는 것은 그쪽입니다. 다만 README 를 보고 "여기 위험 관리가 다 돼 있구나" 하고 켜면 안 됩니다.
2. 설치
검증된 한 경로입니다.
git clone https://github.com/seetinc10/clawdtrader
cd clawdtrader
python3 -m venv .venv
.venv/bin/pip install alpaca-trade-api openai python-dotenv requests pandas
requirements.txt 에는 LangChain 계열 4개가 더 있지만 명령줄 실행기에는 필요 없습니다. 위 다섯 개면 돕니다.
환경변수는 셋뿐입니다.
export ALPACA_API_KEY=... # alpaca.markets 페이퍼 계좌에서 발급
export ALPACA_SECRET_KEY=...
export ALPACA_BASE_URL=https://paper-api.alpaca.markets
export OPENAI_API_KEY=...
export OPENAI_API_BASE=https://api.openai.com/v1 # 다른 제공자면 여기를 바꿉니다
막히는 자리
| 증상 | 원인 | 넘어가는 법 |
|---|---|---|
python live_trader_gui.py 가 No module named '_tkinter' |
홈브루 파이썬에 Tk 가 안 딸려 옵니다 | brew install python-tk 로 넘어갈 수는 있는데, 넘어가도 그다음에서 다시 막힙니다(아래 줄) |
Tk 를 깔고 나면 No module named 'tools.alpaca_news' |
화면판이 부르는 모듈 3개가 저장소에 없음 | 화면판은 포기하고 live_trader.py 를 씁니다. 이 글 전체가 명령줄 경로입니다 |
첫 화면이 Market is CLOSED 만 반복 |
정상 동작입니다 (3절) | 미국 정규장(한국 시간 22:30~05:00)에 다시 돌리거나, 3절의 여섯 줄로 판단만 뽑습니다 |
.env.example 에 ALPACA_* 가 없음 |
예시 파일이 옛날 것 | 위 다섯 줄을 직접 넣습니다 |
| 테스트를 돌렸더니 기억 파일에 낯선 줄이 생김 | 테스트가 실제 data/memory/ 에 씁니다 |
처음 돌릴 때 rm data/memory/*.jsonl 로 비우고 시작합니다 |
화면판을 띄우다 막힌 자리
화면판(live_trader_gui.py)을 띄우면 이렇게 됩니다. 위쪽 빨간 덩어리가 Tk 가 없어서 나는 첫 오류이고, Tk 를 깔아도 아래 세 줄이 남습니다 — 저장소에 아예 없는 모듈을 부르고 있어서 여기서는 우회로가 없습니다.
3. 첫 결과
.venv/bin/python -u live_trader.py
대시보드는 없습니다. 저장소에 화면판 파일이 하나 있지만 2절에서 보신 대로 안 뜨고, 웹 UI 도 TUI 도 없습니다. 띄울 주소를 찾지 마십시오 — 터미널 출력이 전부입니다. 그래서 이 글의 그림은 전부 터미널입니다.
Account Status: ACTIVE
Portfolio Value: $98,911.47
Cash: $98,911.47
Trading Symbols: AAPL, MSFT, NVDA, GOOGL, AMZN, META, TSLA
Trade Interval: 60 seconds
Memory Status:
Strategy insights: 1
Tracked trades: 5
Historical win rate: 40.0%
============================================================
[2026-09-22 12:15:59] Checking market...
Market is CLOSED. Waiting...
설치가 끝나고 처음 띄운 화면
live_trader.py 를 처음 띄운 화면입니다. 초록색 세 군데 — 계좌가 ACTIVE, 평가액 $98,911.47, 기억 승률 40.0% — 가 보이면 Alpaca 키와 기억 파일이 둘 다 붙은 것입니다. 맨 아래 노란 줄이 3절의 나머지 이야기입니다.
여기까지 나오면 연결은 다 된 겁니다. 계좌가 붙었고 기억이 읽혔습니다.
그런데 장이 닫혀 있으면 이 도구는 아무것도 하지 않습니다. 모델을 부르지도, 값을 받아 오지도 않고 60초마다 같은 줄만 찍습니다. 시장 개폐 판정은 브로커의 달력을 그대로 믿습니다(clock.is_open). 장전·장후 시간외는 없는 것과 같습니다. 24시간 도는 봇이 아니라 미국 정규장 6시간 30분짜리 봇입니다.
장이 닫혀 있는데 판단만 보고 싶다면 여섯 줄이면 됩니다.
import live_trader as LT
t = LT.LiveTrader()
prices = t.get_current_prices(LT.SYMBOLS)
status, cash, bp = t.format_portfolio_status()
print(t.get_ai_decision(prices, status, cash, bp))
이렇게 나옵니다. 이 줄이 이 글의 완료 조건입니다.
{"action": "BUY", "symbol": "AAPL", "quantity": 10,
"reason": "Strong market position and growth potential"}
4. 제일 잘 쓰는 법 — 기억으로 조종하기
이 도구의 진짜 쓸모는 주문이 아니라 되먹임을 눈으로 재는 것입니다. 기억은 프롬프트 맨 앞에 붙는 글자 덩어리일 뿐이라, 넣었다 뺐다 하면서 같은 질문을 반복하면 "과거 기록이 판단을 얼마나 바꾸는가"를 숫자로 잴 수 있습니다.
기억에 글을 넣는 명령이 따로 있습니다.
.venv/bin/python strategy_chat.py --insight "NVDA를 거래해서 수익을 내줘. 그리고 왜 그렇게 했는지 설명해줘"
이 한 줄이 다음 판단부터 프롬프트에 들어갑니다. 실제로 확인한 두 조건입니다 — 같은 시각, 같은 값, 같은 모델, 각 8회.
| 조건 | 기억에 든 것 | 결과 8회 |
|---|---|---|
| 가 | 위 문장 하나만 | 매수 NVDA 8회 / 쉬다 0회. 주수 100·40·100·174·100·150·100·174 |
| 나 | 위 문장 + NVDA 손실 3건(−4.2%, −3.1%, −5.6%)과 AAPL 이익 2건 | 매수 NVDA 5회 / 쉬다 3회. 주수 20·30·40·20·50 |
기억이 붙은 프롬프트와 그 프롬프트가 받은 답 8개
이 도구가 일하는 화면입니다. 보라색이 모델에게 실제로 건네지는 기억 덩어리 — 미션 한 줄, 종목별 승패, 최근 손실 3건 — 이고, 아래 여덟 줄이 그 기억을 붙인 채 여덟 번 물어서 받은 답입니다. 노란 줄 셋이 "쉬다" 이고, 산 경우의 주수가 20~50 에 머뭅니다. 기억을 빼면 이 자리가 100~174 였습니다.
바뀝니다. 그것도 두 방향으로요.
- 방향 — 손실 기록을 넣기 전에는 한 번도 쉬지 않았고, 넣은 뒤에는 8번 중 3번 쉬었습니다.
- 크기 — 매수한 경우의 평균 주수가 117주에서 32주로 줄었습니다.
- 말 — 이유 문장이 바뀌었습니다. 기억 없이는 "Strong growth potential in AI and gaming sectors"였고, 손실 기록을 넣으면 "Recent losses in NVDA indicate a need for caution; waiting for a clearer signal before entering" 이 됩니다. 프롬프트에 들어간 그 손실을 직접 가리킵니다.
기억을 넣기 전, 아무 지시도 없을 때의 기본값은 AAPL 매수였습니다(3회 모두). 문장 하나를 기억에 넣자 8회 모두 NVDA 로 바뀌었습니다. 이 도구는 기억이라는 통로로만 조종됩니다 — 명령줄에 지시를 넣는 자리가 따로 없습니다.
기억이 안 해 주는 것
한도를 지키는 일은 기억이 아니라 코드가 합니다. 이 도구에는 "한 종목에 자산의 20% 넘게 넣지 않는다"는 고정 규칙이 있고, 모델이 낸 주수를 여기서 자릅니다. 실측입니다.
NVDA 227.29달러, 계좌 98,911달러 → 20% 한도 = 87주
모델이 낸 174주 -> 실제 주문 87주 (39,549달러 -> 19,775달러)
모델이 낸 150주 -> 실제 주문 87주
모델이 낸 40주 -> 실제 주문 40주 (한도 안이라 그대로)
20% 한도가 모델이 낸 주수를 자르는 화면
모델이 낸 주수가 코드에 잘리는 순간입니다. 노란 WARNING 세 줄을 보십시오 — 174·150·100 이 전부 87 로 깎입니다. 아래 두 줄(40주·20주)은 한도 안이라 그대로 나갑니다.
기억이 없을 때 모델이 낸 8개 주수 중 7개가 한도를 넘었고, 손실 기억을 넣으니 0개였습니다. 한쪽은 코드가 막고 한쪽은 기억이 막습니다. 둘 다 있어야 합니다.
5. weltiq 로 옮기기 — 통합 실험
이 도구가 낸 것은 종목·방향·주수 셋입니다. 진입 조건도, 손절가도, 목표가도 내지 않습니다. 그래서 옮길 때 빈 칸이 생깁니다.
weltiq 는 전략을 문서로 받아 페이퍼로 돌리는 서비스입니다. 옮긴 순서입니다.
1. 판단을 고릅니다. 4절 조건 나의 3회차 — BUY NVDA 30주, 이유 "Current price is low, potential for recovery based on market trends and past performance insights".
2. 빈 칸을 메웁니다. 진입 조건이 없으니 이 도구의 실제 동작에 가장 가까운 것으로 씁니다 — "포지션이 없으면 들어간다". 60초마다 무포지션일 때 매수 판단을 내는 동작이 그것입니다. 손절 3%·익절 5%는 도구의 설정 파일에 박힌 상수에서 가져왔습니다. 모델이 낸 값이 아닙니다.
표시: 진입 조건은 필자가 새로 쓴 것입니다. 도구가 낸 것은 종목·방향·주수뿐입니다.
3. 규칙 문서를 올립니다. 30주가 그대로 통과했습니다.
진입: (position.size = 0) → 진입 long
청산: 보호 손절 3% · 부분익절 1.6667R × 1
수량: 30
4. 슬롯을 만들고 켭니다. 모의 자본 10,000달러, 종목별 최대 손실 300달러, 실행 3시간. 30주 × 227.30달러 = 6,819달러, 미국 주식 수수료 0.
5. 여기서 멈췄습니다. 검증한 시각이 뉴욕 23시였습니다. 슬롯 신호등이 "휴장 — 다음 개장에 평가" 를 띄웠고, 체결은 0건입니다. 정지·삭제까지만 확인했습니다.
옮겨진 것과 안 옮겨진 것
| 칸 | 결과 |
|---|---|
| 종목 NVDA · 방향 롱 · 주수 30 | 그대로 |
| 손절 3% · 익절 5% | 그대로. 단 도구의 설정값이지 판단이 아닙니다 |
| 진입 시점 | 없음. 필자가 씀 |
| "AI 회복 기대"라는 이유 | 근거 기록에 글로만 남습니다. 규칙에는 들어갈 자리가 없습니다 |
| 20% 자산 한도 | 옮기지 못했습니다. 모의 자본을 10,000달러로 잡아 비슷하게 맞춘 것뿐입니다 |
그래서 이게 왜 값어치가 있나. 이 도구의 판단은 한 번 쓰고 사라집니다 — 켜 둔 동안만 살아 있고, 그 사이 무슨 값을 보고 왜 그렇게 했는지가 다음 달까지 남지 않습니다. 규칙으로 한 번 옮겨 두면 같은 문서 하나가 과거 재생과 모의 실행을 같은 몸으로 지나갑니다. 이번에는 그 앞부분까지만 확인했습니다. 체결을 본 뒤라야 "옮겨졌다"고 말할 수 있고, 아직 아닙니다.
6. 써 보니
좋은 것
- 작아서 다 읽힙니다. 판단이 만들어지는 전 과정이 600줄 안에 있고, 프롬프트 문자열이 그대로 보입니다. "LLM 트레이딩 봇"이라는 말이 실제로 뭘 뜻하는지 배우기에 이만한 크기가 없습니다.
- 기억이 진짜로 작동합니다. 4절의 8회×2조건이 그 증거입니다. 과거 손실을 넣으면 주수가 줄고 관망이 늘어납니다. 되먹임을 붙였다 뗐다 하며 재기에 좋은 실험대입니다.
- 자산 한도는 모델을 믿지 않습니다. 코드가 잘라 냅니다. 실제로 8번 중 7번 잘랐습니다.
- 돈이 거의 안 듭니다. 20판에 0.002달러, 시세 무료, 코드 MIT.
나쁜 것
- README 가 코드보다 큽니다. 역할 분담 파이프라인·브래킷 주문·위험 레일 표를 읽고 설치하면, 실제로는 한 번 물어보고 시장가로 사는 물건이 나옵니다. 화면판은 아예 안 켜집니다.
- 명령줄 경로에 손절이 없습니다. 시장가로 사고 끝입니다. 다음 판단에서 모델이 팔자고 해야 팔립니다. 손절 3%·익절 5%는 안 도는 화면판 쪽 설정값입니다. 켜 두고 자리를 비우면 안 됩니다.
- 이유가 근거가 아닙니다. 프롬프트에 오늘 값이 다 들어가는데, 나온 이유는 "Strong growth potential in AI and gaming sectors" 같은 일반론입니다. 준 숫자를 가리키는 문장은 한 번도 안 나왔습니다. 기억에 손실을 넣었을 때만 그 손실을 가리켰습니다.
- 주문을 내자마자 기억에 씁니다. 체결 여부와 상관없이요. 필자가 주문 하나를 내고 곧바로 취소했는데, 계좌에는 아무것도 없는 채로 기억에는 "NVDA 1주 매수, 결과 대기 중"이 남았습니다. 오래 돌릴수록 기억과 계좌가 갈라집니다.
- "오늘 등락률"이 오늘 것이 아닙니다. 프롬프트는
Today: +0.01%라고 적지만, 실제로는 최근 1분봉 안의 등락을 계산한 값입니다. 모델은 하루 등락인 줄 알고 읽습니다.
비용
| 항목 | 실측 |
|---|---|
| 모델 (gpt-4o-mini) | 한 판 485입력·39출력 토큰 = $0.0001. 20판 $0.002 |
| 60초마다 정규장 내내 | 하루 약 390판 = $0.04 |
| 시세 | 0원 (Alpaca 무료 IEX) |
| 코드·계좌 | 0원 |
7. 다음 행동
먼저 rm data/memory/*.jsonl 로 비우고 세 번 돌려 보세요. 그다음 strategy_chat.py --insight 로 문장 하나를 넣고 다시 세 번. 바뀌는 것을 직접 보는 것이 이 도구를 쓰는 이유입니다. 정규장에 켤 생각이라면 손절이 없다는 것만은 기억하시기 바랍니다.
이 연재에서 곧 DayTradingAgent 를 다룹니다. 이 도구가 안 내는 것 — 진입가·손절가·청산 조건 — 을 내는 쪽이라서, 같은 미국장을 놓고 "방향만 주는 도구"와 "가격 수준을 주는 도구"가 어떻게 다른지 나란히 볼 수 있습니다.
weltiq 준비 — 3단계 1. 가입: {{CTA_URL}} 2. 마이 → 연결 관리에서 키를 발급합니다 3.
claude mcp add weltiq --transport http https://weltiq.ai/mcp --header "Authorization: Bearer <키>"페이퍼 전용입니다. 이 글의 5절을 그대로 따라 해 보실 수 있습니다.
검증 원문·명령·응답 전체는 reports/a/26-clawdtrader/ 에 있습니다.