diff --git a/src/main.rs b/src/main.rs index 2c41935..7c1cfb6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,12 +3,30 @@ use std::cmp::Ordering; use std::cmp::min; use fixed::types::U32F32; +#[derive(Debug, Clone)] +struct Trader { + name: String, + id: i32, + balances: HashMap, // Maps Currency to Amount + } + +impl Trader { + fn new(name:&str,id:i32) -> Self { + Trader { + name: String::from(name), + id: id, + balances: HashMap::new() + } + } + } + #[derive(Debug, Clone)] struct Offer { - sell_qty: u64, - sell_remain: u64, - buy_qty: u64, - } + sell_qty: u64, + sell_remain: u64, + buy_qty: u64, + owner: i32, + } trait Dumpable { fn dump(&self); @@ -28,11 +46,12 @@ impl Offer { } struct Market { - asset_name2num: HashMap, - asset_num2name: HashMap, - asset_count:i32, - offers: HashMap<(i32,i32),PQueue>, - } + asset_name2num: HashMap, + asset_num2name: HashMap, + asset_count:i32, + offers: HashMap<(i32,i32),PQueue>, + traders: Vec, + } impl Market { fn new() -> Self { @@ -40,9 +59,11 @@ impl Market { asset_name2num: HashMap::new(), asset_num2name: HashMap::new(), asset_count:0, - offers: HashMap::new() + offers: HashMap::new(), + traders: Vec::new() } } + fn register_asset(&mut self, name:&str) -> i32 { self.asset_count+=1; self.asset_name2num.insert(String::from(name),self.asset_count); @@ -62,7 +83,7 @@ impl Market { value.dump(); } } - fn make_offer(&mut self, sell_type:i32, buy_type:i32, sell_qty_initial:u64, buy_qty_initial:u64) // Dollars, Bitcoin, 64000, 1 + fn make_offer(&mut self, owner:i32, sell_type:i32, buy_type:i32, sell_qty_initial:u64, buy_qty_initial:u64) // Dollars, Bitcoin, 64000, 1 { // Comments assume someone is already selling 1 Bitcoin for 48000 USD (Bitcoin, Dollars, 1, 48000). Then someone comes along and bids $64000 for 1 Bitcoin (sells 64000 USD to buy 1 Bitcoin. println!("Making offer to sell {} {} and get {} {}",fxp_to_fp(sell_qty_initial),self.number_to_name(sell_type),fxp_to_fp(buy_qty_initial),self.number_to_name(buy_type)); let mut sell_qty=sell_qty_initial; // 64000 Dollars @@ -75,13 +96,25 @@ impl Market { if asks.v.len()>0 { let elt=&mut asks.v[0]; let ask_rate=fxp_div(elt.buy_qty,elt.sell_qty); + let elt_buy_remain=fxp_mult(elt.buy_qty,fxp_div(elt.sell_remain,elt.sell_qty)); if sell_rate>=ask_rate { // Transact at ask_rate - let transact=std::cmp::min(sell_qty,fxp_mult(elt.buy_qty,fxp_div(elt.sell_remain,elt.sell_qty))); - elt.sell_remain-=fxp_div(transact,ask_rate); - buy_qty-=fxp_div(transact,ask_rate); - sell_qty-=transact; - if elt.sell_remain==0 { println!("Popping asks"); asks.pop(); } - } else { break; } + // Can we eat the entire ask? + if buy_qty>=elt.sell_remain { + sell_qty-=fxp_mult(sell_qty,fxp_div(elt.sell_remain,buy_qty_initial)); + buy_qty-=elt.sell_remain; + asks.pop(); + } else if elt_buy_remain>=sell_qty { // Can we eat the rest of the offer? + elt.sell_remain-=buy_qty; + sell_qty=0; + buy_qty=0; + } else { + let transact=std::cmp::min(sell_qty,fxp_mult(elt.buy_qty,fxp_div(elt.sell_remain,elt.sell_qty))); + elt.sell_remain-=fxp_div(transact,ask_rate); + buy_qty-=fxp_div(transact,ask_rate); + sell_qty-=fxp_mult(transact,fxp_div(sell_rate,ask_rate)); + if elt.sell_remain==0 { println!("Popping asks"); asks.pop(); } + } + } else { break; } } else { break; } } else { break; } lc-=1; @@ -91,7 +124,7 @@ impl Market { if let None=self.offers.get_mut(&ap) { self.offers.insert(ap,PQueue::new()); } let mut bids=self.offers.get_mut(&ap).unwrap(); println!("Inserting new offer with sell_qty {}, buy_qty {}",fxp_to_fp(sell_qty),fxp_to_fp(buy_qty)); - bids.insert(Offer { sell_qty:sell_qty, sell_remain:sell_qty, buy_qty:buy_qty } ); + bids.insert(Offer { owner:owner, sell_qty:sell_qty, sell_remain:sell_qty, buy_qty:buy_qty } ); } } } @@ -208,8 +241,8 @@ fn main() { println!("This should be 64000: {} or in raw form {}",fxp_to_fp(fxp_recip(fxp_recip(n))),fxp_recip(fxp_recip(n))); println!("This should be 1: {} or in raw form ",fxp_to_fp(fxp_mult(fxp_recip(fxp_from_int(64000)),fxp_from_int(64000)))); println!("{}*{}={}",fxp_to_fp(fxp_from_int(3)),fxp_to_fp(fxp_from_int(5)),fxp_to_fp(fxp_mult(fxp_from_int(3),fxp_from_int(5)))); - m.make_offer(btc,usd,fxp_from_int(1),fxp_from_int(60000)); + m.make_offer(0,btc,usd,fxp_from_int(1),fxp_from_int(60000)); m.dump(); - m.make_offer(usd,btc,fxp_from_int(128000),fxp_from_int(2)); // Buy 1 BTC for 64000 USD + m.make_offer(1,usd,btc,fxp_from_int(128000),fxp_from_int(2)); // Buy 1 BTC for 64000 USD m.dump(); }