From 225fbcbe1c27a930bff40e95e69d3abe3f14b66d Mon Sep 17 00:00:00 2001 From: Teppy Date: Mon, 27 May 2024 15:11:35 -0400 Subject: [PATCH 01/14] changes --- src/main.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.rs b/src/main.rs index 96b8c1e..6f3341a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -38,6 +38,8 @@ struct Offer { sell_qty: FiNum, sell_remain: FiNum, buy_qty: FiNum, + royalty_acc: FiNum, // Buy type. In the royalty tree, for this node and those to the left + royalty_cap: FiNum, // In the royalty tree, just for this node. owner: i32, } From 24170816e1023d4caa6605fe56556d21241492c7 Mon Sep 17 00:00:00 2001 From: Teppy Date: Sun, 9 Jun 2024 21:13:07 -0400 Subject: [PATCH 02/14] changes --- src/main.rs | 107 ++++++++++++++++++++++++++++------------------------ 1 file changed, 58 insertions(+), 49 deletions(-) diff --git a/src/main.rs b/src/main.rs index c891449..2113a4e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -59,66 +59,75 @@ struct RoyaltyTree { tree: Vec, } +struct Royalty { + weight: FiNum, // Here and below + lazy: FiNum, // To be distributed to here and to below based on weights + acc: FiNum, // Accumulated here + } + +impl Royalty { + fn new() -> Self { + Royalty { weight:FiNum::zero(), lazy:FiNum::zero(), acc:FiNum::zero() } + } + } + impl RoyaltyTree { fn new() -> Self { RoyaltyTree { tree:Vec::new() } } - fn get_weight(&self, index:usize) -> FiNum { - println!("Get_weight {} self.tree.len() {} ",index,self.tree.len()); - if index=self.tree.len() { index=wt_left(index).unwrap() } - self.tree[index].weight + fn weight_here_below(&self, index:usize) -> FiNum { + if index FiNum { + if index&1==0 { + FiNum::zero() + } else { + self.weight_here_below(wt_left (index).unwrap())+self.weight_here_below(wt_right(index).unwrap()) } } - } - -struct Royalty { - weight: FiNum, // Here and below - acc: FiNum, // Here and Below - } - -impl Royalty { - fn new(weight: FiNum) -> Self { - Royalty { weight:weight, acc:FiNum::new(0u64) } + fn weight_here(&self, index:usize) -> FiNum { + if index&1==0 { + self.weight_here_below(index) + } else { + self.weight_here_below(index)-self.weight_below(index) + } + } + fn expand_to(&mut self, index: usize) -> &mut Self { + for _ in self.tree.len()..=index+1 { self.tree.push(Royalty::new()) } + self } - } - -impl RoyaltyTree { - fn insert(&mut self, weight: FiNum, royalty:FiNum) -> usize { - let last=self.tree.len(); - let mut nweight=weight; - if let Some(left )=wt_left (last) { if left &mut Self { + if index FiNum { + fn capture(&mut self, index: usize) -> &mut Self { // Clear out lazy by drilling from root to index let ff=wt_forefather(index); let mut index=index; - let mut rval=FiNum::zero(); - loop { - let cap=self.tree[index].acc*weight/self.tree[index].weight; - self.tree[index].weight-=weight; - self.tree[index].acc-=cap; - rval+=cap; - if index!=ff { index=wt_parent(index); } else { break; } + while index!=ff { + self.capture0(index); + index=wt_parent(index); } - rval - } + self + } fn dump(&self) { for index in 0..self.tree.len() { println!("Index {} Weight {}",index,self.tree[index].weight); From 974f9bbd82af5d78a02970415fcae7cece79e88e Mon Sep 17 00:00:00 2001 From: Teppy Date: Mon, 10 Jun 2024 01:45:03 -0400 Subject: [PATCH 03/14] changes --- src/main.rs | 52 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/src/main.rs b/src/main.rs index 2113a4e..6af043d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -99,7 +99,8 @@ impl RoyaltyTree { fn capture0(&mut self, index: usize) -> &mut Self { if index &mut Self { // Clear out lazy by drilling from root to index - let ff=wt_forefather(index); + fn drill(&mut self, index: usize) { + let mut f=self.forefather(); + while f!=index { + self.capture0(f); + f=if f>index { wt_left(f).unwrap() } else { wt_right(f).unwrap() } + } + self.capture0(f); + } + fn capture(&mut self, index: usize) { + let f=self.forefather(); let mut index=index; - while index!=ff { + while index!=f { self.capture0(index); index=wt_parent(index); } - self - } + self.capture0(index); + } + fn add_royalty(&mut self, amount: FiNum) { + let ff=self.forefather(); + self.tree[ff].lazy+=amount; + } + fn insert(&mut self, weight: FiNum) { + self.tree.push(Royalty::new()); + let mut index=self.tree.len()-1; + let rval=index; + let ff=self.forefather(); + while index!=ff { + self.tree[index].weight+=weight; + index=wt_parent(index); + } + self.tree[index].weight+=weight; + } + fn forefather(&self) -> usize { + wt_forefather(self.tree.len()-1) + } fn dump(&self) { for index in 0..self.tree.len() { - println!("Index {} Weight {}",index,self.tree[index].weight); + println!("Index {} Weight {} Lazy {} Acc {}",index,self.tree[index].weight,self.tree[index].lazy,self.tree[index].acc); } } } @@ -280,7 +307,8 @@ impl Market { let bids=self.orders.get_mut(&ap).unwrap(); let sell_qty_remain=sell_qty_initial*buy_qty/buy_qty_initial; if sell_qty_remain>0.into() { - let rt_loc=self.royalties.entry(sell_type).or_insert(RoyaltyTree::new()).insert(sell_qty_remain,FiNum::zero()); + self.royalties.entry(sell_type).or_insert(RoyaltyTree::new()).insert(sell_qty_remain); + let rt_loc=self.royalties.get(&sell_type).unwrap().tree.len(); 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 } )); bids.insert(neworder); @@ -451,11 +479,13 @@ fn tree_stuff() { fn royalty_stuff() { let mut rt=RoyaltyTree::new(); - for _ in 0..20 { - rt.insert(FiNum::new_i32(10),FiNum::zero()); + for _ in 0..3 { + let index=rt.insert(FiNum::new_i32(10)); + rt.add_royalty(FiNum::new_i32(24)) } + rt.dump(); for index in 0..rt.tree.len() { - println!("Index: {} Royalty: {}",index,rt.tree[index].weight); + println!("Index: {} Royalty: {}",index,rt.weight_here_below(index)); } } From ec09d0aefaba631835764663d2f926b62ffc9dbf Mon Sep 17 00:00:00 2001 From: Teppy Date: Mon, 10 Jun 2024 15:08:18 -0400 Subject: [PATCH 04/14] changes --- src/main.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 6af043d..dbf5c50 100644 --- a/src/main.rs +++ b/src/main.rs @@ -120,13 +120,14 @@ impl RoyaltyTree { } self } - fn drill(&mut self, index: usize) { + fn get_royalty(&mut self, index: usize) -> FiNum { let mut f=self.forefather(); while f!=index { self.capture0(f); f=if f>index { wt_left(f).unwrap() } else { wt_right(f).unwrap() } } self.capture0(f); + self.tree[index].acc } fn capture(&mut self, index: usize) { let f=self.forefather(); @@ -155,9 +156,10 @@ impl RoyaltyTree { fn forefather(&self) -> usize { wt_forefather(self.tree.len()-1) } - fn dump(&self) { + fn dump(&mut self) { for index in 0..self.tree.len() { - println!("Index {} Weight {} Lazy {} Acc {}",index,self.tree[index].weight,self.tree[index].lazy,self.tree[index].acc); + let roy=self.get_royalty(index); + println!("Index {} Weight {} Lazy {} Acc {} Royalty {}",index,self.tree[index].weight,self.tree[index].lazy,self.tree[index].acc,roy); } } } From c52c67ef54708c692845d19c241f320369711cd3 Mon Sep 17 00:00:00 2001 From: Teppy Date: Mon, 10 Jun 2024 18:39:12 -0400 Subject: [PATCH 05/14] changes --- src/main.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index dbf5c50..53da393 100644 --- a/src/main.rs +++ b/src/main.rs @@ -76,7 +76,7 @@ impl RoyaltyTree { RoyaltyTree { tree:Vec::new() } } fn weight_here_below(&self, index:usize) -> FiNum { - if index FiNum { if index&1==0 { @@ -89,7 +89,10 @@ impl RoyaltyTree { if index&1==0 { self.weight_here_below(index) } else { - self.weight_here_below(index)-self.weight_below(index) + let w0=self.weight_here_below(index); + let w1=self.weight_below(index); + println!("Weight_here({})={}-{}",index,w0,w1); + w0-w1 } } fn expand_to(&mut self, index: usize) -> &mut Self { @@ -145,13 +148,21 @@ impl RoyaltyTree { fn insert(&mut self, weight: FiNum) { self.tree.push(Royalty::new()); let mut index=self.tree.len()-1; + if index&1==1 { + let left_weight=self.tree[wt_left(index).unwrap()].weight; + self.tree[index].weight=left_weight; + } + println!("Inserting at {}",index); let rval=index; let ff=self.forefather(); while index!=ff { + println!("Index {} Adding weight {}",index,weight); self.tree[index].weight+=weight; index=wt_parent(index); } + println!("Index {} Adding weight {}",index,weight); self.tree[index].weight+=weight; + println!("Index {} Final weight {}",index,self.tree[index].weight); } fn forefather(&self) -> usize { wt_forefather(self.tree.len()-1) @@ -481,7 +492,7 @@ fn tree_stuff() { fn royalty_stuff() { let mut rt=RoyaltyTree::new(); - for _ in 0..3 { + for _ in 0..2 { let index=rt.insert(FiNum::new_i32(10)); rt.add_royalty(FiNum::new_i32(24)) } From 314bf6c85b3cb8ab1c6865f34a28bf95c523bfe5 Mon Sep 17 00:00:00 2001 From: Teppy Date: Tue, 11 Jun 2024 17:44:11 -0400 Subject: [PATCH 06/14] changes --- src/main.rs | 51 ++++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/src/main.rs b/src/main.rs index 53da393..14e8ddf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -76,13 +76,18 @@ impl RoyaltyTree { RoyaltyTree { tree:Vec::new() } } fn weight_here_below(&self, index:usize) -> FiNum { - if index=self.tree.len() && point&1==1 { point=wt_left(point).unwrap() } + if point FiNum { + fn weight_below(&self, index: usize) -> FiNum { if index&1==0 { FiNum::zero() } else { - self.weight_here_below(wt_left (index).unwrap())+self.weight_here_below(wt_right(index).unwrap()) + let w0=self.weight_here_below(wt_left (index).unwrap()); + let w1=self.weight_here_below(wt_right(index).unwrap()); + w0+w1 } } fn weight_here(&self, index:usize) -> FiNum { @@ -114,9 +119,10 @@ impl RoyaltyTree { let d0=d02*self.weight_here_below(index_left)/self.weight_below(index); let d2=d02-d0; assert!(lazy==d0+d1+d2,"Distributing amounts that don't add up."); - self.expand_to(index_right); self.tree[index_left ].lazy+=d0; - self.tree[index_right].lazy+=d2; + // + if index_rightindex { wt_left(f).unwrap() } else { wt_right(f).unwrap() } } self.capture0(f); - self.tree[index].acc - } - fn capture(&mut self, index: usize) { - let f=self.forefather(); - let mut index=index; - while index!=f { - self.capture0(index); - index=wt_parent(index); - } - self.capture0(index); + if index0 { self.get_royalty(self.tree.len()-1); } self.tree.push(Royalty::new()); let mut index=self.tree.len()-1; + println!("Inserting at {}",index); if index&1==1 { let left_weight=self.tree[wt_left(index).unwrap()].weight; self.tree[index].weight=left_weight; + println!(" Non-leaf, weight inherets from left, {}",self.tree[index].weight); } - println!("Inserting at {}",index); let rval=index; let ff=self.forefather(); + println!(" Forefather node is {}",ff); while index!=ff { - println!("Index {} Adding weight {}",index,weight); - self.tree[index].weight+=weight; + if index usize { wt_forefather(self.tree.len()-1) @@ -457,6 +459,10 @@ fn wt_left(index:usize) -> Option { if level>0 { Some(index-(1<<(wt_level(index)-1))) } else { None } } +fn wt_first_left(index: usize, edge: usize) -> Option { // Includes edge + + } + fn wt_right(index:usize) -> Option { let level=wt_level(index); if level>0 { Some(index+(1<<(wt_level(index)-1))) } else { None } @@ -492,13 +498,12 @@ fn tree_stuff() { fn royalty_stuff() { let mut rt=RoyaltyTree::new(); - for _ in 0..2 { + for _ in 0..6 { let index=rt.insert(FiNum::new_i32(10)); rt.add_royalty(FiNum::new_i32(24)) } - rt.dump(); for index in 0..rt.tree.len() { - println!("Index: {} Royalty: {}",index,rt.weight_here_below(index)); + println!("Index: {} Weight_here {} Weight_below {} Weight_here_below {}",index,rt.weight_here(index),rt.weight_below(index),rt.weight_here_below(index)); } } From 66af5fec6a24e2aa92b8220a54e3dbe42db93a85 Mon Sep 17 00:00:00 2001 From: Teppy Date: Wed, 12 Jun 2024 18:29:44 -0400 Subject: [PATCH 07/14] changes --- src/main.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index 14e8ddf..d347d20 100644 --- a/src/main.rs +++ b/src/main.rs @@ -115,7 +115,7 @@ impl RoyaltyTree { let d1=lazy*self.weight_here(index)/self.weight_here_below(index); let d02=lazy-d1; let index_left =wt_left (index).unwrap(); - let index_right=wt_right(index).unwrap(); + let index_right=wt_right_edge(index,self.tree.len()).unwrap(); let d0=d02*self.weight_here_below(index_left)/self.weight_below(index); let d2=d02-d0; assert!(lazy==d0+d1+d2,"Distributing amounts that don't add up."); @@ -459,8 +459,19 @@ fn wt_left(index:usize) -> Option { if level>0 { Some(index-(1<<(wt_level(index)-1))) } else { None } } -fn wt_first_left(index: usize, edge: usize) -> Option { // Includes edge - +fn wt_right_edge(index: usize, edge: usize) -> Option { // Less than edge + if index&1==0 { None } + else { + let mut r=wt_right(index).unwrap(); + if r Option { @@ -498,7 +509,7 @@ fn tree_stuff() { fn royalty_stuff() { let mut rt=RoyaltyTree::new(); - for _ in 0..6 { + for _ in 0..20 { let index=rt.insert(FiNum::new_i32(10)); rt.add_royalty(FiNum::new_i32(24)) } From 10dff1d42189478551556988999329bfbc5f77bf Mon Sep 17 00:00:00 2001 From: Teppy Date: Thu, 13 Jun 2024 22:51:32 -0400 Subject: [PATCH 08/14] changes --- src/main.rs | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/main.rs b/src/main.rs index b5302a7..9f06596 100644 --- a/src/main.rs +++ b/src/main.rs @@ -110,11 +110,11 @@ impl RoyaltyTree { self.tree[index].lazy=FiNum::zero(); } else { let lazy=self.tree[index].lazy; - let d1=lazy*self.weight_here(index)/self.weight_here_below(index); + let d1=if lazy>0.into() { lazy*self.weight_here(index)/self.weight_here_below(index) } else { FiNum::zero() }; let d02=lazy-d1; let index_left =wt_left (index).unwrap(); let index_right=wt_right(index).unwrap(); - let d0=d02*self.weight_here_below(index_left)/self.weight_below(index); + let d0=if d02>0.into() { d02*self.weight_here_below(index_left)/self.weight_below(index) } else { FiNum::zero() }; let d2=d02-d0; assert!(lazy==d0+d1+d2,"Distributing amounts that don't add up."); self.tree[index_left ].lazy+=d0; @@ -140,19 +140,20 @@ impl RoyaltyTree { } fn add_weight(&mut self, index: usize, weight: FiNum) { println!("Add_weight at {}",index); - if self.tree.len()>0 { + if self.tree.len()>0 { let mut ff0=self.forefather(); - self.expand_to(wt_forefather(index)*2); - let ff=self.forefather(); - while ff0!=ff { - let w=self.tree[ff0].weight; - ff0=wt_parent(ff0); - self.tree[ff0].weight=w; - } + let ff1=wt_forefather(index); + let w=self.tree[ff0].weight; + self.expand_to(ff1*2); + while ff0 Date: Fri, 14 Jun 2024 10:14:33 -0400 Subject: [PATCH 09/14] changes --- src/main.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index 9f06596..e1cb15b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -94,13 +94,11 @@ impl RoyaltyTree { } else { let w0=self.weight_here_below(index); let w1=self.weight_below(index); - println!("Weight_here at {}, weight_here_below {}, weight_below {}",index,w0,w1); w0-w1 } } fn expand_to(&mut self, index: usize) -> &mut Self { - println!("Expand_to {} ",index); - for _ in self.tree.len()..=index { println!(" Push!"); self.tree.push(Royalty::new()) } + for _ in self.tree.len()..=index { self.tree.push(Royalty::new()) } self } fn capture0(&mut self, index: usize) -> &mut Self { @@ -136,10 +134,8 @@ impl RoyaltyTree { fn add_royalty(&mut self, amount: FiNum) { let ff=self.forefather(); self.tree[ff].lazy+=amount; - println!("Add royalty amount {}, storing at node {}, lazy amount there is now {}",amount,ff,self.tree[ff].lazy); } fn add_weight(&mut self, index: usize, weight: FiNum) { - println!("Add_weight at {}",index); if self.tree.len()>0 { let mut ff0=self.forefather(); let ff1=wt_forefather(index); @@ -154,7 +150,6 @@ impl RoyaltyTree { self.get_royalty(index); // Just for the side effect of capturing everything to this point let mut index=index; let ff=self.forefather(); - println!("Ascending from {} to {}",index,ff); while index!=ff { self.tree[index].weight+=weight; index=wt_parent(index); From f5ece41880abfc3a96ecef37002a262b74eb4fe9 Mon Sep 17 00:00:00 2001 From: Teppy Date: Tue, 18 Jun 2024 16:18:01 -0400 Subject: [PATCH 10/14] changes --- src/main.rs | 56 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/src/main.rs b/src/main.rs index e1cb15b..7ad8827 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,6 +27,25 @@ struct Trader { balances: HashMap, // Maps Currency to Amount } +struct Asset { + name: String, + royalty0_rate: FiNum, // Traders get this when entered + royalty1_rate: FiNum, // Traders get this when executed + commission0_rate: FiNum, // House gets this when entered + commission1_rate: FiNum, // House gets this when executed + } + +impl Asset { + fn new(name: &str) -> Self { + Asset { + name: String::from(name), + royalty0_rate:FiNum::zero(), + royalty1_rate:FiNum::zero(), + commission0_rate:FiNum::zero(), + commission1_rate:FiNum::zero(), + } + } + } impl Trader { fn new(name:&str,id:usize) -> Self { Trader { @@ -195,33 +214,33 @@ impl Dumpable for Order { struct Market { asset_name2num: HashMap, - asset_num2name: HashMap, - asset_count:usize, + assets: Vec, money_supply: HashMap, traders: Vec, trader_name2num: HashMap, orders: HashMap<(usize,usize),PQueue>>>, royalties: HashMap, // Active orders that are accepting asset X. They receive royalties when someone makes an order to sell X + royalty_rate: HashMap, } impl Market { fn new() -> Self { let mut rval=Market { asset_name2num: HashMap::new(), - asset_num2name: HashMap::new(), - asset_count:0, + assets: Vec::new(), money_supply: HashMap::new(), - orders: HashMap::new(), - royalties: HashMap::new(), traders: Vec::new(), trader_name2num: HashMap::new(), + orders: HashMap::new(), + royalties: HashMap::new(), + royalty_rate: HashMap::new(), }; rval.register_trader("*NONE*"); rval } - fn distribute_royalty(&self, amount:FiNum) { - - } + fn number_to_name(&self, n: usize) -> String { + self.assets[n].name.clone() + } fn sanity_check(&self) { println!("Sanity Checking Market..."); for (cur,amt) in self.money_supply.iter() { @@ -252,18 +271,14 @@ impl Market { *self.money_supply.get_mut(&cur).unwrap()-=delta; } fn register_asset(&mut self, name:&str) -> usize { - self.asset_count+=1; - self.asset_name2num.insert(String::from(name),self.asset_count); - self.asset_num2name.insert(self.asset_count,String::from(name)); - self.money_supply.insert(self.asset_count,FiNum::new(0)); - self.asset_count + self.assets.push(Asset::new(name)); + self.asset_name2num.insert(String::from(name),self.assets.len()-1); + self.money_supply.insert(self.assets.len()-1,FiNum::new(0)); + self.assets.len()-1 } fn name_to_number(&self, name:&str) -> usize { *self.asset_name2num.get(name).unwrap() } - fn number_to_name(&self, num:usize) -> &str { - &*self.asset_num2name.get(&num).unwrap() - } fn dump(&self) { println!("Dumping Market:"); for t in &self.traders { @@ -312,10 +327,11 @@ impl Market { let bids=self.orders.get_mut(&ap).unwrap(); let sell_qty_remain=sell_qty_initial*buy_qty/buy_qty_initial; if sell_qty_remain>0.into() { -// self.royalties.entry(sell_type).or_insert(RoyaltyTree::new()).insert(sell_qty_remain); -// let rt_loc=self.royalties.get(&sell_type).unwrap().tree.len(); + let rt=self.royalties.entry(buy_type).or_insert(RoyaltyTree::new()); + rt.add_weight(rt.next_entry,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: 0 } )); + Order { owner:owner, sell_qty:sell_qty_remain, sell_remain:sell_qty_remain, buy_qty:buy_qty, rt_loc: rt.next_entry } )); + rt.next_entry+=1; bids.insert(neworder); self.traders[owner as usize].sub_balance(sell_type,sell_qty_remain); } From c67b56fb1e287488c6ba86fdde21bd8e6a48a460 Mon Sep 17 00:00:00 2001 From: Teppy Date: Tue, 18 Jun 2024 19:19:25 -0400 Subject: [PATCH 11/14] changes --- src/main.rs | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/src/main.rs b/src/main.rs index 7ad8827..c9f7779 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,6 +27,7 @@ struct Trader { balances: HashMap, // Maps Currency to Amount } +#[derive(Clone)] struct Asset { name: String, royalty0_rate: FiNum, // Traders get this when entered @@ -46,6 +47,7 @@ impl Asset { } } } + impl Trader { fn new(name:&str,id:usize) -> Self { Trader { @@ -70,6 +72,8 @@ struct Order { sell_qty: FiNum, sell_remain: FiNum, buy_qty: FiNum, + royalty_remain: FiNum, // Based on royalty1 + commission_remain: FiNum, // Based on commission1 owner: usize, rt_loc: usize, // Location in the Royalty Tree } @@ -77,6 +81,7 @@ struct Order { struct RoyaltyTree { tree: Vec, next_entry: usize, + spare_change: FiNum, // Waiting to be distributed } struct Royalty { @@ -93,7 +98,7 @@ impl Royalty { impl RoyaltyTree { fn new() -> Self { - RoyaltyTree { tree:Vec::new(), next_entry:0 } + RoyaltyTree { tree:Vec::new(), next_entry:0, spare_change:FiNum::new() } } fn weight_here_below(&self, index:usize) -> FiNum { self.tree[index].weight @@ -151,8 +156,11 @@ impl RoyaltyTree { self.tree[index].acc } fn add_royalty(&mut self, amount: FiNum) { - let ff=self.forefather(); - self.tree[ff].lazy+=amount; + if self.tree.next_entry==0 { self.spare_change+=amount } + else { + let ff=self.forefather(); + if self.weight_here_below(ff).is_zero() { self.spare_change+=amount } else { self.tree[ff].lazy+=amount }; + } } fn add_weight(&mut self, index: usize, weight: FiNum) { if self.tree.len()>0 { @@ -235,12 +243,9 @@ impl Market { royalties: HashMap::new(), royalty_rate: HashMap::new(), }; - rval.register_trader("*NONE*"); + rval.register_trader("*HOUSE*"); rval } - fn number_to_name(&self, n: usize) -> String { - self.assets[n].name.clone() - } fn sanity_check(&self) { println!("Sanity Checking Market..."); for (cur,amt) in self.money_supply.iter() { @@ -276,6 +281,12 @@ impl Market { self.money_supply.insert(self.assets.len()-1,FiNum::new(0)); self.assets.len()-1 } + fn number_to_asset(&self, n: usize) -> Asset { + self.assets[n].clone() + } + fn number_to_name(&self, n: usize) -> String { + self.assets[n].name.clone() + } fn name_to_number(&self, name:&str) -> usize { *self.asset_name2num.get(name).unwrap() } @@ -307,13 +318,22 @@ impl Market { if initial_balanceFiNum::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(); - if sell_qty_initial/buy_qty_initial>=elt.buy_qty/elt.sell_qty { // Transact at ask_rate + if sell_qty0/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; buy_qty-=qty; - let pay_qty=qty*elt.buy_qty/elt.sell_qty; // 1.8499*194623/2.9744 + let pay_qty=qty*elt.buy_qty/elt.sell_qty; self.traders[owner as usize].sub_balance(sell_type,pay_qty); self.traders[owner as usize].add_balance(buy_type ,qty); self.traders[elt.owner as usize].add_balance(sell_type,pay_qty); @@ -325,7 +345,7 @@ impl Market { let ap=(sell_type,buy_type); if let None=self.orders.get_mut(&ap) { self.orders.insert(ap,PQueue::new()); } let bids=self.orders.get_mut(&ap).unwrap(); - let sell_qty_remain=sell_qty_initial*buy_qty/buy_qty_initial; + let sell_qty_remain=sell_qty0*buy_qty/buy_qty_initial; if sell_qty_remain>0.into() { let rt=self.royalties.entry(buy_type).or_insert(RoyaltyTree::new()); rt.add_weight(rt.next_entry,buy_qty); // Weight should really be the quantity you would be able to immediately transact rather than how much you wish for. From 75c5576f93a0ac909f0be2ad49f312165d14b2b3 Mon Sep 17 00:00:00 2001 From: Teppy Date: Wed, 19 Jun 2024 18:38:46 -0400 Subject: [PATCH 12/14] in the middle of adding royalties to make_order --- src/main.rs | 55 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/src/main.rs b/src/main.rs index c9f7779..a5aef50 100644 --- a/src/main.rs +++ b/src/main.rs @@ -314,48 +314,71 @@ impl Market { } fn make_order(&mut self, owner:usize, sell_type:usize, buy_type:usize, sell_qty_initial:FiNum, buy_qty_initial:FiNum) -> bool // Dollars, Bitcoin, 64000, 1 { - let initial_balance=self.traders[owner as usize].get_balance(sell_type); - if initial_balanceFiNum::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(); - if sell_qty0/buy_qty_initial>=elt.buy_qty/elt.sell_qty { // Transact at ask_rate + 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; buy_qty-=qty; let pay_qty=qty*elt.buy_qty/elt.sell_qty; - self.traders[owner as usize].sub_balance(sell_type,pay_qty); - self.traders[owner as usize].add_balance(buy_type ,qty); - self.traders[elt.owner as usize].add_balance(sell_type,pay_qty); - if elt.sell_remain==0.into() { self.orders.get_mut(&ap).unwrap().pop(); } - else { self.orders.get(&ap).unwrap().v[0].borrow_mut().sell_remain-=qty; } + self.traders[owner ].sub_balance(sell_type,pay_qty); + self.traders[owner ].add_balance(buy_type ,qty); + self.traders[elt.owner].add_balance(sell_type,pay_qty); + let rq0=royalty0_qty *pay_qty/sell_qty_initial; + 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; + let rq2=elt.royalty_remain*elt.qty/elt.sell_remain; + let cq2=elt.commission_remain*elt.qty/elt.sell_remain; + royalty_acc+=rq0+rq1; + commission_acc+=cq0+cq1; + self.royalties.entry(sell_type).or_insert(RoyaltyTree::new()).add_royalty(rq0+rq1); + self.orders.get(&ap).unwrap().v[0].borrow_mut().royalty_remain-=rq2; + self.orders.get(&ap).unwrap().v[0].borrow_mut().commission_remain-=cq2; + self.traders[elt.owner].add_balance(rq2); // Sanity check this, too tired to think about it now... + self.traders[0].add_balance(cq2); // ...and this + 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.orders.get_mut(&ap).unwrap().pop(); + } else { + self.orders.get(&ap).unwrap().v[0].borrow_mut().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()); } let bids=self.orders.get_mut(&ap).unwrap(); - let sell_qty_remain=sell_qty0*buy_qty/buy_qty_initial; + let sell_qty_remain=sell_qty*buy_qty/buy_qty_initial; if sell_qty_remain>0.into() { let rt=self.royalties.entry(buy_type).or_insert(RoyaltyTree::new()); rt.add_weight(rt.next_entry,buy_qty); // Weight should really be the quantity you would be able to immediately transact rather than how much you wish for. + // Still to do: add to royalty tree the remaining royalty0+royalty1 amount, and add to the house the remaining commission0+commission1 amounts 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.next_entry } )); rt.next_entry+=1; bids.insert(neworder); - self.traders[owner as usize].sub_balance(sell_type,sell_qty_remain); + self.traders[owner].sub_balance(sell_type,sell_qty_remain); } } + self.traders[0].add_balance(sell_type,royalty_acc+commission_acc); + self.traders[owner].sub_balance(sell_type,royalty_acc+commission_acc); true } } From 724e07b5ed68f714a7724aa18b283e777612c623 Mon Sep 17 00:00:00 2001 From: Teppy Date: Thu, 20 Jun 2024 16:22:08 -0400 Subject: [PATCH 13/14] changes --- src/main.rs | 52 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/src/main.rs b/src/main.rs index a5aef50..f02a7bc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ #![allow(unsafe_code)] #![allow(unused_variables)] #![allow(dead_code)] +use std::io::{self, BufRead}; use std::env; use std::collections::HashMap; use std::cmp::Ordering; @@ -23,6 +24,7 @@ use finum::FiNum; #[derive(Debug, Clone)] struct Trader { name: String, + password: String, // hash(name..salt..password) id: usize, balances: HashMap, // Maps Currency to Amount } @@ -52,6 +54,7 @@ impl Trader { fn new(name:&str,id:usize) -> Self { Trader { name: String::from(name), + password: String::from(""), id: id, balances: HashMap::new() } @@ -98,7 +101,7 @@ impl Royalty { impl RoyaltyTree { fn new() -> Self { - RoyaltyTree { tree:Vec::new(), next_entry:0, spare_change:FiNum::new() } + RoyaltyTree { tree:Vec::new(), next_entry:0, spare_change:FiNum::zero() } } fn weight_here_below(&self, index:usize) -> FiNum { self.tree[index].weight @@ -156,7 +159,7 @@ impl RoyaltyTree { self.tree[index].acc } fn add_royalty(&mut self, amount: FiNum) { - if self.tree.next_entry==0 { self.spare_change+=amount } + if self.next_entry==0 { self.spare_change+=amount } else { let ff=self.forefather(); if self.weight_here_below(ff).is_zero() { self.spare_change+=amount } else { self.tree[ff].lazy+=amount }; @@ -320,16 +323,13 @@ impl Market { let mut royalty1_qty=asset.royalty1_rate*sell_qty_initial; let mut commission0_qty=asset.commission0_rate*sell_qty_initial; let mut commission1_qty=asset.commission1_rate*sell_qty_initial; - let sell_qty_plus=sell_qty_initial+royalty0+royalty1+commission0+commission1; // This is the maximum amount we are going to sell - let mut sell_qty=sell_qty_initial; + let sell_qty_plus=sell_qty_initial+royalty0_qty+royalty1_qty+commission0_qty+commission1_qty; // This is the maximum amount we are going to sell + let sell_qty=sell_qty_initial; if initial_balanceFiNum::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(); if sell_qty/buy_qty_initial>=elt.buy_qty/elt.sell_qty { // Transact at ask_rate @@ -344,17 +344,23 @@ 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; - let rq2=elt.royalty_remain*elt.qty/elt.sell_remain; - let cq2=elt.commission_remain*elt.qty/elt.sell_remain; + let rq2=elt.royalty_remain*qty/elt.sell_remain; + let cq2=elt.commission_remain*qty/elt.sell_remain; royalty_acc+=rq0+rq1; commission_acc+=cq0+cq1; + royalty0_qty-=rq0; + royalty1_qty-=rq1; + commission0_qty-=cq0; + 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; - self.traders[elt.owner].add_balance(rq2); // Sanity check this, too tired to think about it now... - self.traders[0].add_balance(cq2); // ...and this + 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.orders.get_mut(&ap).unwrap().pop(); } else { self.orders.get(&ap).unwrap().v[0].borrow_mut().sell_remain-=qty; @@ -369,9 +375,9 @@ impl Market { if sell_qty_remain>0.into() { let rt=self.royalties.entry(buy_type).or_insert(RoyaltyTree::new()); rt.add_weight(rt.next_entry,buy_qty); // Weight should really be the quantity you would be able to immediately transact rather than how much you wish for. - // Still to do: add to royalty tree the remaining royalty0+royalty1 amount, and add to the house the remaining commission0+commission1 amounts + // Still to do: add to royalty tree the remaining royalty0 amount, and add to the house the remaining commission0 amounts, and then add royalty1 and commission1 to the Order 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.next_entry } )); + Order { owner:owner, sell_qty:sell_qty_remain, sell_remain:sell_qty_remain, buy_qty:buy_qty, rt_loc: rt.next_entry, royalty_remain:royalty0_qty, commission_remain:commission0_qty } )); rt.next_entry+=1; bids.insert(neworder); self.traders[owner].sub_balance(sell_type,sell_qty_remain); @@ -567,12 +573,30 @@ fn royalty_stuff() { } } +fn process_file(fname: &str) { + println!("Processing file: {}",fname) + } + +fn interactive() { + let stdin = io::stdin(); + for line in stdin.lock().lines() { + if let Ok(input) = line { + let words: Vec<&str> = input.split_whitespace().collect(); + match line { + "quit" => break, + _ => println!("Unknown Command"), + } + } + } + } + fn main() { let args: Vec = env::args().collect(); - let mode=if args.len()<=1 { "--exercise" } else { args[1].as_str() }; + let mode=if args.len()<=1 { "--interactive" } else { args[1].as_str() }; let mut m=Market::new(); // USD type is 1, EUR type is 2, BTC type is 10, ETH type is 11, zKN6FBdD SOL type is 12 match mode { + "--interactive" => interactive(), "--exercise" => m.exercise(), "--treestuff" => tree_stuff(), "--royaltystuff" => royalty_stuff(), From d7e08df9a9aaaab78821b3939bdc0cb20b90c43d Mon Sep 17 00:00:00 2001 From: Teppy Date: Sun, 23 Jun 2024 18:50:48 -0400 Subject: [PATCH 14/14] changes --- src/main.rs | 89 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 73 insertions(+), 16 deletions(-) diff --git a/src/main.rs b/src/main.rs index f02a7bc..5a4da2d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -278,11 +278,13 @@ impl Market { self.traders[who as usize].sub_balance(cur,delta); *self.money_supply.get_mut(&cur).unwrap()-=delta; } - fn register_asset(&mut self, name:&str) -> usize { + fn register_asset(&mut self, name:&str) -> Option { + if self.asset_name2num.contains_key(name) { return None } self.assets.push(Asset::new(name)); self.asset_name2num.insert(String::from(name),self.assets.len()-1); self.money_supply.insert(self.assets.len()-1,FiNum::new(0)); - self.assets.len()-1 + let rval=self.assets.len()-1; + Some(rval) } fn number_to_asset(&self, n: usize) -> Asset { self.assets[n].clone() @@ -290,8 +292,8 @@ impl Market { fn number_to_name(&self, n: usize) -> String { self.assets[n].name.clone() } - fn name_to_number(&self, name:&str) -> usize { - *self.asset_name2num.get(name).unwrap() + fn name_to_number(&self, name:&str) -> Option<&usize> { + self.asset_name2num.get(name) } fn dump(&self) { println!("Dumping Market:"); @@ -373,17 +375,18 @@ impl Market { 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() { + self.royalties.entry(sell_type).or_insert(RoyaltyTree::new()).add_royalty(royalty0_qty); let rt=self.royalties.entry(buy_type).or_insert(RoyaltyTree::new()); rt.add_weight(rt.next_entry,buy_qty); // Weight should really be the quantity you would be able to immediately transact rather than how much you wish for. - // Still to do: add to royalty tree the remaining royalty0 amount, and add to the house the remaining commission0 amounts, and then add royalty1 and commission1 to the Order 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.next_entry, royalty_remain:royalty0_qty, commission_remain:commission0_qty } )); + Order { owner:owner, sell_qty:sell_qty_remain, sell_remain:sell_qty_remain, buy_qty:buy_qty, rt_loc: rt.next_entry, royalty_remain:royalty1_qty, commission_remain:commission1_qty } )); rt.next_entry+=1; bids.insert(neworder); self.traders[owner].sub_balance(sell_type,sell_qty_remain); + self.traders[0].add_balance(sell_type,commission0_qty); } } - self.traders[0].add_balance(sell_type,royalty_acc+commission_acc); + self.traders[0].add_balance(sell_type,commission_acc); self.traders[owner].sub_balance(sell_type,royalty_acc+commission_acc); true } @@ -471,8 +474,8 @@ impl Market { let mut rng: StdRng=StdRng::seed_from_u64(13u64); let teppy=self.register_trader("Teppy"); let luni =self.register_trader("Luni"); - let usd =self.register_asset("USD"); - let btc =self.register_asset("BTC"); + let usd =self.register_asset("USD").unwrap(); + let btc =self.register_asset("BTC").unwrap(); self.add_trader_balance(teppy,btc,100000.into()); self.add_trader_balance(luni ,usd,650000000.into()); let mut count=0; @@ -577,18 +580,72 @@ fn process_file(fname: &str) { println!("Processing file: {}",fname) } -fn interactive() { + +fn interactive(m: &mut Market) { + println!("Trading interactively in Tuesday Markets (demo)"); let stdin = io::stdin(); + let mut trader:usize=0; for line in stdin.lock().lines() { - if let Ok(input) = line { - let words: Vec<&str> = input.split_whitespace().collect(); - match line { - "quit" => break, - _ => println!("Unknown Command"), + match line { + Ok(input) => { + let tokens: Vec<&str> = input.split_whitespace().collect(); + match tokens.as_slice() { + ["dump"] => m.dump(), + ["login", username] => + if let Some(t)=m.trader_name2num.get_mut(*username) { trader=*t; println!("Logged in as {}",m.traders[trader].name) } else { println!("Trader {} not found.",username) }, + ["whoami" ] => { println!("Logged in as {}, id {}",m.traders[trader].name,trader ); } + ["addtrader", username] => { let id=m.register_trader(username); println!("Added user {} as id {}",username,id); }, + ["balances"] => { + println!("Balances for trader {}",m.traders[trader].name); + for (key,value) in &m.traders[trader].balances { println!(" {} {}",m.number_to_name(*key),value); } + } + ["addasset", assetname] => { + if let Some(cur)=m.register_asset(assetname) { println!("Added asset {} ",m.number_to_name(cur)) } + else { println!("Asset {} already exists.",assetname) } + } + ["addfunds", username, qty0, cur0 ] => { + let id=m.trader_name2num.get(*username); + let qty=FiNum::new_str(qty0); + let cur=m.name_to_number(cur0); + if id.is_none() { println!("Could not find trader {}",username); } + else if qty.is_zero() { println!("Could not parse quantity {}",qty0) } + else if cur.is_none() { println!("Could not find asset {}",cur0) } + else { + let id=*id.unwrap(); + let cur=*cur.unwrap(); + m.add_trader_balance(id,cur,qty); + println!("Added {} {} to {}",qty,m.number_to_asset(cur).name,m.traders[id].name) + } + } + ["order", qty0, cur0, qty1, cur1 ] => { + 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); + if !qty0.is_zero() && cur0.is_some() && !qty1.is_zero() && cur1.is_some() { + m.make_order(trader,*cur0.unwrap(),*cur1.unwrap(),qty0,qty1); + } + } + ["quit"] => { + break; + } + _ => println!("Invalid command. Please try again."), } } + Err(error) => println!("Error reading input: {}", error), } } +} + +fn erase(filename: &str) { + // Stub function for erasing a file + println!("Erasing file: {}", filename); +} + +fn copy(source: &str, destination: &str) { + // Stub function for copying a file + println!("Copying file from {} to {}", source, destination); +} fn main() { @@ -596,7 +653,7 @@ fn main() { let mode=if args.len()<=1 { "--interactive" } else { args[1].as_str() }; let mut m=Market::new(); // USD type is 1, EUR type is 2, BTC type is 10, ETH type is 11, zKN6FBdD SOL type is 12 match mode { - "--interactive" => interactive(), + "--interactive" => interactive(&mut m), "--exercise" => m.exercise(), "--treestuff" => tree_stuff(), "--royaltystuff" => royalty_stuff(),