Trade

class abce.Trade(id, agent_parameters, simulation_parameters, group, trade_logging, database, check_unchecked_msgs, expiring, perishable, resource_endowment, start_round=None)[source]

Bases: object

Agents can trade with each other. The clearing of the trade is taken care of fully by ABCE. Selling a good works in the following way:

  1. An agent sends an offer. sell()

    ABCE does not allow you to sell the same good twice; self.free(good) shows how much good is not reserved yet

  2. Next subround: An agent receives the offer get_offers(), and can accept(), reject() or partially accept it. accept()

    The good is credited and the price is deducted from the agent’s possessions.

  3. Next subround:

    • in case of acceptance the money is automatically credited.
    • in case of partial acceptance the money is credited and part of the reserved good is unblocked.
    • in case of rejection the good is unblocked.

Analogously for buying: buy()

Example:

# Agent 1
def sales(self):
    self.remember_trade = self.sell('Household', 0, 'cookies', quantity=5, price=self.price)

# Agent 2
def receive_sale(self):
    oo = self.get_offers('cookies')
    for offer in oo:
        if offer.price < 0.3:
            try:
                self.accept(offer)
            except NotEnoughGoods:
                self.accept(offer, self['money'] / offer.price)
        else:
            self.reject(offer)

# Agent 1, subround 3
def learning(self):
    offer = self.info(self.remember_trade)
    if offer.status == 'reject':
        self.price *= .9
    elif offer.status = 'accepted':
        self.price *= offer.final_quantity / offer.quantity

Example:

# Agent 1
def sales(self):
    self.remember_trade = self.sell('Household', 0, 'cookies', quantity=5, price=self.price, currency='dollars')

# Agent 2
def receive_sale(self):
    oo = self.get_offers('cookies')
    for offer in oo:
        if ((offer.currency == 'dollars' and offer.price < 0.3 * exchange_rate)
            or (offer.currency == 'euros' and dollars'offer.price < 0.3)):

            try:
                self.accept(offer)
            except NotEnoughGoods:
                self.accept(offer, self['money'] / offer.price)
        else:
            self.reject(offer)

If we did not implement a barter class, but one can use this class as a barter class,

accept(offer, quantity=-999, epsilon=1e-11)[source]

The buy or sell offer is accepted and cleared. If no quantity is given the offer is fully accepted; If a quantity is given the offer is partial accepted.

Args:

offer:
the offer the other party made
quantity:
quantity to accept. If not given all is accepted
epsilon (optional):
if you have floating point errors, a quantity or prices is a fraction of number to high or low. You can increase the floating point tolerance. See troubleshooting – floating point problems
Return:
Returns a dictionary with the good’s quantity and the amount paid.
buy(receiver, good, quantity, price, currency='money', epsilon=1e-11)[source]

Sends a offer to buy a particular good to somebody. The money promised is reserved. (self.free(currency), shows the not yet reserved goods)

Args:
receiver:
The name of the receiving agent a tuple (group, id). e.G. (‘firm’, 15)
‘good’:
name of the good
quantity:
maximum units disposed to buy at this price
price:
price per unit
currency:
is the currency of this transaction (defaults to ‘money’)
epsilon (optional):
if you have floating point errors, a quantity or prices is a fraction of number to high or low. You can increase the floating point tolerance. See troubleshooting – floating point problems
get_buy_offers(good, sorted=True, descending=False, shuffled=True)[source]
get_buy_offers_all(descending=False, sorted=True)[source]
get_offers(good, sorted=True, descending=False, shuffled=True)[source]

returns all offers of the ‘good’ ordered by price.

Offers that are not accepted in the same subround (def block) are automatically rejected. However you can also manually reject.

peek_offers can be used to look at the offers without them being rejected automatically

Args:
good:
the good which should be retrieved
sorted(bool, default=True):
Whether offers are sorted by price. Faster if False.
descending(bool, default=False):
False for descending True for ascending by price
shuffled(bool, default=True):
whether the order of messages is randomized or correlated with the ID of the agent. Setting this to False speeds up the simulation considerably, but introduces a bias.
Returns:
A list of abce.trade.Offer ordered by price.

Example:

offers = get_offers('books')
for offer in offers:
    if offer.price < 50:
        self.accept(offer)
    elif offer.price < 100:
        self.accept(offer, 1)
    else:
        self.reject(offer)  # optional
get_offers_all(descending=False, sorted=True)[source]

returns all offers in a dictionary, with goods as key. The in each goods-category the goods are ordered by price. The order can be reversed by setting descending=True

Offers that are not accepted in the same subround (def block) are automatically rejected. However you can also manually reject.

Args:

descending(optional):
is a bool. False for descending True for ascending by price
sorted(default=True):
Whether offers are sorted by price. Faster if False.

Returns:

a dictionary with good types as keys and list of abce.trade.Offer as values

Example:

oo = get_offers_all(descending=False)
for good_category in oo:
   print('The cheapest good of category' + good_category
   + ' is ' + good_category[0])
   for offer in oo[good_category]:
       if offer.price < 0.5:
           self.accept(offer)

for offer in oo.beer:
   print(offer.price, offer.sender)
get_sell_offers(good, sorted=True, descending=False, shuffled=True)[source]
get_sell_offers_all(descending=False, sorted=True)[source]
give(receiver, good, quantity, epsilon=1e-11)[source]

gives a good to another agent

Args:
receiver:
The name of the receiving agent a tuple (group, id). e.G. (‘firm’, 15)
good:
the good to be transfered
quantity:
amount to be transfered
epsilon (optional):
if you have floating point errors, a quantity or prices is a fraction of number to high or low. You can increase the floating point tolerance. See troubleshooting – floating point problems

Raises:

AssertionError, when good smaller than 0.
Return:
Dictionary, with the transfer, which can be used by self.log(…).

Example:

self.log('taxes', self.give('money': 0.05 * self['money'])
peak_buy_offers(good, sorted=True, descending=False, shuffled=True)[source]
peak_offers(good, sorted=True, descending=False, shuffled=True)[source]

returns a peak on all offers of the ‘good’ ordered by price. Peaked offers can not be accepted or rejected and they do not expire.

Args:
good:
the good which should be retrieved descending(bool, default=False): False for descending True for ascending by price
Returns:
A list of offers ordered by price

Example:

offers = get_offers('books')
for offer in offers:
    if offer.price < 50:
        self.accept(offer)
    elif offer.price < 100:
        self.accept(offer, 1)
    else:
        self.reject(offer)  # optional
peak_sell_offers(good, sorted=True, descending=False, shuffled=True)[source]
reject(offer)[source]

Rejects and offer, if the offer is subsequently accepted in the same subround it is accepted’. Peaked offers can not be rejected.

Args:

offer:
the offer to be rejected
sell(receiver, good, quantity, price, currency='money', epsilon=1e-11)[source]

Sends a offer to sell a particular good to somebody. The amount promised is reserved. (self.free(good), shows the not yet reserved goods)

Args:
receiver:
the receiving agent
‘good’:
name of the good
quantity:
maximum units disposed to buy at this price
price:
price per unit
currency:
is the currency of this transaction (defaults to ‘money’)
epsilon (optional):
if you have floating point errors, a quantity or prices is a fraction of number to high or low. You can increase the floating point tolerance. See troubleshooting – floating point problems
Returns:
A reference to the offer. The offer and the offer status can be accessed with self.info(offer_reference).

Example:

def subround_1(self):
    self.offer = self.sell('household', 1, 'cookies', quantity=5, price=0.1)

def subround_2(self):
    offer = self.info(self.offer)
    if offer.status == 'accepted':
        print(offer.final_quantity , 'cookies have be bougth')
    else:
        offer.status == 'rejected':
        print('On diet')
take(receiver, good, quantity, epsilon=1e-11)[source]

take a good from another agent. The other agent has to accept. using self.accept()

Args:

receiver:
the receiving agent
good:
the good to be taken
quantity:
the quantity to be taken
epsilon (optional):
if you have floating point errors, a quantity or prices is a fraction of number to high or low. You can increase the floating point tolerance. See troubleshooting – floating point problems
abce.trade.Offer(sender, receiver, good, quantity, price, currency, sell, id, made)[source]