In [1]:
import matplotlib.pylab as pl
import numpy as np
from scipy.optimize import fmin_cobyla
import pandas as pd
%matplotlib inline

Creating a scientific task


In [2]:
result1_task1 = {
    'description': 'Attempt to reproduce the result 1 of this article',
    'doi': '10.1051/itmconf/20140201004',
    'reference': 'result 1, p. 4',
    'type': 'scientific task',
    'possible_outcomes': [
        'the result is reproducible',
        'the result is not reproducible'
        ]
}

The LS-LMSR model from Augur

Heavily inspired from this blog post: Augur’s Automated Market Maker: The LS-LMSR, By Dr. Abe Othman.

The cost function for the LMSR is given by:

$$ C(\textbf{q}) = b \log \left(\sum_{i=1}^n e^{\frac{q_i}{b}} \right) $$

and the marginal prices on each event are given by the partial derivatives of the cost function: $$ p_j(\textbf{q}) = \frac{e^{\frac{q_j}{b}}}{\sum_{i=1}^n e^{\frac{q_i}{b}}} $$ where $b$, which is defined as a constant in the original LMSR model of Hanson, is here defined as a variable of q $$ b(\textbf{q})=\alpha \sum_{i=1}^n q_i $$

with $\alpha$ defined as

$$ \alpha = \frac{0.1}{n \log{n}} $$

with $n$ being the number of dimensions of $\textbf{q}$


In [29]:
class LS_LMSRMarket(object):
    def __init__(self, task, vig=0.1, init=1.0, market='LS_LMSR', b=None):
        """
        Parameters
        ----------
        task    dict
                A dictionary describing the task for which the predictive market is created.
                Keys:
                -----
                type:               str 
                                    (e.g. 'scientific task')
                description:        str
                                    description of the task to be performed
                reference:          str
                                    Internal reference (e.g. 'result 1, p. 4')
                doi:                str
                                    DOI of the related publication
                possible_outcomes:  list
                                    List of strings describing the possible outcomes of the task
                                    
        vig     float
                parameter of the `alpha` variable used to calculate the `b` variable.
                Corresponds to the market "vig" value - typically between 5 and 30 percent in real-world markets
                
        init    float
                The initial subsidies of the market, spread equally in this algorithm on all the outcomes.
        
        market  srt, 'LS_LMSR' | 'LMSR'
                The market type. If 'LMSR' is selected, then a b value should be given.
        """
        self.market = market
        if self.market == 'LSMR':
            if b == None:
                raise Exception('b value is needed for LSMR markets')
            self._b = b

        for k, v in task.items():
            setattr(self, k, v)
        self.init = init
        self.n = len(self.possible_outcomes)
        self._x = [np.ones([self.n])*init/self.n]
        self._book = []
        self.market_value = init
        self._history = []
        self.alpha = vig*self.n/np.log(self.n)
        
    @property
    def b(self):
        if self.market == 'LMSR':
            return self._b
        elif self.market == 'LS_LMSR':
            return self._b_func(self.x)
        else:
            raise Exception('market must be set to either "LMSR" or "LS_LMSR"')
    
    def _b_func(self, x):
        """Calculate the `b` equation: b=\alpha \Sigma x"""
        return self.alpha * x.sum()
        
    @property
    def book(self):
        return pd.DataFrame(self._book)
    
    @property
    def x(self):
        return self._x[-1].copy()
    
    def cost(self, x):
        return self.b*np.log(np.exp(x/self.b).sum())
    
    def _new_x(self, shares, outcome):
        new_x = self.x
        new_x[outcome] += shares        
        return new_x
            
    def price(self, shares, outcome):
        return self._price(self._new_x(shares, outcome))
        
    def _price(self, x):
        return self.cost(x)-self.cost(self.x)
    
    def register_x(self, x):
        self._x.append(x)
        
    def calculate_shares(self, paid, outcome):
        obj_func = lambda s: np.abs(self.price(s, outcome) - paid)
        return fmin_cobyla(obj_func, paid/self.p[outcome], [])
    
    def buy_shares(self, name, paid, outcome):
        shares = self.calculate_shares(paid, outcome)
        self.register_x(self._new_x(shares, outcome))
        self._book.append({'name':name, 
                           'shares':shares, 
                           'outcome':outcome, 
                           'paid':paid})
        self._history.append(self.p)
        self.market_value += paid
        print("%s paid %2.2f EUR, for %2.2f shares of outcome %d, which will give him %2.2f EUR if he wins"%(
                name, paid, shares, outcome, shares/self.x[outcome]*self.market_value))
        return shares
    
    def sell_shares(self, name, shares, outcome):
        price = self.price(-share, outcome)
        self._book.append({'name':name, 
                           'shares':-shares, 
                           'outcome':outcome, 
                           'paid':-price}) 
        self.market_value -= price        
        self._history.append(self.p)        
        return price

    def outcome_probability(self):
        K = np.exp(self.x/self.b)
        return K/K.sum()
    
    @property
    def p(self):
        return self.outcome_probability()
    
    def history(self):
        return np.array(self._history)

In [30]:
pm = LS_LMSRMarket(result1_task1, init=10., vig=0.1)

In [31]:
pm.buy_shares('Mark', 1., 0)


Mark paid 1.00 EUR, for 1.74 shares of outcome 0, which will give him 2.84 EUR if he wins
Out[31]:
array(1.7413109375)

In [32]:
pm.buy_shares('Erik', 300., 1)
pm.buy_shares('Soeren', 1., 0)
pm.buy_shares('Albert', 3., 1)


Erik paid 300.00 EUR, for 303.33 shares of outcome 1, which will give him 305.96 EUR if he wins
Soeren paid 1.00 EUR, for 24.98 shares of outcome 0, which will give him 245.69 EUR if he wins
Albert paid 3.00 EUR, for 3.18 shares of outcome 1, which will give him 3.21 EUR if he wins
Out[32]:
array(3.1762366179231214)

In [33]:
pm.market_value


Out[33]:
315.0

In [34]:
pm.book


Out[34]:
name outcome paid shares
0 Mark 0 1 1.7413109375
1 Erik 1 300 303.32944019
2 Soeren 0 1 24.9783838402
3 Albert 1 3 3.17623661792

In [43]:
total_shares = pm.book.groupby('outcome').shares.sum()
book = pm.book
book['possible_payout'] = pm.market_value * pm.book.shares / total_shares.values[pm.book.outcome.values]
book['ownership_ratio'] = pm.book.shares / total_shares.values[pm.book.outcome.values]
grouped = book.groupby('name')
df = grouped.paid.sum().to_frame(name='paid')
df['possible_payout'] = grouped.possible_payout.sum()
df


Out[43]:
paid possible_payout
name
Albert 3 3.264261
Erik 300 311.735739
Mark 1 20.528414
Soeren 1 294.471586

In [44]:
book


Out[44]:
name outcome paid shares possible_payout ownership_ratio
0 Mark 0 1 1.7413109375 20.52841 0.06516957
1 Erik 1 300 303.32944019 311.7357 0.9896373
2 Soeren 0 1 24.9783838402 294.4716 0.9348304
3 Albert 1 3 3.17623661792 3.264261 0.01036273

In [45]:
pm.x


Out[45]:
array([  31.71969478,  311.50567681])

In [46]:
pm.market_value


Out[46]:
315.0

In [9]:
pl.plot(pm.history())
pl.ylim([0.,1.])
pl.legend(['outcome 0', 'outcome 1'])


Out[9]:
<matplotlib.legend.Legend at 0x114872fd0>

The Augur example

Inspired from Augur white paper

Joe is creating a new event


In [10]:
new_event = {
    "type": "CreateEvent", 
    "vin": [{
        "n": 0,
        "value": 0.01000000,
        "units": "bitcoin", 
        "scriptSig": """
            <Joe’s signature>
            <Joe´s public key >"""
        }], 
    "vout": [{
        "n": 0,
        "value" : 0.01000000, 
        "units": "bitcoin", 
        "event": {
            "id": "<event hash >", 
            "description": """Hillary Clinton 
                              wins the 2016 U.S. 
                              Presidential Election.""",
            "branch": "politics", 
            "is_binary": True, 
            "valid_range": [0, 1], 
            "expiration": 1478329200, 
            "creator": "<Joe’s address>"
            },
        "address": "<base-58 event ID>", 
        "script": """
            OP_DUP 
            OP_HASH160 
            <event hash > 
            OP_EQUALVERIFY 
            OP_MARKETCHECK"""
        }]
    }

Joe is creating a Market of events


In [11]:
new_market = {
    "type": "CreateMarket", 
    "loss_limit": 1.2, 
    "vin": [{
        "n": 0,
        "value": 27.72588722,
        "units": "bitcoin", 
        "tradingFee": 0.005, 
        "scriptSig": """<Joe’s signature>
                        <Joe ’s public key >"""
        }], 
    "vout": [{
        "n": 0,
        "value": 27.72588722, 
        "units": "bitcoin", 
        "script": """
            OP_DUP
            OP_HASH160 
            OP_EVENTLOOKUP 
            OP_ISSHARES 
            OP_MARKETCHECK"""
        },
        {
        "n": 1,
        "value": 10**9,
        "units": "shares", 
        "event": "<event -1 hash >", 
        "branch": "politics", 
        "script": """
            OP_DUP
            OP_HASH160 
            OP_EVENTLOOKUP 
            OP_ISBITCOIN 
            OP_MARKETCHECK"""
        },
        {
        "n": 2,
        "value": 10**9,
        "units": "shares",
        "event": "<event-2 hash>",
        "branch": "politics", 
        "script": """
            OP_DUP
            OP_HASH160 
            OP_EVENTLOOKUP 
            OP_ISBITCOIN
            OP_MARKETCHECK"""
        }],
    "id": "<market hash>",
    "creator": "<Joe’s address>"
}

100 Traders example


In [12]:
n = 100
outcome = 0.001
# The amount is assumed to increase linearly with time, as the market increases its liquidity
amount = np.random.random([n]) * 100. #* (1+np.arange(n))/(1.*n)
outcomes = np.zeros([n])
outcomes[np.random.random([n])<outcome] = 1.0

Creating the new task prediction market


In [13]:
pm = LS_LMSRMarket(result1_task1, init=10., vig=0.1)

One company comes along and bet sh*t ton of money


In [14]:
pm.buy_shares('EvilMegaCorp', 1000, 1)


COBYLA failed to find a solution: Maximum number of function evaluations has been exceeded.
EvilMegaCorp paid 1000.00 EUR, for 1002.00 shares of outcome 1, which will give him 1004.99 EUR if he wins
Out[14]:
array(1002.0)

Performing the bets


In [15]:
for i, a, o in zip(range(n),amount, outcomes):
    pm.buy_shares('Trader-%d'%(i), a, int(o))


COBYLA failed to find a solution: Maximum number of function evaluations has been exceeded.
Trader-0 paid 49.01 EUR, for 566.50 shares of outcome 0, which will give him 1049.74 EUR if he wins
Trader-1 paid 7.33 EUR, for 25.86 shares of outcome 0, which will give him 46.17 EUR if he wins
Trader-2 paid 3.85 EUR, for 13.06 shares of outcome 0, which will give him 22.90 EUR if he wins
Trader-3 paid 88.11 EUR, for 245.95 shares of outcome 0, which will give him 332.66 EUR if he wins
Trader-4 paid 71.24 EUR, for 152.99 shares of outcome 0, which will give him 186.37 EUR if he wins
Trader-5 paid 58.93 EUR, for 112.24 shares of outcome 0, which will give him 128.94 EUR if he wins
Trader-6 paid 76.32 EUR, for 133.16 shares of outcome 0, which will give him 144.84 EUR if he wins
Trader-7 paid 3.87 EUR, for 6.50 shares of outcome 0, which will give him 7.05 EUR if he wins
Trader-8 paid 45.04 EUR, for 73.91 shares of outcome 0, which will give him 78.26 EUR if he wins
Trader-9 paid 4.30 EUR, for 6.93 shares of outcome 0, which will give him 7.32 EUR if he wins
Trader-10 paid 22.76 EUR, for 36.28 shares of outcome 0, which will give him 37.92 EUR if he wins
Trader-11 paid 60.38 EUR, for 93.29 shares of outcome 0, which will give him 95.16 EUR if he wins
Trader-12 paid 69.14 EUR, for 102.76 shares of outcome 0, which will give him 102.49 EUR if he wins
Trader-13 paid 34.94 EUR, for 50.71 shares of outcome 0, which will give him 50.09 EUR if he wins
Trader-14 paid 59.50 EUR, for 84.44 shares of outcome 0, which will give him 82.22 EUR if he wins
Trader-15 paid 47.67 EUR, for 66.32 shares of outcome 0, which will give him 63.95 EUR if he wins
Trader-16 paid 26.81 EUR, for 36.87 shares of outcome 0, which will give him 35.37 EUR if he wins
Trader-17 paid 90.76 EUR, for 122.06 shares of outcome 0, which will give him 115.44 EUR if he wins
Trader-18 paid 99.48 EUR, for 130.38 shares of outcome 0, which will give him 121.81 EUR if he wins
Trader-19 paid 61.46 EUR, for 79.27 shares of outcome 0, which will give him 73.59 EUR if he wins
Trader-20 paid 76.88 EUR, for 97.75 shares of outcome 0, which will give him 90.14 EUR if he wins
Trader-21 paid 51.35 EUR, for 64.64 shares of outcome 0, which will give him 59.38 EUR if he wins
Trader-22 paid 12.50 EUR, for 15.68 shares of outcome 0, which will give him 14.39 EUR if he wins
Trader-23 paid 82.50 EUR, for 102.40 shares of outcome 0, which will give him 93.50 EUR if he wins
Trader-24 paid 91.92 EUR, for 112.67 shares of outcome 0, which will give him 102.39 EUR if he wins
Trader-25 paid 27.42 EUR, for 33.46 shares of outcome 0, which will give him 30.37 EUR if he wins
Trader-26 paid 29.56 EUR, for 35.94 shares of outcome 0, which will give him 32.58 EUR if he wins
Trader-27 paid 94.99 EUR, for 114.39 shares of outcome 0, which will give him 103.32 EUR if he wins
Trader-28 paid 40.40 EUR, for 48.43 shares of outcome 0, which will give him 43.68 EUR if he wins
Trader-29 paid 50.49 EUR, for 60.23 shares of outcome 0, which will give him 54.25 EUR if he wins
Trader-30 paid 69.92 EUR, for 82.90 shares of outcome 0, which will give him 74.53 EUR if he wins
Trader-31 paid 5.15 EUR, for 6.11 shares of outcome 0, which will give him 5.49 EUR if he wins
Trader-32 paid 11.58 EUR, for 13.71 shares of outcome 0, which will give him 12.32 EUR if he wins
Trader-33 paid 27.22 EUR, for 32.15 shares of outcome 0, which will give him 28.87 EUR if he wins
Trader-34 paid 57.23 EUR, for 67.29 shares of outcome 0, which will give him 60.37 EUR if he wins
Trader-35 paid 84.30 EUR, for 98.51 shares of outcome 0, which will give him 88.24 EUR if he wins
Trader-36 paid 78.05 EUR, for 90.74 shares of outcome 0, which will give him 81.19 EUR if he wins
Trader-37 paid 44.18 EUR, for 51.22 shares of outcome 0, which will give him 45.81 EUR if he wins
Trader-38 paid 46.03 EUR, for 53.22 shares of outcome 0, which will give him 47.57 EUR if he wins
Trader-39 paid 60.34 EUR, for 69.52 shares of outcome 0, which will give him 62.10 EUR if he wins
Trader-40 paid 70.70 EUR, for 81.15 shares of outcome 0, which will give him 72.44 EUR if he wins
Trader-41 paid 56.67 EUR, for 64.87 shares of outcome 0, which will give him 57.89 EUR if he wins
Trader-42 paid 98.07 EUR, for 111.70 shares of outcome 0, which will give him 99.63 EUR if he wins
Trader-43 paid 21.39 EUR, for 24.35 shares of outcome 0, which will give him 21.72 EUR if he wins
Trader-44 paid 66.02 EUR, for 74.92 shares of outcome 0, which will give him 66.80 EUR if he wins
Trader-45 paid 19.25 EUR, for 21.84 shares of outcome 0, which will give him 19.47 EUR if he wins
Trader-46 paid 63.03 EUR, for 71.30 shares of outcome 0, which will give him 63.56 EUR if he wins
Trader-47 paid 63.69 EUR, for 71.87 shares of outcome 0, which will give him 64.06 EUR if he wins
Trader-48 paid 99.52 EUR, for 111.86 shares of outcome 0, which will give him 99.70 EUR if he wins
Trader-49 paid 40.23 EUR, for 45.18 shares of outcome 0, which will give him 40.27 EUR if he wins
Trader-50 paid 42.87 EUR, for 48.07 shares of outcome 0, which will give him 42.85 EUR if he wins
Trader-51 paid 62.39 EUR, for 69.82 shares of outcome 0, which will give him 62.23 EUR if he wins
Trader-52 paid 26.67 EUR, for 29.83 shares of outcome 0, which will give him 26.59 EUR if he wins
Trader-53 paid 33.24 EUR, for 37.14 shares of outcome 0, which will give him 33.10 EUR if he wins
Trader-54 paid 73.57 EUR, for 81.99 shares of outcome 0, which will give him 73.10 EUR if he wins
Trader-55 paid 99.32 EUR, for 110.37 shares of outcome 0, which will give him 98.42 EUR if he wins
Trader-56 paid 75.26 EUR, for 83.48 shares of outcome 0, which will give him 74.46 EUR if he wins
Trader-57 paid 91.02 EUR, for 100.73 shares of outcome 0, which will give him 89.87 EUR if he wins
Trader-58 paid 88.65 EUR, for 97.91 shares of outcome 0, which will give him 87.38 EUR if he wins
Trader-59 paid 77.20 EUR, for 85.13 shares of outcome 0, which will give him 75.99 EUR if he wins
Trader-60 paid 67.80 EUR, for 74.67 shares of outcome 0, which will give him 66.67 EUR if he wins
Trader-61 paid 38.29 EUR, for 42.15 shares of outcome 0, which will give him 37.64 EUR if he wins
Trader-62 paid 43.52 EUR, for 47.86 shares of outcome 0, which will give him 42.75 EUR if he wins
Trader-63 paid 65.75 EUR, for 72.21 shares of outcome 0, which will give him 64.51 EUR if he wins
Trader-64 paid 14.84 EUR, for 16.30 shares of outcome 0, which will give him 14.56 EUR if he wins
Trader-65 paid 8.15 EUR, for 8.95 shares of outcome 0, which will give him 7.99 EUR if he wins
Trader-66 paid 72.88 EUR, for 79.88 shares of outcome 0, which will give him 71.40 EUR if he wins
Trader-67 paid 62.76 EUR, for 68.72 shares of outcome 0, which will give him 61.44 EUR if he wins
Trader-68 paid 81.51 EUR, for 89.12 shares of outcome 0, which will give him 79.71 EUR if he wins
Trader-69 paid 66.84 EUR, for 73.01 shares of outcome 0, which will give him 65.32 EUR if he wins
Trader-70 paid 45.64 EUR, for 49.83 shares of outcome 0, which will give him 44.59 EUR if he wins
Trader-71 paid 85.83 EUR, for 93.55 shares of outcome 0, which will give him 83.76 EUR if he wins
Trader-72 paid 91.13 EUR, for 99.20 shares of outcome 0, which will give him 88.85 EUR if he wins
Trader-73 paid 17.74 EUR, for 19.32 shares of outcome 0, which will give him 17.31 EUR if he wins
Trader-74 paid 36.27 EUR, for 39.47 shares of outcome 0, which will give him 35.36 EUR if he wins
Trader-75 paid 15.15 EUR, for 16.49 shares of outcome 0, which will give him 14.77 EUR if he wins
Trader-76 paid 86.90 EUR, for 94.39 shares of outcome 0, which will give him 84.61 EUR if he wins
Trader-77 paid 66.54 EUR, for 72.23 shares of outcome 0, which will give him 64.77 EUR if he wins
Trader-78 paid 66.16 EUR, for 71.76 shares of outcome 0, which will give him 64.37 EUR if he wins
Trader-79 paid 20.36 EUR, for 22.09 shares of outcome 0, which will give him 19.82 EUR if he wins
Trader-80 paid 96.75 EUR, for 104.76 shares of outcome 0, which will give him 94.03 EUR if he wins
Trader-81 paid 10.44 EUR, for 11.31 shares of outcome 0, which will give him 10.15 EUR if he wins
Trader-82 paid 98.60 EUR, for 106.63 shares of outcome 0, which will give him 95.76 EUR if he wins
Trader-83 paid 94.70 EUR, for 102.31 shares of outcome 0, which will give him 91.93 EUR if he wins
Trader-84 paid 95.19 EUR, for 102.74 shares of outcome 0, which will give him 92.36 EUR if he wins
Trader-85 paid 23.70 EUR, for 25.59 shares of outcome 0, which will give him 23.01 EUR if he wins
Trader-86 paid 98.00 EUR, for 105.64 shares of outcome 0, which will give him 95.03 EUR if he wins
Trader-87 paid 13.49 EUR, for 14.56 shares of outcome 0, which will give him 13.09 EUR if he wins
Trader-88 paid 42.49 EUR, for 45.80 shares of outcome 0, which will give him 41.21 EUR if he wins
Trader-89 paid 10.27 EUR, for 11.08 shares of outcome 0, which will give him 9.97 EUR if he wins
Trader-90 paid 63.40 EUR, for 68.28 shares of outcome 0, which will give him 61.46 EUR if he wins
Trader-91 paid 30.11 EUR, for 32.42 shares of outcome 0, which will give him 29.19 EUR if he wins
Trader-92 paid 29.69 EUR, for 31.97 shares of outcome 0, which will give him 28.78 EUR if he wins
Trader-93 paid 90.66 EUR, for 97.49 shares of outcome 0, which will give him 87.82 EUR if he wins
Trader-94 paid 64.64 EUR, for 69.49 shares of outcome 0, which will give him 62.62 EUR if he wins
Trader-95 paid 5.89 EUR, for 6.33 shares of outcome 0, which will give him 5.71 EUR if he wins
Trader-96 paid 75.34 EUR, for 80.93 shares of outcome 0, which will give him 72.96 EUR if he wins
Trader-97 paid 0.98 EUR, for 1.06 shares of outcome 0, which will give him 0.95 EUR if he wins
Trader-98 paid 13.18 EUR, for 14.16 shares of outcome 0, which will give him 12.77 EUR if he wins
Trader-99 paid 94.98 EUR, for 101.92 shares of outcome 0, which will give him 91.93 EUR if he wins

In [16]:
pm.buy_shares('EvilMegaCorp', 1000, 1)


COBYLA failed to find a solution: Maximum number of function evaluations has been exceeded.
EvilMegaCorp paid 1000.00 EUR, for 13536.53 shares of outcome 1, which will give him 6895.32 EUR if he wins
Out[16]:
array(13536.530024649786)

The total to pay for each outcome


In [17]:
pm.market_value


Out[17]:
7408.2715701809821

In [18]:
total_shares = pm.book.groupby('outcome').shares.sum()
book = pm.book
book['possible_payout'] = pm.market_value * pm.book.shares / total_shares.values[pm.book.outcome.values]
grouped = book.groupby('name')
df = grouped.paid.sum().to_frame(name='paid')
df['possible_payout'] = grouped.possible_payout.sum()

In [19]:
df


Out[19]:
paid possible_payout
name
EvilMegaCorp 2000.000000 7408.271570
Trader-0 49.009162 591.130578
Trader-1 7.329255 26.987177
Trader-10 22.761491 37.855273
Trader-11 60.384992 97.344795
Trader-12 69.143253 107.223475
Trader-13 34.941823 52.912785
Trader-14 59.495336 88.109591
Trader-15 47.673667 69.207184
Trader-16 26.808963 38.468481
Trader-17 90.764785 127.362649
Trader-18 99.483789 136.048423
Trader-19 61.455561 82.716239
Trader-2 3.854513 13.629658
Trader-20 76.883839 101.994916
Trader-21 51.351543 67.448660
Trader-22 12.497101 16.362021
Trader-23 82.502978 106.849451
Trader-24 91.924644 117.572043
Trader-25 27.418155 34.912268
Trader-26 29.557966 37.505780
Trader-27 94.993588 119.359616
Trader-28 40.402446 50.534756
Trader-29 50.489049 62.850653
Trader-3 88.110532 256.640181
Trader-30 69.915586 86.498696
Trader-31 5.154403 6.373185
Trader-32 11.580238 14.304507
Trader-33 27.217732 33.547174
Trader-34 57.226003 70.219155
... ... ...
Trader-72 91.132777 103.508468
Trader-73 17.743041 20.161165
Trader-74 36.273736 41.189295
Trader-75 15.152013 17.204976
Trader-76 86.897143 98.493238
Trader-77 66.538326 75.367011
Trader-78 66.159904 74.877229
Trader-79 20.363493 23.050190
Trader-8 45.042872 77.124725
Trader-80 96.751837 109.317885
Trader-81 10.440355 11.803981
Trader-82 98.600458 111.268060
Trader-83 94.701235 106.762417
Trader-84 95.191965 107.210087
Trader-85 23.702136 26.704371
Trader-86 97.996905 110.234023
Trader-87 13.494046 15.188063
Trader-88 42.485733 47.787911
Trader-89 10.274767 11.558943
Trader-9 4.300391 7.234276
Trader-90 63.395668 71.246219
Trader-91 30.105324 33.833690
Trader-92 29.687105 33.354870
Trader-93 90.659028 101.727653
Trader-94 64.640329 72.508123
Trader-95 5.888984 6.608673
Trader-96 75.341113 84.447589
Trader-97 0.984556 1.104331
Trader-98 13.179924 14.778531
Trader-99 94.978600 106.349961

101 rows × 2 columns


In [20]:
total = pm.book.groupby('outcome').shares.sum()
total


Out[20]:
outcome
0     7099.632084
1    14538.530025
Name: shares, dtype: float64

In [21]:
pm.book.groupby('outcome').paid.sum()


Out[21]:
outcome
0    5398.27157
1    2000.00000
Name: paid, dtype: float64

In [22]:
pm.book.groupby('outcome').shares.sum()


Out[22]:
outcome
0     7099.632084
1    14538.530025
Name: shares, dtype: float64

In [23]:
pm.p


Out[23]:
array([ 0.23309422,  0.76690578])

In [24]:
pm.book.groupby('outcome').sum().values/pm.book.groupby('outcome').sum().values.sum()


Out[24]:
array([[ 0.72966659],
       [ 0.27033341]])

Plot the market prediction history


In [25]:
pl.plot(pm.history())
pl.ylim([0.,1.])
pl.legend(['outcome 0', 'outcome 1'])
pl.title('%d Trades, total market value=%2.2f EUR'%(n, pm.market_value))


Out[25]:
<matplotlib.text.Text at 0x1149816d0>

The book of trades


In [26]:
book = pm.book
book['possible_win'] = pm.book.owed - pm.book.paid
book['p0'] = pm.history()[:,0]
book['p1'] = pm.history()[:,1]
book


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-26-b0e34ecd7a7d> in <module>()
      1 book = pm.book
----> 2 book['possible_win'] = pm.book.owed - pm.book.paid
      3 book['p0'] = pm.history()[:,0]
      4 book['p1'] = pm.history()[:,1]
      5 book

/Users/pire/venv/jupyter/lib/python2.7/site-packages/pandas/core/generic.pyc in __getattr__(self, name)
   2148                 return self[name]
   2149             raise AttributeError("'%s' object has no attribute '%s'" %
-> 2150                                  (type(self).__name__, name))
   2151 
   2152     def __setattr__(self, name, value):

AttributeError: 'DataFrame' object has no attribute 'owed'

In [ ]:
pm.market_value

In [ ]:
pm.p

In [ ]:


In [ ]:


In [ ]: