
    =_jH                        d Z ddlmZ ddlZddlmZ ddlZddlZ	h dZ
h dZd Zd Zdd	ZdddZedk(  r=ddlmZ  e       ZdD ]*  Z eeed
      Z ee ded   dded    ded    d       , yy)uD  
Charter Market Regime Classifier - v1 Mavis 2026-07-20.
Classifica il regime di mercato corrente per un symbol, adattato da SQW-023.

Regimi (in ordine di priorità):
- BREAKOUT_UP / BREAKOUT_DOWN: ADX > 30 + directional > 25
- STRONG_BULL_TREND / STRONG_BEAR_TREND: ADX > 32 + directional
- BULL_TREND / BEAR_TREND: ADX 22-32
- VOLATILITY_EXPANSION: ATR ratio > 1.35
- COMPRESSION: BB width < 20mo percentile
- SIDEWAYS: tutto il resto (= CHOP)

Uso: from charter_core.market_regime import classify_regime
      regime = classify_regime(bybit_client, "BTCUSDT", timeframe="60")
    )annotationsN)Path>   
BEAR_TREND
BULL_TRENDBREAKOUT_UPBREAKOUT_DOWNSTRONG_BEAR_TRENDSTRONG_BULL_TRENDVOLATILITY_EXPANSION>   SIDEWAYS
TRANSITIONCOMPRESSIONINSUFFICIENT_DATAc                D    | j                  |d      j                         S )NF)spanadjustewmmeanseriesperiods     //opt/charter-live/charter_core/market_regime.py_emar   !   s    ::6%:05577    c                L    | j                  d|z  d|      j                         S )N      ?F)alphar   min_periodsr   r   s     r   _wilder_smoothr    %   s$    ::C&LF:KPPRRr   c                   | d   }| d   }| d   }|j                  d      }t        j                  ||z
  ||z
  j                         ||z
  j                         gd      j	                  d      }|j                         }|j                          }t        j                  t        j                  ||kD  |dkD  z  |d      | j                        }	t        j                  t        j                  ||kD  |dkD  z  |d      | j                        }
t        ||      }d	t        |	|      z  |j                  dt        j                        z  }d	t        |
|      z  |j                  dt        j                        z  }d	||z
  j                         z  ||z   j                  dt        j                        z  }t        ||      }|||fS )
Nhighlowclose   axisr           )indexd   )shiftpdconcatabsmaxdiffSeriesnpwherer)   r    replacenan)dfr   r"   r#   r$   
prev_closetrup_move	down_moveplus_dmminus_dmatr_wplus_diminus_didxadxs                   r   _adxrB   )   s   f:DRYs7QJ			
	!	z	  	
 ss{	 
 iikGIii'I"5'A+!FQTU]_]e]efGyy9w#69q="I9VYZbdbjbjkH2v&EN7F33emmArvv6NNG^Hf55a8PPH	("'')	)Wx-?,H,HBFF,S	SB
V
$C!!r   60c           
        	 | j                  |||      }|rt        |      dk  rddd|rt        |      nd d	dS t        j                  |g d
      }t        j
                  |d   dd      |d<   |j                  d      j                  d      }t        |d      \  }}}	||d<   ||d<   |	|d<   |d   }
|d   }|d   }|j                  d      }t        j                  |
|z
  |
|z
  j                         ||z
  j                         gd      j                  d      }t        |d      |d<   |d   j                  d      j                         |d<   |d   |d   z  |d<   |j                  d      j!                         }|j                  d      j#                  d      }|d|z  z   |d|z  z
  z
  |z  |d<   |d   j                  d d!"      j%                  d#      |d$<   |j&                  d%   }t        j(                  |d         st+        |d         ndt        j(                  |d         st+        |d         ndt        j(                  |d         st+        |d         ndt+        |d         t        j(                  |d         st+        |d         nd&t        j(                  |d         st+        |d         nd't        j(                  |d$         st+        |d$         nd'd(}d}d)}|d   ddd*|d   |d   |d   d+S |d   d,kD  r|d   |d   |d   d-kD  r||d   dk  rtd.|j,                  v r@t        j(                  |d.   j&                  d%         st+        |d.   j&                  d%         nd}|d   |kD  rd/nd0}d1|d   d2d3|d   d2d4|d   d2d5}|dk(  r!|d   d6kD  r|d   |d   kD  rd7nd8}d1|d   d2d9}|dk(  r!|d   d:kD  r|d   |d   kD  rd;nd<}d1|d   d2d=}|dk(  r|d   d>kD  rd?}d@|d   dAdB}|dk(  r|d   |d$   k  rdC}dD|d   dEdF|d$   dEdG}|dk(  rdH}d1|d   d2dI}|t.        v }||||d   |d   |d   |d   dJS # t        $ r}ddd| dcY d}~S d}~ww xY w)KzClassifica il regime corrente per un symbol.
    Ritorna dict {"regime": str, "adx": float, "atr_ratio": float, "bb_width": float, "is_chop": bool, "reason": str}
    r   Tzfetch_ohlcv error: )regimeis_chopreasonNP   zklines insufficienti (r   ))tsopenr"   r#   r$   volume)columnsrJ   ms)unitutc   rA   r>   r?   r"   r#   r$   r%   r&   atr*   atr_median_42	atr_ratio   )ddof   bb_widthx   (   )r   g?bb_width_q20r   r(   )rA   r>   r?   r$   rU   rY   r\    zADX None)rE   rF   rG   rA   rU   rY         ema_50r   r   zADX=z.1fz > 30, plus_di=z > 25, minus_di=z < 20    r
   r	   z > 32 (trend forte)   r   r   z 22-32 (trend)g?r   z
ATR ratio=z.2fz > 1.35 (volatile)r   z	BB width=z.4fz < q20=z (compression)r   z < 22 (chop))rE   rF   rG   rA   rU   rY   r$   )fetch_ohlcv	Exceptionlenr,   	DataFrameto_datetimesort_values	set_indexrB   r+   r-   r.   r/   r    rollingmedianr   stdquantileilocisnafloatrM   CHOP_REGIMES)bybit_clientsymbol	timeframelimitklineser6   rA   r>   r?   r"   r#   r$   r7   r8   bb_midbb_sdrowcurrE   rG   
ema_50_valrF   s                          r   classify_regimer~   =   sf   e))&)UC S[2%-$Lbrxcfgmcn~  cA  AB  KC  D  	D	f&V	WB~~bhTt<BtH			'	'	-B!"b\C(BuIByMBzN f:DRYs7QJ	TCZ4*#4"9"9";cJ>N=S=S=UV]^	_	c	cij	c	kBr2&BuIU)++B/668Bi"_"55B{O ]]2##%FMM"!!q!)Eq5y(FQY,>?6IBzNJ///DMMdSB~ ''"+C(*E
(;uSZ 02I0G5Y(T24''#j/2JE#j/*PTs7|$46GGC<L4MU3{+,SV24''#j/2JE#j/*PS:<''#nBU:Vc.12\_C !FF
5z-$*5zK0@cR\o_ 	_ 5zB3y>5#j/:Uy>B3z?R#79ARZZ9OXZX_X_`bck`l`q`qrt`uXvr(|0045|}J&)'lZ&?]_FCJs+?3y>#:NN^_bcm_nor^ssxyF$$Ub(+IZ(H$NaE
3'':;$$Ub!$Y#j/!A|E
3'~6$$[)9D)@'c+.s33EF$$Z3~;N)NS_S1^9LS8QQ_`$$E
3'|4$G5z%
OW Y  e-$L_`a_bJcddes   Q 	Q/Q*$Q/*Q/__main__)BybitDemoClient)BTCUSDTETHUSDTSOLUSDTZECUSDTDASHUSDTWIFUSDTz	: regime=rE   z<25z chop=rF   z (rG   rI   )rQ   )rC      )rt   strru   r   rv   intreturndict)__doc__
__future__r   syspathlibr   numpyr2   pandasr,   TRADABLE_REGIMESrr   r   r    rB   r~   __name__bybit_demo_clientr   csymrprint r   r   <module>r      s    # 
     N8S"(Zz z1AR VAsD)Yq{3/va	l^2ak]RSTUV r   