
    wj#                   Z   U d Z ddlmZ ddlZddlZddlZddlmZ ddl	m
Z
mZmZmZ ddlmZ ddlmZmZ ddlmZ dd	lmZ dd
lmZmZmZmZmZmZmZ ddl m!Z!  ejD                  d      Z#ddddddddddddddddddddddd d!d"d#d$d!d%d&d'd!d(d)d*d!dd+d,d!d-d.d/d!d0
Z$d1e%d2<   d3d4d5d!Z&d1e%d6<   d7d7dd8d9d9d:d7d7dd8d9d9d:dd7d7d8d;d;d:ddddd7dd:dd7ddd7dd:dddd8d;d;d:d8ddd8d<d<d:d8ddd8d<d<d:d8ddd8d<d<d:dddd8d;d;d:d=
Z'd1e%d><   d8Z(d?Z)d@Z*dAZ+dBZ,dZ-dCZ.dDZ/dHdEZ0 G dF dGe      Z1y)Iu  
APEX V16 — Brain Trend Following.

Migrated from V15's Braintf.py. The TRADING RULES are unchanged:
  - Entry only on pullbacks in zona sconto RSI 42-58
  - ATR ratio >= 0.8 floor (block low-volatility / congested markets)
  - Capitulation candle veto (candle_strength > 1.8 against direction)
  - AI Chain-of-Thought entry prompt with 3 steps
    (qualità sconto, timing pullback, contesto macro)
  - Post-validation watchdog (RSI re-check, conf>=70, RR floor,
    C>=90% + H4 weak guardia)
  - Time-stop matrix per (asset, session)
  - Same-candle dedup in manage_exit
  - Struct-flip detection (LONG with new BEARISH, SHORT with new BULLISH)
  - Deep-discount H4 paradox guard
  - AI exit prompt biased toward HOLD

WHAT CHANGED (orchestration only, V16-BUG-prevention):
  - Async-first (uses AIClient.ask_for_decision)
  - Returns typed EntryDecision / BrainDecision instead of dicts
  - Reads ctx.entry / ctx.runtime instead of init_data dict
  - Does NOT mutate ctx.runtime (orchestrator owns runtime state)
  - PA pattern reading goes through analysis.price_action (single source)
  - TF_ASSET_PROFILES at module top, calibrated on V15 CFD assets;
    futures asset symbols mapped by equivalence (MES <- US500, etc.)
    )annotationsN)Optional)	PASignalsPAScoreextract_pa_signalsscore_pa)tech_log_fields)AIClientextract_json_from_response)	BrainBase)config_futures)BrainContextBrainDecision	BrainName	DirectionEntryDecisionEntryEvalResultTradeAction) TP_SUGGESTED_CONSERVATIVE_MARGINzbrain.tf)g
ףp=
?333333?#   US500zBS&P500 micro: V16 calibrato su ATR_M5 ~6 (futures), sl_ticks 10-30)sl_rangesl_min_points
v15_originnote)g333333?g333333?F   US100zCNasdaq micro: V16 calibrato su ATR_M5 ~30 (futures), sl_ticks 10-36)g{Gz?g?   US30z@Dow micro: V16 calibrato su ATR_M5 ~80 (futures), sl_ticks 14-44)      ?g333333@g       @XAUUSDz8Gold micro: V16 calibrato su ATR_M5 ~2.5, sl_ticks 27-58)g      @      @EURUSDz#EUR/USD: SL 9-15p (V15 calibration))r   r   r   )gffffff@g333333@GBPUSDz$GBP/USD: SL 15-26p (V15 calibration))g?g
ףp=
?USDJPYz JPY: SL 25-40p (V15 calibration))g      ?g@USDCADz8CAD: V16 calibrato (ATR_TYPICAL 0.0008 alto vs altri FX)zAUDUSD (new in V16)z?AUD/USD: derived from 6E analog, refine in CALIBRAZIONE 5-9 may)r   ?zWTI (new in V16)z1Crude Oil micro: ATR_TYPICAL 0.40, sl_ticks 53-79)
MESMNQMYMMGC6E6B6J6C6AMCLdictTF_ASSET_PROFILES)g      @r#   GENERICuF   no V15 equivalent — generic conservative profile, recalibrate in V16GENERIC_PROFILEx         )LONDON	LONDON_NYNY_CLOSENY_LATE
ASIA_EARLYASIA_LONDON_GAP      )
r-   r.   r0   r1   r/   r,   r*   r+   r)   r2   TF_TIME_STOPg      E@g      M@皙?r(      g      I@c                    d| cxk  rdk  ry d| cxk  rdk  ry d| cxk  rdk  ry d| cxk  rdk  ry	 d
| cxk  rdk  ry yy)N      r:      r;      r<      r=   r      r>   r?    )utc_hours    %/home/work/apex_v16/brain/brain_tf.py_classify_sessionrO      s_    HrH	XK	XJ	XIHqL    c                  |    e Zd ZdZej
                  j                  Zdd fdZddZ	dd	 	 	 	 	 ddZ
e	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd       Ze	 	 	 	 	 	 	 	 dd	       Ze	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd
       ZddZddZe	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd       Zedd       Zdd	 	 	 	 	 	 	 	 	 ddZ xZS )BrainTFa  
    Trend Following Brain. Async (uses AIClient).

    The orchestrator is responsible for:
      - candle-gating (calling evaluate_entry only on M5 just-closed)
      - populating tech with bias_data keys (bias / allowed_direction /
        regime / h1_compatibility / swing_data) and the technical fields
        (price / open / rsi / rsi_prev / rsi_h1 / rsi_h4 / atr_ratio /
         atr_m5_points / vwap / vwap_deviation_pct / market_structure /
         vol_regime / trend_maturity / candle_strength / candle_time)
      - applying the BrainDecision (EXIT/HOLD) and updating
        TradeRuntime.last_exit_eval_time from BrainDecision.metadata
        before persisting state.
    Nc                ^    t         |   |       || _        || _        t	               | _        y N)super__init__ailoggerset_warned_generic_profile)selfconfig	ai_clientrX   	__class__s       rN   rV   zBrainTF.__init__   s(     14$rP   c                *   t         j                  |      }||S || j                  vrg| j                  j                  |       d| d}t        j                  |       | j                  %| j                  j                  j                  |       t        S )Nz
[BrainTF] uL   : no V15-calibrated profile — using GENERIC. Recalibrate in V16 (5-9 may).)	r4   getrZ   add_logwarningrX   systemr6   )r[   symbolprofmsgs       rN   _profile_forzBrainTF._profile_for   s     $$V,K555((,,V4x (B CCLL{{&""**3/rP           )last_entry_eval_timec               h  K   |j                   }|j                  }|j                  }|dv rdnd}t        |j                        }	t        |j
                        }
t        |j                        }t        |j                        }t        t        |dd      xs d      }t        t        |dd            st        dd	
      S t        t        |dd      xs d      }|t        | j                  j                        k  rt        dd
      S |t        | j                  j                        kD  rt        dd
      S t        |	cxk  r	t        k  s@n t        | j!                  ||dd|	ddt         dt         d||
t        t                    S |t"        k  r0t        | j!                  ||dd|ddt"         |t"                    S |t$        kD  r|j&                  }|j(                  }t+        |t$        ||      }|dk(  r0||||k  r't         | j                   ||fdd|dd|d |      S |dk(  r0||||kD  r't         | j                   ||fdd!|dd"|d |      S t        |j,                        }|dk(  r*|d#kD  r%t        | j!                  ||d$d%|dd&|             S |dk(  r*|d'k  r%t        | j!                  ||d(d%|dd)|             S t        |j.                        }|d*k  r(t        | j!                  ||d+d,|dd-| d.|             S t        |j0                        }t        |j2                        }|dk(  xr
 | xr |dk  xs |dk(  xr
 | xr |dkD  }|r(t        | j!                  ||d/d0| d1|d2d3|             S |r||k  rt        dd45      S | j5                  |      }t7        |      }t9        ||      }| j;                  |||||	|
||||||6      }| j<                  j?                  |       d{   }d7d8h}|j@                  |r|nd}n|jB                  |v rd}n|r|nd}|j@                  Dt        | j!                  ||d9d:|jB                   ||jB                  |jD                  ;      |<      S | jG                  |j@                        }|rd=|vr3t        | j!                  ||d>d?||j@                  xs d@ddA B      |<      S t        |j,                        }| jI                  ||||	||t        |j&                        C      }|i } |d   dDk(  r'dE| dF<   t        |jK                  dGd      xs d      | dH<   t         | j                   ||f|d   |dI   |tM        |jK                  dJd            t        |jK                  dKd            t        |jK                  dLd            dM| |<      S |jK                  d=      s|jK                  dN      xs i }!tO        |!t*              rtQ        |!jK                  dOdP            ddQ ndP}"tO        |!t*              rtQ        |!jK                  dRd@            ddA nd@}#t        | j!                  ||dStQ        |jK                  dTdU            ddA |tM        |jK                  dJd            |"|#V      |<      S 	 | jS                  |||t        |dK         W      }$tM        |jK                  dJd            }&tQ        |jK                  dTd\            dd] }'t        |jK                  dLd            }(tY        ||$d^   |$d_   d|(|&|'i d`dadK|$db   dc|(dHt        |jK                  dGd      xs d      ddtQ        |jK                  ded@            ddA dft        |jK                  dfdg            dhtQ        |jK                  dhd@            dd] ditQ        |jK                  djd@            ddA dktQ        |jK                  dld@            ddA dmtQ        |jK                  dnd@            ddA do|$dp   dq|$dq   dr|$dr   ds|$ds   dt|$dt   du|$du   dv|$dv   dw|jK                  dxdy      iz      })t        |)|<      S 7 ]# tT        tV        f$ r:}%t        | j!                  ||dXdY|% |t        |dZd      [      |<      cY d}%~%S d}%~%ww xY ww){a  
        Evaluate a TF entry. `tech` is a TechSnapshot.

        Returns EntryEvalResult:
          - decision = EntryDecision (open) | None (no setup / rejected)
          - evaluated_candle_time = candle_time (float) when AI was called
            and either responded or returned a permanent error; None when
            dedup-skipped, pre-val-rejected, or AI failed transiently.
          - dedup_skipped = True when same-candle dedup short-circuited
            the AI call (no AI cost, no cache update needed).

        Flow: pre-val (RSI zone, ATR floor, capitulation) -> SAME-CANDLE
        DEDUP gate -> AI prompt with Chain-of-Thought -> post-val
        watchdog (RSI/conf/RR/C90+H4) -> price computation -> decision.
        )BUYBOTHrl   SELLcandle_timer   is_candle_closedFNCANDLE_NOT_CLOSED)decisionreject_reasoncandle_age_secondsri   CANDLE_STABILIZINGCANDLE_TOO_OLDPULLBACK_ZONEzRSI .1fz outside TF zone [,])ruledetailtechrsi_prevrsi_lowrsi_high)rr   VOLATILITA_BASSAz
ATR ratio .2fz
x < floor )r{   r|   r}   	atr_floor)candle_strengthstrength_floorpriceopenCAPITULATION_CANDLEzBearish capitulation candle zx vs BUY)r{   r|   r}   zBullish capitulation candle z	x vs SELLg     @P@RSI_H4_OVERBOUGHT_TF_BUYzRSI H4 u    > 65 — TF BUY rejectedg     A@RSI_H4_OVERSOLD_TF_SELLu    < 35 — TF SELL rejectedgffffff?H1_COMPAT_TOO_LOWz
H1 compat u    < 0.70 — z	 rejectedMACD_ACCELERATING_AGAINSTzMACD accelerando contro z (hist=z.6fu   ) — TF rejectedT)rr   dedup_skipped)re   	directionbiasregimersir~   	atr_ratior   r}   signalsscoreprofileunknownoverload	API_ERRORzAI unavailable: )r{   r|   r}   
error_kindattempts)rr   evaluated_candle_timeapprovedAPI_PARSE_ERRORzAI returned malformed JSON r9   )r{   r|   r}   response_preview)resultre   r   r   rsi_h4r   entry_priceTP_BELOW_MIN_PROFITrejected_tp_too_small	tp_sourcetp_price_suggestedtp_price_suggested_airD   
confidencesl_atr_multiplierrr_multiplier)r{   r|   r}   ai_confidence	ai_sl_atrai_rr_multiplierrejection_detailsrule_failedUNSPECIFIED(   r|   AI_REJECTEDreasonzAI did not approve)r{   r|   r}   r   ai_rule_failedai_rejection_detail)re   r   r}   sl_atrPRICE_COMPUTATION_ERRORzcannot compute prices: atr_m5_points)r{   r|   r}   r   zTF setup approvedr7   r   sl_pricebrainTFr   rr_multiplier_aitp_rationale_aitp_rationalerisk_multiplierr!   key_riskstep_1step_1_qualita_scontostep_2step_2_timing_pullbackstep_3step_3_contesto_macrosl_ticks_usedsl_ticks_post_clampclamp_active
sl_flooredsl_min_tickssl_price_ai_rawsl_ticks_presl_floored_or_cappedprofile_originr   ?)r   r   r   tp_pricer   r   	rationalemetadata)-r   allowed_directionr   floatr   r~   r   r   getattrboolr   r\   candle_close_delay_secondscandle_max_age_seconds
RSI_TF_LOWRSI_TF_HIGH_rejectATR_RATIO_FLOORCAPITULATION_STRENGTHr   r   r3   r   h1_compatibilitymacd_deceleratingmacd_hist_lastrh   r   r   _build_entry_promptrW   ask_for_decisiontextr   r   _parse_ai_json_post_validater`   int
isinstancestr_compute_sl_onlyKeyError
ValueErrorr   )*r[   re   r}   	bias_datarj   r   allowedr   r   r   r~   r   r   ro   ager   opncommonr   	h1_compat
macd_decel	macd_histmacd_againstr   r   r   promptrespTRANSIENT_KINDS
ai_eval_tsr   	rejectionextra_fieldsrdai_rule	ai_detailpcer   r   r   rr   s*                                             rN   evaluate_entryzBrainTF.evaluate_entry  sn
    4 $..#55++#*o#=%6	/./	 4 45mQ ? D1E GD"4e<="-@  GD"6<CDt{{==>>"-A  t{{99::"-= 
 c0[0"DLL	s3i (&<qQ8H"[ -9 -   &"DLL	(:#Ic?*_<MN_ -9 -   22JJEIIC /4#F
 E!s{emus{&I1,A9/#9NhW1 "(1  
 F"u}PS&I1,A9/#9NiX1 "(1   t{{#&4-"DLL	(B ,EF -9 -  
 6D="DLL	(A ,FG -9 -   $//0	t"DLL	(;#Ic?,ykS -9 -   $001
$--.	%E^E	A G& E^E	A 	 "DLL	(C29+ >!!*3/@B	 -9 -   ;*>>"T 
 ##F+$T*),))YT&h)+weW	 * 
 WW--f55 %j199 9D+$J__/J(3J99"IK-doo->?#	 &  '1  $$TYY/61"I,=7&*iio2t%<	 &  '1  t{{#''djj) ( 
	  !#L|44,C[)8=JJ3S9@S945 #%I"1il"%fjjq&A"B#FJJ/BC$HI%*6::os+K%L # '1  zz*%/06BBHRSUW[H\c"&&>?DboG;Eb$;OBFF8R01$37UWI"IMvzz(4HIJ4CP"%fjjq&A"B#*(1 &  '1
 
	&&#V$789	 ' B" L!45


8-@AB4CH	 OS!AB =)
^*!#bl #&6 (vzz:NPS/T/[X[)\	
 "c&**^R*H&I$3&O "eFJJ7H#,N&O c&**Z*D&Eds&K c&**5Lb*Q&RSWTW&X c&**5Mr*R&STXUX&Y c&**5Lb*Q&RSWTW&X  b)>&? b&8 b&6 b&8" "+<(=#$ >(:%& '+A(B'( !gkk,&D)
> ",
 	
W 6z *% 		"I,E4QC8")$"F	 &  '1 		sD   Pb2a#Jb2'!a& Fb2&b/5/b*$b/%b2*b//b2c                2   | j                  d      sy|dk(  rt        |cxk  r	t        k  sn dd|ddfS |dk(  rt        |cxk  r	t        k  sn dd|dd	fS t        | j                  d
d            }|t        k  rdd| dt         dfS t        | j                  dd            }t        | j                  dd            }	|dk\  r*|dk(  xr |dk\  xs |dk(  xr |dk  }
|
sdd| d|dd| fS |j                  ddt        d      f      \  }}||cxk  r|k  sn dd|dd |dd!|dd"| fS |	dk  rd#d$|	 d%fS d&|	cxk  rd'k  sn d(d$|	dd)fS t        | j                  d*d      xs d      }|dkD  r|dk(  xr ||kD  xs |dk(  xr ||k  }|rt        j                  j                  |i       }t        |j                  d+d            }t        |j                  d,d            }|dkD  r|dkD  rd-t        z
  }|dk(  r	||z
  |z  }n||z
  |z  }t        dt        t        ||z                    }||z  }|t        j                  z
  }|t        j                  k  r7d.d/| d0| d1|d2d3t        j                  d2d4|d2d5t        j                  d2d6fS y)7z
        Returns (rule, detail) if AI output should be rejected; None if OK.

        AI is unreliable. We re-check the same hard rules even if AI
        approved (V15 lesson learned).
        r   Nrl   POST_VAL_RSIzAI approved with RSI rx   z outside TF BUY zonern   z outside TF SELL zoner   r   POST_VAL_CONFzconfidence z% < z% floorr   ri   r   Z   -   7   POST_VAL_C90_H4Cz% but H4 RSI .0fz	 against r   infPOST_VAL_SL_RANGEzsl_atr_multiplier .3fz out of profile sl_range [ry   z] for POST_VAL_RR_MISSINGzrr_multiplier z not positiveg(\?gq=
ףp?POST_VAL_RR_RANGEz+ outside advisory prompt-range [0.17, 0.67]r   	tick_size
tick_valuer!   r   zAI tp_suggested=    → u%    ticks post-15%-margin → gross/ct $r   u    − commission $z = net/ct $z < $z
 threshold)r`   r   r   r   MIN_CONFIDENCEr   cfg_fut
ASSETS_MAPr   maxroundCOMMISSION_PER_CONTRACT_USDTP_MIN_NET_PROFIT_USD)r   re   r   r   r   r   r   r   sl_multrr_multdir_oksl_lowsl_hightp_suggestedcoherentspecr  r  scaletp_dist_posttp_tickstp_grosstp_nets                          rN   r   zBrainTF._post_validate?  s     zz*% zS'GK'G"+C94HIK K
c(H[(H"+C94IJL L L!45
&#!*T.1AIK K 

#6<=

?C89 e#52 7f$52  )J<}VCL	)UW W "++j3e2EF',W,'( 6s|1WSMxAB B a<)$WI];= ='4''$WSM 20 12 2 VZZ(<cBIcJ!e#C)C Ef$C)C  ))--fb9!$((;"<=	"488L##>?
q=Z!^"BBE E)(4{(Be'K(3l(Be'K"1c%y0H*I&JKH'*4H%(K(KKF = ==1.|nE'j )))1# 7++2+N+Ns*S T''-cl 3  ' = =cB*N   rP   c                   t         j                  |    }t        |d         }t        |d         }t        |j                        }t        t        |dd      xs d      }|dk  rt        d      ||z  t         j                  z  }	t        |	|z        }
t         j                  j                  | d      }t         j                  j                  | d      }t        |t        |
|            }||z  }|dk(  r||z
  }||
|z  z
  }n||z   }||
|z  z   }|dkD  xr |
|k  }i d	t        ||      d
t        ||      d|d|d|dt        |	|dz         dt        ||dz         d|
d|d|d|d|
|k7  d|d|
dt        ||      d||
k7  S )uD  
        Compute SL price + tick diagnostics from sl_atr_multiplier.

        TP variante γ: TP is finalized post-sizing by orchestrator via
        tp_resolver.resolve_tp_price; this Brain step only fixes SL.

        Logic:
          sl_distance_pre   = atr_m5_points * sl_atr * SL_SAFETY_MULT
          sl_ticks_pre      = round(sl_distance_pre / tick_size)
          sl_ticks_post     = clamp(sl_ticks_pre, [MIN_SL_TICKS, MAX_SL_TICKS])
          sl_distance_post  = sl_ticks_post * tick_size
          sl_price          = entry ∓ sl_distance_post   (BUY: -, SELL: +)

        Returns dict with entry_price, sl_price, sl_atr, sl ticks/distances,
        clamp_active. NO TP fields (resolved later).

        Raises:
            KeyError if symbol unknown.
            ValueError if atr_m5_points missing or non-positive.
        r  digitsr   ri   r   z-atr_m5_points missing or non-positive in techi'  rl   r   r   r   sl_distance_pre_clamp   sl_distance_post_clampsl_ticks_pre_clampr   r   sl_max_ticksr   r   r   r   r   )r  r  r   r   r   r   r   SL_SAFETY_MULTr  MIN_SL_TICKSr`   MAX_SL_TICKSr  min)re   r   r}   r   r!  r  r(  r   
atr_pointssl_distance_prer   sl_minsl_maxsl_ticks_postsl_distance_postr   r   r   s                     rN   r   zBrainTF._compute_sl_only  s)   6 !!&)${+,	T(^$DJJ'74#>E#F
?LMM$v-0F0FF_y89%%))&!4%%))&&9FCf$=>(94"%55H)\I-EFO"%55H)\I-EFO aZ9L6$9

eK&@
uXv'>
 z
 y	

 v
 $u_fqj'I
 %u-=vz'J
 !|
 "}
 v
 v
 |}'D
 z
  |!
" u_f'E#
$ #}'D%
 	
rP   c                   |d   \  }}t        ||z   dz  d      }|j                  dd      }t        |j                        }t        |j                        }|j
                  }|j                  }t        |j                        }|j                  }t        |j                        }|j                  }t        |j                        }t        |j                        }|j                  }t        |j                         }|j"                  }t        |j$                        }|j&                  }|dk(  xr ||kD  xs |dk(  xr ||k  }||kD  rdn||k  rd	nd
} t        t)        |dd      xs d      }!|!dkD  r:t*        j,                  j/                  |!t*        j0                  j2                        }"n7t*        j,                  j5                  t*        j0                  j2                        }"|"j7                  d      }#|"j8                  }$d|$cxk  rdk  r	n nd\  }%}&nAd|$cxk  rdk  r	n nd\  }%}&n-d|$cxk  rdk  r	n nd\  }%}&nd|$cxk  rdk  r	n nd\  }%}&nd\  }%}&d}'d|v rd}(n	d|v rd}(nd}(|dkD  rd})n
|dk  rd})nd})|d k\  rd!}*n
|d"k\  rd#}*nd$}*|rd%nd&}+g },|j:                  r|,j=                  d'       |j>                  r|,j=                  d(       |j@                  r|,j=                  d)       |jB                  r|,j=                  d*       |jD                  r|,j=                  d+       |jF                  r|,j=                  d,       |jH                  r|,j=                  d-       |jJ                  r|,j=                  d.       |jL                  r#|,j=                  d/|jN                  xs d0 d1       |,rd2jQ                  |,      nd3}-|jN                  xs d3}.|dk(  xr |
jR                  dk(  xs |dk(  xr |
jR                  dk(  }/|/rd4}0n|
jR                  d5v rd6}0nd7}0|dk(  xr |jT                  xs |dk(  xr |jV                  }1|jX                  xs i }2|2j                  d8d9      }3|3r|2j                  d:d;      nd<}4|3r|2j                  d=d      d>nd;}5|2j                  d?d      }6|d"k\  rd@}7n
|dAk\  rd7}7ndB}7t        |jZ                        }8t\        j^                  j                  | i       }9t        |9j                  dCdD            }:ta        |$      };tb        j                  | i       j                  |;td              }<t        |9j                  dEdF      xs dF      }=t        t)        |dGdF      xs dF      }>|=dkD  r|>|=z  ndF}?|<dHz  }@t        t        |?|@z  dIz              }A| dJk(  r|8dkD  rdK|8z  ndF}BdL|8dMdN|BdOdP}CndQ}CdRdSdTdUdVdWdXdYdZd[d\
j                  | |  d]      }Dd2jQ                  |
jf                        xs d^}Ed2jQ                  |
jh                        xs d^}Ft        t)        |d_dF      xs dF      }GdQjQ                  g d`|% da|# db|& dc| dd| de| df| dg|dhdi| dj|rdkndl dm|' dn|  do|( dp|jj                   dq| dr|8ds|: dtdu|dhdv|dhdw|  dx|dhdy|dzd{|ds|: dtd||) d}|dzd~| d| d| d|dda|7 d| d|+ dsC d|rdkndl d|- d|. d|
jR                   d|
jl                  dhd|0 dv| d| dE d| dF d|	jn                  rdnd d|	jn                   d|jT                   d|jV                   d| d|1 d|dd|* d|dd|rdkndl d| d|4 d|5 da|6 d|dzd|ddd|7 d|jp                   d|jr                   d| d|dkD  rdndl d|dkD  rd| d|dk(  rdnd dndQ d|  d|j                  dd       d|j                  ddQ       d|dOd|dOd|dOd|rd| dndQ d|dOd|dOd|dOd|dOd|jt                   d|8ds|: dtdGddD d|  da|; d|< d|>ds|: dtd|?dd@ddA d|A dÑ|8ds|: dtdđ|  dő| dƑ|ds|: dtdǑ|4 dȑ|5 dɑ|dzdʑ|% dˑ|& d̑|dhd͑|dk(  rdndϛ dБ| dё|	jn                   dґ|
jR                   d|
jl                  dhdӑ|dzdԑ| d|1 dՑ| d֑| dב|jj                   dؑ|dhdّ| dڑ|4 dۑ|5 dܑtv         dݑ|dOd2|dOdޑ|8ds|: dtdߑ|8ds|: dtdA d|A d|A dtv         d| d|dOd      S )u0  
        V17 narrative entry prompt.

        Espone TUTTI i campi del TechSnapshot al modello, organizzati in
        sei sezioni narrative:
          1. Contesto mercato (sessione/liquidità, regime, bias, news)
          2. Storia del prezzo (narrativa naturale)
          3. Segnali esaurimento pullback (checklist tecnica)
          4. Contesto strutturale (swing, EMA50 H1, anti-revenge)
          5. Profilo rischio (range SL meccanico, candle metadata)
          6. Domanda esplicita + Chain of Thought 3-step

        Invarianti rispetto a V16:
          - Chain of Thought 3-step (qualità sconto / timing / macro)
          - Confidence floor MIN_CONFIDENCE (=70)
          - SL profile range mapping (sl_atr_multiplier ∈ profile.sl_range)

        V17 transitional bridge:
          - JSON output mantiene il contratto V16 (`step_1/2/3`,
            `risk_multiplier`, `rr_multiplier` ∈ [0.17, 0.67]) — pipeline
            downstream (evaluate_entry / _post_validate / tp_resolver) NON
            cambia in questo commit.
          - Aggiunto `tp_price_suggested` (livello TP assoluto basato su
            VWAP/swing/EMA50) accanto a `rr_multiplier`. Per ora viene
            loggato; downstream lo consumerà nei commit V17 successivi
            (margine conservativo 15% applicato in pipeline).
        r   r*  rK   r   r   rl   rn   zin risalitazancora in discesafermoro   )tzz	%H:%M UTCrF   )ASIAbassarG   )EUROPAmedia   )zOVERLAP EU-USAalta   )USAr@  )zPOST-USAr<  uT   nessun evento HIGH a calendario imminente (filtro news in orchestrator già passato)BULLISH	rialzistaBEARISH
ribassistalateralesoprasottosur   pulitorC   normaledeboledecelerandoaccelerandohammershooting_starbull_engulfingbear_engulfingpiercing
dark_cloudmorning_starevening_stardoji(std), NESSUNOfavorrC  rE  adverseneutroswing_foundF
swing_typezN/AzNON TROVATOswing_pricez.5fswing_indexz	pro-trend      ?zcontro-trendr(     r  ri   r   r#   g333333?r/   r!   u$   
⚠️ 6J INVERTED QUOTE: 6J quote z.7fu    ≡ USDJPY r  uZ   . Movimento opposto: 6J↑ = yen forte = USDJPY↓. BUY 6J ≡ SELL USDJPY (yen rafforza).r   zFS&P 500 micro: momentum forte, breakout trade-able, target swing high.uG   Nasdaq micro: ad alta volatilità, candele ampie, target livello tondo.u5   Dow micro: meno volatile di MNQ, swing più ordinato.zFGold micro: spike-prone, range giornaliero ampio. Target conservativo.zICrude Oil micro: direzionale con inversioni rapide. Target su VWAP/swing.z<EUR/USD futures: mean-reverting, range giornaliero definito.z<GBP/USD futures: spike e poi range. Target su swing recenti.z1AUD/USD futures: risk-on proxy, scalper-friendly.uE   JPY futures: INVERTED quote (6J↑ = USDJPY↓), tick scale separata.z,CAD futures: INVERTED quote, oil-correlated.)
r)   r*   r+   r,   r2   r-   r.   r1   r/   r0   z,: profile non dedicato, target conservativo.nessunort   u6  Sei un Senior Quant Trader specializzato in DEEP DISCOUNT Trend Following.
Il tuo unico lavoro: entrare SOLO sui pullback quando il prezzo è in sconto
all'interno di un trend confermato. Restituisci SOLO JSON valido — zero
testo fuori dal JSON.

═══ 1. CONTESTO MERCATO OGGI ═══
Sessione      :  (u   ), liquidità z
Regime        : u    — z
Bias H4       : z, direzione consentita: z
RSI H4        : rx   z
Vol regime    : z, Vol spike: SINOz
News          : u+   

═══ 2. STORIA DEL PREZZO ═══
u    è in trend z confermato da z  candele
H1 (struttura attuale: z). Il prezzo quota .fu8   
e ha appena fatto un pullback — RSI M5 è passato da  a z
(z). RSI H1: z%. Deviazione del prezzo da EMA50 H1:
+.2fz%. VWAP intra-day: u    — il prezzo
è z del VWAP di z%. Struttura H1: u    —
z. H1 compatibility con : r   z).
Divergenza RSI/prezzo: z. MACD: u   

═══ 3. SEGNALI DI ESAURIMENTO PULLBACK ═══
Conta i segnali presenti (checklist tecnica):
  • Bouncing RSI M5     : u   
                          (BUY: rsi>rsi_prev = pullback finito;
                           SELL: rsi<rsi_prev = pullback finito)
  • Pattern candela     : u   
  • Doji type           : u   
  • PA dominante        :  (forza    x) — z!
                          FAVOR z#
                          ADVERSE u   
  • Volume              : DEBOLENORMALE (volume_weak=u&   )
  • Absorption          : BUY_ABS=, SELL_ABS=z"
                          (favor u   )
  • ATR ratio           : u   x → movimento u   
  • Candle strength     : u,   x (1.0 = media)
  • Vol spike           : uw   

Più segnali confluenti = pullback più probabilmente esaurito.
Bouncing + (pattern OR volume_weak OR absorption pro uW   ) = setup forte.

═══ 4. CONTESTO STRUTTURALE ═══
Swing recente (lazy)   : z @ z) candele M5 fa)
EMA50 H1 deviazione    : z3% (contesto del pullback)
H1 compat              : z
H1 struttura           : bull=z, bear=z
SL consecutivi sessione: z (re-entry post-SL:    SÌ)
u   ⚠️ u    SL recenti: la struttura ti ha già stoppato. Nuova entry SOLO con almeno 1 pattern reversal attivo + volume_weak + RSI in zona ottimale (z42-46z54-58).u4   

═══ 5. PROFILO RISCHIO ═══
Profilo SL z (V15 origin: r   r   z): r   z
  Range sl_atr_multiplier : u    – z  (mid z, ATR-meccanico)
  u$   ⚠️ SL FLOOR ASSOLUTO: mai sotto z punti.uC   
  Mappatura confidence → sl_atr_multiplier:
    60-69%:  sl_atr=z
    70-79%:  sl_atr=z
    80-84%:  sl_atr=z
    85%+:    sl_atr=z4

Candle metadata (M5 corrente):
  Open           : z
  Close          : z
  Age post-close : r
  zs
  Asset character: u9   

═══ 5b. VINCOLO TEMPORALE TP ═══
Time-stop z minuti.
ATR M5 corrente: z	 punti = z= ticks/candela.
Candele M5 disponibili prima del time-stop: ~z`.
Movimento statisticamente raggiungibile (fattore conservativo 0.6):
    max_reachable_ticks = u<   

⚠️ Scegli un `tp_price_suggested` raggiungibile entro z ticks
   dal prezzo u  . Anche se VWAP/swing/EMA50 indicano
   livelli oltre questa soglia, NON li scegliere — l'orchestratore chiuderà il
   trade per time-stop prima che il target venga colpito.

═══ 6. DOMANDA + CHAIN OF THOUGHT ═══
Considerando il contesto di mercato (sez. 1), la storia del prezzo (sez. 2),
i segnali di esaurimento pullback (sez. 3), il contesto strutturale (sez. 4)
e il profilo rischio (sez. 5):

  → Questo pullback su u,    rappresenta un'opportunità di entrata
    u    con buona probabilità di successo?

Se approvi, indica DUE campi TP (entrambi richiesti, transitional bridge V17):

  • `tp_price_suggested` (NEW V17): livello TP assoluto basato sui livelli
    strutturali visibili — VWAP z, swing z
    z, EMA50 H1 (deviazione u9  %). Il sistema
    applicherà un margine conservativo del 15% prima di piazzare l'ordine.
    Coerente con la direzione (BUY: > entry; SELL: < entry).

  • `rr_multiplier` (LEGACY V16, ancora consumato da tp_resolver):
    frazione del RISCHIO REALE in dollari, range [0.17, 0.67].
        tp_usd_target = rr_multiplier × sl_usd_actual
    Mappatura confidence → rr_multiplier:
        70-74%:  0.17 – 0.33   (TP molto vicino, alta probabilità hit)
        75-79%:  0.33 – 0.50   (TP medio)
        80-84%:  0.50 – 0.67   (TP ambizioso)
        85%+ :   0.67          (max)
    Filosofia APEX "WR > RR": frazione conservativa, target raggiungibile
    intraday su Topstep no-overnight. Hard clamp [0.10, 0.80] applicato
    dall'orchestrator come defense-in-depth.

Velocità di hit TP per la sessione corrente (u   , liquidità
u   ): adatta sia tp_price_suggested sia rr_multiplier alla
probabilità che il prezzo raggiunga il target intraday.

CHAIN OF THOUGHT (3 step obbligatori — sintetizza in `reason`):
  STEP 1 — QUALITÀ DELLO SCONTO:
    RSI z: vicino a 4258u    = sconto OTTIMO,
    vicino al lato opposto della zona = sconto DEBOLE.
  STEP 2 — TIMING ESAURIMENTO PULLBACK:
    bouncing=z, volume_weak=z,
    PA dominant=z),
    VWAP z%, absorption pro zK.
    2+ segnali = +10%, 3+ = +15%, tutti = +20%.
    Absorption AVVERSA a u>    = -10%.
  STEP 3 — CONTESTO MACRO + LIVELLI:
    H1 struct=z, trend_mat=z	, RSI H4=z,
    divergence=z, swing=@u   .
    trend_mat>5 = -10%, divergence contro = -15%.

═══ CRITERI APPROVAZIONE ═══
approved=true SOLO se:
  1) confidence finale >= u   
  2) STEP 1 non è "DEBOLE"
  3) STEP 2 non è "PREMATURO" (>=1 segnale esaurimento)
  4) STEP 3 non è "SFAVOREVOLE"
  5) sl_atr_multiplier in [z]
  6) rr_multiplier in [0.17, 0.67] (mapping confidence sopra)
  7) tp_price_suggested coerente con la direzione
     (BUY: > entry z;
      SELL: < entry z4)
  8) tp_price_suggested entro max_reachable_ticks=u)    ticks
     dal prezzo (BUY: ≤ entry + u3   ×tick_size;
                  SELL: ≥ entry − u>  ×tick_size)

═══ REJECTION CODES (rule_failed quando approved=false) ═══
  - "STEP1_DEBOLE"        : sconto RSI insufficiente
  - "STEP2_PREMATURO"     : pullback non esaurito (no bouncing/volume_weak/PA)
  - "STEP3_SFAVOREVOLE"   : macro/H4/divergence/trend_mat contro
  - "CONFIDENCE_FLOOR"    : conf < u  
  - "ABSORPTION_AGAINST"  : absorption avversa alla direction
  - "ANTI_REVENGE"        : SL recenti senza pattern + volume_weak + RSI ottimale
  - "TP_BEYOND_MAX_REACHABLE": tp_price_suggested oltre max_reachable_ticks (time-budget insufficiente)
  - "OTHER"               : altri motivi (specifica in detail)
Quando approved=true → rule_failed="NONE", detail="ok".

═══ OUTPUT JSON (RISPETTA L'ORDINE) ═══
{
  "step_1_qualita_sconto": "OTTIMO/BUONO/DEBOLE: ...",
  "step_2_timing_pullback": "OTTIMO/BUONO/PREMATURO: ...",
  "step_3_contesto_macro": "FAVOREVOLE/NEUTRO/SFAVOREVOLE: ...",
  "approved": true,
  "confidence": 75,
  "direction": "z4",
  "risk_multiplier": 1.0,
  "sl_atr_multiplier": u  ,
  "rr_multiplier": 0.50,
  "tp_price_suggested": 0.0,
  "tp_rationale": "max 25 parole — livello tecnico + frazione $rischio",
  "key_risk": "rischio principale del setup",
  "reason": "max 8 parole, no virgolette",
  "rejection_details": {"rule_failed": "NONE", "detail": "ok"}
}
)<r  r`   r   rsi_h1r   market_structureregime_reasonr   	h1_reasonr   consecutive_sl_countvwapvwap_deviation_pctdeviation_pct
vol_regimer   	vol_spike
divergencer   r   r   _dtdatetimefromtimestamptimezoneutcnowstrftimehourrP  appendrQ  rR  rS  rT  rU  rV  rW  doji	doji_typejoindominantbuy_absorptionsell_absorption
swing_datar   r  r  rO   rB   TF_TIME_STOP_DEFAULT_MINfavor_directionadverse_directiontrend_maturitystrengthvolume_weakh1_struct_bullh1_struct_bearr   r  )Hre   r   r   r   r   r~   r   r   r}   r   r   r   r  r  sl_midsl_floorr|  r   structr~  r   r  	consec_slr  vwap_devr  r  r  r  r   tech_allowedrsi_bouncing
rsi_motionctnow_dtnow_utc_strutc_hrsession_name	liquiditynews_context
trend_word	vwap_sideatr_quality
macd_statepattern_flagspattern_strdoji_type_str
pa_pro_dirpa_alignabs_pro_dirswingsw_foundsw_typesw_price_strsw_barscompat_labelentry_for_tpr!  digits_for_tp
ts_sessionminutes_to_timestopr  r   atr_m5_ticksn_candles_to_tsmax_reachable_ticksusdjpy_entryinverted_noteasset_character	favor_stradverse_str
candle_agesH                                                                           rN   r   zBrainTF._build_entry_prompt  s^   X "*-(A-q1;;2 t{{#t{{#&&**$//0	NN	112	yy001d001__
(	__
$001
-- %3S8^ 5& 3S8^ 	
 !8^M#&> 	 7427a86\\//s||7G7G/HF\\%%cll&6&67Fook2??&5#L)&2&7#L)6B&>#L)6B&3#L)&9#L)9 	 $J& %J#Ja<I\II"K##K"K&0]m
 $&;; 4 4X > 4 4_ E 4 45E F 4 45E F== 4 4Z @?? 4 4\ B 4 4^ D 4 4^ D99  5)@5(A!CD2?dii.Y3) %@U^^y%@ B& @U^^y%@ 	 H^^55 HH%8T%8%8 ;& 9T%9%9 	 %299]E24<%))L%0-4<uyy*3/% 	 ))M1- &L##L)L TZZ(!!%%fb1DHHXq12 'v.
*..vr:>>0
 $((;4;<	gdOSAHSI6?!m	1-3!%(F(L"MN T>3?!3CC,.L7S7I J&s+ ,LM  M \\J[^QQFZA
 #f LM
N 	 IIe334A		ii 7 78EI74)=sCJsK
j j  j j !j "-j .<j =F;jGj j j ,_j-j j /j 0<nj=j jj j *j 3<$)FjGj jj j 	j !\j "1j 261D1D0EjFj  x!j   3!j  4@-PQ?Q2R!j S8!j" 9A~#j" FI#j" JMS	#j"R#j$ %j$ %j$  %j$%%j& t 'j& ('j& )-Q}oQ,>'?'j&@'j( ;)j( )j( %T?)j( +<)j( =C8)j(D)j* +j* #+j* $-++j* .0+j* 1:#+j* ?A+j* BN+j*O+j, #|-j, $,-j, -7<-j, 89-j, :G-j,H-j4 &2Tt<5j4=5j: )M;j:*;j< +O=j<,=j> #^^,?j> -5?j> 6;^^C4H?j> IP?j> QYz?j> Z]?j> ^g\g?j>h!?j@ "+Aj@ ,.Aj@ /8[Aj@9#AjB $-+CjB .0CjB 1<}CjB=CjD *1)<)<X)LEjD M[EjD \c[n[nZoEjDp%EjF &*%8%8$9GjF :EGjF FJEYEYDZGjF["GjH #,IjH -/IjH 0;mIjH<IjJ 'sOKjJ ,<KjJ =H=KjJIKjL -S1MjL2MjN &/TD9OjN:6OjT 7@[UjTAUjZ "[jZ #&[jZ '3^[jZ 46[jZ 7>Y[jZ?[j\ (-]j\.]j^ $C_j^ )._j^ /;^_j^<_j`  $223aj` 4;aj` <@;N;N:Oaj`Pajb $cjb %9cjb CLa-UY8Zcjb[cjd T]  `a  Ta79+  a  mv  z  m  bi  EL  aM  MO  P  gi  jejdjejj 8kjj "kjj #*++l3"?!@kjj ADkjj ELKKPVWYDZC[kjj\kjl $CLmjl ).mjl /6c]mjl ;Bmjl CImjlNmjn @H)(7;RPojnQojr SMsjr"sjt CLujt!ujv CLwjv!wjx CLyjx!yj~ II;j~j@ !=/ 23Aj@4AjB s#CjB$CjD $$EjD%EjJ (KjJ KjJ  LKjJ !$KjJ %8#8KjJ9KjL  -12MjL 3<MjL =I;MMjLN.MjN />c-BOjNCOjR //SjR0;SjV <O:OWjVPWjX Am_A-.YjX	/Yjj !kjj"kjl Kmjl#mjv $(-'9":wjv ;Cwjv DK)wjvLwjx Nyjx *yjx +8)=yjx>/yjX 0<nYjX=YjZ [jZ	[jd 
S	ejd ejd &/%%7TTBejdCejj ^kjj *kjj +2*=*=)>kjj?kjl  mjl !)mjl */(<mjl=
mjn 4ojn +ojn ,5+ojn 68ojn 9D}ojnEojr $sjr%sjv hwjv #wjv $(#6#6"7wjv 8Awjv BHwjvMwjx |yjx $yjx %,9yjx -.yjx /;^yjx<yjB **CjB+CjJ #3<KjJ (*KjJ +2#KjJ7KjP !=/ 23QjP4QjR "!M?!!34SjR53SjT 4G2GUjTH#UjV $7"7WjV8'WjX (;&;YjX<$Yjd %3#3ejd4ej@ Aj@AjD s|EjD$Ej j	rP   c                h   K   | j                  |       d {   }| j                  ||       |S 7 wrT   )_manage_exit_logic_emit_manage_decision_log)r[   ctxrr   s      rN   manage_exitzBrainTF.manage_exit  s3     0055&&sH5 6s   202c           	       K   |j                   }|j                  }|j                  }|j                  }|j                  }|t
        j                  j                  k(  }|j                  }|j                  }	t        j                  j                  t        j                        j                  }
t        |
      }t         j#                  |i       j#                  |t$              }|dk  r&|	|k\  r!| j'                  d|	dd| d| dd|d	      S |j(                  }|t*        k\  rk|j,                  s_| j/                  |j0                  t3        |j4                              }t7        t8        j:                  j                  d
|dddd||d      S t3        t=        |dd      xs d      }|r$||j>                  k  r| jA                  dddi	      S |jB                  }|jD                  }||k(  }d}|	tF        k\  r|r
d|v rd|vrd}|s
d|v rd|vrd}|jH                  }|xr |dk  xs
 | xr |dkD  }tK        |      }tM        ||      }| jO                  |||||||      }| jP                  jS                  |dd       d{   }|jT                  .| jA                  d|jV                   dd |jV                  d!	      S | jY                  |jT                        }|rd"|vr| jA                  d#dd$i	      S d%d&||||r|ndd'}t[        |j#                  d"            r/| j'                  t]        |j#                  d(d)            dd* |	      S t7        d+t]        |j#                  d(d,            dd* |      S 7 w)-aO  
        TF exit management. Bias toward HOLD (V15 philosophy).

        Order:
          1. Time-stop (only if P&L <= 0): EXIT.
          2. Same-candle dedup: HOLD without AI call.
          3. Build exit prompt (with struct-flip / deep-discount notes).
          4. Call AI (deterministic).
          5. Map exit_now=true -> EXIT, false -> HOLD, error -> HOLD default.

        Brain does NOT mutate runtime. The orchestrator must read
        BrainDecision.metadata["evaluated_candle_time"] (when set) and
        update TradeRuntime.last_exit_eval_time before persisting state.
        r   u   Time Stop TF — r
  zm/zm (rZ  	time_stop)triggersession)r   r   zTP u   % — partial 50% TF + SL→BEauto_partial_50T)r  set_be_after_partialbe_priceprogress_pct)actionr   r   ro   u   stessa candela già analizzatar  dedupFrE  rC     K   )r  r   r   struct_unchangedstruct_flippeddeep_discountr  i  r  )
max_tokenswhereNz
AI error (u   ) — hold defaultai_error)r  r   exit_nowu"   AI malformed JSON — hold defaultai_malformedr   ai_exit_eval)r   r  r  r  r  r   r   zAI exitr7   HOLDzAI hold)/entryruntimetech_nowre   r   r   rl   valuenet_profit_usdminutes_openr  r  r  UTCr  rO   rB   r`   r  _exitr  TF_AUTO_PARTIAL_PROGRESS_PCTpartial_done_round_to_tickr   r   r  r   r   
PARTIAL_50r   last_exit_eval_time_holdr}  market_structure_at_entrySTRUCT_FLIP_GRACE_MINrsi_h4_at_entryr   r   _build_exit_promptrW   r   r   r   r   r   r   )r[   r  r  rtr}   re   r   is_long
net_profitr  rM   r  ts_thresholdprogressr  ro   
struct_nowstruct_at_entryr  r  r  r  r   r   r   r   r   metas                               rN   r  zBrainTF._manage_exit_logic  s     		[[||OO	y}}222&&
 <<##CGG,11#H-#''377-
 ?||;::*<*<B|nCPWyXYZ%0WE    ??33BOO**!!5#8H !"--33hs^+IJ0,0 ($,		 	 GD-;@qA;"*@*@@::7#W-    **
99&/9009
2y7W!%j!8Yo=]!%  //-2- 5k33 	 %T*),((WE-)' ) 
 WW--s- . 
 
 99::#DOO#44FG%/tO    $$TYY/61::;#^4    %,*4?[T
 

:&'::6::h	:;DSA   
 vzz(I67=
 	
;
s   I:M3<M1=C5M3c                   | j                   }| j                  }| j                  }	|j                  t        j
                  j                  k(  }
|
rdnd}t        |	j                        }t        |	j                        }t        |	j                        }|j                  }|j                  }|j                  }|r!d| d|j                   d|	j                   d}n`|rA|j                   dk  }|rd|j                   d	d
|j"                   d}n.d|j                   d}nd|j                   d|	j                   d}|r |
rd|dd|dz
  dd}n:d|dd|dz   dd}n+||z
  }d}|
r|dk  rd}n	|
s|dkD  rd}d|dd|dd|dd | }t        |	j$                        }|
xr |d!kD  xs
 |
 xr |d"k  }|rd#nd$}|
xr |j&                  d%k(  xs |
 xr |j&                  d&k(  }|rd'}n|j&                  d(v rd)}nd*}|
xr |	j(                  xs |
 xr |	j*                  }d+j-                  |j.                        xs d,}d+j-                  |j0                        xs d,}g }|	j2                  r|j5                  d-       |	j6                  r|j5                  d.       |	j8                  r|j5                  d/       |	j:                  r|j5                  d0       |	j<                  r|j5                  d1       |	j>                  r|j5                  d2       |	j@                  r|j5                  d3       |	jB                  r|j5                  d4       |	jD                  r#|j5                  d5|	jF                  xs d6 d7       |rd+j-                  |      nd8} d9}!|jH                  rVt        |	jJ                        }"|
r |"|jL                  z
  |jH                  z  d:z  }!n|jL                  |"z
  |jH                  z  d:z  }!tN        jP                  jS                  |jT                  i       }#tW        |#jS                  d;d            }$dj-                  g d<|jT                   d=| d>|jX                  dd?|jH                  d|$ d@dA|jL                  d|$ d@dB|!dCdD|jZ                  d|$ d@dE|j"                   dF|ddG|ddH|j                   dI|j\                   dJ|rdKndL dM|j^                  d	dN|jX                  ddO| dP|	jJ                  d|$ d@dQ|dd|dd||z
  ddR|dd|dd||z
  ddS|dd|dd||z
  ddT| dU|	j                   dV|j                   dW| dX|	j`                   dY|	jb                  d	dZ|	jd                   d[|	jf                  rd\ndL d]|	jh                  rd^nd_ d`|	jj                   da|j&                   db|jl                  ddc| dd| de|jn                  ddf|jp                  ddg|dhdi| dj|dhd| dk|jr                  rdlndm dn|jr                   do| d|rd\ndL dp|	j(                   dq|	j*                   dr|	jt                  d	ds|  dt|	jv                  d|$ d@du|dCdv| dw| dx|rdynd dz      S ){uE  
        V17 narrative anti-hallucination exit prompt (TF).

        Default conservativo = HOLD (V15 philosophy preservata). Quattro
        sezioni narrative:
          1. Contesto entry originale (snapshot al fill)
          2. Situazione attuale (numeri reali aggiornati: P&L, prezzo,
             RSI M5/H1/H4, struttura now vs entry, ATR, MACD, divergenza,
             sessione)
          3. Price action attuale (PA dominant, favor/adverse, volume,
             absorption, candle strength, VWAP deviation, pattern attivi)
          4. Domanda rigida + regole anti-allucinazione

        Anti-hallucination guardrails (V17):
          - Risposta SOLO con i numeri/flag forniti — niente livelli/swing
            inventati, nessuna speculazione su candele non elencate
          - Se incerto → HOLD (default)
          - EXIT richiede ALMENO 2 segnali confluenti oggettivi citati nel
            `reason`. Single-signal exits sono rifiutati a priori.

        Specifici V16 preservati:
          - struct_flipped (con grace period) → 🚨 alert in sez. 2
          - deep_discount H4 paradox → h4_rule dedicato in sez. 2
          - VWAP trend-confirmed flag → labellato in sez. 3
          - Paradosso struttura against-trend deliberato → nota in sez. 2

        Output JSON invariato: {"exit_now": bool, "reason": str}.
        LONGSHORTu    🚨 STRUTTURA INVERTITA CONTRO ro  r  uG   . Il trend che supportava il TF è terminato — segnale forte di EXIT.re  uC   ⚠️ PARADOSSO STRUTTURA: entry against-trend deliberato (compat=r   z) approvato a Cu1   %. Struttura INVARIATA → NON è motivo di exit.zStruttura H1 INVARIATA: z. Non motivo di exit.zStruttura H1 CAMBIATA: z'. Va valutata insieme ad altri segnali.zDEEP DISCOUNT (H4 entry rx   zi): IGNORA livello assoluto < 35. EXIT solo se H4 era salito >35 post-entry e ora ricaduto, o sceso sotto rf  r
  rk  zi): IGNORA livello assoluto > 65. EXIT solo se H4 era sceso <65 post-entry e ora risalito, o salito sopra r   iu9    ⚠️ Crollo H4 significativo — possibile inversione.   u8    ⚠️ Rally H4 significativo — possibile inversione.zRSI H4: entry u	    → ora rh  z+.1frx  g?gɿztrend confermatoznon confermatorC  rE  r]  r^  r_  r`  r[  rg  rP  rQ  rR  rS  rT  rU  rV  rW  rX  rY  rZ  r\  ri   d   r(  u   Sei un gestore di posizioni Trend Following. Valuta SOLO la full exit.
Default conservativo = HOLD. Rispondi SOLO con JSON valido — zero testo
fuori dal JSON.

═══ 1. CONTESTO ENTRY ORIGINALE ═══
z trade z aperto z minuti fa.
Entry rl  z, SL z
(distanza dal prezzo attuale rn  z%), TP z.
Confidence originale: z%. RSI M5 entry:
z, RSI H4 entry: z.
Struttura H1 al fill: z. Regime al fill:
z. Deep Discount: rv  rj  u   .

NOTA: Partial close gestito dal Router/Orchestrator. Qui valuti SOLO la
FULL EXIT.

═══ 2. SITUAZIONE ATTUALE ═══
P&L netto      : $z
Tempo aperto   : zm  (sessione z)
Prezzo attuale : u&   

RSI multi-TF (entry → ora):
  M5: z)
  H1: z)
  H4: rw  z

Struttura H1 ora    : z
Struttura H1 entry  : 
z

Trend Maturity : z candele H1
ATR Ratio      : zx
Vol Regime     : z
Vol Spike      : ri  z
MACD           : rN  rO  z
Divergenza     : uB   

═══ 3. PRICE ACTION ATTUALE ═══
PA dominante      : rp  rq  rm  z
  Bullish/Bearish : z / z	
  FAVOR 5z  : z
  ADVERSE z
Volume            : rr  rs  rt  z)
Absorption pro z
                    (BUY_ABS=ru  z)
Candle Strength   : z$x (1.0 = media)
Pattern attivi    : z

VWAP intra-day    : z
VWAP deviation    : z% (u   )

═══ 4. DOMANDA RIGIDA — ANTI-ALLUCINAZIONE ═══
Basandoti SOLO sui dati oggettivi sopra: il prezzo si sta muovendo CONTRO
il trade u   con struttura cambiata? EXIT solo se almeno 2 segnali
oggettivi confluenti confermano inversione. Se incerto → HOLD. Non
ipotizzare, non speculare — usa SOLO i numeri forniti.

Esempi di segnali oggettivi citabili dal contesto sopra:
  - struttura H1 CAMBIATA contro la direzione (sez. 2, struct_note)
  - RSI H4 delta significativo contro (sez. 2, h4_rule)
  - PA dominante ADVERSE con forza > 1.5x (sez. 3)
  - pattern reversal contrario attivo + candle strength > 1.8x (sez. 3)
  - divergenza confermata + MACD decelerando (sez. 2)
  - VWAP deviation contraria + vol_regime HIGH (sez. 2 + 3)
  - candela gigante contraria (candle_strength > 2.5x) + vol_spike (sez. 3)

REGOLE OPERATIVE:
  • Rispondi SOLO con i dati forniti — non inventare livelli, swing,
    pattern non elencati, né target ipotetici
  • Se incerto → HOLD (default conservativo)
  • EXIT richiede ALMENO 2 segnali confluenti oggettivi (citali nel reason)
  • Single-signal exits sono RIFIUTATI a priori (es. "RSI estremo" da solo,
    "VWAP contro" da solo, "struct invariata" da sola → HOLD)
  • Paradosso struttura: se entry era against-trend deliberato (vedi nota
    sez. 2), struttura invariata NON è motivo di exit
  uJ   • Deep discount: ignora livello assoluto H4, applica solo h4_rule sez. 2u   

═══ OUTPUT (SOLO JSON) ═══
{
  "exit_now": false,
  "reason": "max 12 parole — cita dati specifici (es. 'struct flip H1 + RSI H4 -18 + adverse PA 1.7x')"
}
)<r  r  r  r   r   rl   r  r   r   r|  r   rsi_m5_at_entryrsi_h1_at_entryr  r  r}  h1_compat_at_entryconfidence_at_entryr  r  r  r  r  r  r  rP  r  rQ  rR  rS  rT  rU  rV  rW  r  r  r   r   r   r  r  r`   re   r   r  r   regime_at_entryr  r  r   r  r  r   r  r  bullish_scorebearish_scorer  r   r  )%r  r   r   r  r  r  r  r  r  r}   r  
trade_type
rsi_m5_now
rsi_h1_now
rsi_h4_nowrsi_m5_entryrsi_h1_entryrsi_h4_entrystruct_noteentered_against_h1h4_ruledeltawarnr  vwap_trend_confirmed
vwap_labelr  r  r  r  r  r  r  sl_dist_pctcurrentr!  r(  s%                                        rN   r  zBrainTF._build_exit_prompt  s   N 		[[||//Y]]%8%88&VG
 488_
4;;'
4;;'
,,,,,, 2:,b22359N9N8O PXY 
 !&!9!9C!?!$77< =112 3-.  /6677LN  *%*I*I)J%(())PR  .|C.@ A@ $a',A/  /|C.@ AA $a',A/  -ED53;R52:Q c 2)Js;K L$<r$)  001-x#~ 0k.x$ 	 ,@'EU
 :u~~: <k:u~~: 	 H^^55 HH2t22 5k3t33 	
 IIe334A		ii 7 78EI $&;; 4 4X > 4 4_ E 4 45E F 4 45E F== 4 4Z @?? 4 4\ B 4 4^ D 4 4^ D99  5)@5(A!CD2?dii.Y DJJ'G&75;L;LLsR$~~75;L;LLsR !!%%ellB7TXXh*+T T  T T T !\T "*T +-//#)>T?T 6(!$T %*T +0..6(!)DTET *$/T 07T 8=~~axq[6QTRT 001T2T c T #T $0"4T5T 667T8T  T )T 3@T(JTKT$ $$S)%T$*%T& //#&'T& '4'T& 5<9'T&='T( **QvhaK()T())T. C/T. /T. )-/T. .0/T. 1;\0I$/O/T.P/T0 C1T0 1T0 )-1T0 .01T0 1;\0I$/O1T0P1T2 C3T2 3T2 )-3T2 .03T2 1;\0I$/O3T2P3T4 		5T4
5T8 ,,-9T8.9T: 667;T:8;T< =T<=T@ %%&AT@'ATB ..%CTB&CTD //"ETD#ETF ..$d3GTF4GTH $(#9#9-}MITHNITJ //"KTJ#KTP ^^$QTP %-QTP .3^^C,@QTP AHQTP IQzQTP RUQTP V`T`QTPaQTR ((-STR .1STR 271D1DS0ISTRJ	STT 
AUTT UTT %+UTT&UTV a.WTV WTV '-WTV(WTX ")!4!4X)DYTX ESYTX T[SfSfRgYTXhYTZ |[TZ [TZ '2dt<[TZ=[T\ #112]T\ 3>]T\ ?C>R>R=S]T\T]T^ ))#._T^/_T` !MaT`"aTd YYqk*eTd+eTf dOgTf $'gTf (2lgTf3
gTn oTnoTZ TaOfhi[TZj[T T	rP   c                ~    	 t        j                  t        |             S # t         j                  t        f$ r Y y w xY wrT   )jsonloadsr   JSONDecodeError	TypeError)r   s    rN   r   zBrainTF._parse_ai_json  s9    	::8>??$$i0 		s     <<)r}   c               R   i t        |      |}| j                  /	  | j                  j                  j                  	 d	|d|||d| yt        j                  d|||||       y# t        $ r7 | j                  j
                  j                  d| d| d| d| d| 
       Y yw xY w)
u  
        Emit a structured "entry_rejected" event and return None.

        Every reject path passes through here. Fields (rule + caller-
        provided numerics) end up in brain_log.jsonl for post-mortem
        analytics — esp. CALIBRAZIONE 5-9 mag where we need to histogram
        skip causes and inspect ATR/RR distributions on real trades.

        V18 12-mag — `tech` opzionale: se passato, i campi RADAR
        (rsi_m5/rsi_h4/h1_compat/macd_hist/pattern/atr_ratio/bias/...)
        vengono auto-popolati via `tech_log_fields(tech)`. Eventuali
        valori in `fields` hanno precedenza sui campi auto-derivati.

        Args:
            rule: short stable code for the rejection cause
                  (e.g. "PULLBACK_ZONE", "POST_VAL_TP_RANGE").
            detail: human-readable explanation, max ~200 chars.
            tech:  TechSnapshot per arricchimento dashboard.
            **fields: rule-specific numerics (rsi_threshold, sl_distance_*, ...).
        Nr   )re   r   r   r{   r   z[TF reject]  ro  z fields=z"[TF reject] %s %s %s: %s fields=%s)entry_rejected)	r	   rX   	brain_logwriteAttributeErrorrd   inforb   debug)r[   re   r   r{   r|   r}   fieldsmerged_fieldss           rN   r   zBrainTF._reject  s    < <?40;F;;;"+%%++$!'! $* 	 JJ4	4  "  ""''"6(!I;avRx H+_. s   -A& &=B&%B&rT   )r]   r
   returnNone)re   r   r-  r3   )re   r   rj   r   r-  r   )r   r3   re   r   r   r   r   r   r   r   r   r3   r   r   r-  zOptional[tuple[str, str]])re   r   r   r   r   r   r-  r3   )re   r   r   r   r   r   r   r   r   r   r~   r   r   r   r   r   r   r   r   r   r   r3   r-  r   )r  r   r-  r   )r  r   r   r   r   r   r  r   r  r   r  r   r  r   r-  r   )r   r   r-  zOptional[dict])
re   r   r   r   r{   r   r|   r   r-  r.  )__name__
__module____qualname____doc__r   r   r  namerV   rh   r  staticmethodr   r   r   r  r  r  r   r   __classcell__)r^   s   @rN   rR   rR      sX    <<D70 '*s
s
 $s
 
s
r	 lll l 	l
 l l l 
#l ld K
K
K
 	K

 
K
 K
b HH H 	H
 H H H H H H H H 
H H\
~
H uu u 	u
 u u u u 
u uv   66 6 	6
 6 
6rP   rR   )rM   r   r-  r   )2r2  
__future__r   r  r  r  loggingtypingr   analysis.price_actionr   r   r   r   analysis.tech_snapshotr	   brain.ai_clientr
   r   brain.brain_baser   corer   r  core.contractsr   r   r   r   r   r   r   trading.tp_resolverr   	getLoggerrb   r4   __annotations__r6   rB   r  r   r   r   r   r  r  r  rO   rR   rL   rP   rN   <module>rB     sM  6 #      3 @ & *   A w$4 & ]	 ( ^	 &[	 $!S	 $!> $!? &!; $!S $.Z $+Lk: 4 :| Z  s6s6s6s6s6 #7 #7#7#7 #7/d 4   
   
  $ ~i ~rP   