diff --git a/src/main.rs b/src/main.rs index c3b8c82..192234d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -261,7 +261,12 @@ impl Dumpable for Order { } } - +struct OrderFinder { + asset0: usize, + asset1: usize, + pq_loc: usize, + rt_loc: usize, + } struct Market { asset_name2num: HashMap, @@ -269,9 +274,10 @@ struct Market { money_supply: HashMap, traders: Vec, trader_name2num: HashMap, - orders: HashMap<(usize,usize),PQueue>>>, + orders: HashMap<(usize,usize),OrderQueue>, royalties: HashMap, // Active orders that are accepting asset X. They receive royalties when someone makes an order to sell X royalty_rate: HashMap, + order_finder: HashMap, // To find an order, look in Orders.get(usize,usize) at position usize next_order_id: usize, } @@ -286,6 +292,7 @@ impl Market { orders: HashMap::new(), royalties: HashMap::new(), royalty_rate: HashMap::new(), + order_finder: HashMap::new(), next_order_id: 1, }; rval.register_trader("*HOUSE*"); @@ -297,7 +304,7 @@ impl Market { println!("Money Supply {}: {}",self.number_to_name(*cur),*amt); let mut acc_orders=FiNum::new(0); for (ac,pq) in &self.orders { if ac.0==*cur { - for off in &*pq.v { acc_orders+=off.borrow().sell_remain; } + for off in &*pq.v { acc_orders+=off.sell_remain; } } } let mut acc_traders=FiNum::new(0); for t in &self.traders { acc_traders+=t.get_balance(*cur); } @@ -348,18 +355,15 @@ impl Market { } fn dump(&mut self) { println!("Dumping Market:"); - for t in &self.traders { - println!(" Trader {}: {}",t.id,t.name); - for (cur,bal) in t.balances.iter() { - println!(" {}: {}",self.number_to_name(*cur),*bal) - } - } + println!("Money Supply:"); + for index in 0..self.assets.len() { + println!(" {}: {}",self.number_to_asset(index).name,self.money_supply[&index]); + } for (ap,pq) in &self.orders { println!("Orders selling {} to buy {}:",self.number_to_name(ap.0),self.number_to_name(ap.1)); let mut sorted=pq.v.clone(); - sorted.sort_by(|a,b| { let a=a.borrow(); let b=b.borrow(); (a.sell_qty/a.buy_qty).cmp(&(b.sell_qty/b.buy_qty)) }); + sorted.sort_by(|a,b| { (a.sell_qty/a.buy_qty).cmp(&(b.sell_qty/b.buy_qty)) }); for off in sorted.iter() { - let off=off.borrow(); println!(" {} @ {} ({}) OrderID: {} PQLoc: {} RTLoc: {} Royalties: {}", off.sell_remain, // off.buy_qty*off.sell_remain/off.sell_qty, off.buy_qty/off.sell_qty, @@ -368,12 +372,19 @@ impl Market { self.royalties.get_mut(&ap.1).unwrap().get_royalty(off.rt_loc)); //,self.royalties.get(&ap.1).unwrap().tree[off.rt_loc].acc); } - pq.dump(); } + println!("Royalties accumulated but not captured:"); for index in 0..self.assets.len() { let tot=self.royalties.get(&index).unwrap().acc_total(); - println!("Accumulated Royalties for {}: {}",self.number_to_asset(index).name,tot); + println!(" For {}: {}",self.number_to_asset(index).name,tot); } + println!("Trader Balances:"); + for t in &self.traders { + println!(" Trader {}: {}",t.id,t.name); + for (cur,bal) in t.balances.iter() { + println!(" {}: {}",self.number_to_name(*cur),*bal) + } + } } fn replay_file(&mut self, fname:&str) { println!("Replaying {}",fname); @@ -399,18 +410,18 @@ impl Market { let ap1=(asset_type1,asset_type0); let [bids0,bids1]=self.orders.get_many_mut([&ap0, &ap1]).unwrap(); while !bids0.empty() && !bids1.empty() - && bids0.peek().borrow().sell_qty/bids0.peek().borrow().buy_qty>=strike0/strike1 - && bids1.peek().borrow().sell_qty/bids1.peek().borrow().buy_qty>=strike1/strike0 { - let asset0_paying =std::cmp::min(bids0.peek().borrow().sell_remain,strike0*bids1.peek().borrow().sell_remain/bids1.peek().borrow().sell_qty); - let asset1_paying =std::cmp::min(bids1.peek().borrow().sell_remain,strike1*bids0.peek().borrow().sell_remain/bids0.peek().borrow().sell_qty); - bids0.peek().borrow_mut().sell_remain-=asset0_paying; - bids1.peek().borrow_mut().sell_remain-=asset1_paying; - self.traders[bids0.peek().borrow().owner].add_balance(asset_type1,asset1_paying); - self.traders[bids1.peek().borrow().owner].add_balance(asset_type0,asset0_paying); - log.push(format!(" {} got {} {}, {} got {} {}",self.traders[bids0.peek().borrow().owner].name,asset1_paying,asset1.name, - self.traders[bids1.peek().borrow().owner].name,asset0_paying,asset0.name)); - if bids0.peek().borrow().sell_remain==FiNum::zero() { bids0.pop(); } - if bids1.peek().borrow().sell_remain==FiNum::zero() { bids1.pop(); } + && bids0.peek().sell_qty/bids0.peek().buy_qty>=strike0/strike1 + && bids1.peek().sell_qty/bids1.peek().buy_qty>=strike1/strike0 { + let asset0_paying =std::cmp::min(bids0.peek().sell_remain,strike0*bids1.peek().sell_remain/bids1.peek().sell_qty); + let asset1_paying =std::cmp::min(bids1.peek().sell_remain,strike1*bids0.peek().sell_remain/bids0.peek().sell_qty); + bids0.peek().sell_remain-=asset0_paying; + bids1.peek().sell_remain-=asset1_paying; + self.traders[bids0.peek().owner].add_balance(asset_type1,asset1_paying); + self.traders[bids1.peek().owner].add_balance(asset_type0,asset0_paying); + log.push(format!(" {} got {} {}, {} got {} {}",self.traders[bids0.peek().owner].name,asset1_paying,asset1.name, + self.traders[bids1.peek().owner].name,asset0_paying,asset0.name)); + if bids0.peek().sell_remain==FiNum::zero() { bids0.pop(); } + if bids1.peek().sell_remain==FiNum::zero() { bids1.pop(); } } Result::ExecutedBatch(log) } @@ -431,7 +442,7 @@ impl Market { let mut commission_acc=FiNum::zero(); let new_order_id:usize; while execute_if_possible && buy_qty>FiNum::new(0) && self.orders.contains_key(&ap) && self.orders.get(&ap).unwrap().v.len()>0 { - let mut elt=(*(self.orders.get(&ap).unwrap().v[0].borrow())).clone(); + let mut elt=self.orders.get(&ap).unwrap().v[0].clone(); if sell_qty/buy_qty_initial>=elt.buy_qty/elt.sell_qty { // Transact at ask_rate let qty=std::cmp::min(elt.sell_remain,buy_qty); elt.sell_remain-=qty; @@ -457,22 +468,23 @@ impl Market { commission1_qty-=cq1; self.royalties.entry(sell_type).or_insert(RoyaltyTree::new()).add_royalty(rq0+rq1); self.royalties.entry(buy_type) .or_insert(RoyaltyTree::new()).add_royalty(rq2); - self.orders.get(&ap).unwrap().v[0].borrow_mut().royalty_remain-=rq2; - self.orders.get(&ap).unwrap().v[0].borrow_mut().commission_remain-=cq2; + let top_order=self.orders.get_mut(&ap).unwrap().peek(); + top_order.royalty_remain-=rq2; + top_order.commission_remain-=cq2; self.traders[0].add_balance(buy_type,cq2); self.royalties.entry(buy_type).or_insert(RoyaltyTree::new()).add_royalty(rq2); if elt.sell_remain==0.into() { // deal with pennies stored in royalty_remain and commission_remain - self.traders[0].add_balance(buy_type,self.orders.get(&ap).unwrap().v[0].borrow_mut().commission_remain); - self.royalties.entry(buy_type).or_insert(RoyaltyTree::new()).add_royalty(self.orders.get(&ap).unwrap().v[0].borrow_mut().royalty_remain); + self.traders[0].add_balance(buy_type,top_order.commission_remain); + self.royalties.entry(buy_type).or_insert(RoyaltyTree::new()).add_royalty(top_order.royalty_remain); self.orders.get_mut(&ap).unwrap().pop(); } else { - self.orders.get(&ap).unwrap().v[0].borrow_mut().sell_remain-=qty; + top_order.sell_remain-=qty; } } else { break; } } if buy_qty>0.into() { let ap=(sell_type,buy_type); - if let None=self.orders.get_mut(&ap) { self.orders.insert(ap,PQueue::new()); } + if let None=self.orders.get_mut(&ap) { self.orders.insert(ap,OrderQueue::new()); } let bids=self.orders.get_mut(&ap).unwrap(); let sell_qty_remain=sell_qty*buy_qty/buy_qty_initial; if sell_qty_remain>0.into() { @@ -480,14 +492,13 @@ impl Market { let rt=self.royalties.entry(buy_type).or_insert(RoyaltyTree::new()); let rt_loc=rt.next_entry; rt.add_weight(rt_loc,buy_qty); // Weight should really be the quantity you would be able to immediately transact rather than how much you wish for. - let neworder=Rc::new(RefCell::new( - Order { owner:owner, sell_qty:sell_qty_remain, sell_remain:sell_qty_remain, buy_qty:buy_qty, rt_loc: rt_loc, pq_loc:0, royalty_remain:royalty1_qty, commission_remain:commission1_qty, id:self.next_order_id } )); + let neworder=Order { owner:owner, sell_qty:sell_qty_remain, sell_remain:sell_qty_remain, buy_qty:buy_qty, rt_loc: rt_loc, pq_loc:0, royalty_remain:royalty1_qty, commission_remain:commission1_qty, id:self.next_order_id }; new_order_id=self.next_order_id; self.next_order_id+=1; rt.next_entry+=1; let pq_loc=bids.insert(neworder); - bids.v[pq_loc].borrow_mut().pq_loc=pq_loc; - bids.v[pq_loc].borrow_mut().rt_loc=rt_loc; + bids.v[pq_loc].pq_loc=pq_loc; + bids.v[pq_loc].rt_loc=rt_loc; self.traders[owner].sub_balance(sell_type,sell_qty_remain); self.traders[0].add_balance(sell_type,commission0_qty); log.push(format!("Moved {} {} ({}) to market",sell_qty_remain,self.number_to_name(sell_type),self.traders[owner].name)); @@ -520,18 +531,18 @@ impl PartialEq for Order { } -struct PQueue { - v: Vec, +struct OrderQueue { + v: Vec, } -impl PQueue { +impl OrderQueue { fn new()->Self { - PQueue { + OrderQueue { v: Vec::new() } } - fn peek(&self) -> &T { - &self.v[0] + fn peek(&mut self) -> &mut Order { + self.v.first_mut().unwrap() } fn empty(&self) -> bool { self.v.len()==0 @@ -540,6 +551,8 @@ impl PQueue { if pos>0 { let parent=(pos-1)/2; if self.v[parent] PQueue { if self.v[pivot] usize { + fn insert(&mut self, mut item: Order) -> usize { + item.pq_loc=self.v.len(); self.v.push(item); self.bubble_up(self.v.len()-1) } - fn pop(&mut self) -> Option { + fn pop(&mut self) -> Option { if self.v.len()==0 { None } else { let end=self.v.len()-1;