matterprotocol.xyz
private alpharequest access →
home/docs·v0.4 · private alpha

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.

what's in scope: the composition layer, the typed interface between primitives, the runtime that executes them, the cli and studio. what's out: the actual market views — those are yours.

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
that's the loop. compose → backtest → tune. once you're satisfied, the same object paper-trades and ships live.

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."

emaCrossfast/slow exponential moving-average crossover.v0.3.4
rsiOversoldenter when RSI dips below a band and reverts.v0.3.2
fundingFlipfunding rate flips sign on a perp venue.v0.3.1
volBreakoutrange break confirmed by σ-multiple volume.v0.2.6
liquiditySweepsweep of a stop cluster, then mean-revert.v0.2.4
basisDivergenceperp basis decouples from spot beyond θ.v0.2.1

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.

volTargetsize positions to a target realized σ.v0.3.5
drawdownCaphard pause if equity curve breaches threshold.v0.3.3
positionLimitper-leg and aggregate notional caps.v0.3.0
correlationLockreject trades that raise portfolio ρ above θ.v0.2.7
kellyFractionfractional-kelly sizing from edge estimate.v0.2.2

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.

timeRebalre-weight on a fixed cadence (1h…7d).v0.3.4
thresholdRebalre-weight when drift exceeds a band.v0.3.2
inverseVolWeightallocate inversely proportional to σ.v0.2.6
riskParityequalize risk contribution across legs.v0.2.3

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.

trailStoptrailing stop activated past breakeven.v0.3.6
takeProfitLadderscale-out across N tiers above entry.v0.3.1
timeInTradeflat after a maximum hold duration.v0.2.8

the composer

the composer is the surface where you assemble strategies. it ships in two forms:

  • climatter compose reads 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.

matter never holds keys or capital. the binary is what you run; where it runs and what it can sign for is your decision.

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.

request access →