Trader¶
-
class
abcEconomics.agents.trader.
Trader
(id, agent_parameters, simulation_parameters)[source]¶ Bases:
object
Agents can trade with each other. The clearing of the trade is taken care of fully by abcEconomics. Selling a good works in the following way:
An agent sends an offer.
sell()
The good offered is blocked and self.possession(…) does shows the decreased amount.
Next subround: An agent receives the offer
get_offers()
, and canaccept()
,reject()
or partially accept it.accept()
The good is credited and the price is deducted from the agent’s possessions.
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['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]¶ 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:
- 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_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
abcEconomics.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 ofabcEconomics.trade.Offer
as valuesExample:
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
(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.possession('money'))
-
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
-
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]¶ 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
- 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_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
-
abcEconomics.agents.trader.
Offer
(sender, receiver, good, quantity, price, currency, sell, status, final_quantity, id, made, status_round)[source]¶ 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:
- this is the name of the sender
- receiver:
- This is the name of the receiver
- currency:
- The other good against which the good is traded.
- good:
- the good offered or demanded
- quantity:
- the quantity offered or demanded
- price:
- the suggested transaction price
- sell:
- this can have the values False for buy; True for sell
- 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