← Назад<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>Futures Screener</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&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/styles.css?v=20260429-v25" />
<meta name="description" content="Futures Screener - Binance Futures Trading Densities" />
<meta name="theme-color" content="#0b0f14" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<link rel="manifest" href="/manifest.json" />
<link rel="icon" href="/icon-192.svg" type="image/svg+xml" />
<link rel="apple-touch-icon" href="/icon-192.svg" />
<script src="https://unpkg.com/lightweight-charts@5.1.0/dist/lightweight-charts.standalone.production.js"></script>
<script src="/lightweight-charts-drawing.umd.js"></script>
</head>
<body>
<!-- Header -->
<header class="top">
<div class="brand">
<span>Futures Screener</span>
</div>
<div class="tabs">
<button class="tab active" data-tab="mini-charts">Mini-Charts</button>
<button class="tab" data-tab="densities">Densities</button>
<button class="tab" data-tab="signals">Signals</button>
</div>
<div class="status">
<span id="state" class="status-text" style="display:none">Idle</span>
<button id="toggleFiltersBtn" title="Settings"
style="background:rgba(255,255,255,0.04); border:1px solid rgba(255,255,255,0.06); color:var(--text-muted); font-size:14px; cursor:pointer; width:28px; height:28px; border-radius:6px; display:flex; align-items:center; justify-content:center; transition:all 0.15s;">⚙</button>
<!-- Auth Button -->
<button id="authBtn" class="auth-btn" title="Login / Register">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
</button>
</div>
</header>
<div class="layout">
<main class="main">
<div id="error" class="error hidden"></div>
<div id="tab-densities" class="tab-content" style="display:none;">
<!-- V2 Density Toolbar -->
<div class="dv2-toolbar">
<div class="dv2-toolbar-left">
<span class="dv2-label">Window</span>
<select id="dv2Window" class="dv2-select">
<option value="1">±1%</option>
<option value="2" selected>±2%</option>
<option value="3">±3%</option>
<option value="5">±5%</option>
</select>
<span class="dv2-label">Min Vol</span>
<select id="dv2MinVol" class="dv2-select">
<option value="10000000">$10M</option>
<option value="50000000" selected>$50M</option>
<option value="100000000">$100M</option>
<option value="500000000">$500M</option>
</select>
<span class="dv2-label">σ</span>
<select id="dv2Sigma" class="dv2-select">
<option value="1.5">1.5</option>
<option value="2" selected>2.0</option>
<option value="2.5">2.5</option>
<option value="3">3.0</option>
</select>
<span class="dv2-label">Age≥ <span id="dv2MinAgeVal" class="dv2-range-val">0m</span></span>
<input type="range" id="dv2MinAge" class="dv2-range" min="0" max="15" step="1" value="0" />
<span class="dv2-label">Erosion≥ <span id="dv2MinErosionVal" class="dv2-range-val">0m</span></span>
<input type="range" id="dv2MinErosion" class="dv2-range" min="0" max="60" step="5" value="0" />
<button id="dv2BlacklistBtn" class="dv2-btn dv2-bl-btn" title="Blacklist">
🚫<span id="dv2BlBadge" class="dv2-bl-badge" style="display:none">0</span>
</button>
</div>
<div class="dv2-toolbar-right">
<span id="dv2Status" class="dv2-status">—</span>
<button id="dv2Refresh" class="dv2-btn" title="Refresh">⟳</button>
<label class="dv2-auto-label">
<input type="checkbox" id="dv2Auto" /> Auto 15s
</label>
</div>
</div>
<!-- V2 Table -->
<div class="table-container" id="table-container">
<table class="table dv2-table">
<thead>
<tr>
<th class="sortable" data-sort="symbol">Coin</th>
<th class="sortable" data-sort="imbalance">Imbalance</th>
<th class="sortable" data-sort="supportScore">Support</th>
<th>Dist</th>
<th>Size</th>
<th>Age</th>
<th>Erosion</th>
<th class="sortable" data-sort="resistScore">Resistance</th>
<th>Dist</th>
<th>Size</th>
<th>Age</th>
<th>Erosion</th>
<th class="sortable" data-sort="volume24h">Vol 24h</th>
</tr>
</thead>
<tbody id="tbody"></tbody>
</table>
</div>
<!-- Mobile Cards View -->
<div class="cards-container" id="cardsContent" style="display:none;"></div>
</div> <!-- End Tab Densities -->
<div id="tab-mini-charts" class="tab-content">
<!-- Global Toolbar -->
<div class="mc-toolbar">
<button id="mcSidebarToggle" class="mc-sidebar-toggle" title="Coins list">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 4h12M2 8h12M2 12h12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
</button>
<div class="mc-toolbar-group">
<span class="mc-toolbar-label">TF:</span>
<div class="mc-tf-buttons" id="mcGlobalTF">
<button class="mc-tf-btn" data-tf="1m">1m</button>
<button class="mc-tf-btn" data-tf="5m">5m</button>
<button class="mc-tf-btn active" data-tf="15m">15m</button>
<button class="mc-tf-btn" data-tf="1h">1h</button>
<button class="mc-tf-btn" data-tf="4h">4h</button>
<button class="mc-tf-btn" data-tf="1d">1d</button>
</div>
</div>
<div class="mc-toolbar-divider mc-hide-mobile"></div>
<div class="mc-toolbar-group mc-hide-mobile">
<span class="mc-toolbar-label">Vol:</span>
<select id="mcFilterVol" class="mc-select">
<option value="0">All</option>
<option value="10">≥$10M</option>
<option value="50" selected>≥$50M</option>
<option value="100">≥$100M</option>
<option value="500">≥$500M</option>
</select>
</div>
<div class="mc-toolbar-group mc-hide-mobile">
<span class="mc-toolbar-label">NATR:</span>
<select id="mcFilterNatr" class="mc-select">
<option value="0" selected>All</option>
<option value="1">≥1%</option>
<option value="2">≥2%</option>
<option value="3">≥3%</option>
<option value="5">≥5%</option>
</select>
</div>
<div class="mc-toolbar-group mc-hide-mobile">
<span class="mc-toolbar-label">Trades:</span>
<select id="mcFilterTrades" class="mc-select">
<option value="0" selected>All</option>
<option value="10000">≥10K</option>
<option value="50000">≥50K</option>
<option value="100000">≥100K</option>
<option value="500000">≥500K</option>
</select>
</div>
<div class="mc-toolbar-divider mc-hide-mobile"></div>
<div class="mc-toolbar-group mc-layout-picker mc-hide-mobile" id="mcLayoutPicker">
<span class="mc-toolbar-label">Layout:</span>
<button class="mc-layout-btn" data-layout="grid" title="Mini-Charts Grid">
<svg width="14" height="14" viewBox="0 0 14 14"><rect x="0" y="0" width="6" height="6" rx="1" fill="currentColor" opacity="0.6"/><rect x="8" y="0" width="6" height="6" rx="1" fill="currentColor" opacity="0.6"/><rect x="0" y="8" width="6" height="6" rx="1" fill="currentColor" opacity="0.6"/><rect x="8" y="8" width="6" height="6" rx="1" fill="currentColor" opacity="0.6"/></svg>
</button>
<button class="mc-layout-btn" data-layout="1" title="1 Chart">
<svg width="14" height="14" viewBox="0 0 14 14"><rect x="0" y="0" width="14" height="14" rx="1" fill="currentColor" opacity="0.6"/></svg>
</button>
<button class="mc-layout-btn" data-layout="2" title="2 Charts">
<svg width="14" height="14" viewBox="0 0 14 14"><rect x="0" y="0" width="6" height="14" rx="1" fill="currentColor" opacity="0.6"/><rect x="8" y="0" width="6" height="14" rx="1" fill="currentColor" opacity="0.6"/></svg>
</button>
<button class="mc-layout-btn" data-layout="4" title="4 Charts">
<svg width="14" height="14" viewBox="0 0 14 14"><rect x="0" y="0" width="6" height="6" rx="1" fill="currentColor" opacity="0.6"/><rect x="8" y="0" width="6" height="6" rx="1" fill="currentColor" opacity="0.6"/><rect x="0" y="8" width="6" height="6" rx="1" fill="currentColor" opacity="0.6"/><rect x="8" y="8" width="6" height="6" rx="1" fill="currentColor" opacity="0.6"/></svg>
</button>
</div>
<div class="mc-toolbar-group">
<label class="mc-density-toggle" title="Show density walls on charts">
<input type="checkbox" id="mcDensityToggle" checked />
<span>Density</span>
</label>
<label class="mc-density-toggle" title="Show auto S/R levels on charts" style="margin-left:8px;">
<input type="checkbox" id="mcLevelsToggle" checked />
<span>Levels</span>
</label>
<button id="mcSortSR" class="mc-sort-sr-btn" title="Sort by nearest S/R level" style="margin-left:8px;">Sort S/R</button>
<label class="mc-density-toggle" title="Show auto trendlines on charts" style="margin-left:8px;">
<input type="checkbox" id="mcTrendlinesToggle" />
<span>Trends</span>
</label>
<button id="mcSortTL" class="mc-sort-sr-btn" title="Sort by nearest auto trendline" style="margin-left:4px;">Sort TL</button>
<div class="ch-type-multi" style="margin-left:8px;">
<button class="mc-sort-sr-btn ch-type-btn" id="mcChannelsBtn" title="Channel overlays">Channels ▾</button>
<div class="ch-type-dropdown" id="mcChannelsDrop">
<label class="sig-type-opt"><input type="checkbox" data-ch="keltner" /><span class="sig-dot" style="background:#fb923c"></span>Keltner (EMA+ATR)</label>
<label class="sig-type-opt"><input type="checkbox" data-ch="regression" /><span class="sig-dot" style="background:#38bdf8"></span>Regression</label>
</div>
</div>
<button id="mcSortSig" class="mc-sort-sr-btn" title="Sort by latest signal" style="margin-left:4px;">Sort Sig</button>
</div>
<div class="mc-toolbar-group" style="margin-left:auto;">
<span id="mcStatus" class="mc-status"></span>
<button id="mcRefreshBtn" class="mc-refresh-btn">Refresh</button>
</div>
</div>
<!-- Multi-Chart Layout (hidden by default, shown when layout=1/2/4) -->
<div id="mcMultiChart" class="mch-container" style="display:none;">
<div class="mch-grid" id="mchGrid">
<!-- Slots injected by JS -->
</div>
</div>
<!-- Charts + Sidebar Layout (default mini-charts grid) -->
<div class="mc-layout" id="mcMiniChartsLayout">
<!-- Charts Grid 3x2 -->
<div class="mc-charts-area">
<div id="chartsGrid" class="mc-grid"></div>
</div>
<!-- Sidebar overlay (mobile) -->
<div class="mc-sidebar-overlay" id="mcSidebarOverlay"></div>
<!-- Coins Sidebar -->
<aside class="mc-sidebar" id="mcSidebar">
<div class="mc-sidebar-header">
<span class="mc-sidebar-title">Coins</span>
<span class="mc-sidebar-count" id="mcCoinCount">0</span>
</div>
<div class="mc-search-wrap">
<input type="text" id="mcSearchInput" class="mc-search-input" placeholder="Search..." autocomplete="off" spellcheck="false" />
</div>
<div class="mc-col-headers" id="mcColHeaders">
<span class="mc-col-hdr" data-sort="symbol">Coin</span>
<span class="mc-col-hdr active asc" data-sort="change">Chg%</span>
<span class="mc-col-hdr" data-sort="natr">NATR</span>
<span class="mc-col-hdr" data-sort="volume">Vol</span>
</div>
<div class="mc-coin-list" id="mcCoinList">
<!-- populated by JS -->
</div>
</aside>
</div>
</div>
<!-- Signals Tab -->
<div id="tab-signals" class="tab-content" style="display:none;">
<div class="sig-toolbar">
<div class="sig-filters">
<div class="sig-type-multi" id="sigTypeFilter">
<button class="sig-type-btn mc-select" id="sigTypeBtn">All Types ▾</button>
<div class="sig-type-dropdown" id="sigTypeDropdown">
<label class="sig-type-opt"><input type="checkbox" value="volume_spike" checked /><span class="sig-dot" style="background:#3b82f6"></span>📊 Volume Spike</label>
<label class="sig-type-opt"><input type="checkbox" value="oi_cvd" checked /><span class="sig-dot" style="background:#8b5cf6"></span>🔮 OI + CVD</label>
<label class="sig-type-opt"><input type="checkbox" value="oi_divergence" checked /><span class="sig-dot" style="background:#f59e0b"></span>🔀 OI Divergence</label>
<label class="sig-type-opt"><input type="checkbox" value="oi_funding_squeeze" checked /><span class="sig-dot" style="background:#f97316"></span>⚡ Funding Squeeze</label>
<label class="sig-type-opt"><input type="checkbox" value="liq_sweep" checked /><span class="sig-dot" style="background:#ef4444"></span>🎯 Liq Sweep</label>
<label class="sig-type-opt"><input type="checkbox" value="channel" checked /><span class="sig-dot" style="background:#06b6d4"></span>📐 Channel</label>
</div>
</div>
<select id="sigDirFilter" class="mc-select">
<option value="">All Directions</option>
<option value="LONG">🟢 Long</option>
<option value="SHORT">🔴 Short</option>
</select>
<input type="text" id="sigSearch" class="mc-search-input" placeholder="Search symbol..." style="width:120px; height:26px; font-size:12px;" />
</div>
<div class="sig-summary" id="sigSummary"></div>
</div>
<div class="sig-layout">
<div class="sig-table-wrap" id="sigTableWrap">
<table class="sig-table">
<thead>
<tr>
<th>Time</th>
<th>Type</th>
<th>Symbol</th>
<th>Dir</th>
<th>Price</th>
<th>Conf</th>
<th class="sig-desc-col">Description</th>
</tr>
</thead>
<tbody id="sigTbody"></tbody>
</table>
</div>
<div class="sig-detail" id="sigDetail">
<div class="sig-detail-empty">Select a signal to see details</div>
</div>
</div>
</div>
<div class="footer">
<span id="updated" class="footer-text"></span>
<button id="filterToggle" class="btn-filters" style="display:none;">Filter</button>
</div>
</main>
</div>
<!-- Modal for Mobile Filters (hidden on desktop) -->
<div id="filterModal" class="modal hidden">
<div class="modal-content">
<div class="modal-header">
<h3>Filters</h3>
<button class="modal-close" id="modalClose">×</button>
</div>
<div class="modal-body">
<label>
<span>Min Notional ($)</span>
<input id="modalMinNotional" type="number" value="50000" min="0" step="1000" />
</label>
<label>
<span>Min Score</span>
<input id="modalMinScore" type="number" value="0" min="0" step="1" />
</label>
<label>
<span>Window %</span>
<input id="modalWindowPct" type="number" value="5.0" min="0.1" step="0.1" />
</label>
<label>
<span>Depth Limit</span>
<input id="modalDepthLimit" type="number" value="100" min="10" max="1000" step="10" />
</label>
<label>
<span>Symbols (empty = all)</span>
<input id="modalSymbols" type="text" placeholder="BTCUSDT,ETHUSDT" />
</label>
<label>
<span>Concurrency</span>
<input id="modalConcurrency" type="number" value="6" min="1" max="20" />
</label>
<label>
<span>NATR % Filter</span>
<select id="modalNatrFilter">
<option value="0" selected>Any (no filter)</option>
<option value="1">NATR >= 1%</option>
<option value="2">NATR >= 2%</option>
<option value="3">NATR >= 3%</option>
<option value="5">NATR >= 5%</option>
</select>
</label>
</div>
<div class="modal-footer">
<button id="modalClear" class="btn-secondary">Clear</button>
<button id="modalApply" class="btn-primary">Apply</button>
</div>
</div>
</div>
<!-- Coin Detail Modal -->
<div id="coinModal" class="mc-modal hidden">
<div class="mc-modal-overlay"></div>
<div class="mc-modal-content">
<div class="mc-modal-header">
<div class="mc-modal-title">
<span id="cmSymbol" class="mc-modal-sym"></span>
<button id="cmCopyBtn" class="mch-copy-btn" title="Copy ticker"><svg width="12" height="12" viewBox="0 0 16 16" fill="none"><rect x="5" y="5" width="9" height="9" rx="1.5" stroke="currentColor" stroke-width="1.5"/><path d="M3 11V3a1 1 0 011-1h8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg></button>
<span id="cmPrice" class="mc-modal-price"></span>
<span id="cmChange" class="mc-modal-change"></span>
<div class="cm-metrics" id="cmStats"></div>
</div>
<button id="cmClose" class="mc-modal-close">×</button>
</div>
<div class="mc-modal-toolbar">
<div class="mc-modal-tf" id="cmTFButtons">
<button class="mc-tf-btn" data-tf="1m">1m</button>
<button class="mc-tf-btn active" data-tf="5m">5m</button>
<button class="mc-tf-btn" data-tf="15m">15m</button>
<button class="mc-tf-btn" data-tf="1h">1h</button>
<button class="mc-tf-btn" data-tf="4h">4h</button>
<button class="mc-tf-btn" data-tf="1d">1d</button>
</div>
<span id="cmChartCountdown" class="mc-chart-countdown"></span>
</div>
<div id="cmChartBody" class="mc-modal-chart">
<div id="cmChartLoader" class="cm-chart-loader">
<div class="cm-spinner"></div>
<span>Loading chart...</span>
</div>
</div>
</div>
</div>
<!-- Auth Modal -->
<div id="authModal" class="auth-modal hidden">
<div class="auth-modal-overlay"></div>
<div class="auth-modal-box">
<button id="authModalClose" class="auth-modal-close">×</button>
<div class="auth-modal-tabs">
<button class="auth-tab active" data-auth-tab="login">Login</button>
<button class="auth-tab" data-auth-tab="register">Register</button>
</div>
<div class="auth-error hidden" id="authError"></div>
<!-- Login Form -->
<form id="loginForm" class="auth-form">
<div class="auth-field">
<label>Email</label>
<input type="email" id="loginEmail" required placeholder="you@email.com" autocomplete="email" />
</div>
<div class="auth-field">
<label>Password</label>
<input type="password" id="loginPassword" required placeholder="••••••" autocomplete="current-password" />
</div>
<button type="submit" class="auth-submit">Login</button>
</form>
<!-- Register Form -->
<form id="registerForm" class="auth-form hidden">
<div class="auth-field">
<label>Name</label>
<input type="text" id="regName" placeholder="Your name" autocomplete="name" />
</div>
<div class="auth-field">
<label>Email</label>
<input type="email" id="regEmail" required placeholder="you@email.com" autocomplete="email" />
</div>
<div class="auth-field">
<label>Password</label>
<input type="password" id="regPassword" required minlength="6" placeholder="Min 6 characters" autocomplete="new-password" />
</div>
<div class="auth-field">
<label>Confirm Password</label>
<input type="password" id="regConfirm" required minlength="6" placeholder="Repeat password" autocomplete="new-password" />
</div>
<button type="submit" class="auth-submit">Create Account</button>
</form>
<div class="auth-divider"><span>or</span></div>
<button id="googleAuthBtn" class="auth-google-btn">
<svg width="18" height="18" viewBox="0 0 24 24"><path d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 0 1-2.2 3.32v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.1z" fill="#4285F4"/><path d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" fill="#34A853"/><path d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z" fill="#FBBC05"/><path d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" fill="#EA4335"/></svg>
Continue with Google
</button>
</div>
</div>
<script>
// Force SW update + cache clear on version bump
(async function() {
if (!('serviceWorker' in navigator)) return;
const SW_VER = 29;
const stored = parseInt(localStorage.getItem('sw_ver') || '0');
if (stored < SW_VER) {
// Unregister old SW, clear all caches, reload
const regs = await navigator.serviceWorker.getRegistrations();
for (const r of regs) await r.unregister();
const keys = await caches.keys();
for (const k of keys) await caches.delete(k);
localStorage.setItem('sw_ver', String(SW_VER));
if (stored > 0) location.reload();
}
navigator.serviceWorker.register('/sw.js').catch(()=>{});
})();
</script>
<script>
// Global helpers (loaded before all modules)
function escAttr(s) { return String(s).replace(/[&"'<>]/g, c => ({'&':'&','"':'"',"'":''','<':'<','>':'>'})[c]) }
function lsSet(key, value) { try { localStorage.setItem(key, value) } catch(e) { console.warn('[localStorage] Write failed:', key, e.name) } }
</script>
<script src="/auth.js?v=20260424-v1"></script>
<script src="/settings.js?v=20260429-v24"></script>
<script src="/signals.js?v=20260429-v31"></script>
<script src="/densities.js?v=20260424-v16"></script>
<script src="/drawing-manager.js?v=20260424-v6"></script>
<script src="/mini-charts.js?v=20260429-v51"></script>
</body>
</html>