name: toss-watchlist-sync description: >- Bidirectional comparison between the pipeline's hot stock discoveries and the Toss Securities watchlist. Identifies pipeline hot stocks NOT on Toss watchlist and Toss watchlist items NOT tracked by the pipeline. Use when the user asks to "sync watchlist", "watchlist sync", "관심종목 동기화", "핫 종목 토스 추가", "compare watchlist", or wants to align pipeline discoveries with brokerage watchlist. Can also auto-apply adds via browser automation (scripts/toss/watchlist_add.mjs). Do NOT use for live trading (use tossinvest-trading). Do NOT use for portfolio reconciliation (use toss-portfolio-recon). Do NOT use for read-only watchlist viewing (use tossinvest-cli).
toss-watchlist-sync
Compare pipeline hot stock discoveries with Toss Securities watchlist to identify sync gaps.
When to Use
- After daily pipeline discovers new hot stocks
- Reviewing which pipeline picks are on the Toss watchlist
- Cleaning up stale watchlist entries
- Aligning analysis pipeline tracking with brokerage monitoring
When NOT to Use
- For read-only watchlist viewing → use
tossinvest-cli - For portfolio reconciliation → use
toss-portfolio-recon - For live trading → use
tossinvest-trading
Prerequisites
tossctlinstalled and in PATH (read path: watchlist list, quotes)- Active authenticated session (
tossctlsession at~/Library/Application Support/tossctl/session.json) - Pipeline outputs available (
outputs/discovery-*.json,outputs/screener-*.json) - For writes: Playwright (reused from
scripts/twitter/node_modules, v1.58.2) +scripts/toss/watchlist_add.mjs
Watchlist Access: Read vs Write
- Read →
tossctl watchlist list(CLI, fast).tossctlcannot write — its add/create/group subcommands are no-ops. - Write (create group, add/remove symbols) → browser automation via Playwright against
https://www.tossinvest.com. This is the going-forward method for any watchlist mutation. Seescripts/toss/watchlist_add.mjs.
Verified write selectors (2026-05-27)
- Stock page:
https://www.tossinvest.com/stocks/{code} - Heart/add button:
button[aria-label^="관심 종목"]— label is관심 종목 설정하기when not favorited,관심 종목 해제하기once added (prefix match is required so it works in both states). - Clicking the heart opens
[role=dialog]: onebutton+checkboxper group, plus a새 그룹 만들기button at the bottom. - New group: click
새 그룹 만들기→input[placeholder="그룹 이름 입력"]→ type name → confirm. - Toggle membership: click the group's
buttoninside the dialog, then read its checkbox to confirm.
Write selector corrections (2026-06-05)
Three failure modes hit during a 13-stock bulk add; fixes are now load-bearing:
- Group-name input is
confirm, notEnter. PressingEnterin the그룹 이름 입력field does NOT reliably create the group — click the dialog's확인button instead. (Supersedes the older "→ Enter" note above.) - Label clicks need
evaluate, not Playwright locators.filter({hasText})on the group rows silently missed the right element. Use pageevaluateto find the label by text and.click()it in the DOM. - 35-group hard limit. Toss caps watchlist groups at 35;
새 그룹 만들기fails silently at the cap (no error, no new group). When at the limit, repurpose an existing group (rename/clear and reuse) rather than retrying group creation. Always check current group count before adding a new group.
Write safety
- Live brokerage account → always dry-run first (default mode of
watchlist_add.mjsreads membership without writing), then--apply --headedso the run is visible and abortable. - The script is idempotent: stocks already in the target group are skipped.
- Session converts the custom tossctl
session.json(cookies/headers/storage dicts) to a Playwright storageState.
Workflow
Step 1: Load Pipeline Hot Stocks
Gather from today's (or latest) pipeline outputs:
outputs/discovery-{date}.json— hot stock discovery resultsoutputs/screener-{date}.json— screener results with STRONG_BUY/BUY signals
Extract the set of recommended symbols.
Step 2: Load Toss Watchlist
tossctl watchlist list --output json
Extract the set of watched symbols.
Step 3–5: 비교 + 리포트 (코드 위임)
포맷/집계 결정론은 [[sonnet-format-determinism]]을 따른다 — 모델은 content-only, 코드가 소유.
스크립트가 set-diff 계산(add_candidates, orphans, overlap), STRONG_BUY/BUY 필터, mrkdwn 리포트 전부 소유한다:
.venv/bin/python scripts/skills/toss_watchlist_sync_watchlist_diff.py \
--pipeline outputs/screener-<date>.json \
--toss-watchlist <watchlist.json> \
--fmt slack
선택: --json-out <path> 로 diff JSON 저장. --fmt md 로 마크다운 출력.
apply 단계(실제 추가)는 별도 수동 확인 후 기존 scripts/toss/watchlist_add.mjs로 진행:
node scripts/toss/watchlist_add.mjs # dry-run
node scripts/toss/watchlist_add.mjs --apply --headed # 실제 추가 (항상 dry-run 후 재확인)
Examples
User: 관심종목 싱크해줘
Agent: toss-watchlist-sync 실행 →
- 파이프라인 추천 but 관심목록 미등록: PLTR, SOFI, ARM
- 관심목록에만 있고 파이프라인 미추적: COIN
- 양쪽 모두 존재: NVDA, AAPL, MSFT
User: toss watchlist sync
Agent: (runs the full comparison, presents sync report)
Error Handling
| Error | Action |
|---|---|
No active session |
Prompt tossctl auth login |
| No pipeline outputs found | Try yesterday's files; warn about stale data |
| Empty watchlist | Report pipeline recommendations only |
| New group not created (no error) | 35-group cap hit — 새 그룹 만들기 fails silently. Check group count first; repurpose an existing group instead of retrying |
Group-name not saved on Enter |
Click the dialog's 확인 button — Enter does not reliably confirm |