o
    Xi?6                     @   s   d Z ddlZddlZddlmZmZ ddlm	Z	m
Z
mZ ddlmZ ddlmZ dd	lmZ eG d
d dZeG dd dZeG dd dZeG dd dZdedede	e fddZejejfde	e dejdejdejdedededede	e fdd Zejejd!fd"e	e d#ejdejdejdejd$ejd%ed&ed'ed(e de	e fd)d*Z!ej"fd+e	e d,e	e d-ej#d.ej#d/ede	e$ fd0d1Z%ej&ej'fd2ed3ej(d4ej)d5ed&ede
e$ fd6d7Z*d8ej)d(e d9ed:ed;ed<ed%ede	e fd=d>Z+d?e d4ej)d@ej)dAej)de	e f
dBdCZ,dS )Du   
信号生成管线 (Steps 2-6)
Step 2: 下跌段识别
Step 3: 盒子识别
Step 4: 放量阳线突破
Step 5: 多周期叠加
Step 6: 1H精准入场
    N)	dataclassfield)ListOptionalDict)	timedelta   )zigzag   )settingsc                   @   s:   e Zd ZU dZeed< eed< eed< eed< eed< dS )DropLegu	   下跌段high_idx
high_pricelow_idx	low_pricedrop_pctN)__name__
__module____qualname____doc__int__annotations__float r   r   !/opt/langlang_ai/core/pipeline.pyr         
 r   c                   @   sJ   e Zd ZU dZeed< eed< eed< eed< eed< eed< eed< d	S )
Boxu   盒子（底部过渡区）	start_idxend_idxbox_lowbox_high	width_pctduration_barsdrop_legN)r   r   r   r   r   r   r   r   r   r   r   r   r      s   
 r   c                   @   s:   e Zd ZU dZeed< eed< eed< eed< eed< dS )Breakoutu   突破信号bar_idxpricevolume_ratiobox	timeframeN)	r   r   r   r   r   r   r   r   strr   r   r   r   r$   *   r   r$   c                   @   s   e Zd ZU dZeed< eed< eed< ejed< eed< eed< eed< eed	< eed
< eed< e	ed< eed< eed< dZ
ee ed< dZee ed< dS )Signalu   完整交易信号coin	directionsignal_type
entry_timeentry_price	stop_losssl_distancer    r   box_width_pctbox_duration_barsr'   entry_methodNbreakout_4hbreakout_1d)r   r   r   r   r*   r   pd	Timestampr   r   r6   r   r$   r7   r   r   r   r   r+   4   s"   
 
r+   swing_pointsmin_dropreturnc              
   C   sz   g }t t| d D ]0}| | \}}}| |d  \}}}	|dkr:|dkr:||	 | }
|
|kr:|t||||	|
d q
|S )ub   
    从摆动点序列中识别所有有效下跌段 (H→L)
    条件：跌幅 >= min_drop
    r   HL)r   r   r   r   r   )rangelenappendr   )r:   r;   legsiidx_htype_hprice_hidx_ltype_lprice_lr   r   r   r   find_drop_legsJ   s    rJ   	drop_legshighslowsclosesmin_bars	max_widthnew_low_tolerancemax_scanc                 C   s  t |}g }	| D ]v}
|
j}||| krq|
j}|| }|| }|}d}t|d t|| |D ].}|| }|| }||d|  k rEd} nt||}t||}|| | }||kr[ n|}q/|| d }||kr~|r~|| | }|	t|||||||
d q|	S )u   
    从下跌段终点开始扫描，识别盒子（底部过渡区）

    三条件：
    1. 前置：有明显下跌
    2. 形态：不创新低（容忍1%），振幅不超max_width
    3. 最少持续min_bars根K线
    Tr   F)r   r   r   r    r!   r"   r#   )r@   r   r   r?   minmaxrA   r   )rK   rL   rM   rN   rO   rP   rQ   rR   nboxeslegstartleg_lowr   r    r   validjlohiwidthdurationr!   r   r   r   
find_boxese   sJ   


r`   1DrV   opensvolumesconfirm_barsmax_waitvol_ratio_thresholdr)   c
                 C   s4  t |}
g }| D ]}d}|jd }t|| |
}t||D ]y}|r# nt|| |jkr+q|| || kr4qtd|d }||krHt||| n|| }|dkrQq|| | }||k r\qt|| d |
}d}t|d |D ]}|| |jk r{d} nqn|r|| d |kr|t	||| |||	d d}qq|S )u  
    在盒子后寻找放量阳线突破

    条件：
    1. 收盘 > 盒子顶
    2. 阳线（close > open）
    3. 成交量 > 前20根均量 × 1.5
    4. 后续confirm_bars根K线收盘不跌回盒顶
    每个盒子只取第一个有效突破。
    Fr   r      T)r%   r&   r'   r(   r)   )
r@   r   rS   r?   r    rT   npmeanrA   r$   )rV   rb   rL   rM   rN   rc   rd   re   rf   r)   rU   	breakoutsr(   foundsearch_start
search_endrC   	vol_startavg_vol	vol_ratioconfirm_end	confirmedkr   r   r   find_breakouts   sL   
"rt   breakouts_4hbreakouts_1dtimestamps_4htimestamps_1dwindow_daysc              
   C   s   t |d}g }t }t }t| D ]8\}	}
||
j }t|D ]*\}}||j }t|| |krH|d|
|t||d ||	 ||  nqqt|D ]\}}||vrc|dd|||j d qNt| D ]\}	}
|	|vr}|d|
d||
j d qh|S )uR  
    多周期叠加：将4H和日线突破配对
    共振条件：4H突破前后window_days天内有日线突破

    Returns:
        List of dicts with keys:
        - signal_type: '共振', '日线', '4H'
        - breakout_4h: Breakout or None
        - breakout_1d: Breakout or None
        - primary_time: 入场参考时间
    )daysu   共振)r.   r6   r7   primary_timeu   日线N4H)r   set	enumerater%   absrA   rT   add)ru   rv   rw   rx   ry   windowresults
matched_4h
matched_1drC   bo4t4r[   bo1dt1dr   r   r   match_resonance   sN   




r   r    breakout_timedf_1h	tolerancec                 C   s   |d |k}||  |}| d|  }| d|  }d}	| D ](\}
}|d |kr+d}	|	rG|d |d krG|d | krG|d |d dd	  S qd
S )u  
    1H精准入场：在突破后等回踩盒顶

    1. 从突破时间开始，在1H级别等价格回踩盒顶(±tolerance)
    2. 回踩后出现阳线确认(close>open 且 close>盒顶)
    3. 入场价 = 这根阳线的收盘价
    4. max_wait小时内没回踩 → 返回None（降级4H直接入场）

    Returns:
        dict with 'entry_time', 'entry_price', 'entry_method' or None
    	timestampr   FlowTcloseopen   1H回踩)r/   r0   r5   N)headiterrows)r    r   r   r   re   maskbars
low_targethigh_targettouched_barr   r   r   find_1h_entry5  s    
r   dfzigzag_thresholddrop_minbox_min_barsbox_max_widthc              
   C   sv   | d j }| d j }| d j }	| d j }
| d j }t|||}t||}t||||
||}t||	|||
|||d}|S )u   
    对单个时间周期运行 Step 1-4

    Args:
        df: K线数据 (timestamp, open, high, low, close, volume)
        timeframe: '1D' or '4H'
    Returns:
        List of Breakout
    highr   r   r   volume)rd   r)   )valuesr	   rJ   r`   rt   )r   r)   r   r   r   r   rd   rL   rM   rb   rN   rc   pointsrB   rV   rj   r   r   r   run_pipeline_single_tfa  s   





r   r,   df_4hdf_1dc                 C   sv  t |dtjtjtjtjtj}t |dtjtjtj	tj
tj}t|||d |d }g }|D ]}|d dur<|d }	|}
n|d }	|}
|	j}|j}t||d |}|dur_|d }|d	 }d
}n&|d rg|d n|d }|d rq|n|}|j|j d }|j|j d }d}|dtj  }|| | }|tjkrq-|t| d|d ||||||j|j|j|	j||d |d d q-|S )u   
    生成某个币种的所有做多信号

    完整管线：
    1. 日线 Step 1-4
    2. 4H Step 1-4
    3. Step 5: 多周期叠加
    4. Step 6: 1H精准入场
    ra   r|   r   r7   Nr6   r{   r0   r/   r   r   u   4H直接r   longr.   )r,   r-   r.   r/   r0   r1   r2   r    r   r3   r4   r'   r5   r6   r7   )r   SZIGZAG_THRESHOLD_DAILYDROP_LEG_MIN_DAILYBOX_MIN_BARS_DAILYBOX_MAX_WIDTH_DAILYBREAKOUT_CONFIRM_DAILYZIGZAG_THRESHOLD_4HDROP_LEG_MIN_4HBOX_MIN_BARS_4HBOX_MAX_WIDTH_4HBREAKOUT_CONFIRM_4Hr   r(   r    r   ilocr%   SL_LONG_OFFSETSL_MAX_DISTANCErA   r+   r   r!   r"   r'   )r,   r   r   r   rv   ru   matchedsignalsm
primary_bo
primary_dfr(   r    
entry_infor0   r/   r5   botf_dfr1   r2   r   r   r   generate_long_signals  sz   



r   )-r   numpyrh   pandasr8   dataclassesr   r   typingr   r   r   datetimer   r	   configr   r   r   r   r$   r+   listr   rJ   BOX_NEW_LOW_TOLERANCEBOX_MAX_SCAN_BARSndarrayr   r`   BREAKOUT_MAX_WAITBREAKOUT_VOL_RATIOr*   rt   RESONANCE_WINDOW_DAYSDatetimeIndexdictr   ENTRY_1H_TOLERANCEENTRY_1H_MAX_WAIT_BARSr9   	DataFramer   r   r   r   r   r   r   <module>   s    			
"	
N	

M
F
,
+