Files
pump-game-ops/tools/tie-distribution.cjs
T
subochev b8a1f8dc39 docs(sec): SEC-9 закрыт — возврат залога при ничьей
Сводка: открыто 8 (было 9), закрыто 8. SEC-9 перенесён в закрытые с полной
историей: причина (close_bet.rs:66), замер доли ничьих (33.6%), решение
владельца (правка контракта), состав правок, собственная мутационная приёмка,
деплой и живой эффект (залипшие #0/#1 закрылись сами, ваулт −1000).
Хвост SEC-8 о «вечном залипании» помечен как устранённый.

Инструменты приёмки:
- tie-refund-accept.cjs — ставки циклом, проверка статуса на цепи
  (живой прогон: 6 возвратов из 25 ставок)
- tie-distribution.cjs, policy-economics.cjs — выбор политики ничьей
- vault-check.cjs — разбор Bet-аккаунтов сырыми байтами
2026-09-14 02:19:28 +03:00

49 lines
2.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Полное распределение: тики между входом и выходом 15-сек окна + шаг самого фида.
const { DatabaseSync } = require('node:sqlite');
const db = new DatabaseSync(process.env.DB || '/app/data/price-history.db');
const rows = db.prepare('SELECT ts, price FROM price_history ORDER BY ts ASC').all();
const vals = rows.map((r) => ({ ts: Number(r.ts), p: Number(r.price) }));
const SCALE = 1e8;
console.log('записей:', vals.length, '| диапазон:', (vals[0].p / SCALE).toFixed(2), '→', (vals[vals.length - 1].p / SCALE).toFixed(2));
// Шаг самого фида: как меняется цена от записи к записи
const stepHist = {};
let zeroSteps = 0;
for (let i = 1; i < vals.length; i++) {
const d = Math.round(Math.abs(vals[i].p - vals[i - 1].p) / SCALE * 100); // в сотых
stepHist[d] = (stepHist[d] || 0) + 1;
if (d === 0) zeroSteps++;
}
const stepKeys = Object.keys(stepHist).map(Number).sort((a, b) => a - b);
console.log('--- шаг фида (от записи к записи, в копейках) ---');
for (const k of stepKeys.slice(0, 12)) console.log(` ровно ${k} коп: ${stepHist[k]}`);
console.log(' уникальных шагов:', stepKeys.length, '| «без изменений»:', zeroSteps, `(${((100 * zeroSteps) / (vals.length - 1)).toFixed(1)}%)`);
const at = (ts) => {
let lo = 0, hi = vals.length - 1, res = null;
while (lo <= hi) {
const m = (lo + hi) >> 1;
if (vals[m].ts <= ts) { res = vals[m].p; lo = m + 1; } else hi = m - 1;
}
return res;
};
const W = 15000, STEP = 1000;
const hist = {};
let n = 0;
for (let t = vals[0].ts; t + W <= vals[vals.length - 1].ts; t += STEP) {
const a = at(t), b = at(t + W);
if (a === null || b === null) continue;
const kop = Math.round(Math.abs(b - a) / SCALE * 100);
hist[kop] = (hist[kop] || 0) + 1;
n++;
}
const keys = Object.keys(hist).map(Number).sort((a, b) => a - b);
console.log('--- окон 15 с проверено:', n, '| уникальных значений |delta|:', keys.length);
console.log(' распределение по модулю разницы (копейки):');
for (const k of keys.slice(0, 15)) console.log(` |Δ|=${k} коп: ${hist[k]} (${((100 * hist[k]) / n).toFixed(2)}%)`);
const tie = hist[0] || 0;
console.log(`НИЧЬЯ (|Δ|=0): ${tie} = ${((100 * tie) / n).toFixed(2)}%`);
const near = (keys.filter((k) => k > 0 && k <= 5).reduce((s, k) => s + hist[k], 0));
console.log(`почти-ничья (|Δ| = 1..5 коп): ${near} = ${((100 * near) / n).toFixed(2)}%`);