{
  "ticker": "010950.KS",
  "ticker_name": "S-Oil",
  "status": "success",
  "trade_date": "2026-04-16",
  "analysis_date": "2026-04-16",
  "decision": "{\n  \"rating\": \"OVERWEIGHT\",\n  \"portfolio_stance\": \"BULLISH\",\n  \"entry_action\": \"WAIT\",\n  \"setup_quality\": \"DEVELOPING\",\n  \"confidence\": 0.6,\n  \"time_horizon\": \"medium\",\n  \"entry_logic\": \"010950.KS의 중기 방향성은 긍정적이지만, 오늘 즉시 신규 진입할 만큼 가격·거래량 확인은 부족하다. 공격적 분석가가 지적한 대로 2025-12-31 분기 영업이익은 3719억 원으로 직전 분기 2292억 원에서 개선됐고, 순이익은 2251억 원으로 확대됐으며, 자유현금흐름은 6134억 원 플러스로 전환됐다. 현금성 자산 1.83조 원 증가와 단기차입금 3.19조 원에서 2.50조 원으로 감소한 점도 회복 논리를 뒷받침한다. 또한 117500원은 50일선 112208.83원과 200일선 81635.41원 위에 있어 중기 상승 구조가 훼손됐다고 보기 어렵다. 다만 보수적·중립적 분석가가 지적한 것처럼 자유현금흐름 개선에는 운전자본 변화 1.42조 원과 유동부채 증가 효과가 포함되어 지속성 검증이 필요하고, 주가는 122000원에서 117500원으로 밀렸으며 MACD 히스토그램은 1134.54에서 775.48로 둔화됐다. 거래량도 844806주, 550835주, 623589주 이후 410000주대까지 줄었고 2026-04-16 유효 일봉 신호가 없어 실행은 대기한다. 116700~117500원 지지 확인과 410000주를 의미 있게 넘는 거래량 회복, 또는 122000원 종가 회복과 거래량 확장이 확인되면 작은 starter는 정당화될 수 있다.\",\n  \"exit_logic\": \"기존 010950.KS 보유분은 114300원 VWMA·4월 저점권 위에 있는 동안 유지하되, 114300원 종가 이탈 후 빠른 회복이나 거래량 개선이 없으면 감축한다. 112000~112200원 50일선 지지권 종가 이탈은 중기 추세와 회복 논리 훼손으로 보고 신규 매수를 중단하며 매도 또는 전면 재평가한다. 122000~124500원 구간에서 거래량 확장 없이 반복적으로 막히면 부분 차익 실현 또는 손절 기준 상향이 필요하다.\",\n  \"position_sizing\": \"신규 자금은 정상 핵심 비중보다 작게, 단계적으로만 투입한다. ATR이 약 7216 KRW로 최근 종가의 약 6.1%라서 116700~117500원 지지 확인 시에도 정상 목표 비중의 25~33% 수준 starter만 허용한다. 122000원 종가 회복과 거래량 확장이 뒤따를 때 다음 tranche를 검토한다. 기존 보유자는 중간 수준의 노출은 유지할 수 있지만, 추가 매수는 확인 전까지 보류한다.\",\n  \"risk_limits\": \"114300원 이탈은 경고가 아니라 감축 검토 신호로 취급한다. 112000~112200원 이탈은 hard stop 또는 thesis reassessment 기준이다. 총차입금 7.91조 원, 순차입금 5.70조 원, 유동비율 0.706, 운전자본 -3.60조 원이라는 취약성을 감안해 정제마진, 유가, KRW, 운전자본, 자유현금흐름, 단기차입금 중 하나라도 악화되면 평균단가 낮추기를 금지한다. 2026-04-16 일봉·장중 스냅샷 부재 때문에 실시간 가격, 거래량, 호가 유동성 확인 전에는 비중을 늘리지 않는다.\",\n  \"catalysts\": [\n    \"010950.KS가 122000원을 종가 기준으로 회복하고 거래량이 확장되며 124500원 재시험 구간에 진입한다.\",\n    \"다음 분기 실적에서 2025-12-31의 영업이익 3719억 원, 순이익 2251억 원, 자유현금흐름 6134억 원 회복이 반복 가능하다는 점이 확인된다.\",\n    \"정제마진, 국제유가 안정, KRW 조건이 재고평가손실 없이 이익 회복을 지지한다.\",\n    \"단기차입금과 순차입금이 대규모 capex에도 추가로 감소한다.\",\n    \"브랜드 수상, MY S-OIL, 품질 보증, 주유소 서비스 경쟁력이 내수 소매 방어력을 보조한다.\"\n  ],\n  \"invalidators\": [\n    \"010950.KS가 114300원 아래로 종가 이탈한 뒤 빠르게 회복하지 못한다.\",\n    \"010950.KS가 112000~112200원 50일선 지지권 아래로 종가 이탈한다.\",\n    \"다음 분기에서 영업손실 재발, 자유현금흐름 약화, 또는 운전자본 효과 반전이 확인된다.\",\n    \"총차입금, 순차입금, 단기차입금이 capex 부담으로 다시 materially 증가한다.\",\n    \"유가 하락이 재고평가손실과 에너지 섹터 자금 유출로 이어지고 정제마진 개선이 이를 상쇄하지 못한다.\"\n  ],\n  \"watchlist_triggers\": [\n    \"116700~117500원에서 지지 반응이 나오고 거래량이 최근 410000주대를 의미 있게 상회한다.\",\n    \"122000원 종가 회복과 거래량 확장이 동시에 나타나 starter 이후 추가 tranche 근거를 제공한다.\",\n    \"124500원 최근 고점권에서 돌파 또는 거래량 없는 재차 실패가 확인된다.\",\n    \"114300원 종가 이탈 여부를 첫 번째 downside confirmation으로 확인한다.\",\n    \"112000~112200원 종가 이탈 여부를 중기 thesis deterioration 신호로 확인한다.\",\n    \"정제마진, 국제유가, KRW 환율, 재고평가손익, capex funding, 다음 실적 발표 일정 업데이트를 추적한다.\"\n  ],\n  \"data_coverage\": {\n    \"company_news_count\": 4,\n    \"disclosures_count\": 0,\n    \"social_source\": \"news_derived\",\n    \"macro_items_count\": 1\n  }\n}",
  "started_at": "2026-04-16T09:53:47.322406+09:00",
  "finished_at": "2026-04-16T10:06:42.952470+09:00",
  "duration_seconds": 775.63,
  "metrics": {
    "llm_calls": 58,
    "tool_calls": 22,
    "tokens_in": 0,
    "tokens_out": 0,
    "tokens_available": false,
    "calls_by_model": {
      "gpt-5.4": 58
    }
  },
  "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_social_sentiment",
        "vendor": "naver",
        "status": "fallback",
        "fallback": true,
        "note": "naver: empty or unusable result"
      },
      {
        "method": "get_company_news",
        "vendor": "naver",
        "status": "success",
        "fallback": false,
        "note": null
      },
      {
        "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_income_statement",
        "vendor": "yfinance",
        "status": "success",
        "fallback": false,
        "note": null
      },
      {
        "method": "get_balance_sheet",
        "vendor": "yfinance",
        "status": "success",
        "fallback": false,
        "note": null
      },
      {
        "method": "get_cashflow",
        "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",
    "intraday_snapshot_missing_same_day"
  ],
  "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"
  }
}