def test_marginal_utility(): """Test the marginal utility.""" currency_holdings = {"FET": 100} utility_params = {"good_id": 20.0} exchange_params = {"FET": 10.0} good_holdings = {"good_id": 2} tx_fee = 9 preferences = Preferences() preferences.init( utility_params_by_good_id=utility_params, exchange_params_by_currency_id=exchange_params, tx_fee=tx_fee, ) ownership_state = OwnershipState() delta_good_holdings = {"good_id": 1} delta_currency_holdings = {"FET": -5} ownership_state.init( amount_by_currency_id=currency_holdings, quantities_by_good_id=good_holdings, ) marginal_utility = preferences.marginal_utility( ownership_state=ownership_state, delta_quantities_by_good_id=delta_good_holdings, delta_amount_by_currency_id=delta_currency_holdings, ) assert marginal_utility is not None, "Marginal utility must not be none."
def test_linear_utility(): """Calculate the linear_utility and checks that it is not none.""" currency_holdings = {"FET": 100} utility_params = {"good_id": 20.0} exchange_params = {"FET": 10.0} tx_fee = 9 preferences = Preferences( utility_params_by_good_id=utility_params, exchange_params_by_currency_id=exchange_params, tx_fee=tx_fee, ) linear_utility = preferences.linear_utility( amount_by_currency_id=currency_holdings) assert linear_utility is not None, "Linear utility must not be none."
def test_logarithmic_utility(): """Calculate the logarithmic utility and checks that it is not none..""" utility_params = {"good_id": 20.0} exchange_params = {"FET": 10.0} good_holdings = {"good_id": 2} tx_fee = 9 preferences = Preferences( utility_params_by_good_id=utility_params, exchange_params_by_currency_id=exchange_params, tx_fee=tx_fee, ) log_utility = preferences.logarithmic_utility( quantities_by_good_id=good_holdings) assert log_utility is not None, "Log_utility must not be none."
def is_profitable_transaction(self, preferences: Preferences, ownership_state_after_locks: OwnershipState, transaction_msg: TransactionMessage) -> bool: """ Check if a transaction is profitable. Is it a profitable transaction? - apply all the locks for role. - check if the transaction is consistent with the locks (enough money/holdings) - check that we gain score. :param preferences: the preferences of the agent :param ownership_state_after_locks: the ownership state after the transaction messages applied. :param transaction_msg: the transaction_msg :return: True if the transaction is good (as stated above), False otherwise. """ if not ownership_state_after_locks.check_transaction_is_consistent( transaction_msg): return False proposal_delta_score = preferences.get_score_diff_from_transaction( ownership_state_after_locks, transaction_msg) if proposal_delta_score >= 0: return True else: return False
def test_preferences_properties(): """Test the properties of the preferences class.""" preferences = Preferences() with pytest.raises(AssertionError): preferences.exchange_params_by_currency_id with pytest.raises(AssertionError): preferences.utility_params_by_good_id
def setup_class(cls): """Initialise the decision maker.""" cls._patch_logger() cls.multiplexer = Multiplexer([_make_dummy_connection()]) private_key_pem_path = os.path.join(CUR_PATH, "data", "fet_private_key.txt") eth_private_key_pem_path = os.path.join(CUR_PATH, "data", "fet_private_key.txt") cls.wallet = Wallet({ FETCHAI: private_key_pem_path, ETHEREUM: eth_private_key_pem_path }) cls.ledger_apis = LedgerApis({FETCHAI: DEFAULT_FETCHAI_CONFIG}, FETCHAI) cls.agent_name = "test" cls.identity = Identity(cls.agent_name, addresses=cls.wallet.addresses, default_address_key=FETCHAI) cls.ownership_state = OwnershipState() cls.preferences = Preferences() cls.decision_maker = DecisionMaker( identity=cls.identity, wallet=cls.wallet, ledger_apis=cls.ledger_apis, ) cls.multiplexer.connect() cls.tx_id = "transaction0" cls.tx_sender_addr = "agent_1" cls.tx_counterparty_addr = "pk" cls.info = {"some_info_key": "some_info_value"} cls.ledger_id = "fetchai" cls.decision_maker.start()
def setup_class(cls): """Initialise the decision maker.""" cls._patch_logger() cls.multiplexer = Multiplexer( [DummyConnection(connection_id=DUMMY_CONNECTION_PUBLIC_ID)]) cls.outbox = OutBox(cls.multiplexer) private_key_pem_path = os.path.join(CUR_PATH, "data", "fet_private_key.txt") eth_private_key_pem_path = os.path.join(CUR_PATH, "data", "fet_private_key.txt") cls.wallet = Wallet({ FETCHAI: private_key_pem_path, ETHEREUM: eth_private_key_pem_path }) cls.ledger_apis = LedgerApis({FETCHAI: DEFAULT_FETCHAI_CONFIG}, FETCHAI) cls.agent_name = "test" cls.ownership_state = OwnershipState() cls.preferences = Preferences() cls.decision_maker = DecisionMaker( agent_name=cls.agent_name, max_reactions=MAX_REACTIONS, outbox=cls.outbox, wallet=cls.wallet, ledger_apis=cls.ledger_apis, ) cls.multiplexer.connect() cls.tx_id = "transaction0" cls.tx_sender_addr = "agent_1" cls.tx_counterparty_addr = "pk" cls.info = {"some_info_key": "some_info_value"} cls.ledger_id = "fetchai" cls.decision_maker.start()
def test_preferences_init(): """Test the preferences init().""" utility_params = {"good_id": 20.0} exchange_params = {"FET": 10.0} tx_fee = 9 preferences = Preferences() preferences.init( exchange_params_by_currency_id=exchange_params, utility_params_by_good_id=utility_params, tx_fee=tx_fee, ) assert preferences.utility_params_by_good_id is not None assert preferences.exchange_params_by_currency_id is not None assert preferences.transaction_fees["seller_tx_fee"] == 4 assert preferences.transaction_fees["buyer_tx_fee"] == 5 assert preferences.is_initialized
def _generate_candidate_proposals( self, preferences: Preferences, ownership_state_after_locks: OwnershipState, is_seller: bool, tx_fee: float): """ Generate proposals from the agent in the role of seller/buyer. :param preferences: the preferences of the agent :param ownership_state_after_locks: the ownership state after the transaction messages applied. :param is_seller: the bool indicating whether the agent is a seller. :return: a list of proposals in Description form """ good_pbk_to_quantities = self._supplied_goods( ownership_state_after_locks.good_holdings ) if is_seller else self._demanded_goods( ownership_state_after_locks.good_holdings) share_of_tx_fee = round(tx_fee / 2.0, 2) nil_proposal_dict = { good_pbk: 0 for good_pbk, quantity in good_pbk_to_quantities } # type: Dict[str, int] proposals = [] for good_pbk, quantity in good_pbk_to_quantities: if is_seller and quantity == 0: continue proposal_dict = nil_proposal_dict proposal_dict[good_pbk] = 1 proposal = build_goods_description( good_pbk_to_quantities=proposal_dict, is_supply=is_seller) if is_seller: delta_good_holdings = { good_pbk: quantity * -1 for good_pbk, quantity in proposal_dict.items() } # type: Dict[str, int] else: delta_good_holdings = proposal_dict marginal_utility_from_delta_good_holdings = preferences.marginal_utility( ownership_state_after_locks, delta_good_holdings) switch = -1 if is_seller else 1 breakeven_price = round(marginal_utility_from_delta_good_holdings, 2) * switch if self.is_world_modeling: pass # assert self.world_state is not None, "Need to provide world state if is_world_modeling=True." # proposal.values["price"] = world_state.expected_price(good_pbk, round(marginal_utility_from_delta_holdings, 2), is_seller, share_of_tx_fee) else: if is_seller: proposal.values[ "price"] = breakeven_price + share_of_tx_fee + ROUNDING_ADJUSTMENT else: proposal.values[ "price"] = breakeven_price - share_of_tx_fee - ROUNDING_ADJUSTMENT proposal.values["seller_tx_fee"] = share_of_tx_fee proposal.values["buyer_tx_fee"] = share_of_tx_fee if not proposal.values["price"] > 0: continue proposals.append(proposal) return proposals
def test_score_diff_from_transaction(): """Test the difference between the scores.""" good_holdings = {"good_id": 2} currency_holdings = {"FET": 100} utility_params = {"good_id": 20.0} exchange_params = {"FET": 10.0} tx_fee = 3 ownership_state = OwnershipState(amount_by_currency_id=currency_holdings, quantities_by_good_id=good_holdings) preferences = Preferences( utility_params_by_good_id=utility_params, exchange_params_by_currency_id=exchange_params, tx_fee=tx_fee, ) tx_message = TransactionMessage( performative=TransactionMessage.Performative.PROPOSE_FOR_SETTLEMENT, skill_callback_ids=[PublicId(AUTHOR, "a_skill", "0.1.0")], tx_id="transaction0", tx_sender_addr="agent_1", tx_counterparty_addr="pk", tx_amount_by_currency_id={"FET": -20}, tx_sender_fee=preferences.transaction_fees["seller_tx_fee"], tx_counterparty_fee=preferences.transaction_fees["buyer_tx_fee"], tx_quantities_by_good_id={"good_id": 10}, info={"some_info_key": "some_info_value"}, ledger_id="fetchai", tx_nonce="transaction nonce", ) cur_score = preferences.utility(quantities_by_good_id=good_holdings, amount_by_currency_id=currency_holdings) new_state = ownership_state.apply_transactions([tx_message]) new_score = preferences.utility( quantities_by_good_id=new_state.quantities_by_good_id, amount_by_currency_id=new_state.amount_by_currency_id, ) dif_scores = new_score - cur_score score_difference = preferences.utility_diff_from_transaction( ownership_state=ownership_state, tx_message=tx_message) assert ( score_difference == dif_scores ), "The calculated difference must be equal to the return difference from the function."
def test_utility(): """Calculate the score.""" utility_params = {"good_id": 20.0} exchange_params = {"FET": 10.0} currency_holdings = {"FET": 100} good_holdings = {"good_id": 2} tx_fee = 9 preferences = Preferences( utility_params_by_good_id=utility_params, exchange_params_by_currency_id=exchange_params, tx_fee=tx_fee, ) score = preferences.utility( quantities_by_good_id=good_holdings, amount_by_currency_id=currency_holdings, ) linear_utility = preferences.linear_utility( amount_by_currency_id=currency_holdings) log_utility = preferences.logarithmic_utility( quantities_by_good_id=good_holdings) assert ( score == log_utility + linear_utility ), "The score must be equal to the sum of log_utility and linear_utility."
def setup_class(cls): """Initialise the decision maker.""" cls._patch_logger() cls.multiplexer = Multiplexer([DummyConnection()]) cls.outbox = OutBox(cls.multiplexer) private_key_pem_path = os.path.join(CUR_PATH, "data", "fet_private_key.txt") cls.wallet = Wallet({FETCHAI: private_key_pem_path}) cls.ledger_apis = LedgerApis({FETCHAI: DEFAULT_FETCHAI_CONFIG}) cls.agent_name = "test" cls.ownership_state = OwnershipState() cls.preferences = Preferences() cls.decision_maker = DecisionMaker(agent_name=cls.agent_name, max_reactions=MAX_REACTIONS, outbox=cls.outbox, wallet=cls.wallet, ledger_apis=cls.ledger_apis) cls.multiplexer.connect()
def setup_class(cls): """Initialise the class.""" cls.ownership_state = OwnershipState() cls.preferences = Preferences()