
Company News
Jerod Santo Joins Socket as Head of Media
Allow myself to introduce... myself.
@luxalgo/broker-sdk
Advanced tools
Open-source broker connectivity for code, apps, and AI agents. 22 brokers, one normalized schema, zero dependencies. Your keys never leave your machine.
Recipes · Schema · OAuth setup · npm · MCP server
Broker SDK is a LuxAlgo open-source project. Official repository: github.com/LuxAlgo/broker-sdk
Connect code, apps, and AI agents to real brokerage and exchange accounts. Point it at Charles Schwab, Alpaca, Robinhood Crypto, Binance, Kraken, Interactive Brokers and more. Get back the same clean picture from every one of them: accounts, balances, positions, trade history, and computed performance stats.
It runs where your code runs: no hosted service, no telemetry, and your keys never touch anyone else's servers.
npm install @luxalgo/broker-sdk
import { connect } from "@luxalgo/broker-sdk";
const kraken = connect({ broker: "kraken", credentials: { apiKey, apiSecret } });
const snapshot = await kraken.fetchSnapshot();
console.log(snapshot.accounts); // normalized: equity, positions, trades
Every broker returns the same shape. Learn it once:
type Account = {
id: string; // broker-side stable id, safe as an upsert key
name: string;
currency: string; // ISO 4217
equity: number; // total account value
cash?: number; // when the broker reports it separately
environment?: "live" | "paper";
positions: { symbol: string; quantity: number; marketValue?: number }[];
trades: { symbol: string; side: "buy" | "sell"; quantity: number; price: number; fee?: number; executedAt?: string }[];
};
import { createPortfolio } from "@luxalgo/broker-sdk";
import { computeStats } from "@luxalgo/broker-sdk/stats";
const portfolio = createPortfolio();
portfolio.add({ broker: "alpaca", credentials: { apiKey, apiSecret } });
portfolio.add({ broker: "binance", credentials: { apiKey, apiSecret } });
portfolio.add({ broker: "hyperliquid", credentials: { walletAddress } });
const { snapshots, failures } = await portfolio.fetchAll();
const stats = computeStats(
snapshots.flatMap((s) => s.accounts.map((a) => ({ ...a, broker: s.broker }))),
);
console.log(stats.totalEquity, stats.trades?.winRate, stats.topPositions);
One broker failing never takes down the sweep: failures come back alongside the snapshots that succeeded. The stats engine does FIFO round-trip matching, win rate, average win and loss, and per-symbol activity. A sell with no recorded buy is ignored, never guessed at.
Brokers that publish their own market-data endpoints can serve historical OHLCV bars with the same read-only credentials, normalized to one shape (time is the bar open in epoch ms, oldest-first):
const alpaca = connect({ broker: "alpaca", credentials: { apiKey, apiSecret } });
const from = Date.now() - 24 * 60 * 60 * 1000;
const bars = await alpaca.fetchBars("AAPL", { timeframe: "1m", from, to: Date.now() });
// [{ time, open, high, low, close, volume }, ...]
await alpaca.fetchBars("BTC/USD", { timeframe: "1h", limit: 500 }); // crypto pairs carry a slash
Supported: Alpaca (stocks on the IEX feed, crypto pairs; 1m, 5m, 15m, 1h, 1d) and Tradier (1m, 5m, 15m via timesales, 1d via history). Other brokers have no market-data endpoint, so fetchBars rejects with UnsupportedCapabilityError; check ahead with supportsBars(brokerId) or the supportsBars flag on listBrokers().
No API? Any account at any institution is importable from a trade-history CSV. The parser is tolerant on headers (brokers disagree on column names) and strict on rows (anything unreadable is skipped and counted, never guessed):
import { parseStatementCsv, positionsFromTrades } from "@luxalgo/broker-sdk/csv";
const { trades, skippedRows, contentHash } = parseStatementCsv(csvText);
const positions = positionsFromTrades(trades);
| Broker | Credentials | Trades history | Bars |
|---|---|---|---|
| Alpaca (live + paper) | API key + secret | ✅ | ✅ |
| Binance | API key + secret (read-only) | ➖ | ➖ |
| Bybit | API key + secret (read-only) | ➖ | ➖ |
| Charles Schwab | your own OAuth2 app | ✅ | ➖ |
| Coinbase | your own OAuth2 app (read scope) | ➖ | ➖ |
| Crypto.com Exchange | API key + secret (read-only) | ➖ | ➖ |
| E*TRADE | your own OAuth 1.0a app | ✅ | ➖ |
| Gemini | API key + secret (auditor role) | ➖ | ➖ |
| Hyperliquid | wallet address only | ✅ | ➖ |
| Interactive Brokers (Flex) | Flex token + query ID | ✅ | ➖ |
| Kraken | API key + secret ("Query Funds") | ➖ | ➖ |
| KuCoin | API key + secret + passphrase (read) | ✅ | ➖ |
| OKX | API key + secret + passphrase (read) | ➖ | ➖ |
| Public.com | API secret key | ✅ | ➖ |
| Questrade | API refresh token | ✅ | ➖ |
| Robinhood Crypto | API key + Ed25519 private key | ✅ | ➖ |
| tastytrade | login (rotating remember token) | ✅ | ➖ |
| Topstep (ProjectX) | username + API key | ✅ | ➖ |
| TradeStation | your own OAuth2 app | ➖ | ➖ |
| Tradier | access token | ✅ | ✅ |
| Trading212 | API key | ➖ | ➖ |
| Webull (OpenAPI) | App key + secret | ➖ | ➖ |
| Any broker via CSV import | a statement file | ✅ | ➖ |
listBrokers() returns every adapter with its exact credential fields and a one-line guide to creating the key with read-only scope, which is all this SDK ever needs.
Sanctioned APIs only. If a broker does not officially support programmatic access for its users, it is not in this repo: no scraping, no reverse-engineered private APIs, ever. Brokers reachable only through credentialed aggregators (Plaid-style: Fidelity, Chase, Vanguard) can't ship in an open-source library and are out of scope. The moment a broker opens an official retail API it becomes eligible, which is exactly how Charles Schwab and Robinhood Crypto earned their rows above. OAuth brokers where you register your own free developer app (Charles Schwab, TradeStation, E*TRADE, Coinbase) are supported bring-your-own-app style; the flow helpers and setup guide live in docs/byo-oauth.md.
onCredentialsRotated so you can persist them before the old ones die.marketValue rather than a made-up one. A history row that can't be read is skipped and counted, not guessed.Run the LuxAlgo MCP server locally and its broker_* tools give Claude, Cursor, or any MCP client read-only access to your real accounts through this SDK. Keys go in your own MCP client config as env vars; the agent can ask "how is my portfolio doing?" but can never trade.
One React component renders the full "connect your broker" flow: a filterable broker picker, guided credential entry with the right fields per broker, and secret masking.
import { BrokerConnect } from "@luxalgo/broker-sdk/connect";
<BrokerConnect
onComplete={(brokerId, credentials) => myVault.store(brokerId, credentials)}
/>;
The security contract in one sentence: credentials go only to your onComplete callback, never to LuxAlgo, and the kit never stores, transmits, or logs them itself. Not using React? The headless state machine behind the component is at @luxalgo/broker-sdk/connect/core. React is an optional peer dependency, so installs without React stay warning-free and the rest of the SDK never touches it.
Run npx broker-sync with your keys in BROKERS_* env vars (e.g. BROKERS_ALPACA_API_KEY, BROKERS_ALPACA_API_SECRET, the same convention as the MCP server) and it polls your brokers on an interval, diffs each snapshot against the last, and emits only what changed.
npx broker-sync --interval 300 --webhook-url https://example.com/hooks/portfolio --webhook-secret change-me
Events are trade_executed, balance_changed, position_opened, position_closed, position_changed, broker_error, and sync_completed, delivered per sweep as one JSON batch. When a secret is configured, every webhook request carries X-BrokerSync-Signature, the lowercase hex HMAC-SHA256 of the raw body. State persists to a local JSON file before delivery, so a crash can drop a batch but never replay one. Programmatic use lives at @luxalgo/broker-sdk/sync.
The write layer lives in a deliberately separate module. Importing the SDK never gives code trading capability by accident:
import { connectTrading } from "@luxalgo/broker-sdk/orders";
const trading = connectTrading({ broker: "alpaca", credentials: { apiKey, apiSecret } }); // paper keys only
const order = await trading.placeOrder({ symbol: "AAPL", side: "buy", type: "limit", quantity: 5, limitPrice: 180.5 });
await trading.cancelOrder(order.id);
Supported: Alpaca (paper by default; a live account additionally requires acknowledgeLiveTrading set to the exact LIVE_TRADING_ACKNOWLEDGEMENT sentence, never a boolean, never a default), Tradier (sandbox only, pinned to the sandbox host so live orders are impossible by construction), and Binance Spot Testnet (pinned to testnet.binance.vision, live orders impossible by construction). Roadmap and full safety posture: docs/orders-rfc.md.
The schema plus golden test vectors live in conformance/vectors/: one per adapter, pairing a raw provider payload with the exact normalized output. Every adapter splits into an IO-only fetchRaw and a pure normalize, so the mapping of every broker is tested without a network or credentials, and every community adapter must pass the gate before merge.
Two workflows keep the adapters honest in production:
Node ≥ 18.17 (built-in fetch; node:crypto for request signing). Zero runtime dependencies. ESM and CJS. TypeScript strict, exactOptionalPropertyTypes on. Bring your own persistence: snapshots are plain JSON.
| Package | What it is |
|---|---|
@luxalgo/broker-sdk (this repo) | The TypeScript SDK and reference implementation |
@luxalgo/mcp | The LuxAlgo MCP server; its local broker_* tools give AI agents read-only portfolio access through this SDK |
Copy-paste starting points live in docs/recipes.md; the bring-your-own-app OAuth guide (Charles Schwab, TradeStation, E*TRADE, Coinbase) in docs/byo-oauth.md. Adapter #23 is yours to add, and CONTRIBUTING.md walks you through it. The short version: sanctioned user-key APIs only, split fetch/normalize, ship a conformance vector, pass the gate.
This software reports what your broker reports. It is not investment advice, and nothing in it recommends any trade. Use at your own risk; verify important numbers against your broker's own statements.
MIT © LuxAlgo Global, LLC. The "Broker SDK" and "LuxAlgo" names and the LuxAlgo logo are trademarks of LuxAlgo Global, LLC; see TRADEMARKS.md. Security reports: SECURITY.md.
FAQs
Open-source broker connectivity for code, apps, and AI agents. 22 brokers, one normalized schema, zero dependencies. Your keys never leave your machine.
The npm package @luxalgo/broker-sdk receives a total of 933 weekly downloads. As such, @luxalgo/broker-sdk popularity was classified as not popular.
We found that @luxalgo/broker-sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.

Company News
Allow myself to introduce... myself.

Research
/Security News
A Twitch browser extension on Chrome and Firefox forwards users’ live OAuth session tokens through proxies controlled by a Russian bot service.

Security News
Anthropic found biased reasoning and recklessness drove Claude Mythos 5 to publish malware on PyPI and compromise a security vendor.