fix(chart): hide-candles zone snaps the first trade to its bucket open - #551
Merged
Merged
Conversation
The "hide the last N candles" boundary is clamped so the zone never reaches left of the first resident trade cross. The clamp used the raw tick timestamp, while the shader compares candle bucket OPENS against it, so the bucket holding the first trade always kept its candle: with trade_candles no wider than hide_candles the setting hid one candle fewer than asked, and on a thinly traded market a 5/3 setting hid a single candle until trades reached the older buckets of the zone. Measured on 2026-09-13 (Main pane, 5m, hide=3): boundary -52298 (the first tick, 23 s into the bucket) instead of -75546 (that bucket's open). The computation moves into `hide_start_rel`, which floors the first trade to its bucket open before the max, with the measured case as a unit test.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
"Hide the last N candles" (the candle popup, «Скрыть последних свечей») hid fewer candles than asked — on a thinly traded market a 5/3 setting hid a single candle, and with
trade_candlesno wider thanhide_candlesit hid N−1 permanently.The zone's shader boundary is clamped so it never reaches left of the first resident trade cross (a bucket with no ticks to show keeps its candle). The clamp used the raw tick timestamp, while the shader omits candles by bucket
t_open >= boundary— and a tick is always later than the open of its own bucket, so the bucket holding the first trade was never hidden. Measured on 2026-09-13 (Main pane, 5m, hide=3): boundary-52298(the first tick, 23 s into the bucket) instead of-75546(that bucket's open).The computation moves into
hide_start_rel(chartdx/data_state/market.rs), which floors the first trade to its bucket open before themax; the measured case is a unit test that fails on the old formula.Notable decisions
combo_left_rel(full read, live drain) stay raw; the snap lives at the one consumer.combo_left_relis relative f32, so at a 26 h offset it carries an ~8 ms ULP: a tick within 8 ms of a bucket edge can floor into the neighbouring bucket. Accepted: one candle, self-healing on the next bucket roll, and candlet_open_relalready carries the same ULP; removing it means wideningChartHistoryRead.combo_left_rel_msto f64 in moon-core — out of scope.Known limitations
The boundary still moves once per bucket (unchanged); a market that has not streamed any trade yet still draws all candles (unchanged, by design).
Issues
none of the 16 open issues is touched by this change (#534/#535 are about bottom-volume depth, not the hide zone)
How to verify
fmt check exit 0 · build all-targets Finished · clippy: pre-existing 81 errors in
moon-core(identical onorigin/main, checked), nothing new in the touched files · tests: moon-core 1961 passed, moon-ui-gpui 1819 + theme_contract 333 passed, 0 failed · FireTest не запускался · live: withchannels.markets+log.filter = "moonterminal::chartdx=info", thexgeomline reportshide_rel == bucket_open − 2·TF(Main/BERAUSDT, 5/3, 32 samples) — before the fix the same line showed a raw tick timestamp.