Индикатор разворота
unknown
javascript
3 years ago
3.5 kB
11
Indexable
// Класс индикатора class ReverseMeter { constructor(period = 400, area = 0.01) { this.period = period; // погрешность для расчетов (если будем считать по коэфициентам линий K) this.area = area; this.dataset = new Extremums(Math.floor(period) / 4, 'max'); // Детектор экстремумов this.hExtremums = new CircularBuffer(period); // Коллекция только экстремумов } nextValue(o, h, l, c) { let result = null; // Если экстремумы заполнены if (this.hExtremums.filled()) { result = this.calculate(o, h, l, c); } // Возвращает либо новый максимальный экстремум либо null const extremum = this.dataset.push(h); if (extremum) { this.hExtremums.push(extremum); } return result; } calculate(o, h, l, c) { let score = 0; // Массив коэфициентов K всех линий между текущей точкой цены и всеми предыдущими экстремумами const kList = []; // Изза подобия треугольников подберем числа в координатах чтобы tan(Alpha) = K был примерно такой же // как если бы мы считали x координаты почестному const x1 = 0.01; const y1 = h; this.hExtremums.forEach((y0) => { // x0 - всегда 0 const x0 = 0; // Из уравнения канонической прямой, чтобы вычислить K - угловой коэфициент // воспользуемся формулой (где 1 = x в формуле), если подставим вместо x = 1 то получим K const k = ((1 - x0) * (y1 - y0)) / (x1 - x0); kList.push(k); }); // Карта кластирезаций // Для расчета сколько примерно одинаковых угловых коэфициентов есть const clustering = new Map(); let score = 0; kList.forEach((k) => { // Округляем все k до точности 0.01 const fixation = 10 ** 2; k = Math.round((k + Number.EPSILON) * fixation) / fixation; // Сохраняем k в Map, и првоеряем было ли такое же значение // Если было увеличиваем счетчик в кол-ве прямых с таким коэффициентом const next = (clustering.get(k) || 0) + 1; // Если очков больше 1, запишем максимальное значение в очки // Так получится на выходе самый большой кластер с одинаковыми коэфициантами k if (next > 1 && next > score) { score = next; } clustering.set(k, next); }); // Нормализуем выходное значение return 1 - 1 / (1 + score); // return score; } }
Editor is loading...