Skip to content

Symbol joining on to_dataframe (instrument_id → raw_symbol)#39

Merged
tbeason merged 2 commits into
mainfrom
symbol-join
Jun 22, 2026
Merged

Symbol joining on to_dataframe (instrument_id → raw_symbol)#39
tbeason merged 2 commits into
mainfrom
symbol-join

Conversation

@tbeason

@tbeason tbeason commented Jun 17, 2026

Copy link
Copy Markdown
Owner

Summary

Records carry only the opaque numeric instrument_id; the human-readable symbol lives in the response metadata.mappings. This adds a symbols kwarg to to_dataframe that joins the raw_symbol back onto the frame:

store = get_range(client; dataset="XNAS.ITCH", schema=Schema.TRADES,
                  symbols=["AAPL"], start_dt=..., end_dt=...)
df = to_dataframe(store; symbols=true)   # adds a :symbol column

The join keys on instrument_id/ts_event, follows instrument-id rolls across the query range, and yields missing for unmatched rows. It applies only when data was fetched with stype_out = SType.INSTRUMENT_ID (the get_range default). Default is symbols=false, so existing to_dataframe calls are unchanged.

For streaming consumers (foreach_record, which returns the DBN.Metadata), the helpers symbol_map, symbol_for, and add_symbol_column! are re-exported so you can build the lookup once and resolve per record:

md = foreach_record(client; ...) do rec
    # ...
end
smap = symbol_map(md)
sym = symbol_for(smap, rec.hd.instrument_id, rec.hd.ts_event)

Where the logic lives

Per the package's delegation boundary (this package owns wire protocols, not record/metadata layout), the actual join logic lives in DatabentoBinaryEncoding.jl (it owns Metadata, the mapping semantics, and records_to_dataframe) and benefits standalone .dbn file readers too. This PR is the thin API wrapper + re-exports.

Dependency

Requires the DatabentoBinaryEncoding symbol-resolution helpers: tbeason/DatabentoBinaryEncoding.jl#38. Merge + release that first, then bump the [compat] entry here.

Tests

test/test_conversion.jl gains a "to_dataframe symbol join" testset: default-off behavior, the joined :symbol column, and the re-exported symbol_map/symbol_for helpers.

Note (out of scope)

While testing I found that src/store.jl defines _foreach_typed_tolerant twice (identical copy-paste), which makes the package fail clean precompilation on Julia 1.12+ (Pkg.test masks it via fallback, so CI is green). Tracked/fixed separately to keep this PR focused.

🤖 Generated with Claude Code

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 82b75c63d9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/DatabentoAPI.jl

import DatabentoBinaryEncoding as DBN
using DatabentoBinaryEncoding: Schema, SType, Compression, Encoding, Action, Side, InstrumentClass
using DatabentoBinaryEncoding: symbol_map, symbol_for, add_symbol_column!

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Bump DBN compat before importing new helpers

When this package is installed in a fresh environment, Project.toml still allows DatabentoBinaryEncoding = "0.1.2", but this line imports helpers that the commit message says come from the separate symbol-resolution DBN release. With the currently allowed DBN version, using DatabentoAPI can fail during module loading before any user code runs; bump the compat/version requirement in the same change that imports these names.

Useful? React with 👍 / 👎.

tbeason and others added 2 commits June 22, 2026 13:20
Records carry only the opaque numeric instrument_id; the human-readable
symbol lives in metadata.mappings. to_dataframe(store; symbols=true) now
joins the raw_symbol onto the frame as a :symbol column, resolved per record
from store.metadata.mappings via DatabentoBinaryEncoding's new symbol helpers.

The join keys on instrument_id/ts_event, follows instrument-id rolls across
the query range, and yields missing for unmatched rows. It applies only when
the data was fetched with stype_out = SType.INSTRUMENT_ID (the get_range
default). Default is symbols=false, so existing to_dataframe calls are
unaffected.

Re-exports symbol_map / symbol_for / add_symbol_column! from
DatabentoBinaryEncoding so streaming consumers (foreach_record, which returns
the metadata) can build the lookup once and resolve symbols per record.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Addresses Codex P1: this package now imports symbol_map / symbol_for /
add_symbol_column! from DatabentoBinaryEncoding, which first exist in its 0.1.4
release. Bump the [compat] lower bound from 0.1.2 to 0.1.4 so a fresh install
can't resolve an older DBN that lacks these bindings (which would make
`using DatabentoAPI` fail during module load).

Also drop the [`symbol_map`](@ref) / [`symbol_for`](@ref) cross-reference links
from the to_dataframe docstring — those helpers are documented in the
DatabentoBinaryEncoding docs, not spliced into this package's API reference, so
the @refs would fail Documenter's cross_references check. Use plain code spans.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tbeason tbeason merged commit 3e3a16d into main Jun 22, 2026
8 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