Trade

class abce.Trade

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()

    The good offered is blocked and self.possession(...) does not account for it.

  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 possesions.

  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 blocked 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.possession('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
accept()

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()

commits to sell the quantity of good at price

The goods are not in haves or self.count(). When the offer is rejected it is automatically re-credited. When the offer is accepted the money amount is credited. (partial acceptance accordingly)

Args:
receiver_group:
group of the receiving agent
receiver_id:
number of the receiving agent
‘good’:
name of the good
quantity:
maximum units disposed to buy at this price
price:
price per unit
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_offers()

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 manualy reject.

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

Args:
good:
the good which should be retrieved
descending(bool, default=False):
False for descending True for ascending by price
sorted(bool, default=True):
Whether offers are sorted by price. Faster if False.
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()

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_group, offer.sender_id)
give()

gives a good to another agent

Args:

receiver_group:
Group name of the receiver
receiver_id:
id number of the receiver
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.possession('money'))
peak_offers()

returns a peak on all offers of the ‘good’ ordered by price. Peaked offers can not be accepted or rejected, but 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
reject()

Rejects the offer offer

Args:
offer: the offer the other party made (offer not quote!)
retract()

The agent who made a buy or sell offer can retract it

The offer an agent made is deleted at the end of the sub-round and the committed good reappears in the haves. However if another agent accepts in the same round the trade will be cleared and not retracted.

Args:
offer: the offer he made with buy or sell (offer not quote!)
sell()

commits to sell the quantity of good at price

The good is not available for the agent. When the offer is rejected it is automatically re-credited. When the offer is accepted the money amount is credited. (partial acceptance accordingly)

Args:
receiver_group:
group of the receiving agent
receiver_id:
number of the receiving agent
‘good’:
name of the good
quantity:
maximum units disposed to buy at this price
price:
price per unit
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()

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

Args:

receiver_group:
group of the receiving agent
receiver_id:
number of 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()

This is an offer container that is send to the other agent. You can access the offer container both at the receiver as well as at the sender, if you have saved the offer. (e.G. self.offer = self.sell(...))

it has the following properties:
sender_group:
this is the group name of the sender
sender_id:
this is the ID of the sender
receiver_group:
This is the group name of the receiver
receiver_id:
this is the ID of the sender
good:
the good offered or demanded
quantity:
the quantity offered or demanded
price:
the suggested tansaction price
buysell:
this can have the values ‘b’ for buy; ‘s’ for sell; ‘qb’ for a nonbinding buy quote; and ‘qs’ for a nonbinding sell quote
status:
‘new’:
has been created, but not answered
‘accepted’:
trade fully accepted
‘rejected’:
trade rejected
‘pending’:
offer has not yet answered, and is not older than one round.
‘perished’:
the perishable good was not accepted by the end of the round and therefore perished.
final_quantity:
If the offer has been answerd this returns the actual quantity bought or sold. (Equal to quantity if the offer was accepted fully)
id:
a unique identifier