
    ^jl/              
          d Z ddlZddlmc mZ ddlZddlm	Z	 ej                  j                  d e e	e      j                         j                  j                               ddlZddlmZ ddlmZmZmZmZmZ deddfdZd	 Zd
 Zd Zd Zd Zd Z d Z!ejD                  jG                  dddiddiddiddiddiddig      d        Z$d Z%d Z&g dZ'ejD                  jG                  de'      d        Z(d Z)d Z*d Z+d  Z,d! Z-ddiddiddiddiddiddigZ.de/fd"Z0e1d#k(  r ejd                   e0              yy)$u  
Unit tests for trading/tp_resolver.py.

Covers:
  - Basic BUY/SELL math (rr_multiplier × sl_ticks × tick_size).
  - MIN_TP_TICKS floor.
  - Hard clamp on rr_multiplier ([RR_MULT_MIN, RR_MULT_MAX]).
  - "contracts cancels" property (algebraic invariant).
  - Validation raises on bad inputs.
  - Asset-class smoke (FX, equity index, metal, energy).

Run via pytest:
    pytest tests/test_tp_resolver.py
Or standalone (parity with other test_*.py runners):
    python3 tests/test_tp_resolver.py
    N)Path)config_futures)MAX_RR_EFFECTIVERR_MULT_MAXRR_MULT_MINTPResolutionresolve_tp_pricelabelreturnc                      t        d|         y )Nz  ok  )print)r
   s    -/home/work/apex_v16/tests/test_tp_resolver.py_okr   #   s    	F5'
    c            	         t        dddddd      } t        | t              }|sdd	t        j                         v st        j                  t              rt        j                  t              nd	d
t        j                         v st        j                  |       rt        j                  |       nd
dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            d}| j                  }d}||k(  }|st        j                  d|fd||f      d
t        j                         v st        j                  |       rt        j                  |       nd
t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }d}||k(  }|st        j                  d|fd||f      d
t        j                         v st        j                  |       rt        j                  |       nd
t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }t        j                  }d} ||      }	||	k(  }|st        j                  d|fd||	f      d
t        j                         v st        j                  |       rt        j                  |       nd
t        j                  |      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      t        j                  |	      dz  }
dd|
iz  }t        t        j                  |            dx}x}x}x}}	| j                   }t        j                  }d} ||      }	||	k(  }|st        j                  d|fd||	f      d
t        j                         v st        j                  |       rt        j                  |       nd
t        j                  |      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      t        j                  |	      dz  }
dd|
iz  }t        t        j                  |            dx}x}x}x}}	| j"                  }t        j                  }d} ||      }	||	k(  }|st        j                  d|fd||	f      d
t        j                         v st        j                  |       rt        j                  |       nd
t        j                  |      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      t        j                  |	      dz  }
dd|
iz  }t        t        j                  |            dx}x}x}x}}	| j$                  }t        j                  }d} ||      }	||	k(  }|st        j                  d|fd ||	f      d
t        j                         v st        j                  |       rt        j                  |       nd
t        j                  |      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      t        j                  |	      dz  }
dd|
iz  }t        t        j                  |            dx}x}x}x}}	| j&                  }d!}||u }|st        j                  d"|fd#||f      d
t        j                         v st        j                  |       rt        j                  |       nd
t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y)$zMES: tick_size=0.25, tick_value=1.25, sl_ticks=20, rr=0.50.
       tp_ticks = round(0.50 * 20) = 10; tp_distance = 10 * 0.25 = 2.5;
       tp_price = 5800 + 2.5 = 5802.50.MESBUY     @      ?      symbol	directionentry_pricerr_multiplier	contractssl_ticksz5assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
isinstanceresr   )py0py1py2py4N
   ==z6%(py2)s
{%(py2)s = %(py0)s.tp_ticks_final
} == %(py5)sr!   r#   py5assert %(py7)spy7g    @z0%(py2)s
{%(py2)s = %(py0)s.tp_price
} == %(py5)sg      @)zo%(py2)s
{%(py2)s = %(py0)s.tp_distance
} == %(py10)s
{%(py10)s = %(py6)s
{%(py6)s = %(py4)s.approx
}(%(py8)s)
}pytestr!   r#   r$   py6py8py10assert %(py12)spy12g      I@)zq%(py2)s
{%(py2)s = %(py0)s.sl_usd_actual
} == %(py10)s
{%(py10)s = %(py6)s
{%(py6)s = %(py4)s.approx
}(%(py8)s)
}g      9@)zq%(py2)s
{%(py2)s = %(py0)s.tp_usd_target
} == %(py10)s
{%(py10)s = %(py6)s
{%(py6)s = %(py4)s.approx
}(%(py8)s)
}zp%(py2)s
{%(py2)s = %(py0)s.rr_effective
} == %(py10)s
{%(py10)s = %(py6)s
{%(py6)s = %(py4)s.approx
}(%(py8)s)
}Fisz<%(py2)s
{%(py2)s = %(py0)s.min_tp_ticks_applied
} is %(py5)s)r	   r   r   @py_builtinslocals
@pytest_ar_should_repr_global_name	_safereprAssertionError_format_explanationtp_ticks_final_call_reprcomparetp_pricetp_distancer.   approxsl_usd_actualtp_usd_targetrr_effectivemin_tp_ticks_applied)r    @py_assert3@py_format5@py_assert1@py_assert4@py_format6@py_format8@py_assert5@py_assert7@py_assert9@py_format11@py_format13s               r   test_basic_buy_mesrT   +   s    $bC
 c<((((((((:(((:((((((c(((c((((((<(((<((((((((((############3###3#############<<"7"<7""""<7""""""3"""3"""<"""7"""""""??0fmm0C0mC00?00000?000000030003000?000000f000f000m000C0000000000033d3d 33 33333 333333333333333333333333333333d333 3333333333d3d 33 33333 333333333333333333333333333333d333 333333331v}}1S1}S1111111111111131113111111111v111v111}111S11111111111##,u,#u,,,,#u,,,,,,3,,,3,,,#,,,u,,,,,,,r   c                     t        dddddd      } | j                  }d}||k(  }|st        j                  d	|fd
||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )Nr   SELLr   r   r   r   r   g    @r&   r-   r    r)   r+   r,   )
r	   rB   r;   rA   r9   r:   r<   r=   r>   r?   r    rK   rL   rI   rM   rN   s         r   test_basic_sell_mesrX   ?   s    
$bC
 <<"7"<7""""<7""""""3"""3"""<"""7"""""""r   c            	         t        dddddd      } | j                  }d}||u }|st        j                  d	|fd
||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }t        j                  }d} ||      }||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      dt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            dx}x}x}x}}y)z@MES MIN_TP_TICKS=4. With sl_ticks=8, rr=0.20 -> raw=2 < floor 4.r   r   r   g?      r   Tr6   r8   r    r)   r+   r,   N   r&   r(   r   r5   r.   r/   r3   r4   )r	   rH   r;   rA   r9   r:   r<   r=   r>   r?   r@   rG   r.   rD   r    rK   rL   rI   rM   rN   rO   rP   rQ   rR   rS   s              r    test_min_tp_ticks_lifts_short_tpr^   L   s   
$aC
 ##+t+#t++++#t++++++3+++3+++#+++t+++++++""""""""""""3"""3"""""""""""""1v}}1S1}S1111111111111131113111111111v111v111}111S111111111111r   c                  D   t        dddddd      } | j                  }d}||u }|st        j                  d	|fd
||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y)z?sl_ticks=20, rr=0.50 -> raw=10 > MES floor 4. Floor not active.r   r   r   r   rZ   r   r   Fr6   r8   r    r)   r+   r,   Nr%   r&   r(   )r	   rH   r;   rA   r9   r:   r<   r=   r>   r?   r@   rW   s         r   %test_min_tp_ticks_inactive_when_abover`   Y   s   
$bC
 ##,u,#u,,,,#u,,,,,,3,,,3,,,#,,,u,,,,,,,############3###3#############r   c            	      6   t        dddddd      } | j                  }|t        k(  }|st        j                  d|fd	|t        f      d
t        j                         v st        j                  |       rt        j                  |       nd
t        j                  |      dt        j                         v st        j                  t              rt        j                  t              nddz  }dd|iz  }t        t        j                  |            dx}}| j                  }d}t        |z  }t        |      }||k(  }|sSt        j                  d|fd||f      d
t        j                         v st        j                  |       rt        j                  |       nd
t        j                  |      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}x}x}}y)zrr=0.95 -> clamped to 0.80.r   r   r   gffffff?rZ   r   r   r&   z:%(py2)s
{%(py2)s = %(py0)s.rr_multiplier_used
} == %(py4)sr    r   r!   r#   r$   assert %(py6)sr0   Nzb%(py2)s
{%(py2)s = %(py0)s.tp_ticks_final
} == %(py10)s
{%(py10)s = %(py4)s((%(py5)s * %(py7)s))
}roundr!   r#   r$   r*   r,   r2   r3   r4   )r	   rr_multiplier_usedr   r;   rA   r9   r:   r<   r=   r>   r?   r@   rf   )
r    rK   rI   rJ   @py_format7@py_assert6@py_assert8rQ   rR   rS   s
             r   test_hard_clamp_upperrl   h   st   
$bC
 !!0![0000![00000030003000!000000[000[00000008R8{R'78'7!88!88888!888888838883888888888888888888{888{888R888!888888888r   c                     t        dddddd      } | j                  }|t        k(  }|st        j                  d|fd	|t        f      d
t        j                         v st        j                  |       rt        j                  |       nd
t        j                  |      dt        j                         v st        j                  t              rt        j                  t              nddz  }dd|iz  }t        t        j                  |            dx}}| j                  }d}||k(  }|st        j                  d|fd||f      d
t        j                         v st        j                  |       rt        j                  |       nd
t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y)zrr=0.05 -> clamped to 0.10.r   r   r   g?rZ   r   r   r&   rb   r    r   rc   rd   r0   Nr\   r(   r)   r+   r,   )r	   rh   r   r;   rA   r9   r:   r<   r=   r>   r?   r@   )r    rK   rI   rJ   ri   rL   rM   rN   s           r   test_hard_clamp_lowerrn   s   s   
$bC
 !!0![0000![00000030003000!000000[000[0000000""""""""""""3"""3"""""""""""""r   c                  `	   t        dddddd      } t        dddddd      }| j                  }|j                  }||k(  }|st        j                  d	|fd
||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }|j                  }||k(  }|st        j                  d	|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}|j                  }d}| j                  }||z  }	||	k(  }|st        j                  d	|fd||	f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      dz  }
dd|
iz  }t        t        j                  |            dx}x}x}x}}	|j                  }d}| j                  }||z  }	||	k(  }|st        j                  d	|fd||	f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      dz  }
dd|
iz  }t        t        j                  |            dx}x}x}x}}	y)uB   tp_distance = rr × sl_ticks × tick_size  ⇒  contracts cancels.r   r   r   r   rZ   r   r   r%   r&   )zN%(py2)s
{%(py2)s = %(py0)s.tp_price
} == %(py6)s
{%(py6)s = %(py4)s.tp_price
}basebigger)r!   r#   r$   r0   zassert %(py8)sr1   N)zZ%(py2)s
{%(py2)s = %(py0)s.tp_ticks_final
} == %(py6)s
{%(py6)s = %(py4)s.tp_ticks_final
})zd%(py2)s
{%(py2)s = %(py0)s.sl_usd_actual
} == (%(py5)s * %(py8)s
{%(py8)s = %(py6)s.sl_usd_actual
}))r!   r#   r*   r0   r1   zassert %(py11)spy11)zd%(py2)s
{%(py2)s = %(py0)s.tp_usd_target
} == (%(py5)s * %(py8)s
{%(py8)s = %(py6)s.tp_usd_target
}))r	   rB   r;   rA   r9   r:   r<   r=   r>   r?   r@   rE   rF   )rp   rq   rK   rO   rI   ri   @py_format9rL   rP   rQ   @py_format10@py_format12s               r   'test_contracts_does_not_affect_tp_pricerv      s   $bD
 $rF
 ==+FOO+=O++++=O++++++4+++4+++=++++++F+++F+++O+++++++7&"7"77"77777"777777747774777777777&777&777"77777777:2:(:(::2(:#::#:::::#:::::::6:::6::::::2::::::::::::(:::::::::2:(:(::2(:#::#:::::#:::::::6:::6::::::2::::::::::::(:::::::::r   kwargsr   r   g      r   r   c                     t        dddddd      }|j                  |        t        j                  t              5  t        di | d d d        y # 1 sw Y   y xY w)	Nr   r   r   r   rZ   r   r    )dictupdater.   raises
ValueErrorr	   )rw   rp   s     r   test_raises_on_bad_inputsr      sW     $bD
 	KK	z	" ! 4 ! ! !s   AAc            	          t        j                  t              5  t        dddddd       d d d        y # 1 sw Y   y xY w)Nr   LONGr   r   rZ   r   r   )r.   r}   r~   r	   rz   r   r    test_raises_on_unknown_directionr      s:    	z	" 
Fd"	

 
 
   5>c            	          t        j                  t              5  t        dddddd       d d d        y # 1 sw Y   y xY w)NZZZ_NONEXISTENTr   r   r   rZ   r   r   )r.   r}   KeyErrorr	   rz   r   r   test_raises_on_unknown_symbolr      s:    	x	  
$d"	

 
 
r   ))r   r   r   )MNQg     @   )MGCg     @   )MCLg     R@(   )6Eg\(\?r   )6Jg]K={?r   zsymbol,entry,sl_ticksc                    t        | d|dd|      }|j                  }||kD  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      ndd	z  }d
d|iz  }t        t        j                  |            d x}}|j                  }t        j                  |    }||k\  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}|j                  }d}||kD  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}|j                  }d}||kD  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}y )Nr   r   rZ   r   >)z/%(py2)s
{%(py2)s = %(py0)s.tp_price
} > %(py4)sr    entryrc   rd   r0   )>=)z6%(py2)s
{%(py2)s = %(py0)s.tp_ticks_final
} >= %(py5)sr)   r+   r,   r   )z4%(py2)s
{%(py2)s = %(py0)s.sl_usd_actual
} > %(py5)s)z4%(py2)s
{%(py2)s = %(py0)s.tp_usd_target
} > %(py5)s)r	   rB   r;   rA   r9   r:   r<   r=   r>   r?   r@   cfg_futMIN_TP_TICKSrE   rF   )r   r   r   r    rK   rI   rJ   ri   rL   rM   rN   s              r   test_asset_class_smoker      s   
hC
 <<<%<%33<%%=!5!5f!==!=====!=======3===3======!======== q q    q      3   3      q        q q    q      3   3      q       r   c            	         t        ddddddd      } | j                  }d	}||k(  }|st        j                  d
|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }d}t        |z  }t        |      }||k(  }|sSt        j                  d
|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      dt	        j
                         v st        j                  t              rt        j                  t              nddt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            dx}x}x}x}}| j                  }d}||k(  }|st        j                  d
|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }t        j                   }d} ||      }||k(  }|st        j                  d
|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      dt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            dx}x}x}x}}| j"                  }d}d}d }||z  }||z   }||k(  }|st        j                  d
|fd!||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      d"z  }d#d$|iz  }t        t        j                  |            dx}x}x}x}x}x}}t%        d%       y)&u   MYM live incident: sl_ticks=13, tp_suggested 138 ticks away → cap a 2× SL.

    Senza cap: tp_ticks=round(138*0.85)=117, rr_effective=9.0x.
    Con cap=2.0: tp_ticks=int(2.0*13)=26, rr_effective=2.0, rr_capped=True.
    MYMr   g    K@r         g     ]@r   r   r   r   r   r   tp_price_suggestedai_suggestedr&   z1%(py2)s
{%(py2)s = %(py0)s.tp_source
} == %(py5)sr    r)   r+   r,   NTr6   z1%(py2)s
{%(py2)s = %(py0)s.rr_capped
} is %(py5)sre   intr   rg   r3   r4      r(          @r5   r.   r/   g      ?)zH%(py2)s
{%(py2)s = %(py0)s.tp_price
} == (%(py5)s + (%(py7)s * %(py9)s))r!   r#   r*   r,   py9assert %(py13)spy13u>   ai_suggested cap: MYM sl=13 tp_suggested=138 → tp=26, rr=2.0)r	   	tp_sourcer;   rA   r9   r:   r<   r=   r>   r?   	rr_cappedr@   r   r   rG   r.   rD   rB   r   )r    rK   rL   rI   rM   rN   rj   rk   rQ   rR   rS   rO   rP   @py_assert10@py_assert11ru   @py_format14s                    r   "test_ai_suggested_rr_capped_at_maxr      s    4b"	C ==*N*=N****=N******3***3***=***N*******== D =D    =D      3   3   =   D       ;;%5%:;%:!;;!;;;;;!;;;;;;;3;;;3;;;;;;;;;;;;;;;;;;%5;;;%5;;;;;;!;;;;;;;;############3###3#############1v}}1S1}S1111111111111131113111111111v111v111}111S11111111111<<-7-R-#-R#X-7X--<-----<-------3---3---<---7---R---#--------HIr   c            	         t        ddddddd      } | j                  }d	}||k(  }|st        j                  d
|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }d}||k(  }|st        j                  d
|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }t        j                  }d} ||      }||k(  }|st        j                  d
|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      dt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            dx}x}x}x}}y)u-   tp_suggested entro 2× SL → cap non engage.r   r   r   r   r   r   g    @r   r   r&   r   r    r)   r+   r,   NFr6   r   r   r(   g?r5   r.   r/   r3   r4   )r	   r   r;   rA   r9   r:   r<   r=   r>   r?   r   r@   rG   r.   rD   r]   s              r   'test_ai_suggested_no_cap_when_below_maxr      s.    $b-	C ==*N*=N****=N******3***3***=***N*******==!E!=E!!!!=E!!!!!!3!!!3!!!=!!!E!!!!!!!############3###3#############2v}}2T2}T2222222222222232223222222222v222v222}222T222222222222r   c                  z   t        dddddd      } | j                  }d}||k(  }|st        j                  d	|fd
||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }d}||k(  }|st        j                  d	|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }|t        kD  }|st        j                  d|fd|t        f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      dt	        j
                         v st        j                  t              rt        j                  t              nddz  }dd|iz  }t        t        j                  |            dx}}t        d       y)u.  rr_fallback: hard-clamp [0.10, 0.80] limita rr_used, ma MIN_TP_TICKS
    può alzare il tp_ticks finale oltre 2× SL su SL strettissimi.

    MNQ: MIN_TP=8, sl_ticks=3, rr=0.10. tp_raw=0.3→0; MIN_TP_TICKS lifts→8.
    cap = 2*3 = 6. MIN_TP=8 > cap → MIN_TP wins (tp_ticks=8), rr_capped=True.
    r   r   g     @g?rZ      r   rr_fallbackr&   r   r    r)   r+   r,   NTr6   r   r8   r[   r(   r   )z3%(py2)s
{%(py2)s = %(py0)s.rr_effective
} > %(py4)sr   rc   rd   r0   z@rr_fallback cap: MIN_TP wins on extreme tight SL, rr_capped=True)r	   r   r;   rA   r9   r:   r<   r=   r>   r?   r   rH   r@   rG   r   r   )r    rK   rL   rI   rM   rN   rJ   ri   s           r   =test_rr_fallback_cap_engages_only_when_min_tp_lifts_above_capr     sk    4aC
 ==)M)=M))))=M))))))3)))3)))=)))M)))))))== D =D    =D      3   3   =   D       ##+t+#t++++#t++++++3+++3+++#+++t+++++++""""""""""""3"""3""""""""""""".............3...3.....................JKr   c                  D   t        dddddd      } | j                  }d}||k(  }|st        j                  d	|fd
||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y)uA   rr_fallback normale: hard-clamp 0.80 << cap 2.0 → no rr_capped.r   r   r   r   r   r   r   r   r&   r   r    r)   r+   r,   NFr6   r   )r	   r   r;   rA   r9   r:   r<   r=   r>   r?   r   rW   s         r   -test_rr_fallback_normal_path_unchanged_no_capr     s    
$bC
 ==)M)=M))))=M))))))3)))3)))=)))M)))))))==!E!=E!!!!=E!!!!!!3!!!3!!!=!!!E!!!!!!!r   c            	      	   t        ddddddd      } | j                  }d	}||k(  }|st        j                  d
|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }d}||k(  }|st        j                  d
|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}| j                  }t        j                  }d} ||      }||k(  }|st        j                  d
|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      dt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            dx}x}x}x}}| j                  }d}d}d}||z  }||z
  }||k(  }|st        j                  d
|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }dd |iz  }t        t        j                  |            dx}x}x}x}x}x}}t!        d!       y)"zCCap simmetrico per SELL: tp_suggested 100 ticks sotto entry, sl=10.r   rV   r   r   r   r%   g     @r   r   r&   r   r    r)   r+   r,   NTr6   r   r   r(   r   r5   r.   r/   r3   r4   g      ?)zH%(py2)s
{%(py2)s = %(py0)s.tp_price
} == (%(py5)s - (%(py7)s * %(py9)s))r   r   r   z'ai_suggested SELL cap: rr_effective=2.0)r	   r   r;   rA   r9   r:   r<   r=   r>   r?   r   r@   rG   r.   rD   rB   r   )r    rK   rL   rI   rM   rN   rO   rP   rQ   rR   rS   rj   rk   r   r   ru   r   s                    r   test_ai_suggested_sell_capr   $  s    $b.	C ==*N*=N****=N******3***3***=***N*******== D =D    =D      3   3   =   D       ############3###3#############1v}}1S1}S1111111111111131113111111111v111v111}111S11111111111<<-6-B--BI-6I--<-----<-------3---3---<---6---B-----------12r   c                     t        d       t                t        d       t                t        d       t	                t        d       t                t        d       t                t        d       t                t        d       t                t        d       t        D ]  } t        |         t        d	       t                t        d
       t                t        d       t        D ]!  \  }}}t        |||       t        d|        # t                t!                t#                t%                t'                t        d       y)Nztest_tp_resolver.pyzbasic BUY MES mathzbasic SELL MES mathzMIN_TP_TICKS lifts short TPz MIN_TP_TICKS inactive when abovezhard clamp upper boundzhard clamp lower boundzcontracts cancels (algebraic)zvalidation raises on bad inputszraises on unknown directionzraises on unknown symbolzasset smoke: zALL TESTS PASSEDr   )r   rT   r   rX   r^   r`   rl   rn   rv   _BAD_INPUT_CASESr   r   r   _ASSET_SMOKE_CASESr   r   r   r   r   r   )rw   r   r   r   s       r   mainr   D  s   	
 #23345$&,I(J)+S1S-TS!9:S!9:+-s3R/S" *!&)*)*$&,I(J!#S)C%D#5 &xvuh7mF8$%& '(+-AC13 	
r   __main__)3__doc__builtinsr9   _pytest.assertion.rewrite	assertionrewriter;   syspathlibr   pathinsertstr__file__resolveparentr.   corer   r   trading.tp_resolverr   r   r   r   r	   r   rT   rX   r^   r`   rl   rn   rv   markparametrizer   r   r   r   r   r   r   r   r   r   r   r   r   __name__exitrz   r   r   <module>r      s  "  
  3tH~--/66==> ?  * s t -(#
2$9	# ;. ABadO!$ !!

  02DE	! F	! J,3 L*"3. ABadO! c 6 zCHHTV r   