| 1 | """ |
| 2 | Effective Exposure Discount Module for Hermes v4.3 |
| 3 | |
| 4 | When bets are essentially won/lost (market price near $1.00 or $0.00) but Kalshi |
| 5 | hasn't officially settled them yet, raw exposure stays locked and blocks new trades |
| 6 | during prime hours. This module provides "effective exposure" that discounts |
| 7 | near-certain outcomes so capital is freed for new opportunities. |
| 8 | |
| 9 | The actual settlement process is unchanged - this only affects the *trading gate*. |
| 10 | """ |
| 11 | |
| 12 | DISCOUNT_TIERS = [ |
| 13 | (0.95, 0.00), |
| 14 | (0.85, 0.25), |
| 15 | (0.75, 0.50), |
| 16 | |
| 17 | ] |
| 18 | |
| 19 | def effective_exposure_factor(side, yes_price): |
| 20 | """ |
| 21 | Given a trade's side ('yes' or 'no') and the current YES price on Kalshi, |
| 22 | return the fraction of cost that should count as effective exposure. |
| 23 | |
| 24 | Returns float in [0.0, 1.0]. |
| 25 | """ |
| 26 | if yes_price is None: |
| 27 | return 1.0 |
| 28 | |
| 29 | if side == "yes": |
| 30 | win_price = yes_price |
| 31 | else: |
| 32 | win_price = 1.0 - yes_price |
| 33 | |
| 34 | for threshold, factor in DISCOUNT_TIERS: |
| 35 | if win_price >= threshold: |
| 36 | return factor |
| 37 | |
| 38 | return 1.0 |
| 39 | |
| 40 | def compute_effective_exposure(open_trades, price_lookup): |
| 41 | """ |
| 42 | Compute total effective exposure across all open trades. |
| 43 | |
| 44 | Args: |
| 45 | open_trades: list of dicts with keys: id, ticker, side, cost |
| 46 | price_lookup: dict mapping ticker -> current YES price (float) |
| 47 | or a callable(ticker) -> float |
| 48 | |
| 49 | Returns: |
| 50 | (effective_total, details) where details is a list of per-trade info dicts |
| 51 | """ |
| 52 | effective_total = 0.0 |
| 53 | details = [] |
| 54 | |
| 55 | for trade in open_trades: |
| 56 | ticker = trade["ticker"] |
| 57 | side = trade["side"] |
| 58 | cost = float(trade["cost"]) |
| 59 | |
| 60 | if callable(price_lookup): |
| 61 | yes_price = price_lookup(ticker) |
| 62 | else: |
| 63 | yes_price = price_lookup.get(ticker) |
| 64 | |
| 65 | factor = effective_exposure_factor(side, yes_price) |
| 66 | effective_cost = round(cost * factor, 2) |
| 67 | effective_total += effective_cost |
| 68 | |
| 69 | details.append({ |
| 70 | "id": trade.get("id"), |
| 71 | "ticker": ticker, |
| 72 | "side": side, |
| 73 | "cost": cost, |
| 74 | "yes_price": yes_price, |
| 75 | "factor": factor, |
| 76 | "effective_cost": effective_cost, |
| 77 | }) |
| 78 | |
| 79 | return round(effective_total, 2), details |