1mod types;
7
8pub use types::{Bet, BinaryMarket, Outcome, YesNoValues};
9
10impl BinaryMarket {
11 pub fn evaluate_shares(&self, outcome: Outcome, money: u64) -> (YesNoValues<u64>, Bet) {
13 let current_product = self.pool.yes * self.pool.no;
15 let mut new_pool = self.pool.map(|pool| pool + money);
17 let div_by = new_pool[-outcome];
23 println!(
26 "solving: ({}-x)*{} = {}",
27 new_pool[outcome], new_pool[-outcome], current_product
28 );
29
30 let expected_shares = (current_product as f64 / div_by as f64).ceil() as u64;
31 assert!(expected_shares <= new_pool[outcome]);
34
35 let share_diff = new_pool[outcome] - expected_shares;
36 new_pool[outcome] = expected_shares;
39
40 (
41 new_pool,
42 Bet {
43 outcome,
44 shares: share_diff,
45 },
46 )
47 }
48
49 pub fn buy_shares(&mut self, outcome: Outcome, money: u64) -> Bet {
50 let (new_pool, bet) = self.evaluate_shares(outcome, money);
51 self.pool = new_pool;
52 bet
53 }
54
55 pub fn probability_of(&self, outcome: Outcome) -> f64 {
56 let total = self.pool.yes + self.pool.no;
57 self.pool[-outcome] as f64 / total as f64
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64 use proptest::proptest;
65
66 #[test]
67 fn example_from_docs() {
68 let market = BinaryMarket {
71 pool: YesNoValues::new(3, 2),
72 };
73
74 let bet = market.evaluate_shares(Outcome::Yes, 1).1;
75
76 assert_eq!(bet.outcome, Outcome::Yes);
77 assert_eq!(bet.shares, 2);
78
79 assert_eq!(market.probability_of(Outcome::Yes), 0.4);
80 }
81
82 #[test]
83 fn bigger() {
84 let market = BinaryMarket {
85 pool: YesNoValues::new(300, 200),
86 };
87
88 let bet = market.evaluate_shares(Outcome::Yes, 200).1;
89
90 assert_eq!(bet.outcome, Outcome::Yes);
91 assert_eq!(bet.shares, 350);
92 }
93
94 #[test]
95 fn rounding_down() {
96 let market = BinaryMarket {
98 pool: YesNoValues::new(200, 200),
99 };
100
101 let bet = market.evaluate_shares(Outcome::No, 100).1;
102
103 assert_eq!(bet.outcome, Outcome::No);
104 assert_eq!(bet.shares, 166);
105 }
106
107 proptest! {
108 #[test]
109 fn no_money_created(bets: Vec<(Outcome, u8)>){
110 println!("new!");
111 let mut market = BinaryMarket {
112 pool: YesNoValues::new(100, 100),
113 };
114
115 let mut total_spent = 100;
116 let mut total_shares = YesNoValues::new(0, 0);
117
118 for (outcome, money) in bets {
119 println!("{:?} {}", outcome, money);
120 let money = (money as u64) + 1; total_spent += money;
123 let bet = market.buy_shares(outcome, money);
124 total_shares[bet.outcome] += bet.shares;
125 }
126
127 println!("total_spent: {}", total_spent);
128 println!("total_shares: {:?}", total_shares);
129
130 assert!(total_spent >= total_shares.yes);
131 assert!(total_spent >= total_shares.no);
132 }
133 }
134}