
    TjM                     T   d Z ddlZddlZddlZddlZddlZddlZddl	m
Z
 dZdZddddd	Zd
ZdZdZdZdZdZdZddddddddZg dZg dZg dZg dZg dZg dZg dZg dZg dZd Zd  Z d.d!Z!d" Z"d# Z#d$ Z$d% Z%d& Z&d' Z'ed(defd)Z(d* Z)d.d+Z*d, Z+e,d-k    r e+             dS dS )/u]  
涨停缩量回调突破 - 网格搜索 v3 (缩量OR定义 + 合并卖出止盈OR回撤 + 最大持有30天)
买入: T0涨停 -> ta∈(T0+1,T0+sw] 缩量(基准zt OR maN, 系数vs, 均量窗n) 且收盘<P0 -> tb∈(ta+1,T0+bu] 收盘突破P0×(1+bs) -> 次日开盘买
卖出: 盘中回撤dd(基准=昨日最高收盘) -> 收盘止盈profit -> 超时MAX_HOLD=30天
阶段1: 卖出网格 止盈{10,15,20,25,30}×回撤{5,7,10,12,15}=25
阶段2a: 缩量网格 基准{zt,maN,or}×n{3,5,8,10}×系数{0.4-0.8}×窗口{3,5,8}=135
阶段2b: 突破网格 上限{6,8,10}×强度{0-3%}×量能{不限,1.5,2,3}=84
    N)Poolz&/Users/xpresso/zt_app/backtest_zt_full20210101g#@gfffff3@gfffff=@)maingemstarbj   g    .A皙?   gMb0?g{GzT?gMbP?zt333333?           vol_basema_n
vol_shrink
shrink_winbreak_upbreak_strengthzt_vol_filter)皙?333333?r
   g      ?g333333?Gz?)皙?gQ?r   gQ?r   r   )r   maNor)   r   r   
   )g?g      ?r   gffffff?g?)r   r   r   )   r   r   )r   g{Gzt?g{Gz?gQ?g{Gz?g?gQ?)r   g      ?g       @g      @c                     |                      d          rdS |                      d          rdS |                      d          rdS dS )N)6000r   )300301r   688r   r   )
startswith)codes    code/grid_or.py
board_typer*   &   sI    |$$3VV~&&4uuu,ff4    c                 b   t          j        t           d|  d          }i }t           d|  }t          j        |          D ]j}|                    d          rS|d d         }t          j        | d| dt          i          }t          |          dk    rt          |           |||<   k||fS )	N/z_members.pklz/daily_z.csv
trade_date)dtyper   )
pdread_pickleBASEoslistdirendswithread_csvstrlen_derive_split_prices)poolmembersdailiesddirfr(   ds          r)   	load_poolrA   ,   s    n99t999::GG!!4!!DZ " "::f 	"SbS6DtMMaMM,1DEEEA1vvzz$Q''' !Gr+   c                    d| j         vs	d| j         vr| S | d                             t                    }|t          |          }nDd| j         v r!t          | d         j        d                   }nt          |j        d                   }|dk    r| S dD ]d}| d|z                                t                    }||z                      d	          | d
|z   <   ||z  |z                      d	          | d|z   <   e|| d<   | S )u  若文件仅存 raw_* + adj_factor，在内存派生 qfq_/hfq_ 列供判定/K线用。
    若无 factor 或 raw（如研究侧旧数据），保持原列不动（fallback 读文件既有列）。
    派生恒等式：hfq = raw×factor（后复权）；qfq = raw×factor/latest（前复权，展示时算）。

    ⚠️ latest 必须是**该股整段末行因子**（切片归一基准会随窗口漂移 → 标注/蜡烛错位）：
    优先序 ①显式传入 latest_factor ②帧内已盖的 `adj_factor_latest` 列(整段常量)
    ③退化为本帧末行因子——**仅当调用方传的是完整序列才正确**。派生后会在帧上盖
    `adj_factor_latest` 常量列，故此后对任意窗口切片再调用都稳定（切片不变性）。
    
adj_factor	raw_closeNadj_factor_latestr   )openhighlowcloseraw_   hfq_qfq_)columnsastypefloatilocround)r@   latest_factorfacltcrcs         r)   r:   r:   9   s    19$$19(D(D
L/
 
 
'
'C =!!			)	)1().q12238B<  	Qww- 1 1vz]!!%((c((++&1*cB--a00&1*AHr+   c                     | d|z            S )ui   判定取价(缩量回调/突破/止盈止损/链特征): 后复权, 免疫除权跳变且历史可复现rM    r@   cols     r)   hfq_colr]   V       Vc\?r+   c                     | d|z            S )uZ   撮合/估值取价(成交价/股数/持仓估值): 原始价, 与实盘下单口径一致rK   rZ   r[   s     r)   raw_colr`   Z   r^   r+   c                 D    d|z   }|| j         v r| |         n
| d|z            S )u   K线/图表展示取价: 优先前复权 qfq_(派生, 除权日平滑无假跳空), 无则该列取原始价。
    定稿(PRICE_SCHEMA): raw=撮合估值, hfq=判定, qfq=图表展示。rN   rK   )index)rr\   rW   s      r)   	kline_colrd   ^   s-     	A<<1Q44Qv|_4r+   c                     |d d         }d }t          |                                           D ]}|d d         |k    r|}|r"|                     |t                                nt                      S )Nr    )sortedkeysgetset)r<   date_strymbestms        r)   active_membersrn   d   sp    	"1"BDGLLNN##  RaR5B;;D'+67;;tSUU###6r+   c                 `   |                      d                              d          } t          |           }|dk     rg S | d                             t                    j        }| d                             t                    j        }| d                             t                    j        }| d                             t                    j        }| d         j        }t          t          |                   }	|d	         |d
         |d         }}}
t          |d                   t          |d                   t          |d                   }}}|	                    d|	                    dd                    }|	                    dd          }|	                    dd          }|	                    dd          }|	                    dd          }|	                    dd          }|	                    dd          }|	                    dd          }|	                    dd          }|	                    dd          }g }t          j        ||	dz
  k              d         D ]F}|dz   |k    r||         }|dk    r|dk    r-|t          d|dz
            |                                         n|d |                                         }|dk    r|dk    s	|||z  k     r|dk    r|dk    r
|||z  k    r|dk    r/|dk    r)||dz
           }|dk    r||         |z  dz
  }||	z  |k    r|dk    r||k    r|||z
           |	dz
  k    r||         } |dk    r| d|z
  z  nd }!d }"d }#t          |dz   t          ||z   dz   |                    D ]}$d }%|
d!v r||$         ||z  k     rd}%|
d"v rf|$|k    r-|t          d|$|z
            |$                                         n|d |$                                         }&|&dk    r||$         |&|z  k     rd}%|%r||$         | k     r|!||$         |!k     r|%rL||$         | k     r@|dk    r"||         dk    r||$         ||         |z  k     r|#||$         |#k     r
||$         }#|$}"|"!t          |"dz   t          ||z   dz   |                    D ]}'||'         | d|z   z  k    rd}(|dk    r|dk    r||'         ||z  k     rd }(|(r|dk    r|dk    r||'         ||z  k    rd }(|(ru|dk    s|dk    ri|'|dz   k    r||dz   |'                                         n||'         })|)dk    r1|dk    r||'         |)|z  k     rd }(|(r|dk    r||'         |)|z  k    rd }(nd }(|(s|'dz   |k     r&|                    ||'dz            ||         f            nH|S )#Nr/   T)drop   pct_chg	hfq_closehfq_openvolr   r   r   r   r   r   
t0_vol_maxr   r   
t0_vol_minr   	ta_dd_maxt0_open_maxt0_prev_limitta_low_floor	tb_t0_min	tb_t0_max
tb_vol_min
tb_vol_maxr      r      F)r   r   )r   r   )sort_valuesreset_indexr9   rP   rQ   valuesLIMIT_UPr*   intrh   npwheremaxmeanrangeminappend)*r@   r(   bpnpctrJ   open_ru   datesbtvbvsbsswbumnztvt0mintaddmax	t0openmaxt0prev
talowfloortbt0_mintbt0_maxtbmintbmaxoutt0v0ma10zprev_copen_pctp0p0_floortata_min_closej	shrink_okrm   kokcbs*                                             r)   signal_detectr   l   sH   	l##//T/::AAA2vv	
I,

e
$
$
+CkN!!%((/EjM  ''.E
E(//%
 
 
'ClO"E	*T""	#BJL!126F3GBBR%&&BzN(;(;SF__BB
&&rvvoq99
:
:CFF<%%Eff[#&&G}c**IVVOQ''F,,Jvvk3''Hvvk3''HFF<%%EFF<%%E
Chsb4i'((+ D D6Q;;W7724((C27OOB&',,...CRC199zzR%%-//77qyyR53;..q==QwwrAvA::$Ry61A5H"}y00 A::",,2;29,,2Y)012W%%$rAvs27Q;2233 	 	AI\!!c!frBw&6&6 	]""45GGCAq2vq()..000RaRq55SVa"f__ $I U1X]]'E!Hx,?,? U1X]]>>eBi!mma59zCY8Y8Y'58l+B+B#(8LB:rAvs27Q;2233 	 	AQx"B-''a<<BFFs1vX/E/EB (Q,,266c!frH}6L6LB #5199		12R!VR!VAX++---QBAvv 199Q"u*)<)<!&B '%!))Ae0C0C!&B" q5199JJa!eeBi8999) (* Jr+   c                 n    i }|                                  D ]\  }}t          |||          }|r|||<   |S N)itemsr   )r=   r   sigr(   r@   r   s         r)   	build_sigr      sJ    
C==??  a1dB'' 	CIJr+   mergec
                 
  & t           t                      j        d |                                D                        }
fd|
D             }
t          |
          }i }|                                D ]<\  &}|D ]4\  }}||v r+|                    |g                               &|f           5=t          }g }g }|
D ]}t          ||          }|dd         D ]}||d                  }||d         |k             }t          |          dk    r7|j
        d         }t          |d                   }|dxx         d	z  cc<   d}|d
k    rS||d         z  d	z
  |k    rd}nnt          |d                   |d         d	||n|z
  z  k    rd}nA|d         |	k    rd}n1|dk    rdt          |d                   |d         d	|z
  z  k    rd}nt          |d                   |d         d	||n|z
  z  k    rd}n|d         |	k    rd}n|dk    rvt          |d                   |d         d	|z
  z  k    rd}n|(t          |d                   |d         d	|z
  z  k    rd}no||d         z  d	z
  |k    rd}nZ|d         |	k    rd}nKt          |d                   |d         d	|z
  z  k    rd}n#||d         z  d	z
  |k    rd}n|d         |	k    rd}t          |d         |          |d<   |r||d         z  d	z
  t          t          z   dt          z  z   z
  }||d         d	|z   z  z  }t          |d                   }|                    |d         |d         ||d         |||d         |d           |                    |           t          |          t"          k     rt          |                    |g           d           }|D ]\  &}t          |          t"          k    r n&|vr&t'          &fd|D                       rB|&         }||d         |k             }t          |          dk    rpt          |j
        d         d                   }t          |j
        d         d                   }|dk    s|dk    rd } |D ]e}!||!d                  }"|"|"d         |k             }#| t          |#          r)|!d!         t          |#j
        d         d                   z  n|!d         z  } ft)          || z   t*          z  |d"z            }$|$dk    r nb|$|z  }%|                    &||d	t          z   z  |d	t          z   z  |d	t          z   z  |%|z  |%|dd#	           ||$d	t          z   t          z   z  z  }|S )$u  卖出:
    mode='merge': 盘中回撤dd(trailing) -> 收盘止盈profit -> 超时 (现有)
    mode='A'(止盈策略): 收盘盈利>=profit | 盘中<=买入价*(1-stop或dd) | 超时
    mode='B'(回撤策略): 盘中<=最高价*(1-profit) | 盘中<=买入价*(1-stop或dd) | 超时
    mode='C'(三规则): 盘中回撤dd(trailing) | 盘中<=买入价*(1-stop) | 收盘止盈profit | 超时
    c                 8    g | ]}t          |d                    S )r/   )ri   ).0r@   s     r)   
<listcomp>z run_backtest.<locals>.<listcomp>   s$    $T$T$TaS<%9%9$T$T$Tr+   c                      g | ]
}|k    |S rZ   rZ   )r   xstarts     r)   r   z run_backtest.<locals>.<listcomp>   s    444qer+   Nr(   r/   r   rs   hold_nr   Abuy_jprofithfq_lowstoptimeoutB
high_sincetrailCddr   amountrD   buy_datefill_px)r(   r   	sell_date	buy_price
sell_priceret_net	hold_daysreasonc                     | d         S )Nr   rZ   )r   s    r)   <lambda>zrun_backtest.<locals>.<lambda>  s
    AaD r+   )keyc              3   0   K   | ]}|d          k    V  dS )r(   NrZ   )r   pr(   s     r)   	<genexpr>zrun_backtest.<locals>.<genexpr>  s,      <<QqyD(<<<<<<r+   raw_openrt   r   qtyr   )	r(   r   r   r   r   r   r   r   r   )rf   ri   unionr   r   
setdefaultr   INIT_CAPrn   r9   rR   rQ   r   COST_BUY	COST_SELLSLIPremoveMAX_POSrh   anyr   	POS_SHARE)'r;   r<   r=   r   r   r   r   moder   hold	all_datesdate_setsig_by_dater   bdt0dcash	positionstradesdateactiveposr@   rowsrc   cursellnet_retfillcandsr   r   held_mvr   dd_rrr   r   r(   s'         `                               @r)   run_backtestr      sr    {suu{$T$T7>>CSCS$T$T$TUVVI4444I444I9~~HKIIKK C Cb 	C 	CIRX~~&&r2..55tSkBBB	C DIF P7 P7..QQQ< /	& /	&CF$AQ|_,-D4yyA~~	!A+''CMMMQMMMDs{{W%)V33#DD1Y<((CLAIY_a<b,ccc!DD]d**$D9&&#l*;q6z*JJJ"DD1Y<((CLAIY_a<b,ccc!DD]d**$D9&&#l*;q2v*FFFDD%%)*=*=WQRUYQYAZ*Z*Z!DD3w<'!+v55#DD]d**$D9&&#l*;q2v*FFFDD3w<'!+v55#DD]d**$D #C$5s ; ;C &W-1h6JQQUX6UVHW55Q{^,,s6{J^b,/	N$*1HY]_ _ ` ` `   %%%y>>G##;??444..IIIE" 7 7	cy>>W,,Ev%%<<<<)<<<<< DM<D01t99>>	!Z 899dil:677a<<5A::" e eA!!F),CS.$67BCPRGGdqx%
;0G*H*HHHYZ[cYddGGdWn	94$;GGQ;;Ew&  $DwZ[^bZbOc-4D-AEUVY]U]L^,/'M),EQ"P "P Q Q Q !h,"566Mr+   c                     t          |           }|dk    rddddS d | D             }d |D             }|t          |          |z  t          t          j        |                    dS )Nr   )r   win_rateavg_retc                     g | ]
}|d          S )r   rZ   )r   ts     r)   r   zstats.<locals>.<listcomp><  s    )))QAiL)))r+   c                     g | ]
}|d k    |S )r   rZ   )r   rc   s     r)   r   zstats.<locals>.<listcomp>=  s    %%%!q1uuAuuur+   )r9   rQ   r   r   )r   r   retswinss       r)   statsr  8  sv    FAAvvq999))&)))D%%t%%%DSYY]uRWT]]?S?STTTr+   c                    t          |           \  }}g }t          j                    }|dk    rt          |t                    }t	          d |                                D                       }t          D ]H}	t          D ]>}
|                    | d|	|
|dt          t          | ||||	|
                               ?In\|dk    rt          D ]}t          D ]}t          D ]}t          D ]}||||dddd}t          ||          }t	          d	 |                                D                       }t          t          | ||||d         |d                             }|                    | d||||ddd|d         |d         |d
|           Ðn|dk    rt          j        t#          t$           d                    }t&          D ]Q}t(          D ]E}t*          D ]9}||          d         t-          ||          d                   ||          d         t-          ||          d                   |||d}t          ||          }t	          d |                                D                       }t          t          | ||||d         |d                             }|                    | d||          d         t-          ||          d                   ||          d         t-          ||          d                   ||||d         |d         |d
|           ;GSt/          |  d| dt1          |           dt          j                    |z
  dz  ddd           |S )Nr   c              3   4   K   | ]}t          |          V  d S r   r9   r   vs     r)   r   z!run_pool_stage.<locals>.<genexpr>F  s(      00a3q66000000r+   )r;   stager   r   nsigr   r   r   r   r   c              3   4   K   | ]}t          |          V  d S r   r
  r  s     r)   r   z!run_pool_stage.<locals>.<genexpr>T  s(      "@"@a3q66"@"@"@"@"@"@r+   )r;   r  r   r   r   r   r   r   r   r   r   r  r   /best_stage2.jsonr   r   r   r   c              3   4   K   | ]}t          |          V  d S r   r
  r  s     r)   r   z!run_pool_stage.<locals>.<genexpr>c  s(      <<!s1vv<<<<<<r+   z stage	    完成: u   条, 耗时<   .1f   分钟T)flush)rA   timer   DEF_BUYsumr   GRID_PROFITGRID_DDr   r  r   GRID_VB	GRID_MA_NGRID_VSGRID_SWjsonloadrG   r3   GRID_BUGRID_BSGRID_ZTVr   printr9   )r;   r  r   r<   r=   resultsr   r   r  prr   r   r   r   r   r   sbest2r   r   r   s                        r)   run_pool_stager*  @  sL    GWG	Bzz))003::<<00000 	^ 	^B ^ ^qBc[_  ]  ]"'T7GSRTVY(Z(Z"["[ ] ^ ^ ^ ^^	^ 
! 	^ 	^B 
^ 
^! 	^ 	^B% ^ ^*,bZ\*+sUVX X'44""@"@3::<<"@"@"@@@!,tWgsDQRGUYZ[U\"]"]^^qbZ\ln68a[^qr26q'aRV(] (]Z[(] ^ ^ ^ ^^	^
^	^ 
!	$$999::;; 	Z 	ZB Z Z" 
Z 
ZB&+Dk*&=s5QU;W]K^G_G_(-dL(AQTUZ[_U`amUnQoQo&(BQSU UB $GR00C<<szz||<<<<<Dl4'3QQUVWQXYYZZANND1%PT+V`Jaknotuyoz  |B  pC  lD  lD27+l2K[^_dei_jkw_x[y[y02b[].21gT!Wd$Y $Y WX$Y Z Z Z Z
ZZ 
T
a
a
a
aW
a
a49;;r>SUBU
a
a
a
aimnnnnNr+   c                  	   g dt          t          j                  dk    rt          t          j        d                   ndt	          j                    } dk    rt          d          5 }g }|                    t          d D                       D ]}|                    |           	 d d d            n# 1 swxY w Y   t          j
        |t          t           dd          ddt                     t          j        |          }i D ]}||d	         |k             }||d
         dk             }t          |          dk    r|}|                    dd          j        d         }t%          |d                   t%          |d                   t%          |d                   t          |d
                   d|<   t'          d| d|d          d|d          d|d         dz  dd|d
          d           t          j
        t          t           dd          dd           d S t          j        t          t           d                    fdD             t          d          5 }g }|                    t          fdt+          d          D                       D ]}|                    |           	 d d d            n# 1 swxY w Y   d d}t          j
        |t          t           d | d          ddt                     d!k    rt          j        |          }i }	t-                    D ],\  }
}||d	         |k             }||d
         dk             }t          |          dk    r|}|                    dd          j        d         }|d"         t%          |d#                   t%          |d$                   t%          |d%                   t%          |d                   t          |d
                   d&|	|<   t'          d'| d(|d"          d)t          |d#                    d*|d$          d+|d%          d|d         dz  dd|d
          d           .t          j
        |	t          t           d,d          dd           t'          d- d.t          |           d/t	          j                    | z
  d0z  d1d2           d S )3N)hs300zz500zz1000r   r   c                     g | ]}|d fS )r   rZ   )r   r;   s     r)   r   zmain.<locals>.<listcomp>s  s    /L/L/Ldq	/L/L/Lr+   z/grid_results_stage1.jsonwF)ensure_asciiindentdefaultr;   r      r   r  )	ascendingr   r   )r   r   r  r   zbest1 u   : 止盈u    回撤u    均收d   z.2fz% u   笔z/best_stage1.json)r1  r2  c                 H    g | ]}|         d          |         d         fS )r   r   rZ   )r   r;   best1s     r)   r   zmain.<locals>.<listcomp>  s0    MMMttX&dD(9:MMMr+   c                 2    g | ]}|         |         fS rZ   rZ   )r   ipoolsr   r  s     r)   r   zmain.<locals>.<listcomp>  s(    /]/]/]qq5$q'0J/]/]/]r+   grid_results_stagez.jsonr-   r   r   r   r   r   )r   r   r   r   r  r   zbest2 u   : 基准z/nu   /系数u   /窗r  r  r  u   条, 总耗时r  r  r  )r9   sysargvr   r  r   starmapr*  extendr   dumprG   r3   r8   r1   	DataFramer   rR   rQ   r%  r!  r   	enumerate)r   r   all_resultsrc   dfr;   subr   fnamer)  r:  r8  r;  r   r  s              @@@@r)   r   r   l  s-   (((E #CH 1 1CqE	Bzz!WW 	&KYY~/L/Le/L/L/LMM & &""1%%%%&	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 		+tt$F$F$FLL[`ijtwxxxx\+&& 	w 	wDRZ4'(CS]b()B2ww!||yE::?BA%*1X;%7%7uQtW~~Z_`abk`lZmZmy|}~  @H  ~I  zJ  zJ  K  KE$Ku4uu8uuQtWuuQy\Z]M]uuuefgoepuuuvvvv	%888#>>U[\]]]]]]	$$999::;;MMMMuMMM!WW 	&KYY~/]/]/]/]/]/]TYZ[T\T\/]/]/]^^ & &""1%%%%&	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 2U111	+tt$5$5e$5$5s;;%XYcfggggA::k**BE$U++ l l4Ft+,X",-r77a<<BNN9N>>CAF+,Z=%&	BRBRbghijvhwbxbx-21\?-C-CPUVWXaVbPcPcorstu}s~ooA Ad  kt  k  kQz]  k  kc!F)nn  k  kUVWcUd  k  kjklxjy  k  k  CD  EN  CO  PS  CS  k  k  k  [\  ]e  [f  k  k  k  l  l  l  lIeTT"<"<"<cBBQV_`aaaaeeeec+&6&6eety{{SU~WYFYeeeefffffs&   0A B==CC9AKKK__main__r   )-__doc__pandasr1   numpyr   r4   r=  r   r  multiprocessingr   r3   
START_DATEr   MAX_HOLDr   r   r   r   r   r   r  r  r  r  r  r  r  r"  r#  r$  r*   rA   r:   r]   r`   rd   rn   r   r   r   r  r*  r   __name__rZ   r+   r)   <module>rP     sA                                       /
d$??	
	QcXYmp  DE  F  F222
.
.
.


MM	
#
#
#
))
**
6
6
6       :    5 5 57 7 7] ] ]~   AKQX_cjr c c c cJU U U* * * *X+g +g +gZ zDFFFFF r+   