{
  "ticker": "010950.KS",
  "ticker_name": "S-Oil",
  "status": "success",
  "trade_date": "2026-04-16",
  "analysis_date": "2026-04-17",
  "decision": "{\n  \"rating\": \"OVERWEIGHT\",\n  \"portfolio_stance\": \"BULLISH\",\n  \"entry_action\": \"WAIT\",\n  \"setup_quality\": \"DEVELOPING\",\n  \"confidence\": 0.64,\n  \"time_horizon\": \"medium\",\n  \"entry_logic\": \"010950.KS에 대한 최종 판단은 제한적 OVERWEIGHT이다. 공격적 분석이 지적한 것처럼 2026-04-15 종가 117,500원은 10일 EMA 116,996.84, VWMA 114,690.88, 50일 SMA 112,459.39 위에 있어 중기 상승 구조가 아직 훼손되지 않았고, RSI 54.18도 과열이 아니다. 또한 2025년 12월 분기 영업이익 3,719억 원, 순이익 2,251억 원, 자유현금흐름 6,134억 원, 순부채 6.38조 원에서 5.70조 원으로 감소한 점은 회복 논리를 뒷받침한다. 다만 보수적·중립적 분석이 강조한 대로 ATR이 종가 대비 약 5.9%로 높고, MACD 히스토그램이 1,134.54에서 609.15로 둔화됐으며, 가격도 122,000원에서 119,100원, 117,500원으로 밀려 즉시 매수 확정 신호는 부족하다. 따라서 방향성은 BULLISH로 유지하되 오늘의 실행은 WAIT이다. 116,500~117,000원 지지가 거래량 안정과 함께 확인되면 작은 starter는 정당화될 수 있고, 120,700~122,000원 위에서 거래량을 동반한 종가 안착과 MACD 재확장이 확인되면 추가 진입을 검토한다.\",\n  \"exit_logic\": \"기존 보유분 또는 향후 진입분은 010950.KS가 114,500원 아래로 종가 이탈하면 축소 또는 청산한다. 112,000~112,500원 이탈은 50일 추세 훼손으로 보고 투자 논리 자체의 무효화로 처리한다. 117,000원 방어 실패와 거래량 악화가 동시에 나타나면 114,500원 종가 이탈 전이라도 일부 위험 축소를 고려한다. 1Q 실적이 정제마진, 디젤 스프레드, 재고평가 이익 기대를 확인하지 못하거나, 운전자본 효과를 제외한 현금흐름이 약하고 CAPEX와 순부채 부담이 다시 커지면 등급을 낮춘다. 원유 조달비 상승이 제품 가격으로 전가되지 못하거나 정제마진이 빠르게 둔화되는 경우도 청산 또는 비중 축소 사유다.\",\n  \"position_sizing\": \"초기 진입은 정상 목표 비중의 25~40% 수준으로 제한한다. 116,500~117,000원 지지 확인만으로는 부분 starter만 허용하고, 120,700~122,000원 위 거래량 동반 종가 안착 및 MACD 히스토그램 재확장이 확인될 때 60~70% 수준까지 단계적으로 확대할 수 있다. 1Q 실적에서 영업이익의 질, 재고평가 이익 비중, 운전자본 제외 현금흐름, CAPEX, 순부채, 정제마진 지속성이 확인되기 전까지는 완전한 overweight 비중으로 올리지 않는다.\",\n  \"risk_limits\": \"010950.KS를 120,700~122,000원 저항대에서 거래량 확인 없이 추격하지 않는다. ATR이 종가 대비 약 5.9%이고 3월 초 비정상적 장중 변동 사례가 있었으므로 종가 손절만으로 손실이 완전히 통제된다고 보지 않는다. 전술 손절 기준은 114,500원 종가 이탈, 논리 훼손 기준은 112,000~112,500원 이탈이다. 하락 거래량 확대, 원유 조달 리스크 악화, 정제마진 약화, 음의 운전자본과 CAPEX 부담 재확대, 순부채 감소 정체가 나타나면 추가 매수를 금지한다.\",\n  \"catalysts\": [\n    \"010950.KS 1Q 실적이 정제마진, 디젤 강세, 재고평가 이익으로 시장 기대를 상회하는 경우\",\n    \"010950.KS가 120,700~122,000원 위에서 거래량을 동반해 종가 안착하고 MACD 히스토그램이 다시 확장되는 경우\",\n    \"124,500원 재시험에 성공해 150,000원 목표가 상향 논리의 신뢰도가 높아지는 경우\",\n    \"디젤 수요, 재건 수요, 공급 정상화 지연으로 높은 정제마진이 유지된다는 추가 증거\",\n    \"한화투자증권 중심의 긍정 서사가 다른 증권사 추정치 상향으로 확산되는 경우\",\n    \"순부채 감소가 이어지고 영업현금흐름 개선이 단순 운전자본 타이밍이 아님이 확인되는 경우\"\n  ],\n  \"invalidators\": [\n    \"010950.KS가 114,500원 아래로 종가 이탈해 VWMA 기반 수급 구조가 약화되는 경우\",\n    \"010950.KS가 112,000~112,500원 아래로 이탈해 50일 추세가 훼손되는 경우\",\n    \"116,500~117,000원 지지 실패와 거래량 악화가 동시에 나타나는 경우\",\n    \"MACD 히스토그램 둔화가 이어지고 가격이 122,000원, 119,100원, 117,500원으로 밀린 흐름을 회복하지 못하는 경우\",\n    \"정제마진이나 디젤 스프레드가 예상보다 빠르게 둔화되는 경우\",\n    \"원유 조달비 상승이 제품 가격으로 충분히 전가되지 못하는 경우\",\n    \"1Q 실적 또는 가이던스가 목표가 150,000원 상향 서사를 뒷받침하지 못하는 경우\",\n    \"운전자본 효과를 제외한 자유현금흐름이 약화되고 대규모 CAPEX와 순부채 부담이 다시 커지는 경우\"\n  ],\n  \"watchlist_triggers\": [\n    \"010950.KS가 116,500~117,000원 부근에서 지지를 방어하고 거래량이 안정되는지 확인\",\n    \"010950.KS가 120,700~122,000원 위로 거래량을 동반해 종가 안착하는지 확인\",\n    \"MACD 히스토그램이 609.15 부근 둔화 이후 다시 확장되는지 확인\",\n    \"010950.KS가 114,500원 또는 112,500원 아래로 무거운 거래량과 함께 이탈하는지 확인\",\n    \"1Q 실적의 영업이익, 재고평가 이익, 운전자본 제외 현금흐름, CAPEX, 순부채 변화를 확인\",\n    \"정제마진, 디젤 스프레드, 원유 조달비, KRW/USD 흐름을 갱신\",\n    \"긍정 뉴스가 한화투자증권 보고서 반복 인용을 넘어 다른 독립 증권사 추정치 상향으로 넓어지는지 확인\"\n  ],\n  \"data_coverage\": {\n    \"company_news_count\": 4,\n    \"disclosures_count\": 0,\n    \"social_source\": \"news_derived\",\n    \"macro_items_count\": 0\n  }\n}",
  "started_at": "2026-04-17T08:20:29.054134+09:00",
  "finished_at": "2026-04-17T09:11:18.925827+09:00",
  "duration_seconds": 3049.87,
  "metrics": {
    "llm_calls": 60,
    "tool_calls": 22,
    "tokens_in": 0,
    "tokens_out": 0,
    "tokens_available": false,
    "calls_by_model": {
      "gpt-5.4": 60
    }
  },
  "tool_telemetry": {
    "total_tool_calls": 22,
    "vendor_calls": {
      "yfinance": 15,
      "naver": 3,
      "ecos": 1,
      "opendart": 1,
      "alpha_vantage": 2
    },
    "fallback_count": 5,
    "events": [
      {
        "method": "get_stock_data",
        "vendor": "yfinance",
        "status": "success",
        "fallback": false,
        "note": null
      },
      {
        "method": "get_indicators",
        "vendor": "yfinance",
        "status": "success",
        "fallback": false,
        "note": null
      },
      {
        "method": "get_indicators",
        "vendor": "yfinance",
        "status": "success",
        "fallback": false,
        "note": null
      },
      {
        "method": "get_indicators",
        "vendor": "yfinance",
        "status": "success",
        "fallback": false,
        "note": null
      },
      {
        "method": "get_indicators",
        "vendor": "yfinance",
        "status": "success",
        "fallback": false,
        "note": null
      },
      {
        "method": "get_indicators",
        "vendor": "yfinance",
        "status": "success",
        "fallback": false,
        "note": null
      },
      {
        "method": "get_indicators",
        "vendor": "yfinance",
        "status": "success",
        "fallback": false,
        "note": null
      },
      {
        "method": "get_indicators",
        "vendor": "yfinance",
        "status": "success",
        "fallback": false,
        "note": null
      },
      {
        "method": "get_indicators",
        "vendor": "yfinance",
        "status": "success",
        "fallback": false,
        "note": null
      },
      {
        "method": "get_company_news",
        "vendor": "naver",
        "status": "success",
        "fallback": false,
        "note": null
      },
      {
        "method": "get_social_sentiment",
        "vendor": "naver",
        "status": "fallback",
        "fallback": true,
        "note": "naver: empty or unusable result"
      },
      {
        "method": "get_social_sentiment",
        "vendor": "yfinance",
        "status": "fallback",
        "fallback": true,
        "note": "yfinance: empty or unusable result"
      },
      {
        "method": "get_macro_news",
        "vendor": "ecos",
        "status": "fallback",
        "fallback": true,
        "note": "ecos: ECOS API key is not configured."
      },
      {
        "method": "get_disclosures",
        "vendor": "opendart",
        "status": "fallback",
        "fallback": true,
        "note": "opendart: empty or unusable result"
      },
      {
        "method": "get_company_news",
        "vendor": "naver",
        "status": "success",
        "fallback": false,
        "note": null
      },
      {
        "method": "get_macro_news",
        "vendor": "alpha_vantage",
        "status": "success",
        "fallback": false,
        "note": null
      },
      {
        "method": "get_cashflow",
        "vendor": "yfinance",
        "status": "success",
        "fallback": false,
        "note": null
      },
      {
        "method": "get_income_statement",
        "vendor": "yfinance",
        "status": "success",
        "fallback": false,
        "note": null
      },
      {
        "method": "get_balance_sheet",
        "vendor": "yfinance",
        "status": "success",
        "fallback": false,
        "note": null
      },
      {
        "method": "get_insider_transactions",
        "vendor": "yfinance",
        "status": "fallback",
        "fallback": true,
        "note": "yfinance: empty or unusable result"
      },
      {
        "method": "get_fundamentals",
        "vendor": "yfinance",
        "status": "success",
        "fallback": false,
        "note": null
      },
      {
        "method": "get_insider_transactions",
        "vendor": "alpha_vantage",
        "status": "success",
        "fallback": false,
        "note": null
      }
    ],
    "called_tools": [],
    "intraday_snapshot_used": false
  },
  "quality_flags": [
    "token_usage_unavailable"
  ],
  "report_writer": {
    "status": "success",
    "scope": "ticker",
    "provider": "codex",
    "model": "gpt-5.4"
  },
  "provider": "codex",
  "models": {
    "quick_model": "gpt-5.4",
    "deep_model": "gpt-5.4",
    "output_model": "gpt-5.4"
  },
  "intraday_snapshot_attempts": [
    {
      "ticker": "010950.KS",
      "attempted": true,
      "success": true,
      "checkpoint": "10:05",
      "interval": "5m",
      "attempted_at": "2026-04-17T10:40:08.739699+09:00",
      "provider": "yfinance_intraday",
      "market_data_asof": "2026-04-17T10:20:00+09:00"
    },
    {
      "ticker": "010950.KS",
      "attempted": true,
      "success": true,
      "checkpoint": "selective_rerun",
      "interval": "5m",
      "attempted_at": "2026-04-17T10:56:09.581460+09:00",
      "provider": "yfinance_intraday",
      "market_data_asof": "2026-04-17T10:35:00+09:00"
    },
    {
      "ticker": "010950.KS",
      "attempted": true,
      "success": true,
      "checkpoint": "14:35",
      "interval": "5m",
      "attempted_at": "2026-04-17T14:41:44.848709+09:00",
      "provider": "yfinance_intraday",
      "market_data_asof": "2026-04-17T14:20:00+09:00"
    }
  ],
  "latest_intraday_snapshot_attempt": {
    "ticker": "010950.KS",
    "attempted": true,
    "success": true,
    "checkpoint": "14:35",
    "interval": "5m",
    "attempted_at": "2026-04-17T14:41:44.848709+09:00",
    "provider": "yfinance_intraday",
    "market_data_asof": "2026-04-17T14:20:00+09:00"
  },
  "intraday_snapshot_latest_attempt": {
    "ticker": "010950.KS",
    "attempted": true,
    "success": true,
    "checkpoint": "14:35",
    "interval": "5m",
    "attempted_at": "2026-04-17T14:41:44.848709+09:00",
    "provider": "yfinance_intraday",
    "market_data_asof": "2026-04-17T14:20:00+09:00"
  }
}