Source code for abce.quote

# Copyright 2012 Davoud Taghawi-Nejad
#
# Module Author: Davoud Taghawi-Nejad
#
# ABCE is open-source software. If you are using ABCE for your research you are
# requested the quote the use of this software.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License and quotation of the
# author. You may obtain a copy of the License at
#       http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
from collections import defaultdict
from random import shuffle


[docs]class Quotation(object): __slots__ = ['sender_group', 'sender_id', 'receiver_group', 'receiver_id', 'good', 'quantity', 'price', 'buysell', 'id'] def __init__(self, sender_group, sender_id, receiver_group, receiver_id, good, quantity, price, buysell, id): self.sender_group = sender_group self.sender_id = sender_id self.receiver_group = receiver_group self.receiver_id = receiver_id self.good = good self.quantity = quantity self.price = price self.buysell = buysell self.id = id
[docs]class Quote(object): """ Quotes as opposed to trades are uncommitted offers. They can be made even if they agent can not fullfill them. With :meth:`~abceagent.Trade.accept_quote` and :meth:`~abceagent.Trade.accept_quote_partial`, the receiver of a quote can transform them into a trade. """
[docs] def get_quotes(self, good, descending=False): """ self.get_quotes() returns all new quotes and removes them. The order is randomized. Args: good: the good which should be retrieved descending(bool,default=False): False for descending True for ascending by price Returns: list of quotes ordered by price Example:: quotes = self.get_quotes() """ ret = [] for offer_id in list(self._quotes.keys()): if self._quotes[offer_id].good == good: ret.append(self._quotes[offer_id]) del self._quotes[offer_id] ret.sort(key=lambda objects: objects.price, reverse=descending) return ret
[docs] def get_quotes_all(self, descending=False): """ self.get_quotes_all() returns a dictionary with all now new quotes ordered by the good type and removes them. The order is randomized. Args: descending(bool,default=False): False for descending True for ascending by price Returns: dictionary of list of quotes ordered by price. The dictionary itself is ordered by price. Example:: quotes = self.get_quotes() """ ret = defaultdict(list) for quote in self._quotes: key = self._quotes[quote].good ret[key].append(self._quotes[quote]) for key in list(ret.keys()): shuffle(ret[key]) ret[key].sort(key=lambda objects: objects.price, reverse=descending) self._quotes = {} return ret
[docs] def accept_quote(self, quote): """ makes a commited buy or sell out of the counterparties quote. For example, if you receive a buy quote you can accept it and a sell offer is send to the offering party. Args:: quote: buy or sell quote that is accepted """ if quote.buysell == 'qs': self.buy(quote.sender_group, quote.sender_id, quote.good, quote.quantity, quote.price) else: self.sell(quote.sender_group, quote.sender_id, quote.good, quote.quantity, quote.price)
[docs] def accept_quote_partial(self, quote, quantity): """ makes a commited buy or sell out of the counterparties quote Args:: quote: buy or sell quote that is accepted quantity: the quantity that is offered/requested it should be less than propsed in the quote, but this is not enforced. """ if quote.buysell == 'qs': self.buy(quote.sender_group, quote.sender_id, quote.good, quantity, quote.price) else: self.sell(quote.sender_group, quote.sender_id, quote.good, quantity, quote.price)
[docs] def quote_sell(self, receiver, good=None, quantity=None, price=None): """ quotes a price to sell quantity of 'good' to a receiver. Use None, if you do not want to specify a value. price (money) per unit offers a deal without checking or committing resources Args: receiver_group: agent group name of the agent receiver_id: the agent's id number 'good': name of the good quantity: maximum units disposed to sell at this price price: price per unit """ offer = Quotation(sender_group=self.group, sender_id=self.id, receiver_group=receiver[0], receiver_id=receiver[1], good=good, quantity=quantity, price=price, buysell='qs', id=self._offer_counter()) self._send(receiver[0], receiver[1], '_q', offer) return offer
[docs] def quote_buy(self, receiver, good=None, quantity=None, price=None): """ quotes a price to buy quantity of 'good' a receiver. Use None, if you do not want to specify a value. price (money) per unit offers a deal without checking or committing resources Args: receiver_group: agent group name of the agent receiver_id: the agent's id number 'good': name of the good quantity: maximum units disposed to buy at this price price: price per unit """ offer = Quotation(sender_group=self.group, sender_id=self.id, receiver_group=receiver[0], receiver_id=receiver[1], good=good, quantity=quantity, price=price, buysell='qb', id=self._offer_counter()) self._send(receiver[0], receiver[1], '_q', offer) return offer