
    wjQI                      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/d0d#d1d2d3d#d4
Z$d5e%d6<   d d7d8d#Z&d5e%d9<   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;d;d<d@d@d>d<d;d;d<d@d@d>d<d:d<d=dAdAd>d:d?d;d<dAd=d>dB
Z'd5e%dC<   dDZ(dEZ)dFZ*dGZ+dZ,dHZ-dIZ. e/ej`                        Z1dJZ2dZ3dKZ4dLZ5dMZ6dNZ7dOZ8dSdPZ9 G dQ dRe      Z:y)Tu  
APEX V16 — Brain Mean Reversion.

Migrated from V15's Brainmr.py. The TRADING RULES are unchanged:
  - Entry only on RSI extremes (BUY <32, SELL >68)
  - ATR ratio cap (atr_ratio > 1.8 -> reject; volatility eccessiva)
  - Indices (MES/MNQ/MYM) PRO-TREND only (V15 patch #20):
      BUY requires BULLISH H1 structure
      SELL requires BEARISH H1 structure
      RANGING regime -> reject (indices don't MR in range)
  - Candle pattern signal SOFT: when reversal pattern absent,
    AI confidence threshold raises 60% -> 75%
  - Post-validation watchdog (RSI re-check, conf threshold by
    pattern presence, RR floor, C>=90% + H4 weak guardia)
  - Time-stop matrix per (asset, session) with TUPLE
    (deep_loss_min, breakeven_min)
  - Grace period for indices (+15min if break-even & RSI toward mean)
  - Trailing emergency (progress > 30% & TP large enough)
  - Auto partial 50% + SL→BE at progress >= 50% (V18: era 65%, allineato a TF)
  - RSI50 cross + P&L > 0 + progress > 15% -> PARTIAL_50 + set_be
  - AI exit per-candle (idempotency via runtime.last_exit_eval_time)

The user reading this file should recognize V15's MR rules; only the
data flow changed (typed dataclasses, no state mutation, async).
    )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.mr)g333333?g?   US500z7S&P500 micro MR: V16 calibrato ATR_M5 ~6, sl_ticks 8-25)sl_rangesl_min_points
v15_originnote)gQ?      ?<   US100z8Nasdaq micro MR: V16 calibrato ATR_M5 ~30, sl_ticks 8-30)gp=
ף?g?d   US30z6Dow micro MR: V16 calibrato ATR_M5 ~80, sl_ticks 11-36)ffffff?333333?      ?皙?XAUUSDz$Gold micro: deep SL, V15 calibration)r   r   max_risk_multr   r   )      @      @EURUSDz#EUR/USD: SL 9-15p (V15 calibration))r   r   r   )gffffff@g      @GBPUSDz$GBP/USD: SL 15-24p (V15 calibration))g?g?r   USDJPYz JPY: SL 24-39p (V15 calibration))r#         @USDCADz;CAD MR: V16 calibrato (ATR_TYPICAL 0.0008 alto vs altri FX))r'   g333333@zAUDUSD (new in V16)z"AUD/USD MR: derived from 6E analog)      ??zWTI (new in V16)z8Crude Oil micro MR: tight ranges, refine in CALIBRAZIONE)
MESMNQMYMMGC6E6B6J6C6AMCLdictMR_ASSET_PROFILESGENERICuI   no V15 equivalent — generic conservative MR profile, recalibrate in V16GENERIC_PROFILE)F   s   )A   n   )K   x   )P   }   )LONDON	LONDON_NYNY_CLOSENY_LATE
ASIA_EARLYASIA_LONDON_GAP)r   i   )_      )U      )
r4   r5   r8   r6   r7   r0   r1   r2   r3   r9   MR_TIME_STOP)#   r   g      @@g      Q@r/   rB      g      >@r,         I@g      .@g      H@g      J@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      rF      rG      rH      rI   r      rJ   rK    )utc_hours    %/home/work/apex_v16/brain/brain_mr.py_classify_sessionr_      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e	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd       ZddZddZedd       Zedd       Ze	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd       Zed d       Zdd	 	 	 	 	 	 	 	 	 d!dZ xZS )"BrainMRa  
    Mean Reversion Brain. Async (uses AIClient).

    Tech keys consumed (orchestrator pre-condition):
        symbol, price, open, rsi, rsi_prev, rsi_h1, rsi_h4,
        atr_ratio, atr_m5_points, vwap, vwap_deviation_pct,
        market_structure, regime, vol_regime, trend_maturity,
        candle_strength, candle_time, divergence, macd_decelerating,
        deviation_pct (EMA50 deviation),
        bias, allowed_direction, h1_compatibility, h1_reason,
        swing_data (optional dict),
        consecutive_sl_count (optional int).

    Plus PA pattern keys (consumed via analysis.price_action):
        hammer, bull_engulfing, morning_star, piercing, doji + doji_type,
        shooting_star, bear_engulfing, evening_star, dark_cloud,
        volume_weak.
    Nc                ^    t         |   |       || _        || _        t	               | _        y N)super__init__ailoggerset_warned_generic_profile)selfconfig	ai_clientrh   	__class__s       r^   rf   zBrainMR.__init__   s(     14$r`   c                *   t         j                  |      }||S || j                  vrg| j                  j                  |       d| d}t        j                  |       | j                  %| j                  j                  j                  |       t        S )Nz
[BrainMR] uL   : no V15-calibrated profile — using GENERIC. Recalibrate in V16 (5-9 may).)	r;   getrj   add_logwarningrh   systemr=   )rk   symbolprofmsgs       r^   _profile_forzBrainMR._profile_for  s     $$V,K555((,,V4x (B CCLL{{&""**3/r`           )last_entry_eval_timec                 K   |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 |dv r|dk  rd}nd}|dk(  r;|t        k\  r2t        | j                  ||ddt         d|dd|t        d            S |dk(  r;|t        k  r2t        | j                  ||ddt         d|dd|t        d            S |t        v }|rt        |j                         j#                         }t        |j$                        j#                         }|dk(  r&t        | j                  ||dd| d|||            S d |v }d!|v }|dk(  r+|s)t        | j                  ||d"d| d#| d$|||%            S |dk(  r+|s)t        | j                  ||d"d| d&| d$|||%            S |t&        kD  r1t        | j                  ||d'd(|d)d*t&         d+|t&        ,            S t        |j(                        }|d-k  r(t        | j                  ||d.d/|d)d0| d1|2            S t        |j*                        }t        |j,                        }|dk(  xr
 | xr |dk  xs |dk(  xr
 | xr |dkD  }|r*t        | j                  ||d3d4| d5|d6d7|||8            S |	r|	|k  rt        dd9:      S | j/                  |      }t1        |      }t3        ||      }| j5                  ||      }| j7                  ||||||||||||;      }| j8                  j;                  |       d{   }d<d=h}|j<                  |	r|	nd}n|j>                  |v rd}n|	r|	nd}|j<                  Dt        | j                  ||d>d?|j>                   ||j>                  |j@                  @      |A      S | jC                  |j<                        }|rdB|vr3t        | j                  ||dCdD||j<                  xs dEddF G      |A      S | jE                  |||||||t        |jF                        H      }|i }|d   dIk(  r'dJ|dK<   t        |jI                  dLd	      xs d	      |dM<   t         | j                  ||f|d   |dN   |tK        |jI                  dOd            t        |jI                  dPd	            t        |jI                  dQd	            |dR||A      S |jI                  dB      s|jI                  dS      xs i } tM        | tN              rt        | jI                  dTdU            ddV ndU}!tM        | tN              rt        | jI                  dWdE            ddF ndE}"t        | j                  ||dXt        |jI                  dYdZ            ddF |tK        |jI                  dOd            ||!|"[	      |A      S 	 | jQ                  |||t        |dP         \      }#tK        |jI                  dOd            }%t        |jI                  dYda            ddb }&t        |jI                  dQd	            }'t        |jI                  dcdd            }(t        |jI                  dedf            })|(|)kD  r|)}(t        tW        ||#dg   |#dh   d	|'|%|&i didjdP|#dk   dl|'dMt        |jI                  dLd	      xs d	      dmt        |jI                  dndE            ddF dc|(dot        |jI                  dodE            ddb dp|#dq   dr|#dr   ds|#ds   dt|#dt   du|#du   dv|#dv   dw|#dw   dx|dy|jI                  dzd{      |      |A      S 7 # tR        tT        f$ r:}$t        | j                  ||d]d^|$ |t        |d_d      `      |A      cY d}$~$S d}$~$ww xY ww)}an  
        Evaluate an MR entry. See BrainTF.evaluate_entry docstring for
        the EntryEvalResult contract and same-candle dedup semantics.

        Direction derivation (V15): BUY if allowed_direction in {BUY, BOTH}
        AND rsi < 50; SELL otherwise. So MR direction comes from RSI side
        of 50 within bias-allowed set, not just from bias alone.
        candle_timer   is_candle_closedFNCANDLE_NOT_CLOSED)decisionreject_reasoncandle_age_secondsry   CANDLE_STABILIZINGCANDLE_TOO_OLD)BUYBOTHrT   r   SELLRSI_NOT_EXTREMEzMR BUY requires RSI < z (oversold). RSI M5=.1fz! -> use TF for shallow pullbacks.oversold)ruledetailtechrsi_thresholdside)r   zMR SELL requires RSI > z (overbought). RSI M5=
overboughtRANGINGINDICES_RANGINGzindex z5 in RANGING regime -> MR not allowed (V15 patch #20).)r   r   r   regimemarket_structureBULLISHBEARISHINDICES_NOT_PRO_TRENDz5 BUY requires BULLISH structure (V15 patch #20). Got .)r   r   r   r   r   z6 SELL requires BEARISH structure (V15 patch #20). Got ATR_TOO_HIGHz
ATR ratio .2fzx > cap u.    — volatility excessive for MR (spike risk).)r   r   r   atr_capr!   H1_COMPAT_TOO_LOWz
H1 compat u    < 0.70 — z	 rejected)r   r   r   MACD_ACCELERATING_AGAINSTzMACD accelerando contro z (hist=z.6fu   ) — MR rejected)r   r   r   macd_deceleratingmacd_hist_lastT)r   dedup_skipped)ru   	directionallowedrsirsi_h4	atr_ratior   	bias_datasignalsscorepattern_confirmedprofileunknownoverload	API_ERRORzAI unavailable: )r   r   r   
error_kindattempts)r   evaluated_candle_timeapprovedAPI_PARSE_ERRORzAI returned malformed JSON    )r   r   r   response_preview)resultru   r   r   r   r   r   entry_priceTP_BELOW_MIN_PROFITrejected_tp_too_small	tp_sourcetp_price_suggestedtp_price_suggested_ai   
confidencesl_atr_multiplierrr_multiplier)r   r   r   ai_confidence	ai_sl_atrai_rr_multiplierr   rejection_detailsrule_failedUNSPECIFIED(   r   AI_REJECTEDreasonzAI did not approve)r   r   r   r   r   ai_rule_failedai_rejection_detail)ru   r   r   sl_atrPRICE_COMPUTATION_ERRORzcannot compute prices: atr_m5_points)r   r   r   r   zMR setup approvedrC   risk_multiplierr.   r&   g     8@r   sl_pricebrainMRr   rr_multiplier_aitp_rationale_aitp_rationalekey_risksl_ticks_usedsl_ticks_post_clampclamp_active
sl_flooredsl_min_tickssl_price_ai_rawsl_ticks_presl_floored_or_cappedr   profile_originr   ?)r   r   r   tp_pricer   r   	rationalemetadata),allowed_directionfloatr   r   r   getattrboolr   rl   candle_close_delay_secondscandle_max_age_secondsRSI_MR_OVERSOLD_rejectRSI_MR_OVERBOUGHTINDICES_FUTURESstrr   upperr   ATR_RATIO_CAPh1_compatibilityr   r   rx   r   r   _pattern_confirms_reversal_build_entry_promptrg   ask_for_decisiontextr   r   _parse_ai_json_post_validatepricerp   int
isinstancer:   _compute_sl_onlyKeyError
ValueErrorr   )*rk   ru   r   r   rz   r   r   r   r   r|   ager   is_indexr   structtrend_is_bulltrend_is_bear	h1_compat
macd_decel	macd_histmacd_againstr   r   r   r   promptrespTRANSIENT_KINDS
ai_eval_tsr   	rejectionextra_fieldsrdai_rule	ai_detailpcer   r   r   	risk_multr&   s*                                             r^   evaluate_entryzBrainMR.evaluate_entry  s>
    $ --DHHot{{#$..)	GD-;@qA GD"4e<="-@  GD"6<CDt{{==>>"-A  t{{99::"-= 
 o%#*II #"8"DLL	(900A B""%c*KMz	 -9 -   3*;#;"DLL	(912C1D E""%c*KM):	 -9 -   _,%++-F../557F"&I,=$VH -> ?fv	 1= 1   &/M%/ME!-&I,C$VH -44:81>v	 1= 1   F"=&I,C$VH -44:81>v	 1= 1   }$"DLL	$YsO8M? KD E=	 -9 -   $//0	t"DLL	(;#Ic?,ykS -9 -   $001
$--.	%E^E	A G& E^E	A 	 "DLL	(C29+ >!!*3/@B",( -9 -   ;*>>"DEE ##F+$T*), ;;GYO))YFi5/ * 
 WW--f55 %j199 9D+$J__/J(3J99"IK-doo->?#	 &  '1  $$TYY/61"I,=7&*iio2t%<	 &  '1  ''/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&7	 #	 '1  zz*%/06BBHRSUW[H\c"&&>?DboG;Eb$;OBFF8R01$37UWI"IMvzz(4HIJ4CP"%fjjq&A"B&7#*(1 &  '1  	&&#V$789	 ' B$ L!45


8-@AB4CH	 OS!AB &**%6<=	gkk/5AB}$%I"#}-J.%#'H ')9 ,U6::>RTW3X3_\_-`	
 &VZZ-K)LTc)R & VZZ
B-G)H#)N $,A)B #N); !L)9 #N); &B/@,A #B~,>  +B/E,F!" ():#$ %\3)G%: #-=
 	
e 6x *% 		"I,E4QC8")$"F	 &  '1 		sD   O1a3`4Ja!` #E#aa/aaaaac                   |dk(  rD| j                   xs6 | j                  xs( | j                  xs | j                  xs | j                  S | j
                  xs6 | j                  xs( | j                  xs | j                  xs | j                  S )ar  
        Returns True if a reversal candle pattern confirms the MR setup.
        For BUY: any bullish reversal pattern (hammer/bull_engulfing/
        morning_star/piercing/doji_bull). For SELL: bearish counterparts.

        V15 had hardcoded dragonfly_doji and gravestone_doji checks;
        analysis.price_action already maps doji+type into doji_bull/bear.
        r   )
hammerbull_engulfingmorning_starpiercing	doji_bullshooting_starbear_engulfingevening_star
dark_cloud	doji_bear)r   r   s     r^   r   z"BrainMR._pattern_confirms_reversalI  s     NN &g&<&< &((&,3,<,<&%%' %% ")?)? "$$"(/(:(:"!!	#r`   c                R   | j                  d      sy|dk(  r|t        k\  rdd|ddt         dfS |d	k(  r|t        k  rdd|dd
t         dfS t        | j                  dd            }|r|t        k  r'dd| dt         dfS |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                  d0d            }|dkD  r|dkD  rd1t        z
  }|dk(  r	||z
  |z  }n||z
  |z  }t        dt        t        ||z                    }||z  }|t        j                  z
  }|t        j                  k  r7d2d3| d4| d5|d6d7t        j                  d6d8|d6d9t        j                  d6d:fS y);zU
        Returns (rule, detail) if AI output should be rejected; None if OK.
        r   Nr   POST_VAL_RSIzAI approved with RSI r   z >= z for BUYr   z <= z	 for SELLr   r   POST_VAL_CONFzconfidence z% < z% floor (pattern confirmed)POST_VAL_CONF_NO_PATTERNz% floor (no reversal pattern)r   ry   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 [,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)rp   r   r   r   CONF_MIN_WITH_PATTERNCONF_MIN_WITHOUT_PATTERNr   cfg_fut
ASSETS_MAPr   maxroundCOMMISSION_PER_CONTRACT_USDTP_MIN_NET_PROFIT_USD)r   ru   r   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                           r^   r   zBrainMR._post_validate_  s    zz*% #"8"+C9D8IRT T3*;#;"+C9D9J8K9UW W L!45
11'%j\6K5L M4 56 6 442%j\6N5O P6 78 8 

#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   r`   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 )uW  
        Compute SL price + tick diagnostics from sl_atr_multiplier.

        Same shape as brain_tf._compute_sl_only (parity). TP variante γ:
        TP is finalized post-sizing by orchestrator via tp_resolver.

        Raises:
            KeyError if symbol unknown.
            ValueError if atr_m5_points missing or non-positive.
        r.  digitsr   ry   r   z-atr_m5_points missing or non-positive in techr   i'  r   r   r   r   sl_distance_pre_clamp   sl_distance_post_clampsl_ticks_pre_clampr   r   sl_max_ticksr   r   r   r   r   )r3  r4  r   r   r   r   r   SL_SAFETY_MULTr6  MIN_SL_TICKSrp   MAX_SL_TICKSr5  min)ru   r   r   r   r@  r.  rG  r   
atr_pointssl_distance_prer   sl_minsl_maxsl_ticks_postsl_distance_postr   r   r   s                     r^   r   zBrainMR._compute_sl_only  s)   " !!&)${+,	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%
 	
r`   c                >   |d   \  }}t        ||z   dz  d      }|j                  dd      }|j                  dd      }t        |j                        }t        |j                        }|j
                  }|j                  }|j                  }t        |j                        }|j                  }|j                  }t        |j                        }|j                  }t        |j                        }|j                  }t        |j                         }|j"                  }t%        |j&                        }t        |j(                        } |j*                  }!|dk(  xr	 |t,        k  xs |d	k(  xr	 |t.        kD  }"|t,        k  rd
}#n|t.        kD  rd}#nd}#t        t1        |dd      xs d      }$|$dkD  r:t2        j4                  j7                  |$t2        j8                  j:                        }%n7t2        j4                  j=                  t2        j8                  j:                        }%|%j?                  d      }&|%j@                  }'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k(  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 }/|jB                  r|/jE                  d'       |jF                  r|/jE                  d(       |jH                  r|/jE                  d)       |jJ                  r|/jE                  d*       |jL                  r|/jE                  d+       |jN                  r|/jE                  d,       |jP                  r|/jE                  d-       |jR                  r|/jE                  d.       |jT                  r#|/jE                  d/|jV                  xs d0 d1       |/rd2jY                  |/      nd3}0|jV                  xs d3}1|
rd4nd5}2|dk(  xr |	jZ                  d6k(  xs |d	k(  xr |	jZ                  d7k(  }3|3rd8}4n|	jZ                  d9v rd:}4nd;}4|dk(  xr |j\                  xs |d	k(  xr |j^                  }5|j`                  xs i }6|6j                  d<d=      }7|7r|6j                  d>d?      nd@}8|7r|6j                  dAd      dBnd?}9|6j                  dCd      }:|d"k\  rdD};n
|dEk\  rd;};ndF};t        |jb                        }<td        jf                  j                  | i       }=t%        |=j                  dGdH            }>ti        |'      }?tj        j                  | i       j                  |?tl              \  }@}A|A}Bt        |=j                  dIdJ      xs dJ      }Ct        t1        |dKdJ      xs dJ      }DCdkD  rDCz  ndJ}EBdLz  }Ft%        t        |E|Fz  dMz              }G| dNk(  r|<dkD  rdO|<z  ndJ}HdP|<dQdR|HdSdT}IndU}IdVdWdXdYdZd[d\d]d^d_d`
j                  | |  da      }Jd2jY                  |	jn                        xs db}Kd2jY                  |	jp                        xs db}Lt        t1        |dcdJ      xs dJ      }M|
rtr        ntt        }NdUjY                  g ddt,         det.         df|! dg| dh|( di|& dj|) dk| dl| dm|! dn| do|dpdq| dr|rdsndt du|* dv|  dw|+ dx| dy|<dz|> d{d||d}d~|dpd|# d|dpd|dpd|dz|> d{d|, d|d}d| dl| d| d|ddi|; d| d|. dzI d| d|"rdsndt dt,         dt.         d|0 d|1 d|2 d|	jZ                   d|	jv                  dpd|4 d| d| dK d| dL d|jx                  rdnd d|jx                   d| d|5rdsndt d|j\                   d|j^                   d|dd|- dtz         d| dd|rdsndt dtr         dtt         d|8 d|9 di|: d|d}d|ddl|; d|j|                   d|j~                   d| d|dkD  rdndt d|dkD  rd| dtr         dndU d|  d|j                  dd       d|j                  ddU       d|dSd|dSd|dSd|rd| dndU d|d|  d| ndU d|dSd|dSdÑ|dSdđ|dSdő|j                   dƑ|<dz|> d{dǑMdțdɑJ dʑ|  di|? dˑB d̑Ddz|> d{d͑EdțdΑFdțdϑG dБ|G dё|<dz|> d{dґ| dӑ|dz|> d{dԑ|d}dՑ|8 d֑|9 dב|( dؑ|) dّt,         dڑt.         dۑN dܑtr         dݑtt         dޑ|2 dߑ|dSd2|dSd|<dz|> d{d|<dz|> d{d|G d|G d|G dtz         d| d|dSd      S )u  
        V17 narrative entry prompt (Mean Reversion).

        MR è il complemento di TF: non cerca trend, cerca INVERSIONI dalla
        media quando il prezzo è in zona di estremo statistico (RSI < 32
        per BUY o > 68 per SELL) con segnali di esaurimento del momentum
        contrario.

        Espone TUTTI i campi del TechSnapshot, organizzati in sei sezioni:
          1. Contesto mercato (sessione/liquidità, regime, bias, news)
          2. Storia del prezzo (narrativa naturale del distacco dalla media)
          3. Segnali di inversione (RSI estremo, pattern reversal, PA, vol)
          4. Contesto strutturale (swing, EMA50 H1, anti-revenge MR)
          5. Profilo rischio (range SL, candle metadata, max_risk_mult cap)
          6. Domanda esplicita + criteri di approvazione

        Invarianti rispetto a V16:
          - Threshold confidence pattern-aware: {CONF_MIN_WITH_PATTERN}%
            con pattern reversal, {CONF_MIN_WITHOUT_PATTERN}% senza
          - SL profile range mapping (sl_atr_multiplier ∈ profile.sl_range)
          - max_risk_mult cap per asset (es. MGC=0.8)
          - atr_ratio cap MR (ATR_RATIO_CAP=1.8)
          - Re-entry post-SL: divergence OBBLIGATORIA + pattern + volume_weak

        V17 transitional bridge (parità con brain_tf):
          - JSON output mantiene il contratto V16 (`risk_multiplier`,
            `rr_multiplier` ∈ [0.17, 0.67]) — pipeline downstream
            (evaluate_entry / _post_validate / tp_resolver) NON cambia.
          - Aggiunto `tp_price_suggested` (livello TP assoluto basato su
            VWAP/EMA50/swing) accanto a `rr_multiplier`. Per ora viene
            loggato; downstream lo consumerà nei commit V17 successivi
            (margine conservativo 15% applicato in pipeline).
        r   rI  r[   r   r   r&   Nr   r   r   r   neutrar|   )tzz	%H:%M UTCrV   )ASIAbassarW   )EUROPAmedia   )zOVERLAP EU-USAalta   )USAr_  )zPOST-USAr[  uT   nessun evento HIGH a calendario imminente (filtro news in orchestrator già passato)r   rangingtrendingsoprasottosur"   pulitor$   normaledeboledecelerandoaccelerandor  r  r  r  r  r  r  r  doji(std), NESSUNOu   CONFIRMED ✅u
   ABSENT ❌r   r   favorr   r   adverseneutroswing_foundF
swing_typezN/AzNON TROVATOswing_pricez.5fswing_indexz	pro-trendg      ?zcontro-trendrG     r.  ry   r   r(   g333333?r6   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   z;S&P 500 micro: momentum forte, breakout, target swing high.z<Nasdaq micro: volatile, candele ampie, target livello tondo.u5   Dow micro: meno volatile di MNQ, swing più ordinato.z:Gold micro: spike-prone, range 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.)
r0   r1   r2   r3   r9   r4   r5   r8   r6   r7   z,: profile non dedicato, target conservativo.nessunor   u   Sei un sistema di Mean Reversion quantitativo. Non cerchi trend: cerchi
INVERSIONI dalla media quando il prezzo è in zona di estremo statistico
(RSI < z per BUY o > zG per SELL) con
segnali di esaurimento del momentum contrario. Bias H4: z, direzione
permessa: u|   . 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        : r   z
Vol regime    : z, Vol spike: SINOz
News          : u+   

═══ 2. STORIA DEL PREZZO ═══
u    è in regime z (struttura H1: z). Il prezzo
quota r   fu=    e si è allontanato dalla media —
deviazione da EMA50 H1: +.2fz%. RSI M5 ha raggiunto
z (zona z). RSI H1: z
. RSI H4: z.
VWAP intra-day: u    — il prezzo è z del VWAP
di z%. Struttura H1: z. H1 compatibility
con : r   z). Divergenza RSI/prezzo:
z. MACD: u~   

═══ 3. SEGNALI DI INVERSIONE ═══
Setup MR richiede ESTREMO + ESAURIMENTO MOMENTUM CONTRARIO:
  • RSI estremo (z): z0
                          (BUY oversold se rsi<z4;
                           SELL overbought se rsi>u!   )
  • Pattern candela attivi : u    
  • Doji type              : u    
  • Pattern reversal MR    : u   
                          (≥1 tra hammer/bull_engulfing/morning_star/
                           piercing/doji_bull per BUY; bearish per SELL)
  • PA dominante           :  (forza    x) —  a z!
                          FAVOR z#
                          ADVERSE u    
  • Volume                 : DEBOLENORMALE (volume_weak=u   )
                          (volumi calanti su candela contraria
                           = momentum in esaurimento)
  • Absorption pro z : z$
                          (BUY_ABS=z&,
                           SELL_ABS=u!   )
  • ATR ratio              : u   x → movimento z	 (cap MR u!   )
  • Candle strength        : u/   x (1.0 = media)
  • Vol spike              : uS   

REGOLA HARD pattern-aware:
  - Pattern CONFIRMED → threshold approval normale: u8   %
  - Pattern ABSENT    → threshold approval ALZATA : u&  %
                        (servono 2+ fattori robusti — es. RSI MOLTO
                         estremo + divergence forte; setup ambigui senza
                         conferma candela = "falling/rising knife" → REJECT)

═══ 4. CONTESTO STRUTTURALE ═══
Swing recente (lazy)   : z @ z) candele M5 fa)
EMA50 H1 deviazione    : z?% (>0.3% = vera distanza dalla media)
H1 compat              : z
H1 struttura           : bull=z, bear=z
SL consecutivi sessione: z (re-entry post-SL:    SÌ)
u   ⚠️ u    SL recenti: re-entry MR consentito SOLO con divergence OBBLIGATORIA + pattern reversal attivo + volume_weak. Mancanti → conf < z% (REJECT).u  

⚠️ Se h1_compat < 0.5 (against-trend MR):
   - RSI MOLTO estremo (<25 BUY o >75 SELL) → conf può essere alta (75%+)
   - Solo divergence + MACD decel → conf 65-70%
   - Altrimenti → conf < 60% (REJECT)
   # TODO(V18 09-mag): hard gate H1_COMPAT_TOO_LOW a 0.70 in
   # evaluate_entry rende unreachable tutte le linee guida h1_compat<0.5
   # nel prompt (qui + criterio approvazione 4 + criterio rifiuto su
   # h1_compat<0.5). Ripulire il prompt se il gate resta stabile.

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

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

═══ 5b. VINCOLO TEMPORALE TP ═══
Time-stop MR z, breakeven): 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'  . MR mira al rientro verso la
   media: se VWAP/EMA50/swing-opposto sono oltre questa soglia, NON li scegliere
   — il time-stop chiude prima che il prezzo torni a quel livello.

═══ 6. DOMANDA + TP TARGET ═══
Considerando il contesto di mercato (sez. 1), la storia del prezzo (sez. 2),
i segnali di inversione (sez. 3), il contesto strutturale (sez. 4) e il
profilo rischio (sez. 5):

  → Il prezzo si trova in una zona di estremo statistico con segnali di
    inversione confermati? Questo rappresenta un'opportunità di entrata
    u	   verso la media, oppure il momentum attuale suggerisce
    di aspettare?

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

  • `tp_price_suggested` (NEW V17): livello TP assoluto verso la media —
    target naturale MR è il VWAP z%, l'EMA50 H1
    (deviazione attuale z%), o lo swing opposto
     u  . Scegli il più vicino e ragionevole nelle
    condizioni attuali. 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 (MR — più conservativo di TF):
        60-69%:  0.17 – 0.25   (TP molto vicino, alta probabilità hit)
        70-74%:  0.25 – 0.40   (TP medio-basso)
        75-79%:  0.40 – 0.55   (TP medio)
        80-84%:  0.55 – 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.

═══ CRITERI APPROVAZIONE ═══
APPROVA se TUTTI:
  1) RSI M5 estremo (< z	 BUY o > zg SELL)
  2) Almeno 2 fattori tra: [divergenza, MACD decel, candle<0.8x, |dev|>0.3%]
  3) confidence >= z
%
     (= z% con pattern, u!   % senza — pattern attualmente: ua   )
  4) Se h1_compat < 0.5 → conf >= 65% strict (against-trend rule)
  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 − uy   ×tick_size)

RIFIUTA se UNO:
  - candle_strength > 1.8 (momentum troppo forte — rising/falling knife)
  - atr_ratio > u3   (gestito dal codice ma re-checka)
  - h1_compat < 0.5 E (no divergence O no MACD decel) → conf < 60%
  - consec_sl > 0 senza divergence + pattern + volume_weak

═══ REJECTION CODES (rule_failed quando approved=false) ═══
  - "RSI_NOT_EXTREME"     : RSI in zona neutra (no oversold/overbought)
  - "NO_PATTERN_LOW_CONF" : pattern absent E meno di 2 fattori robusti
  - "AGAINST_TREND_WEAK"  : h1_compat<0.5 senza divergence + MACD decel
  - "MOMENTUM_TOO_STRONG" : candle_strength > 1.8
  - "ATR_OUT_OF_RANGE"    : atr_ratio > cap
  - "RE_ENTRY_INCOMPLETE" : consec_sl > 0 senza divergence + pattern + volume_weak
  - "ABSORPTION_AGAINST"  : absorption avversa alla direction
  - "CONFIDENCE_FLOOR"    : conf sotto threshold (con/senza pattern)
  - "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 ═══
{
  "approved": true,
  "confidence": 75,
  "direction": "z4",
  "risk_multiplier": 1.0,
  "sl_atr_multiplier": u  ,
  "rr_multiplier": 0.40,
  "tp_price_suggested": 0.0,
  "tp_rationale": "max 25 parole — livello target tecnico + frazione $rischio",
  "key_risk": "rischio principale",
  "reason": "max 12 parole",
  "rejection_details": {"rule_failed": "NONE", "detail": "ok"}
}
)Ar6  rp   r   rsi_h1deviation_pctr   r   regime_reasonr   	h1_reasonvwapvwap_deviation_pct
divergencer   r   
vol_regime	vol_spiker   r   consecutive_sl_countcandle_strengthbiasr   r   r   _dtdatetimefromtimestamptimezoneutcnowstrftimehourr  appendr  r  r  r  r  r  r  doji	doji_typejoindominantbuy_absorptionsell_absorption
swing_datar   r3  r4  r_   rQ   MR_TIME_STOP_DEFAULTfavor_directionadverse_directionr1  r2  strengthvolume_weakr   h1_struct_bullh1_struct_bearopen)Oru   r   r   r   r   r   r   r   r   r   r   r   r<  r=  sl_midsl_floorr&   r  r  r   r   r  r  r  r  vwap_devr  r  r  r  tech_allowed	consec_slr  r  rsi_extremersi_zonectnow_dtnow_utc_strutc_hrsession_name	liquiditynews_contextregime_narrative	vwap_sideatr_quality
macd_statepattern_flagspattern_strdoji_type_strpattern_status
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_breakeven_min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_ageconf_thresholdsO                                                                                  r^   r   zBrainMR._build_entry_prompt  s>   d "*-(A-q1;;2OT: t{{#d001&&**$//0	NN	yy001__
$001
__
(	--112	 7 78 ~~ %:S?%: >& <S+<%< 	  !H$$#HH 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 	 )/)(;9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.
'++FB7;;,
= ,$((;4;<	gdOSAHSI6?!m	1-3!%(F(L"MN T>3?!3CC,.L7S7I J&s+ ,LM  M QQJO^QQFZA
 #f LM
N 	 IIe334A		ii 7 78EI74)=sCJsK
 &7!) 	
| |  | 	| &| '8%8|99| :>	|?	|
 )|
| | !| "-| .<| =F;|G| | | ,_|-| | /| 0<n|=| || | *| 3<$)F|G| ||" #|" 	#|" ((#|" )9#|" :@#|"A#|$ Am_A%&%|$'%|& 't,'|&-'|( S	)|( 
)|( 
)|( &)|( '-S\)|( 2<)|( =C3<)|(H)|* aa'(+|* );+|* <E++|*F+|, T?-|, $-|, %+8-|, ,1-|, 2;-|,<-|. K/|. /|. C/|. !#/|. $0./|.1/|0 1|0 1|0  L1|0 !"1|0 #01|011|8 ;9|8 "9|8 +6$4!@9|8A09|: 1@/@;|:A3;|< 4E2E=|<F =|> !,}?|>- ?|@ !.A|@/ A|B !//C|B0 C|H !&/I|H 08I|H 9>s7KI|H LSI|H T\R\I|H ]`I|H aj_jI|Hk!I|J "+K|J ,.K|J /8[K|J9#K|L $-+M|L .0M|L 1<}M|L= M|N -4,?,?YOO|N P^O|N _f^q^q]rO|NsO|T  [U|T !$U|T -8DT#BU|TC$U|V %)$7$7#8W|V9%W|X &*%9%9$:Y|X; Y|Z !*#[|Z /?[|Z @Km[|Z LU[|Z VcTc[|Zd [|\ !04]|\5 ]|^ )2t<_|^=7_|d 8M6Me|dN7e|f 8P6Pg|fQg|r "s|r #&s|r '3^s|r 46s|r 7>Ys|r?s|t (-u|t.u|v $Cw|v ).w|v /;^w|v<w|x  $223y|x 4;y|x <@;N;N:Oy|xPy|z ${|z %9{|z CLa-UY8Z{|z[{|| H  KL  L79+  X  Yn  Xo  oz  {  RT  U}||U}|T 8U|T "U|T #*++l3"?!@U|T ADU|T ELKKPVWYDZC[U|T\U|V $CLW|V ).W|V /6c]W|V ;BW|V CIW|VNW|X @H)(7;RPY|XQY|Z CPB[$VHB}o>acd[|Ze[|^ SM_|^"_|` CLa|`!a|b CLc|b!c|d CLe|d!e|j II;k|jk|l !=/ 23m|l4m|n s#o|n$o|p $$q|p%q|v Xw|v w|v #|w|v $2w|v 3F1Fw|vGw|x  -12y|x 3<y|x =I;My|xN.y|z />c-B{|zC{|~ //|~0;|B <O:OC|BPC|D Am_A-.E|D/E|Z K[|Z#[|f $(-'9":g|f;g|h 't,i|h-i|j Ik|j k|j nk|j/k|N 0<nO|N=O|P Q|PQ|Z (([|Z )2[|Z 3D1D[|ZE[|^ ##_|^$	_|` 
a|`  /a|` 0H.Ha|` Ija|` kyiya|`za|d #3<e|d (*e|d +2#e|d7e|j !=/ 23k|j4k|l "!M?!!34m|l53m|n 4G2Go|nH#o|p $7"7q|p8'q|r (;&;s|r<s|z {|z {|d e|de|h s|i|h$i| |	r`   c                h   K   | j                  |       d {   }| j                  ||       |S 7 wrd   )_manage_exit_logic_emit_manage_decision_log)rk   ctxr   s      r^   manage_exitzBrainMR.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	d||d	
      S |t(        v }|t*        z   }|r|	|k\  r|dk  rt-        |j.                        }|j0                  }|dk  xr ||kD  xs |dkD  xr ||k  }d|cxk  xr dk  nc }|r%|r#|	|k  r|dk  r@| j'                  d|dddi
      S |	|k\  r"| j'                  d|	dd| d| dd||d
      S |dk  rK|	|k\  rF|xr |	|k\  xr |	|k  xr d|cxk  xr dk  nc }|s"| j'                  d|	dd| d| dd||d
      S | j3                  ||      }|t4        kD  rt-        |j6                        }t-        t9        |dd      xs d      }t;        |j<                  |j>                  z
        }t@        |z  }|dkD  ri||tB        z  kD  r]|r||z
  n||z   }| jE                  |t-        |jF                              }| jI                  |d|dd||z  dd d!t@        ||||d!d"#      S t-        |j.                        }|xr	 |tJ        k\  xs | xr	 |tL        k  }|rz|dkD  ru|tN        kD  rl|jP                  s`| jE                  |j<                  t-        |jF                              }tS        tT        jV                  j                  d$|dd%d&d'|d'|d()      S |tX        k\  rk|jZ                  s_| jE                  |j<                  t-        |jF                              }tS        tT        jV                  j                  d*|dd+d,d'||d-)      S t-        t9        |d.d      xs d      }|r$||j\                  k  r| j_                  d/dd0i
      S ta        |      }tc        ||      } | je                  ||||	      }!|xr  ||j0                  kD  xr |j0                  dk  xs% | xr  ||j0                  k  xr |j0                  dkD  }| jg                  ||| |||!||1      }"| jh                  jk                  |"d2d34       d5{   }#|#jl                  .| j_                  d6|#jn                   d7d8|#jn                  d9
      S | jq                  |#jl                        }$|$rd:|$vr| j_                  d;dd<i
      S d=d>||r|nd5||d?}%ts        |$j#                  d:            r/| j'                  tu        |$j#                  d@dA            d5dB |%
      S ts        |$j#                  dC            rHtS        tT        jV                  j                  tu        |$j#                  d@dD            d5dB i |%ddEi)      S tS        tT        jv                  j                  tu        |$j#                  d@dF            d5dB |%)      S 7 ow)GuB  
        MR exit management. V15 flow:

          1. Time stop (deep loss / breakeven failed) -> EXIT
          2. Grace period for indices (+15min if break-even & toward mean)
          3. Trailing emergency (progress > 30%, TP large) -> MOVE_SL trailing
          4. RSI50 cross + P&L>0 + progress>15% -> PARTIAL_50 + set_be
          5. Auto partial 50% + SL→BE at progress >= 50% -> PARTIAL_50
          6. Same-candle dedup -> HOLD without AI call
          7. AI exit per-candle (default HOLD)
          8. Default reason "stessa candela — AI già valutata"

        Brain does NOT mutate runtime. last_exit_eval_time is signalled
        via BrainDecision.metadata["evaluated_candle_time"].
        rsi50_partial_done is signalled via metadata when emitted, so
        the orchestrator can flip it on TradeRuntime.
        iu   Time Stop MR — r'  zm/z	m, loss $r{  rn  time_stop_deep)triggersessiondeep_threshold)r   r   r   r   r   
   iu$   Grace Period aborted — deep loss $r  grace_aborted_deep_lossu   Grace Period expired — zm (grace_expired)r  r  grace_limitzm BE failed (time_stop_be_failed)r  r  breakeven_thresholdr   ry   u   Trailing MR — progress z% (TP largo r   u   × ATR)trailing)trailing_atr_multatr_usedprogress_pcttp_distanceraw_sl_pricer  )r   r   targetextra_metadatazRSI50 crossing (u   ) — partial 50% + BErsi50_crossT)r  set_be_after_partialbe_pricersi50_partial_doner  )actionr   r   zTP u   % — partial auto MR + SL→BEauto_partial_50)r  r  r  r  r|   u#   stessa candela — AI già valutatadedup)r  r   r   progresstoward_meanregime_alertr  r  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 exitrC   partial_closez
AI partial
ai_partialzAI hold)<entryruntimetech_nowru   r   r   r   valuenet_profit_usdminutes_openr  r  r  UTCr  r_   rQ   rp   r  _exitr   GRACE_INDICES_EXTRA_MINr   r   rsi_m5_at_entry_compute_progress_pctTRAILING_PROGRESS_THRESHOLD_PCTr   r   absr   r   TRAILING_ATR_MULTTRAILING_TP_DISTANCE_MULT_round_to_tickr.  _move_slRSI_BUY_REACHED_MEANRSI_SELL_REACHED_MEANRSI50_PARTIAL_MIN_PROGRESS_PCTr  r   r   
PARTIAL_50AUTO_PARTIAL_PROGRESS_PCTpartial_donelast_exit_eval_time_holdr   r   _regime_alert_build_exit_promptrg   r   r   r   r   r   r   HOLD)&rk   r  r  rtr   ru   r   is_long
net_profitr  r]   r  r  r  symbol_in_indicesr  rsi_now	rsi_entryr  is_break_evenin_gracer  current_priceatrr  trailing_disttrailing_sl_rawtrailing_slreached_meanr  r|   r   r   r  r  r  r   metas&                                         r^   r  zBrainMR._manage_exit_logic  s    $ 		[[||OO	y}}222&&
<<##CGG,11#H-.:.>.>B/

#g+
, 	,+
  >::+L+=R?O P!!+C 07)1>%5',:<    #o5$'>>,."@NDHHoG--IR7Gi$7 9R7Gi$7   :33M1K#::!EjQTEUV"+-F!G &  
 ,zz7+C0;-s7)1N)8W-8: "   >l.AA " , N2, ;., :++	  zz/S/ADWCX Y**1!5)>)05HJ "   --eT: 55!$**-Mos;BsCCe//%..@AK-3MaK-:S*SSDK==#@(5(E  "11#U4>>%: }}(7~ F))4S(=WF%->$'(0'2(7#-$ %  " /8$88 Ak?w*?? 	 Z!^==-- **!!5#8H !"--33*73-7MN,,0 (*.$,
 
  00**!!5#8H !"--33XcN*IJ0,0 ($,		 	 GD-;@qA;"*@*@@::<#W-    %T*),))%wMW5#8#88WU=R=RUW=W _k]w)>)>>]5CXCX[]C] 	
 ((WE;%#W	 ) 
 WW--s- . 
 
 99::#DOO#44FG%/tO    $$TYY/61::;#^4    %4?[T$&
 

:&'::6::h	:;DSA    

?+, "--336::h=>tD:D:)\: 
 ##))vzz(I67=
 	
E
s   TZ Y=E/Z c                    | j                   }| j                  }t        |j                        }|r||k(  ry| j                  t
        j                  j                  k(  r||z
  ||z
  z  dz  S ||z
  ||z
  z  dz  S )zProgress toward TP, in %.ry   g      Y@)r   r   r   r   r   r   r   r  )r  r   eptpr   s        r^   r  zBrainMR._compute_progress_pct  sx     ^^djj!R2X??imm111BJ27+e33U
rBw'%//r`   c           	        | j                   }|j                  }| j                  }|j                  }d}|dk\  r5|r|dk(  r.|dk(  r)dt	        |      v rd}n|dk(  r|dk(  rdt	        |      v rd}|rd| d	| d
| d	| d	S ||k7  r	d| d
| dS y)zAV15 regime-flip detection (only RANGING -> TRENDING after grace).Fr   TRENDINGr   r   Tr   u'   🚨 REGIME CAMBIATO CONTRO POSIZIONE: /z -> u'   . CHIUDI — presupposto MR invalidato.u   ⚠️ Struttura H1 cambiata (u!   ) — valuta se inversione reale.u;   ✅ Struttura invariata — condizioni MR originali valide.)regime_at_entryr   market_structure_at_entryr   r   )	r  r   r%  r  regime_entry
regime_nowstruct_entry
struct_nowregime_flippeds	            r^   r!  zBrainMR._regime_alert  s     ,,[[
66**
1*,1J%Z8%)N*,1J%Z8%)N=#nAl^4
|1ZL Q<= > %4\N$zl S6 7 8Lr`   c                z   | j                   }| j                  }	| j                  }
|j                  t        j
                  j                  k(  }|rdnd}t        |
j                        }t        |
j                        }t        |
j                        }|j                  }|j                  }|j                  }|rdnd}|xr |dk  xs
 | xr |dkD  }|rd|dd	|d
z
  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%                  |j(                        xs d"}g } |
j*                  r| j-                  d#       |
j.                  r| j-                  d$       |
j0                  r| j-                  d%       |
j2                  r| j-                  d&       |
j4                  r| j-                  d'       |
j6                  r| j-                  d(       |
j8                  r| j-                  d)       |
j:                  r| j-                  d*       |
j<                  r#| j-                  d+|
j>                  xs d, d-       | rd!j%                  |       nd.}!d/}"|j@                  rVt        |
jB                        }#|r |#|jD                  z
  |j@                  z  d0z  }"n|jD                  |#z
  |j@                  z  d0z  }"tF        jH                  jK                  |jL                  i       }$tO        |$jK                  d1d
            }%dj%                  g d2|jL                   d3| d4|	jP                  dd5|j@                  d6|% d7d8|jD                  d6|% d7d9|"d:d;|jR                  d6|% d7d<|jT                   d=|dd>| d?|dd@|jV                   dA|jX                   dB|rdCndD dE|	jZ                  dFdG|ddH|	jP                  ddI| dJ|ddK|
jB                  d6|% d7dL|ddM|dd||z
  ddN|ddM|dd||z
  ddO|ddM|dd||z
  ddP| dQ|rdRndS dT|
j\                   dU|jV                   dV|
j^                   dW|jX                   dX| dY|
j`                  dFdZ|
jb                   d[|
jd                  rd\ndD d]|
jf                  rd^nd_ d`|
jh                   da|j                   db|jj                  ddc| dd| de|jl                  ddf|jn                  ddg|dhdi| dj|dhdk| dl|jp                  rdmndn do|jp                   dp| dk|rd\ndD dq|
j                    dr|
j"                   ds|jr                  dFdt|! du|
jt                  d6|% d7dv|d:dw| dx| dy|ddz|	jZ                  dFd{|dd||jT                   d}|rd~nd d      S )uU  
        V17 narrative anti-hallucination exit prompt (MR).

        Default conservativo = HOLD (V15 philosophy preservata). Quattro
        sezioni narrative:
          1. Contesto entry originale (snapshot al fill, zona estrema RSI)
          2. Situazione attuale (P&L, progress vs TP, RSI multi-TF entry→ora,
             toward_mean, struttura/regime now vs entry, ATR, MACD,
             divergenza, sessione + grace_limit)
          3. Price action attuale (PA dominant, favor/adverse, volume,
             absorption, candle strength, pattern attivi, VWAP + distanza
             target)
          4. Domanda rigida + regole anti-allucinazione (3-action output)

        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 difensivo richiede ALMENO 1 cambiamento NUOVO (regime
            cambiato O struttura invertita); single-signal exits rifiutati
          - PARTIAL_50 richiede progress > 50% E segnali di esaurimento

        Specifici V16 preservati:
          - regime_alert (V15 RANGING→TRENDING-against-position detection)
          - deep_discount H4 paradox → h4_rule dedicato in sez. 2
          - VWAP target_reached flag → labellato in sez. 3
          - Grace period for indices (grace_limit visibile in sez. 2)
          - toward_mean signal preserved (anti-allucinazione: domanda rigida)

        Output JSON invariato:
          {"exit_now": bool, "partial_close": bool, "reason": str}.
        LONGSHORTr   r   r   rB   u   ⚠️ DEEP DISCOUNT (H4 entry r   zh): NON usare livello assoluto come motivo exit. Solo se H4 era migliorato e ora ricaduto, o sceso sotto ry  r'  z (LONG) / salito sopra z	 (SHORT).r   r  u;    ⚠️ Peggioramento H4 — valuta inversione strutturale.r  zRSI H4: entry u	    → ora r{  z+.1fz).g?gzVWAP target raggiunto/superatoznon ancora a targetr   r   rq  rr  rs  rt  ro  rz  r  r  r  r  r  r  r  r  rl  rm  rn  rp  ry   r   rG  u   Sei un gestore di posizioni Mean Reversion. Decidi FULL EXIT, PARTIAL_50
o HOLD. 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 r   r~  z, SL z
(distanza dal prezzo attuale r  z%), TP z.
Confidence: z%. RSI M5 entry: z2
(zona estrema MR). Setup: mean reversion da zona z.
RSI H4 entry: z. Struttura H1 al fill:
z. Regime al fill: z.
Deep Discount: r  r}  u?   .

═══ 2. SITUAZIONE ATTUALE ═══
P&L netto      : $r   z
Progress vs TP : z%
Tempo aperto   : zm  (sessione z, grace_limit zm)
Prezzo attuale : u&   

RSI multi-TF (entry → ora):
  M5: r0  z)
  H1: z)
  H4: r  z6
toward_mean (prezzo si sta avvicinando alla media?): u   SI — reversion in corsou   NO — allontanamento o stalloz

Struttura H1 ora    : z
Struttura H1 entry  : z
Regime ora          : z
Regime entry        : 
z

ATR Ratio  : zx
Vol Regime : z
Vol Spike  : r|  z
MACD       : rj  rk  z
Divergenza : uB   

═══ 3. PRICE ACTION ATTUALE ═══
PA dominante      : r  r  r  z
  Bullish/Bearish : z / z	
  FAVOR 5z  : z
  ADVERSE r  z
Volume            : r  r  r  z)
Absorption pro z
                    (BUY_ABS=z, SELL_ABS=z)
Candle Strength   : z$x (1.0 = media)
Pattern attivi    : z

VWAP intra-day    : z
VWAP deviation    : u   % — u   

═══ 4. DOMANDA RIGIDA — ANTI-ALLUCINAZIONE MR ═══
Il prezzo sta tornando verso la media come previsto? Basandoti SOLO sui
dati: toward_mean=z, progress=z%,
P&L=$u  .

EXIT difensivo solo se il regime è cambiato O la struttura si è invertita
contro il trade. PARTIAL_50 se progress > 50% e segnali di esaurimento.
HOLD se il trade è ancora nella direzione attesa. Non ipotizzare — usa
SOLO i dati forniti.

Esempi di trigger oggettivi citabili dal contesto sopra:
  • EXIT difensivo (richiede ALMENO 1 cambiamento NUOVO):
    - regime_alert con 🚨 REGIME CAMBIATO CONTRO POSIZIONE (sez. 2)
    - struttura H1 invertita CONTRO la direzione (sez. 2)
    - candela gigante contro (candle_strength > 2.5x) + vol_spike (sez. 3)
    - divergenza contro + MACD accelerando contro + struct H1 invertita (tutti)
    - toward_mean=NO E tempo aperto > grace_limit (u  m) (sez. 2)
  • EXIT profitto (mean-reversion completata):
    - RSI M5 ha superato 50 E P&L > 0 E progress > 40% (sez. 2)
    - VWAP target raggiunto E P&L > 0 E progress > 40% (sez. 2 + 3)
    - progress > 75% (sez. 2)
    - P&L > 0 E toward_mean INVERTITO da SI a NO (sez. 2)
  • PARTIAL_50 (progress consolidato + esaurimento):
    - progress > 50% E almeno 1 segnale esaurimento (volume_weak,
      candle_strength < 0.8x, divergenza contro entry direction)

REGOLE OPERATIVE:
  • Rispondi SOLO con i dati forniti — non inventare livelli, swing,
    pattern non elencati, né target ipotetici
  • Se incerto → HOLD (default conservativo)
  • EXIT difensivo richiede ALMENO 1 cambiamento NUOVO rispetto all'entry
  • Single-signal exits sono RIFIUTATI a priori (es. "RSI estremo" da solo,
    "VWAP contro" da solo, "struct invertita se era già così" → HOLD)
  • Setup era valido all'entry (conf u/   %) — chiudi
    SOLO per qualcosa di NUOVO
  uM   • Deep discount: NON usare livello H4 assoluto, applica solo h4_rule sez. 2u	  
  • exit_now e partial_close NON possono essere entrambi true

═══ OUTPUT (SOLO JSON) ═══
{
  "exit_now": false,
  "partial_close": false,
  "reason": "max 12 parole — cita dati specifici (es. 'regime flip + struct invertita + adverse PA 1.8x')"
}
);r  r	  r
  r   r   r   r  r   r   r  r   r  rsi_h1_at_entryrsi_h4_at_entryr  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r   r   r3  r4  rp   ru   r   r  r   confidence_at_entryr:  r9  r  r   r   r   r  r  r   r  r  bullish_scorebearish_scorer  r  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rsi_zone_at_entrydeep_discounth4_ruledeltawarnr  vwap_target_reached
vwap_labelr  r  r  r  r  r  r  sl_dist_pctr   r@  rG  s&                                         r^   r"  zBrainMR._build_exit_prompt  so   X 		[[||//Y]]%8%88&VG
 488_
4;;'
4;;'
,,,,,,
 +2J| 0|b0 2k0|b0 	 1,s1C D11=a0D E  ,Qs39>  -ED53;T52:T c 2)Js;K L$<r$)  001-x#~ 0k.x$ 	
 1D,& 	 :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 $**%E$u~~59J9JJSP$~~59J9JJSP !!%%ellB7TXXh*+b b  b b b !\b "*b +-//#)>b?b 6(!$b %*b +0..6(!)DbEb *$/b 07b 8=~~axq[6QbRb &&'b (9b :Fc8JbK2b 3D1DbEb C b!b    !b "4b 5:4I4I3JbKb 'D1b2b  $$S)!b *!b" 3#b" #b$ //#&%b$ '4%b$ 5<9%b$ =K%b$ LWWZJ[%b$\%b& **QvhaK('b&)'b, C-b, -b, )--b, .0-b, 1;\0I$/O-b,P-b. C/b. /b. )-/b. .0/b. 1;\0I$/O/b.P/b0 C1b0 1b0 )-1b0 .01b0 1;\0I$/O1b0P1b2 		3b2
63b4 Va6Q  gG  6H5b4H5b8 ,,-9b8.9b: 667;b:8;b< {{m=b<$=b> ,,-?b>.?b@ Ab@AbD nnS!EbD"EbF ooGbFGbH nnd$/IbH0IbJ  $55m=IKbJJKbL ooMbLMbR ^^$SbR %-SbR .3^^C,@SbR AHSbR IQzSbR RUSbR V`T`SbRaSbT ((-UbT .1UbT 271D1DS0IUbTJ	UbV 
AWbV WbV %+WbV&WbX a.YbX YbX '-YbX(YbZ ")!4!4X)D[bZ ES[bZ T[SfSfRg[bZh[b\ |]b\ ]b\ '2dt<]b\=]b^ #112_b^ 3>_b^ ?C>R>R=S_b^T_b` ,,S1ab`2abb !Mcbb"cbf YYqk*gbf+gbh dOibh $*ibh +5ibh6ibp -qbp  +qbp ,4C.qbp9qbr 	sbr4sbL 5@3DMbLE(Mbn ).(A(A'BobnCobr WdRiklsbr	msb b	r`   c                ~    	 t        j                  t        |             S # t         j                  t        f$ r Y y w xY wrd   )jsonloadsr   JSONDecodeError	TypeError)r   s    r^   r   zBrainMR._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   V18 12-mag — `tech` opzionale: arricchisce l'evento con i campi
        RADAR (rsi_m5/rsi_h4/h1_compat/macd_*/pattern/atr_ratio/bias/...).
        Eventuali `fields` espliciti hanno precedenza sui campi auto-derivati.
        Nr   )ru   r   r   r   r   z[MR reject] r  r  z fields=z"[MR reject] %s %s %s: %s fields=%s)entry_rejected)	r	   rh   	brain_logwriteAttributeErrorrt   inforr   debug)rk   ru   r   r   r   r   fieldsmerged_fieldss           r^   r   zBrainMR._reject  s     <?40;F;;;"+%%++$!'! $& 	 JJ4	4  " ""''"6(!I;avRx H+_. s   -A& &=B&%B&rd   )rm   r
   returnNone)ru   r   rg  r:   )ru   r   r   r:   rz   r   rg  r   )r   r   r   r   rg  r   )r   r:   ru   r   r   r   r   r   r   r   r   r:   r   r   r   r   rg  zOptional[tuple[str, str]])
ru   r   r   r   r   r:   r   r   rg  r:   )ru   r   r   r   r   r   r   r   r   r   r   r   r   r:   r   r   r   r   r   r   r   r:   rg  r   )r  r   rg  r   )r   r:   rg  r   )r   r:   r%  r   r  r   rg  r   )r  r   r   r   r   r   r  r   r  r   r  r   r  r   r  r   rg  r   )r   r   rg  zOptional[dict])
ru   r   r   r   r   r   r   r   rg  rh  )__name__
__module____qualname____doc__r   r   r  namerf   rx   r  staticmethodr   r   r   r   r  r  r  r!  r"  r   r   __classcell__)rn   s   @r^   rb   rb      s   & <<D7. '*j
j
 j
 $j
 
j
`	 # #* lll l 	l
 l l  l l 
#l ld ?
?
?
 ?
 	?

 
?
 ?
J ii i 	i
 i i i i i i  i i 
i i^
g
Z 	0 	0 M M> qq q 	q
 q q q q q 
q qn   $$ $ 	$
 $ 
$r`   rb   )r]   r   rg  r   );rl  
__future__r   r  r  rZ  loggingtypingr   analysis.price_actionr   r   r   r   analysis.tech_snapshotr	   brain.ai_clientr
   r   brain.brain_baser   corer   r3  core.contractsr   r   r   r   r   r   r   trading.tp_resolverr   	getLoggerrr   r;   __annotations__r=   rQ   r  r   r   r   r1  r2  r  	frozensetINDICI_FUTURESr   r  r  r  r  r  r  r  r_   rb   r\   r`   r^   <module>r~     s  4 #      3 @ & *   A w$6 & R	 ( S	 &Q	 $!? $!> $!? &!;	 $!V $.= $+So< 4 <~ ]  YIyYXYIyYXYIyYXYIyYXYIyYX  iY 	iYiY 	iYiY 	iY  iY 	iYiY 	iY-d 2          G223 #'    ! !%    ai ar`   