[READ-ONLY] Mirror of https://github.com/just-cameron/pricing-engine.
0

Configure Feed

Select the types of activity you want to include in your feed.

misc

+242 -23
+1
.gitignore
··· 1 1 target/ 2 + pricing-engine.code-workspace/
+78
Cargo.lock
··· 43 43 ] 44 44 45 45 [[package]] 46 + name = "dtoa" 47 + version = "0.4.3" 48 + source = "registry+https://github.com/rust-lang/crates.io-index" 49 + 50 + [[package]] 46 51 name = "env_logger" 47 52 version = "0.5.11" 48 53 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 75 80 dependencies = [ 76 81 "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 77 82 ] 83 + 84 + [[package]] 85 + name = "itoa" 86 + version = "0.4.2" 87 + source = "registry+https://github.com/rust-lang/crates.io-index" 78 88 79 89 [[package]] 80 90 name = "lazy_static" ··· 119 129 "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 120 130 "pretty_env_logger 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", 121 131 "rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", 132 + "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", 133 + "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", 134 + "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", 135 + ] 136 + 137 + [[package]] 138 + name = "proc-macro2" 139 + version = "0.4.9" 140 + source = "registry+https://github.com/rust-lang/crates.io-index" 141 + dependencies = [ 142 + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 122 143 ] 123 144 124 145 [[package]] 125 146 name = "quick-error" 126 147 version = "1.2.2" 127 148 source = "registry+https://github.com/rust-lang/crates.io-index" 149 + 150 + [[package]] 151 + name = "quote" 152 + version = "0.6.4" 153 + source = "registry+https://github.com/rust-lang/crates.io-index" 154 + dependencies = [ 155 + "proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", 156 + ] 128 157 129 158 [[package]] 130 159 name = "rand" ··· 177 206 ] 178 207 179 208 [[package]] 209 + name = "serde" 210 + version = "1.0.70" 211 + source = "registry+https://github.com/rust-lang/crates.io-index" 212 + 213 + [[package]] 214 + name = "serde_derive" 215 + version = "1.0.70" 216 + source = "registry+https://github.com/rust-lang/crates.io-index" 217 + dependencies = [ 218 + "proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", 219 + "quote 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", 220 + "syn 0.14.5 (registry+https://github.com/rust-lang/crates.io-index)", 221 + ] 222 + 223 + [[package]] 224 + name = "serde_json" 225 + version = "1.0.24" 226 + source = "registry+https://github.com/rust-lang/crates.io-index" 227 + dependencies = [ 228 + "dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 229 + "itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 230 + "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", 231 + ] 232 + 233 + [[package]] 234 + name = "syn" 235 + version = "0.14.5" 236 + source = "registry+https://github.com/rust-lang/crates.io-index" 237 + dependencies = [ 238 + "proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", 239 + "quote 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", 240 + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 241 + ] 242 + 243 + [[package]] 180 244 name = "termcolor" 181 245 version = "1.0.1" 182 246 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 206 270 [[package]] 207 271 name = "ucd-util" 208 272 version = "0.1.1" 273 + source = "registry+https://github.com/rust-lang/crates.io-index" 274 + 275 + [[package]] 276 + name = "unicode-xid" 277 + version = "0.1.0" 209 278 source = "registry+https://github.com/rust-lang/crates.io-index" 210 279 211 280 [[package]] ··· 260 329 "checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" 261 330 "checksum cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efe5c877e17a9c717a0bf3613b2709f723202c4e4675cc8f12926ded29bcb17e" 262 331 "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 332 + "checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd" 263 333 "checksum env_logger 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "7873e292d20e8778f951278972596b3df36ac72a65c5b406f6d4961070a870c1" 264 334 "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" 265 335 "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" 266 336 "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" 337 + "checksum itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5adb58558dcd1d786b5f0bd15f3226ee23486e24b7b58304b60f64dc68e62606" 267 338 "checksum lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fb497c35d362b6a331cfd94956a07fc2c78a4604cdbee844a81170386b996dd3" 268 339 "checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1" 269 340 "checksum log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "61bd98ae7f7b754bc53dca7d44b604f733c6bba044ea6f41bc8d89272d8161d2" 270 341 "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" 271 342 "checksum pretty_env_logger 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8ae1b463255bf6613ad435f8997cb57f5d045ef35eb255f5a3d6085be936bd79" 343 + "checksum proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "cccdc7557a98fe98453030f077df7f3a042052fae465bb61d2c2c41435cfd9b6" 272 344 "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" 345 + "checksum quote 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b71f9f575d55555aa9c06188be9d4e2bfc83ed02537948ac0d520c24d0419f1a" 273 346 "checksum rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "12397506224b2f93e6664ffc4f664b29be8208e5157d3d90b44f09b5fae470ea" 274 347 "checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2" 275 348 "checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" 276 349 "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" 277 350 "checksum regex 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5bbbea44c5490a1e84357ff28b7d518b4619a159fed5d25f6c1de2d19cc42814" 278 351 "checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d" 352 + "checksum serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)" = "0c3adf19c07af6d186d91dae8927b83b0553d07ca56cbf7f2f32560455c91920" 353 + "checksum serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)" = "3525a779832b08693031b8ecfb0de81cd71cfd3812088fafe9a7496789572124" 354 + "checksum serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c6908c7b925cd6c590358a4034de93dbddb20c45e1d021931459fd419bf0e2" 355 + "checksum syn 0.14.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4bad7abdf6633f07c7046b90484f1d9dc055eca39f8c991177b1046ce61dba9a" 279 356 "checksum termcolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "722426c4a0539da2c4ffd9b419d90ad540b4cff4a053be9069c908d4d07e2836" 280 357 "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" 281 358 "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" 282 359 "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" 360 + "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 283 361 "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" 284 362 "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" 285 363 "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
+4
Cargo.toml
··· 7 7 rand = "0.5" 8 8 log = "0.4" 9 9 pretty_env_logger = "0.2.4" 10 + serde_json = "1.0" 11 + serde_derive = "1.0" 12 + serde = "1.0" 13 +
+10
pricing-engine.code-workspace
··· 1 + { 2 + "folders": [ 3 + { 4 + "path": "." 5 + } 6 + ], 7 + "settings": { 8 + "git.ignoreLimitWarning": true 9 + } 10 + }
src/lib.rs src/not-lib.rs
+4
src/main.rs
··· 1 1 #[macro_use] 2 2 extern crate log; 3 3 4 + #[macro_use] 5 + extern crate serde_derive; 6 + extern crate serde_json; 7 + 4 8 pub mod orderbook; 5 9 pub mod testing; 6 10
+3
src/orderbook/mod.rs
··· 1 + extern crate serde; 2 + extern crate serde_json; 3 + 1 4 pub mod orderbook; 2 5 pub mod pricelevel; 3 6 pub mod orders;
+100 -9
src/orderbook/orderbook.rs
··· 1 1 extern crate pretty_env_logger; 2 + 2 3 use orderbook::orders::Order; 3 4 use orderbook::orders::Ordertype; 4 5 use orderbook::pricelevel::PriceLevel; 5 6 use std::collections::HashMap; 7 + use std::f64; 8 + use serde_json; 6 9 7 10 pub struct Orderbook{ 8 - // Describes an orderbook. 11 + // Describes an orderbook 9 12 name: String, // A currency pair, ticker, whatever. 13 + automatch: bool, // Whether or not to match trades 10 14 11 - // Price levels. 15 + // Price levels 12 16 buys: HashMap<String, PriceLevel>, 13 - sells: HashMap<String, PriceLevel> 17 + sells: HashMap<String, PriceLevel>, 18 + 19 + // Bests 20 + best_buy: (String, f64), 21 + best_sell: (String, f64), 14 22 } 15 23 16 24 impl Orderbook { 17 25 pub fn new(name: String) -> Orderbook{ 18 26 return Orderbook{ 19 27 name, 28 + automatch: false, 20 29 buys: HashMap::new(), 21 30 sells: HashMap::new(), 31 + best_buy: (String::default(), f64::MIN), 32 + best_sell: (String::default(), f64::MAX), 22 33 } 23 34 } 24 35 ··· 26 37 let pl = PriceLevel::new(&new_buy); 27 38 match self.buys.contains_key(&new_buy.price_string) { 28 39 true => { 29 - self.buys.entry(new_buy.price_string).or_insert(pl); 40 + let price = new_buy.price_string; 41 + if verbose { 42 + info!("Inserting new buy level {} at {}", 43 + &price, 44 + pl.quantity) 45 + } 46 + self.buys.entry(price).or_insert(pl); 30 47 }, 31 48 false => { 32 - let entry = self.buys.entry(new_buy.price_string).or_default(); 49 + let price = new_buy.price_string; 50 + let entry = self.buys.entry(price.clone()).or_default(); 33 51 34 52 if new_buy.additive { 53 + if verbose { 54 + info!("Adjusting buy level {} by {}", 55 + price, 56 + pl.quantity) 57 + } 58 + 35 59 (*entry).merge(pl); 36 60 } else { 37 61 *entry = pl; ··· 44 68 let pl = PriceLevel::new(&new_sell); 45 69 match self.sells.contains_key(&new_sell.price_string) { 46 70 true => { 47 - self.sells.entry(new_sell.price_string).or_insert(pl); 71 + let price = new_sell.price_string; 72 + if verbose { 73 + info!("Inserting new sell level {} at {}", 74 + &price, 75 + pl.quantity) 76 + } 77 + self.sells.entry(price).or_insert(pl); 48 78 }, 49 79 false => { 50 - let entry = self.sells.entry(new_sell.price_string).or_default(); 51 - *entry = pl; 80 + let price = new_sell.price_string; 81 + let entry = self.sells.entry(price.clone()).or_default(); 82 + 83 + if new_sell.additive { 84 + if verbose { 85 + info!("Adjusting sell level {} by {}", 86 + price, 87 + pl.quantity) 88 + } 89 + 90 + (*entry).merge(pl); 91 + } else { 92 + *entry = pl; 93 + } 52 94 } 53 95 } 54 96 } 55 97 56 98 pub fn insert(&mut self, new_order: Order, verbose: bool){ 99 + self.update_best(&new_order, verbose); 57 100 match new_order.order_type { 58 - Ordertype::Buy => self.update_buy(new_order, verbose), 101 + Ordertype::Buy => self.update_buy(new_order, verbose), 59 102 Ordertype::Sell => self.update_sell(new_order, verbose) 60 103 }; 104 + } 105 + 106 + pub fn insert_from_json(&mut self, order_string: String, verbose: bool) { 107 + let new_order: Order = match serde_json::from_str(&order_string) { 108 + Ok(o) => o, 109 + Err(e) => { 110 + print!("Serializing string: {:?}", e); 111 + return (); 112 + } 113 + }; 114 + 115 + if verbose { 116 + info!("Received JSON string:"); 117 + info!("{}", order_string); 118 + } 119 + 120 + self.insert(new_order, verbose); 121 + } 122 + 123 + pub fn update_best(&mut self, new_order: &Order, _verbose: bool) { 124 + match new_order.order_type { 125 + Ordertype::Buy => { 126 + if new_order.price > self.best_buy.1 { 127 + self.best_buy = (new_order.price_string.clone(), new_order.price.clone()) 128 + } 129 + }, 130 + Ordertype::Sell => { 131 + if new_order.price < self.best_sell.1 { 132 + self.best_sell = (new_order.price_string.clone(), new_order.price.clone()) 133 + } 134 + } 135 + } 136 + } 137 + 138 + pub fn summary(&self) { 139 + let name = &self.name; 140 + let num_buys = self.buys.len(); 141 + let num_sells = self.sells.len(); 142 + let best_buy = &self.best_buy.0; 143 + let best_sell = &self.best_sell.0; 144 + 145 + println!("Name: {} 146 + Buy count: {} 147 + Sell count: {} 148 + 149 + Best buy: {} 150 + Best sell: {}", 151 + name, num_buys, num_sells, best_buy, best_sell); 61 152 } 62 153 }
+4 -2
src/orderbook/orders.rs
··· 1 - #[derive(PartialEq, Eq, Debug)] 1 + extern crate serde_json; 2 + 3 + #[derive(Serialize, Deserialize, PartialEq, Eq, Debug)] 2 4 pub enum Ordertype{ 3 5 Buy = 1, 4 6 Sell = -1 5 7 } 6 8 7 - #[derive(Debug)] 9 + #[derive(Serialize, Deserialize, Debug)] 8 10 pub struct Order { 9 11 pub order_type: Ordertype, 10 12 pub price_string: String,
+1 -2
src/orderbook/pricelevel.rs
··· 1 1 use orderbook::orders::Order; 2 - use std::ops::Add; 3 2 4 3 #[derive(Default)] 5 4 pub struct PriceLevel { ··· 11 10 return PriceLevel {quantity: order.amount} 12 11 } 13 12 14 - pub fn merge(&self, other: PriceLevel) { 13 + pub fn merge(&mut self, other: PriceLevel) { 15 14 self.quantity += other.quantity; 16 15 } 17 16 }
+37 -10
src/testing/mod.rs
··· 1 1 extern crate rand; 2 2 extern crate pretty_env_logger; 3 + extern crate serde_json; 3 4 4 - use testing::rand::prelude::random; 5 + use testing::rand::ThreadRng; 6 + use testing::rand::random; 7 + use testing::rand::distributions::Uniform; 8 + use testing::rand::{Rng, thread_rng}; 5 9 use orderbook::orderbook::Orderbook; 6 10 use orderbook::orders::*; 7 11 ··· 11 15 let mut ob = Orderbook::new(name); 12 16 let cumulative = true; 13 17 18 + let mut rng = thread_rng(); 19 + let price_range = Uniform::new(1, 100); 20 + let amount_range = Uniform::new(1, 1000000); 21 + 14 22 for _ in 1..50 { 15 - let new_order = random_order(cumulative); 23 + let new_order = random_order(cumulative, &mut rng, &price_range, &amount_range); 16 24 // info!("{:?}", &new_order); 17 25 ob.insert(new_order, true); 18 26 } 27 + 28 + // Test string insertion 29 + for _ in 1..50 { 30 + let new_str = random_order_string(cumulative, &mut rng, &price_range, &amount_range); 31 + ob.insert_from_json(new_str, true); 32 + } 33 + 34 + ob.summary(); 19 35 } 20 36 21 - pub fn random_order(cumulative: bool) -> Order { 22 - let price: f64 = random(); 23 - let amount: f64 = random(); 37 + pub fn random_order(cumulative: bool, 38 + rng: &mut ThreadRng, 39 + price_range: &Uniform<i32>, 40 + amount_range: &Uniform<i32>) -> Order { 41 + let price: i32 = rng.sample(price_range); 42 + let amount: i32 = rng.sample(amount_range); 43 + 44 + if random() { 45 + return Order::sell(price.into(), amount.into(), cumulative); 46 + } else { 47 + return Order::buy(price.into(), amount.into(), cumulative); 48 + } 49 + } 24 50 25 - if random() { 26 - return Order::sell(price - 0.5, amount, cumulative); 27 - } else { 28 - return Order::buy(price - 0.5, amount, cumulative); 29 - } 51 + pub fn random_order_string(cumulative: bool, 52 + rng: &mut ThreadRng, 53 + price_range: &Uniform<i32>, 54 + amount_range: &Uniform<i32>) -> String { 55 + let new_order = random_order(cumulative, rng, &price_range, &amount_range); 56 + return serde_json::to_string_pretty(&new_order).unwrap(); 30 57 }