IdiotQuant API 문서

Cloudflare Workers 기반 퀀트 투자 백엔드 REST API

Base URL https://idiotquant-backend.tofu89223.workers.dev
권한: Public인증 불필요 · X-User-Id 헤더 필요 · 🔒 AdminDB role=admin 계정만 · 레거시신규 개발에 사용 비권장

🔍 종목 발굴 스캔 주요

2,000개 종목을 5분마다 7개씩 롤링 스캔하여 stock_data_daily에 저장하는 메인 API입니다.
4가지 전략 태그(ncav · low_pbr · low_per · s_rim)를 strategies JSON 배열로 제공합니다.
ROE는 eps / bps(= 당기순이익 / 자본총계)로 계산됩니다.

GET /scan/daily Public ▶ 직접 열기

날짜별 종목 발굴 목록. strategy로 전략별 필터링 가능.

파라미터타입기본값설명
datestringlatestYYYYMMDD 또는 latest
strategystringallall · ncav · low_pbr · low_per · s_rim
limitnumber50최대 500
sortstringncav_rationcav_ratio · pbr · per · last_price · market_cap
orderstringdescasc · 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 (주당순이익 / 주당순자산 = 당기순이익 / 자본총계)

GET /scan/daily/dates Public ▶ 직접 열기

스캔 날짜 목록과 날짜별 전략 종목 수. 최근 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 }
}
GET /scan/daily/ticker/:ticker Public

특정 종목의 날짜별 시계열 (최근 14일, scan_date 내림차순).

파라미터타입기본값설명
:tickerstring필수6자리 종목코드 (예: 005930)
limitnumber30최대 200
curl "https://idiotquant-backend.tofu89223.workers.dev/scan/daily/ticker/004830?limit=14"
GET /scan/archive Public

3단 아카이브 (일별 14일 → 주별 26주 → 월별 무기한). period 없이 호출하면 기간별 요약, 지정 시 종목 상세.

파라미터타입기본값설명
period_typestringmonthlymonthly · weekly
periodstring없음월별: YYYY-MM, 주별: YYYYMMDD(월요일). 없으면 요약 목록
strategystringallncav · low_pbr · low_per · s_rim · all
limitnumber50최대 500
sortstringncav_rationcav_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, ... }]
GET /scan/archive/ticker/:ticker Public

특정 종목의 아카이브 추이. 장기 가치 변화 분석·백테스트용.

파라미터타입기본값설명
period_typestringmonthlymonthly · weekly
limitnumber24최대 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 }, ...]
}
GET /scan/status Public ▶ 직접 열기

현재 스캔 진행 상태, 아카이브 진행 상태, 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 }
    ]
  }
}

📊 종목 상세

GET /stock/:ticker Public ▶ 직접 열기

종목 코드로 최신 스캔 결과 + 최근 이력을 조회합니다. 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 이상 = 이론적 청산가치 이하 거래 종목.

GET /uapi/*

한국투자증권 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 종목에 균등 적립됩니다.

🔒 Admin trading_accounts 계정 등록 (D1 직접 삽입)

신규 계정 추가는 D1 insert로만 처리합니다. quant_rule_jsonNULL이면 전역 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 각각의 월 예산(원화). 스케줄러가 틱당 적립량 자동 계산.

GET /kr/capital 🔒 Admin

국내 자본 토큰 상태 조회 (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"
}
GET /us/capital 🔒 Admin

해외 자본 토큰 상태 조회. 환율(frst_bltn_exrt) 포함.

curl "https://idiotquant-backend.tofu89223.workers.dev/us/capital" -H "X-User-Id: ADMIN_ID"
POST /kr/capital/token/plus/{amount}/all 🔒 Admin

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"

🔐 인증

GET /kakao/login Public

Kakao OAuth 로그인 리다이렉트. 성공 시 cf_token HttpOnly 쿠키 발급 (유효기간 1시간).

https://idiotquant-backend.tofu89223.workers.dev/kakao/login  ← 브라우저에서 직접 접근
POST /kakao/logout

Kakao 세션 로그아웃. cf_token 쿠키 만료.

curl -X POST "https://idiotquant-backend.tofu89223.workers.dev/kakao/logout" --cookie "cf_token=YOUR_TOKEN"
GET /user/info

현재 로그인 유저 프로필 조회.

curl "https://idiotquant-backend.tofu89223.workers.dev/user/info" -H "X-User-Id: YOUR_USER_ID"
GET /user/starred-stocks

현재 로그인 유저의 관심 종목 목록.

📈 NCAV API 레거시

내부적으로 stock_data_daily를 사용하며 strategy=ncav 필터가 기본 적용됩니다.
신규 개발에는 /scan/* 엔드포인트 사용을 권장합니다.

GET /ncav/daily Public 레거시

날짜별 NCAV 조건 종목 목록. 내부적으로 /scan/daily?strategy=ncav와 동일.

파라미터타입기본값설명
datestringlatestYYYYMMDD 또는 latest
min_rationumber1.0최소 NCAV 비율
limitnumber50최대 200
sortstringncav_rationcav_ratio · pbr · per · last_price · market_cap
orderstringdescasc · desc
curl "https://idiotquant-backend.tofu89223.workers.dev/ncav/daily?date=latest&min_ratio=1.5&limit=20"
GET /ncav/archive Public 레거시

월별 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"
GET /ncav/status 🔒 Admin

스캔 진행 상태 조회. → 현재는 /scan/status 사용 권장.

POST /ncav/scan/run 🔒 Admin

수동으로 1배치(7종목) 즉시 스캔. 테스트·디버깅용.

curl -X POST "https://idiotquant-backend.tofu89223.workers.dev/ncav/scan/run" -H "X-User-Id: ADMIN_ID"

🔬 백테스트 / Strategy

GET /backtest/kr/year/:year 🔒 Admin

국내 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"
GET /backtest/us/year/:year 🔒 Admin

미국 NCAV 백테스트 수동 실행. Finnhub + KIS Overseas API 사용.

curl "https://idiotquant-backend.tofu89223.workers.dev/backtest/us/year/2025" -H "X-User-Id: ADMIN_ID"
GET /strategy/kr/ncav/date/latest Public 레거시

국내 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"

🌐 외부 데이터

GET /fmp/* Public

Financial Modeling Prep API 프록시. 미국 재무제표·가격 데이터.

curl "https://idiotquant-backend.tofu89223.workers.dev/fmp/AAPL"
GET /finnhub/* Public

Finnhub API 프록시. 미국 NCAV용 재무제표 (financials-reported). KV 캐시 적용.

curl "https://idiotquant-backend.tofu89223.workers.dev/finnhub/AAPL"
POST /laboratory/llm

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를 설명해줘"}'

⚙️ 기타

GET /algorithm/trade Public

자동매매 알고리즘 거래 로그 조회 (KV IQ_PURCHASE_LOG 기반).

curl "https://idiotquant-backend.tofu89223.workers.dev/algorithm/trade" -H "X-User-Id: YOUR_ID"
GET /timestamp

유저 활동 타임스탬프 조회 및 갱신 (KV IQ_TIMESTAMP).

curl "https://idiotquant-backend.tofu89223.workers.dev/timestamp" -H "X-User-Id: YOUR_ID"
GET /api/search-log Public

최근 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 제약 대응)
✓ 복사됨!