add balance/mean-reversion signal and Cloudflare visitor logging
Balance signal (15% weight) favors under-represented chairs over last 50 games. Visitor middleware captures real IPs from CF headers, batched into ClickHouse with 90-day TTL.
This commit is contained in:
@@ -456,7 +456,7 @@ function renderPrediction(data) {
|
||||
|
||||
// Signal table
|
||||
const tbody = $('signal-table').querySelector('tbody');
|
||||
const sigNames = {'base_rate':'Base Rate','markov_1':'Markov-1','markov_2':'Markov-2','recent_20':'Recent 20','streak':'Streak'};
|
||||
const sigNames = {'base_rate':'Base Rate','markov_1':'Markov-1','markov_2':'Markov-2','recent_20':'Recent 20','streak':'Streak','balance':'Balance'};
|
||||
tbody.innerHTML = Object.entries(data.signals).map(([key, sig]) =>
|
||||
`<tr><td style="text-align:left">${sigNames[key]||key}</td><td>${(sig.weight*100).toFixed(0)}%</td>` +
|
||||
CHAIRS.map(c => `<td style="color:${CHAIR_COLORS[c]}">${pct(sig.probs[c])}</td>`).join('') + '</tr>'
|
||||
@@ -914,7 +914,7 @@ function renderRunsTest(runs) {
|
||||
|
||||
function renderBacktest(bt) {
|
||||
if (bt.error) { $('backtest-cards').innerHTML = `<div style="color:var(--text2)">${bt.error}</div>`; return; }
|
||||
const names = {base_rate:'Base Rate',markov_1:'Markov-1',markov_2:'Markov-2',recent_20:'Recent 20',streak:'Streak',combined:'Combined'};
|
||||
const names = {base_rate:'Base Rate',markov_1:'Markov-1',markov_2:'Markov-2',recent_20:'Recent 20',streak:'Streak',balance:'Balance',combined:'Combined'};
|
||||
$('backtest-cards').innerHTML = Object.entries(bt.accuracy).map(([key, acc]) => {
|
||||
const fh = bt.full_hits?.[key] ?? '?';
|
||||
const sh = bt.semi_hits?.[key] ?? '?';
|
||||
@@ -925,7 +925,7 @@ function renderBacktest(bt) {
|
||||
}).join('');
|
||||
if (bt.rolling_accuracy) {
|
||||
const ctx = $('backtest-chart').getContext('2d');
|
||||
const colors = {base_rate:'#8b8fa3',markov_1:'#3b82f6',markov_2:'#ec4899',recent_20:'#f59e0b',streak:'#10b981',combined:'#6c5ce7'};
|
||||
const colors = {base_rate:'#8b8fa3',markov_1:'#3b82f6',markov_2:'#ec4899',recent_20:'#f59e0b',streak:'#10b981',balance:'#f472b6',combined:'#6c5ce7'};
|
||||
const datasets = Object.entries(bt.rolling_accuracy).map(([key, data]) => ({
|
||||
label: names[key]||key, data, borderColor: colors[key]||'#fff', backgroundColor: 'transparent',
|
||||
borderWidth: key === 'combined' ? 3 : 1.5, pointRadius: 0, tension: 0.3,
|
||||
|
||||
Reference in New Issue
Block a user