Added and tested Shadowing at the OrderQueue level
This commit is contained in:
15
demo1.log
15
demo1.log
@@ -1,8 +1,7 @@
|
|||||||
OR 2 0 9C4000000000 1 100000000
|
AT Teppy
|
||||||
OR 3 0 9C4000000000 1 100000000
|
AT Luni
|
||||||
NOP Error: Count not find currency
|
AA USD
|
||||||
OR 3 0 9C4000000000 1 100000000
|
AA BTC
|
||||||
OR 3 0 C35000000000 1 100000000
|
NOP Error: Could not parse quantity USD
|
||||||
AF 3 0 186A000000000
|
AF 1 0 3E800000000
|
||||||
OR 3 0 C35000000000 1 100000000
|
AF 2 1 6400000000
|
||||||
OR 1 1 100000000 0 9C4000000000
|
|
||||||
|
|||||||
18
logs/demo.log
Normal file
18
logs/demo.log
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
AT Teppy
|
||||||
|
AT Luni
|
||||||
|
AT Hamza
|
||||||
|
AT UncleSam
|
||||||
|
NOP Error: Could not find asset BTC
|
||||||
|
NOP Error: Could not find asset ETH
|
||||||
|
AA USD
|
||||||
|
AA BTC
|
||||||
|
AA ETH
|
||||||
|
AA SOL
|
||||||
|
AF 1 1 A00000000
|
||||||
|
AF 2 2 3200000000
|
||||||
|
AF 3 3 FA00000000
|
||||||
|
AF 4 0 F424000000000
|
||||||
|
OR 1 1 100000000 2 400000000
|
||||||
|
OR 2 2 100000000 3 400000000
|
||||||
|
OR 3 3 100000000 0 FA00000000
|
||||||
|
OR 1 1 100000000 3 1900000000
|
||||||
102
src/main.rs
102
src/main.rs
@@ -54,6 +54,7 @@ use std::path::Path;
|
|||||||
use std::io::{self, BufRead, Write};
|
use std::io::{self, BufRead, Write};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::collections::HashSet;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
@@ -370,7 +371,7 @@ impl Dumpable for usize {
|
|||||||
|
|
||||||
impl Dumpable for Order {
|
impl Dumpable for Order {
|
||||||
fn dump(&self) {
|
fn dump(&self) {
|
||||||
println!("Giving {}/{} to get {}",self.sell_remain,self.sell_qty,self.buy_qty);
|
println!("Giving {}/{} ({} each) to get {}",self.sell_remain,self.sell_qty,self.buy_qty/self.sell_qty,self.buy_qty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,6 +383,7 @@ struct Market {
|
|||||||
traders: Vec<Trader>,
|
traders: Vec<Trader>,
|
||||||
trader_name2num: HashMap<String,usize>,
|
trader_name2num: HashMap<String,usize>,
|
||||||
orders: HashMap<(usize,usize),OrderQueue>,
|
orders: HashMap<(usize,usize),OrderQueue>,
|
||||||
|
shadows: HashSet<(usize,usize)>,
|
||||||
royalties: HashMap<usize,RoyaltyTree>, // Active orders that are accepting asset X. They receive royalties when someone makes an order to sell X
|
royalties: HashMap<usize,RoyaltyTree>, // Active orders that are accepting asset X. They receive royalties when someone makes an order to sell X
|
||||||
royalty_rate: HashMap<usize,FiNum>,
|
royalty_rate: HashMap<usize,FiNum>,
|
||||||
order_finder: HashMap<usize,(usize,usize)>, // Maps Order ID to an asset pair (in other systems, a "market.") From there you can look in self.orders.get((usize,usize)) which is an OrderQueue, and OrderQueues have a mapping from ID to position in the OrderQueue
|
order_finder: HashMap<usize,(usize,usize)>, // Maps Order ID to an asset pair (in other systems, a "market.") From there you can look in self.orders.get((usize,usize)) which is an OrderQueue, and OrderQueues have a mapping from ID to position in the OrderQueue
|
||||||
@@ -399,6 +401,7 @@ impl Market {
|
|||||||
traders: Vec::new(),
|
traders: Vec::new(),
|
||||||
trader_name2num: HashMap::new(),
|
trader_name2num: HashMap::new(),
|
||||||
orders: HashMap::new(),
|
orders: HashMap::new(),
|
||||||
|
shadows: HashSet::new(),
|
||||||
royalties: HashMap::new(),
|
royalties: HashMap::new(),
|
||||||
royalty_rate: HashMap::new(),
|
royalty_rate: HashMap::new(),
|
||||||
order_finder: HashMap::new(),
|
order_finder: HashMap::new(),
|
||||||
@@ -573,6 +576,8 @@ impl Market {
|
|||||||
let ap0=(asset_type0,asset_type1);
|
let ap0=(asset_type0,asset_type1);
|
||||||
let ap1=(asset_type1,asset_type0);
|
let ap1=(asset_type1,asset_type0);
|
||||||
let [bids0,bids1]=self.orders.get_many_mut([&ap0, &ap1]).unwrap(); // There's a workaround for this where you remove and reinsert the keys.
|
let [bids0,bids1]=self.orders.get_many_mut([&ap0, &ap1]).unwrap(); // There's a workaround for this where you remove and reinsert the keys.
|
||||||
|
let bids0p=bids0.peek();
|
||||||
|
let bids1p=bids1.peek();
|
||||||
while !bids0.empty() && !bids1.empty()
|
while !bids0.empty() && !bids1.empty()
|
||||||
&& bids0.peek().sell_qty/bids0.peek().buy_qty>=strike0/strike1
|
&& bids0.peek().sell_qty/bids0.peek().buy_qty>=strike0/strike1
|
||||||
&& bids1.peek().sell_qty/bids1.peek().buy_qty>=strike1/strike0 {
|
&& bids1.peek().sell_qty/bids1.peek().buy_qty>=strike1/strike0 {
|
||||||
@@ -763,7 +768,7 @@ impl Market {
|
|||||||
ext.cap=min(ext.cap,ext.cost*top.sell_remain);
|
ext.cap=min(ext.cap,ext.cost*top.sell_remain);
|
||||||
progress=true;
|
progress=true;
|
||||||
if arbitrage {
|
if arbitrage {
|
||||||
|
ext.arbitrage=true;
|
||||||
return ext.clone();
|
return ext.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -824,7 +829,7 @@ struct OrderQueue {
|
|||||||
v: Vec<Order>,
|
v: Vec<Order>,
|
||||||
shadowing: bool,
|
shadowing: bool,
|
||||||
shadow: Option<Order>,
|
shadow: Option<Order>,
|
||||||
next: Vec<usize>,
|
next: Vec<usize>, // A priority queue
|
||||||
order_finder: HashMap<usize,usize>, // Maps OrderIDs to locations in v
|
order_finder: HashMap<usize,usize>, // Maps OrderIDs to locations in v
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -839,20 +844,62 @@ impl OrderQueue {
|
|||||||
order_finder:HashMap::new(),
|
order_finder:HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn start_shadow(&mut self) {
|
fn assure_shadowing(&mut self) {
|
||||||
assert!(self.shadowing==false);
|
if !self.shadowing {
|
||||||
|
assert!(self.next.len()==0);
|
||||||
self.shadowing=true;
|
self.shadowing=true;
|
||||||
self.shadow=if self.v.len()>0 { Some(self.v[0].clone()) } else { None }
|
if self.v.len()>0 { self.shadow=Some(self.v[0].clone()); }
|
||||||
|
else { self.shadow=None; }
|
||||||
|
self.queue_shadow(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn stop_shadowing(&mut self) {
|
||||||
|
if self.shadowing {
|
||||||
|
self.next.clear();
|
||||||
|
self.shadowing=false;
|
||||||
|
self.shadow=None;
|
||||||
|
self.next=Vec::new();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn queue_shadow(&mut self, parent: usize) {
|
||||||
|
if parent*2+1<self.v.len() { self.next.push(parent*2+1); self.bubble_up_next(self.next.len()-1); }
|
||||||
|
if parent*2+2<self.v.len() { self.next.push(parent*2+2); self.bubble_up_next(self.next.len()-1); }
|
||||||
}
|
}
|
||||||
fn peek(&mut self) -> &mut Order {
|
fn peek(&mut self) -> &mut Order {
|
||||||
self.v.first_mut().unwrap()
|
if !self.shadowing { self.v.first_mut().unwrap() }
|
||||||
|
else { self.shadow.as_mut().expect("Shadowing mismatch") }
|
||||||
}
|
}
|
||||||
fn peekn(&self) -> Option<&Order> {
|
fn peekn(&self) -> Option<&Order> {
|
||||||
self.v.first()
|
match &self.shadow {
|
||||||
|
Some(order) => Some(order),
|
||||||
|
None => { self.v.first() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn empty(&self) -> bool {
|
fn empty(&self) -> bool {
|
||||||
self.v.len()==0
|
self.v.len()==0
|
||||||
}
|
}
|
||||||
|
fn pop(&mut self) -> Option<Order> {
|
||||||
|
if !self.shadowing { return self.remove(0); }
|
||||||
|
let rval=self.shadow.clone();
|
||||||
|
if self.next.len()==0 { self.shadow=None; }
|
||||||
|
else {
|
||||||
|
self.shadow=Some(self.v[self.next[0]].clone());
|
||||||
|
self.queue_shadow(self.next[0]);
|
||||||
|
if self.next.len()>1 { self.next[0]=self.next.pop().unwrap(); }
|
||||||
|
else { self.next.pop(); }
|
||||||
|
self.trickle_down_next(0);
|
||||||
|
}
|
||||||
|
rval
|
||||||
|
}
|
||||||
|
fn bubble_up_next(&mut self, pos: usize) {
|
||||||
|
if pos>0 {
|
||||||
|
let parent=(pos-1)/2;
|
||||||
|
if self.v[self.next[parent]]<self.v[self.next[pos]] {
|
||||||
|
self.next.swap(parent,pos);
|
||||||
|
self.bubble_up_next(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
fn bubble_up(&mut self, pos: usize) {
|
fn bubble_up(&mut self, pos: usize) {
|
||||||
if pos>0 {
|
if pos>0 {
|
||||||
let parent=(pos-1)/2;
|
let parent=(pos-1)/2;
|
||||||
@@ -882,16 +929,30 @@ impl OrderQueue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn trickle_down_next(&mut self, pos: usize) {
|
||||||
|
let mut pivot=pos;
|
||||||
|
let child0=pos*2+1;
|
||||||
|
let child1=pos*2+2;
|
||||||
|
if child0<self.next.len() {
|
||||||
|
if self.v[self.next[pos]]<self.v[self.next[child0]] { pivot=child0; }
|
||||||
|
if child1<self.next.len() {
|
||||||
|
if self.v[self.next[pivot]]<self.v[self.next[child1]] { pivot=child1; }
|
||||||
|
}
|
||||||
|
if pivot!=pos {
|
||||||
|
self.next.swap(pivot,pos);
|
||||||
|
self.trickle_down_next(pivot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
fn insert(&mut self, item: Order) {
|
fn insert(&mut self, item: Order) {
|
||||||
|
assert!(!self.shadowing);
|
||||||
let id=item.order_id;
|
let id=item.order_id;
|
||||||
self.v.push(item);
|
self.v.push(item);
|
||||||
self.order_finder.insert(id,self.v.len()-1);
|
self.order_finder.insert(id,self.v.len()-1);
|
||||||
self.bubble_up(self.v.len()-1);
|
self.bubble_up(self.v.len()-1);
|
||||||
}
|
}
|
||||||
fn pop(&mut self) -> Option<Order> {
|
|
||||||
self.remove(0)
|
|
||||||
}
|
|
||||||
fn remove(&mut self, pos: usize) -> Option<Order> {
|
fn remove(&mut self, pos: usize) -> Option<Order> {
|
||||||
|
assert!(!self.shadowing);
|
||||||
if self.v.len()<=pos { None }
|
if self.v.len()<=pos { None }
|
||||||
else {
|
else {
|
||||||
let end=self.v.len()-1;
|
let end=self.v.len()-1;
|
||||||
@@ -906,6 +967,7 @@ impl OrderQueue {
|
|||||||
for index in 0..self.v.len() {
|
for index in 0..self.v.len() {
|
||||||
self.v[index].dump();
|
self.v[index].dump();
|
||||||
}
|
}
|
||||||
|
if self.shadowing { for index in 0..self.next.len() { println!(" Shadow {}",self.next[index]); } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1382,6 +1444,24 @@ fn interactive(m: &mut Market, mut out: Option<File>) {
|
|||||||
println!("Seeded RNG with {}",seed);
|
println!("Seeded RNG with {}",seed);
|
||||||
Command::None
|
Command::None
|
||||||
}
|
}
|
||||||
|
["testshadow",src,dst] => {
|
||||||
|
if let Some(cur0)=m.name_to_number(src) {
|
||||||
|
if let Some(cur1)=m.name_to_number(dst) {
|
||||||
|
println!("Currencies are {} and {}",cur0,cur1);
|
||||||
|
if let Some(q)=m.orders.get_mut(&(*cur0,*cur1)) {
|
||||||
|
println!("Dumping queue");
|
||||||
|
q.dump();
|
||||||
|
println!("Dumping shadow");
|
||||||
|
q.assure_shadowing();
|
||||||
|
while let Some(ord)=q.pop() {
|
||||||
|
ord.dump();
|
||||||
|
}
|
||||||
|
q.stop_shadowing();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Command::None
|
||||||
|
}
|
||||||
["randomcommands"|"rc", qty] => {
|
["randomcommands"|"rc", qty] => {
|
||||||
let qty:u32=qty.parse().unwrap();
|
let qty:u32=qty.parse().unwrap();
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user