Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Safe Choices - Prediction Market Simulation</title> | |
| <link rel="stylesheet" href="/static/styles.css?v=12"> | |
| <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&display=swap" rel="stylesheet"> | |
| <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | |
| </head> | |
| <body> | |
| <!-- Header --> | |
| <header class="header"> | |
| <div class="header-content"> | |
| <div class="brand"> | |
| <div class="brand-icon"> | |
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> | |
| <path d="M12 2L2 7l10 5 10-5-10-5z"/> | |
| <path d="M2 17l10 5 10-5"/> | |
| <path d="M2 12l10 5 10-5"/> | |
| </svg> | |
| </div> | |
| <div class="brand-text"> | |
| <h1>Safe Choices</h1> | |
| <span class="brand-tagline">Prediction Market Simulator</span> | |
| </div> | |
| </div> | |
| <div class="header-meta"> | |
| <div class="data-badge"> | |
| <span class="badge-dot"></span> | |
| Polymarket 2025 | |
| </div> | |
| </div> | |
| </div> | |
| </header> | |
| <!-- Main Layout --> | |
| <main class="main"> | |
| <!-- Sidebar --> | |
| <aside class="sidebar"> | |
| <!-- View Toggle --> | |
| <div class="sidebar-section"> | |
| <div class="section-label">View</div> | |
| <div class="toggle-group"> | |
| <button class="toggle-btn active" data-view="simulation" onclick="selectView('simulation')"> | |
| <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> | |
| <rect x="3" y="3" width="18" height="18" rx="2"/> | |
| <path d="M3 9h18"/> | |
| <path d="M9 21V9"/> | |
| </svg> | |
| Simulator | |
| </button> | |
| <button class="toggle-btn" data-view="methodology" onclick="selectView('methodology')"> | |
| <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> | |
| <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/> | |
| <path d="M14 2v6h6"/> | |
| <path d="M16 13H8"/> | |
| <path d="M16 17H8"/> | |
| <path d="M10 9H8"/> | |
| </svg> | |
| Methodology | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Simulation Type --> | |
| <div class="sidebar-section simulation-view-only"> | |
| <div class="section-label">Strategy</div> | |
| <div class="strategy-cards"> | |
| <button class="strategy-card active" data-sim="single" onclick="selectSimulation('single')"> | |
| <div class="strategy-icon"> | |
| <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> | |
| <circle cx="12" cy="12" r="10"/> | |
| <path d="M12 6v6l4 2"/> | |
| </svg> | |
| </div> | |
| <div class="strategy-info"> | |
| <span class="strategy-name">Single Fund</span> | |
| <span class="strategy-desc">All-in sequential betting</span> | |
| </div> | |
| </button> | |
| <button class="strategy-card" data-sim="threshold" onclick="selectSimulation('threshold')"> | |
| <div class="strategy-icon"> | |
| <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> | |
| <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/> | |
| <polyline points="22 4 12 14.01 9 11.01"/> | |
| </svg> | |
| </div> | |
| <div class="strategy-info"> | |
| <span class="strategy-name">Target Return</span> | |
| <span class="strategy-desc">Stop at profit goal</span> | |
| </div> | |
| </button> | |
| <button class="strategy-card" data-sim="multi" onclick="selectSimulation('multi')"> | |
| <div class="strategy-icon"> | |
| <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> | |
| <rect x="3" y="3" width="7" height="7"/> | |
| <rect x="14" y="3" width="7" height="7"/> | |
| <rect x="14" y="14" width="7" height="7"/> | |
| <rect x="3" y="14" width="7" height="7"/> | |
| </svg> | |
| </div> | |
| <div class="strategy-info"> | |
| <span class="strategy-name">Multi Fund</span> | |
| <span class="strategy-desc">Diversified portfolio</span> | |
| </div> | |
| </button> | |
| <button class="strategy-card" data-sim="kelly" onclick="selectSimulation('kelly')"> | |
| <div class="strategy-icon"> | |
| <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> | |
| <path d="M12 2v20M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/> | |
| </svg> | |
| </div> | |
| <div class="strategy-info"> | |
| <span class="strategy-name">Kelly Criterion</span> | |
| <span class="strategy-desc">Optimal position sizing</span> | |
| </div> | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Quick Info --> | |
| <div class="sidebar-section simulation-view-only"> | |
| <div class="quick-stats"> | |
| <div class="quick-stat"> | |
| <span class="quick-stat-value" id="marketCount">4,265</span> | |
| <span class="quick-stat-label">Markets</span> | |
| </div> | |
| <div class="quick-stat"> | |
| <span class="quick-stat-value">2025</span> | |
| <span class="quick-stat-label">Dataset</span> | |
| </div> | |
| </div> | |
| </div> | |
| </aside> | |
| <!-- Content --> | |
| <div class="content"> | |
| <!-- Simulation View --> | |
| <div class="simulation-content" id="simulationContent"> | |
| <!-- Parameters Panel --> | |
| <section class="panel parameters-panel"> | |
| <div class="panel-header"> | |
| <h2> | |
| <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> | |
| <circle cx="12" cy="12" r="3"/> | |
| <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/> | |
| </svg> | |
| Parameters | |
| </h2> | |
| </div> | |
| <!-- Hidden defaults --> | |
| <input type="hidden" id="startingCapital" value="10000"> | |
| <input type="hidden" id="startDate" value="2025-01-01"> | |
| <input type="hidden" id="maxDuration" value="365"> | |
| <div class="params-grid"> | |
| <!-- Core Parameters --> | |
| <div class="param-group"> | |
| <label class="param-label"> | |
| Simulations | |
| <span class="param-hint" data-tooltip="Number of Monte Carlo simulation runs">?</span> | |
| </label> | |
| <div class="param-input-wrap"> | |
| <input type="number" id="numSimulations" class="param-input" value="100" min="10" max="100" step="10"> | |
| <span class="param-unit">runs</span> | |
| </div> | |
| </div> | |
| <div class="param-group"> | |
| <label class="param-label"> | |
| Days Before | |
| <span class="param-hint" data-tooltip="Days before market resolution to invest">?</span> | |
| </label> | |
| <div class="param-input-wrap"> | |
| <input type="number" id="daysBefore" class="param-input" value="1" min="1" max="7" step="1"> | |
| <span class="param-unit">days</span> | |
| </div> | |
| </div> | |
| <div class="param-group"> | |
| <label class="param-label"> | |
| Min Prob @ 7d | |
| <span class="param-hint" data-tooltip="Minimum probability 7 days before resolution">?</span> | |
| </label> | |
| <div class="param-input-wrap"> | |
| <input type="number" id="minProb7d" class="param-input" value="90" min="50" max="99" step="1"> | |
| <span class="param-unit">%</span> | |
| </div> | |
| </div> | |
| <div class="param-group"> | |
| <label class="param-label"> | |
| Min Prob @ Entry | |
| <span class="param-hint" data-tooltip="Minimum probability at time of investment">?</span> | |
| </label> | |
| <div class="param-input-wrap"> | |
| <input type="number" id="minProbCurrent" class="param-input" value="90" min="50" max="99" step="1"> | |
| <span class="param-unit">%</span> | |
| </div> | |
| </div> | |
| <div class="param-group"> | |
| <label class="param-label"> | |
| Min Volume | |
| <span class="param-hint" data-tooltip="Minimum market volume in USD">?</span> | |
| </label> | |
| <div class="param-input-wrap"> | |
| <input type="number" id="minVolume" class="param-input" value="1000000" min="100000" max="10000000" step="100000"> | |
| <span class="param-unit">$</span> | |
| </div> | |
| </div> | |
| <div class="param-group"> | |
| <label class="param-label"> | |
| Trading Frequency | |
| <span class="param-hint" data-tooltip="How often to trade when opportunities exist">?</span> | |
| </label> | |
| <select id="investmentProbability" class="param-input param-select"> | |
| <option value="0.02">Conservative</option> | |
| <option value="0.04" selected>Moderate</option> | |
| <option value="0.06">Aggressive</option> | |
| <option value="1.0">Every Possible Day</option> | |
| </select> | |
| </div> | |
| <!-- Threshold-specific --> | |
| <div class="param-group threshold-only"> | |
| <label class="param-label"> | |
| Target Return | |
| <span class="param-hint" data-tooltip="Stop trading when this return is reached">?</span> | |
| </label> | |
| <select id="targetReturn" class="param-input param-select"> | |
| <option value="4.14">4.14% (Treasury)</option> | |
| <option value="10.56">10.56% (NASDAQ)</option> | |
| <option value="custom">Custom...</option> | |
| </select> | |
| <input type="number" id="customTarget" class="param-input custom-target-input" min="1" max="100" step="0.1" placeholder="Enter %"> | |
| </div> | |
| <!-- Multi-fund specific --> | |
| <div class="param-group multi-only"> | |
| <label class="param-label"> | |
| Number of Funds | |
| <span class="param-hint" data-tooltip="Split capital across independent funds">?</span> | |
| </label> | |
| <div class="param-input-wrap"> | |
| <input type="number" id="numFunds" class="param-input" value="5" min="2" max="10" step="1"> | |
| <span class="param-unit">funds</span> | |
| </div> | |
| </div> | |
| <!-- Kelly-specific --> | |
| <div class="param-group kelly-only"> | |
| <label class="param-label"> | |
| Kelly Fraction | |
| <span class="param-hint" data-tooltip="Fraction of Kelly bet to use (lower = less variance)">?</span> | |
| </label> | |
| <select id="kellyFraction" class="param-input param-select"> | |
| <option value="0.25">Quarter Kelly (25%)</option> | |
| <option value="0.5" selected>Half Kelly (50%)</option> | |
| <option value="1.0">Full Kelly (100%)</option> | |
| </select> | |
| </div> | |
| <div class="param-group kelly-only"> | |
| <label class="param-label"> | |
| Edge Estimate | |
| <span class="param-hint" data-tooltip="How to estimate your edge over the market">?</span> | |
| </label> | |
| <select id="edgeEstimate" class="param-input param-select"> | |
| <option value="historical" selected>Historical Win Rate</option> | |
| <option value="fixed_edge">Fixed 1% Edge</option> | |
| <option value="fixed_edge_2">Fixed 2% Edge</option> | |
| </select> | |
| </div> | |
| </div> | |
| <!-- Run Button --> | |
| <div class="run-container"> | |
| <button class="run-btn" onclick="runSimulation()" id="runBtn"> | |
| <svg class="run-icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> | |
| <polygon points="5 3 19 12 5 21 5 3"/> | |
| </svg> | |
| <span class="run-text">Run Simulation</span> | |
| <div class="run-spinner"></div> | |
| </button> | |
| <span class="run-estimate" id="estimatedTime">~5-10 seconds</span> | |
| </div> | |
| </section> | |
| <!-- Progress Bar --> | |
| <section class="panel progress-panel" id="progressPanel"> | |
| <div class="progress-content"> | |
| <div class="progress-header"> | |
| <span id="progressText">Initializing...</span> | |
| <span id="progressPercent">0%</span> | |
| </div> | |
| <div class="progress-track"> | |
| <div class="progress-fill" id="progressFill"></div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Results Section --> | |
| <section class="results" id="resultsSection"> | |
| <!-- Key Metrics --> | |
| <div class="metrics-row"> | |
| <div class="metric-card metric-primary"> | |
| <div class="metric-label">Average Return</div> | |
| <div class="metric-value" id="avgReturn">--</div> | |
| </div> | |
| <div class="metric-card metric-survivors"> | |
| <div class="metric-label">Avg Return (Survivors)</div> | |
| <div class="metric-value" id="avgReturnSurvivors">--</div> | |
| </div> | |
| <div class="metric-card"> | |
| <div class="metric-label">Success Rate</div> | |
| <div class="metric-value" id="successRate">--</div> | |
| </div> | |
| <div class="metric-card metric-risk"> | |
| <div class="metric-label">Bust Rate</div> | |
| <div class="metric-value" id="bustRate">--</div> | |
| </div> | |
| </div> | |
| <!-- Secondary Stats --> | |
| <div class="stats-row"> | |
| <div class="stat-panel"> | |
| <h3>Risk Analysis</h3> | |
| <div class="stat-list"> | |
| <div class="stat-item"> | |
| <span class="stat-label">Volatility</span> | |
| <span class="stat-value" id="volatility">--</span> | |
| </div> | |
| <div class="stat-item"> | |
| <span class="stat-label">Max Drawdown</span> | |
| <span class="stat-value" id="maxDrawdown">--</span> | |
| </div> | |
| <div class="stat-item"> | |
| <span class="stat-label">5th Percentile</span> | |
| <span class="stat-value" id="percentile5">--</span> | |
| </div> | |
| <div class="stat-item"> | |
| <span class="stat-label">95th Percentile</span> | |
| <span class="stat-value" id="percentile95">--</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="stat-panel multi-stats"> | |
| <h3>Portfolio Stats</h3> | |
| <div class="stat-list"> | |
| <div class="stat-item"> | |
| <span class="stat-label">Surviving Funds</span> | |
| <span class="stat-value" id="avgSurvivingFunds">--</span> | |
| </div> | |
| <div class="stat-item"> | |
| <span class="stat-label">Survivorship Rate</span> | |
| <span class="stat-value" id="survivorshipRate">--</span> | |
| </div> | |
| <div class="stat-item"> | |
| <span class="stat-label">Diversification</span> | |
| <span class="stat-value" id="diversificationBenefit">--</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="stat-panel threshold-stats"> | |
| <h3>Target Performance</h3> | |
| <div class="stat-list"> | |
| <div class="stat-item"> | |
| <span class="stat-label">Target Reached</span> | |
| <span class="stat-value" id="targetReached">--</span> | |
| </div> | |
| <div class="stat-item"> | |
| <span class="stat-label">Avg Time to Target</span> | |
| <span class="stat-value" id="avgTimeToTarget">--</span> | |
| </div> | |
| <div class="stat-item"> | |
| <span class="stat-label">vs Never Stop</span> | |
| <span class="stat-value" id="vsNeverStop">--</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="stat-panel kelly-stats"> | |
| <h3>Kelly Stats</h3> | |
| <div class="stat-list"> | |
| <div class="stat-item"> | |
| <span class="stat-label">Avg Bet Size</span> | |
| <span class="stat-value" id="avgBetSize">--</span> | |
| </div> | |
| <div class="stat-item"> | |
| <span class="stat-label">Avg Edge</span> | |
| <span class="stat-value" id="avgEdge">--</span> | |
| </div> | |
| <div class="stat-item"> | |
| <span class="stat-label">Bets Skipped (No Edge)</span> | |
| <span class="stat-value" id="betsSkipped">--</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Charts --> | |
| <div class="charts-row"> | |
| <div class="chart-panel"> | |
| <div class="chart-header"> | |
| <h3>Return Distribution</h3> | |
| <button class="export-btn" onclick="exportResults()" id="exportBtn"> | |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> | |
| <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/> | |
| <polyline points="7 10 12 15 17 10"/> | |
| <line x1="12" y1="15" x2="12" y2="3"/> | |
| </svg> | |
| Export | |
| </button> | |
| </div> | |
| <div class="chart-container"> | |
| <canvas id="returnChart"></canvas> | |
| </div> | |
| </div> | |
| <div class="chart-panel"> | |
| <div class="chart-header"> | |
| <h3>Capital Evolution</h3> | |
| </div> | |
| <div class="chart-container"> | |
| <canvas id="capitalChart"></canvas> | |
| </div> | |
| </div> | |
| <div class="chart-panel multi-chart"> | |
| <div class="chart-header"> | |
| <h3>Fund Survivorship</h3> | |
| </div> | |
| <div class="chart-container"> | |
| <canvas id="survivorshipChart"></canvas> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| </div> | |
| <!-- Methodology View --> | |
| <div class="methodology-content" id="methodologyContent"> | |
| <article class="article"> | |
| <header class="article-header"> | |
| <h1>Safe Choices</h1> | |
| <p class="article-subtitle">Assessing the efficiency of "safe bets" on prediction markets</p> | |
| </header> | |
| <section class="article-section"> | |
| <div class="callout callout-intro"> | |
| <p>Imagine 50 hedge funds, each deploying $100 on a "State Earthquake Trade." Each fund bets on their state NOT being hit by an earthquake (10% annual probability), earning 1.11x if correct.</p> | |
| <p>After 10 years across 100,000 simulations: <strong>17.42 funds survive on average</strong> (range: 4-32). These survivors produced 11% annual returns for a decade. In an efficient market, luck becomes the differentiating factor between investment legends and bankruptcy.</p> | |
| </div> | |
| </section> | |
| <section class="article-section"> | |
| <h2>Research Questions</h2> | |
| <p>We explore the efficiency of "safe choices" (markets trading at 90+ cents before resolution):</p> | |
| <ul class="article-list"> | |
| <li>How often will traders making random walks across these markets go bust?</li> | |
| <li>How often will they beat traditional benchmarks?</li> | |
| <li>Does stopping at a return threshold (e.g., 12%) improve outcomes?</li> | |
| <li>Does splitting capital across multiple funds improve survivorship?</li> | |
| </ul> | |
| <div class="callout callout-hypothesis"> | |
| <strong>Hypothesis:</strong> Inefficiencies in "safe" markets provide opportunities for positive expected value trades exceeding traditional benchmarks like the risk-free rate. | |
| </div> | |
| </section> | |
| <section class="article-section"> | |
| <h2>Dataset</h2> | |
| <p>Data collected via Polymarket's Gamma API and CLOB API, filtering out high-variability categories:</p> | |
| <div class="tag-group"> | |
| <span class="tag tag-excluded">Sports</span> | |
| <span class="tag tag-excluded">Esports</span> | |
| <span class="tag tag-excluded">Crypto Prices</span> | |
| <span class="tag tag-excluded">Weather</span> | |
| </div> | |
| <p>For remaining markets, we log probability snapshots from 7 days to 1 day before resolution. The dataset covers 2024-2025 and is available on <a href="https://www.kaggle.com/datasets/dhruvgup/polymarket-closed-2025-markets-7-day-price-history/data" target="_blank" rel="noopener">Kaggle</a>.</p> | |
| </section> | |
| <section class="article-section"> | |
| <h2>Simulation Model</h2> | |
| <div class="model-steps"> | |
| <div class="model-step"> | |
| <span class="step-num">1</span> | |
| <span class="step-text">Each day, decide to invest with probability <strong>alpha</strong> (trading frequency)</span> | |
| </div> | |
| <div class="model-step"> | |
| <span class="step-num">2</span> | |
| <span class="step-text">Select uniformly at random from eligible markets meeting thresholds</span> | |
| </div> | |
| <div class="model-step"> | |
| <span class="step-num">3</span> | |
| <span class="step-text">Remain locked until resolution, then reinvest winnings</span> | |
| </div> | |
| <div class="model-step"> | |
| <span class="step-num">4</span> | |
| <span class="step-text">Continue until: bust, target reached, or simulation ends</span> | |
| </div> | |
| </div> | |
| </section> | |
| <section class="article-section"> | |
| <h2>Strategies</h2> | |
| <div class="strategy-explainer"> | |
| <div class="strategy-box"> | |
| <h3>Single Fund</h3> | |
| <p>Deploy all capital sequentially across safe markets, reinvesting all winnings. High risk, high reward.</p> | |
| </div> | |
| <div class="strategy-box"> | |
| <h3>Target Return</h3> | |
| <p>Same as Single Fund but stop trading once a target return (e.g., Treasury rate or NASDAQ average) is reached.</p> | |
| </div> | |
| <div class="strategy-box"> | |
| <h3>Multi Fund</h3> | |
| <p>Split capital into N independent funds. Tests whether diversification improves survivorship rates.</p> | |
| </div> | |
| </div> | |
| </section> | |
| <section class="article-section"> | |
| <h2>Technical Notes</h2> | |
| <ul class="article-list"> | |
| <li>Uses actual Polymarket data filtered for 2025+ resolution</li> | |
| <li>Vectorized operations for performance (~1000 sims in 10-20s)</li> | |
| <li>Binary outcomes: win = 1/probability return, loss = total loss</li> | |
| <li>Reproducible results via random seeds</li> | |
| </ul> | |
| </section> | |
| <section class="article-section"> | |
| <h2>Limitations</h2> | |
| <p>At $10,000 scale distributed across funds, liquidity isn't a concern. However, scaling this strategy significantly would face real liquidity constraints and potential market impact.</p> | |
| </section> | |
| </article> | |
| </div> | |
| </div> | |
| </main> | |
| <script src="/static/script.js?v=12"></script> | |
| </body> | |
| </html> | |