swarm-trader 설치부터 실제 체결까지 — 자료는 정말 공짜인데 안전장치가 비어 있습니다
20개 에이전트가 무료 자료(SEC EDGAR·yfinance)만으로 미국 주식을 판단합니다. 자료가 공짜라는 말은 실측으로 사실이었고, 「코드가 강제하는 리스크 관리」는 실제 주문에서 무너졌습니다.
33편. swarm-trader — 자료는 정말 공짜였고, 안전장치는 비어 있었습니다이 글의 완료 조건: 독자는 유료 키 하나 없이 20개 에이전트를 돌려 미국 주식 판단을 받아 보고, 그 판단이 브로커로 나갈 때 무엇이 검사되고 무엇이 안 되는지 자기 눈으로 확인하면 성공입니다.
| 하는 일 | 투자자 인격 13명 + 계량 전문가 7명이 각자 미국 주식을 분석하고, 포트폴리오 매니저가 그 신호를 모아 매수·매도·숏·커버·관망 하나와 주수를 냅니다. 주문은 알파카 페이퍼로 나갑니다 |
| 맞는 사람 | 유료 자료 구독 없이 멀티에이전트 판단을 돌려 보고 싶은 사람 · LLM 여럿의 의견이 어떻게 하나로 합쳐지는지 보고 싶은 사람 |
| 안 맞는 사람 | 한국 주식·크립토를 보는 사람(둘 다 경로가 없습니다) · 안전장치를 믿고 맡기려는 사람(§4.3 이 이 글의 본론입니다) |
| 이 글의 결과물 | 종목 21개에 대한 판단 21건, 그중 하나가 알파카 페이퍼에서 실제로 체결된 기록, 그리고 그 판단을 weltiq 로 옮기려다 받은 거절 |
| 준비물·비용 | 코드 0원(라이선스 파일 없음 — §1) · 자료 전부 무료(실측, §4.1) · LLM 토큰만 듭니다 — 3종목 1회차 $0.003984 실측 |
| 시간·난도 | 의존성 설치 36.083초 · 첫 판단 1분 44.60초(3종목) · 난도 중 |
| weltiq 와의 관계 | 오늘은 안 붙었습니다. 이 도구가 21종목 중 21종목을 「매수 아님」으로 판단했고, 그중 숏은 우리 미국주식 칸에 없습니다. §5 가 그 기록입니다 |
| 검증 환경·날짜 | macOS · Python 3.11.16 · 커밋 3470b82 · 2026-09-24 · LLM 은 OpenRouter 경유 openai/gpt-5.6-luna 고정 |
| 고지 | 필자는 weltiq 와 제휴를 맺고 기고합니다. 이 글의 모든 명령과 숫자는 위 환경에서 실제로 돌려 얻은 실측이고, 주문은 전부 모의입니다. 이 도구가 내는 SHORT·주수·확신도는 전부 그 도구의 출력이며 필자의 의견이 아닙니다 |
원문 로그와 원자료: reports/a/33-swarm-trader/
1. 이게 뭔가요
zhound420/swarm-trader 는 에이전트 20명이 미국 주식
하나를 각자 보고, 포트폴리오 매니저가 그 의견을 모아 주문을 내는 시스템입니다.
virattt/ai-hedge-fund(이 연재 2편)를 갈라 나온 것이고,
원본에서 바꾼 것 중 제일 큰 둘이 유료 자료를 무료로 갈아 끼운 것과 알파카 실행을 붙인 것입니다.
| 항목 | 값 | 확인 방법 |
|---|---|---|
| 주소 | github.com/zhound420/swarm-trader |
|
| 라이선스 | 없습니다 (license: null) |
GitHub API · ls LICENSE* 결과 없음 |
| 별 수 | ★58 · 포크 13 (관측일 2026-09-24) | GitHub API |
| 만들어진 날 | 2026-03-08 | GitHub API |
| 마지막 푸시 | 2026-03-22 — 6개월 전입니다 | GitHub API |
| 이 글이 돌린 커밋 | 3470b8291c438dc36b22ed37b7e56ba2bbf249b5 |
git log -1 |
| 코드 크기 | src/ + app/ 20,135줄 |
wc -l 실측 |
| 에이전트 | 20 (LLM 인격 13 + 계량 7) | README · --analysts |
| 브로커 | 알파카 페이퍼 하드코딩 (paper-api.alpaca.markets) |
src/alpaca_integration.py:23 |
라이선스 파일이 없다는 것부터 밝혀 둡니다. 저장소에 LICENSE 가 없고 GitHub API 도
null 을 돌려줍니다. 기본값은 「저작권자가 모든 권리를 보유」라, 이 글은 코드를 인용만 하고
가져다 쓰지 않았습니다. 따라 하실 분도 이 점은 알고 시작하세요.
이 도구의 뼈대
trading_mode.json → 스윙이냐 데이냐
↓
애널리스트 20명 (각자 signal + confidence + reasoning)
↓
포트폴리오 매니저 → action · quantity · confidence · reasoning ← LLM 이 정합니다
↓
risk_manager.py → "코드가 강제하는" 검증
↓
execute_trades.py → 알파카 주문
↓
portfolio_monitor.py → 손절 감시
README 가 이 그림에 대해 하는 두 가지 강한 주장이 있습니다. 이 글은 그 둘을 실제로 재 봅니다.
"Trades execute on Alpaca paper trading through a code-enforced risk management layer that no agent can override."
"execute_trades.py → Alpaca bracket orders with mandatory stops"
2. 설치하기
파이썬 3.11 이상이면 됩니다. 필자는 3.11.16 으로 돌렸습니다.
git clone https://github.com/zhound420/swarm-trader.git
cd swarm-trader
python3.11 -m venv .venv
.venv/bin/pip install -e .
의존성 설치는 36.083초였습니다. 설치 중에 경고가 하나 뜨는데 무시해도 됩니다 —
WARNING: fastapi 0.104.1 does not provide the extra 'standard'. 웹 앱 쪽에서만 쓰는 항목입니다.
.env 는 이렇게 채웁니다.
ALPACA_API_KEY=... # 알파카 페이퍼 키 (무료)
ALPACA_API_SECRET=...
OPENROUTER_API_KEY=... # LLM 제공자 하나. Ollama 면 키 0개도 됩니다
LLM_PROVIDER=OpenRouter
LLM_MODEL=openai/gpt-5.6-luna
대시보드는 없습니다. app/ 에 FastAPI 백엔드가 있지만 이 도구의 본체는 CLI 이고,
운영 문서(PLAYBOOK.md)도 전부 명령줄로 설명합니다. 이 글의 화면은 전부 터미널 출력입니다.
2.1 막힌 자리 — 「선택」이라던 계좌가 임포트를 막습니다
README 는 데이트레이딩 계좌를 이렇게 안내합니다.
"Day trading account (optional — falls back to primary if not set)" "If only one account is configured, both modes share it (backward compatible)."
사실이 아닙니다. 스윙 키만 넣고 스윙 모드로 돌리면 임포트에서 죽습니다.
스윙 모드로 돌렸는데 day 계좌가 없다고 막힙니다. src/alpaca_integration.py:33 이 모듈을 읽어 들이는 시점에 _get_headers("day") 를 부르기 때문입니다 — 어느 모드로 돌리든 무조건 지나갑니다. 되돌아가는 길은 swing→day 한 방향뿐이라(src/accounts.py:95-100) day→swing 폴백이 없습니다
고치는 법은 한 줄입니다. .env 에 같은 키를 한 번 더 적으면 됩니다.
ALPACA_DAY_API_KEY=<위와 같은 키>
ALPACA_DAY_API_SECRET=<위와 같은 비밀키>
계좌를 둘로 나눠 쓸 생각이 없어도 이 두 줄이 있어야 뜹니다. README 를 그대로 따라 하면 첫 명령에서 막히는 자리라 먼저 적었습니다.
2.2 잠복 버그 하나 — 스윙 모드의 장중 자료가 빈 헤더로 나갑니다
gather_data.py 는 스윙 모드에서 ALPACA_SWING_API_KEY / ALPACA_SWING_API_SECRET 을 읽습니다.
그런데 이 이름은 저장소 어디에도, .env.example 에도 없습니다. 실제로 불러 봤습니다.
swing headers empty? {'APCA-API-KEY-ID': True, 'APCA-API-SECRET-KEY': True}
swing-mode portfolio call -> 401 {"message": "unauthorized."}
ALPACA_SWING 이라는 문자열이 저장소에 등장하는 곳은 딱 세 곳이고, 그중 둘이 이 버그이고
나머지 하나는 오류 메시지입니다. 스윙 모드로 gather_data.py 를 돌리면 장중 자료가 안 옵니다.
.env 에 이 이름으로도 키를 넣어 두면 피할 수 있습니다.
3. 설치했으니 일단 한 번 돌려봅시다
3.1 첫 판단
진입점은 run_hedge_fund.py 입니다. 자기 독스트링이 스스로를 "Canonical execution script" 라고
부릅니다. run_analysis.py 라는 거의 복제본이 옆에 있는데 다르게 동작하니 이쪽을 쓰세요
(§6 에서 다시 말합니다).
이렇게 말합니다
엔비디아·애플·SPY 를 스윙 모드로 분석해 줘. 주문은 아직 내지 말고.
그러면 이런 게 돌아옵니다
애널리스트 일곱이 종목마다 붙고, 마지막에 종목별 판단이 나옵니다. 화면 아래쪽 세 칸을 보세요 — NVDA·AAPL·SPY 가 **전부 SHORT** 이고 확신도가 82·84·72 입니다. 그리고 그 위 execute_trades 로그의 «APPROVED: SHORT 68 NVDA @ $0.00 ($0 = 0.0% of equity)» — 이 $0.00 이 §4.3 의 주제입니다
직접 치고 싶다면.venv/bin/python run_hedge_fund.py --mode swing --tickers NVDA,AAPL,SPY
`--execute` 를 붙이지 않으면 **드라이런**입니다. 기본값이 안전한 쪽이라는 뜻이고, 이건 좋은 설계입니다.
`--tickers` 는 계좌에 포지션이 없으면 **필수**입니다 — 없으면 `exit 1` 로 끝납니다.
3종목 1회차가 1분 44.60초 걸렸습니다. 6종목은 2분 29.39초였습니다.
3.2 초보자가 막히는 자리 다섯
| 증상 | 원인 | 고침 |
|---|---|---|
ValueError: No Alpaca account configured for mode 'day' |
임포트 시점에 day 계좌를 찾습니다 | .env 에 ALPACA_DAY_* 추가 (§2.1) |
No tickers to analyze |
포지션이 없으면 --tickers 가 필수입니다 |
--tickers NVDA,AAPL |
Quote not found for symbol: BTCUSD |
크립토는 이 도구의 자리가 아닙니다 | 미국 주식만 넣으세요 (§4 의 S1) |
| 스윙인데 장중 자료가 비어 있다 | ALPACA_SWING_API_KEY 미정의 (§2.2) |
그 이름으로도 키를 넣으세요 |
Snapshot for ... already exists |
하루 한 번만 기록합니다. 정상입니다 | 덮어쓰려면 --force |
4. 본격적으로 — 실전 시나리오
4.1 시나리오 D. 「자료가 정말 공짜인가」를 직접 세어 봤습니다
README 의 제일 큰 자랑이 이겁니다.
"Zero paid data APIs required." Hybrid data layer uses SEC EDGAR + yfinance. Works fully free out of the box.
읽고 믿는 대신 나가는 요청을 전부 가로채 호스트를 셌습니다. 자료 함수 여섯 개를 직접 부르고,
requests·urllib·curl_cffi(yfinance 1.7.0 이 쓰는 것) 세 갈래를 다 후킹했습니다.
자료 함수 여섯 개가 전부 성공했고(가격 80봉·재무지표 4·시총·내부자거래 10·뉴스 10·항목검색 4), 나간 곳은 sec.gov 계열 21회와 야후 파이낸스 계열 11회가 전부입니다. 맨 아래 with_auth_header 가 비어 있는 것을 보세요 — **인증 헤더가 붙은 요청이 한 건도 없습니다.** 키 없이 다 됩니다
전체 회차(애널리스트 20명 포함)를 돌렸을 때도 같았습니다. www.sec.gov 129회 ·
data.sec.gov 16회 · paper-api.alpaca.markets 2회. 인증 헤더가 붙은 것은 알파카 2회뿐이고
그 키도 무료입니다.
세 줄 요약
- 무엇이 나왔나 — 유료 호스트 0건.
api.financialdatasets.ai($200/월)는 코드에 남아 있지만src/tools/api_original.py에 아무도 임포트하지 않는 채로 있습니다. 현재src/tools/api.py는api_free를 그대로 재수출하는 9줄짜리 파일입니다 - 몇 단계였나 — 함수 호출 여섯 번. 키 0개
- 무엇이 안 되나 — README 가 이 자리에서 한 번 거짓말을 합니다. README 666행은 이 층을 "유료→무료 폴백 하이브리드 디스패처" 라고 설명하는데, 코드에 유료 경로가 없습니다. 폴백이 아니라 통째로 교체된 것이고, 결과적으로 사용자에게는 더 좋은 쪽입니다
돈 이야기. 이 도구를 돌리는 데 드는 돈은 LLM 토큰뿐입니다. OpenRouter 사용량을 회차 전후로 찍어 재 봤습니다 — 3종목 1회차 $0.003984 (
openai/gpt-5.6-luna, 애널리스트 7명). 자료 구독료는 0원이 맞습니다.
4.2 시나리오 D-2 (= S4). 21종목을 돌렸더니 매수가 0건이었습니다
이 도구가 제일 잘하는 일은 에이전트 여럿의 의견을 하나로 합치는 것입니다. 그래서 그걸 재 봤습니다. 서로 성격이 다른 바구니 다섯 개, 종목 21개.
N 과 바구니를 먼저 정하고 시작했습니다. 결과를 보고 바구니를 고르면 그 순간 이 표는 광고가 됩니다.
| 회차 | 바구니 | 종목 | 결과 |
|---|---|---|---|
| 1 | 대형 기술·지수 | NVDA · AAPL · SPY | SHORT 3 |
| 2 | 안전자산·배당 | GLD · TLT · KO | SHORT 3 |
| 3 | 금융·필수소비·결제 | MSFT · JPM · JNJ · PG · V · COIN | SHORT 4 · HOLD 2 |
| 4 | 반도체·플랫폼 | AVGO · TSM · GOOGL · META · AMZN · AMD | SHORT 4 · HOLD 2 |
| 5 | 성장주 | PLTR · CRM · NET | SHORT 3 |
| 21종목 | SHORT 17 · HOLD 4 · 매수 0 |
21종목 중 매수가 한 건도 없습니다. 금을 숏하고 미 국채를 숏하고 코카콜라를 숏했습니다. 확신도는 58%에서 94%까지 폭넓게 나왔고, 제일 높았던 것은 COIN 94% — "Near-unanimous bearish signals support a full-size short."
세 줄 요약
- 무엇이 나왔나 — 21건의 판단. 방향은 17건이 숏, 4건이 관망. 근거 문장이 매번 붙습니다
- 몇 단계였나 — 회차당 명령 한 줄. 3종목 1분 45초, 6종목 2분 30초
- 무엇이 안 되나 — 이게 이 도구의 성질인지 그날 장의 성질인지는 이 글로 못 가릅니다. 같은 날(SPY −0.77%) 한 번에 몰아 돌린 것이라 국면이 하나입니다. 다른 날 다시 재야 합니다. 다만 금·국채·필수소비재까지 같은 방향이 나온 것은 기록해 둘 만합니다
이 결과가 §5 를 통째로 바꿔 놓았습니다 — 숏은 우리 미국주식 칸에 없으니까요.
4.3 시나리오 S5. 주문을 한 번 내 봤습니다 — 그리고 안전장치 셋이 연달아 비었습니다
이 절이 이 글의 본론입니다.
§3 의 로그에서 계속 눈에 걸리던 줄이 있습니다.
APPROVED: SHORT 68 NVDA @ $0.00 ($0 = 0.0% of equity)
NVDA 68주가 0달러일 리가 없습니다. 그래서 실제로 주문을 내 봤습니다. 도구가 4회차에서 낸 판단 그대로 — AMZN 숏 75주. 도구 자신의 명령 통로를 썼습니다(README 의 크론 메시지가 시키는 것과 같은 방식입니다).
echo '{"trades":[{"ticker":"AMZN","action":"short","qty":75,
"reasoning":"High-confidence bearish signal with no meaningful bullish analyst support."}]}' \
| .venv/bin/python execute_trades.py --mode swing
「코드가 강제한다」는 리스크 층이 AMZN 75주 숏을 «$0.00 = 0.0% of equity» 로 통과시켰습니다. 그 아래가 실제 체결 결과입니다 — 249.25 에 75주 체결, 평가액 **−18,691.5 달러**, 자산 98,911.92 의 **18.9%**. 스윙 모드 1종목 한도는 **8%** 입니다. 그리고 order_class 가 빈 문자열, legs 가 null, 미체결 주문 목록이 [] — **보호 손절이 한 건도 없습니다**. 맨 아래가 왜 0 이 되는지의 코드입니다
왜 이렇게 되나. 판단이 두 프로세스를 건너가면서 가격이 떨어져 나갑니다.
리스크 에이전트는 그래프 안에서 현재가를 제대로 알고 있습니다. 포트폴리오 매니저도 그
가격으로 최대 주수를 계산합니다. 그런데 최종 산출물인 PortfolioDecision 의 스키마에는
가격 칸이 없습니다 — action · quantity · confidence · reasoning 넷뿐이고, 레벨 셋은
LLM 이 원하면 넣는 선택 항목입니다.
run_hedge_fund.py 는 그 dict 를 JSON 으로 만들어 execute_trades.py 를 별도 프로세스로
띄워 넘깁니다. 받는 쪽은 가격을 모르니 보유 포지션에서 찾습니다.
# execute_trades.py:392-394
pos = positions.get(ticker, {}) # 새 종목이면 빈 dict
ref_price = entry_price or limit_price or float(pos.get("current_price", 0))
새로 사는 종목은 보유 목록에 없습니다. 그래서 ref_price = 0 이 되고, 그 0 이 세 군데로 퍼집니다.
| 무엇이 | 어떻게 되나 | 어디 |
|---|---|---|
| 1종목 한도 8% | trade_value = qty × 0 = 0 → 0% > 8% 는 영원히 거짓 → 항상 통과 |
risk_manager.py:176, 351-356 |
| 섹터 한도 30% | 같은 trade_value 를 씁니다 → 항상 통과 |
risk_manager.py:365-374 |
| 최소 현금 20% | 같음 → 항상 통과 | risk_manager.py:338-348 |
| 의무 브래킷(−7% 손절 / 3R 목표) | ref > 0 이라야 계산합니다 → 아예 안 붙습니다 |
execute_trades.py:416-430 · :167-181 |
즉 이 검사들은 「이미 들고 있는 종목을 더 사는 경우」에만 작동합니다. 새 포지션을 여는 주문 — 검사가 존재하는 바로 그 이유 — 에서는 전부 조용히 통과합니다.
그리고 감시기가 그 포지션을 못 봅니다
README 는 portfolio_monitor.py 가 손절을 자동 집행한다고 합니다. AMZN 숏 75주를 들고
있는 상태에서 돌렸습니다.
「Positions: 1」 이라고 적고 0주짜리 BTCUSD 하나만 표에 올립니다. **AMZN 75주 숏은 목록에 없습니다.** 그리고 «All positions within stop thresholds» — 18.9% 짜리 무방비 숏을 들고 있는 계좌에 대고 하는 말입니다. 아래가 원인입니다: long_positions 를 qty > 0 으로 거르고 그 목록만 손절 검사에 넣습니다. 숏은 수량이 음수라 고리에 들어오지 못합니다
README 표의 "Short selling — Full short selling support" 와 "portfolio_monitor.py → auto-sells stops" 는 둘 다 참인데 서로 맞물리지 않습니다. 숏을 열 수는 있고, 그 숏의 손절은 아무도 안 봅니다.
세 줄 요약
- 무엇이 나왔나 — 실제 체결 1건(AMZN 75주 숏 @ 249.25). 그리고 안전장치 세 층이 연달아 빈 것
- 몇 단계였나 — 명령 한 줄. 도구 자신의 문서가 시키는 방식 그대로
- 무엇이 안 되나 — 위 전부. 단 드라이런이 기본값인 것은 진짜입니다.
--execute없이는 브로커에 안 닿고, 엔드포인트는 페이퍼로 박혀 있어 실계좌 URL 이 코드에 없습니다
4.4 시나리오 S7. 중지 조건이 발동했습니다 — 나가는 쪽에서
포지션을 정리하려고 도구의 커버 명령을 냈습니다. 그리고 이 글에서 제일 이상한 장면이 나왔습니다.
Legacy validator BLOCKED cover AMZN:
Trade value $18,716 exceeds max $7,911 (8% of portfolio)
들어올 때 통과시킨 바로 그 8% 규칙이, 나갈 때 길을 막았습니다.
이유는 §4.3 의 그림 그대로입니다. 들어올 때는 AMZN 이 보유 목록에 없어 가격이 0 이었습니다. 나갈 때는 포지션이 생겼으니 가격이 있습니다. 그래서 같은 계산이 이번에는 18,716 달러를 정확히 보고, 한도 7,911 달러를 넘는다고 막습니다.
검사가 들어올 때는 눈이 멀고 나갈 때만 눈을 뜹니다. 그 결과가 이것입니다 — 도구가 들여보낸 크기를 도구가 내보내 주지 않습니다.
필자는 알파카 API 로 직접 청산했습니다. 도구를 거치지 않고서요.
| 진입 | 75주 숏 @ 249.25 · 2026-09-23T19:43:36.523944264Z |
| 청산 | 75주 커버 @ 249.450667 · 2026-09-23T19:44:50.545625032Z |
| 보유 시간 | 74초 |
| 실현 손익 | −15.050025 USD |
| 자산 | 98,911.92 → 98,894.90 |
| 청산 경로 | 도구 밖. DELETE /v2/positions/AMZN 을 직접 호출 |
세 줄 요약
- 무엇이 나왔나 — 중지 조건이 실제로 발동한 유일한 사례. 그런데 발동한 자리가 출구였습니다
- 몇 단계였나 — 커버 명령 1회(막힘) → 알파카 직접 호출 1회(성공)
- 무엇이 안 되나 — 도구만으로는 이 포지션을 닫을 수 없습니다. 8%를 넘는 포지션이 한 번 열리면, 도구의 커버는 영원히 막힙니다. 수량을 쪼개면 나갈 수는 있습니다 — 다만 그걸 사람이 알아채고 손으로 해야 합니다
4.5 「스케줄 자율 운용」은 어디에 있나
README 는 "3-cron autonomous pipeline" 과 "Automation — Manual runs → 3-cron autonomous pipeline" 을 앞세웁니다. 코드에서 찾아봤습니다.
| 찾은 것 | 결과 |
|---|---|
APScheduler · schedule · crontab · systemd · launchd |
0건 |
상주 루프(while True + sleep)로 회차를 도는 코드 |
0건 |
알파카 /clock 호출 (장중인지 확인) |
0건 |
| 도커 | docker-compose.yml 은 일회성 실행입니다 |
마크다운의 cron 언급 |
README 28줄 · PLAYBOOK 23줄 · CRON-ARCHITECTURE 15줄 · BRIDGE-DESIGN 3줄 |
스케줄러는 없습니다. 그리고 있는 쪽도 예상과 다릅니다. README 가 적어 둔 것은 이런 모양입니다.
openclaw cron add --name swing-midday \
--cron "0 12 * * 1-5" --tz "America/Los_Angeles" --exact \
--agent swing-agent \
--message 'Midday analysis.
1. Gather data: poetry run python gather_data.py
2. Analyze universe stocks for swing mode
3. Execute: echo trades | poetry run python execute_trades.py --mode swing
4. Report: trades executed, rejections from risk manager.'
시간표에 걸리는 것이 명령이 아니라 문장입니다. openclaw 라는 별도 제품(의존성에 없습니다)이
정해진 시각에 또 다른 LLM 에이전트를 깨우고, 그 에이전트가 이 영어 지시문을 읽고 스크립트를
골라 돌립니다. "Analyze universe stocks for swing mode" 는 실행되는 줄이 아니라 사람 말입니다.
그러니 「자율 운용」의 정확한 뜻은 이렇습니다 — 타이머에 걸린 LLM 이 영어로 적힌 할 일 목록을 읽고 대신 타이핑해 주는 것. 나쁜 설계라는 말이 아닙니다. 다만 저장소를 받아서 켜 두면 알아서 도는 물건이 아니라는 것은 알고 시작해야 합니다. 시간표를 세우는 것은 독자 몫입니다.
그리고 장중 게이트가 코드에 없다는 점이 여기에 붙습니다. 알파카 /clock 을 아무도 부르지
않으므로, 주말이나 장 마감 뒤에 회차가 돌면 주문이 그대로 큐에 쌓입니다. 크론 표현식의
* * 1-5 가 유일한 방어선입니다.
4.6 돌리지 않은 시나리오
- S1 글로벌 종목 하나(BTC-USD): 이 도구로는 안 됩니다. 회차마다
Quote not found for symbol: BTCUSD가 떴습니다. 유니버스가 하드코딩된 미국 티커이고, 수량은 항상 정수 주수이며, 브로커는 알파카 주식 페이퍼입니다. 크립토 경로가 없습니다 - S2 한국 종목: 이 도구로는 안 됩니다. 위와 같은 이유입니다
- S3 내 실행 기록 복기: 이 도구는 자기 스냅샷만 읽습니다. 우리 내보내기를 먹는 입구가 없습니다
- S6 고리 한 바퀴: 닫지 못했습니다. 판단 → 주문 → 체결까지는 갔는데(§4.3), 규칙 수정 뒤 재주문으로 돌아오지 못했습니다. 청산이 도구 안에서 막혔기 때문입니다(§4.4). 고리가 끊긴 자리가 기록으로 남은 것이 이번 회차의 결과입니다
- S8 끊고 다시 붙이기: 안 돌렸습니다. 상주 프로세스가 없어 끊길 것이 없습니다(§4.5)
- S9 수수료 바꿔 재기 · S10 대결: 안 돌렸습니다. B축 회차의 몫입니다
5. weltiq 와 연결하기
5-1. 옮기려 했고, 거절당했습니다
절차는 다른 편과 같습니다. 도구의 숫자를 규칙 문서로 옮기고, 근거를 적고, 중지 조건과 함께 슬롯을 만듭니다. 옮길 것은 이 도구가 제일 높은 확신도로 낸 판단이었습니다 — COIN 숏 52주, 확신도 94%.
레벨은 도구가 안 냈으므로 도구의 코드가 쓰는 식을 그대로 다시 계산했습니다. 손절 = 기준가 × (1 + 0.07), 목표 = 기준가 − 손절거리 × 3.0. 숫자는 하나도 만들지 않았습니다.
POST /v1/strategy-rules 가 422 로 거절했습니다 — {"code":"invalid_rules","detail":"unsupported_direction"}. 도구가 낸 숫자(진입 숏 52주·손절 212.09·목표 156.59)는 전부 그대로인데, 우리 us-equity 에 숏 방향이 없습니다
weltiq 에서 숏이 열려 있는 곳은 파생 세 군데뿐입니다 — binance-usdm · bybit-linear · cme.
미국 주식은 롱 전용입니다.
그래서 이 판단은 근사할 방법이 없습니다. 종목을 바꿔 롱으로 옮기면 그건 도구의 판단이 아니라 필자의 판단이고, 방향을 뒤집으면 더 나쁩니다. 우리 쪽에 칸이 없으면 그대로 기록하는 것이 이 연재의 규칙이라 그렇게 합니다.
21종목 중 롱이 한 건도 없었다는 것(§4.2)이 여기서 값을 치릅니다. 매수가 하나라도 나왔으면 이 절에 우리 체결 기록이 실렸을 겁니다. 오늘은 없습니다.
5-2. 그런데 이 편은 붙는 방향이 반대입니다
이 연재에서 5절은 대개 이런 모양입니다 — 도구가 판단은 하는데 주문을 못 내니 우리가 그 자리를 채운다. 이번 편은 뒤집혀 있습니다.
| 이 도구 | weltiq | |
|---|---|---|
| 미국 주식 숏 | 됩니다 | 안 됩니다 |
| 새 포지션에 1종목 한도 | 안 걸립니다(§4.3) | 필수. 없으면 슬롯 생성 거절 |
| 새 포지션에 손절 | 안 붙습니다(§4.3) | 규칙 문서에 레벨이 없으면 거절 |
| 숏 포지션 손절 감시 | 못 봅니다(§4.3) | 방향 무관 |
| 들어간 크기로 나가기 | 막힙니다(§4.4) | 청산에 진입 한도를 다시 걸지 않습니다 |
우리가 못 하는 칸이 하나, 저쪽이 못 하는 칸이 넷입니다. 그리고 저쪽이 못 하는 넷은 전부 「들어간 뒤에 무슨 일이 생기나」쪽입니다.
그래서 이 도구를 우리 위에서 쓰는 법은 이렇게 정리됩니다.
- 숏 판단은 못 옮깁니다. 미국 주식이 롱 전용인 한 그렇습니다
- 매수 판단이 나오면 그때는 옮길 값이 큽니다 — 도구가 안 붙여 주는 한도·손절·감시를 슬롯이 전부 들고 있으니까요. 도구의 약한 자리와 우리의 강한 자리가 정확히 겹칩니다
- 이 조합이 해 주지 않는 것: 우리 슬롯은 도구의 확신도를 크기에 반영하지 않습니다. 94%든 58%든 옮겨진 주수는 도구가 낸 그대로입니다
5-3. 이 편에서 우리 쪽에 남은 숙제
정직하게 하나 적어 둡니다. 이 도구는 미국 주식 숏을 실제로 냅니다. 그 판단을 재려면 우리에게 그 칸이 있어야 하는데 없습니다. 「도구가 원했는데 우리에게 없는 칸」으로 기록합니다.
대신 실행 구간을 꿰는 실은 이 편에서도 그대로였습니다. 거절된 문서든 통과한 문서든
doc_hash 로 남고, 무엇이 왜 거절됐는지가 코드와 함께 기록에 남습니다.
실전 구간은 아직 열려 있지 않습니다 — 「같은 문서가 그대로 간다」까지가 사실이고 그
뒤는 예정이며, 승격 사다리가 관문입니다.
(이 글은 우리 쪽 슬롯을 만들지 않았습니다. 규칙 문서가 422 로 거절돼 슬롯 생성까지 가지 못했기 때문입니다. 따라서 정지·삭제할 슬롯도 없습니다. 도구 쪽 알파카 페이퍼 포지션은 74초 만에 청산했고 계좌는 비어 있습니다.)
6. 써 보니
좋았던 것
- 자료가 정말 공짜입니다. 이 글에서 잰 것 중 README 의 주장이 가장 깨끗하게 맞아떨어진 자리입니다. 인증 헤더 0건, 유료 호스트 0건, 회차 비용은 LLM 토큰뿐($0.003984/3종목). 200달러짜리 구독을 SEC EDGAR + 야후로 갈아 끼운 것은 이 포크의 진짜 기여입니다
- 기본이 드라이런입니다.
--execute없이는 브로커에 안 닿고, 알파카 주소가 페이퍼로 박혀 있어 실계좌 URL 이 코드에 아예 없습니다 - 판단에 근거가 반드시 붙습니다.
reasoning이 필수 필드라 빈 채로 나올 수 없고, 애널리스트 20명이 각자 자기 근거를 냅니다 - 에이전트를 직접 만들 수 있습니다.
--analysts로 조합을 바꾸고, 새 인격을 추가하는 경로가 열려 있습니다
아쉬웠던 것
- 「코드가 강제하는 리스크 관리」가 새 포지션에서 통째로 비어 있습니다. 8% 한도·섹터 한도· 현금 유보·의무 손절 넷이 전부 기준가 0 으로 통과합니다(§4.3). 원인은 프로세스 경계에서 가격이 떨어져 나가는 것 하나인데, 결과는 README 의 제일 큰 주장 둘을 동시에 무너뜨립니다
- 숏 포지션의 손절을 아무도 안 봅니다.
portfolio_monitor.py가qty > 0으로 거릅니다(§4.3) - 들어간 크기로 나갈 수 없습니다. 8% 넘는 포지션은 도구의 커버가 막습니다(§4.4)
- README 가 코드와 어긋나는 자리가 넷입니다 — 「day 계좌는 선택」(§2.1), 「유료→무료 폴백 하이브리드」(§4.1), 「3-cron 자율 파이프라인」(§4.5), 그리고 숏 지원과 손절 감시가 맞물린다는 인상
- 진입점이 둘이고 다르게 동작합니다.
run_analysis.py가run_hedge_fund.py의 거의 복제본인데, 실행을 같은 프로세스 안에서 처리하고 스윙 의무 브래킷을 적용하지 않으며 기본 모델도 다릅니다. 같은 미션에 다른 경로가 붙는 함정입니다 - 6개월째 푸시가 없고 라이선스 파일이 없습니다
이런 사람에게 맞다 / 안 맞다
맞다 — 유료 자료 없이 멀티에이전트 판단을 돌려 보고 싶은 사람. 그리고 판단을 받아서 자기 실행 층에 붙일 사람. 판단 산출부는 깨끗하고 근거가 붙어 나옵니다.
안 맞다 — 이 도구의 안전장치를 믿고 --execute 를 걸어 두려는 사람. §4.3·§4.4 를 고치기
전에는 켜 두지 마세요. 그리고 한국 주식·크립토를 보는 사람.
7. 다음 편 예고
다음은 alex-jb/orallexa-ai-trading-agent 입니다. 이 편의 도구가 브래킷을 붙이겠다고
적어 놓고 새 포지션에서 안 붙였다면, 다음 편은 브래킷 코드는 진짜인데 자율 경로가
손절을 안 넘기는 물건입니다. 그리고 이 연재에서 확신도를 크기에 반영하는 설비가 가장 잘
갖춰진 도구이기도 합니다 — 이번 편에서 94%와 58%가 똑같이 취급되는 것을 봤으니,
그 다음 질문으로 자연스럽게 이어집니다.