Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,6 @@
# `generate_sdk_surfaces --check` doesn't false-positive on Windows.
ffi/src/endpoint_request_options.rs text eol=lf linguist-generated=true
ffi/src/endpoint_with_options.rs text eol=lf linguist-generated=true
sdks/go/endpoint_options.go text eol=lf linguist-generated=true
sdks/go/endpoint_request_options.h.inc text eol=lf linguist-generated=true
sdks/go/endpoint_with_options.h.inc text eol=lf linguist-generated=true
sdks/go/fpss_methods.go text eol=lf linguist-generated=true
sdks/go/historical.go text eol=lf linguist-generated=true
sdks/go/tick_converters.go text eol=lf linguist-generated=true
sdks/go/tick_structs.go text eol=lf linguist-generated=true
sdks/go/utilities.go text eol=lf linguist-generated=true
sdks/cpp/include/endpoint_options.hpp.inc text eol=lf linguist-generated=true
sdks/cpp/include/endpoint_request_options.h.inc text eol=lf linguist-generated=true
sdks/cpp/include/endpoint_with_options.h.inc text eol=lf linguist-generated=true
Expand All @@ -20,7 +12,6 @@ sdks/cpp/src/fpss.cpp.inc text eol=lf linguist-generated=true
sdks/cpp/src/historical.cpp.inc text eol=lf linguist-generated=true
sdks/cpp/src/lifecycle.cpp.inc text eol=lf linguist-generated=true
sdks/cpp/src/utilities.cpp.inc text eol=lf linguist-generated=true
sdks/go/validate.go text eol=lf linguist-generated=true
sdks/python/src/historical_methods.rs text eol=lf linguist-generated=true
sdks/python/src/streaming_methods.rs text eol=lf linguist-generated=true
scripts/validate_python.py text eol=lf linguist-generated=true
Expand All @@ -36,7 +27,6 @@ sdks/typescript/src/streaming_methods.rs text eol=lf linguist-generated=true
sdks/typescript/src/tick_classes.rs text eol=lf linguist-generated=true
sdks/typescript/src/fpss_event_classes.rs text eol=lf linguist-generated=true
sdks/typescript/src/buffered_event.rs text eol=lf linguist-generated=true
sdks/go/fpss_event_structs.go text eol=lf linguist-generated=true
sdks/cpp/include/fpss_event_structs.h.inc text eol=lf linguist-generated=true

# Generated validator surfaces that were missed from the original list.
Expand Down
7 changes: 0 additions & 7 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,3 @@ updates:
patch-minor:
update-types: ["patch", "minor"]

- package-ecosystem: "gomod"
directory: "/sdks/go"
schedule:
interval: "weekly"
groups:
go-patch-minor:
update-types: ["patch", "minor"]
19 changes: 0 additions & 19 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,6 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- uses: actions/setup-go@v6
with:
go-version: "1.23"
- uses: actions/setup-python@v6
with:
python-version: "3.12"
Expand Down Expand Up @@ -123,9 +120,6 @@ jobs:
ffi_artifact: ffi-windows-msvc-x86_64
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: "1.23"
- uses: actions/download-artifact@v8
with:
name: ${{ matrix.ffi_artifact }}
Expand All @@ -137,19 +131,6 @@ jobs:
path: target/x86_64-pc-windows-gnu/release/
- run: cmake -S sdks/cpp -B build/cpp
- run: cmake --build build/cpp --config Release --target thetadatadx_cpp
- shell: bash
working-directory: sdks/go
run: |
set -euo pipefail
if [ "${{ runner.os }}" = "Linux" ]; then
export LD_LIBRARY_PATH="${{ github.workspace }}/target/release"
elif [ "${{ runner.os }}" = "macOS" ]; then
export DYLD_LIBRARY_PATH="${{ github.workspace }}/target/release"
else
export PATH="${{ github.workspace }}/target/x86_64-pc-windows-gnu/release:$PATH"
export CGO_LDFLAGS="-L${{ github.workspace }}/target/x86_64-pc-windows-gnu/release"
fi
go test ./...

build-ffi:
name: Build FFI (${{ matrix.os }})
Expand Down
24 changes: 0 additions & 24 deletions .github/workflows/live.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,6 @@ jobs:
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- uses: actions/setup-go@v6
with:
go-version: "1.23"
- name: Materialize creds.txt
shell: python
env:
Expand Down Expand Up @@ -92,16 +89,6 @@ jobs:
env:
LD_LIBRARY_PATH: ${{ github.workspace }}/target/release
run: ./build/cpp/thetadatadx_fpss_smoke creds.txt
- shell: bash
env:
LD_LIBRARY_PATH: ${{ github.workspace }}/target/release
CGO_LDFLAGS: -L${{ github.workspace }}/target/release
run: cd sdks/go && go run ./cmd/live_smoke ../../creds.txt
- shell: bash
env:
LD_LIBRARY_PATH: ${{ github.workspace }}/target/release
CGO_LDFLAGS: -L${{ github.workspace }}/target/release
run: cd sdks/go && go run ./cmd/fpss_smoke ../../creds.txt
- name: FLATFILES synthetic golden (decoder)
# Runs against a hand-built blob in the repo; no live wire. This
# is the always-on regression gate for the FIT decoder + CSV
Expand Down Expand Up @@ -138,9 +125,6 @@ jobs:
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- uses: actions/setup-go@v6
with:
go-version: "1.23"
- name: Materialize creds.txt
shell: python
env:
Expand Down Expand Up @@ -168,11 +152,6 @@ jobs:
env:
LD_LIBRARY_PATH: ${{ github.workspace }}/target/release
run: ./build/cpp/thetadatadx_validate creds.txt
- shell: bash
env:
LD_LIBRARY_PATH: ${{ github.workspace }}/target/release
CGO_LDFLAGS: -L${{ github.workspace }}/target/release
run: cd sdks/go && go run ./cmd/validate ../../creds.txt
release-validation:
name: Full Release Validation
needs: endpoint-validation
Expand All @@ -182,9 +161,6 @@ jobs:
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup-rust-deps
- uses: actions/setup-go@v6
with:
go-version: "1.23"
- uses: actions/setup-python@v6
with:
python-version: "3.12"
Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [8.0.29] - 2026-05-06

### Removed

- **Go SDK.** The cgo bridge between Rust's C ABI and Go's runtime
carries per-call overhead that masks the upstream throughput this
SDK is engineered for. Users who need Go bindings can build their
own cgo wrapper against the unchanged C ABI in `crates/ffi/` —
header at `sdks/cpp/include/thetadx.h`, all FFI types and free fns
exported as `tdx_*` symbols.

Closes #481.

## [8.0.28] - 2026-05-06

### Breaking
Expand Down
3 changes: 0 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ for the FLATFILES coverage matrix.
- **Python 3.9+** - for the Python SDK
- **maturin** - for building the PyO3 Python bindings (`pip install "maturin>=1.9.4,<2.0"`)
- **Node.js 18+** - for the TypeScript/Node.js SDK
- **Go 1.21+** - for the Go SDK

Note: `protoc` is required even if you're not modifying `.proto` files, because `build.rs` compiles protos during `cargo build`.

Expand Down Expand Up @@ -64,7 +63,6 @@ cargo test --manifest-path tools/cli/Cargo.toml
# 6. Language SDK smoke checks (if modified)
cargo check --manifest-path sdks/python/Cargo.toml
(cd sdks/typescript && npm run build)
(cd sdks/go && LD_LIBRARY_PATH=../../target/release go test ./...)
c++ -std=c++17 -fsyntax-only -I sdks/cpp/include sdks/cpp/src/thetadx.cpp
cmake -S sdks/cpp -B build/cpp
cmake --build build/cpp --target thetadatadx_cpp
Expand Down Expand Up @@ -114,7 +112,6 @@ We follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
| `ffi` | `ffi/` |
| `python` | `sdks/python/` |
| `typescript` | `sdks/typescript/` |
| `go` | `sdks/go/` |
| `cpp` | `sdks/cpp/` |
| `cli` | `tools/cli/` |
| `mcp` | `tools/mcp/` |
Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 6 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ThetaDataDx

Rust SDK for ThetaData market data — single Rust core, five language surfaces (Rust, Python, TypeScript, Go, C++).
Rust SDK for ThetaData market data — single Rust core, four language surfaces (Rust, Python, TypeScript, C++).

[![build](https://github.com/userFRM/ThetaDataDx/actions/workflows/ci.yml/badge.svg)](https://github.com/userFRM/ThetaDataDx/actions/workflows/ci.yml)
[![license](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](./LICENSE)
Expand All @@ -10,18 +10,18 @@ Rust SDK for ThetaData market data — single Rust core, five language surfaces
[![Docs](https://img.shields.io/docsrs/thetadatadx)](https://docs.rs/thetadatadx)
[![Discord](https://img.shields.io/badge/Discord-community-5865F2.svg?logo=discord&logoColor=white)](https://discord.thetadata.us/)

`thetadatadx` is a native Rust SDK for [ThetaData](https://thetadata.us) market data. It connects directly to ThetaData's three public surfaces — MDDS (historical request/response over gRPC), FPSS (real-time streaming over TCP), and FLATFILES (whole-universe daily blobs over the legacy MDDS port) — decodes ticks in-process, and exposes a typed API across Rust, Python, TypeScript, Go, and C++ from a single Rust core. No JVM, no subprocess, no IPC serialization.
`thetadatadx` is a native Rust SDK for [ThetaData](https://thetadata.us) market data. It connects directly to ThetaData's three public surfaces — MDDS (historical request/response over gRPC), FPSS (real-time streaming over TCP), and FLATFILES (whole-universe daily blobs over the legacy MDDS port) — decodes ticks in-process, and exposes a typed API across Rust, Python, TypeScript, and C++ from a single Rust core. No JVM, no subprocess, no IPC serialization. Go consumers can build a thin cgo wrapper against the unchanged C ABI in [`ffi/`](ffi/) — header at [`sdks/cpp/include/thetadx.h`](sdks/cpp/include/thetadx.h), all FFI types and free fns exported as `tdx_*` symbols.

> [!IMPORTANT]
> A valid [ThetaData](https://thetadata.us) subscription is required. The SDK authenticates against ThetaData's Nexus API using your account credentials.

## Highlights

- **Typed everywhere.** 61 ThetaData endpoints exposed as typed methods across all five SDKs; no raw JSON or protobuf on the public surface.
- **Typed everywhere.** 61 ThetaData endpoints exposed as typed methods across all four SDKs; no raw JSON or protobuf on the public surface.
- **Arrow-backed DataFrames.** Python `to_arrow()` / `to_pandas()` / `to_polars()` pipe through shared Arrow buffers.
- **SPKI-pinned FPSS TLS.** Public-key pinning on the FPSS streaming handshake.
- **FIT decoder + SPSC ring buffer** on the FPSS path. Decode cost is measured in the benchmarks under `crates/thetadatadx/benches/`.
- **Shared FFI layer.** Go, C++, and Node.js go through the same `extern "C"` layer; the Python wheel uses PyO3 ABI3 directly.
- **Shared FFI layer.** C++ and Node.js go through the same `extern "C"` layer; the Python wheel uses PyO3 ABI3 directly. The C ABI is also the supported integration path for any third-party Go/C/other-language consumer that wants to roll their own wrapper.
- **Covers all three public surfaces.** MDDS gRPC endpoints, FPSS wire format with reconnect semantics, and the FLATFILES daily-blob protocol — every transport speaks directly to ThetaData's production servers from a single client. See the [parity checklist](docs/java-parity-checklist.md) and the [vendor flat-file reference](https://http-docs.thetadata.us/operations/get-v2-flat-file-getting-started.html).
- **FLATFILES daily blobs.** Pull whole-universe `(sec_type, req_type, date)` blobs over the legacy MDDS port; decode to vendor-byte CSV, JSONL, or a typed `Vec<FlatFileRow>` in memory. Cross-language coverage is tracked under the binding issues; the Rust core is shipped today.

Expand Down Expand Up @@ -100,32 +100,6 @@ for (const t of tdx.stockHistoryEOD('AAPL', '20240101', '20240301')) {
}
```

### Go

```sh
go get github.com/userFRM/ThetaDataDx/sdks/go
```

```go
package main

import (
"fmt"
thetadata "github.com/userFRM/ThetaDataDx/sdks/go"
)

func main() {
tdx, err := thetadata.ConnectFromFile("creds.txt", thetadata.Production())
if err != nil { panic(err) }
defer tdx.Close()
ticks, _ := tdx.StockHistoryEod("AAPL", "20240101", "20240301")
for _, t := range ticks {
fmt.Printf("%d: O=%.2f H=%.2f L=%.2f C=%.2f V=%d\n",
t.Date, t.Open, t.High, t.Low, t.Close, t.Volume)
}
}
```

### C++

```cpp
Expand Down Expand Up @@ -202,7 +176,6 @@ flowchart TB

core -->|PyO3 / maturin| python["Python SDK<br/>(pyo3 · Arrow)"]
ffi -->|napi-rs| ts["TypeScript SDK<br/>(N-API · BigInt)"]
ffi -->|cgo| go["Go SDK"]
ffi -->|extern C| cpp["C++ SDK<br/>(RAII header-only)"]
core -->|tonic| rust["Rust consumer<br/>(direct crate)"]

Expand All @@ -211,17 +184,16 @@ flowchart TB
classDef sdkStyle fill:#14532d,stroke:#052e16,color:#fff
class thetadatadx,tdbe coreStyle
class ffi ffiStyle
class python,ts,go,cpp,rust sdkStyle
class python,ts,cpp,rust sdkStyle
```

| Layer | Crate / package | Purpose |
|-------|-----------------|---------|
| Encoding / types | [`crates/tdbe`](crates/tdbe/) | Tick structs, FIT/FIE codecs, Greeks, Price |
| Core SDK | [`crates/thetadatadx`](crates/thetadatadx/) | MDDS gRPC client, FPSS streaming, auth |
| C FFI | [`ffi/`](ffi/) | Stable `extern "C"` layer consumed by Go, C++, Node.js |
| C FFI | [`ffi/`](ffi/) | Stable `extern "C"` layer consumed by C++, Node.js, and any third-party C/Go consumer |
| Python | [`sdks/python`](sdks/python/) | PyO3 / maturin wheel with Arrow DataFrame adapter |
| TypeScript | [`sdks/typescript`](sdks/typescript/) | napi-rs prebuilt binary |
| Go | [`sdks/go`](sdks/go/) | CGo bindings over the FFI layer |
| C++ | [`sdks/cpp`](sdks/cpp/) | RAII header-only wrapper |
| CLI | [`tools/cli`](tools/cli/) | `tdx` CLI — every generated historical endpoint from the command line |
| MCP | [`tools/mcp`](tools/mcp/) | MCP server - gives clients access to every generated historical endpoint plus offline tools over JSON-RPC |
Expand Down
6 changes: 2 additions & 4 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ Server retention window: 7 calendar days. Older history: contact ThetaData sales
| REST/WS server (`tools/server`) | Pending | #432 |
| Python (`sdks/python`) | Pending | #435 |
| TypeScript (`sdks/typescript`) | Pending | #436 |
| Go (`sdks/go`) | Pending | #437 |
| C++ (`sdks/cpp`) | Pending | #438 |
| `sdk_surface.toml` declarative spec | Pending | #439 |

Expand All @@ -169,11 +168,10 @@ Server retention window: 7 calendar days. Older history: contact ThetaData sales

### Cross-language parity for `utils`

The Rust SDK exposes `thetadatadx::utils::{conditions, exchange, sequences}` for post-processing tick records. The Python, TypeScript, Go, and C++ SDKs do **not** currently expose any of these helpers. Tracked in issue #424.
The Rust SDK exposes `thetadatadx::utils::{conditions, exchange, sequences}` for post-processing tick records. The Python, TypeScript, and C++ SDKs do **not** currently expose any of these helpers. Tracked in issue #424.

- [ ] **Python** — bind `thetadatadx.utils.{conditions, exchange, sequences}` via PyO3.
- [ ] **TypeScript** — bind via napi-rs under the same `utils.*` namespace.
- [ ] **Go** — flat helper functions `thetadatadx.UtilsConditionName(code)`, etc.
- [ ] **C++** — header at `sdks/cpp/include/thetadx_utils.h` with `extern "C"` bindings plus thin C++ wrappers.

### MDDS endpoint coverage on subscription-tier-blocked rows
Expand All @@ -193,7 +191,7 @@ The 7 SKIP rows in the MDDS validator are subscription-blocked on the current te

### Cross-SDK parity validation

- [ ] Run the validator matrix through the Python, TypeScript, Go, and C++ SDKs and compare row-for-row against the Rust artifact. Locks in the contract that all four bindings return identical data for every endpoint.
- [ ] Run the validator matrix through the Python, TypeScript, and C++ SDKs and compare row-for-row against the Rust artifact. Locks in the contract that all three bindings return identical data for every endpoint.

### Upstream features

Expand Down
2 changes: 1 addition & 1 deletion crates/thetadatadx/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "thetadatadx"
version = "8.0.28"
version = "8.0.29"
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
Expand Down
Loading
Loading