Repository navigation
Conversation
[Medium impact] The PR appears safe to merge; no blocking issues remain. SummaryThe PR derives range limits from each pool's
Reviews (4) · Last reviewed commit: "Scope the LP band's RANGE formulas and g..." · Reviewed by Greptile |
Author
|
Note for whoever merges: this PR and #252 are two halves of the same fix. |
…not a flat percentage The band width was chosen from OHLCV volatility and clamped to a flat [4%, 20%], with the venue's bin/tick ceiling applied afterwards as a prose step — "shrink W until it fits" — that a tick can skip, and did. Two Orca opens at the identical 20.8% width landed 118 spacings on a `tick_spacing=16` pool (opened fine) and 237 on a `tick_spacing=8` pool (SIMULATION_FAILED, no funds moved, slot left empty). On Meteora the floor is the trap: a `bin_step=10` pool caps the half-width at 3.40%, below the 4% floor, so a percent-first clamp is guaranteed to over-reach the hard 69-bin limit and fail the open. `W_max` is now derived from the pool's own `bin_step` / `tick_spacing` and applied as the ceiling — `W = min(clamp(ATR×2, 4%, 20%), W_max)` — so the granularity cap binds instead of trailing. The fit table (68 bins / 120 spacings) ships in the `lp_range_config` skill, with the one-line solve for off-table pools, so no log arithmetic is left to the caller under a tick budget. A "4% floor" is explicitly void when `W_max < 4%`: a fine-grained pool cannot hold that band, and widening past `W_max` is what fails the open. Stated in the skill, in the `lp_slot_operator` strategy that copies it, and in AGENT.md so the root summary no longer reads percent-first.
…et the clamp keep a one-sided band on its side of P The table was computed AT 120 spacings, so rounding alone pushed 6 of its 8 entries over the cap (tick_spacing=8 at 4.80% is 120.098 spacings) — the very over-cap open this change exists to prevent. Values are now computed at 119 spacings, one unit under the cap like Meteora's 68-of-69, and the headroom is stated so a reader cannot round the last decimal back onto the cap; the off-table formula takes 119 too. The clamp step also instructed the caller to keep P bracketed, which contradicts the one-sided BUY/SELL placement the table above defines (both bounds below P, or both above). It now preserves the band's side instead of forcing P inside it, so a valid one-sided range is neither widened across P nor skipped. Adjacent boundary fixed while there: the 4%-floor note claimed Orca tick_spacing <= 8 falls under 4%, but W_max at 8 is 4.756% — the boundary is <= 4 (2.379%).
The table was recomputed one spacing under the cap (119, not 120), so the "round the last decimal up and the clamp lands back on the cap" warning no longer holds — the printed values already carry a spacing of headroom, and 5.943/9.491 are themselves rounded up from the 119-spacing figure. State what the numbers are (ceilings at 119, rounded to four significant figures) instead of a rounding rule that the table contradicts.
lgrawet
force-pushed
the
fix/lp-range-granularity-clamp
branch
from
November 2, 2026 21:58
accc986 to
e87a032
Compare
The HARD GUARDRAIL in AGENT.md and the GUARDRAIL in lp_slot_operator told the loop to verify `lower < current_price < upper` on every open. That contradicts the one-sided ranges defined a few lines above in the same files: BUY (`base_pct=0`) places both bounds below `P` by design and SELL places both above, so an operator obeying the guardrail would either rewrite a valid one-sided slot into a two-sided range or skip the slot. Both now state the rule the venue orientation actually needs: the band sits on the side `side` mandates — `side=1` entirely below (`upper < P`), `side=2` entirely above (`lower > P`), `side=3` bracketing (`lower < P < upper`). A bound pair on the wrong side is still treated as the inverted venue formula it is (Meteora `P` applied to an Orca/Raydium pool, or the reverse) and still fails the open's simulation.
… own bounds The width clamp still told the operator to keep P bracketed and the inline RANGE formulas collapse onto P at base_pct 0 or 100, so a BUY or SELL range still had to be rewritten by hand — the conflict this PR set out to remove. The asymmetric formulas now apply to side=3 only, side=1 and side=2 get an explicit venue-independent construction wholly below / above P with an epsilon offset, and the clamp shrinks the width while preserving the side rather than always bracketing P.
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.
Summary
Three defects in the Solana LP band construction, all in
solana_dex_lp_expert:width from volatility and then tried to shrink it to fit the venue's bin/tick
limit — a step an agent could skip, and did: an Orca open at 20.8% on
tick_spacing=8is 237 spacings →SIMULATION_FAILED, no funds moved, slotleft empty.
bin_step=10pool caps the half-width at 3.40%, below any sanevolatility-derived "4% floor", so a percent-first clamp is guaranteed to
over-reach.
It required
lower < P < upperunconditionally, while BUY (side=1)deliberately places both bounds below
Pand SELL (side=2) both above.Changes
lp_range_configskill:W_maxtables for Meteora (68 bins, one under the 69cap) and Orca/Raydium (119 spacings, one under the 120 cap), derived from
bin_step/tick_spacing; one-line off-table formula; the clamp expressed asln(upper/lower) ≤ ln((1+W_max)/(1−W_max))and required to preserve theband's side.
lp_slot_operatorloop: the same table-driven clamp; range bounds split intoRANGE (asymmetric by
base_pct, venue-flipping) and one-sided (ε-offset,venue-independent,
lower=upper·(1−W)/upper=lower·(1+W)); the RANGEformulas explicitly restricted to
0<base_pct<100.AGENT.md: side-aware guardrail; width described asW = min(vol, W_max).Verification
spacings, under 120, so the four-significant-figure rounding cannot push a
W_maxband over.pytest tests/test_lp_skill_loop_agreement.py tests/test_lp_correctness.py→ 57 passed.
Supersedes
#252, folded in here: both PRs rewrote the same clamp block, and their
one-sided formulas had already drifted apart.