Skip to content

Commit

Permalink
Merge pull request calumrussell#95 from calumrussell/hyperliquid-bina…
Browse files Browse the repository at this point in the history
…ry-from-file

66 Create hyperliquid binary from file
  • Loading branch information
calumrussell authored Sep 5, 2024
2 parents c72c000 + 8e45512 commit af8fc37
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 5 deletions.
4 changes: 4 additions & 0 deletions rotala/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ criterion = { version = "0.5.1", features = ["async_tokio"] }
name = "uist_server_v1"
path = "./src/bin/uist_server_v1.rs"

[[bin]]
name = "uist_server_v2"
path = "./src/bin/uist_server_v2.rs"

[[bin]]
name = "jura_server_v1"
path = "./src/bin/jura_server_v1.rs"
Expand Down
35 changes: 35 additions & 0 deletions rotala/src/bin/uist_server_v2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use std::env;
use std::sync::Mutex;

use actix_web::{web, App, HttpServer};
use rotala::http::uist_v2::server::*;
use rotala::http::uist_v2::AppState;
use rotala::input::athena::Athena;
use std::path::Path;

#[actix_web::main]
async fn main() -> std::io::Result<()> {
let args: Vec<String> = env::args().collect();

let address: String = args[1].clone();
let port: u16 = args[2].parse().unwrap();
let file_path = Path::new(&args[3]);

let source = Athena::from_file(file_path);
let app_state = AppState::single("Test", source);

let uist_state = web::Data::new(Mutex::new(app_state));

HttpServer::new(move || {
App::new()
.app_data(uist_state.clone())
.service(info)
.service(init)
.service(fetch_quotes)
.service(tick)
.service(insert_order)
})
.bind((address, port))?
.run()
.await
}
2 changes: 1 addition & 1 deletion rotala/src/http/uist_v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ impl HttpClient {

type UistState = Mutex<AppState>;

mod server {
pub mod server {
use actix_web::{get, post, web};

use super::{
Expand Down
29 changes: 29 additions & 0 deletions rotala/src/input/athena.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
#![allow(dead_code)]

use std::collections::HashMap;
use std::path::Path;
use std::{borrow::Borrow, collections::HashSet};

use rand::thread_rng;
use rand_distr::{Distribution, Uniform};
use serde::{Deserialize, Serialize};

use crate::source::hyperliquid::get_hyperliquid_l2;

#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum Side {
Bid,
Expand Down Expand Up @@ -130,6 +133,21 @@ impl Athena {
depth.get_bbo()
}

pub fn add_depth(&mut self, depth: Depth) {
let date = depth.date;
let symbol = depth.symbol.clone();

self.inner.entry(date).or_default();

let date_levels = self.inner.get_mut(&date).unwrap();
date_levels.insert(symbol, depth);

if !self.dates_seen.contains(&date) {
self.dates.push(date);
self.dates_seen.insert(date);
}
}

pub fn add_price_level(&mut self, date: i64, symbol: &str, level: Level, side: Side) {
self.inner.entry(date).or_default();

Expand Down Expand Up @@ -193,6 +211,17 @@ impl Athena {
source
}

pub fn from_file(path: &Path) -> Self {
let hl_source = get_hyperliquid_l2(path);

let mut athena = Self::new();
for (_key, value) in hl_source {
let into_depth: Depth = value.into();
athena.add_depth(into_depth);
}
athena
}

pub fn new() -> Self {
Self {
dates: Vec::new(),
Expand Down
48 changes: 44 additions & 4 deletions rotala/src/source/hyperliquid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,33 @@ use std::{collections::HashMap, fs::read_to_string};
use serde::{Deserialize, Serialize};
use serde_json::from_str;

use crate::input::athena::{Depth, Level};

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Level {
pub struct HyperLiquidLevel {
pub px: String,
pub sz: String,
pub n: i8,
}

impl From<HyperLiquidLevel> for Level {
fn from(value: HyperLiquidLevel) -> Self {
Self {
price: value.px.parse().unwrap(),
size: value.sz.parse().unwrap(),
}
}
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct PointInTime {
pub coin: String,
pub time: u64,
pub levels: Vec<Vec<Level>>,
pub levels: Vec<Vec<HyperLiquidLevel>>,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Data {
pub struct PointInTimeWrapper {
pub channel: String,
pub data: PointInTime,
}
Expand All @@ -28,7 +39,36 @@ pub struct Data {
pub struct L2Book {
pub time: String,
pub ver_num: u64,
pub raw: Data,
pub raw: PointInTimeWrapper,
}

impl From<L2Book> for Depth {
fn from(value: L2Book) -> Depth {
let date = value.raw.data.time as i64;
let symbol = value.raw.data.coin;

let mut bids_depth: Vec<Level> = Vec::new();
let mut asks_depth: Vec<Level> = Vec::new();

if let Some(bids) = value.raw.data.levels.first() {
let bids_depth_tmp: Vec<Level> =
bids.iter().map(|v| -> Level { v.clone().into() }).collect();
bids_depth.extend(bids_depth_tmp);
}

if let Some(asks) = value.raw.data.levels.get(1) {
let asks_depth_tmp: Vec<Level> =
asks.iter().map(|v| -> Level { v.clone().into() }).collect();
asks_depth.extend(asks_depth_tmp);
}

Depth {
bids: bids_depth,
asks: asks_depth,
date,
symbol,
}
}
}

pub fn get_hyperliquid_l2(path: &Path) -> HashMap<u64, L2Book> {
Expand Down

0 comments on commit af8fc37

Please sign in to comment.