Skip to content

test(verify): consolidate TradingView trade-list fragments before pairing#54

Merged
luisleo526 merged 1 commit into
mainfrom
fix/verify-corpus-fragment-consolidation
Jun 30, 2026
Merged

test(verify): consolidate TradingView trade-list fragments before pairing#54
luisleo526 merged 1 commit into
mainfrom
fix/verify-corpus-fragment-consolidation

Conversation

@luisleo526

Copy link
Copy Markdown
Collaborator

Problem

TradingView's "List of Trades" (and the engine mirroring it) splits one entry fill into multiple "Trade #" rows — a tiny qty_step rounding remainder sharing the same entry time+price, or FIFO partial-close lots of a grid bot. verify_corpus's greedy entry-time matcher then cross-pairs same-entry lots → spurious count + exit-p90 deltas (the ~90% qty-p90 is the fingerprint), even though the engine's fills are trade-for-trade price-exact.

Fix

consolidate_fragments() groups rows by an exact (entry_time, entry_price, direction) key and merges each group into one logical trade (sum qty/pnl, keep the shared entry, represent the exit by the shared price or qty-weighted final close). Applied symmetrically to the TV and engine lists before alignment (mirrored in regen_validation_report.py).

Non-masking guarantee: the key is compared exactly, so two rows merge only when they are the same fill event; a distinct trade lands on a different bar or price level and keeps its own key. Real divergences are never merged.

Validation

result
corpus 251 excellent / 1 anomaly / 0 fail, ZERO tier changes (4 legitimately-fragmenting corpus strategies consolidate symmetrically and stay excellent — proof the key is correct, not inert)
tomukasss-engulfing weak → excellent (count 31%→0%, qty-p90 51%→0.2%)
xlm/xau grids fragment artifact cleared (qty-p90 90%→0.5%); their real residual exit-p90 ~6% (TV holds lots days longer) correctly remains surfaced
scraped canonical tiers excellent+strong 65 → 76 / 90

Scripts-only change (no src//include/); added a doctest for the helper.

🤖 Generated with Claude Code

…ring

TradingView's "List of Trades" (and the engine mirroring it) splits one entry
FILL into multiple "Trade #" rows: a tiny qty_step rounding remainder sharing
the SAME entry time+price, or FIFO partial-close lots of a grid bot. The greedy
entry-time matcher in verify_corpus then cross-pairs same-entry lots, producing
spurious count + exit-price-p90 deltas (the ~90% qty-p90 is the fingerprint)
even though the engine's fills are trade-for-trade price-exact.

Add consolidate_fragments(): group rows by an EXACT (entry_time, entry_price,
direction) key and merge each group into one logical trade (sum qty/pnl, keep
the shared entry, represent the exit by the shared price or qty-weighted final
close). Applied symmetrically to the TV and engine lists before alignment
(mirrored in regen_validation_report.py). Because the key is compared exactly,
two rows merge only when they are the same fill event — a distinct trade lands
on a different bar or price level and keeps its own key, so real divergences are
never masked.

Corpus byte-identical: verify_corpus.py --all stays excellent=251 / anomaly=1 /
fail=0 with ZERO tier changes (4 corpus strategies that legitimately fragment
consolidate symmetrically and stay excellent — the key is correct, not inert).
Scraped targets: tomukasss weak->excellent (count 31%->0%, qty-p90 51%->0.2%);
xlm/xau grids' fragment artifact cleared (qty-p90 ~90%->~0.5%, count->~0) while
their REAL residual exit-p90 ~6% (TV holds lots days longer) correctly remains.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@luisleo526 luisleo526 merged commit 0a662ed into main Jun 30, 2026
5 checks passed
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