
    ni                          d Z ddlZddlmZmZmZ ddlmZmZm	Z	m
Z
mZmZmZmZmZmZmZmZmZ dededefdZd	ed
ededefdZ G d d      Zy)u]   
PolyEdge — Risk & Position Sizing

Kelly Criterion-based sizing with bankroll management.
    N)DictAnyOptional)KELLY_FRACTIONBASE_BET_PCTMAX_BET_PCTMIN_BET_USDMAX_BET_USDMAX_DAILY_LOSS_PCTMAX_CONSECUTIVE_LOSSESCOOLDOWN_BARSMAX_OPEN_POSITIONSBANKROLL_FLOOR_PCTTAKER_FEE_BPSMAKER_FEE_BPSUSE_LIMIT_ORDERSpricesize_usdreturnc                 >    t         dz  }|t        | d| z
        z  |z  S )zY
    Calculate Polymarket taker fee.
    Fee = baseRate * min(price, 1-price) * size
    i'     )r   min)r   r   	base_rates      1/var/www/html/crpytotradingbot/polymarket/risk.pycalc_taker_feer      s)    
 %Is5!e),,x77    edge	win_pricebankrollc                    || z   }t        dt        d|            }d|z
  }d|z
  |z  }|dk  ry||z  |z
  |z  }|dk  ry|t        z  }||z  }t        t        t        |t                    }t        ||t
        z        }t        |d      S )aG  
    Calculate optimal bet size using Kelly Criterion.
    
    For a binary bet:
    - Win probability: p = market_price + edge (our estimate of true prob)
    - Win payout: (1 - buy_price) / buy_price  (odds)
    - Kelly: f* = (p * b - q) / b
      where b = payout odds, p = win prob, q = 1-p
    
    We use fractional Kelly (KELLY_FRACTION) for safety.
    
    Args:
        edge: Our edge (fair_value - market_price for buy_yes)
        win_price: Price we buy at (market YES price for buy_yes)
        bankroll: Current bankroll
    
    Returns:
        Bet size in USD
    {Gz?gGz?r   r      )maxr   r   r	   r
   r   round)	r   r   r   pqbkelly_ffbets	            r   kelly_bet_sizer+      s    2 	DAD#dA,A	AA 
Y)#AAv 1uqyAoG!| 	. A h,C k3sK0
1C
c8k)
*Ca=r   c                   z    e Zd ZdZdefdZdefdZdee	e
f   defdZdee	e
f   fd	Zd
 Zd Zdee	e
f   fdZy)RiskManagerz=
    Manages bankroll, tracks P&L, enforces risk limits.
    initial_bankrollc                     || _         || _        || _        || _        d| _        d| _        d| _        d| _        d| _        d| _	        d| _
        d| _        d| _        d| _        d| _        |g| _        g | _        y )Nr   )r.   r   peak_bankrolldaily_starttotal_tradeswinslossesconsecutive_lossescooldown_remainingopen_positions	total_pnl
total_feesmax_drawdown_pct	daily_pnldaily_tradesequity_curve	trade_log)selfr.   s     r   __init__zRiskManager.__init__V   s     0(-+ 	"#"# !  $4"4!r   r   c                    | j                   dkD  rdd| j                    dfS | j                  t        k\  rt        | _         ddt         dfS | j                   t        | j                  d      z  }|t        k\  r	dd|d	d
fS | j                  | j                  t        z  k  rddt        ddfS | j                  t        k\  rddt         d
fS | j                  t        k  ryy)z_
        Check if we're allowed to trade.
        Returns (allowed: bool, reason: str)
        r   Fz
Cooldown: z bars remainingzHit z! consecutive losses, cooling downr   zDaily loss limit hit (z.1%)zBankroll below z.0%z floorzMax open positions ()FzBankroll depleted)TOK)r6   r5   r   r   r;   r#   r1   r   r   r.   r   r7   r   r	   )r?   daily_loss_pcts     r   	can_tradezRiskManager.can_tradeo   s    ""Q&Jt'>'>&?OOO ""&<<&3D#D!7 88YZZZ ..3t/?/?+CC//2>#2FaHHH ==4003EEEO,>s+C6JJJ "4401C0DAFFF ==;&-r   signalc                     | j                         \  }}|sy|d   }|d   dk(  r|d   }nd|d   z
  }t        ||| j                        }|d   dk(  r"|d	z  }t        || j                  t        z        }|S )
z
        Size a trade based on signal edge and Kelly criterion.
        
        Args:
            signal: Signal dict from SignalEngine
        
        Returns:
            Bet size in USD (0 if shouldn't trade)
        r   r   	directionbuy_yesmarket_pricer   strengthstrongg      ?)rE   r+   r   r   r   )r?   rF   allowedreasonr   	buy_pricer*   s          r   
size_tradezRiskManager.size_trade   s     ..*f~+)+~.IF>22IT9dmm< *)3JCc4==;67C
r   resultc                    |d   }|d   }||z
  }| xj                   |z  c_         | xj                  |z  c_        | xj                  |z  c_        | xj                  |z  c_        | xj                  dz  c_        | xj
                  dz  c_        |d   r| xj                  dz  c_        d| _        n*| xj                  dz  c_        | xj                  dz  c_        t        | j                  | j                         | _
        | j                  | j                   z
  | j                  z  dz  }t        | j                  |      | _        | j                  j                  | j                          | j                  j                  |       y)a(  
        Record a completed trade.
        
        Args:
            result: {
                'direction': str,
                'bet_size': float,
                'buy_price': float,
                'won': bool,
                'pnl': float,
                'fee': float,
            }
        pnlfeer   wonr   d   N)r   r8   r9   r;   r2   r<   r3   r5   r4   r#   r0   r:   r=   appendr>   )r?   rQ   rS   rT   net_pnldd_pcts         r   record_tradezRiskManager.record_trade   s2    UmUm) '!3'!QQ%=IINI&'D#KK1K##q(# !!3!3T]]C$$t}}48J8JJSP #D$9$96 B  /f%r   c                 N    | j                   dkD  r| xj                   dz  c_         yy)z&Called each bar to decrement cooldown.r   r   N)r6   r?   s    r   tickzRiskManager.tick   s&    ""Q&##q(# 'r   c                 B    | j                   | _        d| _        d| _        y)zReset daily counters.r   N)r   r1   r;   r<   r\   s    r   new_dayzRiskManager.new_day   s    ==r   c                    | j                   t        | j                  d      z  dz  }d}d}| j                  D cg c]  }|d   s	|d   |d   z
   }}| j                  D cg c]  }|d   r	|d   |d   z
   }}|rt	        |      t        |      z  }|rt	        |      t        |      z  }|r*t	        |      t        t        t	        |            d      z  n
t        d      }| j                  | j                  | j                  | j                  z  dz
  dz  | j                  | j                   | j                  ||||| j                  | j                  | j                  d	S c c}w c c}w )
zGet current performance stats.r   rV   r   rU   rS   rT   r!   inf)r   r8   
return_pctr2   r3   r4   win_rateavg_winavg_lossprofit_factorr:   r9   r5   )r3   r#   r2   r>   sumlenabsfloatr   r8   r.   r4   r:   r9   r5   )r?   wrrd   re   tr3   r4   pfs           r   	get_statszRiskManager.get_stats   sK   YYT..22S8-1^^Hqx%1U8#HH/3~~N!QuX!E(QuX%NN$i#d)+G6{S[0H8>SYSV-t44E%L ==4+@+@@1DK --IIkk  $ 5 5//"&"9"9
 	
 INs   
E!E!!
E&,E&N)__name__
__module____qualname____doc__rj   r@   tuplerE   r   strr   rP   rZ   r]   r_   rn    r   r   r-   r-   Q   sn    " "25 Bc3h E <&&4S> &&P)

4S> 
r   r-   )rr   mathtypingr   r   r   configr   r   r   r	   r
   r   r   r   r   r   r   r   r   rj   r   r+   r-   ru   r   r   <module>ry      sy     & &   8% 85 8U 83
33 3 	3ln
 n
r   