TradingAgents 설치부터 실전까지 — 에이전트 열한 명이 토론하는데 열세 판 전부 매도였습니다

★10만짜리 다중 에이전트 트레이딩 프레임워크를 깔고, 같은 질문을 열세 번 던져 답이 얼마나 흔들리는지 실측하고, 그 결론을 weltiq 로 옮겨 봅니다. 열세 판 전부 매도 쪽이었습니다.

12편. TradingAgents — 에이전트 열한 명이 토론해서 결론을 내는 프레임워크

이 글의 완료 조건: 같은 질문을 여러 판 던져 등급의 분포를 직접 세어 보고, 그 도구가 진입 조건을 숫자로 말하는지 아닌지를 확인하면 성공입니다. 한 판으로는 이 도구의 성격을 못 읽습니다.

하는 일 트레이딩 회사의 조직도를 그대로 LLM 에이전트로 옮겼습니다. 애널리스트가 자료를 읽고, 강세론자와 약세론자가 서로 반박하며 토론하고, 리서치 매니저가 판정하고, 트레이더가 실행안을 쓰고, 리스크 팀 셋이 또 논쟁한 뒤 포트폴리오 매니저가 결론을 냅니다
맞는 사람 이미 들고 있는 것을 어떻게 할지 묻고 싶은 사람, 결론보다 근거를 보고 싶은 사람. 토론 문서를 끝까지 읽을 생각이 있으면 이 목록에서 제일 읽을거리가 많습니다
안 맞는 사람 지금 무엇을 살지 숫자로 받고 싶은 사람(이 도구는 그 칸을 잘 안 채웁니다) · 한 번 돌려 보고 도구를 판단할 사람(4절이 그 이유입니다)
이 글의 결과물 열세 판의 등급 분포(Hold 0 · Underweight 6 · Sell 7 · Buy 0), 같은 날 같은 종목의 답이 갈린 원인, 장부를 줬을 때와 안 줬을 때 지시가 달라지는 실측, 그리고 고리가 어디서 멈췄는지의 기록
준비물·비용 코드 0원(Apache-2.0) · 모델 돌릴 때마다 듭니다 — 이 글 13판 $0.754369, 판당 평균 $0.058 · 시세 0원(FRED·Alpha Vantage 키는 선택) · weltiq 5절을 따라 할 때만
시간·난도 설치 3.3초, 한 판에 3~5분. 난도 중 — venv 와 환경변수를 만질 수 있으면 됩니다
weltiq 와의 관계 붙습니다. 다만 이번엔 고리가 안 돌았습니다 — 이 도구는 "언제 사라"를 숫자로 말하지 않아서 옮길 진입 조건이 없었습니다(5절)
검증 환경·날짜 macOS 26.6.2 · arm64 · uv 0.10.12 · CPython 3.12 · TradingAgents 0.5.0 · openai/gpt-5.6-luna(OpenRouter) · 2026-09-22
제휴 고지 필자는 weltiq 로부터 이 연재의 원고료를 받습니다. 도구 평가는 필자가 직접 돌린 결과만 씁니다

이 도구가 내놓는 Buy/Hold/Sell 같은 등급은 전부 그 도구의 출력입니다. 맞는지에 대해 이 글은 아무 말도 하지 않습니다. 주문은 전부 페이퍼(모의) 이고 실주문은 한 건도 없습니다.


1. 이게 뭔가요

TauricResearch/TradingAgents 는 판단하는 사람이 하나가 아니라 열한 명이 순서대로 일합니다 — 애널리스트 4명(시장·감성·뉴스·펀더멘털), 리서치 3명(강세·약세·매니저), 트레이더 1명, 리스크 관리 3명(공격적·보수적·중립), 그리고 포트폴리오 매니저.

결론은 다섯 단계 등급입니다 — Buy · Overweight · Hold · Underweight · Sell. 소스에 박혀 있고(rating.py) 등급을 읽을 수 없으면 REVIEW 를 냅니다. 이 부분의 주석이 인상적이라 그대로 옮깁니다.

# a decision nobody can read is not a Hold, and a Hold recorded in its place is
# quoted back to the next run as a call that was never made (#1170).

읽을 수 없는 결정을 Hold 로 기록하지 않는다는 겁니다. "아무것도 안 함"을 함부로 쓰지 않으려는 도구입니다.

항목 값 확인 방법
주소 · 라이선스 github.com/TauricResearch/TradingAgents · Apache-2.0 GitHub API
별 수 ★107,945 · 포크 20,666 (관측일 2026-09-22) GitHub API
마지막 푸시 / 개설 2026-09-18 / 2024-12-28 · 열린 이슈 171 · 아카이브 아님 GitHub API
버전 0.5.0 · 파이썬 >=3.10 저장소 pyproject.toml
논문 arXiv 2412.20138 · Trading-R1 기술 리포트 arXiv 2509.11420 README

이 연재에서 지금까지 다룬 것 중 가장 큽니다 — 두 번째로 큰 2편 ai-hedge-fund(★63.6k)의 1.7배입니다. 분석하고 등급을 내되 주문은 내지 않습니다. README 의 포트폴리오 매니저 설명에 "승인되면 주문이 모의 거래소로 간다"고 적혀 있지만 저장소 어디에도 그 거래소는 없습니다 — 비어 있는 그 자리가 weltiq 가 들어가는 칸입니다. 이 도구 자신의 문장도 옮겨 둡니다 — "TradingAgents framework is designed for research purposes. … It is not intended as financial, investment, or trading advice."


2. 설치

⚠ 이 도구는 돌릴 때마다 돈이 듭니다

에이전트가 열한 명이고 각자 LLM 을 여러 번 부릅니다. 이 글을 쓰면서 열세 판을 돌려 $0.754369, 한 판당 평균 $0.058 을 썼습니다(openai/gpt-5.6-luna, 실측). 토론 라운드를 2회로 올리면 더 듭니다. 무료 모델로도 돌아가지만 이 도구의 값이 토론의 질이라 권하지 않습니다.

설치는 저장소를 받아서 합니다.

git clone https://github.com/TauricResearch/TradingAgents.git && cd TradingAgents
uv venv -p 3.12 /path/to/venv
uv pip install --python /path/to/venv/bin/python .

3.288초, 85개 패키지, 가상환경 185MB(--no-cache 실측). 키는 환경변수로 줍니다.

export OPENROUTER_API_KEY=...
export TRADINGAGENTS_LLM_PROVIDER=openrouter
export TRADINGAGENTS_LLM_BACKEND_URL=https://openrouter.ai/api/v1
export TRADINGAGENTS_DEEP_THINK_LLM=openai/gpt-5.6-luna
export TRADINGAGENTS_QUICK_THINK_LLM=openai/gpt-5.6-luna

TRADINGAGENTS_* 는 편의 기능이 아니라 대화형 질문을 건너뛰는 스위치입니다 — 설정한 단계는 아예 묻지 않고 넘어가므로 자동화할 때 이게 핵심입니다.

설치가 끝난 화면 — TradingAgents CLI 첫 기동

초록 테두리의 환영 상자와 그 아래 Workflow Steps 한 줄이 이 도구의 전부를 요약합니다 — 애널리스트 팀 → 리서치 팀 → 트레이더 → 리스크 관리 → 포트폴리오 관리. 이 다섯 단계가 뜨면 설치는 제대로 된 것입니다. 맨 아래 Step 1: Ticker Symbol 이 첫 질문입니다.

막히는 자리

증상 원인 우회
pip install tradingagents 로 깔았는데 CLI 가 다르다 다른 사람의 포크입니다. PyPI 메타데이터의 Repository 가 github.com/Mai0313/tradingagents 이고 requires_python 도 >=3.12(본가는 >=3.10) 본가는 PyPI 에 올리지 않습니다. 반드시 git clone
모델을 gpt-5.6 으로 적었더니 훨씬 비싸다 OpenRouter 가 벤더 접두사 없는 이름을 다르게 해석 openai/gpt-5.6-luna 처럼 접두사를 붙이세요
Optional macro_data unavailable … FRED_API_KEY … is not set 거시 지표 자료원 키가 없음 무시해도 됩니다. 거시 칸만 비고 나머지는 돕니다
StockTwits fetch failed … HTTP Error 403: Forbidden 그쪽이 막음 그 판의 감성 자료가 비어 결론이 달라질 수 있습니다. 4절에서 실제로 그랬습니다
Reddit RSS 429 … backing off 63.0s 호출 제한 알아서 63초 쉬고 한 번 더 칩니다. 그만큼 느려집니다
$SPY: Data doesn't exist for startDate = … 벤치마크 시세를 미래 구간까지 요청 결과에 영향 없습니다. 로그만 지저분해집니다

3. 첫 결과

웹 대시보드가 없습니다. 저장소를 뒤져도 streamlit·gradio·fastapi·flask 가 한 줄도 없습니다. 대신 터미널 안에서 도는 TUI 가 있고 잘 만들어져 있습니다. 띄우는 명령은 python -m cli.main(설치했으면 tradingagents), 주소는 없고, 로그인도 없지만 LLM 키가 없으면 그 자리에서 붙여 넣으라고 묻습니다.

Step 1: Ticker Symbol      → BTC-USD
Detected asset type: crypto
Step 2: Analysis Date      → [2026-09-22]     (엔터로 오늘 날짜)
Step 4: Analysts Team      → 스페이스로 셋 선택, 엔터

티커를 치면 자산 종류를 스스로 알아보고(Detected asset type: crypto) 크립토일 때는 애널리스트 목록에서 펀더멘털을 빼 버립니다 — 비트코인에 재무제표가 없으니 당연한데, 이걸 코드로 막아 둔 도구는 흔치 않습니다(filter_analysts_for_asset_type).

에이전트 열한 명이 순서대로 일하는 화면

왼쪽 위 Progress 가 이 도구의 핵심 화면입니다. 팀별로 누가 completed·in_progress·pending 인지 실시간으로 바뀝니다. 지금은 Market Analyst 가 끝나고 Sentiment Analyst 가 도는 중입니다. 오른쪽 Messages & Tools 에 에이전트가 방금 쓴 문장이 흐르고, 아래 Current Report 에 그 산출물이 그대로 찍힙니다. 맨 아래 상태줄의 Agents: 1/11 | LLM: 4 | Tools: 10 | Tokens: 70.8k↑ 4.0k↓ | ⏱ 00:40 이 지금까지 몇 명이 끝났고 토큰을 얼마나 썼는지입니다 — 돈이 드는 도구에서 이게 화면에 붙어 있는 건 큰 장점입니다.

리스크 팀 셋이 서로 반박하는 화면

Current Report 안이 Neutral Analyst 가 공격적 분석가와 보수적 분석가를 중재하는 장면입니다. "aggressive analyst is right that BTC-USD is extended" 로 한쪽을 인정하고, "However, the aggressive case overstates the certainty of the downside" 로 반박하고, "the conservative argument is too cautious" 로 다른 쪽도 칩니다. 왼쪽 Progress 를 보시면 트레이더까지 completed 이고 리스크 팀이 도는 중입니다. 이 토론 자체가 이 도구가 파는 물건입니다 — 다른 도구들은 결론만 내놓지, 그 결론이 어떤 반박을 이기고 나온 것인지를 보여 주지 않습니다.

4분쯤 지나면 끝납니다. 결과는 날짜 폴더 아래 message_tool.log 와 리포트 여섯 개(market_report·sentiment_report·news_report·investment_plan·trader_investment_plan·final_trade_decision)로 떨어지고, 파이썬에서 graph.save_reports() 로 부르면 팀별로 쪼갠 13개 트리가 따로 나옵니다. trader_investment_plan.md 가 제일 실행에 가깝습니다 — 이날 첫 판의 출력 전문입니다.

**Action**: Sell
**Reasoning**: The research plan recommends Underweight, which maps to a Sell/trim
decision because BTC-USD is tactically extended despite a bullish primary trend.
The verified close of 86,532.34 is above the upper Bollinger band at 84,053.38,
RSI is 73.76, and ATR is elevated at 2,435.97 ...
**Entry Price**: not provided
**Stop Loss**: not provided
**Position Sizing**: Reduce BTC-USD exposure to approximately 50%–75% of a normal
allocation; if already at or above standard size, trim a portion.

FINAL TRANSACTION PROPOSAL: **SELL**

Entry Price: not provided, Stop Loss: not provided 이 두 줄을 기억해 두세요. 5절에서 이게 벽이 됩니다.


4. 제일 잘 쓰는 법 — 같은 질문을 열세 번 던지기

이 편을 쓰는 이유입니다. 수익률 실험 1회차에서 이 도구는 Hold 를 냈습니다 — 같은 조건에서 돌린 넷 중 유일하게 "아무것도 하지 않겠다"를 고른 도구였습니다. 그걸 보고 "신중한 도구"라고 적고 싶어집니다. 그런데 9편 InvestSkill 에서 똑같은 유혹에 빠질 뻔했습니다 — 자료 부족을 이유로 판단을 거절하길래 "좋은 도구의 표시"라고 쓰려다가 같은 프롬프트를 7번 던져 보니 거절은 2회뿐이었습니다. 그래서 이번에도 여러 번 던졌습니다. 설정은 1회차와 똑같이 고정하고(모델 openai/gpt-5.6-luna, 애널리스트 4종, 토론 1라운드, 리스크 논의 1라운드) 바꾼 것은 종목과 날짜뿐입니다.

판 종목 분석 날짜 등급 트레이더 제안 걸린 시간
rA1 · rA3 BTC-USD 2026-09-22 Underweight SELL 254.1초 · 225.5초
rA2 · rA4 · rA5 BTC-USD 2026-09-22 Sell SELL 206.5 · 260.9 · 215.4초
rB1 · rB2 BTC-USD 2026-06-30 (고점 대비 −53%) Underweight SELL 174.7초 · 177.0초
rC0 · rC2 NVDA 2026-09-22 Sell SELL 301.1초 · 219.3초
rC1 NVDA 2026-09-22 Underweight SELL 241.7초
rD1 NVDA 2026-09-22 (장부 같이 줌) Sell SELL 218.5초
rE1 NVDA 2026-03-30 (고점 대비 −20%) Underweight SELL 195.8초

여기에 3절에서 CLI 로 돌린 한 판(BTC-USD, 2026-09-22, 애널리스트 3명)이 더해집니다 — 그 판도 Sell 이었습니다.

그래서 Hold 는 열세 판 중 몇 번이었나. 0번입니다.

횟수
총 판수 (프로그램 12 + CLI 1) 13
Hold 0
Underweight 6
Sell 7
Buy · Overweight 0
트레이더의 FINAL TRANSACTION PROPOSAL 이 SELL 13 / 13

첫째, "신중한 도구"라는 요약은 틀렸습니다. 1회차의 Hold 는 이 도구의 성격이 아니라 그날 그 판의 결과였습니다. 오늘 열세 판에서 Hold 는 한 번도 안 나왔습니다.

둘째, 그런데 방향은 놀랍도록 일관됩니다. 열세 판 전부가 매도 쪽이고 매수는 한 번도 없었습니다. 등급이 Underweight 와 Sell 사이에서 흔들릴 뿐 부호가 바뀌지 않았습니다. 종목을 바꿔도(BTC↔NVDA), 날짜를 바꿔도, 시장 국면을 바꿔도 그랬습니다.

셋째, 국면을 뒤집어도 안 바뀌었습니다. 비트코인이 고점 대비 53% 내려앉아 RSI 29.99 인 날(2026-06-30)을 물어봤습니다. "과매도니 반등 노려볼 만하다"가 나올 법한 자리인데 돌아온 답이 이렇습니다.

**Action**: Sell
**Reasoning**: … RSI at 29.99 and proximity to the lower Bollinger Band indicate
oversold conditions and rebound risk, but do not confirm a bottom; therefore,
trim exposure rather than aggressively short or average down.
**Entry Price**: 58558.86     **Stop Loss**: 60669.57

"과매도는 맞지만 바닥을 확인해 주지는 않는다" 는 문장으로 매수를 거절했습니다. NVDA 가 20% 빠졌던 날(2026-03-30)도 같았습니다.

열세 판으로 "이 도구는 절대 사지 않는다"고 말할 수는 없습니다 — 물어본 것은 두 종목·세 날짜뿐이니까요. 다만 "한 번 Hold 를 냈으니 신중한 도구"라는 문장은 열세 판으로도 충분히 무너집니다.

왜 갈렸나 — 입력이 판마다 달랐습니다

같은 날 같은 종목을 같은 설정으로 물었는데 답이 갈렸다면 모델이 흔들린 것일 수도 있고 본 자료가 달랐을 수도 있습니다. 감성 리포트를 열어 봤습니다.

판 StockTwits 그 판의 등급
rA1 받음 — "15 labeled bullish messages, 1 labeled bearish" Underweight
rA2 못 받음 — "StockTwits returned an HTTPError and no messages for BTC-USD" Sell
rA3 받음 — "17 Bullish (57%), 1 Bearish (3%)" Underweight

자료를 못 받은 판이 더 약세로 갔습니다. 표본 셋으로 인과를 말할 수는 없지만 같은 질문의 답이 그날 그 API 가 살아 있었는지에 달려 있다는 사실 자체가 알아야 할 것입니다. 로그에 403 Forbidden 한 줄로 지나가고 화면에는 안 나옵니다.

장부를 알려 주면 답이 달라집니다

다른 도구에 없는 칸이 하나 있습니다 — --portfolio 로 현재 보유와 현금을 같이 넘길 수 있습니다. 소스의 설명이 정확합니다.

# Three states are distinct and must stay so: a position, a flat book, and no
# context at all, since treating "not provided" as "flat" would invent a fact
# about the caller's account.

"안 줬다"를 "비었다"로 해석하지 않겠다는 겁니다. 그래서 장부를 실제로 줘 봤습니다 — NVDA 보유 0, 현금 1만 달러({"cash": 10000.0, "currency": "USD", "positions": []}). 돌아온 답이 이겁니다.

**Position Sizing**: 0% currently; remain uninvested/underweight.
**Reasoning**: … With no current NVDA position, this means avoid initiating or
adding aggressively rather than forcing a short sale; a pullback toward 220.17 or
214.40–219.36 would offer better evaluation points …

장부를 몰랐을 때는 "50~75%로 줄여라"였는데 빈 장부를 알려 주자 "0%, 들어가지 마라"로 바뀌었습니다. 등급(Sell)은 같은데 실행 지시가 달라졌습니다 — 장부를 진짜로 읽는다는 증거이고, 동시에 5절에서 만날 벽의 정체이기도 합니다.

안 돌린 것

조용히 빼지 않고 적습니다. 글로벌 종목 보기는 4·5절에서 계속 하고 있고(시장 애널리스트가 1년치를 받아 10EMA·50SMA·200SMA·MACD·RSI·볼린저·ATR 을 계산합니다), 내 실행 기록 복기는 5-2 에서 했습니다. 한국 종목은 야후 파이낸스가 덮는 시장이면 다 되지만(005930.KS) KRX 쪽과 이어 보는 것은 19편 TradingAgents-KR 의 자리라 건드리지 않았습니다. 중지 조건 발동은 이 도구가 중지 조건을 내지 않아 weltiq 쪽 게이트만 5-1 에 적고 발동까지는 안 돌렸고, 수수료 바꿔 재기도 이 도구가 수수료를 다루지 않아 안 돌렸습니다. 나란히 돌려 비교는 수익률 실험 트랙의 몫입니다.


5. weltiq 로 옮기기 — 통합 실험

솔직히 말씀드리면 이번엔 고리가 안 돌았습니다. 왜 안 돌았는지를 그대로 씁니다.

5-1. 옮기는 순서

TradingAgents 의 결론은 등급과 글이지 주문도 파라미터도 아닙니다. 옮기는 순서는 넷 — ① POST /v1/strategy-rules 규칙 문서 ② POST /v1/ai/thesis 근거 ③ POST /v1/containers 중지 조건을 건 전략 컨테이너 ④ 무인 실행. ②와 ③은 건너뛸 수 없습니다.

중지 조건을 빼면: {"detail":[{"type":"missing","loc":["body","stop_max_loss"],"msg":"Field required"},
                            {"type":"missing","loc":["body","stop_after_hours"],"msg":"Field required"}]}
근거를 안 쓰면:  {"detail":{"code":"thesis_required","questions":[
   "이 전략이 수익을 내는 이유를 한 문장으로 쓰세요 (본인의 말로).",
   "어떤 시장 조건에서 이 논리가 깨집니까?",
   "무효 조건(가격 레벨 또는 시점)을 숫자로 지정하세요."]}}

이 두 게이트가 "자율의 테두리"입니다. 그런데 이 편의 문제는 그 앞에 있습니다 — ①에 넣을 것이 없습니다. 도구가 쓴 글을 규칙 문서로 옮겨 주는 /v1/ai/formalize 가 있지만 이 편에서는 그 경로를 쓰지 못해(필자 계정 사정, 검증 기록에) 규칙을 손으로 썼습니다 — 숫자는 도구 출력 그대로만 넣고 없는 칸은 만들지 않았습니다.

5-2. 제일 잘 붙는 자리 — 장부를 되먹이는 곳

현재 장부를 인자 하나로 받고 그걸 판단 에이전트에게 통째로 넘기는 칸이 처음부터 있습니다(tradingagents --portfolio …). 그리고 weltiq 의 내보내기(GET /v1/containers/{cid}/export)가 내놓는 것이 정확히 그 장부라 통역이 필요 없습니다 — 형식만 바꾸면 됩니다. 변환 코드는 30줄이고 해석이 한 줄도 없습니다(84_export_to_portfolio.py): 체결을 합산해 수량과 평균가를 내고 자본에서 체결 대금과 수수료를 뺀 게 전부입니다. 기록을 필자 말로 요약하지 않았습니다 — 이게 이 연재가 지키는 선입니다. 그리고 이 장부를 다시 넣었을 때 답이 실제로 달라졌습니다(4절의 그 결과).

장부를 안 줬을 때 (rC0) 빈 장부를 줬을 때 (rD1)
등급 Sell Sell
Position Sizing "reduce to 50%–75% … trim about 25%–50%" "0% currently; remain uninvested/underweight"
근거 문장 — "With no current NVDA position, this means avoid initiating or adding aggressively rather than forcing a short sale"

등급은 같은데 지시가 달라졌습니다. 그래서 이 도구는 판단을 한 번 받아 주문으로 바꾸는 쪽이 아니라, 전략 컨테이너가 들고 있는 장부를 점검 시점마다 되먹여 "지금 이 포지션을 어떻게 할지" 묻는 쪽으로 쓰는 게 제일 낫습니다. 그게 이 도구가 스스로 설계한 입력입니다. 다만 진입은 안 됩니다 — 다음 절에서 보시듯 "언제 사라"를 숫자로 말하지 않습니다. 이 조합은 이미 들고 있는 것을 관리하는 자리에서 살고 빈손에서 시작하는 자리에서는 아직 못 삽니다.

5-3. 고리는 어디서 멈췄나

① 테두리를 칩니다 — us-equity NVDA 1분봉, 자본 1만 달러, 누적 손실 300 달러에서 중지, 3시간 뒤 자동 종료.

② 그런데 옮길 진입 조건이 없습니다. 오늘 NVDA 네 판이 전부 Sell 이었고 트레이더 서식의 상태가 이렇습니다.

판 Entry Price Stop Loss 이걸로 진입 규칙이 되나
rC0 227.38 (현재가) not provided 안 됩니다 — 현재가는 조건이 아닙니다
rD1 (빈 장부) not provided not provided 안 됩니다
1회차 BTC not provided 78473.91 안 됩니다 — 진입가가 없으면 손절만 있는 규칙입니다

weltiq 가 받는 것은 "언제 사고 언제 판다" 는 규칙인데 이 도구가 내놓는 것은 "지금 비중을 몇 퍼센트로 가져가라" 는 배분 지시입니다. 둘 사이에 다리가 없습니다. 1회차에서 Hold 때문에 막혔던 것과 같은 벽인데 오늘은 Sell 인데도 똑같이 막혔습니다 — 막은 것은 등급이 아니라 출력의 종류였습니다. 억지로 메우지 않았습니다. "50~75%로 줄이라"를 주식 수로 환산하면 그건 필자의 판단이지 도구의 결정이 아닙니다.

③ 조건을 바꿔 가며 숫자가 나올 때까지 물었습니다. 4절의 표가 그 과정이고 매수 판단은 끝내 안 나왔습니다. 다만 열두 판 중 딱 한 판이 완전한 숫자 세 개를 내놨습니다 — NVDA 가 20% 빠졌던 2026-03-30 입니다.

**Action**: Sell     **Entry Price**: 173.2     **Stop Loss**: 178.91

진입 173.20, 손절 178.91 — 손절이 진입보다 위에 있습니다. 이건 숏입니다("반등해서 173.20 에 닿으면 팔고, 178.91 위로 가면 틀린 것으로 본다"). 도구가 처음으로 완결된 거래를 내놓은 셈이라 그대로 올려 봤습니다.

POST /v1/strategy-rules  {"...": "side: short, entry 173.20, stop 178.91"}
→ 422 {"code":"invalid_rules","detail":"unsupported_direction"}

weltiq 의 us-equity 전략 컨테이너는 롱 전용입니다. 숏이 열린 곳은 파생 세 곳(binance-usdm·bybit-linear·cme)뿐입니다. 이 도구가 열세 판 만에 처음 낸 완결된 거래를, weltiq 가 받을 칸이 없어서 못 받았습니다.

④ 그래서 방향을 뒤집어 필자가 롱 규칙을 새로 썼습니다. 같은 판의 포트폴리오 결정문에 이런 문장이 있습니다 — "A more constructive stance would require a sustained reclaim of $173.20, then $178.91 and $182.63 …" 173.20 을 되찾으면 건설적으로 보겠다는 것이고 그다음 레벨을 178.91 로 지목했습니다. 이 두 숫자를 그대로 썼습니다.

여기서 무엇이 바뀌었는지 분명히 해 둡니다. 숫자는 그대로인데 매매의 방향이 뒤집혔습니다. 도구가 낸 완결된 거래는 숏이었습니다 — "173.20 에 팔고 178.91 위로 가면 틀린 것". 아래에 올린 규칙은 롱입니다 — "173.20 위로 올라서면 사고 178.91 에 판다". 그러므로 이 롱 규칙은 도구의 결정이 아니라, 도구의 조건부 문장에서 필자가 새로 쓴 전략입니다. 도구가 판 자리에서 필자가 샀다는 뜻입니다. 이 뒤에 나오는 숫자는 TradingAgents 의 성적이 아닙니다.

POST /v1/strategy-rules → 규칙 문서 지문 e16aeaafb0050ec6…
진입: (close > 173.20) → 진입 long E · True → 가격 조건 청산 (limit=178.91)
청산: 내부 청산 규칙 · 보호 손절 5%

보호 손절 5% 도 이 도구가 준 값이 아닙니다 — weltiq 의 기본값이고 도구는 롱 쪽 손절을 말하지 않았습니다(그 사실을 근거에도 적었습니다). 수량 1 도 도구의 결정이 아닙니다. ⑤ 전략 컨테이너가 붙었습니다 — status=running, stop={"max_loss":"300","after_hours":3}, attached=true, data_mode=realtime.

weltiq 전략 컨테이너 — TradingAgents 의 숫자가 규칙이 된 화면

제목 아래 한 줄(진입: (close > 173.20) → … (limit=178.91))의 두 숫자가 TradingAgents 의 문장에서 온 값 그대로이고, 사람이 다시 계산하지 않았습니다. 다만 방향(롱)은 필자가 정한 것입니다 — ④ 참조. 실행 중 옆 상태가 휴장 — 다음 개장에 평가 인 것에 주목해 주세요 — 컨테이너는 붙어 있고 규칙도 이미 맞았지만(종가 227.3 > 173.20), 미국장이 방금 닫혀 다음 개장까지 기다립니다. 주문 0·체결 0 이 그 결과입니다. 계정 식별자는 가렸습니다.

여기서 걸릴 거라고 예상했던 벽 하나를 피했습니다. 돌고 있는 us-equity 엔진은 그 뒤 추가된 블록(price_level·price_exit)을 모르고 9편이 그걸로 KeyError 를 맞았는데, 처음부터 그 엔진이 아는 문법으로 써서 한 번에 붙었습니다. 우회한 것이지 고쳐진 것은 아닙니다.

⑥ 같은 규칙 문서를 리플레이로 통과시켰습니다. 체결을 보려면 장이 열려야 하는데 이미 닫혀서 백테스트 모드로 보냈습니다.

POST /v1/backtest  {venue: us-equity, symbol: NVDA, tf: 1m, hours: 720}
n_bars 7799 · n_fills 7779 · n_trades 3889
pnl -225.2851365 · fees 17.60245370
intent_outcomes: {"accepted": 7779, "market_closed": 20}

30일 동안 3,889번 거래해서 −225.29 달러. 이 숫자는 전략 평가가 아니라 기계가 도는지 확인한 것입니다(④ 참조 — 도구의 전략이 아닙니다). 왜 이렇게 나왔는지가 오히려 교훈입니다. 도구가 준 레벨은 2026-03-30 의 것인데 지금 NVDA 는 227 달러라, 진입선 173.20 은 항상 참이고 목표가 178.91 은 항상 이미 지나쳐 있어서 봉마다 사고 봉마다 팔았습니다. 손실 225달러 중 17.6달러가 수수료이고 나머지는 스프레드입니다. 여섯 달 전 판단을 그대로 옮기면 이렇게 됩니다 — 이 도구의 출력에 유효기간이 안 적혀 있습니다. Time Horizon: 3–6 months 는 있지만 "이 가격은 이날 기준"이라는 표시는 없습니다.

그래서 고리는 어디까지 돌았나

칸 됐나
① 테두리를 친다 됐습니다 — 중지 조건 두 개 필수 게이트 통과
② 도구가 판단한다 됐습니다 — 13판
③ 판단을 규칙으로 옮긴다 안 됐습니다 — 진입 조건을 숫자로 말한 판이 12판 중 1판이고 그나마 숏이라 못 받았습니다. 실제로 돌린 롱 규칙은 도구의 판단이 아니라 필자가 새로 쓴 것입니다(④)
④ 무인으로 돈다 됐습니다 — attached=true, 다만 휴장이라 체결 0
⑤ 결과를 되먹인다 됐습니다 — 내보내기 → --portfolio → 답이 실제로 달라짐 (5-2)
⑥ 그 결과로 규칙을 고쳐 다시 돈다 안 됐습니다 — 되먹인 답이 "0%, 들어가지 마라"라 고칠 규칙이 없었습니다

고리는 닫히지 않았습니다. 닫히지 않은 이유를 감싸지 않고 적습니다.

막은 것 어느 쪽 상태
us-equity 숏 불가 weltiq 이 도구가 낸 유일한 완결 거래를 못 받았습니다 — 숏이 열린 곳이 파생 셋뿐입니다
주문 한도 1 weltiq 당시 API 키 경로의 주문 수량 상한 기본값이 1 이었고, 9편에서 진입 의도 1,159건이 이것 때문에 전부 거절됐습니다. 2026-09-23 에 고쳤습니다 — 이제 규칙 문서가 선언한 sizing.qty 가 곧 주문 상한입니다(qty: 44 → 상한 44). 당시 다시 확인하지 못했던 큰 수량 재확인도 지금은 돌아갑니다
배분 지시 vs 규칙 도구 쪽 성질 "표준 배분의 50~75%"는 weltiq 문법에 대응 칸이 없습니다. 결함이 아니라 출력의 종류가 다른 것입니다
분석 날짜로 리플레이 불가 weltiq 1분봉 리플레이 상한이 720시간이라 2026-03-30 을 다시 못 돌립니다. 긴 구간용 비동기 작업(POST /v1/backtests)은 받아졌지만 워커가 안 떠 있어 queued 에서 멈췄습니다

같은 규칙 문서가 페이퍼와 백테스트를 같은 몸으로 지났습니다. 다만 실전 구간은 아직 열려 있지 않습니다(live_orders: false).


6. 써 보니

좋았던 것

  1. 토론이 기록으로 남습니다. 강세론자와 약세론자가 무슨 근거로 싸웠고 누가 무엇으로 반박했는지가 문서 여섯 개(파이썬으로 부르면 팀별 13개)에 그대로 있습니다. 결론만 주는 도구와 이게 제일 크게 다릅니다.
  2. 읽을 수 없는 결정을 Hold 로 기록하지 않습니다. 등급을 못 뽑으면 REVIEW 를 냅니다 — "아무것도 안 함"을 기본값으로 쓰지 않으려는 설계이고 소스 주석에 이유가 적혀 있습니다.
  3. 장부를 인자 하나로 받고 "안 줬다"와 "비었다"를 구별합니다. 이 구별을 코드 주석으로 못 박아 둔 도구는 드뭅니다.
  4. 자산 종류를 알아보고 맞는 애널리스트만 쓰며, 화면에 토큰과 비용이 붙어 있습니다. 자료를 못 받으면 "StockTwits returned an HTTPError" 를 리포트 본문에 쓰고 신뢰도를 낮춥니다.

아쉬웠던 것

  1. 진입 조건을 숫자로 말하지 않습니다. 열세 판 중 Entry Price 와 Stop Loss 가 둘 다 채워진 판은 한 판뿐이었습니다. 실행으로 옮기려는 분에게는 이게 제일 큰 벽이고, 출력이 규칙이 아니라 배분 지시라는 점도 같은 이야기입니다.
  2. 레벨에 날짜가 안 붙습니다. 5-3 의 리플레이에서 여섯 달 전 가격을 그대로 넣었더니 30일에 3,889번 거래했습니다. Time Horizon 은 있지만 "이 숫자는 몇 월 며칠 기준"이 없습니다.
  3. 판마다 답이 흔들리는데 그 폭이 화면에 안 나옵니다. 같은 날 같은 종목에 Underweight 와 Sell 이 섞여 나왔고 원인 중 하나가 그 판에 StockTwits 가 살아 있었는지였습니다. 한 판만 돌리면 이걸 알 수 없습니다.
  4. 돌릴 때마다 돈과 시간이 듭니다. 판당 $0.058 · 3~5분이라 하루에 열 종목을 훑는 용도로는 안 맞고, 무료 자료원도 자주 막힙니다(StockTwits 403, Reddit 429, FRED 키 없음 — 전부 조용히 로그로만 지나갑니다).
  5. PyPI 이름이 다른 사람에게 가 있습니다. 별 10만짜리 프로젝트로서는 위험한 상태입니다.

비용

저장소·설치 0원 (Apache-2.0)
모델 호출 (13판, OpenRouter 경유 openai/gpt-5.6-luna) $0.754369 · 판당 $0.058
유료 자료원 안 썼습니다. FRED·Alpha Vantage 키가 있으면 거시·펀더멘털 칸이 채워집니다

OpenRouter 의 사용량 집계는 약간 지연돼서 판별 금액은 신뢰하기 어렵습니다. 그래서 판별 값은 싣지 않고 구간 전체의 증가분($0.754369)과 그 평균만 적습니다. 같은 구간에 이 키로 다른 작업은 돌리지 않았습니다.


7. 다음 편 예고

13편은 hummingbot/hummingbot(★20.1k)입니다. 이번 편과 정반대편에 있는 물건입니다 — TradingAgents 가 "무엇을 할지 고민하는" 쪽이라면 hummingbot 은 "정해진 것을 쉬지 않고 실행하는" 쪽이고, 마켓메이킹·차익거래 봇을 24시간 돌리는 도구이며 LLM 은 등장하지 않습니다. 볼거리는 이름 하나입니다 — 거래소 커넥터 목록에 binance_paper_trade 가 있습니다. 모의에서 실전으로 가는 전환이 문자열 하나인 설계이고, weltiq 는 그 전환에 승격 사다리라는 관문을 둡니다. 어느 쪽이 옳은지가 아니라 무엇이 다른지를 이번 편처럼 실제로 돌려서 적어 보겠습니다.

weltiq 준비 — 3줄 1. 가입: {{CTA_URL}} 2. 마이 → 연결 관리에서 API 키 발급 3. claude mcp add weltiq --header "Authorization: Bearer <키>" https://weltiq.ai/mcp

들고 있는 포지션을 점검 시점마다 이 도구에게 다시 물어보고 싶으시면, 그 장부를 내보내는 자리입니다.


이 글의 모든 명령·출력·숫자는 2026-09-22 에 실제로 돌려서 얻었습니다. 주문은 전부 모의이고 실주문은 없습니다. 어떤 매매 의견도 아닙니다. 여기 적지 않은 시행착오·원문 로그·결함 목록은 검증 기록에 있습니다.