Skip to content

feat: complete typed Market Data coverage - #99

Open
nyg wants to merge 3 commits into
masterfrom
codex/market-data-coverage
Open

feat: complete typed Market Data coverage#99
nyg wants to merge 3 commits into
masterfrom
codex/market-data-coverage

Conversation

@nyg

@nyg nyg commented Sep 7, 2026

Copy link
Copy Markdown
Owner

Completes the Market Data sub-task of #82 by adding typed support for OHLC, Depth, Trades, Spread, GroupedBook, and authenticated Level3.

Kraken's current Spot REST specification also includes MaintenanceSchedule, which was absent from the issue's August inventory. This PR adds that endpoint and its public enum constant too, bringing Market Data to 12/12 endpoints with typed methods.

  • Add endpoint classes, parameter builders covering every documented request field for the six endpoints in Kraken Spot REST API coverage: 21 of 60 endpoints typed #82, response records, and KrakenAPI convenience methods. Support assetVersion and asset_class where documented.
  • Preserve pair-keyed rows, decimal prices and trade times, opaque trade cursors, and Level3 nanosecond timestamps. Keep Jackson response builders package-private and supply unknown-value fallbacks on new response enums.
  • Add JUnit 5/Surefire, MockitoExtension, AssertJ, and 60 self-contained offline tests covering parameters, tuple decoding, empty responses, display names, cursor reuse, precision, future enums, error propagation, and public/private facade routing.
  • Document the API and parameter semantics in the README, add a public MarketDataExample, and update the custom-endpoint example to use an accurate order-book response shape. Client-facing library types and methods include Javadoc consistent with the existing API; implementation helpers and tests have no added comments.

Validation: JAVA_HOME=/Library/Java/JavaVirtualMachines/temurin-25.jdk/Contents/Home ~/.local/bin/mvnd -B clean package passes for both modules (60 tests, no failures). Library Javadoc passes with doclint=all,-missing. Tests use documented JSON fixtures and Mockito requester mocks; no live authenticated Kraken request was made.

Refs #82. The umbrella issue remains open for the other API groups.

nyg added 3 commits September 7, 2026 21:24
Move new API documentation into the README, preserve existing comments, and apply the no-comments rule to all added code. Rewrite endpoint and facade tests with MockitoExtension, AssertJ, explicit types, unit variables, and self-contained should/when methods.

Verified with Temurin 25 and mvnd: both modules package successfully, all 60 tests pass, and the Javadoc artifact builds.
Document client-facing types, constructors, methods, parameters, response records, and enums in the existing library style. Keep implementation helpers and tests free of new comments.

@nyg nyg left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed against the existing library conventions. I built the branch locally with JAVA_HOME=.../temurin-25.jdk mvnd -B clean package: BUILD SUCCESS, 60 tests pass. The functional claims hold up.

This is the closest of the three coverage PRs to the existing house style. The notes below are mostly small consistency items, plus a few test issues.

Javadoc

@param params the request parameters appears 12 times. Every other params-taking method in the library describes what the parameters actually are — @param params the filtering and pagination parameters, @param params the sort order, converted asset and zero allocation parameters. Worth a pass to make these say something.

{@inheritDoc} is used on five toMap() overrides. The library only uses it in two places today, both on DefaultKrakenRestRequester methods that add a @throws clause on top of the inherited text. TickerParams.toMap() and EarnAllocationsParams.params() carry no Javadoc at all, which is the pattern to follow here.

The new params classes put a Javadoc block on every private field. Existing params classes carry their semantics in the class-level Javadoc instead. Not wrong, but it is a new convention.

level3OrderBook says "Queries the Level3 endpoint" while every other private endpoint method in KrakenAPI says "Queries the private X endpoint".

The endpoint constructors say "Creates the GroupedBook endpoint"; the existing ones say "Creates the endpoint."

MarketDataExample has no class-level Javadoc. EarnOverviewExample, EoyBalanceExample and StakingRewardsSummaryExample all have one.

Timestamps

OhlcData.Candle.time, OrderBook.Level.time, RecentSpreads.Spread.time and Level3OrderBook.Order.timestamp are raw long; RecentTrades.Trade.time is BigDecimal. The library maps Kraken unix timestamps to Instant everywhere else — Report, LedgerEntry, PostTrade, EarnAllocations. Jackson's JavaTimeModule reads fractional epoch seconds into an Instant with nanosecond precision, so precision is not a reason to avoid it here. MaintenanceSchedule already uses Instant, so the PR is internally inconsistent too.

Params

Level3OrderBookParams calls the four-argument putIfNonNull(params, "depth", depth, String::valueOf). PostParams has a three-argument overload that defaults to Object::toString, which is what EarnAllocationsParams and LedgerEntriesParams use.

Package layout

Level3OrderBookEndpoint is a private endpoint living in endpoint/market/, and Level3OrderBookParams is a PostParams sitting in market/params/ next to QueryParams implementations. Grouping it with the other market data is reasonable, but AGENTS.md currently says market/ is "for public market data" — that line needs updating if this stays.

Tests

assertThat(List.of(KrakenAPI.Private.LEVEL3)).extracting(KrakenAPI.Private::getPath).contains("Level3") in Level3OrderBookEndpointTest asserts nothing — it builds a one-element list from the constant and then checks that constant is in it. The equivalent line in GroupedOrderBookEndpointTest does test something because it goes through values(). Both also sit inside a test whose name is about parameter encoding.

The empty-response fixture in Level3OrderBookEndpointTest.should_return_empty_collections_when_no_entries_are_available contains "grouping":1, which is a leftover from the GroupedBook test — Level3OrderBook has no such field. It passes only because FAIL_ON_UNKNOWN_PROPERTIES is disabled.

Unused imports: java.util.List in GroupedOrderBookEndpointTest and OrderBookEndpointTest, java.util.Map in MaintenanceScheduleEndpointTest.

Every test rebuilds an ObjectMapper that duplicates the configuration in DefaultKrakenRestRequester. That is the right call given the no-shared-helpers rule, but it means a change to the requester's mapper config will not be caught by any of these tests.

No // Given / // When / // Then blocks anywhere. The repo has no test suite today, so whichever way this goes it sets the precedent — worth deciding explicitly.

Build

The test dependencies are declared in library/pom.xml with <version>${junit.version}</version>. Every other dependency version in this project lives in the parent <dependencyManagement>, with modules declaring versionless dependencies. Jackson comes in through jackson-bom; junit-bom would match that precedent.

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