"""If a leg fills, should we immediately CROSS to finish the book?

There is no atomic way to sell all three outcomes on Kalshi. Combos are
all-or-nothing parlays priced by RFQ and cannot be sold, so the only way to hold
a box is to leg into it and accept the risk between fills. That risk is the
strategy's whole loss: -72c of partials today against +0.94c of completions.

The alternative to waiting is to CROSS -- once one leg fills, hit the bid on the
other two immediately, turning an unhedged partial into a finished book at a
known cost. That cost is the spread plus the taker fee on two legs.

Worth it only if
    (first fill) + (bid on leg 2) + (bid on leg 3) - taker fees > 1.00

which is a much higher bar than the maker version, because selling into the bid
gives up the spread on both legs. This measures it on today's actual books.
"""
import collections, sys

sys.path.insert(0, r'E:\soccer\main')
import kalshi_trader as kt

TAKER_RATE = 0.07


def taker_fee(p):
    return TAKER_RATE * p * (1.0 - p)


def main():
    fills = collections.defaultdict(lambda: [0.0, 0.0])
    for f in (kt.get_fills().get('fills') or []):
        if (not str(f.get('created_time', '')).startswith('2026-08-16')
                or f.get('is_taker')
                or str(f.get('side', '')).lower() == 'yes'
                or str(f.get('action', '')).lower() != 'sell'):
            continue
        a = fills[f['ticker']]
        q = float(f.get('count_fp') or 0)
        a[0] += q
        a[1] += float(f.get('yes_price_dollars') or 0) * q

    books = collections.defaultdict(list)
    for t in fills:
        books['-'.join(t.split('-')[:2])].append(t)

    print(f'{"book":32} {"have":>6} {"legs left":>10} {"cross cost":>11} '
          f'{"total":>7} {"vs 1.00":>8}')
    tot = n = 0
    for ev, ts in sorted(books.items()):
        if len(ts) >= 3:
            continue                       # already complete
        have = sum(fills[t][1] for t in ts)
        # the missing legs: infer from the event's three markets
        legs = set()
        for suffix in ('TIE',):
            legs.add(f'{ev}-{suffix}')
        for t in ts:
            legs.add(t)
        missing = []
        ok = True
        for t in legs - set(ts):
            m = (kt.get_market(t) or {}).get('market', {})
            bid = m.get('yes_bid_dollars')
            if bid is None or (m.get('status') or '') != 'active':
                ok = False
                break
            missing.append((t, float(bid)))
        if not ok or not missing:
            continue
        # we only know the third leg when exactly one is missing
        if len(ts) != 2:
            continue
        cross = sum(b for _, b in missing)
        fee = sum(taker_fee(b) for _, b in missing)
        total = have + cross - fee
        n += 1
        tot += total - 1.0
        print(f'  {ev.replace("KX","")[:30]:30} {have*100:>5.0f}c '
              f'{len(missing):>10} {cross*100:>10.0f}c {total*100:>6.0f}c '
              f'{(total-1)*100:>+7.1f}c')
    if n:
        print(f'\n  {n} books one leg short; crossing all of them: '
              f'{tot*100:+.1f}c total, {tot/n*100:+.2f}c each')
    print('\n  Compare with holding: a partial is EV-neutral in theory but ran')
    print('  -9.7c a book today. Crossing converts that variance into a known,')
    print('  usually small, loss.')


if __name__ == '__main__':
    main()
