How to create an orderbook and publish through gRPC?

Hi

I got this basic app that pulls orderbook streams from the websockets of two exchanges (Binance & bitstamp): GitHub - oo92/Currency-exchange

At the moment, that's all it does.

I am trying to add two more things:

  • Merge, sort and combine the orderbooks.
  • From the combined orderbook, publish the spread, top 10 bids, top 10 asks, as stream through a gRPC server.

Unfortunately, I couldn't figure out how to go about adding these.

This is an example gRPC server that I managed to write:

main.rs:

use tonic::{transport::Server, Request, Response, Status};

use bookstore::bookstore_server::{Bookstore, BookstoreServer};
use bookstore::{GetBookRequest, GetBookResponse};


mod bookstore {
    include!("bookstore.rs");
}


#[derive(Default)]
pub struct BookStoreImpl {}

#[tonic::async_trait]
impl Bookstore for BookStoreImpl {
    async fn get_book(
        &self,
        request: Request<GetBookRequest>,
    ) -> Result<Response<GetBookResponse>, Status> {
        println!("Request from {:?}", request.remote_addr());

        let response = GetBookResponse {
            id: request.into_inner().id,
            author: "Peter".to_owned(),
            name: "Zero to One".to_owned(),
            year: 2014,
        };
        Ok(Response::new(response))
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let addr = "[::1]:50051".parse().unwrap();
    let bookstore = BookStoreImpl::default();

    println!("Bookstore server listening on {}", addr);

    Server::builder()
        .add_service(BookstoreServer::new(bookstore))
        .serve(addr)
        .await?;

    Ok(())
}

build.rs:

use std::{env, path::PathBuf};

fn main() {
    let proto_file = "./proto/bookstore.proto";

    tonic_build::configure()
        .build_server(true)
        .out_dir("./src")
        .compile(&[proto_file], &["."])
        .unwrap_or_else(|e| panic!("protobuf compile error: {}", e));

    println!("cargo:rerun-if-changed={}", proto_file);
}

bookstore.proto

syntax = "proto3";

package bookstore;

// The book store service definition.
service Bookstore {
  // Retrieve a book
  rpc GetBook(GetBookRequest) returns (GetBookResponse) {}
}

// The request with a id of the book
message GetBookRequest {
  string id = 1;
}

// The response details of a book
message GetBookResponse {
  string id = 1;
  string name = 2;
  string author = 3;
  int32 year = 4;
}

Hey @oo92 what errors are you seeing?

Were you able to do the first bit (merging, sorting and combining the order books)? That seems like a relatively low-dependency task -- easiest to tackle first

Hello

Couldn't figure it out yet, unfortunately.

What happens when you compile the code you do have? Could you paste the output/errors you get from the build?

When I do cargo run, this is the output:

Status  : Connected
Exchange: Bitstamp.net
Symbol  : BTC/USD
Time    : Mon Jul 31 14:42:18 2023 UTC

         Bids                    Asks
0.63844107 @ 29309.00	0.05000000 @ 29315.00
0.05000000 @ 29307.00	2.65137936 @ 29316.00
0.70000000 @ 29306.00	0.68221738 @ 29317.00
0.10232754 @ 29303.00	0.27228309 @ 29318.00
1.09216838 @ 29298.00	0.70000000 @ 29319.00
0.06152976 @ 29296.00	0.06364650 @ 29322.00
1.63000000 @ 29294.00	0.68207909 @ 29323.00
0.25581886 @ 29288.00	3.44435852 @ 29324.00
3.50220416 @ 29286.00	0.01783041 @ 29326.00
2.39130000 @ 29270.00	2.50600000 @ 29330.00
1.20000000 @ 29267.00	0.10000000 @ 29331.00
0. ask: 0.06354, size: 4.523
0. bid: 0.06353, size: 19.0821
1. ask: 0.06355, size: 19.3926
1. bid: 0.06352, size: 48.2768
2. ask: 0.06356, size: 32.7113
2. bid: 0.06351, size: 49.7472
3. ask: 0.06357, size: 50.4533
3. bid: 0.0635, size: 14.9521
4. ask: 0.06358, size: 18.3426
4. bid: 0.06349, size: 20.5242
5. ask: 0.06359, size: 13.5283
5. bid: 0.06348, size: 18.4582
6. ask: 0.0636, size: 41.5354
6. bid: 0.06347, size: 45.8479
7. ask: 0.06361, size: 52.307
7. bid: 0.06346, size: 6.5536
8. ask: 0.06362, size: 8.6047
8. bid: 0.06345, size: 67.9738
9. ask: 0.06363, size: 67.6705
9. bid: 0.06344, size: 7.8933
^C

Its trying to print the output of the 2 streams at once. Did you look at the Github repo?

Oh sorry, I thought you were having a problem with tonic or gRPC -- not with the logic of the program -- I don't know much about order books, I thought your code wasn't compiling at all