This commit is contained in:
2025-01-13 13:34:26 -05:00
parent 05d52a26d1
commit 4250598a5f
12 changed files with 194 additions and 33 deletions

13
13.log Normal file
View File

@@ -0,0 +1,13 @@
AF 2 1 14F0117759
AF 1 1 1D1E0D15FF
AF 2 1 70D4B3855
OR 2 0 22E869AB9A 1 2327CD75D7
AF 2 1 12F54589D1
AF 1 0 16EC0573FE
AF 3 1 1DBA3B2F64
AF 1 0 22A45121F2
AF 3 0 BDB8CCB60
OR 2 0 21CDCD2B81 1 2407EB5978
AF 3 1 24E1249869
OR 3 0 231B497C77 1 7C6A3D844
OR 1 1 161753A88E 0 21069FA53A

11
demo1.log Normal file
View File

@@ -0,0 +1,11 @@
AT Teppy
AT Luni
AT Hamza
AA USD
AA BTC
SR 0 51EB851 0 0 0
SR 1 51EB851 0 0 0
AF 1 1 500000000
AF 2 0 3D09000000000
AF 3 0 3D09000000000
OR 1 1 100000000 0 C35000000000

11
demo13.log Normal file
View File

@@ -0,0 +1,11 @@
AT Teppy
AT Hamza
AA USD
AA BTC
SR 0 0 0 0 33333333
SR 1 0 0 0 33333333
AF 1 1 500000000
AF 2 0 3D09000000000
AF 1 1 1D1E0D15FF
OR 2 0 231B497C77 1 7C6A3D844
OR 1 1 161753A88E 0 21069FA53A

12
demo13x.log Normal file
View File

@@ -0,0 +1,12 @@
AT Teppy
AT Hamza
AA USD
AA BTC
NOP SR 0 0 0 33333333 33333333
NOP SR 1 0 0 33333333 33333333
SR 0 11111111 22222222 33333333 44444444
SR 1 18888888 28888888 38888888 48888888
AF 1 1 400000000
AF 2 0 3D09000000000
OR 2 0 2800000000 1 100000000
OR 1 1 100000000 0 1900000000

11
demo2.log Normal file
View File

@@ -0,0 +1,11 @@
AT Teppy
AT Luni
AT Hamza
AA USD
AA BTC
SR 0 0 28F5C28 0 0
SR 1 0 28F5C28 0 0
AF 1 1 500000000
AF 2 0 3D09000000000
AF 3 0 3D09000000000
OR 1 1 100000000 0 C35000000000

11
demo3.log Normal file
View File

@@ -0,0 +1,11 @@
AT Teppy
AT Luni
AT Hamza
AA USD
AA BTC
SR 0 0 0 33333333 0
SR 1 0 0 33333333 0
AF 1 1 500000000
AF 2 0 3D09000000000
AF 3 0 3D09000000000
OR 1 1 100000000 0 C35000000000

11
demo4.log Normal file
View File

@@ -0,0 +1,11 @@
AT Teppy
AT Luni
AT Hamza
AA USD
AA BTC
SR 0 0 0 0 19999999
SR 1 0 0 0 19999999
AF 1 1 500000000
AF 2 0 3D09000000000
AF 3 0 3D09000000000
OR 1 1 100000000 0 C35000000000

View File

@@ -3,9 +3,9 @@ AT Luni
AT Hamza AT Hamza
AA USD AA USD
AA BTC AA BTC
SR 0 51EB851 28F5C28 33333333 19999999
SR 1 51EB851 28F5C28 33333333 19999999 SR 1 51EB851 28F5C28 33333333 19999999
AF 1 1 500000000 AF 1 1 500000000
AF 2 0 3D09000000000 AF 2 0 3D09000000000
AF 3 0 3D09000000000 AF 3 0 3D09000000000
SR 0 51EB851 28F5C28 33333333 19999999
OR 1 1 100000000 0 C35000000000 OR 1 1 100000000 0 C35000000000

11
demoy.log Normal file
View File

@@ -0,0 +1,11 @@
AT Teppy
AT Luni
AT Hamza
AA USD
AA BTC
SR 0 51EB851 28F5C28 33333333 19999999
SR 1 51EB851 28F5C28 33333333 19999999
AF 1 1 500000000
AF 2 0 3D09000000000
AF 3 0 3D09000000000
OR 1 1 100000000 0 C35000000000

10
demoz.log Normal file
View File

@@ -0,0 +1,10 @@
AT Teppy
AT Luni
AT Hamza
AA USD
AA BTC
SR 0 51EB851 28F5C28 33333333 19999999
SR 1 51EB851 28F5C28 33333333 19999999
AF 1 1 500000000
AF 2 0 3D09000000000
AF 3 0 3D09000000000

View File

@@ -36,6 +36,9 @@ impl FiNum {
pub fn recip(&self) -> Self { pub fn recip(&self) -> Self {
FiNum((0x8000000000000000u64/self.0)<<1) FiNum((0x8000000000000000u64/self.0)<<1)
} }
pub fn fmt_pct2(&self) -> String {
format!("{:>5.2}%", (100.0*(self.0 as f64))/((1u64<<32) as f64))
}
pub fn fmt_recip(&self) -> String { pub fn fmt_recip(&self) -> String {
if *self<FiNum::one() { format!("1/{}",self.recip()) } if *self<FiNum::one() { format!("1/{}",self.recip()) }
else { format!("{}",self) } else { format!("{}",self) }
@@ -120,6 +123,7 @@ impl Div for FiNum {
impl std::fmt::Display for FiNum { impl std::fmt::Display for FiNum {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
// write!(f, "{:08X}.{:08X}", self.0>>32,self.0&0xFFFFFFFF)
write!(f, "{:.8}", (self.0 as f64)/((1u64<<32) as f64)) write!(f, "{:.8}", (self.0 as f64)/((1u64<<32) as f64))
} }
} }

View File

@@ -50,6 +50,8 @@ use std::collections::HashMap;
use std::cmp::Ordering; use std::cmp::Ordering;
use rand::prelude::*; use rand::prelude::*;
use rand::rngs::StdRng; use rand::rngs::StdRng;
use std::time::Instant;
//use hashbrown::HashMap; //use hashbrown::HashMap;
mod finum; mod finum;
use finum::FiNum; use finum::FiNum;
@@ -110,8 +112,8 @@ struct Order {
sell_qty: FiNum, sell_qty: FiNum,
sell_remain: FiNum, sell_remain: FiNum,
buy_qty: FiNum, buy_qty: FiNum,
royalty_remain: FiNum, // Based on royalty1 royalty_remain: FiNum, // Based on royalty1. The thing that is being sold
commission_remain: FiNum, // Based on commission1 commission_remain: FiNum, // Based on commission1. The thing that is being sold
owner: usize, owner: usize,
order_id: usize, order_id: usize,
} }
@@ -200,17 +202,14 @@ impl RoyaltyTree {
self.tree[index].lazy=FiNum::zero(); self.tree[index].lazy=FiNum::zero();
} else { } else {
let lazy=self.tree[index].lazy; let lazy=self.tree[index].lazy;
// println!("Index is {}, lazy.0 {}",index,lazy.serialize());
// self.raw_dump();
let d1=if lazy>0.into() { lazy*self.weight_here(index)/self.weight_here_below(index) } else { FiNum::zero() }; let d1=if lazy>0.into() { lazy*self.weight_here(index)/self.weight_here_below(index) } else { FiNum::zero() };
let d02=lazy-d1; let d02=lazy-d1;
let index_left =wt_left (index).unwrap(); let index_left =wt_left (index).unwrap();
let index_right=wt_right(index).unwrap(); let index_right=wt_right(index).unwrap();
// println!("D02 is {}, self.weight_here_below({}) is {}, self.weight_below({}) is {}",d02.serialize(),index_left,self.weight_here_below(index_left),index,self.weight_below(index));
if self.weight_below(index)>0.into() { if self.weight_below(index)>0.into() {
let d0=if d02>0.into() { d02*self.weight_here_below(index_left)/self.weight_below(index) } else { FiNum::zero() }; let d0=if d02>0.into() { d02*self.weight_here_below(index_left)/self.weight_below(index) } else { FiNum::zero() };
let d2=d02-d0; let d2=d02-d0;
self.sanity(); // self.sanity();
if !self.weight_here_below(index_left ).is_zero() { self.tree[index_left ].lazy+=d0; } else { self.spare_change+=d0; } if !self.weight_here_below(index_left ).is_zero() { self.tree[index_left ].lazy+=d0; } else { self.spare_change+=d0; }
if !self.weight_here_below(index_right).is_zero() { self.tree[index_right].lazy+=d2; } else { self.spare_change+=d2; } if !self.weight_here_below(index_right).is_zero() { self.tree[index_right].lazy+=d2; } else { self.spare_change+=d2; }
} }
@@ -220,7 +219,6 @@ impl RoyaltyTree {
self.tree[index].acc+=d1; self.tree[index].acc+=d1;
self.tree[index].lazy=FiNum::zero(); self.tree[index].lazy=FiNum::zero();
} }
// println!("Royalty at {} is {}",index,self.tree[index].acc);
self self
} }
fn sanity(&self) { fn sanity(&self) {
@@ -243,7 +241,10 @@ impl RoyaltyTree {
if self.next_entry==0 || FiNum::is_zero(self.tree[self.forefather()].weight) { self.spare_change+=amount } if self.next_entry==0 || FiNum::is_zero(self.tree[self.forefather()].weight) { self.spare_change+=amount }
else { else {
let ff=self.forefather(); let ff=self.forefather();
if self.weight_here_below(ff).is_zero() { self.spare_change+=amount } else { self.tree[ff].lazy+=amount }; if self.weight_here_below(ff).is_zero() { self.spare_change+=amount } else {
self.tree[ff].lazy+=amount+self.spare_change;
self.spare_change=FiNum::zero()
};
} }
} }
// We really need two methods: remove an order and redistribute, remove some and return captured amount // We really need two methods: remove an order and redistribute, remove some and return captured amount
@@ -302,7 +303,6 @@ impl RoyaltyTree {
self.expand_to(ff1*2); self.expand_to(ff1*2);
while ff0<ff1 { while ff0<ff1 {
ff0=wt_parent(ff0); ff0=wt_parent(ff0);
println!("Setting self.tree[{}].weight to {} and count to {}",ff0,w,c);
self.tree[ff0].weight=w; self.tree[ff0].weight=w;
self.tree[ff0].count=c; self.tree[ff0].count=c;
} }
@@ -392,14 +392,34 @@ impl Market {
println!("Sanity Checking Market..."); println!("Sanity Checking Market...");
for (cur,amt) in self.money_supply.iter() { for (cur,amt) in self.money_supply.iter() {
println!("Money Supply {}: {}",self.number_to_name(*cur),*amt); println!("Money Supply {}: {}",self.number_to_name(*cur),*amt);
let mut acc_orders=FiNum::new(0); let mut off_orders=FiNum::new(0);
let mut off_roy=FiNum::new(0);
let mut off_com=FiNum::new(0);
for (ac,pq) in &self.orders { if ac.0==*cur { for (ac,pq) in &self.orders { if ac.0==*cur {
for off in &*pq.v { acc_orders+=off.sell_remain; } for off in &*pq.v {
off_orders+=off.sell_remain;
off_roy +=off.royalty_remain;
off_com +=off.commission_remain;
}
} } } }
let mut acc_traders=FiNum::new(0); let mut acc_traders=FiNum::new(0);
for t in &self.traders { acc_traders+=t.get_balance(*cur); } let mut ntraders=0;
let acc=acc_orders+acc_traders; for t in &self.traders {
println!(" {}: Orders {} Traders {} Total {} Should Be {}",self.number_to_name(*cur),acc_orders,acc_traders,acc,*amt); let b=t.get_balance(*cur);
if !b.is_zero() { ntraders+=1 }
acc_traders+=b;
}
let ar = self.royalties.get(cur).map(|rt| rt.acc_total()).unwrap_or(FiNum::zero());
let sc = self.royalties.get(cur).map(|rt| rt.spare_change).unwrap_or(FiNum::zero());
let acc=acc_traders+off_orders+off_roy+off_com+ar+sc;
println!(" Traders {}",acc_traders);
println!(" Orders {}",off_orders);
println!(" Royalties in Orders {}",off_roy);
println!(" Commissions in Orders {}",off_com);
println!(" Accumulated Royalties {}",ar);
println!(" Spare Change Royalties {}",sc);
println!(" Total from Above {}",acc);
println!(" Total from Money Supply {} {}",*amt,if *amt!=acc { " Mismatch!" } else { "" });
} }
} }
fn random_order_id(&mut self) -> Option<usize> { fn random_order_id(&mut self) -> Option<usize> {
@@ -468,12 +488,12 @@ impl Market {
let rt=self.royalties.get_mut(&ap.1).unwrap(); let rt=self.royalties.get_mut(&ap.1).unwrap();
let indexr=rt.order_finder.get(&off.order_id).unwrap(); let indexr=rt.order_finder.get(&off.order_id).unwrap();
let royalty_amt=rt.get_royalty(*indexr); let royalty_amt=rt.get_royalty(*indexr);
println!(" {} @ {} ({}) OrderID: {} Royalties: {}", println!(" {} @ {} ({}) OrderID: {} Royalties Accumulated: {} Royalties Offered {} Commissions Offered: {}",
off.sell_remain, // off.buy_qty*off.sell_remain/off.sell_qty, off.sell_remain, // off.buy_qty*off.sell_remain/off.sell_qty,
(off.buy_qty/off.sell_qty).fmt_recip(), (off.buy_qty/off.sell_qty).fmt_recip(),
self.traders[off.owner as usize].name, self.traders[off.owner as usize].name,
off.order_id, off.order_id,
royalty_amt); royalty_amt,off.royalty_remain,off.commission_remain);
} }
} }
println!("Royalty Accum SpareChange"); println!("Royalty Accum SpareChange");
@@ -515,6 +535,7 @@ impl Market {
let cmd=Command::deserialize(line); let cmd=Command::deserialize(line);
if let Command::NOP(comment)=cmd { println!("{}",comment); } if let Command::NOP(comment)=cmd { println!("{}",comment); }
else { else {
println!("{}",cmd.explain(self));
let res=self.execute(&cmd); let res=self.execute(&cmd);
println!("{}",res.describe()); println!("{}",res.describe());
} }
@@ -549,11 +570,14 @@ impl Market {
Result::ExecutedBatch(log) Result::ExecutedBatch(log)
} }
*/ */
fn retract_order(&mut self, order_id:usize) -> Result { // Still need to credit back funds! But first fix the bug where we are creating commission0 from thin air in make_order (not charging seller) fn retract_order(&mut self, order_id:usize) -> Result { // Still need to credit back funds!
let pair=self.order_finder.get(&order_id).unwrap(); let pair=self.order_finder.get(&order_id).unwrap();
let sell_type=pair.0;
let queue=self.orders.get_mut(pair).unwrap(); let queue=self.orders.get_mut(pair).unwrap();
let queue_index=*queue.order_finder.get(&order_id).unwrap(); let queue_index=*queue.order_finder.get(&order_id).unwrap();
let order=&queue.v[queue_index]; let order=&queue.v[queue_index];
let credit=order.sell_remain+order.royalty_remain+order.commission_remain;
self.traders[order.owner].add_balance(sell_type,credit);
println!("Order owner is {}",order.owner); println!("Order owner is {}",order.owner);
// Remove from royalties // Remove from royalties
let rt=self.royalties.get_mut(&pair.0).unwrap(); let rt=self.royalties.get_mut(&pair.0).unwrap();
@@ -582,10 +606,9 @@ impl Market {
let mut commission_acc=FiNum::zero(); let mut commission_acc=FiNum::zero();
let new_order_id:usize; 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 { 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].clone(); let 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 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); let qty=std::cmp::min(elt.sell_remain,buy_qty);
elt.sell_remain-=qty;
buy_qty-=qty; buy_qty-=qty;
let pay_qty=qty*elt.buy_qty/elt.sell_qty; let pay_qty=qty*elt.buy_qty/elt.sell_qty;
self.traders[owner ].sub_balance(sell_type,pay_qty); self.traders[owner ].sub_balance(sell_type,pay_qty);
@@ -600,6 +623,7 @@ impl Market {
//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); //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 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() }; let cq2=if !elt.sell_remain.is_zero() { elt.commission_remain*qty/elt.sell_remain } else { FiNum::zero() };
//elt.sell_remain-=qty;
royalty_acc+=rq0+rq1; royalty_acc+=rq0+rq1;
commission_acc+=cq0+cq1; commission_acc+=cq0+cq1;
royalty0_qty-=rq0; royalty0_qty-=rq0;
@@ -609,17 +633,23 @@ impl Market {
self.royalties.entry(sell_type).or_insert(RoyaltyTree::new()).add_royalty(rq0+rq1); 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.royalties.entry(buy_type) .or_insert(RoyaltyTree::new()).add_royalty(rq2);
let top_order=self.orders.get_mut(&ap).unwrap().peek(); 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.royalty_remain-=rq2;
top_order.commission_remain-=cq2; 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); self.traders[0].add_balance(buy_type,cq2);
if elt.sell_remain==0.into() { // deal with pennies stored in royalty_remain and commission_remain if elt.sell_remain==qty { // deal with pennies stored in royalty_remain and commission_remain
self.traders[0].add_balance(buy_type,top_order.commission_remain); //if !top_order.commission_remain.is_zero() { println!("Little commission? {} ",top_order.commission_remain); }
self.royalties.entry(buy_type).or_insert(RoyaltyTree::new()).add_royalty(top_order.royalty_remain); let rq3=top_order.royalty_remain;
self.royalties.get_mut(&sell_type).unwrap().remove_order_id(top_order.order_id); let cq3=top_order.commission_remain;
self.royalties.get_mut(&buy_type).unwrap().remove_order_id(top_order.order_id);
self.order_finder.remove(&top_order.order_id); self.order_finder.remove(&top_order.order_id);
self.traders[top_order.owner].order_finder.remove(&top_order.order_id); self.traders[top_order.owner].order_finder.remove(&top_order.order_id);
self.orders.get_mut(&ap).unwrap().pop(); // This removes id (which is stored as part of the Order) from self.order's finder self.orders.get_mut(&ap).unwrap().pop(); // This removes id (which is stored as part of the Order) from self.order's finder
self.order_count-=1; self.order_count-=1;
self.traders[0].add_balance(buy_type,cq3);
self.royalties.entry(buy_type).or_insert(RoyaltyTree::new()).add_royalty(rq3);
} else { } else {
top_order.sell_remain-=qty; top_order.sell_remain-=qty;
} }
@@ -637,8 +667,8 @@ impl Market {
self.next_order_id+=1; self.next_order_id+=1;
// Pay royalties to existing orders on the sell size // Pay royalties to existing orders on the sell size
self.royalties.entry(sell_type).or_insert(RoyaltyTree::new()).add_royalty(royalty0_qty+royalty1_qty); self.royalties.entry(sell_type).or_insert(RoyaltyTree::new()).add_royalty(royalty0_qty);
royalty_acc+=royalty0_qty+royalty1_qty; royalty_acc+=royalty0_qty;
// Create a new entry in the RoyaltyTree to accumulate for this Order // Create a new entry in the RoyaltyTree to accumulate for this Order
let rt=self.royalties.entry(buy_type).or_insert(RoyaltyTree::new()); let rt=self.royalties.entry(buy_type).or_insert(RoyaltyTree::new());
@@ -649,15 +679,18 @@ impl Market {
// Insert the new order in the priority queue (OrderQueue) // Insert the new order in the priority queue (OrderQueue)
let neworder=Order { owner:owner, sell_qty:sell_qty_remain, sell_remain:sell_qty_remain, buy_qty:buy_qty, royalty_remain:royalty1_qty, commission_remain:commission1_qty, order_id:id }; let neworder=Order { owner:owner, sell_qty:sell_qty_remain, sell_remain:sell_qty_remain, buy_qty:buy_qty, royalty_remain:royalty1_qty, commission_remain:commission1_qty, order_id:id };
bids.insert(neworder); bids.insert(neworder);
royalty_acc+=royalty1_qty;
commission_acc+=commission1_qty;
self.order_count+=1; self.order_count+=1;
self.order_finder.insert(id,(sell_type,buy_type)); self.order_finder.insert(id,(sell_type,buy_type));
self.traders[owner].sub_balance(sell_type,sell_qty_remain); self.traders[owner].sub_balance(sell_type,sell_qty_remain);
commission_acc+=commission0_qty+commission1_qty; self.traders[owner].sub_balance(sell_type,commission0_qty);
self.traders[0].add_balance(sell_type,commission0_qty);
self.traders[owner].order_finder.insert(id,(sell_type,buy_type)); self.traders[owner].order_finder.insert(id,(sell_type,buy_type));
log.push(format!("Moved {} {} ({}) to market",sell_qty_remain,self.number_to_name(sell_type),self.traders[owner].name)); log.push(format!("Moved {} {} ({}) to market",sell_qty_remain,self.number_to_name(sell_type),self.traders[owner].name));
} }
} }
self.traders[0].add_balance(sell_type,commission_acc); // self.traders[0].add_balance(sell_type,commission_acc);
self.traders[owner].sub_balance(sell_type,royalty_acc+commission_acc); self.traders[owner].sub_balance(sell_type,royalty_acc+commission_acc);
log.push(format!("Paid {} {} in royalties and {} {} ({}) in commissions",royalty_acc ,self.number_to_name(sell_type), log.push(format!("Paid {} {} in royalties and {} {} ({}) in commissions",royalty_acc ,self.number_to_name(sell_type),
commission_acc,self.number_to_name(sell_type),self.traders[owner].name)); commission_acc,self.number_to_name(sell_type),self.traders[owner].name));
@@ -947,6 +980,28 @@ impl Command {
_ => format!("NOP (This should never happen)"), _ => format!("NOP (This should never happen)"),
} }
} }
fn explain(&self, m: &Market) -> String {
match self {
Self::AddTrader { user: name } => format!("addtrader {}",name),
Self::AddAsset { asset: name } => format!("addasset {}",name),
Self::SetRoyalty { asset_id, roy0, com0 , roy1 , com1 }
=> format!("setroyalty {} {} {} {} {}",m.number_to_name(*asset_id),roy0,com0,roy1,com1),
Self::AddFunds { user_id, asset_id, amt }
=> format!("addfunds {} {} {}",m.traders[*user_id].name,m.number_to_name(*asset_id),amt),
Self::SubFunds { user_id, asset_id , amt }
=> format!("subfunds {} {} {}",m.traders[*user_id].name,m.number_to_name(*asset_id),amt),
Self::Order { user_id, sell_type, sell_qty, buy_type, buy_qty }
=> format!("order {} {} {} {} (as {})",sell_qty,m.number_to_name(*sell_type),buy_qty,m.number_to_name(*buy_type),m.traders[*user_id].name),
Self::OrderBatch { user_id, sell_type, sell_qty, buy_type, buy_qty }
=> format!("orderbatch {} {} {} {} (as {})",sell_qty,m.number_to_name(*sell_type),buy_qty,m.number_to_name(*buy_type),m.traders[*user_id].name),
Self::ExecuteBatch { asset_type0, strike0, asset_type1, strike1 }
=> format!("executebatch {} {} {} {}",strike0,m.number_to_name(*asset_type0),strike1,m.number_to_name(*asset_type1)),
Self::RetractOrder { order_id } => format!("retract {}",order_id),
Self::Error(str) => format!("NOP Error: {}",str),
Self::NOP(str) => format!("NOP {}",clean(str)),
_ => format!("NOP (This should never happen)"),
}
}
fn deserialize(line: String) -> Self { fn deserialize(line: String) -> Self {
let tokens: Vec<&str> = line.split_whitespace().collect(); let tokens: Vec<&str> = line.split_whitespace().collect();
match tokens.as_slice() { match tokens.as_slice() {
@@ -1010,21 +1065,18 @@ impl Market {
Command::SetRoyalty { asset_id,roy0,com0,roy1,com1 } => { Command::SetRoyalty { asset_id,roy0,com0,roy1,com1 } => {
if *roy0+*com0+*roy1+*com1<FiNum::new_i32(1) { if *roy0+*com0+*roy1+*com1<FiNum::new_i32(1) {
self.set_royalty(*asset_id,*roy0,*com0,*roy1,*com1); self.set_royalty(*asset_id,*roy0,*com0,*roy1,*com1);
println!("Set royalty for {} to {} {} {} {}",asset_id,roy0,com0,roy1,com1);
Result::Ok Result::Ok
} }
else { Result::Error(format!("Sum of royalties and commissions should be less than 1.00")) } else { Result::Error(format!("Sum of royalties and commissions should be less than 1.00")) }
} }
Command::AddFunds{ user_id, asset_id, amt } => { Command::AddFunds{ user_id, asset_id, amt } => {
self.add_trader_balance(*user_id,*asset_id,*amt); self.add_trader_balance(*user_id,*asset_id,*amt);
// println!("Added {} {} to {}",*amt,self.number_to_asset(*asset_id).name,self.traders[*user_id].name);
Result::FundsRemaining(self.get_trader_balance(*user_id,*asset_id)) Result::FundsRemaining(self.get_trader_balance(*user_id,*asset_id))
} }
Command::SubFunds { user_id,asset_id,amt } => { Command::SubFunds { user_id,asset_id,amt } => {
if *amt>self.get_trader_balance(*user_id,*asset_id) { Result::Error(format!("Not enough {} in {}",asset_id,user_id)) } if *amt>self.get_trader_balance(*user_id,*asset_id) { Result::Error(format!("Not enough {} in {}",asset_id,user_id)) }
else { else {
self.sub_trader_balance(*user_id,*asset_id,*amt); self.sub_trader_balance(*user_id,*asset_id,*amt);
println!("Subtracted {} {} from {}",*amt,self.number_to_asset(*asset_id).name,self.traders[*user_id].name);
Result::FundsRemaining(self.get_trader_balance(*user_id,*asset_id)) Result::FundsRemaining(self.get_trader_balance(*user_id,*asset_id))
} }
} }
@@ -1161,7 +1213,8 @@ fn interactive(m: &mut Market, mut out: Option<File>) {
Ok(input) => { Ok(input) => {
let tokens: Vec<&str> = input.split_whitespace().collect(); let tokens: Vec<&str> = input.split_whitespace().collect();
let cmd:Command=match tokens.as_slice() { let cmd:Command=match tokens.as_slice() {
["dump"] => { m.dump(); m.sanity_check(); Command::None }, ["dump"] => { m.dump(); Command::None },
["sanity"] => { m.sanity_check(); Command::None },
["randomorder"] => { println!("Random OrderID: {:?}",m.random_order_id()); Command::None } ["randomorder"] => { println!("Random OrderID: {:?}",m.random_order_id()); Command::None }
["login", username] => { ["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) } 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) }
@@ -1198,6 +1251,7 @@ fn interactive(m: &mut Market, mut out: Option<File>) {
} }
["randomcommands", qty] => { ["randomcommands", qty] => {
let qty:u32=qty.parse().unwrap(); let qty:u32=qty.parse().unwrap();
let start = Instant::now();
for i in 0..qty { for i in 0..qty {
let cmd=m.random_command(); let cmd=m.random_command();
// println!("RandomCommand #{}: {}",1+i,cmd.serialize()); // println!("RandomCommand #{}: {}",1+i,cmd.serialize());
@@ -1210,6 +1264,8 @@ fn interactive(m: &mut Market, mut out: Option<File>) {
let res=m.execute(&cmd); let res=m.execute(&cmd);
// println!("Result: {}",res.describe()); // println!("Result: {}",res.describe());
} }
let duration = start.elapsed();
println!("Ran {} commands in {:?}",qty,duration);
Command::None Command::None
}, },
["quit"] => { return }, ["quit"] => { return },