
    ΧjC                     .   d Z ddlZddlZddlZddlZddlZej                            dej        	                    ej        
                    e                               ddlZddlmZ ddlmZ dZd Zd Zd Zd	 Zd
 Zedk    r e             dS dS )u  池级缓存 × 2（ADJUDICATION 2026-09-14 §1/§2；Mac 侧产物）

输出（--out 目录；沙盒默认 /tmp/pool_cache_sbx，落库时 --out $BASE）:
  ① pool_signal_count.csv  pool,trade_date,n_sig
     S(pool,d) = 该池在交易日 d 的**达标信号数**（当日使 chain_for_buy 定出 tb=d 的股票家数）。
     达标定义与 scan **同一份实现**（g.build_sig + plot_ideal_top10.chain_for_buy），严禁另写一份。
  ② pool_daily_stats.csv   pool,trade_date,n_zt,avg_ret,n_members
     n_zt      = 该池当日 pct_chg >= 9.8 的成分股家数（f13 分子 = n_zt/20）
     avg_ret   = 该池当日**有行情**成分股 pct_chg 均值（百分数单位，f14）
     n_members = 当日实际参与计算的成分股数（缺失判据: < 0.8 × 现行名单成分数 → 该日池级特征置 NaN）

成分股口径: 用 `{pool}_members.pkl` 的**时点快照**（shape={月末日: set(代码)}，取 ≤ 当日 的最近快照；
d 早于首个非空快照时用首个非空快照）。这是"当日真实成分"的最佳可得近似，且比"全用现行名单"更忠实
—— 裁定原文写"现行名单"，但其目标为"成分股家数"，此处按"时点名单"实现并在对照报告中并列给出两种口径。

用法:
  python build_pool_caches.py                      # 沙盒
  python build_pool_caches.py --out $BASE          # 落库（非交易日执行）
  python build_pool_caches.py --out $BASE --append # 只补库中尚无的 (pool,date)
    N)COMBO)chain_for_buyg#@c                     t          j        t          j         d|  d          t	          fdD                       }fd|D             S )uD   {日期: set(代码)} 时点快照, 按日期升序; 过滤空快照/z_members.pklc              3   N   K   | ]}t          |                   d k    |V   dS )r   N)len.0kms     //Users/xpresso/zt_app/code/build_pool_caches.py	<genexpr>zsnapshots.<locals>.<genexpr>$   s1      ..aAaD		A..    c                 >    g | ]}|t          |                   fS  )setr	   s     r   
<listcomp>zsnapshots.<locals>.<listcomp>%   s'    '''qQAaD		N'''r   )pdread_picklegBASEsorted)poolksr   s     @r   	snapshotsr   !   sa    
!&55455566A	....1...	.	.B''''B''''r   c                 D    | d         d         }| D ]\  }}||k    r|} |S )u2   ≤ date 的最近快照; 早于首个则用首个r      r   )snapsdatepickr   ss        r   members_asofr"   (   s:    8A;D  199DDKr   c                    g }|                                 D ]6\  }}|                    |ddg                             |                     7t          j        |d          }t          j        |d         d          |d<   |                    dg          }i }g }|                    d          D ]\  }	}
|	|vrt          ||	          ||	<   ||	         }|
|
d	         	                    |                   }|j
        r(|                    | |	d
t          d          d
f           t|                    | |	t          |d         t          k                                              t          |d                                                   t          t!          |                    f           t          j        |g d          S )u;   ② 池×日统计（时点成分股 ∩ 当日有行情）
trade_datepct_chg)codeTignore_indexcoerce)errors)subsetr&   r   nanr   r$   n_ztavg_ret	n_members)columns)itemsappendassignr   concat
to_numericdropnagroupbyr"   isinemptyfloatintZT_PCTsummeanr   	DataFrame)r   r   dailiespartsr&   ddf	mem_cacherowsdtsubmsetr!   s                r   
pool_statsrJ   3   s   E==?? E EaQi0188d8CCDDDD	5t	,	,	,BM"Y-AAAByM	9+	&	&BID::l++ n nCY(33IbM}F  &&'7 	BKKr1eEllA6777T2sAiLF$:#?#?#A#ABBE!I,J[J[J]J]D^D^`cdghidjdj`k`klmmmm<&\&\&\]]]]r   c           
      :   t          j        ||          }i |                                D ]\  }}||                             d                              d          }|D ]z\  }}	t          |||t          |                    \  }
}}|
+t          |d         j        |                   }|t          ||          vr^	                    |d          dz   |<   {t          j        | t                    fdt                    D             d          S )	uB   ① 达标信号数按 tb(信号日)计数（仅时点成分股）r$   T)dropNr   r   c                      g | ]
}|         S r   r   )r
   r   cnts     r   r   z%pool_signal_count.<locals>.<listcomp>W   s    "?"?"?a3q6"?"?"?r   r   r$   n_sig)r   	build_sigr2   sort_valuesreset_indexr   strilocr"   getr   r@   r   )r   r   rA   bpsigr&   bsrC   bdt0dt0itaitbitbrN   s                 @r   pool_signal_countr`   H   s4   
+gr
"
"C
CIIKK 	) 	)bDM%%l33??T?JJ 	) 	)IR)!T2s2ww??MCc{Q|_)#.//B<r2222ggb!nnq(CGG	) <VC[["?"?"?"?6#;;"?"?"?A A B B Br   c                  j   t          j                    } |                     dd           |                     dd           |                     dd           |                                 t	          j        j        d	
           d j                            d          D             }t          j	                    }g g }}|D ]t}t          |          }t          j        |          \  }}t          |||          }	t          |||t          |                   }
|                    |	           |                    |
           t#          | dt%          |           dt%          |d         d                    dt%          |	           d|	d                                          d|	d                                          dt%          |
           d|
d                                          d|
d                                          dt+          |
d                                                    d	           vt/          j        |d	          }t/          j        |d	          }fd} ||dg d            ||dg d           t#          dt          j	                    |z
  d d!           d S )"Nz--outz/tmp/pool_cache_sbx)defaultz--poolszhs300,zz500,zz1000,zz2000z--append
store_true)actionT)exist_okc                     g | ]}||S r   r   )r
   ps     r   r   zmain.<locals>.<listcomp>a   s    0001a0Q000r   ,u   : 时点快照 u    个(现行名单 r   u    只) | 统计 u    日(r$   ~u   ) | 信号日 u	   ) 合计 rP   )flushr'   c           	         j          d| }j        rt          j                            |          rt          j        |dt          i          }t          t          |d         |d                             | | 
                    fdd                    }t          |          rt          j        ||gd	          n|}|                    ddg          |                             |d
           t          | dt          |           dt          |           d           d S |                     ddg          |                             |d
           t          | dt          |            d|            d S )Nr   r$   )dtyper   c                 (    | d         | d         fv S )Nr   r$   r   )rhaves    r   <lambda>z%main.<locals>.write.<locals>.<lambda>u   s    !F)Q|_)E)M r   r   )axisTr'   F)indexu	   : 追加 u    行 -> 共 u    行z: u    行 -> )outr3   ospathexistsr   read_csvrT   r   zipapplyr   r5   rR   to_csvprint)	rD   namecolsfpoldaddrt   rp   as	          @r   writezmain.<locals>.writep   s   8 		4r** 		4+bs(;<<<Cs3v;L(9::;;DbhhMMMMTUhVVVWC>A#hhO")S#JT::::CCOOV\233D9@@5@QQQTHHCHHHH#c((HHHIIIIINNFL12248??%?PPPT22SWW22b2233333r   zpool_signal_count.csvrO   zpool_daily_stats.csvr-   u   完成, 用时 z.0fr!   )argparseArgumentParseradd_argument
parse_argsru   makedirsrt   poolssplittimer   r   	load_poolrJ   r`   r   r3   r|   r   minmaxr<   r>   r   r5   )apr   t0	sig_parts
stat_partsr   sn_rA   stscstatssigsr   r   s                 @r   mainr   Z   s   		 	"	"BOOG%:O;;;OOI'BOCCCOOJ|O444
AK%%%%00c**000E	BzI r rt__[&&
7b'**tR%+>>"y//333 e ec"gg e eRVAY e e`cdf`g`g e e\"&&((e e+-l+;+?+?+A+Ae eQTUWQXQXe e\"&&((e e+-l+;+?+?+A+Ae eLOPRSZP[P_P_PaPaLbLbe elp	r 	r 	r 	r 	r Ijt444E9YT222D4 4 4 4 4 
E$')H)H)HIII	E%')_)_)_```	
3DIKK",
3
3
3
344444r   __main__)__doc__r   ru   sysr   pandasr   rv   insertdirnameabspath__file__grid_orr   scan_daily_tbr   plot_ideal_top10r   r=   r   r"   rJ   r`   r   __name__r   r   r   <module>r      s*   (                     27??27??8#<#<== > > >           * * * * * *	( ( (  ^ ^ ^*B B B$%5 %5 %5P zDFFFFF r   