secretctl
로그인 없이 토스증권 공개 시세를 다루는 익명 CLI — 쿠키·세션을 전혀 보내지 않습니다.
시세 · 차트 · 호가 · 체결 · 수급 · 시장지수 · 인기순위 · AI 시그널 · 조건검색(스크리너)을 사람도 에이전트도 같은 명령 표면(secretctl)으로. 폴링 알림(watch)과 로컬 HTTP 데몬(serve) + Python 클라이언트까지.
이 저장소는 tossinvest-cli(이하 업스트림)를 로그인 없이 재구성한 변형입니다. 로그인 없이 조회할 수 있는 시세 등의 데이터만 지원합니다.
[!WARNING]
이 프로젝트는 토스증권 공식 제품이 아닙니다. 토스증권 웹의 비공식 내부 API 를 사용하며, 토스증권 이용약관(TOS) 위반에 해당할 수 있습니다. API 는 예고 없이 변경될 수 있고, 사용으로 인한 계좌 제한·손실·기타 불이익에 대해 개발자는 어떠한 책임도 지지 않습니다. 본인의 판단과 책임 하에 사용하세요.
Quick Start
For Human
# 빌드 (Go 1.25+)
make build # -> ./bin/secretctl
./bin/secretctl get 005930
./bin/secretctl get 삼성전자 --output json
./bin/secretctl market index
For Agent
Build secretctl from source with `make build` (Go 1.25+). It is anonymous and
login-free: it never sends cookies, so it only reads Toss public market data
(quotes, charts, order books, indices, rankings, AI signals, screeners). There
is no auth/account/trading surface. Use `--output json` for structured output,
`secretctl serve` for a local HTTP/JSON API, and `secretctl watch` for polling
alerts emitted as JSONL on stdout.
지원 범위
secretctl 는 로그인이 필요 없는 공개 데이터만 다룹니다. 업스트림의 조회 표면 중 인증이 필요 없는 항목을 그대로 가져오고, 인증·계좌·거래 표면은 전부 제거했습니다.
다루는 것 (공개 · 로그인 불필요)
| 기능 |
커맨드 |
| 시세 (OHLC·52주 고저·시총·거래대금·체결강도) |
get <symbol|name> |
| 멀티 시세 / 실시간 갱신 |
batch <sym...> (--chart·--live) |
| 캔들 차트 |
chart <sym> --interval 1m|3m|5m|10m|15m|30m|60m |
| 체결 (틱) |
trades <sym> --count N |
| 호가 (10단계) |
orderbook <sym> |
| 상/하한가 (KR) |
limits <sym> |
| 매수 유의사항 |
warnings <sym> |
| 수급 (투자자별 순매수, KR) |
flows <sym> |
| 장 운영 시간 |
market hours |
| 환율·달러 인덱스 |
market fx |
| 시장 지수 (코스피·나스닥·VIX 등) |
market index |
| 실시간 인기 순위 |
market ranking --size N |
| 토스 AI 시그널 |
market signals |
| 조건검색 (스크리너) |
market screener [id] · --filter '<json>' --nation kr|us |
출력은 모두 --output table|json|csv 를 지원합니다. 종목명/한글명/6자리 KR 코드 모두 자동 해석됩니다.
다루지 않는 것 (전부 제외)
| 제외 |
이유 |
| 계좌·포트폴리오·잔고·주문내역·거래내역 |
로그인 세션 필요 → 익명 범위 밖 |
| 매수/매도/정정/취소 등 모든 거래 |
인증 + 거래 게이트 영역 (업스트림에 있음) |
| 매도가능수량·수수료 |
계좌 컨텍스트(cert) 인증 필요 |
| 관심종목 폴더/종목 변경 |
인증된 쓰기(mutation) |
| 실시간 SSE 푸시 |
로그인 전용 채널 → watch 폴링으로 대체 |
명령어
# 조회
secretctl get|batch|chart|trades|limits|warnings|flows|orderbook <symbol...>
secretctl market hours|fx|index|signals
secretctl market ranking --size N
secretctl market screener [preset-id] [--nation kr|us] [--filter '<json>']
# 알림 (폴링 → JSONL stdout)
secretctl watch <symbol> --above <price> | --below <price>
secretctl watch --ranking-enter <symbol> [--ranking-size N]
secretctl watch --screener <preset-id> | --screener-filter '<json>'
# 임베드
secretctl serve [--addr 127.0.0.1:8080] # 로컬 HTTP+JSON 데몬
secretctl serve --addr 0.0.0.0:8080 --allow-public --token <secret> # 외부 노출 시
# 시스템
secretctl version
전역 플래그 (모든 명령 공통)
| 플래그 / 환경변수 |
설명 |
--output table|json|csv |
출력 형식 |
--user-agent <ua> · SECRETCTL_USER_AGENT |
요청 User-Agent override (단순 fingerprint — 쿠키 아님, 익명 불변). 토스가 구버전 UA 를 막을 때 사용 |
--http-timeout 15s |
요청별 HTTP timeout |
serve 는 비루프백 주소(0.0.0.0·LAN IP·빈 호스트)에 바인드하려면 --allow-public 이 필요하며(미설정 시 거부), 노출 시 --token <secret>(또는 SECRETCTL_TOKEN)으로 /healthz 외 전 라우트에 Authorization: Bearer 를 요구할 수 있습니다.
알림 (watch) — SSE 역할의 익명 대체
업스트림의 실시간 푸시는 로그인 전용 SSE 채널이라 익명 범위 밖입니다. watch 는 그 역할(실시간 알림)을 공개 데이터 폴링 + fire-once 트리거로 대체하고, 알림을 JSON 한 줄(JSONL)로 stdout 에 흘립니다(조건당 1회, 조건 해제 시 재무장).
secretctl watch AAPL --above 300
secretctl watch --ranking-enter TSLA --ranking-size 30
secretctl watch --screener 2 --screener-nation kr
알림 전달은 Sink 인터페이스(기본 StdoutSink)입니다. 텔레그램·Discord·webhook 등 외부 채널은 인터페이스만 정의돼 있고 구현하지 않았습니다 — watch 의 stdout 을 외부 릴레이로 파이프하면 됩니다(업스트림의 ... || curl <webhook> 패턴).
secretctl watch AAPL --above 300 | while read -r line; do
curl -s "https://api.telegram.org/bot$TOKEN/sendMessage" \
-d chat_id="$CHAT" --data-urlencode text="$line" >/dev/null
done
임베드: HTTP 데몬 + Python 클라이언트
secretctl serve --addr 127.0.0.1:8080
curl 127.0.0.1:8080/quote/AAPL
curl "127.0.0.1:8080/market/screener?preset=2&nation=kr&size=5"
from secretctl import Client # pip install -e ./pyclient
with Client("http://127.0.0.1:8080") as c:
print(c.quote("삼성전자")["last"])
print(c.market_index())
라우트는 CLI 와 1:1 대응하고 동일한 JSON 을 반환합니다. 자세한 내용은 pyclient/README.md. 데몬은 기본 localhost 바인드이며 익명 read-only 프록시입니다.
이 프로젝트가 하지 않는 것
| 하지 않는 것 |
설명 |
| 로그인 / 인증 |
세션·쿠키 코드가 아예 없습니다. 그래서 공개 데이터만 봅니다. |
| 거래 (주문/정정/취소) |
거래 표면은 업스트림(인증 + 게이트)의 영역입니다. |
| 계좌·포트폴리오 조회 |
인증이 필요하므로 범위 밖입니다. |
| 외부 알림 채널 구현 |
Sink 인터페이스만 제공 — 텔레그램 등은 직접 구현/파이프합니다. |
설치
# 1) install.sh (macOS/Linux) — 최신 릴리스 바이너리 다운로드
curl -fsSL https://raw.githubusercontent.com/Gyupil/tossinvest-secret/main/install.sh | sh
# 2) go install
go install github.com/Gyupil/tossinvest-secret/cmd/secretctl@latest
# 3) 소스 빌드
git clone https://github.com/Gyupil/tossinvest-secret.git
cd tossinvest-secret # (모듈 루트)
make build && make test
# Python 클라이언트 (선택)
cd pyclient && pip install -e .
Windows 는 GitHub Releases 의 .zip 을 받으세요.
모듈 경로는 github.com/Gyupil/tossinvest-secret 입니다. go install · install.sh 가 동작하려면 이 go.mod(와 .github/·.goreleaser.yaml·install.sh)가 저장소 루트에 위치해야 합니다. 릴리스는 태그 push(vX.Y.Z) 시 goreleaser 가 크로스컴파일·아카이브·체크섬을 만듭니다. CI(.github/workflows/ci.yml)는 build·vet·test·gofmt·pytest 를 검사합니다.
구조
cmd/secretctl/ CLI (quote · market · watch · serve · version)
internal/client/ 하드닝된 쿠키리스 HTTP 클라이언트 (public 메서드만)
internal/output/ table / json / csv 렌더러
internal/alert/ 폴링 트리거 + Sink (StdoutSink 만)
internal/httpserver/ REST 데몬
internal/domain/ public 시세 구조체
pyclient/ 데몬용 Python 클라이언트
License
MIT. 상당 부분이 tossinvest-cli(MIT)에서 파생되었으며, 원저작자 고지는 LICENSE 에 보존돼 있습니다.