COTexplorer/frontend/index.html
Greg 37f8eac932 Initial commit: CFTC COT Explorer
FastAPI application that ingests CFTC Commitments of Traders data into SQLite
and exposes it via a REST API with analytics endpoints (screener, percentile rank,
concentration). Includes CLI for historical and weekly data ingestion, Docker setup,
and a frontend.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 11:23:00 +01:00

189 lines
7.0 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CFTC COT Explorer</title>
<link rel="stylesheet" href="/static/style.css">
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.2/dist/chart.umd.min.js"></script>
</head>
<body>
<header>
<div class="header-left">
<span class="logo">COT Explorer</span>
<select id="exchangeFilter">
<option value="">All Exchanges</option>
</select>
</div>
<nav>
<button class="tab-btn active" data-view="detail">Market Detail</button>
<button class="tab-btn" data-view="screener">Screener</button>
<button class="tab-btn" data-view="compare">Compare</button>
</nav>
</header>
<main>
<!-- ======== DETAIL VIEW ======== -->
<div id="view-detail" class="view active">
<aside id="market-sidebar">
<input type="text" id="marketSearch" placeholder="Search markets..." autocomplete="off">
<div id="market-tree"></div>
</aside>
<section id="detail-main">
<div id="detail-placeholder" class="placeholder">
<p>Select a market from the left panel to begin exploring.</p>
</div>
<div id="detail-content" style="display:none">
<div id="detail-header">
<h2 id="detail-title"></h2>
<span id="detail-exchange" class="badge"></span>
<span id="detail-unit" class="unit"></span>
</div>
<div class="chart-controls">
<div class="control-group">
<label>Range</label>
<div class="btn-group" id="rangeGroup">
<button class="range-btn" data-range="1Y">1Y</button>
<button class="range-btn active" data-range="3Y">3Y</button>
<button class="range-btn" data-range="5Y">5Y</button>
<button class="range-btn" data-range="Max">Max</button>
</div>
</div>
<div class="control-group">
<label>Row type</label>
<div class="btn-group" id="rowTypeGroup">
<button class="rt-btn active" data-rt="All">All</button>
<button class="rt-btn" data-rt="Old">Old</button>
<button class="rt-btn" data-rt="Other">Other</button>
</div>
</div>
<div class="control-group">
<label>Metric</label>
<select id="metricSelect">
<option value="noncomm_net">Non-Comm Net</option>
<option value="noncomm_long">Non-Comm Long</option>
<option value="noncomm_short">Non-Comm Short</option>
<option value="comm_net">Commercial Net</option>
<option value="open_interest">Open Interest</option>
<option value="pct_noncomm_long">% Non-Comm Long</option>
<option value="pct_noncomm_short">% Non-Comm Short</option>
</select>
</div>
<div class="control-group">
<label>Overlay</label>
<label class="checkbox-label">
<input type="checkbox" id="overlayOI" checked> Open Interest
</label>
</div>
</div>
<div class="chart-wrapper">
<canvas id="detailChart"></canvas>
</div>
<div id="stats-bar">
<div class="stat-item">
<span class="stat-label">Current</span>
<span class="stat-value" id="statCurrent"></span>
</div>
<div class="stat-item">
<span class="stat-label">Period High</span>
<span class="stat-value" id="statMax"></span>
</div>
<div class="stat-item">
<span class="stat-label">Period Low</span>
<span class="stat-value" id="statMin"></span>
</div>
<div class="stat-item">
<span class="stat-label">3Y Percentile</span>
<span class="stat-value" id="statPctile"></span>
</div>
<div class="stat-item">
<span class="stat-label">Week Change</span>
<span class="stat-value" id="statChange"></span>
</div>
</div>
</div>
</section>
</div>
<!-- ======== SCREENER VIEW ======== -->
<div id="view-screener" class="view" style="display:none">
<div class="screener-toolbar">
<h2>Market Screener</h2>
<div class="screener-filters">
<select id="screenerExchange">
<option value="">All Exchanges</option>
</select>
<select id="screenerDirection">
<option value="">All directions</option>
<option value="long">Extreme long (≥70th pctile)</option>
<option value="short">Extreme short (≤30th pctile)</option>
</select>
<select id="screenerLookback">
<option value="52">1-year lookback</option>
<option value="156" selected>3-year lookback</option>
<option value="260">5-year lookback</option>
</select>
<button id="screenerRefresh" class="btn-primary">Refresh</button>
</div>
</div>
<div class="table-wrapper">
<table id="screenerTable">
<thead>
<tr>
<th>Market</th>
<th>Exchange</th>
<th class="num">Net Position</th>
<th class="num">Open Interest</th>
<th class="num">Pctile Rank</th>
<th class="num">Wk Chg Long</th>
<th class="num">Wk Chg Short</th>
</tr>
</thead>
<tbody id="screenerBody"></tbody>
</table>
</div>
</div>
<!-- ======== COMPARE VIEW ======== -->
<div id="view-compare" class="view" style="display:none">
<div class="compare-toolbar">
<h2>Compare Markets</h2>
<div class="compare-controls">
<div class="compare-search-wrap">
<input type="text" id="compareSearch" placeholder="Add market..." autocomplete="off">
<div id="compareDropdown" class="autocomplete-dropdown" style="display:none"></div>
</div>
<div class="control-group">
<label>Metric</label>
<select id="compareMetric">
<option value="noncomm_net">Non-Comm Net</option>
<option value="open_interest">Open Interest</option>
<option value="comm_net">Commercial Net</option>
<option value="pct_noncomm_long">% Non-Comm Long</option>
</select>
</div>
<div class="control-group">
<label>Range</label>
<select id="compareRange">
<option value="1Y">1 Year</option>
<option value="3Y" selected>3 Years</option>
<option value="5Y">5 Years</option>
<option value="Max">All</option>
</select>
</div>
</div>
<div id="compareTags"></div>
</div>
<div class="chart-wrapper" id="compareChartWrap">
<div class="placeholder" id="comparePlaceholder">
<p>Search for markets above to add them to the comparison chart.</p>
</div>
<canvas id="compareChart" style="display:none"></canvas>
</div>
</div>
</main>
<script type="module" src="/static/app.js"></script>
</body>
</html>