matter docs.
matter is a typescript sdk for composing trading strategies out of typed primitives. this page is the working draft of the public docs — concepts, the primitive interface, the composer, and a worked example.
overview
writing a trading strategy from scratch means rewriting the same four decisions every time: when to enter, how much to risk, when to re-weight, when to exit. matter ships those decisions as primitives — small, typed functions that snap together into a full strategy.
you compose primitives into a strategy, the type checker enforces that the wiring makes sense, and you ship the result as a single typed object. the same object backtests locally, paper-trades, and goes live — no rewrites between environments.
quickstart
five lines to a working strategy. requires node ≥ 20 and an alpha invite.
terminal// install $ npm i @matter/sdk @matter/entries @matter/risk @matter/exits
then write a strategy file:
strategy.tsimport { matter, type Strategy } from '@matter/sdk' import { emaCross } from '@matter/entries' import { volTarget } from '@matter/risk' import { trailStop } from '@matter/exits' export const meanRevEth: Strategy = matter.compose([ emaCross({ fast: 12, slow: 26 }), volTarget({ sigma: 0.18 }), trailStop({ pct: 4.5 }), ])
backtest it:
terminal$ matter backtest strategy.ts --pair ETH-PERP --since 2024-01-01 ✓ typecheck ✓ dataflow ✓ 583 days backtested in 1.8s pnl: +38.2% sharpe: 1.74 max dd: -12.4% trades: 141
core concepts
matter has a small surface area. four words do most of the work:
primitive
a typed function with a declared role. it accepts a context (market state, account state, parameters), reads or writes one slot of strategy state, and returns a structured decision.
composition
an ordered list of primitives wrapped in matter.compose(). order matters: entry primitives can veto, risk primitives constrain, rebalance primitives schedule, exit primitives close.
strategy
the typed object produced by composition. inputs and outputs are inferred from the primitives — no manual type annotations needed at the call site.
runtime
the engine that ticks a composed strategy against a data source (historical, paper, or live). the runtime is shared; it's the audited bit. your strategy code only decides what to do.
the primitive interface
every primitive implements the same shape. that's the whole reason composition works:
@matter/sdkexport type Primitive<P, In, Out> = { role: 'entry' | 'risk' | 'rebalance' | 'exit' version: SemVer params: P init?(ctx: Context): void step(ctx: Context, input: In): Out }
role is the slot the primitive fills. step runs once per tick. init is for one-time setup (loading lookbacks, etc).
the type system enforces that an entry primitive's output is consumable by the next risk primitive, and so on down the chain. you cannot compose two entries back-to-back; the compiler refuses.
entry primitives
entry primitives watch market state and emit a signal when their condition fires. they don't size — they only say "now."
risk primitives
risk primitives are the only place where size is decided. an entry can fire all day; if no risk primitive sizes it, nothing happens.
rebalance primitives
rebalance primitives decide when to redistribute weight across legs. they don't open or close positions on their own — they reshape what's already open.
exit primitives
exit primitives close positions. they take precedence over entries — if any exit fires, the position is reduced before any new entry is considered.
the composer
the composer is the surface where you assemble strategies. it ships in two forms:
- cli —
matter composereads a typescript file and reports the type, dataflow, and any composition errors. - studio — a drag-and-snap visual editor (you've seen the embedded preview on the home page). studio writes to the same typescript file.
both produce the same artifact: a typed Strategy object. there's no special "studio format" — everything lowers to plain code.
backtest & paper-trade
matter backtest runs a strategy against historical data. matter paper runs it against live data without sending orders.
terminal$ matter paper strategy.ts --pair BTC-PERP → tick 1820 · price 67124.30 · pos 0.0 → tick 1821 · price 67131.50 · pos 0.0 → tick 1822 · emaCross fired · risk sized 0.43 · pos +0.43 BTC
paper mode shares the runtime with live mode — the same order paths, the same accounting, the same failure modes. only the venue connector changes.
ship a strategy
once a strategy backtests and paper-trades to your satisfaction, you build it for production:
terminal$ matter build strategy.ts --out dist/ ✓ typecheck ✓ dataflow ✓ bundled → dist/strategy.bin (284 KB) ✓ manifest written → dist/manifest.json
the binary is your strategy plus the matter runtime, statically linked. point it at a venue connector and a key it can sign with, and it runs.
example strategies
three reference strategies, each composed entirely from shipping primitives:
basis carry
captures the perp-spot basis premium. enters on divergence, sizes to a vol target, rebalances on time, exits on convergence or a drawdown breach.
basis-carry.tsmatter.compose([ basisDivergence({ theta: 0.005 }), volTarget({ sigma: 0.12 }), drawdownCap({ pct: 6 }), timeRebal({ cadence: '4h' }), timeInTrade({ max: '72h' }), ])
trend, vol-targeted
a classic. ema crossover entry, vol target sizing, trailing stop.
trend-vt.tsmatter.compose([ emaCross({ fast: 12, slow: 26 }), volTarget({ sigma: 0.18 }), trailStop({ pct: 4.5 }), ])
funding carry
shorts perps when funding flips persistently positive; risks against position notional and dd.
funding-carry.tsmatter.compose([ fundingFlip({ persistFor: '3h', sign: 'pos' }), positionLimit({ notional: '500k' }), drawdownCap({ pct: 5 }), takeProfitLadder({ tiers: [2, 5, 10] }), ])
glossary
plain definitions, in the order they tend to come up:
- primitive
- a typed unit of strategy logic with a declared role. the smallest piece you can publish, version, or import.
- composition
- an ordered list of primitives that becomes a strategy. produced by
matter.compose(). - strategy
- the typed object that comes out of composition. shippable as-is.
- runtime
- the engine that ticks a strategy against a data source. shared across backtest, paper, and live.
- role
- the slot a primitive fills: entry, risk, rebalance, or exit.
- tick
- one execution step. matter runs the full composition once per tick.
- context
- the per-tick object passed to every primitive: market state, account state, and shared scratch space.
- venue connector
- the adapter between matter and a specific exchange or onchain protocol. swappable; doesn't change your strategy.
- manifest
- the json descriptor emitted alongside a built strategy. lists primitives, versions, and the data sources required.
support
during private alpha, support is direct and by hand:
- email — hello@matterprotocol.xyz
- private telegram — included with alpha access
- github issues — opens with the public release
still in private alpha.
this is the working draft of the public docs. real access is invite-only — request a seat and we'll get you reading the actual sdk.