diff --git a/app/api/routes.py b/app/api/routes.py index 530748a..4ebbd0c 100644 --- a/app/api/routes.py +++ b/app/api/routes.py @@ -213,6 +213,15 @@ class SnapReport(BaseModel): last_bar_t: int | None = None tf: str | None = None chart_w: float | None = None + chart_h: float | None = None + cursor_y: float | None = None + # Where the indicator actually landed versus where the price says it should + # — the only way to tell a wrong answer from a correctly-computed one drawn + # in the wrong place. + dot_y: float | None = None + expected_y: float | None = None + bar_low_y: float | None = None + bar_high_y: float | None = None note: str | None = None diff --git a/static/chart.js b/static/chart.js index 7a5fe13..888facf 100644 --- a/static/chart.js +++ b/static/chart.js @@ -642,6 +642,23 @@ class ConfluenceChart { bars_held: this.bars.length, first_bar_t: this.bars[0].t, last_bar_t: this.bars[this.bars.length - 1].t, chart_w: this.chartEl.clientWidth, + chart_h: this.chartEl.clientHeight, + cursor_y: Math.round(point.y), + dot_y: this.snapDot && !this.snapDot.hidden + ? Math.round(this.snapDot.getBoundingClientRect().top + - this.chartEl.getBoundingClientRect().top) + 5 + : null, + expected_y: Math.round(y), + bar_low_y: (() => { + const bar = this.bars.find(candle => candle.t === snapped.t); + const at = bar && this.candles.priceToCoordinate(bar.l); + return at == null ? null : Math.round(at); + })(), + bar_high_y: (() => { + const bar = this.bars.find(candle => candle.t === snapped.t); + const at = bar && this.candles.priceToCoordinate(bar.h); + return at == null ? null : Math.round(at); + })(), note: point.t == null ? 'coordinateToTime returned null' : `drift ${drift}s (${Math.round(drift / step)} bars), step ${step}s`,