mirror of
https://github.com/cjudice-commits/prediction-market-arb.git
synced 2026-07-27 13:37:46 +00:00
a65256ca74
New arb/prepare.py + GET /api/prepare: for one monthly arb pair it re-pulls fresh quotes (incl. real Kalshi top-of-book ask size) and builds the exact order pair a cross-venue hedge would need -- sides from best_side, size capped to the thinner book, limit = ask + slippage buffer, capital required, guaranteed worst-case, and warnings. Places NO orders and touches no order endpoints anywhere. UI: a "Prepare trade" button in the monthly drawer's breakdown card opens a PREVIEW-ONLY ticket modal (max-size + slippage-cent inputs that re-price live; a deliberately disabled Confirm button as the Step-2 placeholder). Also reorders the expanded drawer so the breakdown/Prepare card is the wide left column. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
135 lines
5.4 KiB
HTML
135 lines
5.4 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>Arb Scanner · Kalshi × Polymarket</title>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@500;600&display=swap" rel="stylesheet">
|
||
<link rel="stylesheet" href="style.css">
|
||
</head>
|
||
<body>
|
||
<div class="aurora"></div>
|
||
|
||
<header>
|
||
<div class="brand">
|
||
<div class="logo">◆</div>
|
||
<div>
|
||
<h1>Arb Scanner</h1>
|
||
<span class="sub">Kalshi × Polymarket · crypto</span>
|
||
</div>
|
||
<div class="tabs" id="tabs">
|
||
<button data-m="monthly" class="on">Monthly arb</button>
|
||
<button data-m="hourly">Hourly <span class="spec">spec</span></button>
|
||
<button data-m="daily">IBKR × Kalshi</button>
|
||
<button data-m="positions">Positions</button>
|
||
</div>
|
||
</div>
|
||
<div class="actions">
|
||
<div class="live"><span class="dot"></span><span id="meta">connecting…</span></div>
|
||
<label class="auto"><input type="checkbox" id="auto"><span>Auto 8s</span></label>
|
||
<button id="settingsBtn" class="ghost">Settings</button>
|
||
<button id="refresh" class="primary"><span class="bspin"></span><span class="blabel">Refresh</span></button>
|
||
</div>
|
||
</header>
|
||
|
||
<div id="hbanner" class="hbanner" hidden>
|
||
<div class="hb-ico">⚠</div>
|
||
<div class="hb-txt">
|
||
<b>Speculative — not a locked arb.</b> Kalshi settles on CF Benchmarks,
|
||
Polymarket on Binance. Different feeds & the discrete-strike gap mean
|
||
legs can both lose. Live Binance↔CF divergence:
|
||
<span id="hbDiv" class="hb-div">—</span>
|
||
</div>
|
||
</div>
|
||
|
||
<section id="summary" class="summary"></section>
|
||
|
||
<section id="hero" class="hero" hidden>
|
||
<div class="hero-head"><h2>Top opportunities</h2><span class="muted">positive guaranteed return, ranked</span></div>
|
||
<div id="heroCards" class="hero-cards"></div>
|
||
</section>
|
||
|
||
<section class="toolbar">
|
||
<div class="search">
|
||
<svg viewBox="0 0 24 24" width="15" height="15"><path d="M21 21l-4.3-4.3M11 18a7 7 0 1 1 0-14 7 7 0 0 1 0 14Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
|
||
<input type="search" id="search" placeholder="Search asset, ticker, market…">
|
||
</div>
|
||
<div id="assetChips" class="chips"></div>
|
||
<div class="seg" id="statusSeg">
|
||
<button data-s="" class="on">All</button>
|
||
<button data-s="ARB">Arb</button>
|
||
<button data-s="NO ARB">No arb</button>
|
||
<button data-s="NO POLY">No Poly</button>
|
||
<button data-s="BAD BASIS">Bad basis</button>
|
||
<button data-s="LOW SIZE">Low size</button>
|
||
</div>
|
||
<label class="chk"><input type="checkbox" id="favOnly"><span>Favorable basis</span></label>
|
||
<span class="count" id="rowCount"></span>
|
||
</section>
|
||
|
||
<main>
|
||
<table id="grid">
|
||
<thead><tr id="head"></tr></thead>
|
||
<tbody id="body"></tbody>
|
||
</table>
|
||
<div id="empty" class="empty" hidden>
|
||
<div class="empty-art">◇</div>
|
||
<p>No markets match the current filters.</p>
|
||
</div>
|
||
</main>
|
||
|
||
<section id="positions" class="positions" hidden></section>
|
||
|
||
<div id="ibkrSetup" class="hbanner" hidden>
|
||
<div class="hb-ico">⚙︎</div>
|
||
<div class="hb-txt">
|
||
<b id="ibkrSetupTitle">IBKR not connected.</b>
|
||
<span id="ibkrSetupMsg"></span>
|
||
<span class="muted">Local-only feature — needs the IBKR Client Portal Gateway running on this Mac and a populated <code>data/ibkr_contracts.json</code>.</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="settingsModal" class="modal" hidden>
|
||
<div class="card">
|
||
<h2>Scanner settings</h2>
|
||
<p class="hint">Mirrors the workbook <em>Settings</em> sheet · persisted server-side.</p>
|
||
<label>Kalshi fee rate <input type="number" step="0.001" id="s_kfee"></label>
|
||
<label>Polymarket fee rate <input type="number" step="0.001" id="s_pfee"></label>
|
||
<label>Min net return <input type="number" step="0.0001" id="s_minret"></label>
|
||
<label>Min Poly volume ($) <input type="number" step="100" id="s_minvol"></label>
|
||
<label>Min contracts <input type="number" step="1" id="s_minct"></label>
|
||
<div class="row">
|
||
<button id="saveSettings" class="primary">Save & rescan</button>
|
||
<button id="closeSettings" class="ghost">Cancel</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="ticketModal" class="modal" hidden>
|
||
<div class="card tk-card">
|
||
<div class="tk-top">
|
||
<h2>Prepare trade <span class="tk-badge">PREVIEW ONLY</span></h2>
|
||
<button id="tkClose" class="ghost tk-x" aria-label="Close">✕</button>
|
||
</div>
|
||
<div class="tk-banner">Nothing is sent to Kalshi or Polymarket. This is exactly
|
||
what the two orders <b>would</b> be — for review only.</div>
|
||
<div id="ticketBody"></div>
|
||
<div class="tk-controls">
|
||
<label>Max size <input type="number" id="tkMax" min="1" step="1" placeholder="all"></label>
|
||
<label>Slippage buffer (¢) <input type="number" id="tkBuf" min="0" step="1" value="1"></label>
|
||
</div>
|
||
<div class="tk-foot">
|
||
<button class="primary tk-confirm" disabled
|
||
title="Execution is not wired — this is Step 1 (preview only)">Confirm & Send — not enabled</button>
|
||
<span class="tk-foot-note">Step 2 would place these with your keys, only on your click.</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="toast" class="toast" hidden></div>
|
||
<script src="app.js"></script>
|
||
</body>
|
||
</html>
|