Files
Kalshi_Polymarket/web/index.html
T

135 lines
5.4 KiB
HTML
Raw Normal View History

<!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&nbsp;Scanner</h1>
<span class="sub">Kalshi&nbsp;×&nbsp;Polymarket · crypto</span>
</div>
<div class="tabs" id="tabs">
<button data-m="monthly" class="on">Monthly&nbsp;arb</button>
<button data-m="hourly">Hourly&nbsp;<span class="spec">spec</span></button>
<button data-m="daily">IBKR&nbsp;×&nbsp;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&nbsp;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&nbsp;Benchmarks,
Polymarket on Binance. Different feeds &amp; 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&nbsp;arb</button>
<button data-s="NO POLY">No&nbsp;Poly</button>
<button data-s="BAD BASIS">Bad&nbsp;basis</button>
<button data-s="LOW SIZE">Low&nbsp;size</button>
</div>
<label class="chk"><input type="checkbox" id="favOnly"><span>Favorable&nbsp;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 &amp; 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 &amp; Send — not enabled</button>
<span class="tk-foot-note">Step&nbsp;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>