IdiotQuant API 문서
Cloudflare Workers 기반 퀀트 투자 백엔드 REST API
🔍 종목 발굴 스캔 주요
2,000개 종목을 5분마다 7개씩 롤링 스캔하여 stock_data_daily에 저장하는 메인 API입니다.
4가지 전략 태그(ncav · low_pbr · low_per · s_rim)를 strategies JSON 배열로 제공합니다.
ROE는 eps / bps(= 당기순이익 / 자본총계)로 계산됩니다.
날짜별 종목 발굴 목록. strategy로 전략별 필터링 가능.
| 파라미터 | 타입 | 기본값 | 설명 |
|---|---|---|---|
date | string | latest | YYYYMMDD 또는 latest |
strategy | string | all | all · ncav · low_pbr · low_per · s_rim |
limit | number | 50 | 최대 500 |
sort | string | ncav_ratio | ncav_ratio · pbr · per · last_price · market_cap |
order | string | desc | asc · desc |
# 최신 날짜 전체 종목 curl "https://idiotquant-backend.tofu89223.workers.dev/scan/daily?strategy=all&limit=300&sort=ncav_ratio&order=desc" # NCAV 전략만 필터 curl "https://idiotquant-backend.tofu89223.workers.dev/scan/daily?strategy=ncav&limit=50" # S-RIM 전략 (ROE > 8% && PBR < 1.0) curl "https://idiotquant-backend.tofu89223.workers.dev/scan/daily?strategy=s_rim&sort=pbr&order=asc" # 특정 날짜 저PBR curl "https://idiotquant-backend.tofu89223.workers.dev/scan/daily?date=20260601&strategy=low_pbr"
const res = await fetch(
'https://idiotquant-backend.tofu89223.workers.dev/scan/daily?strategy=all&limit=300&sort=ncav_ratio&order=desc'
);
const { success, data, meta } = await res.json();
// data: [{ ticker, name, scan_date, ncav_ratio, roe, per, pbr, eps, bps,
// current_assets, total_liabilities, market_cap, last_price, strategies }]
// strategies: string[] — e.g. ["ncav", "low_pbr"]
// roe: number (eps/bps) — e.g. 0.12 = 12%
console.log(`${meta.scanDate} 기준 ${meta.total}개 종목 (${meta.strategy})`);
{
"success": true,
"data": [
{
"ticker": "004830",
"name": "덕성",
"scan_date": "20260601",
"ncav_ratio": 2.341,
"current_assets": 85200,
"total_liabilities": 12400,
"market_cap": 31100,
"last_price": 4280,
"net_income": 3200000000,
"per": 9.8,
"pbr": 0.42,
"eps": 437,
"bps": 10190,
"roe": 0.04289,
"strategies": ["ncav", "low_pbr", "low_per"]
}
],
"meta": { "scanDate": "20260601", "strategy": "all", "total": 1, "sort": "ncav_ratio", "order": "DESC" }
}
💡 전략 기준: ncav ncav_ratio≥1.0 · low_pbr 0<pbr<0.5 · low_per 0<per<10 · s_rim roe>0.08 && 0<pbr<1.0
💡 ROE = eps / bps (주당순이익 / 주당순자산 = 당기순이익 / 자본총계)
스캔 날짜 목록과 날짜별 전략 종목 수. 최근 30일.
curl "https://idiotquant-backend.tofu89223.workers.dev/scan/daily/dates"
// 응답
{
"success": true,
"data": [
{
"scan_date": "20260601",
"total_cnt": 1847,
"ncav_cnt": 42,
"low_pbr_cnt": 312,
"low_per_cnt": 198,
"s_rim_cnt": 87
}
],
"meta": { "total": 14 }
}
특정 종목의 날짜별 시계열 (최근 14일, scan_date 내림차순).
| 파라미터 | 타입 | 기본값 | 설명 |
|---|---|---|---|
:ticker | string | 필수 | 6자리 종목코드 (예: 005930) |
limit | number | 30 | 최대 200 |
curl "https://idiotquant-backend.tofu89223.workers.dev/scan/daily/ticker/004830?limit=14"
3단 아카이브 (일별 14일 → 주별 26주 → 월별 무기한). period 없이 호출하면 기간별 요약, 지정 시 종목 상세.
| 파라미터 | 타입 | 기본값 | 설명 |
|---|---|---|---|
period_type | string | monthly | monthly · weekly |
period | string | 없음 | 월별: YYYY-MM, 주별: YYYYMMDD(월요일). 없으면 요약 목록 |
strategy | string | all | ncav · low_pbr · low_per · s_rim · all |
limit | number | 50 | 최대 500 |
sort | string | ncav_ratio | ncav_ratio · pbr · per · last_price · period_label |
# 월별 요약 목록 curl "https://idiotquant-backend.tofu89223.workers.dev/scan/archive" # 2026년 6월 NCAV 종목 상세 curl "https://idiotquant-backend.tofu89223.workers.dev/scan/archive?period_type=monthly&period=2026-06&strategy=ncav&sort=ncav_ratio" # 주별 아카이브 요약 curl "https://idiotquant-backend.tofu89223.workers.dev/scan/archive?period_type=weekly"
// 월별 요약 (period 없음)
const { data } = await fetch('https://idiotquant-backend.tofu89223.workers.dev/scan/archive').then(r => r.json());
// data: [{ period_label, total_stocks, ncav_stocks, low_pbr_stocks, low_per_stocks, s_rim_stocks, avg_ncav_ratio }]
// 특정 월 상세 (period 지정)
const { data: detail } = await fetch(
'https://idiotquant-backend.tofu89223.workers.dev/scan/archive?period_type=monthly&period=2026-06&strategy=ncav'
).then(r => r.json());
// detail: [{ ticker, name, ncav_ratio, roe, per, pbr, eps, bps, days_scanned, strategies, ... }]
특정 종목의 아카이브 추이. 장기 가치 변화 분석·백테스트용.
| 파라미터 | 타입 | 기본값 | 설명 |
|---|---|---|---|
period_type | string | monthly | monthly · weekly |
limit | number | 24 | 최대 120 |
# 덕성(004830) 월별 24개월 추이
curl "https://idiotquant-backend.tofu89223.workers.dev/scan/archive/ticker/004830?period_type=monthly&limit=24"
// 응답
{
"data": [{ "period_label": "2026-06", "ncav_ratio": 2.34, "roe": 0.043, "per": 9.8, "pbr": 0.42, "days_scanned": 18 }, ...]
}
현재 스캔 진행 상태, 아카이브 진행 상태, DB 요약 통계를 반환합니다.
curl "https://idiotquant-backend.tofu89223.workers.dev/scan/status"
// 응답
{
"data": {
"scan": { "lastIndex": 350, "scanDate": "20260601", "totalStocks": 2000, "progressPct": 18, "done": false },
"archive": { "weekLabel": "20260526", "weekDone": false, "weekProgressPct": 42,
"monthLabel": "2026-06", "monthDone": false, "monthProgressPct": 12 },
"stockDataDaily": { "total_rows": 25858, "scan_days": 14, "unique_tickers": 1847, "latest_date": "20260601" },
"stockDataArchive": [
{ "period_type": "monthly", "periods": 2, "total_rows": 3694 },
{ "period_type": "weekly", "periods": 4, "total_rows": 7388 }
]
}
}
📊 종목 상세
종목 코드로 최신 스캔 결과 + 최근 이력을 조회합니다. stock_data_daily 기반, 인증 불필요.
curl "https://idiotquant-backend.tofu89223.workers.dev/stock/005930" curl "https://idiotquant-backend.tofu89223.workers.dev/stock/004830"
const { success, ticker, name, latest, history } = await fetch(
'https://idiotquant-backend.tofu89223.workers.dev/stock/005930'
).then(r => r.json());
if (success) {
console.log(`${name}(${ticker})`);
console.log(`NCAV 비율: ${latest.ncav_ratio.toFixed(2)}`);
console.log(`ROE: ${(latest.roe * 100).toFixed(1)}%`);
console.log(`전략: ${latest.strategies.join(', ')}`);
}
{
"success": true,
"ticker": "005930",
"name": "삼성전자",
"latest": {
"scan_date": "20260601",
"ncav_ratio": 1.423,
"last_price": 58400,
"market_cap": 3913440,
"per": 11.3,
"pbr": 0.98,
"eps": 5170,
"bps": 59600,
"roe": 0.08676,
"strategies": ["s_rim"]
},
"history": [
{ "scan_date": "20260601", "ncav_ratio": 1.423, "last_price": 58400 },
{ "scan_date": "20260525", "ncav_ratio": 1.401, "last_price": 57200 }
]
}
// 스캔 결과 없는 종목
{ "success": false, "error": "NCAV 스캔 결과에 '000000' 종목 없음. 아직 스캔되지 않았거나 NCAV 조건 미충족." }
💡 NCAV 비율 = (유동자산 − 총부채) ÷ 시가총액. 1.0 이상 = 이론적 청산가치 이하 거래 종목.
한국투자증권 UAPI 프록시. 국내·해외 시세/잔고/주문.
헤더: X-User-Id · X-User-Role · X-User-Plan 필요
💰 자동매매 계정 / Capital 토큰
자동매매 계정은 D1 trading_accounts 테이블에 등록합니다.
KR / US 시장별로 별도 행이며, 스케줄러(min%5===0)는 이 테이블을 조회해 활성 계정을 병렬 실행합니다.
Capital 토큰은 D1 capital_tokens 테이블에 저장되며, 매 5분 틱마다 월 예산 기반으로 active 종목에 균등 적립됩니다.
신규 계정 추가는 D1 insert로만 처리합니다. quant_rule_json이 NULL이면 전역 KV 룰 사용.
# KR 계정 등록
npx wrangler d1 execute idiotquant_main --remote --command="
INSERT INTO trading_accounts
(user_id, country, appkey, appsecret, account_number, monthly_budget_krw)
VALUES ('USER_ID', 'KR', 'APPKEY', 'APPSECRET', 'ACCOUNT_NO', 2000000)"
# US 계정 등록
npx wrangler d1 execute idiotquant_main --remote --command="
INSERT INTO trading_accounts
(user_id, country, appkey, appsecret, account_number, monthly_budget_krw)
VALUES ('USER_ID', 'US', 'APPKEY', 'APPSECRET', 'ACCOUNT_NO', 1000000)"
# per-user 투자 룰 지정 (NULL이면 전역 룰 사용)
npx wrangler d1 execute idiotquant_main --remote --command="
UPDATE trading_accounts
SET quant_rule_json='{"ncav_ratio":1.5,"active_count":10}'
WHERE user_id='USER_ID' AND country='KR'"
💡 monthly_budget_krw: KR / US 각각의 월 예산(원화). 스케줄러가 틱당 적립량 자동 계산.
국내 자본 토큰 상태 조회 (D1 capital_tokens). 종목별 누적 토큰, 매수/매도 액션, 스캔 인덱스 포함.
curl "https://idiotquant-backend.tofu89223.workers.dev/kr/capital" -H "X-User-Id: ADMIN_ID"
// 응답 (발췌)
{
"stock_list": [
{ "symbol": "005930", "name": "삼성전자", "token": 45200, "action": "active", "ncavRatio": "1.42" }
],
"charge_info": { "capital_charge_rate": 164 },
"action": "buy"
}
해외 자본 토큰 상태 조회. 환율(frst_bltn_exrt) 포함.
curl "https://idiotquant-backend.tofu89223.workers.dev/us/capital" -H "X-User-Id: ADMIN_ID"
active 종목 전체에 토큰 수동 추가. 특정 종목은 /ticker/{symbol} 사용. minus도 동일 패턴.
# 전체 active 종목에 3만원 추가 curl -X POST "https://idiotquant-backend.tofu89223.workers.dev/kr/capital/token/plus/30000/all" -H "X-User-Id: ADMIN_ID" # 특정 종목에만 추가 curl -X POST "https://idiotquant-backend.tofu89223.workers.dev/kr/capital/token/plus/30000/ticker/005930" -H "X-User-Id: ADMIN_ID" # 차감 curl -X POST "https://idiotquant-backend.tofu89223.workers.dev/kr/capital/token/minus/30000/all" -H "X-User-Id: ADMIN_ID" curl -X POST "https://idiotquant-backend.tofu89223.workers.dev/us/capital/token/plus/50000/all" -H "X-User-Id: ADMIN_ID"
🔐 인증
Kakao OAuth 로그인 리다이렉트. 성공 시 cf_token HttpOnly 쿠키 발급 (유효기간 1시간).
https://idiotquant-backend.tofu89223.workers.dev/kakao/login ← 브라우저에서 직접 접근
Kakao 세션 로그아웃. cf_token 쿠키 만료.
curl -X POST "https://idiotquant-backend.tofu89223.workers.dev/kakao/logout" --cookie "cf_token=YOUR_TOKEN"
현재 로그인 유저 프로필 조회.
curl "https://idiotquant-backend.tofu89223.workers.dev/user/info" -H "X-User-Id: YOUR_USER_ID"
현재 로그인 유저의 관심 종목 목록.
📈 NCAV API 레거시
내부적으로 stock_data_daily를 사용하며 strategy=ncav 필터가 기본 적용됩니다.
신규 개발에는 /scan/* 엔드포인트 사용을 권장합니다.
날짜별 NCAV 조건 종목 목록. 내부적으로 /scan/daily?strategy=ncav와 동일.
| 파라미터 | 타입 | 기본값 | 설명 |
|---|---|---|---|
date | string | latest | YYYYMMDD 또는 latest |
min_ratio | number | 1.0 | 최소 NCAV 비율 |
limit | number | 50 | 최대 200 |
sort | string | ncav_ratio | ncav_ratio · pbr · per · last_price · market_cap |
order | string | desc | asc · desc |
curl "https://idiotquant-backend.tofu89223.workers.dev/ncav/daily?date=latest&min_ratio=1.5&limit=20"
월별 NCAV 압축 아카이브. period 없이 호출 시 월별 요약, 지정 시 종목 상세.
curl "https://idiotquant-backend.tofu89223.workers.dev/ncav/archive" curl "https://idiotquant-backend.tofu89223.workers.dev/ncav/archive?period=2026-06&min_ratio=1.0"
스캔 진행 상태 조회. → 현재는 /scan/status 사용 권장.
수동으로 1배치(7종목) 즉시 스캔. 테스트·디버깅용.
curl -X POST "https://idiotquant-backend.tofu89223.workers.dev/ncav/scan/run" -H "X-User-Id: ADMIN_ID"
🔬 백테스트 / Strategy
국내 NCAV 백테스트 수동 실행. KIS API로 전체 종목 스캔 후 KV 저장. index로 중단점 재개 가능.
# 2025년 백테스트 시작 curl "https://idiotquant-backend.tofu89223.workers.dev/backtest/kr/year/2025" -H "X-User-Id: ADMIN_ID" # 100번 종목부터 재개 curl "https://idiotquant-backend.tofu89223.workers.dev/backtest/kr/year/2025/index/100" -H "X-User-Id: ADMIN_ID"
미국 NCAV 백테스트 수동 실행. Finnhub + KIS Overseas API 사용.
curl "https://idiotquant-backend.tofu89223.workers.dev/backtest/us/year/2025" -H "X-User-Id: ADMIN_ID"
국내 NCAV 전략 최신 결과 (KV 기반 구버전). 신규 개발에는 /scan/daily 사용 권장.
curl "https://idiotquant-backend.tofu89223.workers.dev/strategy/kr/ncav/date/latest" curl "https://idiotquant-backend.tofu89223.workers.dev/strategy/all/ncav/list"
🌐 외부 데이터
Financial Modeling Prep API 프록시. 미국 재무제표·가격 데이터.
curl "https://idiotquant-backend.tofu89223.workers.dev/fmp/AAPL"
Finnhub API 프록시. 미국 NCAV용 재무제표 (financials-reported). KV 캐시 적용.
curl "https://idiotquant-backend.tofu89223.workers.dev/finnhub/AAPL"
Cloudflare Workers AI (LLM) 추론. 모델: @cf/meta/llama-4-scout-17b-16e-instruct
curl -X POST "https://idiotquant-backend.tofu89223.workers.dev/laboratory/llm" \
-H "Content-Type: application/json" \
-d '{"prompt": "삼성전자의 NCAV를 설명해줘"}'
⚙️ 기타
자동매매 알고리즘 거래 로그 조회 (KV IQ_PURCHASE_LOG 기반).
curl "https://idiotquant-backend.tofu89223.workers.dev/algorithm/trade" -H "X-User-Id: YOUR_ID"
유저 활동 타임스탬프 조회 및 갱신 (KV IQ_TIMESTAMP).
curl "https://idiotquant-backend.tofu89223.workers.dev/timestamp" -H "X-User-Id: YOUR_ID"
최근 24시간 종목 검색 순위 조회 (D1 D1_IQ_SEARCH_LOG).
# 검색 순위 상위 20개
curl "https://idiotquant-backend.tofu89223.workers.dev/api/search-log" -H "count: 20"
# 검색 기록 저장
curl -X POST "https://idiotquant-backend.tofu89223.workers.dev/api/search-log" \
-H "Content-Type: application/json" \
-d '{"ticker":"005930","name":"삼성전자","isUs":false}'
const data = await fetch('https://idiotquant-backend.tofu89223.workers.dev/api/search-log', {
headers: { count: '20' }
}).then(r => r.json());
await fetch('https://idiotquant-backend.tofu89223.workers.dev/api/search-log', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ticker: '005930', name: '삼성전자', isUs: false })
});
📋 공통 응답 형식
모든 API는 아래 형식으로 응답합니다.
// 성공
{ "success": true, "data": [...], "meta": { "total": 50, "scanDate": "20260601", ... } }
// 오류 (400 / 403 / 500)
{ "success": false, "error": "오류 메시지" }
• 모든 API는 CORS 헤더를 포함합니다.
• Admin 전용 API는 D1 users 테이블에 role='admin'인 유저만 접근 가능합니다.
• X-User-Role 헤더는 무시됩니다 — role은 DB에서만 결정됩니다.
📝 Changelog
- 2026-06-04: D1 읽기 최적화 — /scan/daily·dates Cloudflare Cache API 5분 엣지 캐시, users 조회 in-memory 캐시(60s), SELECT * → 필요 컬럼만 조회 - 2026-06-04: /scan/daily limit 최대값 500 → 2000으로 상향 (전체 종목 조회 지원) - 2026-06-03: /dashboard/scan 개선 - 다음/직전 스캔 배치 종목명·티커, 예상 완료 시각, 최근 스캔 결과 테이블 추가 - 2026-06-03: ROE 계산식 수정 - NCAV(유동자산-부채)를 분모로 쓰던 버그를 EPS/BPS(자본총계 기반)로 교정, s_rim 전략 태깅 동일 수정; migration 0005로 기존 stock_data_daily/archive 일괄 교정 - 2026-06-03: docs 페이지 개편 - /scan/* 섹션 신설, 섹션 우선순위 재정렬, 레거시 배지 추가 - 2026-06-02: ncav_daily double-write 제거, 전체를 stock_data_daily 기반으로 통합 - ncavScanKr: ncav_daily 쓰기 제거, stock_data_daily만 사용 - /ncav/daily, /ncav/archive: stock_data_daily/archive 기반으로 전환 (ncav 전략 필터 기본) - /stock/:ticker: stock_data_daily 기반으로 전환, strategies·roe 필드 추가 - 2026-06-02: /scan/* API 신규 추가 (stock_data_daily · stock_data_archive 기반) - GET /scan/daily, /scan/daily/dates, /scan/daily/ticker/:ticker - GET /scan/archive, /scan/archive/ticker/:ticker - GET /scan/status - ?strategy=ncav|low_pbr|low_per|s_rim|all, ?period_type=monthly|weekly 지원 - 2026-06-02: 다중 전략 종목 데이터 누적 (stock_data_daily · stock_data_archive) - 지원 전략: NCAV · 저PBR · 저PER · S-RIM (roe > 0.08 && pbr < 1.0) - 모든 스캔 종목 저장 (기존 ncav_daily는 NCAV 종목만 저장하던 것을 확장) - 3단 아카이브: 일별 14일 보관 → 주별(26주) → 월별(무기한) - 롤링 아카이브: min%5===3 tick마다 50종목씩 처리 (10ms CPU 제약 대응)