# 12편 TradingAgents — 실행 기록

2026-09-22 04:45~05:35 KST. 모든 숫자는 실측. LLM 은 OpenRouter 경유 `openai/gpt-5.6-luna` 고정.

## 0. 먼저 읽은 것

B축 1회차 기록(`reports/b/01/21-tradingagents-*`)을 먼저 읽었다. 그 회차의 결정은 **Hold**
(`21-tradingagents-decision.json`), 221.9초, 문서 13개. 다시 설치하지 않고 그때 만든 venv
(`/private/tmp/tut-venvs/tradingagents`)와 소스(`/private/tmp/tut-src/TradingAgents`)를 그대로 썼다.

## 1. 사실 확인

| | 값 | 파일 |
|---|---|---|
| GitHub | ★107,945 · 포크 20,666 · Apache-2.0 · pushed 2026-09-18 | `01-github-repo.json` |
| PyPI `tradingagents` | **본가 아님** — `Repository: github.com/Mai0313/tradingagents` | `02-pypi.json` |
| 설치 (재측정, `--no-cache`) | Resolved/Prepared/Installed 85 packages · **3.288초** · venv 185MB | 본문 §2 |

## 2. 화면 캡처

`screencapture -l <windowid>` 로 **내가 연 Terminal 창(id 5937, 제목 TA-SHOT)만** 찍었다.
매 캡처 전에 `Quartz.CGWindowListCopyWindowInfo` 로 창 id 를 확인했다. 다른 창은 건드리지 않았다.

- `shots/01-cli-welcome.png` — CLI 첫 기동 (§2 설치 완료 화면)
- `shots/02-cli-live-analysts.png` — 에이전트 진행 TUI (§3)
- `shots/03-cli-risk-debate.png` — **대표 그림.** 리스크 팀 셋의 논쟁 (§3)
- `shots/04-weltiq-slot.png` — weltiq 슬롯 상세 (§5). 읽기 프록시 9190 경유, 계정 식별자 blur

CLI 대화형 입력은 `osascript` 로 넣었다. `keystroke "문자열"` 은 입력기 때문에 깨져서
(`BTC-USD` → `` `FJ-UG ``) **텍스트는 Terminal `do script`, 특수키는 `key code`** 로 나눴다.

## 3. 반복 실행 — 이 편의 중심 숫자

`run_repeat.py` (프로그램 12판) + CLI 1판 = **13판**. 설정은 B축 1회차와 동일
(애널리스트 4종·토론 1라운드·리스크 1라운드). 바꾼 것은 종목과 날짜뿐.

| | 결과 | 파일 |
|---|---|---|
| **Hold** | **0 / 13** | `10-repeat-results.jsonl` |
| Underweight | 6 | 〃 |
| Sell | 7 (프로그램 6 + CLI 1) | 〃 |
| Buy · Overweight | **0** | 〃 |
| 트레이더 `FINAL TRANSACTION PROPOSAL` | **SELL 13/13** | 〃 |

조건 변경: BTC 2026-06-30(고점 대비 −53%, RSI 29.99) 2판 · NVDA 2026-03-30(−20%) 1판 ·
NVDA 장부 동봉 1판. **전부 매도 쪽.** 매수 판단은 끝내 안 나왔다.

갈린 원인 하나를 잡았다 — `StockTwits` 가 그 판에 살아 있었는지. 못 받은 판(rA2)이 Sell,
받은 판(rA1·rA3)이 Underweight 였다 (표본 셋, 인과 주장 아님).

## 4. weltiq 연결

| 단계 | 결과 | 파일 |
|---|---|---|
| `/v1/ai/formalize` | **402 insufficient_credits** (balance 2.7471) — 저희 계정 사정 | `41-formalize.json` |
| 숏 규칙 (도구 출력 그대로 entry 173.20 / stop 178.91) | **422 `unsupported_direction`** — us-equity 롱 전용 | `77-rules-submit-short.json` |
| 롱 규칙 (같은 판의 "reclaim 173.20 → 178.91") | `doc_hash e16aeaafb0050ec6…` | `77-rules-submit-long.json` |
| 중지 조건 누락 | 422 `stop_max_loss`·`stop_after_hours` required | `78-no-stop.json` |
| 근거 누락 | 422 `thesis_required` (질문 3개) | `79-no-thesis.json` |
| 근거 제출 | ok | `80-thesis.txt` · `80-thesis.json` |
| 슬롯 | `ct_485691ad2c1b2a12` · running · **attached=true** · `wait.code=market_closed` | `81-container.json` · `82-container-detail.json` |
| 내보내기 → `--portfolio` | `{"cash":10000.0,"currency":"USD","positions":[]}` | `83-export.json` · `84-portfolio-from-export.json` |
| 리플레이 (같은 doc_hash) | 7,799봉 · 7,779체결 · **3,889거래 · pnl −225.285 · fees 17.602** | `87-backtest-720h-qty1.json` |
| 수량 57 재확인 | **못 했다 — 402 insufficient_credits.** `max_order_qty` 는 코드로만 확인 | `89-backtest-720h-qty57.json` |
| 긴 구간(분석 날짜) 비동기 백테스트 | `bj_7a4cb5999da92a8a` **queued 에서 멈춤 — 워커 미기동.** 취소함 | `86-backtest-result.json` |

슬롯은 확인 뒤 **정지·삭제**했다(`DELETE → deleted: true`). 돌고 있던 12개는 조회만 했고
건드리지 않았다. 엔진·웹 프로세스는 재시작하지 않았다.

## 5. 벽 둘 — 예고된 것

| | 결과 |
|---|---|
| `max_order_qty` 기본값 1 | **코드로 확인**(`weltiq/api/server.py:2264` · `weltiq/runner/portfolio.py:276` · `weltiq/runner/backtest_worker.py:197`). 이번엔 수량 1 로 올려서 **걸리지 않았고**, 큰 수량 재확인은 크레딧 부족으로 **미확인** |
| 엔진이 `price_level`/`price_exit` 를 모름 | **처음부터 `slot_rules` 로 써서 피했다.** `attached=true` 로 한 번에 붙음. 엔진 재시작 안 함 |

새로 드러난 저희 쪽 것 둘: **us-equity 숏 불가**(도구가 낸 유일한 완결 거래를 못 받음),
**1분봉 리플레이 720시간 상한**(도구가 분석한 날짜를 다시 돌릴 수 없음).

## 6. 비용

| | |
|---|---|
| OpenRouter 시작 | `usage 17.371531788` (`00-openrouter-key-start.json`) |
| OpenRouter 종료 | `99-openrouter-key-end.json` |
| **증가분** | **$0.754369** — 13판, 판당 평균 $0.058 |
| 상한 | $1. 같은 구간에 이 키로 다른 작업 없음 |

판별 금액은 OpenRouter 집계 지연 때문에 신뢰할 수 없어 글에 싣지 않았다(`cost_usd` 필드는
jsonl 에 남겨 뒀지만 그렇게 표시).

## 7. 파일

| | |
|---|---|
| `run_repeat.py` | 반복 실행 (라벨·티커·날짜·자산종류 목록) |
| `run_portfolio.py` | 장부 동봉 실행 (`--portfolio` 경로) |
|  `75_port.py` | 도구 출력 → `slot_rules` 문서 (short/long) |
| `84_export_to_portfolio.py` | weltiq 내보내기 → TradingAgents 장부 서식 (해석 없음) |
| `api.py` · `shotproxy.py` | weltiq API · 캡처용 읽기 프록시(포트 9190) |
| `runs/` | 13판의 리포트 원문 전체 |

---

## 8. v2 재편 때 기사에서 내린 것 (2026-09-24)

독자판을 v2 포맷(`CONTENT_PLAN_2026-09-22` §2.3 R2·R11)으로 재편하며 본문에서 뺀 것들이다.
**값은 여기 그대로 남긴다.**

### 8-1. `/v1/ai/formalize` 402 응답 원문

2026-09-22 실행 당시(`41-formalize.json`) 본문은 `code`·`balance`·`detail` 세 칸이었다.
**2026-09-23 에 `estimate`·`shortfall`·`topup_url` 이 더해져** 아래 모양이 됐고, 거절 자체는 그때와 지금이 같다
(`formalize` 는 5 크레딧이 필요한데 잔액이 2.7471 이었다).

```json
{"code":"insufficient_credits","balance":"2.747100","estimate":"5","shortfall":"2.252900",
 "topup_url":"https://weltiq.ai/my/billing",
 "detail":"크레딧을 충전해야 계속할 수 있습니다 — 잔액 2.747100 크레딧, 2.252900 크레딧 부족 (충전: https://weltiq.ai/my/billing)"}
```

R11(필자 사정·크레딧 잔액은 독자판에서 뺀다)·R2(「크레딧」은 독자판 금지어)에 따라 독자판에는
「이 편에서는 그 경로를 쓰지 못해 규칙을 손으로 썼습니다(필자 계정 사정, 검증 기록에)」 한 줄만 남겼다.

### 8-2. 소스 참조 (R2 — `weltiq/….py:NN` 은 독자판 금지)

| 본문에서 뺀 참조 | 무엇 | 지금 상태 |
|---|---|---|
| `weltiq/pine.py:28` | `SHORT_VENUES` — 숏이 열린 venue 세 곳(`binance-usdm`·`bybit-linear`·`cme`) | 2026-09-24 확인: 같은 줄 그대로 |
| `weltiq/runner/slot_contract.py` | 당시 슬롯 경로의 `max_order_qty` 기본값 1 | 2026-09-23 수정으로 규칙 문서의 `sizing.qty` 가 상한이 됨 (§5 참조) |

독자판에는 venue 이름 셋과 「2026-09-23 에 고쳤습니다 — 이제 규칙 문서가 선언한 `sizing.qty` 가
곧 주문 상한입니다(`qty: 44` → 상한 44)」 문장을 그대로 남겼다. **시제를 되돌리지 않았다.**

### 8-3. 그 밖에 내린 줄

- 「슬롯 한도를 다른 작업과 나눠 쓰고 있어서 정지·삭제했다」 — R11(필자 사정). 정지·삭제 사실 자체는 §4 에 이미 있다.
- 시나리오 번호 표기(`S1`·`S3`·`S5`·`S7`·`S9`·`S10`) — R2. 독자판에서는 사람 말로 바꿔 적었다.
