Skip to content

fix(orders): close(id) closes logical unclosed qty, not physical lots (grid bots)#49

Merged
luisleo526 merged 1 commit into
mainfrom
fix/close-id-logical-qty-grid
Jun 30, 2026
Merged

fix(orders): close(id) closes logical unclosed qty, not physical lots (grid bots)#49
luisleo526 merged 1 commit into
mainfrom
fix/close-id-logical-qty-grid

Conversation

@luisleo526

Copy link
Copy Markdown
Collaborator

Problem

strategy.close(id) under the default FIFO close-entries rule summed every physical open lot carrying id to decide the close quantity. TradingView instead closes the quantity entered under id that a prior close(id) has not already targeted — it does not re-sum physical lots.

The two agree when each id maps to one open lot (the common case), but diverge for grid bots that re-use a single entry id across sequential buy/sell cycles:

  • the FIFO trade-record drain removes the oldest lot (often a different id), leaving the id-tagged lot physically open, so the next close(id) double-counts it → over-close;
  • a TP whose id-lot was already drained finds no physical match and is skipped → under-close.

Net effect on the 3commas grid corpus: wrong trade count + PnL (xrp-grid 143 vs TV 153; exit-price p90 ~18×).

Fix

Add a per-id id_unclosed_qty_ ledger — "entered qty for id minus already-closed-by-close(id) qty for id" — maintained at every entry site (fresh open, pyramid add, raw fill) and consumed by compute_close_target_qty under the FIFO rule only. The ANY rule keeps the physical id-matched path untouched. No new C-ABI export (in-engine state only).

Validation

before after
xrp-grid match vs TV 26.7% 99.3% (143/144, px 100%)
pol-grid match vs TV 21.5% 99.1% (338/341, px 100%)
corpus 251 excellent / 1 anomaly 251 / 1 (held, byte-identical)
ctest 76/76 76/76 + new test_strategy_close_reused_id_closes_one_logical_slot (fails pre-fix)

python3 scripts/check_c_abi_runtime.py exits 0 (no symbol change).

🤖 Generated with Claude Code

… (grid bots)

strategy.close(id) under the default FIFO close-entries rule summed every
physical open lot carrying `id` to decide the close quantity. TradingView
instead closes the quantity entered under `id` that a prior close(id) has not
already targeted — it does not re-sum physical lots. The two agree when each
id maps to one open lot, but diverge for grid bots that re-use a single entry
id across sequential buy/sell cycles: the FIFO trade-record drain removes the
oldest lot (often a different id), leaving the id-tagged lot physically open,
so the next close(id) double-counts it (over-close) — and a TP whose id-lot
was already drained finds no physical match and is skipped (under-close).

Add a per-id `id_unclosed_qty_` ledger ("entered qty for id minus
already-closed-by-close(id) qty") maintained at every entry site and consumed
by compute_close_target_qty under the FIFO rule only. The ANY rule keeps the
physical id-matched path untouched.

3commas grid corpus: xrp-grid 26.7%->99.3%, pol-grid 21.5%->99.1% trade-for-
trade match vs TradingView (price-exact 100%). Corpus held 251 excellent / 1
anomaly; ctest 76/76 incl. new test_strategy_close_reused_id_closes_one_logical_slot
(fails pre-fix). No new C-ABI export.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@luisleo526 luisleo526 merged commit eddb129 into main Jun 30, 2026
5 checks passed
@luisleo526 luisleo526 deleted the fix/close-id-logical-qty-grid branch June 30, 2026 12:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant