
    (i                        d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl	Z
ddlZddlZddlZddlZddlZddlZddlmZ ddlmZ ddlmZmZmZ ddlmZmZ ddlmZ ddlmZm Z  dd	l!m"Z" dd
l#m$Z$ ddl%Z%ddl%m&Z& ddl'Z' e        ejP                  jS                  dd      Z* G d d      Z+	 ddl,m-Z.m/Z/m0Z0  e.       a1 e/tb                e2d       dZ3d Z6 G d d      Z7d Z8d Z9d Z:d Z;d Z<d Z=d Z>d Z?d!Z@d ZAd"ZBe G d# d$             ZC G d% d&      ZDd' ZEeFd(k(  r ej                   eE              yy# e4$ rZ5 e2de5        da1dZ3Y dZ5[5}dZ5[5ww xY w))u   
Volatility Arbitrage: BTC 15-min binaries
Kalshi KXBTC15M — IV vs 3-min rolling RV
6-exchange CCXT weighted average spot price
No delta hedging — directional IV/RV signal only.
    N)deque)	dataclass)OptionalListDict)datetimetimezone)load_dotenv)serializationhashes)padding)default_backend)web   tg)max_workersthread_name_prefixc                   4    e Zd ZdedefdZdefdZdefdZy)TelegramNotifier	bot_tokenchat_idc                 4    || _         || _        d| | _        y )Nzhttps://api.telegram.org/bot)r   r   base_url)selfr   r   s      volatility.py__init__zTelegramNotifier.__init__   s    "6ykB    textc                     	 t        j                  | j                   d| j                  |ddd       y # t        $ r}t        d|        Y d }~y d }~ww xY w)Nz/sendMessageHTML)r   r   
parse_mode   )jsontimeoutu   ⚠️  Telegram send failed: )requestspostr   r   	Exceptionprint)r   r   es      r   _do_sendzTelegramNotifier._do_send#   sV    	8MMT]]O<8!%t6R  	821#677	8s   36 	AAAc                 D    t         j                  | j                  |       y N)_tg_poolsubmitr*   )r   r   s     r   sendzTelegramNotifier.send+   s    t,r   N)__name__
__module____qualname__strr   r*   r/    r   r   r   r      s0    C# C C
8S 8- -r   r   )get_conncreate_all_tableswrite_tradeu   ✓ PostgreSQL connectedTu   ⚠️  No PG: Fc                      t         sy t        j                         j                  d       t        S # t        $ r# t               at        cY S # t        $ r Y Y y w xY ww xY w)NzSELECT 1)PG_pgcursorexecuter'   _get_pgr4   r   r   pgr>   6   sF    d			j	)#: &9SSj%%&s,   (1 	AA	A	AAAAc                   @    e Zd Zd Zdeeee   f   fdZdee   fdZ	y)BTCPriceFeedc                 b   t        j                         t        j                         t        j                         t        j                         t        j
                         t        j                         d| _        t        ddj                  | j                  j                                       y )N)	cryptocomcoinbasebitstampkrakengeminibullishu   ✓ CCXT price feed: z, )ccxtrB   rC   rD   rE   rF   rG   	exchangesr(   joinkeysr   s    r   r   zBTCPriceFeed.__init__@   sk    )kkmkkm||~
 	%dii0C0C0E&F%GHIr   returnc                     i }| j                   j                         D ]  \  }}	 |j                  d      }|d   ||<   ! |S #  d ||<   Y -xY w)NzBTC/USDlast)rI   itemsfetch_ticker)r   pricesnameexchangetickers        r   fetch_priceszBTCPriceFeed.fetch_pricesK   s`    "nn224 	$ND($!..y9%f~t	$ $#ts   AA
c                     | j                         }d}d}|j                         D ]  \  }}|	|dv rdnd}|||z  z  }||z  } |dk(  ry ||z  S )Nr   )rC   rB   r      )rV   rP   )r   rR   weighted_sumtotal_weightrS   priceweights          r   get_average_pricezBTCPriceFeed.get_average_priceU   sx    ""$!<<> 	'KD% "&??Q.&		'
 1l**r   N)
r0   r1   r2   r   r   r3   r   floatrV   r]   r4   r   r   r@   r@   ?   s2    	Jd3#78 +8E? +r   r@   c                 d    ddt        j                  | t        j                  d      z        z   z  S )N      ?      ?       @)matherfsqrtxs    r   Nrh   c   s'    3#TYYs^); <<==r   c                     t        j                  d| z  | z        t        j                  dt         j                  z        z  S )Ng      rb   )rc   expre   pirf   s    r   nrl   d   s.    488DF1H%		#dgg+(>>>r   c                     |dk  s|dk  r	| |kD  rdS dS |t        j                  |      z  }t        j                  | |z        d|dz  z  |z  z   |z  }||z
  }t        |      S )Nr   ra           r`   r   )rc   re   logrh   FKTsigsTd1d2s          r   	bin_pricerx   f   sj    AvQ#7C7	tyy|	B
((1Q3-#c1f*Q,
&"	,B	bBR5Lr   c                     |dk  s|dk  ry|t        j                  |      z  }t        j                  | |z        d|dz  z  |z  z   |z  }||z
  }t        |      | |z  t        j                  |      z  z  S Nr   rn   r`   r   rc   re   ro   rl   rp   s          r   	bin_deltar|   m   ss    Av#	tyy|	B
((1Q3-#c1f*Q,
&"	,B	bBR5AGdiil*++r   c                     |dk  s|dk  ry|t        j                  |      z  }t        j                  | |z        d|dz  z  |z  z   |z  }||z
  }t        |       |z  | dz  |dz  z  |z  z  S rz   r{   rp   s          r   	bin_gammar~   t   sy    Av#	tyy|	B
((1Q3-#c1f*Q,
&"	,B	bBbE6B;!Q$a-!+,,r   c                    | dk  s
| dk\  s|dk  ryd}d\  }}t        ||||      | z
  }t        ||||      | z
  }||z  dkD  ryt        |      t        |      k  r||}}||}}||}
}	||z
  }d}t        d      D ]t  }t        |      |k  r|c S t        ||z
        |dz  k  r|c S ||
k7  rD||
k7  r?||z  |
z  ||z
  ||
z
  z  z  ||z  |
z  ||z
  ||
z
  z  z  z   |	|z  |z  |
|z
  |
|z
  z  z  z   }n||||z
  z  ||z
  z  z
  }d	|z  |z   d
z  |cxk  r|k  sn ||cxk  rd	|z  |z   d
z  k  rmn nj|r t        ||z
        t        ||	z
        dz  k\  sH|s t        ||z
        t        |	|z
        dz  k\  s&|rt        ||	z
        |k  s|st        |	|z
        |k  r||z   dz  }d}nd}t        ||||      | z
  }|	||}
}	}||z  dk  r||}}n||}}t        |      t        |      k  sm||}}||}}w |S )z<Brent's method to find implied vol from binary option price.{Gz?Gz?r   Ng-C6?)r   g      $@T         r   F)rx   absrange)r[   rq   rr   rs   tolabfafbcfcdmflag_sfss                   r   
extract_ivr   {   sk   }a
CDAq	1aA		&B	1aA		&B	Bw{4
2wR!1RBrrA	AAE3Z !r7S=(q1u:d
"1H8b2b2b52b5/*2b2b52b5/*+2b2b52b5/*+A B!Hbe$$A A#a%Q""a!&7qs1uai&7s1Q3x3qs8A:-3qs8s1Q3xz1s1Q3x#~3qs8c>1aAEEq!Q"U*ab17Q;rrArrAr7SWaqABC!F Hr   c           	         t        |       dk  ry t        dt        |             D cg c]6  }| |   dkD  r,| |dz
     dkD  r!t        j                  | |   | |dz
     z        8 }}t        |      dk  ry t	        |      t        |      z  t	        fd|D              t        |      dz
  z  }t        j
                  |dz  dz  dz  |z        S c c}w )	N
   rX   r   r"   c              3   .   K   | ]  }|z
  d z    yw)r   Nr4   ).0rmus     r   	<genexpr>zrealized_vol.<locals>.<genexpr>   s     $Aqtai$s        v@   i  )lenr   rc   ro   sumre   )rR   interval_secilrvarr   s        @r   realized_volr      s    
6{R383v;3G 
,aAYq[VAaC[] ((6!9VAaC[(
) 
,B 
,
2w{4	RRB
$$
$c"gai
0C99S6\"_T),677
,s   ;C   i  iX  c                   |    e Zd ZU dZee   ed<   dZeed<   dZ	e
ed<   dZee   ed<   dZe
ed<   dZe
ed	<   d
Zeed<   y)PosNsider   	contractsrn   	avg_price	market_identry_iventry_rvFclosing)r0   r1   r2   r   r   r3   __annotations__r   intr   r^   r   r   r   r   boolr4   r   r   r   r      sP    D(3-IsIu#Ix}#HeHeGTr   r   c                   "   e Zd Zd Zd Zd&dZd Zd Zd Zde	e
   fd	Zdefd
ZdefdZd Zde
fdZd Zd Zd Zd Zd Zde	e
   fdZd Zd Zd Zd Zd Zd Zd Zd ZdefdZ d Z!de"fdZ#d Z$d  Z%d! Z&d" Z'de	e
   fd#Z(d$ Z)d% Z*y)'VolArbc                    || _         d| _        d | _        |rt        j                  j                  |      rt        |      j                         n|}t        j                  t        |t              r|j                         n|d t                     | _        t        d       t               | _        d | _        t%        t&              | _        d| _        d| _        d | _        t        j0                  d      | _        d | _        | j7                          d | _        d | _        d | _        d | _        d | _         d | _!        d| _"        d| _#        tI               | _%        d| _&        d	| _'        d| _(        d | _)        d | _*        d | _+        d | _,        d | _-        d
| _.        d| _/        g | _0        g | _1        d | _2        t%        t&              | _3        t%        t&              | _4        t%        t&              | _5        t%        d      | _6        to               | _8        d | _9        d| _:        d
| _;        d
| _<        d| _=        d| _>        d| _?        d| _@        d| _A        d| _B        d| _C        d | _D        y )Nz-https://api.elections.kalshi.com/trade-api/v2)passwordbackendu   ✓ Kalshi key loaded)maxlenrX   rn   KALSHI_MARKET_IDgQ?g{Gz?r   Fd   i  g?g      ?T)Ek_keyk_basek_pkospathisfileopenreadr   load_pem_private_key
isinstancer3   encoder   r(   r@   
price_feedspotr   WARMUP_SAMPLES	spot_hist	sample_ivlast_samplestrikegetenvr   market_interval_minutes_parse_intervalyes_bidyes_askmidivrvttedeltagammar   pos
edge_enter	edge_exitr   rv_priceiv_pricepending_oidpending_sidepending_pricepending_counttraded_this_marketob_yesob_noqueue_position
iv_history
rv_history
ts_historyeventsset
ws_clientstelegramDRAWDOWN_LIMITbalancepeak_balanceRV_MINRV_MAX	follow_ivrunningactivepausedauto_unpausetask)r   r   k_seckds       r   r   zVolArb.__init__   s   
E	')ww~~e'<e!!#%B%::)"S1		r'8:DI )* '. &*	 %^ <'+(*		2D(E6:$(,(,$(#'#'$(

5)-)- +/+/.2"# ). 
-1 "'n!=!&n!=!&n!= ##.  #u 59 #!"  !,0	r   c           	         | j                   sy||z   dz   |j                  d      d   z   }| j                   j                  |j                         t	        j
                  t	        j                  t        j                               t        j
                  j                        t        j                               }t        j                  |      j                         S )N z/trade-api/v2?r   )mgfsalt_length)r   splitsignr   r   PSSMGF1r   SHA256DIGEST_LENGTHbase64	b64encodedecode)r   tsmethodr   msgrt   s         r   _k_signzVolArb._k_sign&  s    yy6kO+djjoa.@@iinnSZZ\KKGLL9$+KK$=$=?@FQ $++--r   Nc                   K   | j                    | }t        t        t        j                         dz              }| j                  | j                  |||      |dd}	 t        j                  d      }t        j                  |      4 d {   }|j                  |j                  |j                  d|   }	d|i}
|d	k(  r||
d
<    |	|fi |
4 d {   }|j                          d {   xs i cd d d       d {    cd d d       d {    S 7 7 D7 .7 7 # 1 d {  7  sw Y   nxY wd d d       d {  7   y # 1 d {  7  sw Y   y xY w#  i cY S xY ww)N  zapplication/json)zKALSHI-ACCESS-KEYzKALSHI-ACCESS-SIGNATUREzKALSHI-ACCESS-TIMESTAMPzContent-Typer"   )total)r$   )GETPOSTDELETEheadersr  r#   )r   r3   r   timer   r  aiohttpClientTimeoutClientSessiongetr&   deleter#   )r   r  epdataurlr  htor   fnkwr   s               r   _kz	VolArb._k.  sE    bT"TYY[%&'"&**(,R(D(*<NP	&&Q/B,,R8 K KAEEB6J]6>d2f:c=R=JJAAFFHn6JJJJ	K K K KnJ	K KJJ	K K K K K
 	r	s   AE(0E DE AE
DE
D#.D/D#6E
DE
E D!E E(E E
D#E
!E #D5	)D,*D5	1E
8E EE 	E(
EEEE E(E E%#E(c                    K   t        j                         }|j                  d| j                  j                         d{   }|r|| _        | j
                  S 7 w)z4Fetch BTC/USD from 6-exchange CCXT weighted average.N)asyncioget_event_looprun_in_executorr   r]   r   )r   loopr[   s      r   
fetch_spotzVolArb.fetch_spot>  sM     %%'**41R1RSSDIyy Ts   >A AAc                 V   | j                   sy| j                   j                  d      d   }d|v rs	 |j                  d      }d}t        |dz
  dd      D ]  }||   j	                         r	||   |z   } n |r*t        |      | _        t        d| j                   d	       yyy#  Y yxY w)
u@   Parse market interval from ticker, e.g. KXBTC15M → 15 minutes.N-r   Mr   rX   u   ✓ Interval: z minutes)r   r   rfindr   isdigitr   r   r(   )r   rU   m_idxr   r   s        r   r   zVolArb._parse_intervalF  s    ~~v%%c*1-&=S)uqy"b1 Aay((*"1IM	
 36q6D0N4+G+G*HQR  s   A0B$ $B(c                     | j                   j                  d      }t        |      dk  ry|d   }	 t        |dd       t        |dd       fS #  Y yxY w)uF   Parse expiry hour/minute from market ID, e.g. 26APR012000 → (20, 0).r%  r   NrX      	      )r   r   r   r   )r   partstps      r   _parse_market_timezVolArb._parse_market_timeY  sZ    $$S)u:>$1X	1QL#b2h-00	s   A ArM   c                 2   | j                   j                  d      }t        |      dk  ry|d   }	 ddddddd	d
ddddd}dt        |dd       z   }|j	                  |dd j                               }t        |dd	       }t        |d	d       }t        |dd       }|r| j                  syddl}	|	j                  |||||      }
|
|	j                  | j                        z
  }|	j                  j                         |z
  j                         dz  S #  Y yxY w)z5Minutes elapsed since market opened (same as rsibot).r%  r   NrX   r   r   r"      r,     r-  r   r.     JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC  r   minutes<   )r   r   r   r   r  upperr   r   	timedeltanowtotal_seconds)r   r/  r0  	month_mapyearmonthdayhourminutedt_modexpirystarts               r   minutes_into_marketzVolArb.minutes_into_marketc  s#   $$S)u:>$1X	 qqqqq qqrMIC1QL(D]]2a7==?3EAa\CAa\DAb]F < <%__T5#tVDFf..t7S7S.TTEOO'')E1@@BRGG	s   A:D ,A%D Dc                 N  K   | j                   sy| j                  j                  d      }t        |      dk  ry|d   }	 ddl}ddddd	d
ddddddd}dt        |dd       z   }|j                  |dd	 j                               }t        |d	d       }t        |dd       }t        |dd       }	|sy|j	                  |||||	      }
|j                  j                         |
k\  r| j                          d{   S 	 y7 # t        $ r}t        d|        Y d}~yd}~ww xY ww)z:Check if current market has expired, switch to next if so.Fr%  r   rX   r   Nr   r   r"   r3  r,  r4  r-  r   r.  r5  r6  rC  u   ⚠️ Error parsing expiry: )r   r   r   r   r   r   r  rG  rI  switch_to_next_marketr'   r(   )r   r/  r0  rQ  rK  rL  rM  rN  rO  rP  rR  r)   s               r   check_market_expiryzVolArb.check_market_expiryy  s9    ++$$S)u:>1X	7% qqqqq qqrMIC1QL(D]]2a7==?3EAa\CAa\DAb]F__T5#tVDF""$.!77999 /  : 	71!566	7sU   =D% A2D 2D%3AD 8C?9D <D%>D%?D 	D"
DD%D""D%c                 *  K   | j                   sy| j                  j                  d      }t        |      dk  ry|d   }|d   }	 ddl}ddddd	d
ddddddd}|j                         D ci c]  \  }}||
 }}}dt        |dd       z   }	|j                  |dd	 j                               }
t        |d	d       }t        |dd       }t        |dd       }|
sy|j	                  |	|
|||      |j                  | j                         z   }|j                  dz  d||j                      |j                  d|j                  d|j                  d}|j                  d}| d| d| }| j                  }| j#                          d{    || _        t%               | _        d| _        d| _        d| _        d| _        d| _        d| _        g | _        g | _        d| _        t!        d| d|        t;        d      D ]  }| j=                  dd| j                          d{   }|j                  d|      }|r>|j                  d      }|+t?        |      | _        t!        d| j*                  d         n/|dk(  rt!        d!       tA        jB                  d       d{     | j*                  st!        d"       | jE                  d#| d|        | jF                  r'| jF                  jI                  d$|d%d  d|d%d         | jK                          d{    | jL                  r| j8                  s	 y| jL                  rd| _        t!        d&       yc c}}w # t        $ r}t!        d|        Y d}~yd}~ww xY w7 7 e7 7 ow)'z9Compute next market ID and switch to it (same as rsibot).Fr%  r   rX   r   Nr   r   r"   r3  r,  r4  r-  r   r.  r5  r6  rC  rD  r   02du$   ⚠️ Error computing next market: Tu   
🔄 Market switched:     →    r  	/markets/marketfloor_strike  Strike: $,.2fz  Waiting for strike...u-     ⚠️ Could not fetch strike after retriesswitchu   🔄 Market switched: iu%     ▶️ Auto-resumed for next market)'r   r   r   r   r   rP   r   r  rG  rH  rL  rM  rN  rO  rP  r'   r(   cancel_pendingr   r   r   r   r   r   r   r   r   r   r   r   r  r^   r  sleep	log_eventr   r/   check_balancer   )r   r/  r0  prefixrQ  rK  kv	rev_monthrL  rM  rN  rO  rP  nxtnext_tpnext_sfxnext_idr)   old_idattemptr   mr^  s                           r   rV  zVolArb.switch_to_next_market  s    ++$$S)u:>qq	% qqqqq qqrMI*3//*;<$!QA<I<C1QL(D]]2a7==?3EAa\CAa\DAb]F??4T6B%%d.J.J%KLC88C<,Ysyy-A,B773-~cjj5EGG**S)H 7)1XJ7G
 !!### 5"'
 	(gY?@Ry 	$Gggey0@%ABBAh"A uu^4+"'"5DKKD'9:;!|/1--###	$ {{ACxF85	!:;==MM!7st~U7SVSW=/Z[  """T[[  DK9;s =  	8<=	
 	$  C $ 	#s   AN&M% +M8A"M% NBM% -NN	BN'N(A>N&N'A:N!N"=NM% %	N.N<NNNNNNc                   K   | j                   st        d       y| j                  dd| j                           d{   }|j                  d|      }|st        d| j                           y|j                  d      }|+t	        |      | _        t        d	| j
                  d
d       nt        d| j                           | j                         }|3| j                  r'| j                  |z
  }t        |dz  d      dz  | _	        nd| _	        t        d| j                           |8t        d|dd|dz  dd       t        d| j                  xs d|z
  dd       y7 'w)z=Load market from KALSHI_MARKET_ID env var, fetch expiry info.u    ❌ Set KALSHI_MARKET_ID in .envFr  r\  Nr]  u   ❌ Market not found: r^  r_  r`  z (floor_strike)u+   ⚠️  No floor_strike in market data for rF  rX       ~~Ag5?z
  Market:   Elapsed: .1fz min (.0fs)
  TTE:        minT)
r   r(   r  r  r^   r   rT  r   maxr   )r   r   rp  r^  elapsed_minremaining_mins         r   load_marketzVolArb.load_market  sj    ~~45 ''%9T^^,<!=>>EE(A*4>>*:;< uu^,#-DKKD1AB??OPQ ..0"t'C'C 88;FM=2-q1^DDH#DH
4>>*+,"KC0{2~c6J"MNJ < < BkQRUVVZ[\5 ?s   ;E'E$D'E'c                 4    | j                         }||dz  S dS )z$Seconds elapsed since market opened.rF  r   )rT  )r   rp  s     r   market_elapsedzVolArb.market_elapsed  s#    $$&q2v-A-r   c                   K   | j                   sy| j                  dd| j                    d       d {   }|j                  di       }|j                  dg       }|j                  dg       }t        |D cg c]$  \  }}t	        |      t        t	        |            g& c}}d d	
      | _        t        |D cg c]$  \  }}t	        |      t        t	        |            g& c}}d d	
      | _        | j                  r| j                  d   d   nd | _        | j                  r%t        d| j                  d   d   z
  d      | _
        nd | _
        | j                  8| j                  ,t        | j                  | j                  z   dz  d      | _        n| j                  xs | j                  | _        | j                  d uS 7 c c}}w c c}}w w)NFr  r\  z
/orderbookorderbook_fpyes_dollars
no_dollarsc                     | d   S Nr   r4   rf   s    r   <lambda>z!VolArb.fetch_ob.<locals>.<lambda>
  s
    1Q4 r   T)keyreversec                     | d   S r  r4   rf   s    r   r  z!VolArb.fetch_ob.<locals>.<lambda>  s
    !A$ r   r   ra   r   r   )r   r  r  sortedr^   r   r   r   r   roundr   r   )r   r   obybnbpr   s          r   fetch_obzVolArb.fetch_ob  sv    ~~e''%9T^^,<J!GHHUU>2&VVM2&RVVL"-EBGDAquQxU1X7G!/?2F41aeAhE!H6F .>
 -1KKt{{1~a(T:: tzz!}Q'7!7;DL!dl<<#(@dllT\\91<a@DH5dhxxt##! I HFs/   1GGAG8)G
!G<)G
%C GGc                     | j                   rl| j                  r_| j                  rR| j                  rEt	        | j                   | j                  t        | j                        | j                        | _        y y y y y r,   )r   r   r   r   r   r^   r   rL   s    r   calc_ivzVolArb.calc_iv  sM    88		dkkdhh 499eDKK6H$((SDG 7?k	8r   c                     t        | j                        dk\  r/t        t        | j                        | j                        | _        y y )Nr   )r   r   r   listr   r   rL   s    r   calc_rvzVolArb.calc_rv  s3    t~~"$"4#7HDG %r   c                 |   | j                   r| j                  r| j                  r| j                  rt	        | j                   t        | j                        | j                  | j                        | _        t        | j                   t        | j                        | j                  | j                        | _        y y y y y r,   )	r   r   r   r   r|   r^   r   r~   r   rL   s    r   calc_greekszVolArb.calc_greeks   st    99dgg"499eDKK.@$((DGGTDJ"499eDKK.@$((DGGTDJ 7>9r   c                    d| _         d| _        | j                  r| j                  r| j                  r| j
                  rDt        | j                  t        | j                        | j                  | j
                        | _         | j                  rEt        | j                  t        | j                        | j                  | j                        | _        yyyyy)z7Calculate fair price using RV vs market price using IV.N)	r   r   r   r   r   r   rx   r^   r   rL   s    r   	calc_edgezVolArb.calc_edge%  s    99ww )$))U4;;5GSWSZSZ [ww )$))U4;;5GSWSZSZ [  *29r   c                 f    | j                   %| j                  | j                   | j                  z
  S y)zREdge = rv_price - iv_price. Positive = YES underpriced, negative = NO underpriced.N)r   r   rL   s    r   get_edgezVolArb.get_edge/  s+    ==$)B==4==00r   c                   K   d| j                   d|ddd|dddd	| d
t        t        j                         dz         | dt        t        |dz              i}| j	                  dd|       d {   }|r!|j                  di       j                  d      nd }|r+t               }|rt        || j                   d|||d|       |S |S 7 X#  Y |S xY ww)NrU   r   actionbuycounttypelimitclient_order_idzvol-r%  r
  _pricer   r  z/portfolio/ordersorderorder_id	placement
volatilityr  )r   r   r  r  r  r  r>   r7   )r   r   r[   r  r   r   oidconns           r   kalshi_orderzVolArb.kalshi_order6  s     t~~vtXueVW$tfAc$))+d2B.C-D EvV_c%c	"235 ''&"5q9934aeeGB##J/$4D t~~{D%QVXdors
s
 : 
s*   A-C/C07C'C
 C
CCc                   K   | j                   r| j                  dd| j                           d {    t        d| j                  j	                          d       | j                  dd| j                  j	                          d| j                  d       d	| _        d | _         d | _        d | _        d
| _        y y 7 w)Nr  /portfolio/orders/u   
  ✗ Cancelled pending z ordercancelz
Cancelled  @ $.3fFr   )	r   r  r(   r   rG  rd  r   r   r   rL   s    r   rb  zVolArb.cancel_pendingD  s     ''(&89I9I8J$KLLL.t/@/@/F/F/H.IPQNN8z$2C2C2I2I2K1LDQUQcQcdgPh%ij&+D##D $D!%D!"D Ls   /B?B=BB?c                   K   | j                   r| j                  st        d       y| j                  rt        d       y| j                   }t        d| j                   d|dd       | j                  d|| j                         d{   }|r5|| _        d| _        || _        | j                  | _        t        d	|        yt        d
       y7 Gw)z,Buy vol: place YES limit at the bid (maker).u
   ❌ No bidN"   ⚠️  Already have pending orderu   
📈 LONG VOL: z YES @ $r   (joining bid)yes     ✓ Resting:      ❌ Failed)	r   r   r(   r   r   r  r   r   r   )r   r[   r  s      r   long_volzVolArb.long_volO  s     ||4>>,67!$..!1%NST%%eUDNNCC"D %D!&D!%DOC5)*.! Ds   BCC	ACc                   K   | j                   r| j                  st        d       y| j                  rt        d       yt	        d| j                   z
  d      }t        d| j
                   d|dd	       | j                  d
|| j
                         d{   }|r5|| _        d
| _        || _        | j
                  | _	        t        d|        yt        d       y7 Gw)z/Sell vol: place NO limit at the no-bid (maker).u
   ❌ No askNr  ra   r   u   
📉 SHORT VOL: z NO @ $r  r  nor  r  )
r   r   r(   r   r  r   r  r   r   r   )r   no_pricer  s      r   	short_volzVolArb.short_vola  s     ||4>>,67t||+Q/"4>>"2'(3~VW%%dHdnnEE"D $D!)D!%DOC5)*.! Fs   BCCACc                 j  K   | j                   sd | _        y | j                  dd| j                   d| j                    d      }| j                  dd| j                         }t	        j
                  ||d       d {   }d | _        |d   rt        |d   t              st        |d   t              r|d   j                  d	      nd }|rpt        |t              r`|D ][  }|j                  d
      | j                   k(  s"t        t        |j                  d|j                  dd                        | _         n |d   r&t        |d   t              st        |d   t              sy |d   j                  d      }|rt        |t              sy t        d |D              }|| j                  k\  rv| j                  }| j                   }	| j                  }
| j"                  j$                  }|rt'        d|
 d|j)                          d|	d       | j+                  dd|
 d|j)                          d|	d       | j,                  rD| j,                  j/                  d|
 d|j)                          d|	dd| j1                                 t3               | _        n7t'        d|
 d|j)                          d|	d       | j+                  dd|
 d|j)                          d|	d       | j,                  rD| j,                  j/                  d|
 d|j)                          d|	dd| j1                                 || j"                  _        | j"                  xj6                  |
z  c_        |	| j"                  _        | j                  | j"                  _        | j:                  xs d| j"                  _        | j>                  xs d| j"                  _         tC               }|r,	 tE        || j                  |rdnd||	|
d| j                          d | _         d | _        d | _        d| _        y y 7 #  Y %xY ww) Nr  z/portfolio/fills?ticker=z
&order_id=z	&limit=10z1/portfolio/orders/queue_positions?market_tickers=Treturn_exceptionsrX   queue_positionsr  queue_position_fpr   0r   fillsc           	   3   d   K   | ](  }t        t        |j                  d d                   * yw)count_fpr  N)r   r^   r  )r   fs     r   r   z,VolArb.check_pending_fill.<locals>.<genexpr>  s%     M!3uQUU:s%;<=Ms   .0u   
✓ CLOSE FILLED:  r  r  kalshi_fillzCLOSE FILLED u   ✅ CLOSE FILL: 
u   
✓ FILLED: zFILLED u
   ✅ FILL: 
close_fillfillr  r  )#r   r   r  r   r  gatherr   r'   dictr  r  r   r^   r   r   r   r   r   r   r(   rG  rd  r   r/   _tg_vol_infor   r   r   r   r   r   r   r   r>   r7   )r   
fills_task
queue_taskresultsr  qpr  filled_countr   r[   r  is_closer  s                r   check_pending_fillzVolArb.check_pending_fills  s    "&DWWU&t~~&6jAQAQ@RR[\^
WWU??OPR
z:QUVV #1:jY?CMgVWjZ^C_gajnn->?eiO:ot#D) Bvvj)T-=-==.1%FF#6?OQT8UV3X /Y+	 qzZ
I>jQXYZQ[]aFb
w'Jud3MuMM4---$$D&&E&&Exx''H,UG1TZZ\N$uSkRS}eWAdjjl^SWX]^aWb.cd==MM&&*5'4::<.U3Kr,,./12 5ugQtzz|nDsLM}wa

~TRWX[Q\.]^==MM&&$UG1TZZ\N$uSk,,./12 !%""e+"%*"%)^^"$(GGLq!$(GGLq!4DdnnhlTZ\` %ulTEUEUW  $D $D!%D!"DM ./ Wp s2   A<P3>P)?BP3KP3 +P, P3,P0.P3c                    K   | j                   sy | j                  dk(  r| j                  }n'| j                  rt	        d| j                  z
  d      nd }|y t        || j                  z
        dk  ry | j                  }d| j                  d| j                  ddd	| j                  | j                   d
t        t	        |dz              i}| j                  dd| j                    d|       d {   }|rj|j                  d      rY|d   j                  d      dk7  rB|| _        ||kD  rdnd}t        d| d| j                  j                          d|dd|d       y d | _         d | _        d | _        d| _        y 7 w)Nr  ra   r   gMbP?rU   r   r  r  r  r  r   r  r  z/amendr  statuscanceledu   ↑u   ↓r  r  z: $r  u    → $r   )r   r   r   r   r  r   r   r   r   r   r  r  r(   rG  )r   current_bid	old_price
amend_datar   	directions         r   
follow_bidzVolArb.follow_bid  s~    %,,K:>,,%dll 2A6DK{T///058&&&	dnnD%%eT''  !(#eK#4E.F*GI
 ''&$6t7G7G6H"OQ[\\wAgJNN8$<
$J!,D!,y!8eIByk4#4#4#:#:#<"=S3vVabeUfgh#D $D!%D!"D ]s   C,E>.E</BE>c                   K   | j                          d{    | j                  j                  dk(  rt        d       y| j                  j                  dk(  r0| j
                  rt        d| j
                  xs dz
  d      nd}d	|}}nd}| j                  xs d}t        d
| j                  j                   d| j                  j                  j                          d|j                          d|dd	       | j                  ||| j                  j                         d{   }|rQ|| _
        || _        || _        | j                  j                  | _        d| j                  _        t        d| d       yy7 e7 [w)zCClose binary position (maker on opposite side, with bid following).Nr   u   ⚠️  No positionr  ra   r   r   r   r  u   
🔒 Closing r  rZ  r  r  z (maker)Tu     ✓ Close order resting: z (bid following active))rb  r   r   r(   r   r   r  r   rG  r  r   r   r   r   r   )r   no_bid
close_sideclose_pricer  s        r   	close_allzVolArb.close_all  sV    !!###88"'(&88==E!?C||U3$,,"6$7;QUF&*FJJ,,.$K 2 231TXX]]5H5H5J4Kj&&()k#->hH 	I%%j+txx?Q?QRR"D *D!,D!%!3!3D#DHH/u4KLM  	$ Ss#   F E;DF "E>#AF >F c                   K   | j                  dd       d {   }|rd|vry |d   | _        | j                  | j                  kD  r| j                  | _        | j                  | j                  z
  }|| j                  k\  r| j                  s|d| _        d| j                  dz  dd|dz  dd	| j                  dz  dd
}t        d|        | j                  d|       | j                  r| j                  j                  |       y y y y 7 w)Nr  z/portfolio/balancer   Tu   🚨 DRAWDOWN GUARD: Balance $r   .2fz is $z below peak $u    — auto-pausedr  drawdown)	r  r   r   r   r   r(   rd  r   r/   )r   resultr  r  s       r   re  zVolArb.check_balance  s    wwu&:;;&0i(<<$+++ $D$$t||3t***4;;DK3DLL4DS3I J|C(d6G6G6KC5P Q%&C Bse*NN:s+}}""3'  4?* <s   DD
C2Dc                    g }| j                   #|j                  d| j                   dz  dd       | j                  #|j                  d| j                  dz  dd       | j                  |j                  d| j                  d       | j                  |j                  d| j                  d       | j
                  |j                  d	| j
                  d       d
j                  |      S )NzIV: r   rt  %zRV: zIV_price: $r  zRV_price: $zMid: $r  )r   appendr   r   r   r   rJ   )r   r/  s     r   r  zVolArb._tg_vol_info  s    77tDGGCK3DA-F G77tDGGCK3DA-F G==$ell[s@S3T&U==$ell[s@S3T&U88txxn.E!Fyyr   c                 f    | j                   j                  t        j                         ||d       y )N)r  kindr  )r   r  r  )r   r  r  s      r   rd  zVolArb.log_event  s!    $))+tCHIr   c                    | j                         }| j                         }t        |cxk  xr	 t        k  nc }i d| j                  d| j
                  d| j                  d| j                  rt        | j                  dz  dz  dz  d      nd d	| j                  d
| j                  d| j                  d| j                  rt        | j                  dz  d      nd d| j                  rt        | j                  dz  d      nd d|t        |d      nd dt        | j                  d      dt        | j                  d      d| j                   t        | j                   d      nd d| j"                  t        | j"                  d      nd d| j%                         t        | j%                         d      nd d| j&                  d d d| j(                  d d | j*                  r:| j*                  | j,                  | j.                  | j0                  | j2                  dnd | j4                  j6                  dkD  rq| j4                  j8                  | j4                  j6                  t        | j4                  j:                  dz  d      t        | j4                  j<                  dz  d      dnd t?        | j@                        t?        | jB                        t?        | jD                        tG        | jH                        tJ        | jL                  | jN                  t?        | jP                        dd  | j6                  | jR                  t        |d      |d S )!Nr   r   r   tte_minr   r   rF  rX   r   r   r   r   r   r   r   spreadr   r4  r   r   r   r   r   edger   rx  r   )r  r   r[   r  queuer   )r   r   r   r   i)pendingpositionr   r   r   samplesmax_samplesr   r   r   contracts_per_trade	thresholdelapsed	in_window)*iv_rv_spreadr  TRADE_WINDOW_STARTTRADE_WINDOW_ENDr   r   r   r   r  r   r   r   r   r   r   r   r   r   r  r   r   r   r   r   r   r   r   r   r   r   r   r  r   r   r   r   r   r   r   r   r   r   )r   r  r  r  s       r   build_statezVolArb.build_state  s   ""$%%'&'E5EE	+
DII+
dkk+
 +
 uTXX.3b8!<d	+

 t||+
 t||+
 488+
 TWW%#q)$+
 TWW%#q)$+
 &*<eFA&$+
 U4::q)+
 U4::r*+
 4==3LdmmQ/RV+
 4==3LdmmQ/RV+
 1LE$--/1-RV+
  dkk#2&!+
" TZZ_#+
0 !! ''))++++,, (, ##a'	 !XX//!$(("3"3c"91=!$(("3"3c"91=	
 .2t/t/t/4>>*)kkkk4;;'-#'>>Wa("U+
 +	
r   c                 2  K   | j                   sy t        j                  | j                               }t	               }| j                   D ]  }|j                  |       d {     | xj                   |z  c_         y 7 #  |j                  |       Y KxY wwr,   )r   r#   dumpsr  r   send_stradd)r   r  deadwss       r   	broadcastzVolArb.broadcast@  su     jj))+,u// 	!B{{3'''	! 	4 ( DHHRLs0   A
BA? A=!A?%B=A??BBc                   K   t        j                         }|j                  |       d {    | j                  j	                  |       	 |j                  t        j                  | j                                      d {    |2 3 d {   }
7 f7 7 	6 	 | j                  j                  |       |S # | j                  j                  |       w xY wwr,   )
r   WebSocketResponsepreparer   r  r  r#   r  r  discard)r   requestr  r  s       r   
ws_handlerzVolArb.ws_handlerI  s     ""$jj!!!B	(++djj)9)9);<===  c 	" >R OO##B'	 OO##B'sc   )CBC5B7 BB7 BBBB7 CB7 BB7 C7CCc                   K   t        j                  | j                         | j                         d       d {    t	        j                         }| j
                  rH|| j                  z
  | j                  k\  r,| j                  j                  | j
                         || _        | j                         }|2| j                  r&| j                  |z
  }t        |dz  d      dz  | _        | j                          | j                          | j!                          | j#                          |}| j$                  j                  |       | j&                  j                  | j(                  rt+        | j(                  dz  d      nd        | j,                  j                  | j.                  rt+        | j.                  dz  d             y d        y 7 w)NTr  rF  rX   rr  r   r   )r  r  r#  r  r  r   r   r   r   r  rT  r   rz  r   r  r  r  r  r   r   r   r  r   r   )r   rI  r{  r|  ts_nows        r   refreshzVolArb.refreshV  sJ    nnT__.SWXXXiik99t///4>>ANN!!$)),d.>..0"t'C'C 88;FM=2-q1^DDH(8(8(:DNN<Lv&$''uTWWs]A6tL$''uTWWs]A6LtL 	Ys   8GGFGc                 ,   | j                   rd| j                   dnd}| j                  rd| j                  dnd}| j                  r| j                  dz  ddnd}| j                  r| j                  dz  ddnd}| j                  rh| j                  r\| j                  | j                  z
  dz  }|dd}| j	                         }|r|| j
                  kD  rdn|r|| j
                   k  rd	nd
}nd}d}| j                  r| j                  dnd}	| j                  r| j                  dnd}
| j                  r| j                  dz  dz  dz  ddnd}| j                         }d
}| j                  j                  dkD  r=| j                  j                  j                          d| j                  j                   }d}| j                  r8d| j                  j                          d| j                    d| j"                  d}| j$                  rdnd}|dkD  rd|ddnd}t'        d| d| d| d|	 d|
 d| d | d!t)        | j*                         d"| d#| d$| j,                  d%d&| | | | d'       t.        j0                  j3                          y )(N$r`  r   r   rt  r  +.1fYESNOFLATWAITr  r   r   rF  ru  rp  r   rg   r   z PND:@z PAUSEDz W:r   z[VOL] z K:r  z | B:z/A:z | IV:z RV:(z) z [z] | D:z.6fz | end)r   r   r   r   r  r   r   r   r   r  r   r   r   rG  r   r   r   r   r   r(   r   r   r   sysstdoutflush)r   sprg  r   r   r  ssr  rt   bdakttr  pspndpausewindows                    r   r  zVolArb.statusf  s   %)YYq4 !C&*kkaD!"s&*ggC "3&*ggC "377twwggdggos*F4="B==?DD$8%tPTVZVeVeUePetkqCb&c&*llS!&*llS!04"2%c*!,c%%'88!HHMM'')*!DHH,>,>+?@B$++1134Ad6H6H5I4K]K]^aJbcC![[	b)013wsm1%"Cs!B4uRDB4 84tB4qT^^!4 5Rt2cU C::c"#bT#vhug?DF	H 	

r   c                 l    | j                   (| j                  | j                   | j                  z
  dz  S y )Nr   )r   r   rL   s    r   r  zVolArb.iv_rv_spread  s0    77477#6GGdgg%,,r   c                   K   t        j                          }| j                  r| j                  r	 | j                          d {    | j	                          d {    | j                         }t        |cxk  xr	 t        k  nc }| j                  s| j                          d {    | j                  r| j                          d {    | j                         }|A| j                  r5t        d       | j                  dd       | j                          d {    |r| j                   xr' | j"                  xr | j                   | j"                  kD  }| j$                  j&                  dk(  r+| j                  s| j(                  s|| j*                  d uxr. | j,                  | j*                  cxk  xr | j.                  k  nc }|st1        |      | j2                  kD  r| j*                  | j*                  dz  }d|dd| j,                  dz  d	d
| j.                  dz  d	d|d}t        d|        | j                  d|       | j4                  r.| j4                  j7                  | d| j9                                 d| _        n|r	t1        |      | j2                  kD  r|rdnd}	| j:                  r|| j2                   k  }
n|| j2                  kD  }
|
r| j:                  rdnd}t        d|dd|dz  dd|	 d| d	       | j                  dd|dd|	 d| d       d| _        | j4                  rX| j4                  j7                  d| j&                   d| j<                  dd |dd|dz  dd!|	 d"| d#| j9                                 | j?                          d {    n| j:                  rdnd}| j@                  rtC        d$| j@                  xs d%z
  d&      nd'}t        d(|dd|dz  dd|	 d)| d	       | j                  dd|dd|	 d*| d       d| _        | j4                  rN| j4                  j7                  d+| j&                   d|dd |dd|dz  dd!|	 d"| d#| j9                                 | jE                          d {    | j                  r| j$                  j&                  dk(  r|t1        |      | j2                  k  rt        d,|dd-       | j                          d {    n| j                  r?t        d.|d	d/       | j                  d0d1|d	d2       | j                          d {    |t        kD  r0t        d3|d	d4t         d5       | j                  d0d6       d| _        t        j                          |z
  d7k\  r$| jG                          t        j                          }| jI                          d {    tK        jL                  d8       d {    | j                  r| j                  rt        d;| j                   d<| j                   d=       | j4                  r7| j4                  j7                  d>| j                   d<| j                   d=       y y 7 A7 ,7 7 7 q7 7 7 7 M7 7 # tN        $ rJ}t        d9|        dd l(}|jS                          tK        jL                  d:       d {  7   Y d }~d }~ww xY ww)?Nu/   
⚠️ IV/RV null — cancelling resting orderr  u   IV/RV null — cancelledr   r   u   ⏭ SKIP: RV rt  z
% outside ru  r%  z% filter | Edge +.3fr  skipTabovebelowIVRVu   
📈 Edge  (z	%), spot u    strike — YES []signalzEDGE r  u    strike → YES [u   📈 ORDER: YES xr  r  z
Edge: z%) | z	 strike [z]
ra   r   r   r   u   
📉 Edge u    strike — NO [u    strike → NO [u   📉 ORDER: NO xu   
↩ Edge reverted to u    — cancellingu   
⏸ Outside window (u   s) — cancelling ordersr"  zOutside window (u   s) — cancelledu   
⏸ Past trading window (zs > u   s) — waiting for next marketu   Past window — pausedr   q=
ףp?u   
❌ Loop error: rX   u   
✓ Loop ended (running=z	, active=)u   ⚠️ Loop ended (running=)*r  r   r   rW  r  r  r  r  r   r  r   r  r  r(   rd  rb  r   r   r   r   r   r   r   r   r   r   r   r/   r  r   r   r  r   r  r  r  r  r  rc  r'   	traceback	print_exc)r   lsr  r  r  above_strikerv_okrv_pctr  
side_labelgo_yesmoder  r)   r0  s                  r   r"  zVolArb.loop  s    YY[llt{{i#**,,,,,.  ))+G*gI9III;;--/// ##//+++}} <D$4$4LNNN8-GH--/// $(99#X#XT[[AXLxx))Q.t7G7GPTPgPglpl| $t 3 ]tww8]RVR]R]8]$TT__)DI\%)WWs]F$1&ZTWX[G\\]^b^i^ijm^mnq]r  sC  DH  IM  CN  #OC!Bse*- NN637#}} $ 2 2cU"T=N=N=P<Q3R S6:D3"s4y4??'B4@gJ#~~)-0@)@)-)?%/3~~t4 %T$Kr$s(3yYcXdduvzu{{|&} ~ $x5d1ZLXijnioop9q r:> 7#'==$(MM$6$6*;DNN;K4PTP\P\]`Oa b115d2d3hs^5Q[P\\efjekkn+/+<+<+>*?)A%B '+mmo 5 5/3~~t4UYUaUa58L1Mq+Qgk %T$Kr$s(3yYcXddtuytzz{&| } $x5d1ZLXhimhnno9p q:> 7#'==$(MM$6$6*:4>>:J$xX[n ]115d2d3hs^5Q[P\\efjekkn+/+<+<+>*?)A%B '+nn&6 6 6 ''DHH,>,>!,CHXt9t6!$;D;o"VW"&"5"5"777
 '' 6wsmC[\]x3CGC=P`1ab"11333!11 ;GC=M]L^^|}~x3IK&*yy{2~"DKKM		2.."""--%%%M llt{{V 	*4<<.	$++aPQ==MM!<T\\N)TXT_T_S``abc S -  0 , 0V !6 !7 8 4 #% #&qc*+i113--"""#s  /[;Z% ZZ% Z	AZ% *Z+#Z% ZAZ% !Z"JZ% /Z0C.Z% ZA&Z% ZAZ% ZBZ%  Z!!Z% =Z#>Z% [;A*[;Z% 	Z% Z% Z% Z% Z% Z% Z% Z% !Z% #Z% %	[8.:[3([+)[3.[;3[88[;c                   K   t        dt         d       t        d       | j                          d{    | j                  dkD  rt        d| j                  dz  d       t        d	       | j	                          d{   }|st        d
       | j
                  r t        | j                        t        k  r|r=t        j                  | j                         | j                         d       d{    n| j                          d{    | j                  r t        j                         }|| j                  z
  | j                  k\  r,| j                  j!                  | j                         || _        t        | j                        }|dk\  r| j#                          | j%                         }|2| j&                  r&| j&                  |z
  }t)        |dz  d      dz  | _        | j-                          | j/                          | j1                          | j2                  j!                  |       | j4                  j!                  | j6                  rt9        | j6                  dz  d      nd       | j:                  j!                  | j<                  rt9        | j<                  dz  d      nd       | j6                  rd| j6                  dz  ddnd}| j<                  rd| j<                  dz  ddnd}t        d| dt         d| j                  d| | d       t>        j@                  jC                          | jE                          d{    t        jF                  d       d{    | j
                  rt        | j                        t        k  r| j
                  sy| j#                          t        dt        | j                         d       t        | j<                  rd| j<                  dz  ddnd        |s$t        d!       | j	                          d{   syt        d"       | j                          d{   r| jH                  rt        d#| jH                  d$       | jJ                  rt        d%| jJ                  d$       | j-                          | j6                  rt        d&| j6                  dz  dd       | jM                         }|t        d'|d(d       | jO                         }	t        d)|	d*d+       t        d,tP         d-tR         d+       d| _*        | jV                  rd.| _,        t        d/       nd| _,        t        d0       t        d1| jZ                  dz  dd       t        d2tP         d-tR         d3       t        d4| j\                  dz  d*d-| j^                  dz  d*d       | j`                  rm| j`                  jc                  d5| jd                   d6| jZ                  dz  dd7| j\                  dz  d*d-| j^                  dz  d*d8| jf                  dz  d*
       yy7 7 7 Y7 C7 7 7 17 w)9zMCollect 7 min of 1s spot samples for RV, load market early so IV streams too.u   
⏳ Warming up — collecting z spot samples (7 min)...z5   Press R to pause/resume, Z to abort, V for status
Nr   u   💰 Balance: $r   r  u   🔍 Loading market...u=   ⚠️  Market not loaded — will show RV only during warmupTr  r   rF  rX   rr  r   z | IV: rt  r  r   z | RV: z  [/z] $r`  r  r.  u   

✓ Warmup complete — z samplesz  RV: z  RV: computing...u   
🔍 Loading market...u   
🔍 Fetching orderbook...z  YES bid: $r  z  YES ask: $z  IV: z	  IV-RV: r  z
  Market elapsed: ru  r   z  Trading window: r%  Fu   
✓ Ready — AUTO-TRADINGu0   
✓ Ready — PAUSED. Press R to start trading.z  Auto-trades when |edge| > z  Orders only in zs windowz  RV filter: u$   🚀 Volatility bot started
Market: z
Edge threshold: z%
RV filter: z%
Drawdown limit: $)4r(   r   re  r   r}  r   r   r   r  r  r#  r  r   r  r   r   r  r  rT  r   rz  r   r  r  r  r   r   r   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   	market_okrI  rl   r{  r|  iv_strrv_strr  r  s
             r   warmupzVolArb.warmup  sb    00@@XYZFG   """<<!ODLL$4S#9:; 	&'**,,	QRlls4>>2^CnnT__%6[_```oo'''yyiik)))T^^;NN))$))4'*D$'7LLN"668*t/K/K$($@$@;$NM"=2#5q9^LDH  "  &&s+&&$''uTWWs]A'>tT&&$''uTWWs]A'>tT9=74773;s"315b9=74773;s"315baS.!1TYYt4DVHVHU[]^

  ".."""--%%%G lls4>>2^CJ ||V,S-@,AJKTWWtwws{3'q):NO,-))+++,-  ||U\$,,s1C#DE||U\$,,s1C#DELLNwwtwws{3&7q9:""$IfT]!,-%%'$WSM34"#5"6a8H7IKLDK02DKEG,T__S-@,EQGH!"4!5Q7G6HQRdkk#oc2!DKKOC3HJK==MM>>* +##'??3#6s"; <"kk#oc2!DKKOC3H I$$($7$7$;C#@	BC g 	# - a': #% , !s   2Y"Y
AY"YA4Y"7Y8Y"YIY"YY"2Y3,Y"!B
Y"+Y,#Y"YG;Y"Y"Y"Y"Y"Y"Y"Y"r,   )+r0   r1   r2   r   r  r  r#  r   r1  r   r^   rT  r   rW  rV  r}  r  r  r  r  r  r  r  r  rb  r  r  r  r  r  re  r3   r  rd  r  r  r  r  r  r  r  r"  r>  r4   r   r   r   r      s
   V1r. &Xe_ ,4 4FT FP!F. .
$*TIU
\(5/ 	#"$"$F#P#8N.(& c  J/
T /
b 
M 8huo 
odb_Cr   r   c            	        K   t        j                  d      } | j                  ddd       | j                  ddd       | j                  d	dd
       | j                  dt        d d       | j	                         }|j
                  rx|j
                  j                         }t        j                  d| d      }t        j                  d| d      }|r|sRt        d| d| d       t        j                  d       n*t        j                  d      }t        j                  d      }t        j                  d      }|r|s t        d       t        j                  d       |s t        d       t        j                  d       t        ||      }d|_        |j                  r|j
                  r{|j
                  j                         }t        j                  d| d      xs t        j                  d      }t        j                  d| d      xs t        j                  d      }n*t        j                  d      }t        j                  d      }|r|s t        d       t        j                  d       t        ||      |_        d|_        |j
                  rd |j
                   d!nd"}	t        d#|	 d$       |j"                  rd|_        t        d%       d }
d }|j&                  rt)        j*                         }|j,                  j/                  d&|j0                         t)        j2                  |      }
|
j5                          d {    t7        t        j                  d'd(            }t)        j8                  |
d)|      }|j;                          d {    t        d*| d&       t        j<                  j?                  t        j<                  jA                  t        j<                  jC                  tD                    d+      }t        j<                  jG                  |      rt        j<                  jI                  t        j<                  j?                  |d,            rQtK        jL                  g d-|tJ        jN                  tJ        jN                  t        jP                  .      }t        d/       t        d0       t        d1       t        d2       t        d3       t        d4|        t        d5tR         d6tT         d7       t        d8tV         d9       t        d:       t        d;       |j                  rd<n|j&                  rd=nd>}|j"                  r|d?z  }t        d@| dA       |j                  r|jY                          d {    |j                  r|jZ                  r8|jZ                  j]                         st_        j`                  dB       d {    nat        dC       |j                  r|j                  jc                  dD       d|_2        t_        jf                  |ji                               |_-        |j                  ry y t        dE       t        dF       t        dG       t        dH       t        dI       t        dJ       t        dK       t        dL       t        d3       t_        jj                         }	 |j                  r>|jm                  d dM        d {   }|dNk(  r|jY                          d {    n|dOk(  r`|j"                  r|j"                  dPz  dQdRndS}|jn                  r|jn                  dPz  dQdRndS}|j"                  r(|jn                  r|j"                  |jn                  z
  dPz  nd }t        dAdT        |jp                  rt        dU|jp                  dVdW       |jr                  rt        dX|jr                  dY       |jt                  rt        dZ|jt                  d[       |jv                  r#t        d\|jv                  d]z  d^z  d_z  dQd`       |jy                         }t        da|dbdctR         d6tT         dd       t        de| df       t        dg| dht{        |j|                         di       |t        dj|dkdR       |j                         }|kt        dl|dmd |dPz  dkdn       ||j                  kD  rt        do       n9||j                   k  rt        dp       nt        dq|j                  dPz  dQdn       t        dr|j                  dsdt       t        du|j                  dvdt       t        dw|j                   dx       |j                  j                  dykD  rt        dz|j                  j                  j                          d{|j                  j                          t        d||j                  j                  dPz  dQd}|j                  j                  dPz  dQdR       |j                  rAt        d~|j                  j                          d{|j                   d|j                  d       t        dT        n|dk(  r|j                          d {    nq|dk(  r9t        |j                  dz   d      |_C        t        d|j                   dx       n3|d6k(  r8t        |j                  dz
  d      |_C        t        d|j                   dx       n|dk(  rL|j                   |_O        |j                  s|j                  |_Q        t        d|j                  rdnd        n|dk(  r8|j                          d {    |j                          d {    d|_2        nh|dk(  rX|j                  j                  dykD  r0|j                          d {    |j                          d {    d|_        d|_2        nt        d       |j                  r>|rQt        j                  t        j                  |j                        t        j                         |j                          |
r|
j                          d {    t        j                  dy       y 7 	R7 	7 7 7 7 7 7 37 7 7 7 9# |rQt        j                  t        j                  |j                        t        j                         |j                          |
r|
j                          d {  7   t        j                  dy       w xY ww)Nu&   Volatility Arb — BTC 15-min Binaries)descriptionz
--telegram
store_truez3Headless mode: telegram notifications, no dashboard)r  helpz--dashboardz'Dashboard mode: websocket + frontend UIz--ivz:Follow IV mode: trade WITH the market instead of fading itz	--accountuQ   Account name (e.g. mom) — reads KALSHI_MOM_API_KEY, TELEGRAM_MOM_BOT_TOKEN etc.)r  defaultrB  KALSHI__API_KEY_API_SECRETu   ❌ Missing KALSHI_z_API_KEY/KALSHI_rX   KALSHI_API_KEYKALSHI_API_SECRETr   u!   ❌ Missing KALSHI_API_KEY/SECRETu$   ❌ Missing KALSHI_MARKET_ID in .envT	TELEGRAM_
_BOT_TOKENTELEGRAM_BOT_TOKEN_CHAT_IDTELEGRAM_CHAT_IDu/   ❌ Missing TELEGRAM_BOT_TOKEN/TELEGRAM_CHAT_IDr+  r/  r   u   ✓ Telegram modeu    — headless, auto-unpauseu.   ✓ Follow IV mode — trading WITH the marketz/wsWS_PORT8765z0.0.0.0u#   ✓ Dashboard WS on ws://localhost:frontendzpackage.json)npmrundev)cwdr  stderr
preexec_fnu7   ✓ Frontend dev server started (http://localhost:5174)zG
======================================================================u&   VOLATILITY ARB — BTC 15-min Binariesz%CCXT 6-exchange avg spot vs Kalshi IVzF======================================================================z
  KALSHI_MARKET_ID = z  Trading window  = r%  zs into marketz  RV window       = zs (3 min rolling)z  RV filter       = 25-75%z  Drawdown limit  = $15ztelegram (headless)	dashboardinteractivez + follow-IVz  Mode            = r  r"   u&   
⚠️ Loop task ended — restartingu%   ⚠️ Loop task ended — restartingz	Controls:u)     [G] Start (3-min warmup → auto-trade)z  [V] Vol analysis detailz   [N] Cancel pending maker orderz%  [+] More contracts/trade  [-] Fewerz  [R] Pause/resumez  [Z] Close all + stopz
  [Q] Quitc                  P    t        d      j                         j                         S )Nz	Command: )inputstriprG  r4   r   r   r  zmain.<locals>.<lambda>  s    5;M;S;S;U;[;[;] r   GVr   rt  r  zN/Az2==================================================z  Spot:   $r`  z (6-exchange avg)r_  ,z  Mid:    $z.4frw  r   r   rF  ry  rs  ru  zs (window: rv  z
  IV:     z  (annualized)z
  RV:     z  (z	 samples)z
  IV-RV:  r  z
  Edge:   r%  z%)z  Signal: YESz  Signal: NOu     Signal: FLAT (±z
  Delta:  z.8fz
 /contractz
  Gamma:  z.10fz
  Size:   z/trader   z
  Pos:    z xz  Entry:  IV=z% RV=z  Pending: r  r  rh   +r   z  Rz
  PausedResumedZFQu   ❌ Invalid)ZargparseArgumentParseradd_argumentr3   
parse_argsaccountrG  r   r   r(   r  exitr   r   r   r   r   r   r   rW  r   Applicationrouteradd_getr  	AppRunnersetupr   TCPSiterS  r   rJ   dirnameabspath__file__isdirr   
subprocessPopenDEVNULLsetsidr  r  r   r>  r   doner  rc  r/   r   create_taskr"  r   r!  r   r   r   r   r   r  r   r   r  r   r   r   r   r   r   r   r   r   r   r   r   rb  minrz  r   r   r   r  killpggetpgidpidr-  SIGTERMwaitcleanup)parserargsrf  kkksr   r   tg_tokentg_chatacctrunnerfrontend_procappws_portsitefrontend_dirr8  lpr   r   r   r  r  r  s                           r   mainr  Z  s
    $$1YZF
\R  T
lF  H
|Y  [
#tp  rD ||##%YY12YY45'x/?x{STVYV^V^_`VaYY'(YY*+
))&
'CRBCSXXa[<=sxx{r2AAI }}<<\\'')Fyy9VHJ!?@cBIINbDcHii)F88 <=^K]A^Gyy!56Hii 23GwCDchhqk%h8
'+||DLL>#!$'BCDww>? FM~~oo

5!,,/s#llnbii	623{{69g6jjl3G9C@Aww||BGGOOBGGOOH4M$NPZ[77==&277>>"'',,|Uc:d+e&,,%<!))*2D2D99&M KM	-	
23	
12	&M	#C5
)*	 !3 4A6F5G}
UV	  00A
BC	&(	#%$(MM dnn{ZgDww&	 b
)*}}hhjiivvaffkkmmmA&&& ?@::JJOO$KL ,,QVVX6 ii 	k9:)*0156"#&'lf##%B	)),,T3]^^8((*$$#X/0ttADDHS>+B/0ttADDHS>+B01!$$+,4BBvh-(vvu{166$-?P%QRxxQXXaL'A!Buuek!%%$=>uuejvb1CC0H$MN..0GK}K@R?SSTUeTffhijJrd.9:Jrd#c!++.>-?yIJ~
2d)156::<D'
4+RSbIJ!,,.o0F!Q\\M153H#&8c9I#8Nb$QRJqwwsm:>?JqwwtnJ?@Jq{{m6:;uu*
155::+;+;+=*>b@QRSaeennS.@-EU155>>Z]K]^aJbbcde}}ANN,@,@,B+C2aooEVVZ[\[j[jknZopqVH&#X**,,,#X"%akkAos";AKBq{{m623#X"%akkAoq"9AKBq{{m623#X#$88|AH88)*DQXX9 EFG#X**,,,++-''$AH#Xuu*..000kkm++ %AI$AH-(u ))x 		"**]%6%67H""$nn&&&HHQKo 	 	4 	 '. _$@ - -' 1+ '	 		"**]%6%67H""$nn&&&HHQKs  Mur$Au r'!G8ur*Au(r-)A2uA9u#s 9r0:s r3Ns r6C*s r9s r<=s r?s 4s5*s !A(u	s
u'u*u-u0s 3s 6s 9s <s ?s s uA)u
.t1/u

u__main__)H__doc__r   r  r  rc   r  hashlibhmacr  urllib.parseurllibr#   ru  r-  re  concurrent.futures
concurrentr%   collectionsr   dataclassesr   typingr   r   r   r   r	   dotenvr
   cryptography.hazmat.primitivesr   r   )cryptography.hazmat.primitives.asymmetricr   cryptography.hazmat.backendsr   r  r   rH   futuresThreadPoolExecutorr-   r   dbr5   r=   r6   r7   r:   r(   r9   r'   r)   r>   r@   rh   rl   rx   r|   r~   r   r   r   MARKET_DURATIONr  r  r   r   r  r0   rR  r4   r   r   <module>r     s`   m l l l l l l    ! ' ' '  @ = 8     00QSW0X- -$9FF
)C&s+	
$%Dr&!+ !+H > >,-5n8   
  KC KC\ob zGKK q&  9	OA3
 #5b9s   4'D? ?EEE