
    
i                        S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSKrSSK	J
r
  SSKJrJr  SSKJr  SSKJr   SSKrSr\
" 5         \R*                  " S	5      r\R*                  " S
5      rSrSrSrSrSrSrSrSrSr Sr!Sr"Sr#Sr$Sr%Sr&Sr'Sr(Sr)Sr*Sr+Sr,Sr-S r.Sr/S!r0S"r1S#r2S$r3S%r4S&r5S'r6S(r7S)r8S*r9S+r:SSSSSS,.r;SSSSSS,.r</ r=\R|                  " 5       r?/ r@/ rA\R                  " 5       rB\#qC\#qDSrE\F" 5       qG\R|                  " 5       rHS-rIS.rJS/rK/ rL\R|                  " 5       rMSqN\R|                  " 5       rO/ qP\R                  " 5       rRSqS/ qT/ qUSqVS0 rWS1 rXS2 rYS3 rZS4 r[S5 r\S6 r]S7 r^S8 r_S9 r`S: raS; rbS< rcS= rdS> reS? rfS@ rgSA rhSB riSC rjSD rkSE rlSF rmSG rnSH roSIrpSrqSrrSrsSqtSJ ruS\SK jrvSL rwSM rxSN rySO rzSP r{SQ r|SR r}S]SS jr~S^ST jrSU rSV rSW rSX rSY rSZ r\S[:X  a  \" 5         gg! \ a    Sr GNf = f)_u  
PAPER TRADING BOT - BTC 15-Min Kalshi Markets
$100 starting balance. Smart tiered bet sizing. 2:1 reward/risk.
Trailing high-water mark stop-loss — protects profits, not just starting balance.
Live dashboard: open dashboard.html via OPEN DASHBOARD shortcut
    N)load_dotenv)serializationhashes)padding)default_backendTFKALSHI_API_KEY_IDKALSHI_PRIVATE_KEY_PATHz https://api.elections.kalshi.comC:\kalshibotzC:\kalshibot\datazC:\kalshibot\data\archivez!C:\kalshibot\trade_analytics.jsonz"C:\kalshibot\market_snapshots.jsonz&C:\kalshibot\data\session_history.jsonzC:\kalshibot\paper_log.jsonzC:\kalshibot\auto_params.jsoni  i'  g     @o@g?g      ?g=
ףp=?g333333?x   gMbP?         g?               ?      @      ?g      ?g-C6:?gQ?-   ga2U0*C?binancecoinbasekrakenokxbybit      ga2U0*S?c                     [        U S5       n[        R                  " UR                  5       S [	        5       S9sS S S 5        $ ! , (       d  f       g = f)Nrb)passwordbackend)openr   load_pem_private_keyreadr   )pathfs     paper_trade.pyload_private_keyr(   `   s6    	dD	Q11!&&(TSbSde 
		s   ,A
Ac                  :    [         c  [        [        5      q [         $ N)_private_key_cacher(   KEY_PATH     r'   get_private_keyr/   d   s    !-h7r.   c           	      h   X-   U-   R                  S5      nU R                  U[        R                  " [        R                  " [
        R                  " 5       5      [        R                  R                  S9[
        R                  " 5       5      n[        R                  " U5      R                  S5      $ )Nzutf-8)mgfsalt_length)encodesignr   PSSMGF1r   SHA256DIGEST_LENGTHbase64	b64encodedecode)pktsmethodr%   msgsigs         r'   sign_requestrA   j   sx    ;
%
%g
.C
''#w{{w||FMMO'DKK--/06ACC ''00r.   c                     [        [        [        R                  R                  5       R	                  5       S-  5      5      n[        5       n[        U[        X2X5      SS.$ )Ni  zapplication/json)zKALSHI-ACCESS-KEYzKALSHI-ACCESS-TIMESTAMPzKALSHI-ACCESS-SIGNATUREzContent-Type)strintdatetimenow	timestampr/   KEY_IDrA   )r>   r%   r=   r<   s       r'   get_headersrI   p   sR    	S""&&(224t;<	=B		B!'B'3BF'I.0 0r.   c                  z    [         [        :  a-  [        S[         S S[         S[        -
  -  S S35        [         qg g )Nz  ** NEW HIGH: $.2fz  Stop now at $r   z **)balancehigh_water_markprintTRAILING_STOP_PCTr-   r.   r'   update_high_water_markrP   w   s>      _WaHYFY=Z[^<__bcd! !r.   c                      g)NFr-   r-   r.   r'   check_session_stop_lossrR   }   s    r.   c            	      l   [         (       d  g S/n S nS nS nS n U  H*  n [        R                  " UXX4S9nUR                  SSS	9  M,     [        R                  " S5        MH  ! [         aD  n[        S
UR                  S5      S    SU 35        [        R                  " S5         S nAM  S nAff = f)Nz-wss://stream.binance.us:9443/ws/btcusdt@tradec                      [         R                  " U5      n[        UR                  S5      =(       d    UR                  S5      =(       d    S5      nUS:  a  [        R                  " 5       n[
           U[        S'   U[        S'   [        R                  XC45        S S S 5        [        (       a8  [        U[        -
  [        -  5      [        :  a  [        R                  5         Uq
g [        (       d  Uq
g g g ! , (       d  f       Na= f!    g = f)Npcr   r   )jsonloadsfloatgettime
price_lockpricesprice_timesprice_historyappend_last_hot_btcabsHOT_PATH_BTC_MOVEhot_path_eventset)wsr?   datapricerF   s        r'   on_msgbinance_ws.<locals>.on_msg   s    	JJsOD$((3-=488C==A>Eqyiik-2F9%-0K	*!((#6   !=S%-*?=)P%QUf%f"&&($)M&$)M ' Z 	s+   A2D	 4)C8A
D	 (D	 8
DD	 	Dc                     g r*   r-   )rf   errs     r'   on_errorbinance_ws.<locals>.on_error   s    4r.   c                 h    [            S [        S'   S [        S'   S S S 5        g ! , (       d  f       g = f)Nr   )r\   r]   r^   )rf   argss     r'   on_closebinance_ws.<locals>.on_close   s#    %)F9%)K	" ZZs   #
1c                     [        S5        g )Nu!     ✅ Binance WebSocket connected)rN   )rf   s    r'   on_openbinance_ws.<locals>.on_open   s    12r.   )
on_messagerm   rq   rt      r   )ping_intervalping_timeoutu     ⚠  Binance WS /   z error: r   r   )	WS_AVAILABLE	websocketWebSocketApprun_forever	ExceptionrN   splitr[   sleep)WS_URLSri   rm   rq   rt   ws_urlrf   es           r'   
binance_wsr      s    < 	8G"  *
3
F	++%%8 Ra@  	

1   *6<<+<Q+?*@LM

1s   &A%%
B3/9B..B3c                     S/n  U  H  n [         R                  " USS9nUR                  S:X  aj  [        UR	                  5       S   5      n[
        R
                  " 5       n[           U[        S'   U[        S'   [        R                  XC45        S S S 5          OM     [
        R                  " S5        M  ! , (       d  f       N,= f!    M  = f)N9https://api.binance.us/api/v3/ticker/price?symbol=BTCUSDTr   timeout   rh   r   r   requestsrZ   status_coderY   rW   r[   r\   r]   r^   r_   r`   r   )	REST_URLSurlrrh   rF   s        r'   poll_binance_restr      s     	DI C	LLa0==C'!!&&(7"34E IIKC#,1y)C;y3I%,,c\: $  (  	

1  $ Hs$   AC')B6C6
C	 CCc                       [         R                  " SSS9n U R                  S:X  al  [        U R	                  5       S   S   5      n[
        R
                  " 5       n[           U[        S'   U[        S'   [        R                  X!45        S S S 5        O [
        R                  " S5        M  ! , (       d  f       N&= f!    N-= f)N/https://api.coinbase.com/v2/prices/BTC-USD/spotr   r   r   rg   amountr   r   )r   rh   rF   s      r'   poll_coinbaser      s    
	NXYZA}}#affhv.x89		).F:&#J0G!((#6  Z $ 	

1   Z 	s*   AB> ")B-B> -
B;7B> ;B> >Cc                       [         R                  " SSS9n U R                  S:X  a  U R                  5       R                  S0 5      n[	        UR                  S0 5      R                  SS/5      S   5      nUS:  aL  [
        R
                  " 5       n[           U[        S	'   U[        S	'   [        R                  X245        S S S 5        [
        R                  " S
5        M  ! , (       d  f       N&= f!    N-= f)N2https://api.kraken.com/0/public/Ticker?pair=XBTUSDr   r   r   resultXXBTZUSDrV   r   r   r   r   rZ   r   rW   rY   r[   r\   r]   r^   r_   r`   r   )r   r   rh   rF   s       r'   poll_krakenr      s    

	Q[\]A}}#h3vzz*b9==cA3GJK19))+C#+0x(#+h2G%,,c\: $ 	

1  $ 	s*   BC2 )C!C2 !
C/+C2 /C2 2C6c                  R  ^
^^ [            [        [        5      m[        [        5      mS S S 5        [        R                  " 5       m
T V s/ s H0  n TU    (       d  M  TU    (       d  M  T
TU    -
  S:  d  M)  U TU    4PM2     nn U(       d  g[        U
UU4S jS 5       S 5      nU(       d  gSR                  S U 5       5      nS nTS   TS   TS	   pvnU(       a5  U(       a.  U(       a'  Xg-   S
-  oU-
  U-  n	[        U	5      S:  a
  SU	S-  S S3nX#U4$ ! , (       d  f       N= fs  sn f )Nr   NNNc              3      >#    U  HH  nTR                  U5      (       d  M  TR                  U5      (       d  M3  TTU   -
  S :  d  MA  TU   v   MJ     g7f)r   NrZ   ).0srF   snap_psnap_ts     r'   	<genexpr>!get_best_price.<locals>.<genexpr>   sO      Q%RZZ] '-zz!} :=q	/R9O &)%Rs   AA
AAr   +c              3   *   #    U  H	  u  pUv   M     g 7fr*   r-   )r   r   _s      r'   r   r      s     )541Q5s   r   r   r   r{   gMb@?zEDGE d   +.3fz% Binance vs others)r\   dictr]   r^   r[   nextjoinrb   )srcvalidrh   srcsedgebrV   kavgdivrF   r   r   s             @@@r'   get_best_pricer      s   	f[(9v 
IIKC+1n6CVC[VC[VY\bcf\gVgkmUmc6#;6En) Q%R QRVXE)HH)5))DDY
!3VH5E!AQ1ukc'S3s8fuSWTN:M%Nd 
 os#   D
D$D$(
D$6D$
D!c                     [         R                   " 5       o [        -
  n[           [         VVs/ s H  u  p#X!:  d  M  X#4PM     nnn[         VVs/ s H  u  p#X S-
  :  d  M  X#4PM     snn[        S S & S S S 5        [	        W5      [
        :  a  gUS   S   oTS   S   nXe-
  U-  nUS-  S S3nU[        :  a  US	U4$ U[        * ::  a  US
U4$ USU4$ s  snnf s  snnf ! , (       d  f       Nq= f)NX  r   r   r   r   r   %UPDOWNFLAT)r[   MOMENTUM_SECONDSr\   r_   lenWARMUP_TICKSMOMENTUM_THRESHOLD)	rF   cutofftrU   recentoldestnewestmompcts	            r'   get_momentumr      s    
))+C&6 6v	%2B]TQak&1&]B/<O}tq3YFQF}Oa 
 6{\!*:AYq\F2JqM6?f
$CWTN!
C	#	#C,<%<	##	#C,<%< CO 
s3   
CCCCC"C)CC
C-c                  J     [         R                  " SSS9n U R                  S:X  a  U R                  5       R                  S/ 5      nU(       a  [	        US   R                  SS5      5      nUS:  a  [
        R
                  " 5       n[           U[        S'   U[        S'   [        R                  X245        W(       a.  [        X$-
  U-  5      [        :  a  [        R                  5         UnS	S	S	5        [
        R                  " S
5        GM  ! , (       d  f       N'= f!    N.= f)uF   OKX spot BTC price — free, no auth, reliable alternative to Binance.8https://www.okx.com/api/v5/market/ticker?instId=BTC-USDTr   r   r   rg   r   lastr   Nr   )r   rZ   r   rW   rY   r[   r\   r]   r^   r_   r`   rb   rc   rd   re   r   )r   rg   rh   rF   ra   s        r'   poll_okxr      s    
	WabcA}}#vvx||FB/!$q'++fa"89Eqy"iik',1F5M;u3E)00#>,e6K}5\1]ar1r . 2 2 405 ( 	

1!  (Z 	s+   BD AD,D 
DD D D"c                       [         R                  " SSS9n U R                  S:X  a  U R                  5       R                  S0 5      R                  S/ 5      nU(       ap  [	        US   R                  SS5      5      nUS:  aL  [
        R
                  " 5       n[           U[        S	'   U[        S	'   [        R                  X245        S
S
S
5        [
        R                  " S5        M  ! , (       d  f       N&= f!    N-= f)u8   Bybit spot BTC price — free, no auth, good redundancy.Dhttps://api.bybit.com/v5/market/tickers?category=spot&symbol=BTCUSDTr   r   r   r   listr   	lastPricer   Nr   r   )r   lstrh   rF   s       r'   
poll_bybitr     s    
	cmnoA}}#ffhll8R044VR@!#a&**[!"<=Eqy"iik'.3F7OC[5I)00#> ( 	

1  (Z 	s*   BC8 )C'C8 '
C51C8 5C8 8C<c                        [        5       n [           U qU (       a  U S   OSqSSS5        U  H  n[	        U5        M     [
        R                  " [        5        MZ  ! , (       d  f       N>= f!    N1= f)u   
Background thread — refreshes ALL open KXBTC15M markets every 3 seconds.
Main loop scores each market independently for more trading opportunities.
r   N)get_all_15m_marketsmarket_cache_lockall_markets_cachemarket_cacherecord_kalshi_pricer[   r   KALSHI_POLL_INTERVAL)marketsms     r'   poll_kalshi_marketr      sh     	)+G"$+!-4wqz$ # #A&  	

'(  #"
 	s!   A- AA- 
A*&A- -A1c           	      P   U (       d  g[            [        R                  [        R                  " 5       U S   U S   45        [        R                  " 5       S-
  n[         VVVs/ s H  u  p#oBU:  d  M  X#U4PM     snnn[        SS& SSS5        gs  snnnf ! , (       d  f       g= f)z/Store Kalshi contract prices for lag detection.Nyes_askno_askr   )kalshi_price_lockkalshi_price_historyr`   r[   )marketr   r   yns        r'   r   r   1  s    6	##TYY[&2CVHEU$VWs"8L"\8Luq1U[P[7A78L"\Q	 
	 #]	 
	s$   AB#B
3B
;BB
B%c                    U (       a  U(       d  gU S   nU S   nU S   nU S   nUS::  d  US::  a  gUS-  nUS:  a  g[        5       nUS:  a  US	-  O[        nXS
-  -  n	X-
  U-  n
U	S:  a  [        U
5      U	-  nOSnUS:  a  SnO&US:  a  SnOUS:  a  SnOUS:  a  SnOUS
:  a  SnOSnSnSnU
S:  a  X-
  nSnOU
S:  a  X-
  nSnU[        :  a  g[	        [        SUS-  5      5      nUS:  a  US:  a  [        SUS-   5      nX4$ )u   
SIGNAL 1 — EXPIRATION VALUE (0-50 pts)
Is BTC clearly above/below floor with time running out?
Is Kalshi underpricing the actual probability?
r   Nfloor	secs_leftr   r   r   g      N@g      @g      Y@r   r   g
ףp=
?       @gGz?r   g)\(?g      ?g?g?gp=
ף?N        r   r   2   i  r   )get_btc_volatilityBTC_VOL_PER_MINrb   MIN_MISPRICINGrD   min)r   	btc_pricer   r   r   r   	mins_leftlive_volvol_per_minexpected_range_pctdistance_pctz_scoreexpected_prob	direction
mispricingscores                   r'   score_expiration_valuer   :  s^    7E$I	"G!FA~!GT!I3w!#H(018e#/K$S(89%2LAl#&88 #~	C	C	C	C)-IJa",
			"+
	N"7B
S()*E1}CB	"r.   c                   ^ U (       a  U(       d  g[         R                   " 5       nU[        -
  m[           [        U4S j[         5       S5      nSSS5        W(       d  gX-
  U-  n[        U5      [        :  a  g[           [        U4S j[         5       S5      nSSS5        W(       d  gUu  pgU S   nU S   n	US:  a1  US-  n
X-
  nX-
  nUS	:  a  [        [        S
US-  5      5      nUS4$  gUS:  a8  [        U5      S-  nX-
  nX-
  nUS	:  a  [        [        S
US-  5      5      nUS4$ g! , (       d  f       N= f! , (       d  f       N= f)u   
SIGNAL 2 — LAG DETECTION (0-30 pts)
Did BTC move recently but Kalshi hasn't repriced yet?
Detect the window where we can enter before market makers catch up.
r   c              3   <   >#    U  H  u  pUT:  d  M  Uv   M     g 7fr*   r-   )r   r   rU   r   s      r'   r   &score_lag_detection.<locals>.<genexpr>t  s     CmdaqF{ms   	Nc              3   >   >#    U  H  u  po1T:  d  M  X#4v   M     g 7fr*   r-   )r   r   r   r   r   s       r'   r   r   z  s     U1EgaAf6A61Es   
r   r   r   r   Q?r      r   r   )r[   LAG_WINDOW_SECSr\   r   r_   rb   LAG_MIN_BTC_MOVEr   r   rD   r   )r   r   rF   old_btcbtc_move
old_kalshiold_yesold_nocur_yescur_noexpected_yes_moveactual_yes_movelagr   expected_no_moveactual_no_mover   s                   @r'   score_lag_detectionr  i  sJ    7YY[C?"F	CmCTJ 
7#w.H
8}''	U1EUW[\
 
g OGi GhF!|$sN#-1:Bc	*+E$;   
Ax=3.!?/:Bc	*+E&= ; 
 
	s   D0E0
D>
Ec                 l    U (       a  Uc  g[        U5      [        -  n[        [        SUS-  5      5      $ )u   
SIGNAL 3 — MOMENTUM CONFIRMATION (0-20 pts)
Used only as a tiebreaker or confirming signal.
Never triggers a trade on its own.
r   rw      )rb   r   rD   r   )r   momentumstrengths      r'   score_momentumr    s3     (8}11Hs2x!|$%%r.   c                    U (       a  U(       d  g[        X5      u  pE[        X5      u  pgU=(       d    U=(       d
    US;   a  UOSnU(       d  gUS:H  =(       a    US:H  =(       d    US:H  =(       a    US:H  n	U	(       a  gX8:X  a  [        X5      OSn
US:  a  US:  a  U
S:X  a  gU
S:X  a  gU
[        :  a  gUS:  a  US:X  a  gXF-   U
-   nSU SU S	U
 3nU[        :  a  S
nOU[
        :  a  SnOSnXX4$ )zi
Master scoring function. Combines all 3 signals.
Returns: (score, trade_direction, tier, breakdown_str)
)r   NN )r   r   Nr   r   r   zEXP:z LAG:z MOM:HIGHMEDIUM)r   r  r  MIN_MOM_SCORE
SCORE_HIGHSCORE_MEDIUM)r   r   r  r   	exp_scoreexp_dir	lag_scorelag_dir	trade_diropposing	mom_scoretotal	breakdowntiers                 r'   get_confidence_scorer)    s   
 +<1&DI.vAIY7YI4NyTXI.T!9i6&9 ;V#9	T(9  7@7My3STI1}Q9>  A~  =   1}a !I-EykykykBI	*	v	,	x'+T,,r.   c                     U [         :  a  gU S:  a  SnO/U S:  a  SnO&U S:  a  SnOU S:  a  S	nOU S
:  a  SnOU S:  a  SnOSn[        X-  S5      n[        S[        X1S-  5      5      nU$ )z
Kelly-inspired dynamic bet sizing.
Bet size scales with BOTH confidence score AND current balance.
Higher score = bigger % of balance. Balance grows = bets grow.
Hard floor: $0.50. Soft cap: 15% of balance per trade.
r   Z   g333333?U   gQ?K   g{Gz?A   g?7   r  r   g{Gz?{Gz?r{   r   )r  roundmaxr   )r   current_balancer   bets       r'   get_dynamic_betr5    s     |C	"Dc	"Dc	"Dc	"Dc	"Dc	"Dc c
%q
)C
dCt34
5CJr.   c           
          U S:X  a/  [        [        [        [        [        [
        S-  5      5      S5      $ [        [        [        [        [        [
        S-  5      5      S5      $ )u0   Legacy wrapper — used when no score available.r  g?r{   r0  )r1  r   BET_HIGH_MAXr2  BET_HIGH_MINrL   BET_MED_MAXBET_MED_MIN)r(  s    r'   get_bet_for_tierr;    sG    v~Ss<5'IJANN[#k7U?"CDaHHr.   c                  t   Sn Sn[        SU 5      n [        R                  " [        U -   U-   USS9nUR                  S:w  a  / $  [
        R
                  R                  [
        R                  R                  5      n/ nUR                  5       R                  S/ 5       GHz  n [
        R
                  R                  US   R                  S	S
5      5      n[
        R
                  R                  US   R                  S	S
5      5      nXts=::  a  U::  Ga  O  Mz  X-
  R                  5       n	U	S:  a  M  UR                  US   [        UR                  S5      =(       d    S5      [        UR                  S5      =(       d    S5      [        UR                  S5      =(       d    S5      [        UR                  S5      =(       d    S5      [        UR                  S5      =(       d    S5      U	[        UR                  S5      =(       d    S5      S.5        GMz  GM}     [        US S9$ !   / s $ = f!    GM  = f)zReturn ALL currently open KXBTC15M markets (Kalshi often has 2-3 overlapping).
Sorted by secs_left ascending so we score shortest-window first.z/trade-api/v2/marketsz,?status=open&limit=20&series_ticker=KXBTC15MGETr   )headersr   r   r   	open_timeZz+00:00
close_timer   tickeryes_ask_dollarsr   yes_bid_dollarsno_ask_dollarsno_bid_dollarsfloor_strikevolume_24h_fp)rB  r   yes_bidr   no_bidr   r   volumec                     U S   $ )Nr   r-   )xs    r'   <lambda>%get_all_15m_markets.<locals>.<lambda>  s    ;r.   )key)rI   r   rZ   BASE_URLr   rE   rF   timezoneutcrW   fromisoformatreplacetotal_secondsr`   rY   sorted)
r%   paramsr>  r   rF   r   r   open_tclose_tsecss
             r'   r   r     s    &D<F%&GLLD617AN==C




 1 1 5 5
6CGVVX\\)R(	''55an6L6LSRZ6[\F''55ao6M6McS[6\]G'''446"9h !( %aee,=&>&C! D %aee,=&>&C! D %aee,<&=&B C %aee,<&=&B C %aeeN&;&@q A!% %aeeO&<&A B D E (	 )" '788) 2I& 	s%   1H( #A3H1H12C#H1(H.1H7c                  2    [        5       n U (       a  U S   $ S$ )z,Legacy: returns first active market or None.r   N)r   )r   s    r'   get_15m_marketr]    s    !#G 71:*d*r.   c                 J   SU  3n[        SU5      n[        R                  " [        U-   US9nUR                  S:X  af  UR                  5       R                  S0 5      n[        UR                  S5      =(       d    S5      [        UR                  S5      =(       d    S5      4$ g	)
Nz/trade-api/v2/markets/r=  )r>  r   r   rD  r   rF  )NN)rI   r   rZ   rQ  r   rW   rY   )rB  r%   r>  r   r   s        r'   get_live_pricer_    s    &vh/D%&Gll8d?G<A}}FFHLL2&aee-.3!4aee,-235 	5r.   rw   c                  D  ^ [            [        SS  V Vs/ s H  u  pUPM	     nn nSSS5        [        W5      S:  a  g[        U5      [        U5      -  m[        U4S jU 5       5      [        U5      -  n[	        US-  T-  S-  S5      $ s  snn f ! , (       d  f       Nq= f)	u;   Std deviation of last 60 BTC ticks — measures choppiness.iN
   r   c              3   2   >#    U  H  oT-
  S -  v   M     g7f)r{   Nr-   )r   rU   means     r'   r   %get_btc_volatility.<locals>.<genexpr>  s     3FqH?Fs   r   r   r   )r\   r_   r   sumr1  )r   rU   r   variancerc  s       @r'   r   r     s    	 -cd 34 3! 34 

6{Rv;V$D3F33c&kAH(c/T)C/33	 5 
s   BBBB
Bc           
      &   [         R                   R                  5       n0 SU_SU S   _S[        R                  " 5       _SUR                  S5      _SUR                  _SUR                  5       _SU S   _S	U R                  S	S
5      _SU R                  SS
5      _SU S   _S[        [        U R                  SS5      5      S-  S5      _S[        [        U R                  SS5      5      [        -  S5      _S[        5       _SU R                  SS5      _S[        U R                  SS5      U R                  SS5      -
  S5      _SU R                  SS5      _SU R                  SS5      _U R                  SS5      U R                  SS5      U R                  SS5      U R                  SS5      U R                  SS
5      S .EnUS!:X  a  Ub  [        [        R                  " 5       U R                  S#[        R                  " 5       5      -
  5      nUR                  U[        US5      [        X S   -
  U S   -  S-  S5      U=(       d    SS:  a  S$OS%UUS&.5          [        [        5       n[        R                   " U5      n	S"S"S"5        W	R#                  U5        [        [        S'5       n[        R$                  " XS[&        S(9  S"S"S"5        g"! , (       d  f       NS= f!   / n	 N\= f! , (       d  f       g"= f! [(         a
  n
 S"n
A
g"S"n
A
ff = f))zJWrite rich per-trade data to trade_analytics.json for the learning engine.eventrB  rG   time_str%H:%M:%Shourday_of_weekr   signal_type?r(  entry_pricemomentum_pctmomentum_rawr   r   r   momentum_strengthr{   btc_volatilitymarket_yes_askmarket_spreadmarket_yes_bidr   r   r   	entry_btcconfidence_scorer  r!  r%  )rx  r  r!  r%  confidence_tierexitN
entry_timeWINLOSS)
exit_pricepnlpnl_pctoutcomeexit_reason	hold_secswindentdefault)rE   rF   r[   strftimerk  weekdayrZ   r1  rb   r   r   rD   updater"   ANALYTICS_PATHrW   loadr`   dumprC   r   )posrh  r~  r  r  rF   recordr  r&   rg   r   s              r'   log_analyticsr    s   





!CUS] 	TYY[ 	S\\*5	
 	SXX 	S[[] 	S- 	SWW]C8 	SWWVS1 	S/ 	U3sww~q'A#BS#H!L 	U3sww~q'A#BEW#WYZ[ 	/1 	SWW%5q9 	U377+;Q#?#''JZ\]B^#^`ab  	SWW[!4!" 	SWW[!4#$ !WW%7; WW[!4 WW[!4 WW[!4 WWVS1-F0 :1		cgglDIIK&HHI	% a= *=/A"ASEW!WZ]!]_`a%(XAN5&$
 		n%499Q<D%F.#&!TYYtqRU-V&& &%r&& sf   K" -KK" !K< -K+K< 
KK" K< K" "K(&K< +
K95K< 9K< <
LLc                    U (       d  g[         R                   R                  5       n[        n  [        U5       n[        R
                  " U5      nSSS5        [        R                  " 5       nW V	s/ s H)  oR                  S5      (       d  M  XS   -
  S::  d  M'  U	PM+     n
n	U V	s/ s H)  oR                  S5      (       d  M  XS   -
  S::  d  M'  U	PM+     nn	U
(       a  U
S   S   OU nU(       a  US   S   OU n[        X-
  U-  S-  S5      n[        X-
  U-  S-  S5      nUUR                  S	5      UR                  UR                  5       U UUU(       a  [        US-  S5      OSU=(       d    S
[        5       U(       a  US   OSU(       a  US   OSU(       a  [        US   US   -
  S5      OSU(       a  US   OSS.nUR                  U5        [        U5      S:  a  USS n[        US5       n[        R                  " Xv[         S9  SSS5        g! , (       d  f       GN= f!   / n GN= fs  sn	f s  sn	f ! , (       d  f       g= f!    g= f)u   
Runs every scan cycle. Tracks BTC price trend + Kalshi odds over time.
Stored in market_snapshots.json — separate from per-trade analytics.
NrG   r.  i1  r   r   r   r   rj  r   r   r   rI  r   r   )rG   ri  rk  rl  r   
btc_chg_1m
btc_chg_5mr  r   
volatilityr   r   spreadr   i  i0r  r  )rE   rF   SNAPSHOTS_PATHr"   rW   r  r[   rZ   r1  r  rk  r  r   r`   r   r  rC   )r   r   r  r   rF   	snap_pathr&   snapsnow_tsr   snaps_1msnaps_5m
btc_1m_ago
btc_5m_agochg_1mchg_5mr  s                    r'   log_market_snapshotr  L  s   
 f





!CI 	iAtyy|u 99;$_u!k(:A;@W\^?^Au_$`u!k(:A;@W\_?_Au`2:Xa[-	
2:Xa[-	
	.*<sBAF	.*<sBAF!<<
388;;=$!!7?5C3Q$.-/176),T176(+TNT5	!2VI5F!FJZ^286+.d
  	Vu:eEFme)S!Q		%C(H!!; ! ``0 "!Ds   H) HH) I 2H3	H3H3"I (H8	H8H8DI 4H=I 
H&!H) $I &H) )H0-I =
II I Ic                      [        [        5       n [        R                  " U 5      nSSS5        W Vs/ s H  o"R	                  S5      S:X  d  M  UPM     nn[        U5      [        :  a  gSSKJn  U" S 5      nU HJ  nUR	                  SS5      nXW   S==   S	-  ss'   UR	                  S
5      S:X  d  M;  XW   S==   S	-  ss'   ML     UR                  5        VVs/ s H+  u  pxUS   [        :  d  M  US   US   -  [        :  d  M)  UPM-     n	nnUR                  5        VVs/ s H+  u  pxUS   [        :  d  M  US   US   -  [        ::  d  M)  UPM-     n
nnU" S 5      nU HR  nUR	                  SS5      S:  a  SOSnX   S==   S	-  ss'   UR	                  S
5      S:X  d  MC  X   S==   S	-  ss'   MT     SnUS   S   [        :  a%  US   S   US   S   -  nU[        ::  a
  SUS-  S S3n[        [        5      n[        [        5      n[        U	5      n[        U
5      nUU:g  =(       d    UU:g  n/ nU(       a(  UR!                  SU Vs/ s H  owS S3PM
     sn 35        U(       a(  UR!                  SU Vs/ s H  owS S3PM
     sn 35        U(       a  UR!                  U5        [#        [$        R$                  R'                  5       5      [        U5      UUUS.n[        [(        S5       n [        R*                  " UU SS9  SSS5        UqUq[        U5      qU(       a>  U(       d  U(       a0  [/        S[        U5       S 35        U H  n[/        S!U 35        M     g[/        S"[        U5       S#35        g! , (       d  f       GNa= f!    g= fs  snf s  snnf s  snnf s  snf s  snf ! , (       d  f       N= f)$u#  
Runs every AUTO_RETUNE_EVERY completed trades.
Only updates auto_params.json when patterns are very strong:
  - 60%+ win rate AND 20+ trades in bucket = mark as GOOD hour
  - 40% or below AND 20+ trades = mark as AVOID hour
Does NOT constantly tweak — only acts on overwhelming evidence.
Nrh  rz  r   )defaultdictc                      SSS.$ Nr   )winsr&  r-   r-   r.   r'   rN  auto_analyze.<locals>.<lambda>  s	    A#:r.   rk  r&  r   r  r|  r  c                      SSS.$ r  r-   r-   r.   r'   rN  r    s	    1q"9r.   rr  r   strongweakr  zWeak signals losing (r   .0fu$   % WR) — consider raising thresholdz"Best hours (60%+ WR, 20+ trades): 02dz:xxz%Avoided hours (40%- WR, 20+ trades): )generated_attrades_analyzed
good_hoursavoid_hoursnotesr  r{   )r  z 
  [LEARN] Auto-params updated ( trades analyzed)    z
  [LEARN] uO    trades analyzed — no strong patterns yet (need 60%+ or 40%- with 20+ trades))r"   r  rW   r  rZ   r   AUTO_RETUNE_EVERYcollectionsr  itemsAUTO_MIN_BUCKET_TRADESAUTO_MIN_WIN_RATEAUTO_MAX_WIN_RATErW  r  r  r`   rC   rE   rF   AUTO_PARAMS_PATHr  _last_autotune_countrN   )r&   rg   r   exitsr  hour_mapr   hdnew_good	new_avoidmom_mapbucket	weak_noteweak_wrexisting_goodexisting_avoid
new_good_snew_avoid_schangedr  rX  notes                          r'   auto_analyzer  w  s   .!Qtyy|!91g& 8QE9
5z%%v':;HEE&!G!55u$hk&&9Q&>&9  !) 0 C 0wZ#99 i!G*,0AA  0H C !) 0 C 0wZ#99 i!G*,0AA  0I C 9:GUU#6:cAv A% 55u$gof&=&B&= 
 Ivw#99&/&)GFOG,DD''/C/@@deIJ'MK(N"J#K]*Kk^.KGEELL#E^hFi^hYZCPS}^hFiEj!klELL#HalImal\]sGSV-alImHn!opELL+ 1 1 5 5 78J&'!F 
	$499VQq+I	$JKu:J+1#e*=NOPD54v/E
3u:,&uvwo "!F9CC, GjIm 
%	$sn   N NN NNN 5N 
N &N&=N&N&N,
 N1
6N6
NN N N6
Oc                  T    [         [        4 H  n [        R                  " U SS9  M     g)z;Create data/ and data/archive/ folders if they don't exist.T)exist_okN)DATA_DIRARCHIVE_DIRosmakedirs)r  s    r'   ensure_data_dirsr    s    $
A% %r.   c                    [         R                  R                  U 5      (       d  g [        U 5       n[        R
                  " U5      nSSS5        [        W[        5      (       d  [        U5      $ [        U5      nXR:  a  [        R                  R                  5       R                  S5      n[         R                  R                  U 5      R                  SSU S35      n[         R                  R                  [        U5      n[        US5       n[        R                   " XCS["        S9  SSS5        [        U S5       n[        R                   " / U5        SSS5        [%        S	U S
U SU 35        gU$ ! , (       d  f       GN5= f! , (       d  f       Nc= f! , (       d  f       NH= f! [&         a  n	[%        SU S
U	 35         Sn	A	gSn	A	ff = f)z
If a JSON file has >= threshold records, move it to archive with a timestamp.
Archives are NEVER deleted. The working file is reset to empty [].
r   Nz%Y%m%d_%H%M%Sz.jsonr   r  r{   r  u     🗄  z: u#    records archived → data/archive/u      ⚠  archive check failed for )r  r%   existsr"   rW   r  
isinstancer   r   rE   rF   r  basenamerU  r   r  r  rC   rN   r   )
r%   label	thresholdr&   rg   countr=   fnamedestr   s
             r'   archive_file_if_larger    sQ   
 77>>$$Z1TYYq\dZ$%%c$i'7D	%%))+44_EBGG$$T*227at5MJEGGLLe4DdCAtyyC'PdCAtyyQ'7HUG2eW,OPUwWX Z !   0r!=>sk   F+ E7	'F+ 1B F+ F	,F+  FF+ 5F+ 7
FF+ 	
FF+ 
F($F+ +
G5GGc                  X   [        5          [        R                  R                  [        5      (       d  g[        [        5       n [        R                  " U 5      nSSS5        WR                  S/ 5      nU Vs/ s H  o3R                  S5      S:X  d  M  UPM     nnU Vs/ s H  o3R                  S5      S:X  d  M  UPM     nnU Vs/ s H  o3R                  SS5      S:  d  M  UPM     nn[        [        S U 5       5      S	5      nUR                  S
[        5      nUR                  S[        5      n	U(       a$  [        [        U5      [        U5      -  S-  S5      OSn
[        R                  R                  5       R                  S5      [        U5      [        U5      [        U5      [        U5      [        U5      -
  U
U[        UU	[        U[        -
  [        -  S-  S5      S.n/ n[        R                  R                  [         5      (       a/   [        [         5       n [        R                  " U 5      nSSS5        UR#                  U5        [        [         S5       n [        R$                  " XS[&        S9  SSS5        U(       a   [)        S[        U5       SU
S SUS 35        g[)        S5        g! , (       d  f       GNg= fs  snf s  snf s  snf ! , (       d  f       N= f!   / n N= f! , (       d  f       N|= f! [*         a  n[)        SU 35         SnAgSnAff = f)z
Called at startup BEFORE paper_log is wiped.
Reads the last session's paper_log and appends a summary to session_history.json.
Even sessions with 0 trades are recorded so we have a complete run history.
Ntradesrh  rz  entryr  r   c              3   D   #    U  H  oR                  S S5      v   M     g7fr  r   Nr   r   r   s     r'   r   'save_session_summary.<locals>.<genexpr>  s     =u!eeE1oou    r   rL   rM   r   r   z%Y-%m-%d %H:%M:%Sr{   )session_endr  entriesr  losseswin_rate_pct	total_pnlstart_balanceend_balancepeak_balancer  r  r  u     💾 Session saved: z trades | WR:r  z	% | P&L:$+.2fuB     💾 Session saved: 0 trades this session (recorded for history)u'     ⚠  Could not save session summary: )r  r  r%   r  PAPER_LOG_PATHr"   rW   r  rZ   r1  re  STARTING_BALANCEr   rE   rF   r  SESSION_LOG_PATHr`   r  rC   rN   r   )r&   logr  r   r  r  r  r  end_balpeak_balwin_ratesummaryhistoryr   s                 r'   save_session_summaryr    sn    '=ww~~n--v.!Qdiil!GGHb) &C1%%.F*BQC &D1%%.G*CQD %=1ua1)<Q=#=u==qA	GGI'78GG-/?@>CE#d)c%j036:'00446??@ST"5z"7|"4y"5zCI5'(/&'$g0@&@DT%TWZ%Z\]^
 77>>*++!*+qDIIaL'+w"C(AIIgC8 )*3u:,mHS>QZ[deiZjklVXE "!CD=, ,+ bG((  =7s;<<=s   (L L J;L 9KKL !K=KL 	K&K,D)L K- %K<K- !L %K6 .L /L ;
K
L 
K*&K- )L *K- -K31L 6
L L 
L)L$$L)c                      [        5         [        5         [        [        S[        5      n [        [
        S[        5      nU S:  a  [        SU S S[        S S35        US:  a  [        SUS S[        S S35        g	g	)
z
Master data preservation call. Run at every startup before anything is reset.
1. Save session summary from last run
2. Auto-archive large files to data/archive/
3. Never delete anything
trade_analyticsmarket_snapshotsr   u     📊 Analytics:  ,z records  (archives at )u     📊 Snapshots:  N)r  r  r  r  ARCHIVE_ANALYTICS_ATr  ARCHIVE_SNAPSHOTS_ATrN   )a_counts_counts     r'   preserve_and_archiver    s     #N5FH\]G#N5GI]^G{#GA;.EFZ[\E]]^_`{#GA;.EFZ[\E]]^_` r.   c                      [        [        S5       n [        R                  " [        [
        [        S.U S[        S9  S S S 5        g ! , (       d  f       g = f)Nr  rL   rM   r  r{   r  )r"   r  rW   r  rL   rM   	paper_logrC   )r&   s    r'   save_logr    s:    	nc	"a		g/&()*1c	C 
#	"	"s   ,A
Ac
                 :   [          V
s/ s H  oR                  S5      S:X  d  M  U
PM     nn
/ n[         GHY  nUR                  SUS   5      n[        XS   -
  US   -  S5      n[        XS   -
  US   -  S-  S5      n[	        [
        R
                  " 5       UR                  S	[
        R
                  " 5       5      -
  5      nUR                  0 S
US
   _SUS   _SUS   _SUR                  SS5      _SUR                  SS5      _SUS   _SU_SUS   _SUS   _SUS   _SUS   _SU_SU_SUS   _SU_S[        R                  R                  UR                  S	[
        R
                  " 5       5      5      R                  S5      _5        GM\     [        [        S[        -
  -  S5      nXxU	nnn0 SS_S[
        R
                  " 5       _SU _SU_SU=(       d    S _S![        [        S5      _S"[        _S#[        [        S5      _S$U_S%U=(       d    S&_SU=(       d    S'_S(U_S)[        _S*U_S+U=(       d    S,_S-U=(       d    S _S.U_XS/.En [        S0S15       n[         R"                  " UU[$        S29  S S S 5        g s  sn
f ! , (       d  f       g = f!    g = f)3Nrh  rz  current_pricero  r  r   r   r{   r{  rB  sider   rm  rn  r(  targetstopcostpnl_absr  r   	held_secsentry_time_strrj  r   modepaperlast_updater   
btc_sourcer   r  rL   starting_balancerM   
stop_levelr  r   r   bet_tiersession_haltedrx  ry  --score_breakdownr   )open_positionscompleted_tradeszC:\kalshibot\bot_state.jsonr  r  )r  rZ   paper_positionsr1  rD   r[   r`   rE   fromtimestampr  rM   rO   rL   r  r  r"   rW   r  rC   )btcsourcesr   r  r   r   r  r   r(  r'  r   r  pos_datarU   currentr  r  r  r  _sc_tr_bdstater&   s                           r'   
save_stater&    sJ   !>	1UU7^v%=Q	E> H_%%=)9:]#33qzA1E]#33q7GG#MqQ		aeeL$))+&FFG	 
Qx[
QvY
 Q{^
 QUU=#6	

 QUU63/
 Q}-
 W
 Qx[
 QvY
 QwZ
 QvY
 W
 W
 QwZ
 Y
  h//==lDIIK022:(:2F#
 	 2 !.?*?@!DJcC&		S&17 	5!$ '9:J 	5!4	 7CJ	
 	HM
 $/	0CV 	H / 	C 	3;$ 	39" 	& -5E1371IIeQ, 87[ ?Z 87Ds4   J J J J7J 
JJ J Jc	                 .  ^ U S   n	US:X  a  SOSn
U
S:X  a  U S   OU S   n[         Us=::  a
  [        ::  d  g  gU(       a  UO
[        U5      n[        U[        S-  5      n[        S	[        S
[        X-  5      5      5      n[        X-  S5      nU[        :  a  SU4$ [        [        US
[        -   -  S5      S5      n[        US
[        -
  -  S5      n[        X-
  U-  S5      n[        UU-
  U-  S5      nUS:  a  [        UU-  S
5      OSn[        U S   S-  5      n[        U S   S-  5      nU4S jnU" S5      nU" S5      nU" S5      n0 SU S   _SU
_SU_SU_SU_SU_SU_SU_SU_SU_S[        R                  " 5       _S U_S!U_S"U S"   _S#U_S$U_S%U=(       d    S_U S   U S&   U S   UUUUS'.En[        U-  q[           [        R                  U5        S S S 5        [        R                  0 UES([        R                  R!                  5       R#                  S)5      S*.E5        [%        US(5        ['        5         [        [(        S
[*        -
  -  S5      n[-        S+S, 35        [-        S-U S.U
S:X  a  S/OS0 35        [-        S1US2 S3U S"   S2 35        [-        S4US5 S6U S7US8 S9U S:U S;35        [-        S<US8 S=US5 S>US8 S=US5 S?U S@35        [-        SA[        S8 SB[(        S8 SCUS8 35        [-        SDS, 35        SEU4$ ! , (       d  f       GN0= f)FNrB  r   yesnor   r   )FSKIPg?ra  r   r{   Fr   gq=
ףp?r   r   <   c                 ~   > [         R                  " U  S3T5      nU(       a  [        UR                  S5      5      $ S$ )Nz:(-?\d+)r   r   )researchrD   group)tagr   r  s     r'   _parsepaper_enter.<locals>._parsec  s3    II#h'9"#s1771:**r.   EXPLAGMOMr	  ro  r  r  r  r
  r  max_gainmax_lossr{  rw  r   r   r(  rm  rq  rI  )rt  rv  r   rx  r  r!  r%  r  rj  )rh  ri  
  z>==============================================================z  PAPER TRADE []  z
YES BTC UPzNO  BTC DOWNz  BTC: $,.2fz
  Floor: $z
  Entry: $.3fz xz = $rK     |  zm s leftz  Target: +$z ($z)  Stop: -$z)  [z:1]  Balance: $	  Peak: $z  Trailing stop: $  T)MIN_ENTRY_PRICEMAX_ENTRY_PRICEr;  r   rL   r2  rD   r1  PROFIT_TARGET	STOP_LOSSr[   position_lockr  r`   r  rE   rF   r  r  r  rM   rO   rN   )r   trade_directionrm  r   r  r   override_betoverride_scorer  rB  r	  ro  r4  r  r  r
  r  r6  r7  rrminssecs_rr1  exp_slag_smom_sr  r  s           `                   r'   paper_enterrO  P  s   HF*d2%D'+u}&#&:JK{=o=}=}(L.>{.KCWt^$CC3s0123E+%q)Dg~e[005M(9:A>EF[A	M2A6Df*e3Q7HkD(E115H081uX(!,!B6+&",-D6+&+,F+ 5ME6%=5&-%G8VH% Gvt G]K GKGEG!4G)16G;A4G xG ",XG 	G '29	G
 G
 *1&/G ;G !.{G 8=qG $I.#I.{+-EGC tOG	s# 
 P Pg"*"3"3"7"7"9"B"B:"NP Q#wJ!.?*?@!DJ	D/	OK=D%KL^+\
]^	HYt$Jvgt.D
EF	J{3'r%T#JeD6F8SY
Z[	L#c&[#cRVWZQ[[_`b_ccf
gh	LYs.CCUV`adUe
fg	Bvh- 
s   L
Lc                     [            [        (       d
   SSS5        g/ n [         GHh  n[        US   5      u  p#Uc  M  US   S:X  a  UOUnUS::  a  M.  XAS'   US   nXE-
  U-  n[        XE-
  US   -  S	5      nSnXAS
   :  a  SUS-  S S3nO<XAS   ::  a  SUS-  S S3nO)[        R                  " 5       US   -
  S:  a
  SUS-  S S3nU(       d  M  [        [
        XAS   -  -   S5      qUS:  a  SOSn	[        SU	 SU SUS SUS SUS S[
        S  35        [        R                  0 UES!UXx[
        [        R                  R                  5       R                  S"5      S#.E5        [        US!UXxS$9  U R                  U5        [        5         GMk     U  H  n[        R                  U5        M     SSS5        g! , (       d  f       g= f)%u   
Called by the 2-second fast monitor thread.
Checks every open position for target/stop/time exit.
Prints only when something actually exits — silent otherwise.
NrB  r	  r(  r   r  ro  r  r   r
  zTARGET +r   .1fr   r  zSTOP r{  i  zTIME +.1fr{   zWIN r}  u   
  ⚡[z]   $r;     →$z  P&L:$r  z  Bal:$rK   rz  rj  )rh  r~  r  reasonbalance_afterri  )r~  r  r  )rE  r  r_  r1  r[   rL   rN   r  r`   rE   rF   r  r  r  remove)
to_closer  ybnbr!  r  r  r  rU  icons
             r'   check_exits_fastr\    s     
 
"?C#CM2FBz8K50bbG!|X#* -(E%/GW_G<a@GFM)8GTWKX[K\\]A^K'5QTUXHYYZA[s<00365QTUYHZZ[A\v'L*@ @!D$+qL&fbE#;d73- P%d^773-A B   "]C "]&*14;/7/@/@/D/D/F/O/OPZ/["] ^ c6g")?$
3 #4 C""3' ; 
s   F9B0F9CF99
Gc                     SSK n SSKnSSKnUR                  " S5         " S SU R                  R
                  5      n UR                  SU5       nUR                  5         SSS5        g! , (       d  f       g= f! [         a     gf = f)zXServe the kalshibot folder at localhost:8765 so dashboard.html can fetch bot_state.json.r   Nr
   c                       \ rS rSrS rSrg),start_dashboard_server.<locals>.QuietHandleri  c                     g r*   r-   )selfrp   s     r'   log_message8start_dashboard_server.<locals>.QuietHandler.log_message  s    dr.   r-   N)__name__
__module____qualname____firstlineno__rb  __static_attributes__r-   r.   r'   QuietHandlerr_    s    *r.   ri  )r  i="  )	http.serversocketserverr  chdirserverSimpleHTTPRequestHandler	TCPServerserve_foreverOSError)httprk  r  ri  httpds        r'   start_dashboard_serverrt    sj    ((HH_+t{{;; +##J=! >== s/   A< A+"A< +
A95A< 9A< <
B	B	c                        [         R                  " [        5        [        5         M'  ! [         a
  n  Sn A NSn A ff = f)uR   Daemon thread — checks positions every 2 seconds independently of the main loop.N)r[   r   FAST_MONITOR_INTERVALr\  r   )r   s    r'   fast_monitor_looprw    s7    
	JJ,-   		s   $) 
==c                     [            [         HZ  n U R                  SU S   5      nU S   nX-
  U-  n[        SU S   S:X  a  SOS SUS	 S
US	 SUS-  S SU S   S	 SU S   S	 35        M\     SSS5        g! , (       d  f       g= f)uP   Called by main loop every 10 seconds — just prints HOLD status, no exit logic.r  ro  z  HOLD r	  r(  YESNO rS  r;  rT    (r   rR  z%)  target:$r
  z  stop:$r  N)rE  r  rZ   rN   )r  r!  r  r  s       r'   print_position_statusr|    s    	"Cggos=/ABG-(E%/GGS[%%7EUC DC[WSMWS[4F G ]3/xFC7HJ K	 # 
s   A%A55
Bc                     [        S5        [        S5        [        S5        [         V s/ s H  o R                  S5      S:X  d  M  U PM     nn U(       d  [        S[        S S[        S 35        g U V s/ s H  o R                  S	S
5      S
:  d  M  U PM     nn U V s/ s H  o R                  S	S
5      S
::  d  M  U PM     nn [        [        S U 5       5      S5      n[        [        S U 5       5      S5      n[        [        R                  " 5       [        -
  S-  5      n[        [        R                  " 5       [        -
  S-  S-  5      n[        SU SU S35        [        S[        S 35        [        S[        S S[        [        -
  S S35        [        S[        S 35        [        SUS S[        [        -
  [        -  S-  S S35        [        SUS 35        [        SS  35        [        S![        U5       S[        U5       S"[        U5       S#[        U5      [        U5      -  S-  S$ S%3	5        U(       a  [        S&U[        U5      -  S 35        0 nU Hw  n U R                  S'S(5      n	X;  a  S
S
S
S).X'   X   S*==   S+-  ss'   X   S	==   U R                  S	S
5      -  ss'   U R                  S	S
5      S
:  d  Mh  X   S,==   S+-  ss'   My     U(       ah  [        S-5        [        UR                  5       5       H@  u  pU
S*   (       a  U
S,   U
S*   -  S-  OS
n[        S.U	S/ SU
S*    S0U
S	   S S1US$ S%3	5        MB     [        S2S3S4 SS5S6 SS7S8 SS9S: SS;S: SS<S: S=35        US>S   H  n [        SU R                  S?S(5      S4 SU R                  S'S(5      S6 SU R                  S@5      SA:X  a  SBOSCS8 SDU R                  SES
5      SF SDU R                  SGS
5      SF SDU R                  S	S
5      SH SU R                  S	S
5      S
:  a  SIOSJ 35        M     [        SK5        [        S5        g s  sn f s  sn f s  sn f )LNzC

=================================================================z  PAPER TRADING SESSION REPORTA=================================================================rh  rz  z"  No completed trades.  Balance: $rK   r?  r  r   c              3   D   #    U  H  oR                  S S5      v   M     g7fr  r   r  s     r'   r   print_report.<locals>.<genexpr>  s     95a%%q//5r  r{   c              3   D   #    U  H  oR                  S S5      v   M     g7f)r  r   Nr   r  s     r'   r   r    s     :Eq%%**Er  i  r+  z  Session      : zh r   z  Start        : $z  Peak balance : $z  (+$r  z  Final balance: $z  Total P&L    : $r  r{  r   rR  z%)z  Total wagered: $r@  u   ─────────────────────────────────────────────z  Trades       : zW / zL)  Win rate: r  r   z  Avg/trade    : $rm  rn  )r  r  r  r  r   r  z  By type      :r  z<16z trades  P&L: $z  WR: r8  Timez>8Typez>9Sidez>4Entryz>7ExitzP&Lz  Resultiri  r	  r(  ry  rz  rS  ro  r;  r~  z>+6.2fr|  r}  z#
  Log: C:\kalshibot\paper_log.json)rN   r  rZ   rL   rM   r1  re  rD   r[   session_startr  r   rW  r  )r   r  r  r  r  	total_bethrsrJ  typesstrg   wrs               r'   print_reportr    sJ   	/	
*+	&M!>	1UU7^v%=Q	E>273-yY\H]^_!9EqUU5!_q%8ED9!:EqUU5!_%9EF:c95991=Ic:E::A>I		m+t34C},4:;D	cU"TF!
,-	/4
56	s35IY9YZ]8^^_
`a	wsm
,-	y.c7;K3KM]2]^a2abf1ggi
jk	yo
./	Bxj/	c%j\SYKtCK=WZ[_W`adejakWkloWopsVttu
vwe(3u:)=d(CDEEUU=#&?!Aq(IEI	'a5!1QUU5!_!D!155?Q	& 1Q 6 1	 
  "u{{}-HB37=fd7m+C/aBDC4=/eT@RRXY[\_X``abc . 
D2fR[6"+R|2fR[PRSXY[R\\d
ef34[155C(,Bquu]3/G.K2%%-.E"= >%%a(-S|A1Fs0K L%%a.(AEE%N14D5&*QS 	T 
 
24	&MK ? ::s#   P7P75P<P<Q;Qc                  b   [        5         [        q[        q[	        [
        S5       n [        R                  " [        [        / S.U 5        S S S 5        [        S[        S S35        [        R                  R                  [        5      (       a   [	        [        5       n [        R                  " U 5      nS S S 5        [        SWR                  SS5       S	35        UR                  S
/ 5       H  n[        SU 35        M     UR                  S/ 5      qUR                  S/ 5      qO/ q/ q[        S5        [        S5        [        S5        [        S5        [        S5        [        S5        [        S5        [        S[$         S[&         S35        [        S[(         S35        [        S[*        S-  S S35        [        S[,        S-  S S [.        S-  S S![,        [.        -  S" S#35        [        S$[0        S-  S S%35        [        S&5        [        S5        [2        (       a'  [4        R6                  " [8        S'S(9R;                  5         [4        R6                  " [<        S'S(9R;                  5         [4        R6                  " [>        S'S(9R;                  5         [4        R6                  " [@        S'S(9R;                  5         [4        R6                  " [B        S'S(9R;                  5         [4        R6                  " [D        S'S(9R;                  5         [4        R6                  " [F        S'S(9R;                  5         [4        R6                  " [H        S'S(9R;                  5         [4        R6                  " [J        S'S(9R;                  5         [        S)5        S*S+S, 4S-S.S/ 4S0S1S2 4S3S4S5 4S6S7S8 4/n/ nU HH  u  pgn [L        R                  " US9S:9n	U" U	5      n
[        S;US< S=U
S> 35        URO                  U5        MJ     [        SB[U        U5       SCSDRW                  U5       35        [U        U5      SE:  a  [        SF5        [        SG5        [        SH5        [Y        SI5       GH1  n[Z        R\                  " SJ5        [^           [a        SK [b        Re                  5        5       5      n[U        [f        5      nS S S 5        W(       as  W[h        :  ai  [^           [b        SL   =(       d    [b        SM   =(       d	    [b        SN   nSORW                  SP [b         5       5      nS S S 5        [        SQWSR SSW ST35          OkU(       d  M  [^           [b        SL   =(       d    [b        SM   =(       d	    [b        SN   nS S S 5        [        SUWSR SVW SW[h         SX35        GM4     [        SY5        [        SZ[        S S[[        SJ[0        -
  -  S S\35        S]nS^nS n  [j        Rm                  [&        S:9nU(       a  [j        Ro                  5         [Z        RZ                  " 5       n[q        5         [s        5       u  nnnU(       d<  [        S_[t        Rt                  Rw                  5       Ry                  S`5       Sa35        M  [{        5       u  nnn[|           [        [        5      nU(       a  US]   OS nS S S 5        W(       a/  USb   U:w  a&  USb   n[        ScUSb   SdS   Se[U        W5       Sf35        [^           [U        [f        5      nS S S 5        W[h        :  nSgu  nnn n!n"U(       d8  W(       a1  U H+  n#[        U#UUU5      u  n$n%n&n'U$U:  d  M  U$U%U&U'U#4u  nnn n!n"M-     UUU U!4u  n(n)n*n+U"(       a  U"nU*=(       d    ShnU(       a  SiU SW[h         SA3n,OKU=(       d    Sjn-U*(       a  SSU* ST3OSkn.[U        W5      SJ:  a  SV[U        U5       Sl3OSkn/U- SmU SnU( U. U/ SoU+ 3	n,[        [        SJ[0        -
  -  SE5      n0[        (       a  SpOSkn1U(       d  SqO2[        USr   Ss-  5       St[        USr   Ss-  5       SuUSv   S SwUSx   S 3n2[        SoU(       a  SyOSo Sz[t        Rt                  Rw                  5       Ry                  S`5       S{USR SSU S|U, S}U2 S~[        S S[        S SU0S S[U        [        5       SW[         STU1 35        U(       a  [        SoU 35        [        (       a
  [        5         [        UUUUUUUU(U*U+S9
  [        UUUU5        [U        [         V3s/ s H  n3U3R                  S5      S:X  d  M  U3PM     sn35      n4U4S]:  a!  U4[        :w  a  U4[        -  S]:X  a
  [        5         [t        Rt                  Rw                  5       R                  n5Sn6U(       + =(       a    [        5       (       + =(       a    US L=(       a    U*S L=(       a    U)S L=(       a    [U        [        5      [        :  =(       ay    UU-
  [        :  =(       af    USr   [        :  =(       aS    UR                  SvS]5      S]:  =(       a7    UR                  SxS]5      S]:  =(       a    [        [        :  =(       a    U6(       + n7U7(       Gd  U*Gb  U([        :  Ga  / n8U(       a  U8RO                  S5        [        5       (       a  U8RO                  S5        Uc  U8RO                  Sq5        U*c  U8RO                  SU( S35        U)c  U8RO                  S5        [U        [        5      [        :  a  U8RO                  S5        UU-
  [        ::  a(  U8RO                  S[        [        UU-
  -
  5       S35        U(       a.  USr   [        ::  a!  U8RO                  S[        USr   5       S35        U(       a=  UR                  SvS]5      S]:X  d  UR                  SxS]5      S]:X  a  U8RO                  S5        [        [        :  a  U8RO                  S[        S S35        U6(       a  U8RO                  S5        [        SU( SSU* SSDRW                  U85       35        U7(       a6  [        U([        5      n9U9S]::  a  GM}  [        UU)U*UUUU9U(U+S9	u  n:n;U:(       a  UnGM  ! , (       d  f       GN&= f! , (       d  f       GN= f! ["         a  n[        SU 35        / q/ q S nAGNS nAff = f! ["         a2  n[        S?US< S@[Q        U5      RR                   SA35         S nAG	M?  S nAff = f! , (       d  f       GNJ= f! , (       d  f       GN= f! , (       d  f       GN= f! , (       d  f       GN= f! , (       d  f       GNO= fs  sn3f ! [         a    [        5         [        5          g ["         a/  n[        SU 35        [Z        R\                  " S5         S nAGNBS nAff = f)Nr  r  u     ✅ Paper balance reset to $rK   z  (all learning data preserved)u     ✅ Loaded auto_params.json (r  rn  r  r  z     r  r  u(     ⚠  Could not load auto_params.json: zB
=================================================================z3  PAPER TRADING BOT v1.5  --  $250 Starting BalancezB  KXBTC15M  |  Binance (WS+REST) + Coinbase + Kraken + OKX + Bybitr~  zA  Signal engine : LAG+MOM / MOM-only / EXP+LAG+MOM (v1.5 filters)z@  Filters       : entry>=0.60 | MOM>=8 | EXP blocked without LAGuJ     Bet sizing    : DYNAMIC — scales with score + balance (Kelly-inspired)z  Position mon  : every zs  |  Entry scan: every zs (instant on big BTC move)z"  Kalshi cache  : refreshed every z"s (background thread, no blocking)z/  Hot path      : instant trigger if BTC moves r   z%+ (beats market maker lag)z  R:R           : +r  z% target / -z	% stop = rQ  z:1z'  Trailing stop: halt if balance drops z% from PEAKz7  Dashboard    : Double-click OPEN DASHBOARD on desktopT)r
  daemonzL  Starting: Binance WS + REST, Coinbase, Kraken, OKX, Bybit, Kalshi cache...z
Binance.USr   c                 :    [        U R                  5       S   5      $ )Nrh   rY   rW   r   s    r'   rN  run.<locals>.<lambda>*  s    5'*+r.   Coinbaser   c                 @    [        U R                  5       S   S   5      $ )Nrg   r   r  r  s    r'   rN  r  ,  s    5&)(34r.   Krakenr   c                 L    [        U R                  5       S   S   S   S   5      $ )Nr   r   rV   r   r  r  s    r'   rN  r  .  s#    5(+J7<Q?@r.   OKXr   c                 F    [        U R                  5       S   S   S   5      $ )Nrg   r   r   r  r  s    r'   rN  r  0  s    5&)!,V45r.   Bybitr   c                 L    [        U R                  5       S   S   S   S   5      $ )Nr   r   r   r   r  r  s    r'   rN  r  2  s#    5(+F3A6{CDr.   r   r   u     ✅ z<10z $z>10,.2fu     ❌ z unreachable (r  z  Active feeds: u	   /5  —  z, r{   uJ     ⚠  WARNING: fewer than 2 price sources. LAG detection will be limited.u     ────────────────────────────────────────────────────────────z  Waiting for prices...r   r   c              3   6   #    U  H  o(       d  M  Uv   M     g 7fr*   r-   )r   rU   s     r'   r   run.<locals>.<genexpr>E  s     6AAaas   
	r   r   r   r   c              3   F   #    U  H  n[         U   (       d  M  Uv   M     g 7fr*   )r]   )r   r   s     r'   r   r  I  s     ?6aVAY6s   !	!z  Ready  BTC $r:  z []z  BTC $z (rz   z
 ticks)...u"     Slow feeds — continuing anywayr>  z  Stop at: $z  |  Ctrl+C to stop
r   BASEz  [rj  z] No price datarB  z  [NEW WINDOW] ir{  z markets open))r   NNr  Nr  zwarming up (r   r  zmkts) z  score:r@  z
  [HALTED]z	no marketr   r+  r   zs Y:r   z N:r   u   ⚡[z]  BTC $r9  r<  z  |  $z (peak:$z stop:$z) [)r   r(  r'  rh  rz  Fz
warming upzsession haltedzscore z below thresholdzno directionzmax positionsz	cooldown r=  zonly zs left in windowzmarket has no valid prices yetz	balance $z too lowzhour blocked by learningu     ⚠  score:u   ] SKIP — )rG  rH  r  z	  Error: ra  )Yr  r  rL   rM   r"   r  rW   r  rN   r  r%   r  r  r  rZ   r  r  r   rv  SCAN_INTERVALr   rc   rC  rD  rO   r|   	threadingThreadr   startr   r   r   rt  rw  r   r   r   r   r`   typerd  r   r   ranger[   r   r\   anyr]   valuesr_   r   rd   waitclearrP   r   rE   rF   r  r   r   r   r   r)  r1  r  rD   r  MAX_POSITIONSr|  r&  r  r  r  r  r  rk  rR   ENTRY_COOLDOWNMIN_SECS_LEFTr:  r  r5  rO  KeyboardInterruptr  r  )<r&   apr  r   test_sourcesworkingnamer   parserresprh   ihasticksrU   r   
last_entrycurrent_tierlast_market_tickertriggered_by_hot_pathrF   r  r  r   r  r   r   r   r   warmup
best_scorebest_dir	best_tierbest_breakdownbest_marketmktsctdtrbdr   r#  r(  r'  mom_strr  tier_strn_mktsr  halt_strmkt_strr   	completedcurrent_hourhour_blocked	can_tradereasonsr4  enteredr   s<                                                               r'   runr    se    G2B	nc	"a		.CS_abdef 
#	*+;C*@@_
`a	ww~~&''	.&'1499Q<b'3BFF;LS4Q3RRcdew+UU4&>-B+&&r2J&&3K
 
r	-	
?@	
NO	&M	MO	LN	VX	$%:$;;STaSbb}
~	./C.DDf
gh	;<Mc<QRU;VVq
rs	c 1#6l9S=QTBUU^_lmv_vwz^{{}
~	34Ec4I#3Nk
Z[	CE	&M|
$?EEG-d;AACMd;AACKd;AAC24@FFH-dCIIK.dCIIKHdCIIKJdCIIK	
XY 
Q	+	-	F	4	6	I	@	B	O	5	7	[	D	FL G)6	H<<Q/D4LEF4*BuWo67NN4  * 
S\N)DIIg4F3G
HI
7|aZ[	/	
#$2Y

1666CM@R 5L(9%O
);Ovh?Oxx?6??  N1T("TF!45uS9%O
);Ovh?O GAd82eWAl^:FG  	23	L\'1=N;N2OPS1TTi
jkJ6L+=
[	3$2$7$7$7$N!$$$&))+C"$!/!1C$H--113<<ZHIYZ\d'3~$Hi"01(/'!*T # &*.@@%+H%5"x(8(>'?s3w<.P^_`S%7U\)FKbHJ)^[g"C%9#sHi%XNBBJWY[]_acegjWjT
Hi # 1;HiQ_0_-E9dI[F<4L(qa@#-v+/RvQ<R69'lQ6FBs7|nE2BCqXeWXJvhbT!6G2GH!LJ)7RH,2{ 3R 7893vk?RSU?U;V:W X$Y/4Cx8H7MO  B 5u4@(BSBSBWBWBYBbBbcmBnAo pd2gYc'%y Ic](?3*?wzRUFV W/*+1]O1XJH I URv;' 5 7sGT8Y"DVXyA	N	1QUU7^v5MQ	NOI1}.B!BySdGdhiGi#,,00277L L# %,C,E(E %$&%+/t+;%@IQU@U%(=8% *$~5% ;'-7	%
 JJy!,q0%
 6<ZZ!5Lq5P% {*% %$  !1e|6K|8T*,,GW8X>{8S<PUwVfGg8h$~8V'=8'..:Y#~5SVWegjkuguWvSwRxx~G  9Af[1]BGNNUZ[^_efq_r[sZt  uE  TF  EGvzz)A6!;vzz(ST?UYZ?Z]d]k]k  mM  ^N[(SZ[^R__gGh8iGa8beWBtfK		'@R?STU*5':!8X(D#xQU69%9BD
 Jq k 
#	" ('
  	.<QC@AJ2[	.d  	HF4*N473C3C2DAFGG	H Z 
 ( #" D OF ! 	.NHJ 	3IaS/"DJJrNN	3s   $q*r q<6A2r 7Ar8 4s7At	*tB u 1u t-#Au 't?7Au >Gu 
u'u-Lu 
u *
q9<
rr 
r5r00r58
s4&s//s47
t		
t	
t*	-
t<7u ?
u	u v.6	v.?$v))v.__main__r   )r  r   Nr  )Nr   r  )__doc__r  r9   rE   r[   rW   r  r   r-  dotenvr   cryptography.hazmat.primitivesr   r   )cryptography.hazmat.primitives.asymmetricr   cryptography.hazmat.backendsr   r}   r|   ImportErrorgetenvrH   r,   rQ  BOT_DIRr  r  r  r  r  r  r  r  r  r  rC  rD  rB  rA  r   r   r  r  r  r   rO   r  r  r  r  r8  r7  r:  r9  r   r   r  r  r]   r^   r_   Lockr\   r  r  r  rL   rM   r  re   traded_tickersrE  rv  r   rc   r   r   r   r   r   Eventrd   ra   r  r  r+   r(   r/   rA   rI   rP   rR   r   r   r   r   r   r   r   r   r   r   r   r  r  r)  r5  r;  r   r]  r_  r  r  r  r  r  r   r  r  r  r  r  r  r  r  r&  rO  r\  rt  rw  r|  r  r  rd  r-   r.   r'   <module>r     s   A @ @ @  @ = 8L 99()99./- #(189> 24    	    
  !  "T\`a"T\`a.."
	99;##5>>#     ~~'  ~~'   (
 f10"+Z&$(")"]-^'R&'-R&I9>+
      4-^)VAxF&
2.=`a"C
0d3j%(N
	K)Vw3r zE C%  Ls   G/ /G;:G;