2nd fix
This commit is contained in:
parent
73570d2904
commit
0c7e81d222
3 changed files with 13 additions and 3 deletions
|
|
@ -1069,3 +1069,8 @@ so nine elapsed minutes occupy nine logical slots and the line remains straight.
|
||||||
Gaps over 30 minutes stay compressed, preserving the established treatment of the
|
Gaps over 30 minutes stay compressed, preserving the established treatment of the
|
||||||
65-minute settlement break and weekends. A browser regression pins both the
|
65-minute settlement break and weekends. A browser regression pins both the
|
||||||
nine-slot spacing and equal historical/future screen slope.
|
nine-slot spacing and equal historical/future screen slope.
|
||||||
|
|
||||||
|
Production then showed that whitespace-only points could still disappear from the
|
||||||
|
shared scale. The time-scale owner now uses transparent zero-valued points with an
|
||||||
|
`autoscaleInfoProvider` that returns null. They remain invisible and cannot affect
|
||||||
|
price range, but Lightweight Charts retains their timestamps as real series data.
|
||||||
|
|
|
||||||
|
|
@ -233,6 +233,7 @@ class ConfluenceChart {
|
||||||
// something to label and so timeToCoordinate answers out there.
|
// something to label and so timeToCoordinate answers out there.
|
||||||
this.futureSpace = this.chart.addSeries(LightweightCharts.LineSeries, {
|
this.futureSpace = this.chart.addSeries(LightweightCharts.LineSeries, {
|
||||||
priceScaleId: 'right',
|
priceScaleId: 'right',
|
||||||
|
color: 'rgba(0,0,0,0)',
|
||||||
lastValueVisible: false,
|
lastValueVisible: false,
|
||||||
priceLineVisible: false,
|
priceLineVisible: false,
|
||||||
crosshairMarkerVisible: false,
|
crosshairMarkerVisible: false,
|
||||||
|
|
@ -531,7 +532,7 @@ class ConfluenceChart {
|
||||||
if (step <= 0) return [];
|
if (step <= 0) return [];
|
||||||
const slots = [];
|
const slots = [];
|
||||||
for (let index = 1; index <= ConfluenceChart.FUTURE_SLOTS; index += 1) {
|
for (let index = 1; index <= ConfluenceChart.FUTURE_SLOTS; index += 1) {
|
||||||
slots.push({ time: last.t + index * step });
|
slots.push({ time: last.t + index * step, value: 0 });
|
||||||
}
|
}
|
||||||
return slots;
|
return slots;
|
||||||
}
|
}
|
||||||
|
|
@ -544,7 +545,7 @@ class ConfluenceChart {
|
||||||
const gap = bars[index].t - bars[index - 1].t;
|
const gap = bars[index].t - bars[index - 1].t;
|
||||||
if (gap <= step || gap > ConfluenceChart.MAX_INTRADAY_GAP_SECONDS) continue;
|
if (gap <= step || gap > ConfluenceChart.MAX_INTRADAY_GAP_SECONDS) continue;
|
||||||
for (let time = bars[index - 1].t + step; time < bars[index].t; time += step) {
|
for (let time = bars[index - 1].t + step; time < bars[index].t; time += step) {
|
||||||
slots.push({ time });
|
slots.push({ time, value: 0 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return [...slots, ...this.futureTimes(bars)];
|
return [...slots, ...this.futureTimes(bars)];
|
||||||
|
|
@ -585,7 +586,7 @@ class ConfluenceChart {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const futureTime = bar.t + ConfluenceChart.FUTURE_SLOTS * step;
|
const futureTime = bar.t + ConfluenceChart.FUTURE_SLOTS * step;
|
||||||
this.futureSpace.update({ time: futureTime });
|
this.futureSpace.update({ time: futureTime, value: 0 });
|
||||||
for (const level of this.levels) {
|
for (const level of this.levels) {
|
||||||
if (level.kind !== 'manual' || level.hidden || ConfluenceChart.isFlat(level)
|
if (level.kind !== 'manual' || level.hidden || ConfluenceChart.isFlat(level)
|
||||||
|| futureTime < level.anchor_t || futureTime > (level.cutoff_t ?? Infinity)) continue;
|
|| futureTime < level.anchor_t || futureTime > (level.cutoff_t ?? Infinity)) continue;
|
||||||
|
|
|
||||||
|
|
@ -201,11 +201,15 @@ test('a short final data gap does not kink a future trendline',
|
||||||
historicalSlope: (current.y - previous.y) / (current.x - previous.x),
|
historicalSlope: (current.y - previous.y) / (current.x - previous.x),
|
||||||
futureSlope: (future.y - current.y) / (future.x - current.x),
|
futureSlope: (future.y - current.y) / (future.x - current.x),
|
||||||
historicalSlots: (current.x - previous.x) / (future.x - current.x),
|
historicalSlots: (current.x - previous.x) / (future.x - current.x),
|
||||||
|
missingSlotOwned: c.futureSpace.data()
|
||||||
|
.some(point => Number(point.time) === previousTime + minute),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.ok(Math.abs(result.historicalSlots - 9) < 0.01,
|
assert.ok(Math.abs(result.historicalSlots - 9) < 0.01,
|
||||||
`a nine-minute data gap occupied ${result.historicalSlots} slots`);
|
`a nine-minute data gap occupied ${result.historicalSlots} slots`);
|
||||||
|
assert.equal(result.missingSlotOwned, true,
|
||||||
|
'the invisible scale series discarded the missing intraday timestamp');
|
||||||
assert.ok(Math.abs(result.historicalSlope - result.futureSlope) < 1e-9,
|
assert.ok(Math.abs(result.historicalSlope - result.futureSlope) < 1e-9,
|
||||||
`line kinked from ${result.historicalSlope} to ${result.futureSlope}`);
|
`line kinked from ${result.historicalSlope} to ${result.futureSlope}`);
|
||||||
assertNoPageErrors(page, assert);
|
assertNoPageErrors(page, assert);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue