fix(dhan): paginated statement API + history row shape#3
Merged
SwathiMystery merged 1 commit intomainfrom Apr 20, 2026
Merged
Conversation
Discovered while running the first real sync: the Dhan v2 Statement API
doesn't match what I originally guessed. Actual shape:
GET /trades/{from}/{to}/{page}
- Page number is a REQUIRED third path segment (not optional).
- Page size is ~20, newest-first. Paginate until empty list.
- History rows are aggregated per-order-per-day, so exchangeTradeId='0'.
Falling back to orderId so UNIQUE(broker, broker_trade_id) holds.
- Timestamps come in two formats: 'YYYY-MM-DD HH:MM:SS' (today's /trades)
and 'YYYY-MM-DDTHH:MM:SS' (history pages). Parser handles both.
- createTime/updateTime can be literal 'NA' on history rows.
- customSymbol on history has spaces ('NIFTY 21 APR 24300 PUT'); underlying
extractor strips trailing whitespace.
Adds tests/fixtures/dhan/{trades_today,trades_history_page0}.json and
tests/test_dhan_mapper.py (10 cases) covering every fix above. Fixtures
use synthetic IDs only; no real account data.
Verified against a live account: 103 executions over 30 days, 18 round-trip
trades reconstructed cleanly.
6a1571c to
ee660a9
Compare
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
Fix the Dhan adapter to match the v2 API's actual behaviour. Historical-trades endpoint is
GET /trades/{from}/{to}/{page}(page is a required 3rd path segment), notGET /trades/{from}/{to}as originally guessed. Also fix several smaller shape mismatches discovered during the first real sync.Why
The first live
khata sync --broker dhancall 4xx'd on the Statement API. Probing against a live account revealed the true endpoint shape plus three related quirks that would have silently corrupted data on ingest.Changes
get_trades_rangenow takes apageargument and maps to/trades/{from}/{to}/{page}.fetch_tradespaginates each date chunk until the response is empty (safety-bounded at 100 pages).orderIdwhenexchangeTradeIdis"0"(history rows are aggregated per-order-per-day). Without this,UNIQUE(broker, broker_trade_id)would collapse every history row to a single insert."YYYY-MM-DD HH:MM:SS"(today's/trades) and"YYYY-MM-DDTHH:MM:SS"(history pages)."NA"increateTime/updateTimewithout crashing."NIFTY 21 APR 24300 PUT"→"NIFTY", not"NIFTY ".TEST_CLIENT_*,TEST_ORDER_*) — no real account data.Verification
ruff check+ruff format --checkclean.Checklist
uv run ruff check khata testscleanuv run ruff format khata testsappliedScreenshots / output