Skip to content

BuckyMaler/crypto-order-book

Repository files navigation

Order Book

About

This project was bootstrapped with Create React App and built with TypeScript, React, and Redux.

Requirements

Requirement Support Additional Details
A functioning real-time order book Full This includes displaying price, size, total, the spread, and the depth graph
Order levels are sorted by price Full Bids are sorted here and asks are sorted here
Price levels with a size of 0 are removed Full Order removals and updates are calculated here
Users can switch between the BTC and ETH markets Full
The design mirrors the mockups Full
Responsive orientation changes None
The websocket disconnects when the app isn't in focus Full For improved UX the websocket will only disconnect if the app is out of focus for 30+ seconds
Users can manually reconnect the websocket Full
Re-rendering is variably throttled based on device Partial Re-rendering is throttled by a constant here
Critical flows are tested Full Integration tests for OrderBook are here. In a production codebase I'd include more tests.
The app is publicly hosted Full bucky-09-20-21.vercel.app

File Structure

Files are organized in "feature folders", with all the Redux logic for a given feature in a single "slice file".

src/
├── app/
├── common/
├── features/
├── App.tsx
├── index.tsx
File/Folder Purpose
app/ Contains store configuration
common/ Contains reusable components, utilities, etc.
features/ Contains "feature folders" which each contain all functionality for a feature
App.tsx The root component
index.tsx The entry point that renders the component tree

Store Configuration

The store is composed of 3 slices of state, 2 middlewares, and an enhancer. The slices of state are: websocket, activeMarket, and orderBook.

{
  websocket: {
    status: null | 'connecting' | 'connected' | 'disconnected';
    feeds: {
      [key: string]:
        | 'subscribe'
        | 'unsubscribe'
        | 'subscribed'
        | 'unsubscribed';
    };
  };
  activeMarket: {
    productId: string;
    displayName: string;
  };
  orderBook: {
    bids: {
      entities: {
        [key: string]: {
          price: number;
          qty: number;
        };
      };
      ids: Array<number>;
    };
    asks: {
      entities: {
        [key: string]: {
          price: number;
          qty: number;
        };
      };
      ids: Array<number>;
    };
    snapshotReceived: boolean;
  };
}

The middlewares are a Redux Saga middleware and a custom middleware. The custom middleware is used to connect and disconnect the websocket, and to send and receive websocket messages.

The enhancer leverages redux-batched-subscribe and lodash.throttle to throttle subscription notifications. By throttling subscription notifications, React re-renders that are triggered due to state changes are also throttled.

References

Development

Prerequisites

Running the App

Run the following commands from the project directory.

  1. Install the dependencies: npm install
  2. Start the app: npm start