본문 바로가기
Project/🚀 AI Finance 2026

#4 Alchemetric API 정의서

by 로띠 2026. 2. 6.

1. API 개요

Alchemetric API는 FastAPI 기반의 REST JSON 서비스로, 주가 수집부터 머신러닝 예측까지 전 과정을 HTTP 엔드포인트로 제공. 내부 서비스 전용이므로 별도 인증 없이 사용 가능.

Base URLhttp://localhost:8000
Swagger UIhttp://localhost:8000/docs
FormatREST JSON
인증None (내부 서비스 전용)
총 엔드포인트10개 라우트 모듈, 60개 엔드포인트

라우트 모듈 총괄

모듈명 Base Path 엔드포인트 수 상태
주가 데이터 /stocks 6 운영중
펀더멘털 /fundamental 5 운영중
거시경제 지표 /macro 3 운영중
뉴스 센티먼트 /news 3 운영중
공시 / 수급 /disclosure 4 운영중
기술적 지표 /indicators 7 운영중
머신러닝 /ml 9 운영중
백테스트 /backtest 7 운영중
리포트 / 구독 /report 8 예정
관리자 /admin 14 운영중

Swagger UI에서 모든 엔드포인트를 인터랙티브하게 테스트 가능. 서버 실행 후 http://localhost:8000/docs에 접속

2. 주가 데이터 (/stocks)

주가 데이터의 수집, 조회, 삭제를 담당하는 라우트. yfinance와 FinanceDataReader를 통해 한국/미국 주식 가격 데이터를 수집하고, 종목별 또는 섹터별로 조회 가능.

엔드포인트 목록

Method Path 설명
POST /stocks/collect 주가 데이터 수집 실행
GET /stocks/prices/code/{code} 종목별 주가 조회
GET /stocks/prices/sector/{sector} 섹터별 주가 조회
DELETE /stocks/prices/code/{code} 종목 주가 삭제
GET /stocks/info/{code} 종목 정보 조회
GET /stocks/sector/{sector} 섹터별 종목 목록

CollectRequest

// POST /stocks/collect
// Request Body
{
  "sector": "반도체",        // 수집 대상 섹터
  "start_date": "2024-01-01", // 수집 시작일 (optional)
  "end_date": "2024-12-31",   // 수집 종료일 (optional)
  "codes": ["005930", "000660"] // 특정 종목만 (optional)
}

CollectResponse

// 200 OK
{
  "status": "success",
  "message": "주가 데이터 수집 완료",
  "data": {
    "sector": "반도체",
    "collected_codes": ["005930", "000660"],
    "total_rows": 1240,
    "date_range": {
      "start": "2024-01-02",
      "end": "2024-12-30"
    }
  }
}

주가 조회 응답

// GET /stocks/prices/code/005930
{
  "status": "success",
  "data": {
    "code": "005930",
    "name": "삼성전자",
    "prices": [
      {
        "date": "2024-12-30",
        "open": 56000,
        "high": 56800,
        "low": 55500,
        "close": 56200,
        "volume": 12345678
      }
    ],
    "total_count": 245
  }
}

3. 펀더멘털 데이터 (/fundamental)

KIS(한국투자증권) API를 통한 펀더멘털 지표와 DART OpenAPI를 통한 재무제표 데이터를 수집하고 조회. PER, PBR, EPS 등 밸류에이션 지표와 매출액, 영업이익 등 재무 데이터를 제공.

엔드포인트 목록

Method Path 설명
POST /fundamental/collect KIS 펀더멘털 수집
POST /fundamental/collect/financial DART 재무제표 수집
GET /fundamental/summary/{code} 펀더멘털 + 재무 요약
GET /fundamental/{code} 펀더멘털 조회
GET /fundamental/{code}/financial 재무제표 조회

펀더멘털 수집 요청

// POST /fundamental/collect
// Request Body
{
  "sector": "반도체",
  "codes": ["005930"],   // optional: 특정 종목만
  "base_date": "20241230" // optional: 기준일 (YYYYMMDD)
}

펀더멘털 요약 응답

// GET /fundamental/summary/005930
{
  "status": "success",
  "data": {
    "code": "005930",
    "name": "삼성전자",
    "fundamental": {
      "per": 12.5,
      "pbr": 1.2,
      "eps": 4496,
      "bps": 46812,
      "dividend_yield": 2.1,
      "market_cap": 335000000000000
    },
    "financial": {
      "revenue": 258935000000000,
      "operating_profit": 6567000000000,
      "net_income": 15487000000000,
      "roe": 5.2,
      "debt_ratio": 35.8,
      "fiscal_year": "2024"
    }
  }
}

4. 거시경제 지표 (/macro)

yfinance, FinanceDataReader, FRED API를 통해 11개 거시경제 지표를 수집. EAV(Entity-Attribute-Value) 구조로 저장되며, 피처 엔지니어링 단계에서 ML 학습 데이터에 자동 병합.

엔드포인트 목록

Method Path 설명
POST /macro/collect 거시지표 수집
GET /macro/latest 최신값 전체 조회
GET /macro/{indicator_name} 개별 지표 시계열

지원 지표 목록

지표명 설명 데이터 소스 FeatureStore 컬럼
KRW_USD 원/달러 환율 yfinance (KRW=X) krw_usd
VIX 변동성 지수 yfinance (^VIX) vix
KOSPI 코스피 지수 yfinance (^KS11) kospi_index
SP500 S&P 500 지수 yfinance (^GSPC) sp500
US_10Y 미국 10년물 국채금리 yfinance (^TNX) us_10y
KR_3Y 한국 3년물 국채금리 FDR (INVESTING:) kr_3y
WTI WTI 원유 선물 yfinance (CL=F) wti
GOLD 금 선물 yfinance (GC=F) gold
FED_RATE 미국 기준금리 FRED API (FEDFUNDS) fed_rate
USD_INDEX 달러 인덱스 FRED API (DTWEXBGS) usd_index
US_CPI 미국 소비자물가지수 FRED API (CPIAUCSL) us_cpi

최신값 조회 응답

// GET /macro/latest
{
  "status": "success",
  "data": {
    "KRW_USD": { "value": 1320.50, "date": "2024-12-30" },
    "VIX":     { "value": 15.20,   "date": "2024-12-30" },
    "KOSPI":   { "value": 2655.28, "date": "2024-12-30" },
    "SP500":   { "value": 5881.63, "date": "2024-12-30" },
    "US_10Y":  { "value": 4.57,    "date": "2024-12-30" },
    "KR_3Y":   { "value": 2.68,    "date": "2024-12-30" },
    "WTI":     { "value": 71.72,   "date": "2024-12-30" },
    "GOLD":      { "value": 2624.50, "date": "2024-12-30" },
    "FED_RATE":  { "value": 5.33,    "date": "2024-12-01" },
    "USD_INDEX": { "value": 124.85,  "date": "2024-12-27" },
    "US_CPI":    { "value": 315.49,  "date": "2024-11-01" }
  }
}

5. 뉴스 센티먼트 (/news)

네이버 뉴스 API로 종목별/시장 뉴스를 수집하고, KR-FinBert-SC(한국어 금융 센티먼트 모델)로 감성 점수를 부여. 센티먼트 점수는 -1.0(부정) ~ +1.0(긍정) 범위이며, ML 피처로 자동 반영.

엔드포인트 목록

Method Path 설명
POST /news/collect 뉴스 수집 + 센티먼트 분석
GET /news/articles 뉴스 기사 목록 조회
GET /news/sentiment/{code} 종목 센티먼트 요약

NewsCollectRequest

// POST /news/collect
{
  "market": "KR",
  "codes": [
    ["005930", "삼성전자"],
    ["000660", "SK하이닉스"]
  ],
  "include_market_news": true,
  "max_items_per_code": 50
}

센티먼트 요약 응답

// GET /news/sentiment/005930
{
  "date": "2024-12-30",
  "sentiment": {
    "score": 0.25,           // 일평균 센티먼트
    "label": "positive",
    "std": 0.42               // 센티먼트 표준편차
  },
  "volume": 15               // 뉴스 건수
}

센티먼트 분석은 snunlp/KR-FinBert-SC 모델(HuggingFace)을 사용. 최초 실행 시 모델 다운로드(~500MB)가 필요하며, GPU 없이도 CPU로 동작.

6. 공시 / 수급 (/disclosure)

DART OpenAPI를 통한 전자공시 목록 수집과 KRX(한국거래소)의 수급 데이터(공매도, 프로그램매매)를 수집. 공시에는 KR-FinBert-SC 센티먼트 분석이 자동 적용되며, 유형별 가중치(type_score)가 부여.

엔드포인트 목록

Method Path 설명
POST /disclosure/collect DART 공시 수집 + 센티먼트
GET /disclosure/list 종목별 공시 목록 조회
POST /disclosure/supply/collect KRX 수급 데이터 수집
GET /disclosure/supply/{market}/{code} 종목별 수급 시계열 조회

DisclosureCollectRequest

// POST /disclosure/collect
{
  "market": "KOSPI",
  "codes": ["005930", "000660"],
  "days": 60,                  // 수집 기간 (일)
  "analyze_sentiment": true    // 센티먼트 분석 여부
}

수급 조회 응답

// GET /disclosure/supply/KOSPI/005930
[
  {
    "date": "2024-12-30",
    "market": "KOSPI",
    "code": "005930",
    "short_selling_volume": 1234567,
    "short_selling_ratio": 3.45,
    "program_buy_volume": 5678900,
    "program_sell_volume": 4567800,
    "program_net_volume": 1111100,
    "source": "pykrx"
  }
]

7. 기술적 지표 (/indicators)

수집된 주가 데이터를 기반으로 SMA, EMA, RSI, MACD, Bollinger Bands, OBV 등 기술적 분석 지표를 계산. 각 지표는 개별 엔드포인트로 제공되며, summary 엔드포인트를 통해 전체 지표를 한번에 조회 가능.

엔드포인트 목록

Method Path 설명
GET /indicators/sma/{code} SMA (단순 이동평균)
GET /indicators/ema/{code} EMA (지수 이동평균)
GET /indicators/rsi/{code} RSI (상대강도지수)
GET /indicators/macd/{code} MACD (이동평균수렴확산)
GET /indicators/bollinger/{code} Bollinger Bands (볼린저밴드)
GET /indicators/obv/{code} OBV (거래량 균형)
GET /indicators/summary/{code} 전체 지표 요약

모든 기술적 지표 엔드포인트는 쿼리 파라미터로 window (기간, 기본값 20)와 limit (반환 개수, 기본값 100)을 지원.

지표 요약 응답

// GET /indicators/summary/005930
{
  "status": "success",
  "data": {
    "code": "005930",
    "date": "2024-12-30",
    "close": 56200,
    "sma_20": 55800.5,
    "ema_20": 55920.3,
    "rsi_14": 52.4,
    "macd": 120.5,
    "macd_signal": 95.2,
    "macd_histogram": 25.3,
    "bb_upper": 57200.0,
    "bb_middle": 55800.5,
    "bb_lower": 54401.0,
    "obv": 285643210
  }
}

8. 머신러닝 (/ml)

피처 계산, 모델 학습, 예측까지 ML 파이프라인 전체를 제어. Phase 5 기준 69개 피처(기술적 24 + 재무 9 + 거시경제 11 + 뉴스 5 + 공시/수급 10)를 사용하며, RandomForest, XGBoost, LightGBM 알고리즘과 Optuna 하이퍼파라미터 최적화를 지원.

엔드포인트 목록

Method Path 설명
POST /ml/features/compute 피처 계산
POST /ml/train 모델 학습
GET /ml/models 모델 목록
GET /ml/models/{model_id} 모델 상세 + 학습 로그
DELETE /ml/models/{model_id} 모델 삭제
POST /ml/predict/{code} 종목 예측
GET /ml/predictions 예측 결과 목록 (start_date, end_date 파라미터로 날짜 범위 필터링)
GET /ml/predictions/{code} 종목별 예측 (start_date, end_date 파라미터 지원)
GET /ml/feature-importance/{model_id} 피처 중요도

MLTrainRequest

// POST /ml/train
// Request Body
{
  "sector": "반도체",
  "algorithm": "xgboost",      // "random_forest" | "xgboost" | "lightgbm"
  "train_ratio": 0.85,          // 학습 데이터 비율 (기본 0.85)
  "target_column": "target_5d", // 예측 타겟 (5일 후 수익률)
  "codes": ["005930"],          // optional: 특정 종목만
  "base_date": "2024-12-30"     // optional: 기준일
}

MLPredictResponse

// POST /ml/predict/005930
// 200 OK
{
  "status": "success",
  "data": {
    "code": "005930",
    "name": "삼성전자",
    "model_id": "xgb_semi_20241230_143052",
    "prediction_date": "2024-12-30",
    "target_date": "2025-01-06",
    "signal": "BUY",            // "BUY" | "SELL" | "HOLD"
    "confidence": 0.73,
    "predicted_return": 0.025,   // 예상 수익률 2.5%
    "current_price": 56200,
    "predicted_price": 57605
  }
}

target_dateexchange_calendars 기반 영업일 캘린더로 보정 주말/공휴일을 건너뛴 실제 영업일이 반환

9. 백테스트 (/backtest)

학습된 ML 모델을 과거 데이터에 적용하여 트레이딩 시뮬레이션을 수행. 복수 모델의 예측 신호를 집계(majority vote, weighted vote 등)하여 매매 결정을 내리고, 수익률/위험 지표를 산출. 복수 백테스트 결과를 비교 분석하는 기능도 제공.

엔드포인트 목록

Method Path 설명
POST /backtest/run 백테스트 실행
GET /backtest/runs 백테스트 이력 조회
GET /backtest/runs/{run_id} 백테스트 상세 조회
GET /backtest/runs/{run_id}/trades 거래 로그 조회
GET /backtest/runs/{run_id}/equity 에쿼티 커브 조회
DELETE /backtest/runs/{run_id} 백테스트 삭제
POST /backtest/compare 복수 백테스트 비교
POST /backtest/race/model 모델 레이스 (모델별 개별 백테스트 수익률 경주)
POST /backtest/race/stock 종목 레이스 (종가 수익률 비교 경주)
GET /backtest/race/{race_group} 모델 레이스 결과 재조회

BacktestRunRequest

// POST /backtest/run
// Request Body
{
  "market": "KOSPI",
  "codes": ["005930", "000660"],
  "start_date": "2025-01-01",
  "end_date": "2025-12-31",
  "model_ids": [1, 2, 3],
  "aggregation_method": "majority_vote",  // "majority_vote" (기본) | "weighted_vote" | "probability_avg" | "unanimous"
  "initial_capital": 10000000,
  "transaction_fee": 0.00015,
  "tax_rate": 0.0020,
  "slippage_base_rate": 0.0005,   // 슬리피지 기본 비율 (optional, 기본값 0.0005)
  "risk_free_rate": 0.035,        // 무위험 수익률 (optional, Sharpe 계산에 사용)
  "max_position_pct": 0.2,
  "name": "test_backtest"
}

aggregation_method 옵션

방식 설명
majority_vote 다수결 투표 (기본값)
weighted_vote 모델 정확도 가중 투표
probability_avg 예측 확률 평균
unanimous 만장일치

BacktestRunResponse

// POST /backtest/run
// 200 OK
{
  "status": "success",
  "data": {
    "run_id": 1,
    "name": "test_backtest",
    "market": "KOSPI",
    "codes": ["005930", "000660"],
    "period": {
      "start": "2025-01-01",
      "end": "2025-12-31"
    },
    "metrics": {
      "total_return": 0.156,
      "annualized_return": 0.156,
      "sharpe_ratio": 1.42,
      "sortino_ratio": 2.01,
      "max_drawdown": -0.082,
      "calmar_ratio": 1.90,
      "win_rate": 0.58,
      "profit_factor": 1.65,
      "total_trades": 124,
      "benchmark_return": 0.089,
      "alpha": 0.067
    },
    "initial_capital": 10000000,
    "final_capital": 11560000,
    "created_at": "2025-12-31T15:30:00"
  }
}

거래 로그 응답

// GET /backtest/runs/1/trades
{
  "status": "success",
  "data": [
    {
      "date": "2025-01-06",
      "code": "005930",
      "action": "BUY",
      "price": 56200,
      "quantity": 35,
      "amount": 1967000,
      "fee": 295,
      "signal_confidence": 0.73
    }
  ],
  "total_count": 124
}

에쿼티 커브 응답

// GET /backtest/runs/1/equity
{
  "status": "success",
  "data": {
    "run_id": 1,
    "equity_curve": [
      { "date": "2025-01-01", "equity": 10000000, "drawdown": 0.0 },
      { "date": "2025-01-02", "equity": 10045000, "drawdown": 0.0 },
      { "date": "2025-01-03", "equity": 9982000, "drawdown": -0.0063 }
    ],
    "total_points": 245
  }
}

BacktestCompareRequest

// POST /backtest/compare
// Request Body
{
  "run_ids": [1, 2, 3]
}

BacktestCompareResponse

// POST /backtest/compare
// 200 OK
{
  "status": "success",
  "data": {
    "runs": [
      {
        "run_id": 1,
        "name": "majority_vote_backtest",
        "total_return": 0.156,
        "annualized_return": 0.156,
        "sharpe_ratio": 1.42,
        "sortino_ratio": 2.01,
        "max_drawdown": -0.082,
        "calmar_ratio": 1.90,
        "win_rate": 0.58,
        "profit_factor": 1.65,
        "total_trades": 124,
        "benchmark_return": 0.089,
        "alpha": 0.067
      },
      {
        "run_id": 2,
        "name": "weighted_vote_backtest",
        "total_return": 0.189,
        "annualized_return": 0.189,
        "sharpe_ratio": 1.67,
        "sortino_ratio": 2.35,
        "max_drawdown": -0.071,
        "calmar_ratio": 2.66,
        "win_rate": 0.61,
        "profit_factor": 1.82,
        "total_trades": 118,
        "benchmark_return": 0.089,
        "alpha": 0.100
      }
    ],
    "best_by": {
      "total_return": 2,
      "sharpe_ratio": 2,
      "max_drawdown": 2
    }
  }
}

transaction_fee는 매수/매도 시 적용되는 수수료율이며, tax_rate는 매도 시에만 적용되는 세율. max_position_pct는 종목당 최대 포지션 비중을 제한.

ModelRaceRequest / ModelRaceResponse

// POST /backtest/race/model
// Request Body
{
  "market": "KOSPI",
  "model_ids": [1, 3, 5],           // null이면 전체 활성 모델
  "start_date": "2024-01-01",
  "end_date": "2024-12-31",
  "initial_capital": 10000000
}
// POST /backtest/race/model
// Response
{
  "race_group": "a1b2c3d4-...",
  "race_type": "model",
  "market": "KOSPI",
  "summary": {
    "total_models": 3,
    "success_count": 2,
    "best_model": "xgboost",
    "best_return": 0.152
  },
  "participants": [
    {
      "model_id": 3,
      "model_name": "KOSPI_xgboost_v2",
      "algorithm": "xgboost",
      "status": "success",
      "metrics": { "total_return": 0.152, "sharpe_ratio": 1.23 },
      "equity_curve": [
        { "date": "2024-01-02", "cumulative_return": 0.0 },
        { "date": "2024-01-03", "cumulative_return": 0.005 }
      ]
    }
  ]
}

StockRaceRequest / StockRaceResponse

// POST /backtest/race/stock
// Request Body
{
  "market": "KOSPI",
  "codes": ["005930", "000660", "035720"],
  "period_days": 30
}
// POST /backtest/race/stock
// Response
{
  "race_group": "e5f6g7h8-...",
  "race_type": "stock",
  "market": "KOSPI",
  "period_days": 30,
  "summary": {
    "total_stocks": 3,
    "best_stock": "SK하이닉스",
    "best_return": 0.085
  },
  "participants": [
    {
      "code": "000660",
      "name": "SK하이닉스",
      "total_return": 0.085,
      "equity_curve": [
        { "date": "2025-02-01", "close": 195000, "cumulative_return": 0.0 },
        { "date": "2025-02-03", "close": 198000, "cumulative_return": 0.0154 }
      ]
    }
  ]
}

모델 레이스는 각 모델을 개별 백테스트하여 수익률을 경주 비교하고, 종목 레이스는 백테스트 엔진 없이 종가 수익률만으로 종목 간 성과를 비교한다. race_group UUID로 같은 레이스의 실행들을 묶어 재조회할 수 있다.

10. 리포트 / 구독 (/report) Phase 6 예정

수집된 데이터를 기반으로 시장 리포트를 자동 생성하고, 구독자에게 이메일/카카오톡/Slack으로 발송하는 서비스 GPT-4o-mini로 시장 요약을 생성하고, Jinja2 템플릿 + matplotlib 차트로 HTML 리포트를 렌더링.

엔드포인트 목록 (예정)

Method Path 설명
GET /report/subscribers 구독자 목록 조회
POST /report/subscribers 구독자 등록
POST /report/generate 리포트 즉시 생성 (+ 선택적 발송)
GET /report/history 리포트 이력 목록
GET /report/history/{id} 리포트 상세 조회
GET /report/history/{id}/html HTML 리포트 미리보기
POST /report/history/{id}/deliver 리포트 재발송
GET /report/delivery-logs 발송 이력 조회

리포트 생성 파이프라인

// POST /report/generate
{
  "report_type": "market",       // "market" (종목 리포트는 향후)
  "report_date": "2024-12-30",   // 기준일 (optional, 기본=오늘)
  "deliver": true                // 생성 후 즉시 발송 여부
}

발송 채널

채널 방식 포맷
이메일 SMTP (Gmail) HTML multipart + CID 인라인 이미지
Slack slack_sdk Block Kit 메시지 + 파일 업로드
카카오톡 나에게 보내기 API 피드 템플릿 + 대표 이미지

Phase 6 개발 예정 기능. 스케줄러 연동 시 평일 19:00(KST)에 자동 생성·발송

11. 관리자 (/admin)

시스템 상태 모니터링, 로그 조회, 설정 확인, 스케줄러 잡 관리 등 운영에 필요한 관리 기능을 제공. APScheduler 기반 스케줄러를 통해 데이터 수집, 학습 등의 배치 작업을 예약하고 관리. 잡은 스텝 기반 파이프라인으로 구성되며, 단일 스텝 실행(run-step)이나 특정 스텝부터 재실행(run-from)을 지원. 각 스텝 실행 결과는 pipeline_step_log에 기록되어 세밀한 모니터링이 가능.

엔드포인트 목록

Method Path 설명
GET /admin/health 헬스체크
GET /admin/db DB 상태
GET /admin/logs 로그 조회
GET /admin/config 설정 확인
GET /admin/scheduler/jobs 잡 목록
POST /admin/scheduler/jobs 잡 생성
PUT /admin/scheduler/jobs/{job_id} 잡 수정
DELETE /admin/scheduler/jobs/{job_id} 잡 삭제
POST /admin/scheduler/jobs/{job_id}/run 즉시 실행 (전체 파이프라인)
POST /admin/scheduler/jobs/{job_id}/run-step 단일 스텝만 실행
POST /admin/scheduler/jobs/{job_id}/run-from 지정 스텝부터 이후 전체 실행
GET /admin/scheduler/logs 실행 이력
GET /admin/scheduler/logs/{log_id}/steps 스텝별 로그 조회
GET /admin/scheduler/logs/{log_id}/steps/{step_type}/log 스텝 로그 텍스트 조회

헬스체크 응답

// GET /admin/health
{
  "status": "healthy",
  "uptime": "3d 14h 22m",
  "version": "1.0.0",
  "database": "connected",
  "scheduler": "running"
}

잡 생성 요청

// POST /admin/scheduler/jobs
{
  "job_name": "KOSPI 반도체 수집",
  "market": "KOSPI",
  "cron_expr": "0 18 * * 1-5",     // 평일 18:00 실행
  "days_back": 7,
  "enabled": true,
  "steps": [                          // 파이프라인 스텝 정의
    { "step_type": "price",       "step_order": 1, "enabled": true },
    { "step_type": "fundamental", "step_order": 2, "enabled": true },
    { "step_type": "feature",     "step_order": 3, "enabled": true },
    { "step_type": "ml",          "step_order": 4, "enabled": true }
  ],
  "target_codes": [                    // 대상 종목 (미지정시 전체)
    { "code": "005930", "name": "삼성전자" },
    { "code": "000660", "name": "SK하이닉스" }
  ]
}

step_type 허용값: price fundamental market_investor macro news disclosure supply alternative feature ml predict

즉시 실행 요청

// POST /admin/scheduler/jobs/{job_id}/run
// Request Body (optional)
{
  "base_date": "2024-12-30"  // optional: 특정 기준일로 실행
}

단일 스텝 실행

// POST /admin/scheduler/jobs/{job_id}/run-step
{
  "step_type": "feature",     // 실행할 스텝 타입
  "base_date": "2024-12-30"  // optional
}

지정 스텝부터 실행

// POST /admin/scheduler/jobs/{job_id}/run-from
{
  "from_step": "feature",    // 이 스텝부터 이후 전체 실행
  "base_date": "2024-12-30"  // optional
}

스텝별 로그 조회 응답

// GET /admin/scheduler/logs/{log_id}/steps
[
  {
    "id": 1,
    "log_id": 42,
    "trace_id": "a1b2c3d4-...",
    "step_type": "price",
    "step_order": 1,
    "status": "success",         // pending / running / success / failed / skipped
    "started_at": "2024-12-30 18:00:01",
    "finished_at": "2024-12-30 18:02:15",
    "duration_sec": 134,
    "saved_count": 2450,
    "summary": "50종목 가격 수집 완료",
    "error_message": null
  }
]

스텝 로그 텍스트 조회

// GET /admin/scheduler/logs/{log_id}/steps/{step_type}/log
{
  "step_type": "price",
  "log_text": "[18:00:01] 가격 수집 시작...\n[18:00:02] 005930 수집 완료..."
}

12. 공통 응답 형식

모든 API 응답은 일관된 JSON 구조. 성공과 에러 두 가지 형식으로 구분되며, HTTP 상태 코드와 함께 반환.

성공 응답 (200 OK)

{
  "status": "success",
  "message": "처리 완료",      // optional: 작업 결과 메시지
  "data": { ... }               // 응답 데이터 (엔드포인트마다 다름)
}

에러 응답 (4xx / 5xx)

// 404 Not Found
{
  "status": "error",
  "message": "종목 코드 999999를 찾을 수 없습니다",
  "detail": null
}

// 422 Validation Error
{
  "status": "error",
  "message": "요청 데이터 검증 실패",
  "detail": [
    {
      "loc": ["body", "sector"],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]
}

// 500 Internal Server Error
{
  "status": "error",
  "message": "내부 서버 오류가 발생했습니다",
  "detail": "Database connection timeout"
}

HTTP 상태 코드 요약

상태 코드 설명 사용 상황
200 OK 정상 처리 (조회, 수집, 학습 등)
201 Created 리소스 생성 (잡 생성)
400 Bad Request 잘못된 요청 파라미터
404 Not Found 존재하지 않는 종목/모델/잡
422 Validation Error 요청 Body 검증 실패 (FastAPI 자동)
500 Internal Error 서버 내부 오류 (DB, 외부 API 등)