Ë
    $K¦j´  ã                  ó�   — d dl mZ d dlmZ d dlmZ d dlZd dlZddl	m
Z
 dZ ed¬	«       G d
„ d«      «       Z	 	 d	 	 	 	 	 	 	 dd„Zy)é    )Úannotations)Ú	dataclass)ÚPathNé   )ÚSettingsz0.1.0T)Úfrozenc                  ó6   — e Zd ZU ded<   ded<   ded<   ded<   y)ÚFactorDatasetResultÚintÚrowsÚstocksÚperiodsr   Úoutput_pathN)Ú__name__Ú
__module__Ú__qualname__Ú__annotations__© ó    ú=C:\FundamentalWorkbench\src\fundamental_mvp\factor_dataset.pyr
   r
      s   … à
ƒIØƒKØƒLØÔr   r
   c                ó~  — t        | j                  «      j                  dd«      }t        | j                  «      j                  dd«      }t        | j                  dz  «      j                  dd«      }d}|r7t        j                  |«      j                  «       j                  «       }d|› d�}t        j                  |«      j                  «       j                  «       }d|› d|› d|› d	|› d
t        › d|› d�}	t        j                  «       5 }
|
j                  |	«      j                  «       }ddd«       dD ]  }t        j                  |   «      ||<   Œ j                  s$|d   |d   kD  j!                  «       rt#        d«      ‚| j                  j%                  dd¬«       | j                  dz  }|j'                  |d¬«       |j)                  | j                  dz  dd¬«       t+        t-        |«      t/        |d   j1                  «       «      t/        |d   j1                  «       «      |¬«      S # 1 sw Y   �ŒxY w)as  Build a point-in-time monthly factor panel from the M1 data assets.

    Financial rows only become visible on ``available_trade_date``. Forward
    returns are labels and are never used to construct the factor columns.
    Industry membership is the current M1 taxonomy, so historical industry
    drift remains an explicit data limitation rather than being hidden.
    Ú'z''zsecurity_master.parquetÚ zAND trade_date <= DATE 'a«  
    WITH monthly_raw AS (
      SELECT source_code,
             date_trunc('month', trade_date) AS month,
             last_day(date_trunc('month', trade_date)) AS rebalance_date,
             arg_max(trade_date, trade_date) AS price_date,
             arg_max(close_qfq, trade_date) AS close_qfq,
             arg_max(close_raw, trade_date) AS close_raw,
             avg(amount_yuan) AS avg_amount
      FROM read_parquet('z#')
      WHERE trade_date >= DATE 'z' a*  
        AND close_qfq > 0
      GROUP BY source_code, date_trunc('month', trade_date)
    ), monthly AS (
      SELECT *,
             lead(price_date) OVER (PARTITION BY source_code ORDER BY month) AS next_date,
             lead(close_qfq) OVER (PARTITION BY source_code ORDER BY month) / close_qfq - 1 AS forward_return
      FROM monthly_raw
    ), joined AS (
      SELECT m.*, f.report_period, f.available_trade_date,
             f.weighted_roe_reported, f.gross_margin_reported,
             f.operating_revenue_yoy_reported, f.net_profit_yoy_reported,
             f.debt_ratio_reported, f.current_ratio_reported,
             f.asset_turnover_reported, f.ocf_net_profit_ratio_reported,
             f.research_development_expense_ytd, f.operating_revenue_ytd,
             f.parent_equity, f.total_shares,
             row_number() OVER (
               PARTITION BY m.source_code, m.rebalance_date
               ORDER BY f.available_trade_date DESC, f.report_period DESC
             ) AS finance_rank
      FROM monthly m
      LEFT JOIN read_parquet('a˜  ') f
        ON f.source_code = m.source_code
       AND f.available_trade_date <= m.price_date
    )
    SELECT j.source_code, s.security_id, s.name,
           s.industry_l1_code, s.industry_l1_name,
           s.industry_l2_code, s.industry_l2_name,
           j.rebalance_date, j.price_date, j.next_date, j.report_period, j.available_trade_date,
           j.close_qfq AS close, j.close_raw, j.avg_amount, j.forward_return,
           j.weighted_roe_reported AS profitability,
           j.gross_margin_reported AS gross_margin,
           (j.operating_revenue_yoy_reported + j.net_profit_yoy_reported) / 2 AS growth,
           -j.debt_ratio_reported AS balance_sheet,
           j.current_ratio_reported AS liquidity,
           j.asset_turnover_reported AS efficiency,
           j.ocf_net_profit_ratio_reported AS cash_quality,
           CASE WHEN j.operating_revenue_ytd > 0
                THEN j.research_development_expense_ytd / j.operating_revenue_ytd END AS rd_intensity,
           CASE WHEN j.parent_equity > 0 AND j.total_shares > 0 AND j.close_raw > 0
                THEN j.parent_equity / (j.close_raw * j.total_shares) END AS book_to_price,
           'zC' AS dataset_version
    FROM joined j
    LEFT JOIN read_parquet('zµ') s USING (source_code)
    WHERE j.finance_rank = 1 AND j.forward_return IS NOT NULL
      AND j.available_trade_date IS NOT NULL
    ORDER BY j.rebalance_date, j.source_code
    N)Úrebalance_dateÚ
price_dateÚ	next_dateÚreport_periodÚavailable_trade_dater   r   zDfactor panel contains financial information unavailable at rebalanceT)ÚparentsÚexist_okzfactor_monthly_panel.parquetF)Úindexzfactor_monthly_panel.csvz	utf-8-sig)r!   ÚencodingÚsource_coder   )r   r   r   r   )ÚstrÚdaily_price_pathÚreplaceÚfinancial_pit_pathÚprocessed_dirÚpdÚ	TimestampÚdateÚ	isoformatÚFACTOR_DATASET_VERSIONÚduckdbÚconnectÚexecuteÚfetchdfÚto_datetimeÚemptyÚanyÚAssertionErrorÚmkdirÚ
to_parquetÚto_csvr
   Úlenr   Únunique)ÚsettingsÚ
start_dateÚend_dateÚ
price_pathÚfinance_pathÚmaster_pathÚ
end_filterÚsafe_endÚ
safe_startÚqueryÚ
connectionÚpanelÚcolumnr   s                 r   Úbuild_monthly_factor_panelrH      s-  € ô �X×.Ñ.Ó/×7Ñ7¸¸TÓB€JÜ�x×2Ñ2Ó3×;Ñ;¸CÀÓF€LÜ�h×,Ñ,Ð/HÑHÓI×QÑQÐRUÐW[Ó\€KØ€JÙÜ—<‘< Ó)×.Ñ.Ó0×:Ñ:Ó<ˆØ/°¨z¸Ð;ˆ
Ü—‘˜jÓ)×.Ñ.Ó0×:Ñ:Ó<€Jð	ð %˜ð &!Ø!+ ¨B¨z¨lð ;ð*  ,˜nð -ô( $Ð$ð %à(˜Mð *ðk9€Eôt 
�‰Ô	˜ZØ×"Ñ" 5Ó)×1Ñ1Ó3ˆ÷ 
ó iˆÜŸ™ u¨V¡}Ó5ˆˆfŠð ià�;Š;˜EÐ"8Ñ9¸EÀ,Ñ<OÑO×TÑTÔVÜÐcÓdÐdà×Ñ× Ñ ¨¸Ð Ô=Ø×(Ñ(Ð+IÑI€KØ	×Ñ�[¨ÐÔ.Ø	‡L�L�×'Ñ'Ð*DÑDÈEÐ\g€LÔhÜÜ�‹ZÜ�5˜Ñ'×/Ñ/Ó1Ó2Ü�EÐ*Ñ+×3Ñ3Ó5Ó6Øô	ð ÷ 
Ñ	ús   Ä H2È2H<)z
2019-01-01N)r;   r   r<   r$   r=   z
str | NoneÚreturnr
   )Ú
__future__r   Údataclassesr   Úpathlibr   r.   Úpandasr)   Úconfigr   r-   r
   rH   r   r   r   Ú<module>rO      ss   ðÝ "å !Ý ã Û å ð !Ð ñ �$Ô÷ð ó ðð #Øð`Øð`àð`ð ð`ð ô	`r   