{
  "ticker": "034020.KS",
  "ticker_name": "두산에너빌리티",
  "status": "success",
  "trade_date": "2026-04-17",
  "analysis_date": "2026-04-17",
  "decision": "{\n  \"rating\": \"OVERWEIGHT\",\n  \"portfolio_stance\": \"BULLISH\",\n  \"entry_action\": \"WAIT\",\n  \"setup_quality\": \"DEVELOPING\",\n  \"confidence\": 0.62,\n  \"time_horizon\": \"medium\",\n  \"entry_logic\": \"034020.KS의 중기 방향성은 우호적으로 유지한다. 공격적 분석가가 지적한 것처럼 2026-04-16 종가 110800 KRW가 10일 EMA 101843.87, 50일 SMA 98904, 200일 SMA 79492를 모두 상회했고, 거래량도 8123993주로 전일 5470474주보다 증가해 돌파의 질은 약하지 않다. 다만 보수적·중립적 분석가가 강조한 forward PER 약 101배, 베타 1.832, ATR 약 4.85%, 순이익률 0.497%, 운전자본 의존 가능성이 있는 2025년 4분기 현금흐름 개선 때문에 오늘 추격 매수는 보류한다. 신규 진입은 105700-106500 KRW 지지 확인 또는 110800 KRW 상향 재안착과 거래량 후속 확인이 있을 때만 소규모 시작이 정당화된다.\",\n  \"exit_logic\": \"034020.KS가 확인 진입 후 105700 KRW를 종가 기준으로 이탈하면 신규 매수 금지와 전술 비중 축소를 검토한다. 101800-102000 KRW 하회는 10일 EMA 훼손과 돌파 실패가 겹치는 구간으로 보고 중기 OVERWEIGHT 근거를 크게 낮추며 물량을 실질적으로 감축하거나 종료한다. 다음 실적에서 영업이익률 개선, 이자비용 부담 완화, 운전자본 효과를 제외한 자유현금흐름 반복성, 순부채 추가 감소가 확인되지 않으면 투자 등급을 재검토한다.\",\n  \"position_sizing\": \"기존 보유자는 핵심 물량은 유지하되 현재 가격에서 추가 추격은 하지 않는다. 신규 자금은 정상 비중보다 작은 시험 비중으로만 시작하고, 105700-106500 KRW 지지 또는 110800 KRW 재돌파가 확인된 뒤 분할 진입한다. 베타 1.832와 ATR 약 4.85%를 감안해 실적 반복성과 수급 안정이 확인되기 전까지는 전체 포트폴리오에서 과도한 비중 확대를 금지한다.\",\n  \"risk_limits\": \"전술 리스크 기준은 105700 KRW, 중기 추세 보호 기준은 101800-102000 KRW로 둔다. 105700 KRW 이탈은 단순 변동성이 아니라 돌파 신뢰도 약화로 해석하고, 101800-102000 KRW 이탈은 방어 실패로 본다. forward PER 약 101배가 영업이익률, 현금 전환, 수주 모멘텀으로 뒷받침되지 않으면 비중을 늘리지 않는다. 외국인·기관 매도와 KOSPI 약세가 지속될 경우 고베타 노출을 낮춘다.\",\n  \"catalysts\": [\n    \"034020.KS가 105700-106500 KRW를 종가 기준으로 지키고 이후 110800 KRW 위로 거래량을 동반해 재안착\",\n    \"원전 공급망, 전력 인프라, 해외 에너지 협력 관련 뉴스가 실제 수주 또는 실적 기대를 높이는 방향으로 이어짐\",\n    \"2025년 4분기 영업현금흐름 1.397조 KRW, 자유현금흐름 1.206조 KRW, 순부채 감소가 일회성 운전자본 효과가 아니라 반복 가능한 개선으로 확인\",\n    \"자사주 취득 정정 공시가 주주가치에 긍정적인 조건으로 명확해짐\",\n    \"KOSPI 위험선호 회복과 함께 외국인·기관의 대형주 매도 압력이 완화\"\n  ],\n  \"invalidators\": [\n    \"034020.KS가 101800-102000 KRW를 종가 기준으로 하회해 돌파 실패와 10일 EMA 훼손을 동시에 시사\",\n    \"105700 KRW 이탈 후 거래량이 증가하며 매도 압력이 확대\",\n    \"외국인·기관 매도가 시장 안정 이후에도 지속돼 2026-04-17 약세가 단순 조정이 아니라 분산 매도로 확인\",\n    \"다음 실적에서 영업이익률, 순이익률, 자유현금흐름, 순부채 개선이 기대를 충족하지 못함\",\n    \"원전·전력 인프라·해외 협력 재료가 구체적 계약이나 이익 전망 개선으로 연결되지 못함\",\n    \"자사주 취득 관련 후속 공시가 불리하거나 재무 부담을 키우는 방향으로 확인\"\n  ],\n  \"watchlist_triggers\": [\n    \"034020.KS가 110800 KRW 위에서 종가를 형성하고 최근 돌파일에 준하는 거래량 후속 매수세를 보임\",\n    \"034020.KS가 105700-106500 KRW에서 거래량 감소와 함께 지지를 확인하고 RSI가 70 이상 과열로 급등하지 않음\",\n    \"034020.KS가 105700 KRW를 하회해 신규 매수 금지와 기존 전술 비중 축소 검토가 필요해짐\",\n    \"다음 실적에서 영업이익률 확대, 이자비용 부담 완화, 운전자본 효과를 제외한 양의 자유현금흐름, 순부채 추가 감소가 확인\",\n    \"KRX와 KOSPI 위험선호가 개선되고 외국인·기관 순매도 압력이 완화\",\n    \"110800 KRW 재돌파가 거래량 없이 발생하거나 외국인·기관 매도가 지속돼 돌파 추격을 보류해야 하는 상황 발생\"\n  ],\n  \"data_coverage\": {\n    \"company_news_count\": 4,\n    \"disclosures_count\": 1,\n    \"social_source\": \"news_derived\",\n    \"macro_items_count\": 1\n  }\n}",
  "started_at": "2026-04-17T09:25:41.733139+09:00",
  "finished_at": "2026-04-17T09:37:19.421790+09:00",
  "duration_seconds": 697.69,
  "metrics": {
    "llm_calls": 52,
    "tool_calls": 22,
    "tokens_in": 0,
    "tokens_out": 0,
    "tokens_available": false,
    "calls_by_model": {
      "gpt-5.4": 52
    }
  },
  "tool_telemetry": {
    "total_tool_calls": 22,
    "vendor_calls": {
      "yfinance": 15,
      "naver": 3,
      "ecos": 1,
      "opendart": 1,
      "alpha_vantage": 2
    },
    "fallback_count": 4,
    "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": "success",
        "fallback": false,
        "note": null
      },
      {
        "method": "get_macro_news",
        "vendor": "alpha_vantage",
        "status": "success",
        "fallback": false,
        "note": null
      },
      {
        "method": "get_company_news",
        "vendor": "naver",
        "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_income_statement",
        "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"
  },
  "intraday_snapshot_attempts": [
    {
      "ticker": "034020.KS",
      "attempted": true,
      "success": true,
      "checkpoint": "10:05",
      "interval": "5m",
      "attempted_at": "2026-04-17T10:40:27.265813+09:00",
      "provider": "yfinance_intraday",
      "market_data_asof": "2026-04-17T10:20:00+09:00"
    },
    {
      "ticker": "034020.KS",
      "attempted": true,
      "success": true,
      "checkpoint": "selective_rerun",
      "interval": "5m",
      "attempted_at": "2026-04-17T10:56:29.798934+09:00",
      "provider": "yfinance_intraday",
      "market_data_asof": "2026-04-17T10:35:00+09:00"
    },
    {
      "ticker": "034020.KS",
      "attempted": true,
      "success": true,
      "checkpoint": "14:35",
      "interval": "5m",
      "attempted_at": "2026-04-17T14:42:05.009471+09:00",
      "provider": "yfinance_intraday",
      "market_data_asof": "2026-04-17T14:20:00+09:00"
    }
  ],
  "latest_intraday_snapshot_attempt": {
    "ticker": "034020.KS",
    "attempted": true,
    "success": true,
    "checkpoint": "14:35",
    "interval": "5m",
    "attempted_at": "2026-04-17T14:42:05.009471+09:00",
    "provider": "yfinance_intraday",
    "market_data_asof": "2026-04-17T14:20:00+09:00"
  },
  "intraday_snapshot_latest_attempt": {
    "ticker": "034020.KS",
    "attempted": true,
    "success": true,
    "checkpoint": "14:35",
    "interval": "5m",
    "attempted_at": "2026-04-17T14:42:05.009471+09:00",
    "provider": "yfinance_intraday",
    "market_data_asof": "2026-04-17T14:20:00+09:00"
  }
}