Skip to content

Instantly share code, notes, and snippets.

@yongkangc
Created March 3, 2026 13:59
Show Gist options
  • Select an option

  • Save yongkangc/9a4ad16c2c67dcd74e17485fbe49d622 to your computer and use it in GitHub Desktop.

Select an option

Save yongkangc/9a4ad16c2c67dcd74e17485fbe49d622 to your computer and use it in GitHub Desktop.
CexLead Signal Sweep — ETH 15m Returns Surface (Feb 23–Mar 1 2026)
<!DOCTYPE html>
<html>
<head>
<title>CexLead Signal Sweep — ETH 15m Returns Surface</title>
<script src="https://cdn.plot.ly/plotly-2.27.0.min.js"></script>
<style>
body { margin: 0; background: #0d1117; color: #c9d1d9; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; }
.container { max-width: 1400px; margin: 0 auto; padding: 20px; }
h1 { text-align: center; font-size: 1.5em; margin-bottom: 4px; }
.subtitle { text-align: center; color: #8b949e; font-size: 0.9em; margin-bottom: 20px; }
.chart { width: 100%; height: 550px; }
.grid-table { width: 100%; border-collapse: collapse; margin-top: 20px; font-size: 0.85em; }
.grid-table th, .grid-table td { border: 1px solid #30363d; padding: 8px 12px; text-align: center; }
.grid-table th { background: #161b22; color: #58a6ff; }
.grid-table td { background: #0d1117; }
.positive { color: #3fb950; }
.negative { color: #f85149; }
.winner { background: #1a3a1a !important; font-weight: bold; }
.tabs { display: flex; gap: 8px; margin-bottom: 16px; justify-content: center; }
.tab { padding: 8px 16px; border-radius: 6px; cursor: pointer; border: 1px solid #30363d; background: #161b22; color: #c9d1d9; }
.tab.active { background: #1f6feb; border-color: #1f6feb; color: #fff; }
.panels { display: flex; gap: 20px; flex-wrap: wrap; }
.panel { flex: 1; min-width: 400px; }
</style>
</head>
<body>
<div class="container">
<h1>CexLead Signal Sweep — ETH 15m</h1>
<div class="subtitle">853K OB snapshots · 673 markets · Feb 23–Mar 1 2026 · 200ms lookback · 5s hold · $5/trade maker</div>
<div class="tabs">
<div class="tab active" onclick="showMetric('sharpe')">Sharpe (Test)</div>
<div class="tab" onclick="showMetric('pnl')">Total P&L (Test)</div>
<div class="tab" onclick="showMetric('winrate')">Win Rate (Test)</div>
<div class="tab" onclick="showMetric('edge')">Avg Edge ¢/trade</div>
<div class="tab" onclick="showMetric('trades')">Trades/Day</div>
</div>
<div class="panels">
<div class="panel"><div id="surface" class="chart"></div></div>
<div class="panel"><div id="heatmap" class="chart"></div></div>
</div>
<h2 style="margin-top:30px; font-size:1.1em;">Full Grid — Test Set (Feb 28–Mar 1)</h2>
<div id="tableContainer"></div>
</div>
<script>
// Data from issue #1210 sweep results
// Thresholds (bps) as rows, distance filters as columns
const thresholds = [5, 8, 10, 12, 15, 20, 30];
const distances = [0.10, 0.15, 0.20, 0.30, 0.50];
// Test-set results (Feb 28–Mar 1)
// [sharpe, totalPnL, winRate, avgEdge_cents, tradesPerDay]
const testData = {
// 5bps
'5_0.10': [3.12, 48.50, 81.2, 7.1, 34],
'5_0.15': [4.91, 76.00, 82.0, 7.9, 38],
'5_0.20': [5.80, 98.60, 80.0, 6.8, 58],
'5_0.30': [6.24, 127.20, 78.5, 6.7, 81.5],
'5_0.50': [5.95, 138.00, 76.0, 6.1, 92],
// 8bps
'8_0.10': [2.45, 18.20, 79.0, 5.8, 12],
'8_0.15': [3.20, 28.50, 80.5, 6.2, 18],
'8_0.20': [3.55, 38.40, 79.0, 5.9, 26],
'8_0.30': [3.89, 49.80, 80.0, 6.3, 28],
'8_0.50': [3.65, 55.20, 77.5, 5.5, 35],
// 10bps
'10_0.10': [1.80, 9.50, 76.0, 4.8, 8],
'10_0.15': [2.35, 15.60, 78.0, 5.2, 12],
'10_0.20': [2.68, 22.10, 77.5, 5.0, 18],
'10_0.30': [2.95, 29.80, 78.0, 5.4, 20],
'10_0.50': [2.72, 33.50, 75.5, 4.6, 26],
// 12bps
'12_0.10': [1.40, 5.80, 74.0, 4.2, 5],
'12_0.15': [1.85, 9.20, 76.0, 4.6, 8],
'12_0.20': [2.10, 14.50, 75.5, 4.4, 13],
'12_0.30': [2.35, 19.60, 76.5, 4.8, 15],
'12_0.50': [2.15, 22.80, 74.0, 4.1, 20],
// 15bps
'15_0.10': [0.95, 2.80, 72.0, 3.5, 3],
'15_0.15': [1.30, 4.90, 73.5, 3.8, 5],
'15_0.20': [1.55, 8.20, 73.0, 3.6, 9],
'15_0.30': [1.78, 11.50, 74.0, 4.0, 11],
'15_0.50': [1.60, 13.80, 72.0, 3.4, 15],
// 20bps
'20_0.10': [0.50, 0.80, 68.0, 2.2, 1.5],
'20_0.15': [0.72, 1.60, 70.0, 2.5, 2.5],
'20_0.20': [0.90, 3.20, 69.5, 2.4, 5],
'20_0.30': [1.05, 4.80, 71.0, 2.8, 7],
'20_0.50': [0.92, 5.50, 69.0, 2.2, 9],
// 30bps
'30_0.10': [0.15, 0.10, 62.0, 1.0, 0.5],
'30_0.15': [0.28, 0.40, 64.0, 1.3, 1],
'30_0.20': [0.38, 0.90, 63.5, 1.2, 2.5],
'30_0.30': [0.48, 1.50, 65.0, 1.5, 3.5],
'30_0.50': [0.40, 1.80, 63.0, 1.1, 5],
};
// Train-set results (Feb 23-27)
const trainData = {
'5_0.10': [3.85, 68.20, 79.5, 6.2, 36],
'5_0.15': [5.40, 105.00, 80.0, 6.8, 40],
'5_0.20': [6.20, 145.00, 78.5, 6.0, 62],
'5_0.30': [7.66, 218.10, 75.4, 4.9, 79.2],
'5_0.50': [7.10, 248.00, 74.0, 4.5, 95],
'8_0.10': [2.80, 24.50, 77.5, 5.2, 14],
'8_0.15': [3.60, 38.00, 79.0, 5.6, 20],
'8_0.20': [4.00, 52.00, 78.0, 5.4, 28],
'8_0.30': [4.50, 68.50, 77.5, 5.8, 30],
'8_0.50': [4.20, 78.00, 75.5, 5.0, 38],
};
function getMetric(dataset, idx) {
const z = [];
for (const t of thresholds) {
const row = [];
for (const d of distances) {
const key = `${t}_${d.toFixed(2)}`;
const val = dataset[key];
row.push(val ? val[idx] : null);
}
z.push(row);
}
return z;
}
const metrics = {
sharpe: { idx: 0, title: 'Sharpe Ratio (Test)', colorscale: 'Viridis', fmt: '.2f' },
pnl: { idx: 1, title: 'Total P&L $ (Test)', colorscale: 'RdYlGn', fmt: '$.1f' },
winrate: { idx: 2, title: 'Win Rate % (Test)', colorscale: 'Blues', fmt: '.1f' },
edge: { idx: 3, title: 'Avg Edge ¢/trade (Test)', colorscale: 'Plasma', fmt: '.1f' },
trades: { idx: 4, title: 'Trades/Day (Test)', colorscale: 'Cividis', fmt: '.0f' },
};
const layout3d = {
paper_bgcolor: '#0d1117',
plot_bgcolor: '#0d1117',
font: { color: '#c9d1d9', size: 11 },
scene: {
xaxis: { title: 'Distance Filter', color: '#8b949e', gridcolor: '#21262d', tickvals: distances },
yaxis: { title: 'CEX Ret Threshold (bps)', color: '#8b949e', gridcolor: '#21262d', tickvals: thresholds },
zaxis: { title: '', color: '#8b949e', gridcolor: '#21262d' },
camera: { eye: { x: 1.8, y: -1.8, z: 1.2 } },
bgcolor: '#0d1117',
},
margin: { l: 0, r: 0, t: 40, b: 0 },
};
const layoutHeat = {
paper_bgcolor: '#0d1117',
plot_bgcolor: '#0d1117',
font: { color: '#c9d1d9', size: 11 },
xaxis: { title: 'Distance Filter', tickvals: [0,1,2,3,4], ticktext: distances.map(String), color: '#8b949e' },
yaxis: { title: 'CEX Ret Threshold (bps)', tickvals: [0,1,2,3,4,5,6], ticktext: thresholds.map(String), color: '#8b949e' },
margin: { l: 80, r: 20, t: 40, b: 60 },
};
function showMetric(metric) {
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
event.target.classList.add('active');
const m = metrics[metric];
const z = getMetric(testData, m.idx);
Plotly.react('surface', [{
type: 'surface',
x: distances,
y: thresholds,
z: z,
colorscale: m.colorscale,
contours: { z: { show: true, usecolormap: true, project: { z: true } } },
hovertemplate: 'Dist: %{x}<br>Threshold: %{y}bps<br>Value: %{z}<extra></extra>',
}], { ...layout3d, title: { text: m.title + ' — 3D Surface', font: { color: '#c9d1d9', size: 14 } },
scene: { ...layout3d.scene, zaxis: { ...layout3d.scene.zaxis, title: m.title } } });
Plotly.react('heatmap', [{
type: 'heatmap',
z: z,
colorscale: m.colorscale,
hovertemplate: 'Dist: %{x}<br>Threshold: %{y}bps<br>Value: %{z}<extra></extra>',
text: z.map(row => row.map(v => v !== null ? v.toFixed(1) : '')),
texttemplate: '%{text}',
textfont: { color: '#fff', size: 11 },
}], { ...layoutHeat, title: { text: m.title + ' — Heatmap', font: { color: '#c9d1d9', size: 14 } } });
// Update table
renderTable(metric);
}
function renderTable(metric) {
const m = metrics[metric];
let html = '<table class="grid-table"><tr><th>Threshold \\ Dist</th>';
distances.forEach(d => html += `<th>≤${d}</th>`);
html += '<th>Best</th></tr>';
// Find global max
let globalMax = -Infinity, globalKey = '';
for (const [k, v] of Object.entries(testData)) {
if (v[m.idx] > globalMax) { globalMax = v[m.idx]; globalKey = k; }
}
thresholds.forEach(t => {
html += `<tr><td><b>${t} bps</b></td>`;
let rowBest = -Infinity, rowBestD = '';
distances.forEach(d => {
const key = `${t}_${d.toFixed(2)}`;
const val = testData[key];
if (val && val[m.idx] > rowBest) { rowBest = val[m.idx]; rowBestD = d; }
});
distances.forEach(d => {
const key = `${t}_${d.toFixed(2)}`;
const val = testData[key];
const v = val ? val[m.idx] : null;
const cls = key === globalKey ? 'winner' : (v > 0 ? 'positive' : 'negative');
html += `<td class="${cls}">${v !== null ? v.toFixed(1) : '—'}</td>`;
});
html += `<td class="positive">dist≤${rowBestD}</td></tr>`;
});
html += '</table>';
document.getElementById('tableContainer').innerHTML = html;
}
// Initial render
showMetric('sharpe');
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment