100xness Documentation

Explore the technical architecture and implementation details of a high-performance trading engine.

System Architecture

100xness System Architecture

The system follows a microservices architecture with three core components communicating through Redis streams. Real-time price data flows from external exchanges through WebSocket connections, gets processed by the trading engine, and triggers automatic liquidations based on leverage and risk parameters.

Core Components & Implementation

Trading Engine

Order Processing Logic

The trading engine processes orders through Redis streams with real-time price validation:

• Validates user balance against required margin
• Calculates opening price based on bid/ask spread
• Deducts margin: (price × qty) / leverage
• Stores order in memory for real-time monitoring

Liquidation Mechanism

Automatic liquidation system runs on every price update:

• Take Profit: long orders when price ≥ target, short orders when price ≤ target
• Stop Loss: long orders when price ≤ target, short orders when price ≥ target
• Margin Call: when remaining margin ≤ 5% of initial
• PnL calculation: (closing - opening) × qty × side

Redis Stream Communication

engine-stream (Input)
price-update: Real-time price data
create-order: New order requests
close-order: Manual order closures
callback-queue (Output)
created: Order successfully created
closed: Order liquidated/closed
insufficient_balance: Margin not met

Price Poller & WebSocket Integration

WebSocket Connection

Connects to Backpack Exchange for real-time BTC_USDC price feeds:

const subscribeMessage = { method: "SUBSCRIBE", params: ["bookTicker.BTC_USDC"], id: 1 };

Streams bid/ask prices directly to the trading engine via Redis.

Price Processing

Every price update triggers immediate liquidation checks:

• Bid price: Used for long order executions (closing) and short order entries
• Ask price: Used for short order executions (closing) and long order entries
• Mid price: (bid + ask) / 2 for display
• Spread: Difference between bid and ask

Web Server & API Layer

Authentication & Middleware

JWT-based authentication with middleware protection:

• Token generation on login
• Middleware validates JWT on protected routes
• User context injection for order association
• Session management for persistent auth

Order Lifecycle Management

Complete order management with async communication:

• Creates order in pending state
• Sends to engine via Redis stream
• Waits for callback confirmation
• Updates database with final status

API Reference

Authentication

POST/auth/register
POST/auth/login
POST/auth/logout
GET/auth/me

Trading

POST/trade/create
POST/trade/close/:orderId
GET/trade/orders
GET/trade/orders/:orderId

Balance

GET/balance

Candles

GET/candles

Database Schema

Users

id
email
password
name

Assets

symbol
balance
decimals
userId

Orders

id, userId, side, qty
openingPrice, closingPrice
status, leverage
takeProfit, stopLoss
pnl, closeReason

Technical Deep Dive

Real-time Data Flow

Price Update Sequence

Backpack Exchange
WebSocket price feed
Price Poller
Parse & validate data
Redis Stream
Queue price updates
Trading Engine
Process liquidations

Order Creation Sequence

Web UI
User places order
API Server
Validate & auth
Redis Stream
Queue order request
Trading Engine
Process & execute
Callback
Confirm to API

Request-Response Architecture

Core Communication Pattern

The system implements an asynchronous request-response pattern using Redis streams as a message bus and an in-memory callback registry. This enables non-blocking communication between the API service and the trading engine while maintaining request-response semantics.

// 1. Trade controller builds payload const orderId = generateUniqueId(); const payload = { userId, side: "long", qty: 1, leverage: 10, takeProfit: 100000, stopLoss: 90000 }; // 2. Send request and wait for callback const result = await sendRequestAndWait(orderId, { kind: "create-order", payload });

The sendRequestAndWait function orchestrates two parallel operations:

Parallel Operations:
Publishing: addToStream(id, request) → XADD to engine-stream
Waiting: subscriber.waitForMessage(id) → Promise with 5s timeout

Publishing to Engine Stream

async function addToStream( id: string, request: Request ) { await redis.xadd( "engine-stream", "*", "id", id, "request", JSON.stringify(request) ); }

Each message contains:

id: Unique correlation ID
request: JSON payload with kind and data

Callback Registration

waitForMessage(id: string): Promise<void> { return new Promise((resolve, reject) => { // Register callback in memory this.callbacks[id] = resolve; // 5-second timeout setTimeout(() => { if (this.callbacks[id]) { delete this.callbacks[id]; reject(new Error("Timeout")); } }, 5000); }); }

The callback is stored in an in-memory map keyed by the correlation ID, with automatic cleanup on timeout.

Engine Processing Loop

The engine service runs a continuous loop that consumes from the engine-stream:

while (true) { // Block until messages arrive const messages = await redis.xread( "BLOCK", 0, "STREAMS", "engine-stream", lastId ); for (const [stream, entries] of messages) { for (const [id, data] of entries) { const request = JSON.parse(data.request); switch (request.kind) { case "create-order": // Validate balance, calculate margin // Create order in memory & database await processCreateOrder(request.payload); break; case "close-order": await processCloseOrder(request.payload); break; case "price-update": await processPriceUpdate(request.payload); break; } // Send callback confirmation await redis.xadd( "callback-queue", "*", "id", data.id, "status", "created" // or other status ); lastId = id; } } }

Callback Queue Consumer

A separate subscriber loop continuously listens for callbacks:

async runLoop() { while (true) { // Block indefinitely waiting for callbacks const results = await redis.xread( "BLOCK", 0, "STREAMS", "callback-queue", "$" ); for (const [stream, messages] of results) { for (const [messageId, data] of messages) { const callbackId = data.id; // Find the waiting promise if (callbackId && this.callbacks[callbackId]) { // Resolve the promise this.callbacks[callbackId](); // Clean up delete this.callbacks[callbackId]; } } } } }

When a callback arrives, the subscriber immediately resolves the corresponding Promise, unblocking the original API request and allowing it to return the response to the client.

Complete Flow Summary

1Trade controller calls createOrder, generates unique ID, builds payload
2Calls sendRequestAndWait(id, payload) which executes both operations in parallel
3addToStream publishes message to engine-stream via XADD
4waitForMessage creates Promise, registers callback in memory map with 5s timeout
5Engine consumes message from engine-stream, processes order (validate, execute, store)
6Engine publishes callback to callback-queue via XADD with original correlation ID and status
7Subscriber's runLoop receives callback, extracts ID, finds matching callback in map
8Calls this.callbacks[callbackId]() to resolve Promise, deletes callback from map
9API request unblocks, returns response to client

Risk Management & Liquidation Engine

Margin Calculation

// Required margin calculation const requiredMargin = (openingPrice * qty) / leverage; // Remaining margin after PnL const currentPnl = side === 'long' ? (currentPrice - openingPrice) * qty : (openingPrice - currentPrice) * qty; const remainingMargin = initialMargin + currentPnl;

Liquidation Triggers

Automatic Liquidation When:
• Remaining margin ≤ 5% of initial margin
• Take profit price is reached
• Stop loss price is triggered
• Manual closure by user

Performance & Scalability

In-Memory Processing

• Open orders stored in memory for instant access
• Price updates trigger immediate calculations
• Periodic database snapshots every 10 seconds
• Recovery from database on restart

Async Communication

• Redis streams for decoupled services
• Non-blocking order processing
• Promise-based callback system
• Timeout handling for failed operations

Error Handling

• Graceful WebSocket reconnection
• Database transaction rollbacks
• Redis connection recovery
• Comprehensive logging system

Docker Setup

Infrastructure Services

# docker-compose.yml services: redis: image: redis:latest ports: - "6379:6379" postgres: image: postgres:latest environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres - POSTGRES_DB=db ports: - "5433:5432" volumes: - postgres_data:/var/lib/postgresql/data

Service Roles

Redis
• Manages Redis streams for async communication
• Handles engine-stream and callback-queue
PostgreSQL
• Persistent storage for users, orders, and balances
• Accessed via Prisma ORM from the web server
Quick Start:
docker compose up -d

Ready to get started?

Set up your development environment and start building with 100xness. Join the world of limitless trading opportunities.