This commit is contained in:
2024-06-18 19:19:25 -04:00
parent f5ece41880
commit c67b56fb1e

View File

@@ -27,6 +27,7 @@ struct Trader {
balances: HashMap<usize,FiNum>, // 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<Royalty>,
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_balance<sell_qty_initial { return false; }
let mut buy_qty=buy_qty_initial;
let ap=(buy_type,sell_type);
let asset=self.number_to_asset(sell_type);
let mut royalty0_qty=asset.royalty0_rate*sell_qty_initial;
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_qty0=sell_qty_initial-royalty0_qty-royalty1_qty-commission0_qty-commission1_qty;
self.royalties.entry(sell_type).or_insert(RoyaltyTree::new()).add_royalty(royalty0_qty);
self.traders[0].add_balance(sell_type,commission0_qty);
self.traders[owner as usize].sub_balance(sell_type,royalty0_qty+commission0_qty);
while 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();
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.