Protocol Engineer · Rust Trading Engine

Marko Sabec

TypeScript/Rust protocol engineering · 18+ yrs · Rain

Marko is an 18+ year software and protocol engineer based in Ljubljana, Slovenia, with blockchain leadership roles at MetaWealth and Solstake.tv behind him, now a Senior Rust/Protocol Engineer at Rain working on multi-chain Solana, EVM, and Stellar payment infrastructure. His Rust project is QuantForge, an open-source trading engine on Binance Spot and SQLite, shipped as a single binary.

Every design decision answers one question: what happens when something goes wrong with real money on the line. Dry runs have no venue to call, strategies are deterministic so backtests and live runs agree, money math is Decimal everywhere, and the write ordering after a fill guarantees a crash can never double a position.

18+ yrs
Software engineering career, Ljubljana, Slovenia
Rain
Senior Rust/Protocol Engineer, multi-chain payments
QuantForge
Creator, open-source Rust trading-systems framework
Solana
Smart-contract lead at MetaWealth and Solstake.tv
The challenge

A trading framework that can't send a live order by accident

A trading system lives or dies on correctness under real money: a dry-run test that accidentally reaches a live venue is not a bug you get to discover twice. Getting that right meant designing the engine so an unsafe path has nothing to call, rather than a check that might be skipped.

The quieter failure is state. A crash between a fill and a database write leaves the bot believing it is flat while the exchange holds a position, and the next run buys the same exposure twice.

  • •Dry-run mode with no venue handle at all
  • •Local position state that survives a failed journal write
  • •Backtests and live runs making identical decisions on identical bars
The outcome

QuantForge: open source, fail-safe by construction

Marko has a public ports-and-adapters Rust trading engine: deterministic strategies behind an FFI-ready boundary, a dry run that structurally cannot trade, crash-safe position state, and an end-to-end suite that runs against a mock exchange with a scrubbed environment.

He's applying the same Rust skills in production too, as a Senior Rust/Protocol Engineer at Rain, building multi-chain Solana, EVM, and Stellar payment infrastructure.

  • ✓QuantForge public, with its design decisions on a companion blog
  • ✓Live trading gated behind explicit, auditable confirmation
  • ✓Rust in production at Rain on multi-chain payment infra
[ Architecture ]

Ports and adapters, with the strategy as a pure function

QuantForge separates the engine from the outside world with four traits: MarketDataSource, TradingVenue, CandleStore, and RunJournalStore. Binance Spot and SQLite are adapters behind them. Strategies sit behind a determinism contract: a pure function of the bar sequence, no clock, no randomness, no I/O, and decisions only on closed candles.

Because strategies are deterministic, a backtest and a live run over the same bars make the same decisions. A restart replays recent bars to warm indicators up, and backtests fill at the next bar's open. The StrategyContext is plain owned data with no borrows into the engine, so the boundary can later cross an FFI line into Python.

[ Dry run ]

A dry run with no venue to call

The live engine holds its venue as Option<&dyn TradingVenue>, and a dry run passes None. There is no flag to check before sending: there is nothing to send to.

Going live takes --mode live, credentials, and either --yes or a typed confirmation. A non-interactive run without --yes prints a preview of what it would do and exits cleanly, and the production host is labelled as such in the output.

[ Crash safety ]

An executed order is never forgotten on restart

After a fill, the journal write can fail. QuantForge defers that error until the position change is persisted: an executed order must exist in local state, otherwise a restart sees a flat position and doubles the exposure. Unsellable remnants below the venue minimum are written off so a run never wedges on dust.

Quantities are Decimal end to end and rounded down to the symbol's step size and lot rules before an order leaves the process. Time arithmetic uses checked operations, so an overflow is an error rather than a silently wrapped timestamp.

[ Testing ]

End-to-end tests that cannot touch real credentials

The e2e harness spawns the real binary with a cleared environment and an allowlist, so a sourced .env holding live keys can never leak into a test. The offline tier runs against a scriptable mock Binance server, and the testnet tier only runs when credentials are present.

CLI output is grep-friendly key: value lines on stdout with logs on stderr, and the absence of a run_id line means the bot did not run. The command tree and help output are snapshot-locked, so every CLI change shows up as a reviewed diff.

The journey

One clear path through the build

Drag to explore · Select a milestone to read the full story

Max Wells

Mentor perspective

Marko Sabec designs from the failure backwards. Instead of guarding the live path with flags, he made the dry run structurally unable to trade, and instead of trusting the happy path after a fill, he ordered the writes so a crash cannot double a position. Years of protocol work, where a wrong state transition costs real money, show in every boundary.

Max Wells

Rustify mentor

Want results like Marko's?

Max WellsAvailable for calls

Max Wells

Founder · Rustify

Book your Rust career diagnostic

30 minutes, 1:1 with Max. An honest read on where you are and whether Bootcamp or Mentorship fits, before you apply.

Only a few diagnostic slots left this week.

Applications are reviewed carefully.

← Back to case studies

More client journeys

See another path into Rust

Ready to Land a $80k+ Rust Job in the US or Europe?