Skip to content

Commit d0a8ade

Browse files
documentation update
1 parent d895c8f commit d0a8ade

5 files changed

Lines changed: 291 additions & 199 deletions

File tree

Makefile

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,17 @@ demo-retry: ## Retry, Retry-After, preflight (needs mock-server)
8080
cd $(CONSUMER_DIR) && ./gradlew runRetry
8181

8282
.PHONY: demo-response
83-
demo-response: ## Response<T> surface features (needs mock-server)
83+
demo-response: ## MarketDataResponse surface features (needs mock-server)
8484
cd $(CONSUMER_DIR) && ./gradlew runResponse
8585

8686
.PHONY: demo-concurrency
8787
demo-concurrency: ## 50-permit semaphore (needs mock-server)
8888
cd $(CONSUMER_DIR) && ./gradlew runConcurrency
8989

90+
.PHONY: demo-options
91+
demo-options: ## Full options surface: every endpoint + all params, CSV facet, columns, Option A (needs mock-server)
92+
cd $(CONSUMER_DIR) && ./gradlew runOptions
93+
9094
.PHONY: demos-all
9195
demos-all: ## Run every mock-server-based demo back-to-back (needs mock-server)
92-
cd $(CONSUMER_DIR) && ./gradlew runDemoConfig runExceptions runRetry runResponse runConcurrency
96+
cd $(CONSUMER_DIR) && ./gradlew runDemoConfig runExceptions runRetry runResponse runConcurrency runOptions

README.md

Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,8 @@ common path is two lines:
3232

3333
```java
3434
try (var client = new MarketDataClient()) {
35-
Response<OptionsExpirations> resp =
36-
client.options().expirations(OptionsExpirationsRequest.of("AAPL"));
37-
System.out.println(resp.data().expirations());
35+
var resp = client.options().expirations(OptionsExpirationsRequest.of("AAPL"));
36+
System.out.println(resp.values()); // values() is the typed payload (a List<ZonedDateTime>)
3837
}
3938
```
4039

@@ -43,10 +42,15 @@ try (var client = new MarketDataClient()) {
4342
```kotlin
4443
MarketDataClient().use { client ->
4544
val resp = client.options().expirations(OptionsExpirationsRequest.of("AAPL"))
46-
println(resp.data().expirations)
45+
println(resp.values()) // List<ZonedDateTime>
4746
}
4847
```
4948

49+
Every response implements `MarketDataResponse<T>`: `values()` returns the typed payload
50+
(typed per endpoint — a `List`, a scalar `String`, …), and the same metadata accessors
51+
(`statusCode()`, `isNoData()`, `requestId()`, `json()`, `saveToFile(path)`) are available on
52+
every response, on every resource.
53+
5054
## Options
5155

5256
Reached via `client.options()`. Every endpoint has a synchronous method and an
@@ -73,17 +77,17 @@ only one variant per group:
7377

7478
```java
7579
try (var client = new MarketDataClient()) {
76-
Response<OptionsChain> resp = client.options().chain(
80+
var resp = client.options().chain(
7781
OptionsChainRequest.builder("AAPL")
7882
.expirationFilter(ExpirationFilter.all()) // every expiration, not just front-month
7983
.strikeFilter(StrikeFilter.range(150, 200)) // 150 <= strike <= 200
8084
.side(OptionSide.CALL)
8185
.strikeLimit(5)
8286
.build());
8387

84-
for (OptionQuote q : resp.data().chain()) {
85-
System.out.printf("%s delta=%.3f rho=%s%n",
86-
q.optionSymbol(), q.delta(), q.rho()); // rho may be null (optional column)
88+
for (OptionQuote q : resp.values()) { // values() is a List<OptionQuote>
89+
System.out.printf("%s delta=%s rho=%s%n",
90+
q.optionSymbol(), q.delta(), q.rho()); // delta/rho are @Nullable Double
8791
}
8892
}
8993
```
@@ -100,27 +104,51 @@ MarketDataClient().use { client ->
100104
.strikeLimit(5)
101105
.build()
102106
)
103-
resp.data().chain.forEach { q ->
104-
println("${q.optionSymbol} delta=${q.delta} rho=${q.rho}") // rho may be null
107+
resp.values().forEach { q ->
108+
println("${q.optionSymbol} delta=${q.delta} rho=${q.rho}") // delta/rho are nullable
105109
}
106110
}
107111
```
108112

109113
### Multiple quotes
110114

111115
`quotes` fans out one request per symbol concurrently and returns a
112-
`Map<String, Response<OptionsQuotes>>` keyed by the input symbol, so per-symbol
116+
`Map<String, OptionsQuotesResponse>` keyed by the input symbol, so per-symbol
113117
status and errors stay observable. `countback` caps the historical series to the
114118
N most recent rows before `to`:
115119

116120
```java
117-
Map<String, Response<OptionsQuotes>> bySymbol = client.options().quotes(
121+
Map<String, OptionsQuotesResponse> bySymbol = client.options().quotes(
118122
OptionsQuotesRequest.builder("AAPL250117C00150000", "AAPL250117P00150000")
119123
.to(LocalDate.now())
120124
.countback(5) // at most 5 EOD rows per symbol, before `to`
121125
.build());
126+
127+
bySymbol.forEach((sym, resp) -> System.out.println(sym + "" + resp.values().size() + " rows"));
128+
```
129+
130+
### Universal parameters & CSV
131+
132+
Universal parameters are set fluently on the resource (an immutable configured value, so you
133+
can "configure once, call many"); `columns` projects the response to a subset of fields, and
134+
`asCsv()` selects a CSV view of any endpoint:
135+
136+
```java
137+
// type-preserving universal params + column projection (typed):
138+
var chain = client.options()
139+
.dateFormat(DateFormat.TIMESTAMP).mode(Mode.DELAYED).limit(50)
140+
.columns("optionSymbol", "strike", "delta") // fields you don't request come back null
141+
.chain(OptionsChainRequest.of("AAPL"));
142+
143+
// CSV facet (adds human/headers, which only make sense for CSV):
144+
CsvResponse csv = client.options().asCsv().columns("optionSymbol", "strike").chain(req);
145+
csv.saveToFile(Path.of("aapl-chain.csv"));
122146
```
123147

148+
With `columns`, a field you didn't request decodes to `null` (no error); a **required** field
149+
you *did* request (or didn't project away) that the API omits raises a `ParseError` — so a
150+
`null` never silently hides a dropped field.
151+
124152
## Configuration
125153

126154
Values are resolved through this cascade (highest priority first):
@@ -147,9 +175,11 @@ Values are resolved through this cascade (highest priority first):
147175
| `MARKETDATA_USE_HUMAN_READABLE` | Human-readable field names | `false` |
148176
| `MARKETDATA_MODE` | Data mode (live/cached/delayed) | `live` |
149177

150-
Endpoint-shape variables (`OUTPUT_FORMAT`, `DATE_FORMAT`, `COLUMNS`,
151-
`ADD_HEADERS`, `USE_HUMAN_READABLE`, `MODE`) are reserved here and will be
152-
honored when the request layer lands.
178+
The corresponding per-call setters — `dateFormat`/`limit`/`offset`/`mode`/`columns` on the
179+
resource, plus `human`/`headers` and `asCsv()` on the CSV facet — are exposed on `options`
180+
today (and on every resource as it lands). Auto-applying these env-var values as request
181+
*defaults* (`DATE_FORMAT`, `COLUMNS`, `ADD_HEADERS`, `USE_HUMAN_READABLE`, `MODE`,
182+
`OUTPUT_FORMAT`) is still reserved.
153183

154184
### Demo mode
155185

@@ -213,13 +243,15 @@ isn't an exact match is rejected before any request is made.
213243
## Package layout
214244

215245
```
216-
com.marketdata.sdk # MarketDataClient, RateLimits, and the resource
217-
# façades (UtilitiesResource, OptionsResource) —
218-
# public; Configuration, EnvVars, Tokens, Version
219-
# are package-private and not part of the API
220-
com.marketdata.sdk.options # Options request builders + response records
246+
com.marketdata.sdk # MarketDataClient, RateLimits, the resource façades
247+
# (UtilitiesResource, OptionsResource, OptionsCsvResource),
248+
# and MarketDataResponse<T> + the named response types
249+
# (OptionsChainResponse, CsvResponse, …) — public;
250+
# Configuration, EnvVars, Tokens, Version are
251+
# package-private and not part of the API
252+
com.marketdata.sdk.options # Options request builders + row records
221253
# (OptionsChainRequest, OptionQuote, sealed
222-
# ExpirationFilter / StrikeFilter, …)
254+
# ExpirationFilter / StrikeFilter, Greek, …)
223255
com.marketdata.sdk.exception # Sealed MarketDataException hierarchy + ErrorContext
224256
```
225257

0 commit comments

Comments
 (0)