diff --git a/src/main.rs b/src/main.rs index df02ee2..0852490 100644 --- a/src/main.rs +++ b/src/main.rs @@ -618,6 +618,9 @@ impl Market { self.order_count-=1; Result::RetractedOrder(order_id) } + fn make_smart_order(&mut self, owner:usize, sell_type:usize, buy_type:usize, sell_qty_initial:FiNum, buy_qty_initial:FiNum, max0: FiNum, max1: FiNum, execute_if_possible:bool) -> Result { + Result::Error(format!("make_smart_order not Implemented.")) + } fn make_order(&mut self, owner:usize, sell_type:usize, buy_type:usize, sell_qty_initial:FiNum, buy_qty_initial:FiNum, execute_if_possible:bool) -> Result { let mut log:Vec=Vec::new(); let initial_balance=self.traders[owner].get_balance(sell_type); @@ -649,7 +652,6 @@ impl Market { let cq0=commission0_qty*pay_qty/sell_qty_initial; let rq1=royalty1_qty *pay_qty/sell_qty_initial; let cq1=commission1_qty*pay_qty/sell_qty_initial; - //println!("Transact at ask rate. Qty={} elt.sell_remain={} elt.royalty_remain={} elt.commission_remain={}",qty,elt.sell_remain,elt.royalty_remain,elt.commission_remain); let rq2=if !elt.sell_remain.is_zero() { elt.royalty_remain *qty/elt.sell_remain } else { FiNum::zero() }; let cq2=if !elt.sell_remain.is_zero() { elt.commission_remain*qty/elt.sell_remain } else { FiNum::zero() }; self.royalties.entry(sell_type).or_insert(RoyaltyTree::new()); @@ -663,10 +665,8 @@ impl Market { rts.sub_weight(cap_index,pay_qty); let wh1=rts.weight_here(cap_index); let acc1=rts.tree[cap_index].acc; - //println!("Weight {} / {} Acc {} / {} Cap {}",wh0,wh1,acc0,acc1,cap); self.traders[elt.owner].add_balance(sell_type,cap); } - //elt.sell_remain-=qty; royalty_acc+=rq0+rq1; commission_acc+=cq0+cq1; royalty0_qty-=rq0; @@ -676,18 +676,14 @@ impl Market { 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); let top_order=self.orders.get_mut(&ap).unwrap().peek(); - //println!("top_order.commission_remain={} cq2={} elt.commission_remain={} qty={} elt.sell_remain={}",top_order.commission_remain,cq2,elt.commission_remain,qty,elt.sell_remain); top_order.royalty_remain-=rq2; top_order.commission_remain-=cq2; - //println!("Crediting {} commissions to house {}+{}+{}",sell_type,cq0,cq1,cq2); self.traders[0].add_balance(sell_type,cq0+cq1); self.traders[0].add_balance(buy_type,cq2); if elt.sell_remain==qty { // deal with pennies stored in royalty_remain and commission_remain - //if !top_order.commission_remain.is_zero() { println!("Little commission? {} ",top_order.commission_remain); } let rq3=top_order.royalty_remain; let cq3=top_order.commission_remain; let dist=self.royalties.get_mut(&buy_type).unwrap().remove_order_id(top_order.order_id); - //println!("Popping top order {} and reclaiming {}",top_order.order_id,dist); self.traders[elt.owner].add_balance(sell_type,dist); self.order_finder.remove(&top_order.order_id); self.traders[top_order.owner].order_finder.remove(&top_order.order_id); @@ -752,7 +748,7 @@ impl Market { for ass1 in 0..self.assets.len() { if true || ass0!=ass1 { if let Some(topq)=self.orders.get(&(ass1,ass0)) { - if let Some(top)=topq.peekn() { + let top=topq.peek_nomut(); if true { println!("There is a direct path from {} to {} with a cost of {} {}", self.number_to_name(ass0),self.number_to_name(ass1),top.buy_qty/top.sell_qty,self.number_to_name(ass1)); let candidate=cheapest[ass0].cost*top.buy_qty/top.sell_qty; @@ -869,6 +865,10 @@ impl OrderQueue { if !self.shadowing { self.v.first_mut().unwrap() } else { self.shadow.as_mut().expect("Shadowing mismatch") } } + fn peek_nomut(&self) -> &Order { + if !self.shadowing { self.v.first().unwrap() } + else { self.shadow.as_ref().expect("Shadowing mismatch") } + } fn peekn(&self) -> Option<&Order> { match &self.shadow { Some(order) => Some(order), @@ -1127,6 +1127,7 @@ enum Command { AddFunds { user_id: usize, asset_id: usize, amt: FiNum }, SubFunds { user_id: usize, asset_id: usize, amt: FiNum }, Order { user_id: usize, sell_type: usize, sell_qty: FiNum, buy_type: usize, buy_qty: FiNum }, + SmartOrder { user_id: usize, sell_type: usize, sell_qty: FiNum, buy_type: usize, buy_qty: FiNum, max0: FiNum, max1: FiNum }, OrderBatch { user_id: usize, sell_type: usize, sell_qty: FiNum, buy_type: usize, buy_qty: FiNum }, ExecuteBatch { asset_type0: usize, strike0: FiNum, asset_type1: usize, strike1: FiNum }, RetractOrder { order_id: usize }, @@ -1268,6 +1269,9 @@ impl Market { Command::Order { user_id, sell_type, sell_qty, buy_type, buy_qty } => { self.make_order(*user_id,*sell_type,*buy_type,*sell_qty,*buy_qty,true) } + Command::SmartOrder { user_id, sell_type, sell_qty, buy_type, buy_qty, max0, max1 } => { + self.make_smart_order(*user_id,*sell_type,*buy_type,*sell_qty,*buy_qty,*max0,*max1,true) + } Command::OrderBatch { user_id, sell_type, sell_qty, buy_type, buy_qty } => { self.make_order(*user_id,*sell_type,*buy_type,*sell_qty,*buy_qty,false) } @@ -1361,6 +1365,22 @@ fn tokens_to_command(m: &Market, logged_in: usize, tokens: Vec<&str>,line: &str) else if qty1.is_zero() { Command::Error("Qty1 is must be > 0".to_string()) } else { Command::Order { user_id: logged_in, sell_type: *cur0.unwrap(), sell_qty: qty0, buy_type: *cur1.unwrap(), buy_qty: qty1 } } } + // Sell up to qty0 cur0 to buy up to qty1 cur1 where no suborder exceeds maxsub (expressed as a fraction) + ["smart", qty0, cur0, qty1, cur1, max0, "/", max1 ] => { + let qty0=FiNum::new_str(qty0); + let cur0=m.name_to_number(cur0); + let qty1=FiNum::new_str(qty1); + let cur1=m.name_to_number(cur1); + let max0=FiNum::new_str(max0); + let max1=FiNum::new_str(max1); + if !cur0.is_some() { Command::Error("Count not find currency".to_string()) } + else if !cur1.is_some() { Command::Error("Count not find currency".to_string()) } + else if qty0.is_zero() { Command::Error("Qty0 is must be > 0".to_string()) } + else if qty1.is_zero() { Command::Error("Qty1 is must be > 0".to_string()) } + else if max0.is_zero() { Command::Error("Max0 is must be > 0".to_string()) } + else if max1.is_zero() { Command::Error("Max1 is must be > 0".to_string()) } + else { Command::SmartOrder { user_id: logged_in, sell_type: *cur0.unwrap(), sell_qty: qty0, buy_type: *cur1.unwrap(), buy_qty: qty1, max0: max0, max1: max1 } } + } ["orderbatch", qty0, cur0, qty1, cur1 ] => { let qty0=FiNum::new_str(qty0); let cur0=m.name_to_number(cur0);