Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Jan Rock committed Oct 27, 2024
1 parent 797d674 commit 5ab45b3
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 97 deletions.
103 changes: 101 additions & 2 deletions src/models/model.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
pub mod models {
use serde::Deserialize;
use std::fmt;
use ordered_float::OrderedFloat;
use serde::{ Serialize, Serializer, ser::SerializeStruct, Deserialize, Deserializer };
use uuid::Uuid;

use colored::*;
extern crate env_logger;
extern crate log;

pub mod orderbook {
tonic::include_proto!("orderbook");
Expand All @@ -16,4 +23,96 @@ pub mod models {
pub persist: String,
pub offline: Vec<String>,
}
}

// For Orderbook
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Order {
pub id: Uuid,
pub price: OrderedFloat<f64>,
pub volume: OrderedFloat<f64>,
pub side: String,
pub timestamp: String,
pub order_type: String,
}

// Custom deserialization for Order
impl<'de> Deserialize<'de> for Order {
fn deserialize<D>(deserializer: D) -> Result<Order, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
struct OrderData {
price: f64,
volume: f64,
side: String,
timestamp: String,
order_type: String,
}

let helper = OrderData::deserialize(deserializer)?;
//let id = Uuid::parse_str(&helper.id).map_err(de::Error::custom)?;

Ok(Order {
id: Uuid::new_v4(),
price: OrderedFloat(helper.price),
volume: OrderedFloat(helper.volume),
side: helper.side,
timestamp: helper.timestamp,
order_type: helper.order_type,
})
}
}

// Custom serialization for Order (to avoid serialization of OrderedFloat for csv crate)
// TODO: find a better way to handle serialization of OrderedFloat
impl Serialize for Order {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state: <S as Serializer>::SerializeStruct =
serializer.serialize_struct("Order", 5)?;
state.serialize_field("price", &self.price.into_inner())?;
state.serialize_field("volume", &self.volume.into_inner())?;
state.serialize_field("side", &self.side)?;
state.serialize_field("timestamp", &self.timestamp)?;
state.serialize_field("order_type", &self.order_type)?;
//state.serialize_field("id", &self.id.to_string())?;
state.end()
}
}

// Implement the Display trait for the Order struct (more readable output with colors)
impl fmt::Display for Order {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let output: String = format!(
"Price: {:.5}, Volume: {:.3}, Side: {}, ID: {}, Timestamp: {}",
self.price,
self.volume,
self.side,
self.id,
self.timestamp
);
if self.side == "ask" {
write!(f, "{}", output.red())
} else {
write!(f, "{}", output.green())
}
}
}

//For Tradebook
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Trade {
pub id: Uuid,
pub trader: String,
pub pair: String,
pub price: OrderedFloat<f64>,
pub volume: OrderedFloat<f64>,
pub side: String,
pub timestamp: String,
pub order_type: String,
pub status: String,
}
}
99 changes: 4 additions & 95 deletions src/server.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::collections::HashMap;
use std::env;
use std::fs::File;
use std::fmt;
use std::sync::Arc;
use std::error::Error;
use models::model::models::Config;
Expand All @@ -11,17 +10,11 @@ use tonic::{ transport::Server, Request, Response, Status };
use futures::future::join_all;
use csv::{ ReaderBuilder, Writer };
use chrono::Utc;
use serde::{ Serialize, Serializer, ser::SerializeStruct, Deserialize, Deserializer };
use serde_json::Value;
use ordered_float::OrderedFloat;
use uuid::Uuid;
use crate::utils::config::load_config;

use colored::*;
extern crate env_logger;
extern crate log;
use log::info;

use orderbook::order_book_server::{ OrderBook, OrderBookServer };
use orderbook::{
OrderBookRequest,
Expand All @@ -38,101 +31,17 @@ pub mod orderbook {
tonic::include_proto!("orderbook");
}

use log::info;

use crate::models::model::models::{ Order, Trade };

#[derive(Debug)]
pub struct OrderBookService {
order_books: Arc<Mutex<HashMap<String, Vec<Order>>>>,
order_tx: mpsc::Sender<OrderRequest>,
trade_books: Arc<Mutex<HashMap<String, Vec<Trade>>>>,
}

// For Orderbook
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Order {
id: Uuid,
price: OrderedFloat<f64>,
volume: OrderedFloat<f64>,
side: String,
timestamp: String,
order_type: String,
}

//For Tradebook
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Trade {
id: Uuid,
trader: String,
pair: String,
price: OrderedFloat<f64>,
volume: OrderedFloat<f64>,
side: String,
timestamp: String,
order_type: String,
status: String,
}

// Custom deserialization for Order
impl<'de> Deserialize<'de> for Order {
fn deserialize<D>(deserializer: D) -> Result<Order, D::Error> where D: Deserializer<'de> {
#[derive(Deserialize)]
struct OrderData {
price: f64,
volume: f64,
side: String,
timestamp: String,
order_type: String,
}

let helper = OrderData::deserialize(deserializer)?;
//let id = Uuid::parse_str(&helper.id).map_err(de::Error::custom)?;

Ok(Order {
id: Uuid::new_v4(),
price: OrderedFloat(helper.price),
volume: OrderedFloat(helper.volume),
side: helper.side,
timestamp: helper.timestamp,
order_type: helper.order_type,
})
}
}

// Custom serialization for Order (to avoid serialization of OrderedFloat for csv crate)
// TODO: find a better way to handle serialization of OrderedFloat
impl Serialize for Order {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
let mut state: <S as Serializer>::SerializeStruct = serializer.serialize_struct(
"Order",
5
)?;
state.serialize_field("price", &self.price.into_inner())?;
state.serialize_field("volume", &self.volume.into_inner())?;
state.serialize_field("side", &self.side)?;
state.serialize_field("timestamp", &self.timestamp)?;
state.serialize_field("order_type", &self.order_type)?;
//state.serialize_field("id", &self.id.to_string())?;
state.end()
}
}

// Implement the Display trait for the Order struct (more readable output with colors)
impl fmt::Display for Order {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let output: String = format!(
"Price: {:.5}, Volume: {:.3}, Side: {}, ID: {}, Timestamp: {}",
self.price,
self.volume,
self.side,
self.id,
self.timestamp
);
if self.side == "ask" {
write!(f, "{}", output.red())
} else {
write!(f, "{}", output.green())
}
}
}

// Implement the OrderBook trait for OrderBookService to handle gRPC requests (core)
#[tonic::async_trait]
impl OrderBook for Arc<OrderBookService> {
Expand Down

0 comments on commit 5ab45b3

Please sign in to comment.