kiedanski / pymarket

PyMarket is a python library aimed to ease the design, simulation and comparison of different market mechanisms.
https://pymarket.readthedocs.io/en/latest/
MIT License
27 stars 4 forks source link

Error when two bids submitted that cannot be settled #25

Open 20robin06 opened 3 years ago

20robin06 commented 3 years ago

Description

When two bids are submitted that cannot be settled I receive an error:

i.e.:

r = np.random.RandomState(1234)
mar = pm.Market()

mar.accept_bid(1, 5, 4, True, 0)
mar.accept_bid(1, 5, 5, True, 0)

mar.accept_bid(1, 6, 6, False, 0)
mar.accept_bid(1, 6, 7, False, 0))

What I Did

The command I ran:

bids = mar.bm.get_df()
transactions, extras = mar.run('p2p')
stats = mar.statistics()

The error message:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-128-a1f818cf5b34> in <module>
      1 bids = mar.bm.get_df()
----> 2 transactions, extras = mar.run('uniform')

c:\projects\colombiadata\venv\lib\site-packages\pymarket\market.py in run(self, algo, *args, **kwargs)
    150         df = self.bm.get_df()
    151         mec = MECHANISM[algo](df, *args, **kwargs)
--> 152         transactions, extra = mec.run()
    153         self.transactions = transactions
    154         self.extra = extra

c:\projects\colombiadata\venv\lib\site-packages\pymarket\mechanisms\mechanism.py in run(self)
    170     def run(self):
    171         """Runs the mechanisms"""
--> 172         trans, extra = self._run()
    173         trans = self._cleanup(trans)
    174         return trans, extra

c:\projects\colombiadata\venv\lib\site-packages\pymarket\mechanisms\mechanism.py in _run(self)
    133         N = bids.shape[0]
    134         if (bids.loc[bids['buying']].shape[0] not in [0, N]):
--> 135             trans, extra = self.algo(self.bids, *self.args, **self.kwargs)
    136             return trans, extra
    137         else:

<ipython-input-125-14a8cb0a7b32> in uniform_price_mechanism(bids)
     16 
     17     ## Filter only the trading bids.
---> 18     buying_bids = buying_bids.iloc[: b_ + 1, :]
     19     selling_bids = selling_bids.iloc[: s_ + 1, :]
     20 

TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
zhanghaoyang1993 commented 2 years ago

I guess it is becuase of the p2p clearing process here (file 'p2p_random.py', line:100):

while quantities.sum() > 0 and tmp_active.sum() > 0:

It means go into the loop when there are unmatched quantity or there are possible trade pairs exist (even though when buy price is lower than sell price). As a result, if the sell prices of remaining sellers are higher than the buy prices of remaining buyer, there will be a bug. I recommand to add a new condition statement into the loop to avoid the problem.