
    i0                    f   d Z ddlmZ ddlZddlmc mZ ddl	Z	ddl
Z
ddlZddlmZ e
j                  j                  d e ee      j%                         j&                  j&                               ddlmZ ddlmZ ddZd Zd	 Zd
 Zd Zd ZddZedk(  r e
j@                   e              yy)a  
Tick alignment + broker-result discipline on MOVE_SL.

V16 incident 29 apr (BUG 6): BrainMR trailing computed
trailing_sl=0.7324928571428572 (16 decimals on 6C 0.00005 tick grid),
broker silently rejected, V16 ignored OrderResult.success and mutated
runtime.current_sl_price as if the move had succeeded -> next iter
recomputed and re-issued -> 20+ rejected calls in 8 minutes.

Four-layer fix verified here:
  1. Brain rounds via _round_to_tick using tech.tick_size.
  2. Orchestrator inspects OrderResult.success; on reject does NOT
     mutate runtime.
  3. Broker (topstepx_v16) defense-in-depth re-aligns to tick.
  4. Logging: move_sl_failed event with prev_sl + attempted_sl + error.
    )annotationsN)PathOrderResult)	BrainBasec                     t        d|         y )Nz  ok  )print)labels    8/home/work/apex_v16/tests/test_move_sl_tick_alignment.py_okr      s    	F5'
    c            	     d   d} d}t        j                  | |      }d}||z
  }t        |      }d}||k  }|s#t        j                  d|fd||f      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t        j                  |      t        j                  |      t        j                  |      d	z  }t        j                  d
|       dz   d|iz  }	t        t        j                  |	            dx}x}x}x}}t         j                  }
 |
||      }||k(  }|sxt        j                  d|fd||f      dt        j                         v st        j                  t               rt        j                  t               ndt        j                  |
      dt        j                         v st        j                  |      rt        j                  |      nd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}
x}}t         j                  }
d}d} |
||      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t               rt        j                  t               ndt        j                  |
      t        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }	dd|	iz  }t        t        j                  |            dx}
x}x}x}x}}t        d       y)z
    _round_to_tick(0.7324928571428572, 0.00005) -> 0.73250.
    The 16-decimal raw float that triggered the incident must align
    cleanly to the 6C tick grid.
    m?ܔp?-C6
?q=
ףp?&.><z;%(py6)s
{%(py6)s = %(py0)s((%(py1)s - %(py3)s))
} < %(py9)sabsalignedpy0py1py3py6py9zexpected 0.7325, got z
>assert %(py11)spy11N==)z]%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s._round_to_tick
}(%(py3)s, %(py4)s)
} == %(py8)sr   tick)r   py2r   py4r   py8zassert %(py10)spy10gƑp?g        )z^%(py8)s
{%(py8)s = %(py2)s
{%(py2)s = %(py0)s._round_to_tick
}(%(py4)s, %(py6)s)
} == %(py11)s)r   r"   r#   r   r$   r   zassert %(py13)spy13zDLayer 1: _round_to_tick aligns 6C 0.7324928... -> 0.7325, idempotent)r   _round_to_tickr   
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_saferepr_format_assertmsgAssertionError_format_explanationr   )rawr!   r   @py_assert2@py_assert4@py_assert5@py_assert8@py_assert7@py_format10@py_format12@py_assert1@py_format9@py_format11@py_assert3@py_assert10@py_assert9@py_format14s                    r   .test_brain_round_to_tick_aligns_off_grid_pricerA   '   sm    CD&&sD1GJwJ3 J4J 4'JJJ 4JJJJJJ3JJJ3JJJJJJwJJJwJJJJJJ JJJ4JJJ+@	)JJJJJJJJ##=#GT2=2g====2g======9===9===#======G===G======T===T===2======g===g=======##@I@s@#Is3@y@3y@@@@3y@@@@@@9@@@9@@@#@@@I@@@s@@@3@@@y@@@@@@@@NOr   c                 R   d} d}d|z  }| |z
  }t        j                  |d      }d}||z
  }t        |      }d}||k  }	|	s
t        j                  d|	fd||f      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
t        j                  |      t        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                  |            dx}x}x}x}	}d}t        j                  |d      }d}||z
  }t        |      }d}||k  }	|	s
t        j                  d|	fd||f      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t        j                  |      t        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                  |            dx}x}x}x}	}t        d       y)u  
    BrainMR.manage_exit trailing path: trailing_sl_raw is computed from
    current_price ± 1.5 * atr, then aligned via _round_to_tick(... ,
    tech.tick_size). The emitted move_sl_to MUST equal the aligned price.
    raw_sl_price preserved in metadata for forensic comparison.

    We don't import brain_mr here (pulls pandas via TechSnapshot). Instead
    we exercise the same arithmetic via _round_to_tick to verify the
    alignment math is invariant to where it lives.
    rh|?g/nR?g      ?r   g8gDio?r   r   r   r   r   r   zassert %(py11)sr   NgI5o?aligned2z<Layer 1 (parity): MR trailing computation -> tick-aligned SL)r   r(   r   r)   r*   r+   r,   r-   r.   r0   r1   r   )current_priceatrtrailing_distr2   r   r3   r4   r5   r6   r7   r8   r9   raw2rD   s                 r   -test_brain_mr_trailing_emits_aligned_sl_pricerI   9   s    M
C#IM
-
'C&&sG4G (w (3 !(D(!D((((!D((((((3(((3((((((w(((w((((((!(((D(((((((D''g6H!)x'!)3!")T)"T))))"T))))))3)))3))))))x)))x)))')))")))T)))))))FGr   c                   * ddl m} m}m} ddlm}m}m}m}m	} ddl
m}m}	m}
 ddlm}  G d d      } G d d	      * G *fd
d      } | |j                   |j"                        }dg|_         |	       } |dZi 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|_         |||-      |j(                  d<    |       }t+        j,                         5 } |
t/        |      d.z        } ||d/d/||| |       d0      } ||j0                  j2                  d1d2d3d4d56      }|j(                  d   }t5        j6                  |j9                  d||             d/d/d/       j:                  }|j&                  }d}||k(  }|st=        j>                  d7|fd8||f      d9tA        jB                         v st=        jD                  |      rt=        jF                  |      nd9t=        jF                  |      t=        jF                  |      t=        jF                  |      d:z  }t=        jH                  d;|j:                  j&                         d<z   d=|iz  }tK        t=        jL                  |            d/x}x}x}}|jN                  jP                  D cg c]  }|d>   d?k(  s| }}tS        |      } d}| |k(  }!|!st=        j>                  d7|!fd@| |f      dAtA        jB                         v st=        jD                  tR              rt=        jF                  tR              ndAdBtA        jB                         v st=        jD                  |      rt=        jF                  |      ndBt=        jF                  |       t=        jF                  |      dCz  }"t=        jH                  dDtS        |             dEz   dF|"iz  }#tK        t=        jL                  |#            d/x} x}!}|d   }$|$d   }%d}|%|k(  } | slt=        j>                  d7| fdG|%|f      t=        jF                  |%      t=        jF                  |      dHz  }&dIdJ|&iz  }"tK        t=        jL                  |"            d/x}%x} }|$dK   }%d}|%|k(  } | slt=        j>                  d7| fdG|%|f      t=        jF                  |%      t=        jF                  |      dHz  }&dIdJ|&iz  }"tK        t=        jL                  |"            d/x}%x} }|$dL   }%d2}|%|k(  } | slt=        j>                  d7| fdG|%|f      t=        jF                  |%      t=        jF                  |      dHz  }&dIdJ|&iz  }"tK        t=        jL                  |"            d/x}%x} }dM}%|$dN   }|%|v } | slt=        j>                  dO| fdP|%|f      t=        jF                  |%      t=        jF                  |      dHz  }&dIdJ|&iz  }"tK        t=        jL                  |"            d/x}%x} }|$dQ   }%d3}|%|k(  } | slt=        j>                  d7| fdG|%|f      t=        jF                  |%      t=        jF                  |      dHz  }&dIdJ|&iz  }"tK        t=        jL                  |"            d/x}%x} }|jN                  jP                  D cg c]  }|d>   dRk(  s| }'}g } |'| k(  }|st=        j>                  d7|fdS|'| f      dTtA        jB                         v st=        jD                  |'      rt=        jF                  |'      ndTt=        jF                  |       dUz  }(t=        jH                  dV      dWz   dX|(iz  })tK        t=        jL                  |)            d/x}} tU        dY       y/# 1 sw Y   xY wc c}w c c}w )[z
    When broker.modify_stop returns OrderResult(success=False), the
    orchestrator must NOT mutate active.runtime.current_sl_price and
    must emit a move_sl_failed event with prev_sl + attempted_sl + error.
    r   RuntimeConfigRunModeAccountKindBrainDecisionTradeAction
TradeEntryTradeRuntimeutc_nowActiveTradeSessionState
StateStoreOrchestratorc                      e Zd Zd Zy)Ztest_orchestrator_handle_move_sl_skips_state_mutation_on_broker_reject.<locals>.FakeBrokerc                $   K   t        dd      S w)NFz adapter modify_sl returned False)successerrorr   selfsymbolorder_idnew_sl_prices       r   modify_stopzftest_orchestrator_handle_move_sl_skips_state_mutation_on_broker_reject.<locals>.FakeBroker.modify_stopk   s     8 s   N__name__
__module____qualname__re    r   r   
FakeBrokerr\   j   s    	r   rk   c                      e Zd Zd Zd Zy)Ytest_orchestrator_handle_move_sl_skips_state_mutation_on_broker_reject.<locals>.JsonlSinkc                    g | _         y Neventsra   s    r   __init__zbtest_orchestrator_handle_move_sl_skips_state_mutation_on_broker_reject.<locals>.JsonlSink.__init__r       "DKr   c                B    | j                   j                  d|i|       y Neventrq   appendra   
event_namekws      r   writez_test_orchestrator_handle_move_sl_skips_state_mutation_on_broker_reject.<locals>.JsonlSink.writes       KK:r:;r   Nrg   rh   ri   rs   r}   rj   r   r   	JsonlSinkrm   q   
    ,	<r   r   c                      e Zd Z fdZd Zy)Ztest_orchestrator_handle_move_sl_skips_state_mutation_on_broker_reject.<locals>.FakeLoggerc                R    dd l }|j                  d      | _                | _        y Nr   testlogging	getLoggersystem	brain_logra   r   r   s     r   rs   zctest_orchestrator_handle_move_sl_skips_state_mutation_on_broker_reject.<locals>.FakeLogger.__init__w   !    !++F3DK&[DNr   c                     y ro   rj   ra   r|   s     r   	log_errorzdtest_orchestrator_handle_move_sl_skips_state_mutation_on_broker_reject.<locals>.FakeLogger.log_error{       r   Nrg   rh   ri   rs   r   r   s   r   
FakeLoggerr   v       	) 	(r   r   modeaccount6Crb   
brain_nameMR	directionBUY	contracts   entry_pricerC   sl_priceCl?tp_priceV-?	opened_atrsi_m5_at_entry      9@rsi_h1_at_entry      >@rsi_h4_at_entry      D@atr_ratio_at_entry      ?market_structure_at_entryRANGINGregime_at_entryh1_compat_at_entry      ?confidence_at_entryF   stop_order_id12345entryruntime
state.jsonNconfig	ai_clientmarket_data_providerstatestoreloggerbrokermax_iterationsztrailing testr   trailingr&   )	sl_targetraw_sl_priceactionreason
move_sl_tometadatar   zU%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.runtime
}.current_sl_price
} == %(py7)sactiver   r"   r#   py7z)current_sl_price must remain 0.7320, got z
>assert %(py9)sr   rw   move_sl_failedz0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenfailedr   r   r   r   zexpected 1 move_sl_failed, got z
>assert %(py8)sr$   z%(py1)s == %(py4)sr   r#   assert %(py6)sr   current_sl_priceattempted_sl_pricezmodify_sl returned Falser_   inz%(py1)s in %(py4)stargetmove_sl)z%(py0)s == %(py3)ssuccess_events)r   r   z-move_sl success event must NOT fire on rejectz
>assert %(py5)spy5zELayer 2+4: broker reject -> runtime untouched, move_sl_failed emittedrj   )+core.configrL   rM   rN   core.contractsrP   rQ   rR   rS   rT   persistence.state_storerV   rW   rX   orchestratorrZ   DRY
INELIGIBLEasset_filterr   active_tradestempfileTemporaryDirectoryr   MOVE_SLvalueasynciorun_handle_move_slr   r)   r*   r+   r,   r-   r.   r/   r0   r1   r   rq   r   r   )+rL   rM   rN   rP   rQ   rR   rS   rT   rV   rW   rX   rZ   rk   r   cfgr   r   r   r   tmpr   orchdecisionr   r:   r=   @py_assert6r5   @py_format8r8   er   r3   r4   @py_format7r;   ev@py_assert0@py_format5r   @py_format4@py_format6r   s+                                             @r   Ftest_orchestrator_handle_move_sl_skips_state_mutation_on_broker_rejectr   Z   s    @?   * < <
( ( W[[+2H2H
ICvCNE  $05!'  #) )	
 
 /3
 EI  #, "   E nG%G +% IE\F		$	$	& B#49|34$TuV<	
 !&&,,"#-yI	
 $$T*D((vx@A!B& >> >** f *f4  *f                  +    /5    4FNN4S4S3TU       ))00SAAgJBR4RaSFSv;L!L;!LLL;!LLLLLL3LLL3LLLLLLvLLLvLLL;LLL!LLL>s6{mLLLLLLLL	Bh<4<4<4<4 !+V+!V++++!V+++!+++V+++++++"#-v-#v----#v---#---v-------%4G4%4444%444%4444444444h<%:%<:%%%%<:%%%<%%%:%%%%%%%!'!1!1!8!8TAAgJ)<SaTNTP>RPPP>RPPPPPP>PPP>PPPRPPP!PPPPPPPOPEB B. T Us%   5B]-.]:<]:]?]?-]7c                   ' ddl m} m}m} ddlm}m}m}m}m	} ddl
m}m}	m}
 ddlm}  G d d      } G d d	      ' G 'fd
d      } | |j                   |j"                        }dg|_         |	       } |dRi 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|_         |||-      |j(                  d<    |       }t+        j,                         5 } |
t/        |      d.z        } ||d/d/||| |       d0      } ||j0                  j2                  d1d2d3d4i5      }|j(                  d   }t5        j6                  |j9                  d||             d/d/d/       j:                  }|j&                  }d}||k(  }|st=        j>                  d6|fd7||f      d8tA        jB                         v st=        jD                  |      rt=        jF                  |      nd8t=        jF                  |      t=        jF                  |      t=        jF                  |      d9z  }d:d;|iz  }tI        t=        jJ                  |            d/x}x}x}}|jL                  jN                  D cg c]  }|d<   d=k(  s| }}tQ        |      } d}| |k(  }!|!st=        j>                  d6|!fd>| |f      d?tA        jB                         v st=        jD                  tP              rt=        jF                  tP              nd?d@tA        jB                         v st=        jD                  |      rt=        jF                  |      nd@t=        jF                  |       t=        jF                  |      dAz  }"dBdC|"iz  }#tI        t=        jJ                  |#            d/x} x}!}|d   }$|$dD   }%d}|%|k(  } | slt=        j>                  d6| fdE|%|f      t=        jF                  |%      t=        jF                  |      dFz  }&dGdH|&iz  }"tI        t=        jJ                  |"            d/x}%x} }|$dI   }%d2}|%|k(  } | slt=        j>                  d6| fdE|%|f      t=        jF                  |%      t=        jF                  |      dFz  }&dGdH|&iz  }"tI        t=        jJ                  |"            d/x}%x} }dJ}%|$dK   }|%|v } | slt=        j>                  dL| fdM|%|f      t=        jF                  |%      t=        jF                  |      dFz  }&dGdH|&iz  }"tI        t=        jJ                  |"            d/x}%x} }|$dK   }%|%jR                  } dN}! | |!      }|stdOt=        jF                  |%      t=        jF                  |       t=        jF                  |!      t=        jF                  |      dPz  }tI        t=        jJ                  |            d/x}%x} x}!}tU        dQ       y/# 1 sw Y   YxY wc c}w )Sz
    Counterpart of the test above: when broker raises an exception
    (network/transient), move_sl_failed is also emitted with
    error='raised: ...'.
    r   rK   rO   rU   rY   c                      e Zd Zd Zy)Qtest_orchestrator_handle_move_sl_logs_move_sl_failed_event.<locals>.RaisingBrokerc                    K   t        d      w)Nwebsocket dropped)ConnectionErrorr`   s       r   re   z]test_orchestrator_handle_move_sl_logs_move_sl_failed_event.<locals>.RaisingBroker.modify_stop   s     !"566s   Nrf   rj   r   r   RaisingBrokerr      s    	7r   r  c                      e Zd Zd Zd Zy)Mtest_orchestrator_handle_move_sl_logs_move_sl_failed_event.<locals>.JsonlSinkc                    g | _         y ro   rp   rr   s    r   rs   zVtest_orchestrator_handle_move_sl_logs_move_sl_failed_event.<locals>.JsonlSink.__init__   rt   r   c                B    | j                   j                  d|i|       y rv   rx   rz   s      r   r}   zStest_orchestrator_handle_move_sl_logs_move_sl_failed_event.<locals>.JsonlSink.write   r~   r   Nr   rj   r   r   r   r     r   r   r   c                      e Zd Z fdZd Zy)Ntest_orchestrator_handle_move_sl_logs_move_sl_failed_event.<locals>.FakeLoggerc                R    dd l }|j                  d      | _                | _        y r   r   r   s     r   rs   zWtest_orchestrator_handle_move_sl_logs_move_sl_failed_event.<locals>.FakeLogger.__init__   r   r   c                     y ro   rj   r   s     r   r   zXtest_orchestrator_handle_move_sl_logs_move_sl_failed_event.<locals>.FakeLogger.log_error   r   r   Nr   r   s   r   r   r
     r   r   r   r   r   rb   r   r   r   r   r   r   r   rC   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Nr   ztrailing on raiser   r   r   r   r   r   r   r   zassert %(py9)sr   rw   r   r   r   r   r   zassert %(py8)sr$   r   r   r   r   r   r   r  r_   r   r   zraised: zLassert %(py7)s
{%(py7)s = %(py3)s
{%(py3)s = %(py1)s.startswith
}(%(py5)s)
})r   r   r   r   zDLayer 2+4: broker raise -> runtime untouched, move_sl_failed emittedrj   )+r   rL   rM   rN   r   rP   rQ   rR   rS   rT   r   rV   rW   rX   r   rZ   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r)   r*   r+   r,   r-   r.   r0   r1   r   rq   r   
startswithr   )(rL   rM   rN   rP   rQ   rR   rS   rT   rV   rW   rX   rZ   r  r   r   r   r   r   r   r   r   r   r   r   r:   r=   r   r5   r   r8   r   r   r3   r4   r   r;   r   r   r   r   s(                                          @r   :test_orchestrator_handle_move_sl_logs_move_sl_failed_eventr     s    @?  NM)7 7< <
( ( W[[+2H2H
ICvCNE  $05!'  #) )	
 
 /3
 EI  #, "  57 E nG%G +% IE\F		$	$	& B#49|34$TuV ?1
 !&&,,&!:.	
 $$T*D((vx@AB" >>4>**4f4*f4444*f44444464446444>444*444f4444444))00SAAgJBR4RaSFSv;!;!;!33vv;!	B !+V+!V++++!V+++!+++V+++++++"#-v-#v----#v---#---v--------"W+-+----+------+-------g;-;!!-*-!*-----;---!---*----------NO3B B$ Ts   5BW WWWc            	        ddl m}  i  G fdd      }| j                  |       } |       |_        d}t	        j
                  |j                  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}}d   }d}||z
  }
t!        |
      }d}||k  }|st        j                  d|fd||f      dt        j                         v st        j                  t               rt        j                  t               ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }t        j"                  dd          dz   d|iz  }t        t        j                  |            dx}x}x}
x}x}}|j$                  }d}||z
  }t!        |      }d}||k  }|sAt        j                  d|fd||f      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t        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }t        j"                  d|j$                         dz   d|iz  }t        t        j                  |            dx}x}x}x}x}}t'        d       y) a!  
    Even if upstream fails to round, topstepx_v16.modify_stop must
    align using ASSETS_MAP[symbol]['tick_size'] before calling the SDK
    adapter. We pass an off-grid price and verify the adapter receives
    the aligned value AND OrderResult.sl_price reflects the aligned value.
    r   )TopstepXBrokerc                      e Zd Zd Z fdZy)Rtest_broker_topstepx_modify_stop_aligns_to_tick_as_safety_net.<locals>.FakeAdapterc                    dddii| _         y )Nr   	tick_sizer   )_instrument_cacherr   s    r   rs   z[test_broker_topstepx_modify_stop_aligns_to_tick_as_safety_net.<locals>.FakeAdapter.__init__  s    &*[',B%CD"r   c               ,   K   |d<   |d<   |d<   yw)Nrb   r   new_slTrj   )ra   rb   r   r  captureds       r   	modify_slz\test_broker_topstepx_modify_stop_aligns_to_tick_as_safety_net.<locals>.FakeAdapter.modify_sl  s(     !'HX(5H_%!'HXs   N)rg   rh   ri   rs   r  )r  s   r   FakeAdapterr    s    	D	r   r  r   r   r   T)is)z/%(py2)s
{%(py2)s = %(py0)s.success
} is %(py5)sresult)r   r"   r   zassert %(py7)sr   Nr  r   r   r   )z<%(py7)s
{%(py7)s = %(py0)s((%(py2)s - %(py4)s))
} < %(py10)sr   )r   r"   r#   r   r%   z+adapter should receive aligned 0.7325, got z
>assert %(py12)spy12)zZ%(py8)s
{%(py8)s = %(py0)s((%(py3)s
{%(py3)s = %(py1)s.sl_price
} - %(py5)s))
} < %(py11)s)r   r   r   r   r$   r   z8OrderResult.sl_price should reflect aligned 0.7325, got z
>assert %(py13)sr'   zOLayer 3: topstepx_v16.modify_stop re-aligns 0.7324928... -> 0.7325 (safety net))broker.topstepx_v16r  __new___adapterr   r   re   r^   r)   r*   r+   r,   r-   r.   r0   r1   r   r/   r   r   )r  r  r   r2   r  r:   r4   r=   r   r   r5   r   r?   r6   r<   @py_format13r3   r7   r>   r9   r@   r  s                        @r   =test_broker_topstepx_modify_stop_aligns_to_tick_as_safety_netr"  	  s)    3H  ##N3F!mFO
C[[++D'3?@F>>!T!>T!!!!>T!!!!!!6!!!6!!!>!!!T!!!!!!!! F !F* 3*+ d +d2  +d              "    %+    ,    /3    6hx6H5IJ        ' 3'( 4 (4/   (4                            "(    )    ,0    C6??BST      YZr   c                     t        d       t                t                t                t	                t                t        d       y)Nztest_move_sl_tick_alignment.pyzALL 5 TESTS PASSEDr   )r	   rA   rI   r   r  r"  rj   r   r   mainr$  1  s5    	
*+2413JL>@AC	
r   __main__)r
   strreturnNone)r'  int)!__doc__
__future__r   builtinsr+   _pytest.assertion.rewrite	assertionrewriter)   r   sysr   pathlibr   pathinsertr&  __file__resolveparentbroker.broker_baser   brain.brain_baser   r   rA   rI   r   r  r"  r$  rg   exitrj   r   r   <module>r:     s   " #    
   3tH~--/66==> ? * &P$HB[Q|JPb![P zCHHTV r   