def test_match_recommendations_one_offer_multiple_bids(self, market):
        """Test match_recommendations() method of TwoSidedMarket using 1 offer N bids."""
        bid1 = Bid("bid_id1", pendulum.now(), price=1, energy=1, buyer="Buyer")
        bid2 = Bid("bid_id2", pendulum.now(), price=1, energy=1, buyer="Buyer")
        offer1 = Offer("offer_id1",
                       pendulum.now(),
                       price=2,
                       energy=2,
                       seller="Seller")

        market.bids = {"bid_id1": bid1, "bid_id2": bid2}
        market.offers = {"offer_id1": offer1}

        recommendations = [
            BidOfferMatch(
                bids=[bid.serializable_dict() for bid in market.bids.values()],
                offers=[
                    offer.serializable_dict()
                    for offer in market.offers.values()
                ],
                trade_rate=1,
                selected_energy=1,
                market_id=market.id).serializable_dict()
        ]
        market.match_recommendations(recommendations)
        assert len(market.trades) == 2
    def test_match_recommendations_fake_offer_bid(self, market,
                                                  two_sided_market_matching):
        """Test the case when an offer or bid which don't belong to market is sent."""
        bid = Bid("bid_id1", pendulum.now(), price=2, energy=1, buyer="B")
        offer = Offer("id", pendulum.now(), price=2, energy=1, seller="other")

        market.bids = {"bid_id1": bid}

        recommendations = [
            BidOfferMatch(bids=[bid.serializable_dict()],
                          offers=[offer.serializable_dict()],
                          trade_rate=2,
                          selected_energy=1,
                          market_id=market.id).serializable_dict()
        ]
        # The sent offer isn't in market offers, should be skipped
        market.match_recommendations(recommendations)
        assert len(market.trades) == 0
        assert not market.validate_bid_offer_match.called
        assert not market.accept_bid_offer_pair.called
        assert not market._replace_offers_bids_with_residual_in_recommendations_list.called

        market.offers = {offer.id: offer}
        market.bids = {}
        # The sent bid isn't in market offers, should be skipped
        market.match_recommendations(recommendations)
        assert len(market.trades) == 0
        assert not market.validate_bid_offer_match.called
        assert not market.accept_bid_offer_pair.called
        assert not market._replace_offers_bids_with_residual_in_recommendations_list.called
    def test_double_sided_validate_requirements_satisfied(self, market):
        offer = Offer("id",
                      pendulum.now(),
                      2,
                      2,
                      "other",
                      2,
                      requirements=[{
                          "trading_partners": ["bid_id2"]
                      }],
                      attributes={"energy_type": "Green"})
        bid = Bid("bid_id",
                  pendulum.now(),
                  9,
                  10,
                  "B",
                  9,
                  buyer_id="bid_id",
                  requirements=[],
                  attributes={})
        with pytest.raises(InvalidBidOfferPairException):
            # should raise an exception as buyer_id is not in trading_partners
            market._validate_requirements_satisfied(bid, offer)
        bid.buyer_id = "bid_id2"
        market._validate_requirements_satisfied(
            bid, offer)  # Should not raise any exceptions
        bid.requirements.append({"energy_type": ["Grey"]})
        with pytest.raises(InvalidBidOfferPairException):
            # should raise an exception as energy_type of offer needs to be in [Grey, ]
            market._validate_requirements_satisfied(bid, offer)

        # Adding another requirement that is satisfied, should not raise an exception
        bid.requirements.append({"energy_type": ["Green"]})
        market._validate_requirements_satisfied(bid, offer)
 def test_get_bids(self, market):
     """Test the get_bids() method of TwoSidedMarket."""
     market.bids = {
         "bid1": Bid("bid1",
                     pendulum.now(),
                     9,
                     10,
                     "B",
                     9,
                     buyer_id="bid_id"),
         "bid2": Bid("bid2",
                     pendulum.now(),
                     9,
                     10,
                     "B",
                     9,
                     buyer_id="bid_id"),
         "bid3": Bid("bid3",
                     pendulum.now(),
                     9,
                     10,
                     "B",
                     9,
                     buyer_id="bid_id")
     }
     assert market.get_bids() == market.bids
Beispiel #5
0
    def _populate_market_bids_offers(self):
        self.market.offers = {
            "id1": Offer("id1", now(), 3, 3, "seller", 3),
            "id2": Offer("id2", now(), 0.5, 1, "seller", 0.5)
        }

        self.market.bids = {
            "id3": Bid("id3", now(), 1, 1, "buyer", 1),
            "id4": Bid("id4", now(), 0.5, 1, "buyer", 1)
        }
 def test_delete_bid(self, market):
     """Test the delete_bid method of TwoSidedMarket."""
     bid1 = Bid("bid1", pendulum.now(), 9, 10, "B", 9, buyer_id="bid_id")
     bid2 = Bid("bid2", pendulum.now(), 9, 10, "B", 9, buyer_id="bid_id")
     market.bids = {
         "bid1": bid1,
         "bid2": bid2,
     }
     market.delete_bid("bid1")
     assert "bid1" not in market.bids
     assert len(market.bids) == 1
     market.delete_bid(bid2)
     assert len(market.bids) == 0
     with pytest.raises(BidNotFoundException):
         market.delete_bid(bid2)
 def test_matching_list_gets_updated_with_residual_offers(self):
     matches = [
         BidOfferMatch(offers=[
             Offer("offer_id", pendulum.now(), 1, 1,
                   "S").serializable_dict()
         ],
                       selected_energy=1,
                       bids=[
                           Bid("bid_id", pendulum.now(), 1, 1,
                               "B").serializable_dict()
                       ],
                       trade_rate=1,
                       market_id="").serializable_dict(),
         BidOfferMatch(offers=[
             Offer("offer_id2", pendulum.now(), 2, 2,
                   "S").serializable_dict()
         ],
                       selected_energy=2,
                       bids=[
                           Bid("bid_id2", pendulum.now(), 2, 2,
                               "B").serializable_dict()
                       ],
                       trade_rate=1,
                       market_id="").serializable_dict()
     ]
     offer_trade = Trade("trade",
                         1,
                         Offer("offer_id", pendulum.now(), 1, 1, "S"),
                         "S",
                         "B",
                         residual=Offer("residual_offer", pendulum.now(),
                                        0.5, 0.5, "S"))
     bid_trade = Trade("bid_trade",
                       1,
                       Bid("bid_id2", pendulum.now(), 1, 1, "S"),
                       "S",
                       "B",
                       residual=Bid("residual_bid_2", pendulum.now(), 1, 1,
                                    "S"))
     matches = TwoSidedMarket._replace_offers_bids_with_residual_in_recommendations_list(
         matches, offer_trade, bid_trade)
     assert len(matches) == 2
     assert matches[0]["offers"][0]["id"] == "residual_offer"
     assert matches[1]["bids"][0]["id"] == "residual_bid_2"
    def test_match_recommendations(self, market):
        """Test match_recommendations() method of TwoSidedMarket."""
        bid = Bid("bid_id1", pendulum.now(), price=2, energy=1, buyer="Buyer")
        offer = Offer("offer_id1",
                      pendulum.now(),
                      price=2,
                      energy=1,
                      seller="Seller")

        market.bids = {"bid_id1": bid}
        market.offers = {"offer_id1": offer}

        recommendations = [
            BidOfferMatch(bids=[bid.serializable_dict()],
                          offers=[offer.serializable_dict()],
                          trade_rate=2,
                          selected_energy=1,
                          market_id=market.id).serializable_dict()
        ]
        market.match_recommendations(recommendations)
        assert len(market.trades) == 1
    def test_double_sided_pay_as_clear_market_works_with_floats(
            self, pac_market):
        ConstSettings.IAASettings.PAY_AS_CLEAR_AGGREGATION_ALGORITHM = 1
        offers = [
            Offer("id1", pendulum.now(), 1.1, 1, "other").serializable_dict(),
            Offer("id2", pendulum.now(), 2.2, 1, "other").serializable_dict(),
            Offer("id3", pendulum.now(), 3.3, 1, "other").serializable_dict()
        ]

        bids = [
            Bid("bid_id1", pendulum.now(), 3.3, 1, "B",
                buyer_origin="S").serializable_dict(),
            Bid("bid_id2", pendulum.now(), 2.2, 1, "B",
                buyer_origin="S").serializable_dict(),
            Bid("bid_id3", pendulum.now(), 1.1, 1, "B",
                buyer_origin="S").serializable_dict()
        ]

        matched = pac_market.get_clearing_point(bids, offers,
                                                pendulum.now())[0]
        assert matched == 2.2
 def test_validate_bid_offer_match_raises_exception(self, market,
                                                    bid_energy,
                                                    offer_energy,
                                                    clearing_rate,
                                                    selected_energy):
     offer = Offer("id", pendulum.now(), 2, offer_energy, "other", 2)
     bid = Bid("bid_id", pendulum.now(), 2, bid_energy, "B", 8)
     market._validate_requirements_satisfied = MagicMock()
     with pytest.raises(InvalidBidOfferPairException):
         market.validate_bid_offer_match([bid], [offer], clearing_rate,
                                         selected_energy)
         market._validate_requirements_satisfied.assert_not_called()
    def test_double_sided_market_performs_pay_as_clear_matching(
            self, pac_market, offer, bid, mcp_rate, mcp_energy, algorithm):
        ConstSettings.IAASettings.PAY_AS_CLEAR_AGGREGATION_ALGORITHM = algorithm
        offers = [
            Offer("id1", pendulum.now(), offer[0], 1,
                  "other").serializable_dict(),
            Offer("id2", pendulum.now(), offer[1], 1,
                  "other").serializable_dict(),
            Offer("id3", pendulum.now(), offer[2], 1,
                  "other").serializable_dict(),
            Offer("id4", pendulum.now(), offer[3], 1,
                  "other").serializable_dict(),
            Offer("id5", pendulum.now(), offer[4], 1,
                  "other").serializable_dict(),
            Offer("id6", pendulum.now(), offer[5], 1,
                  "other").serializable_dict(),
            Offer("id7", pendulum.now(), offer[6], 1,
                  "other").serializable_dict()
        ]

        bids = [
            Bid("bid_id1", pendulum.now(), bid[0], 1, "B",
                buyer_origin="S").serializable_dict(),
            Bid("bid_id2", pendulum.now(), bid[1], 1, "B",
                buyer_origin="S").serializable_dict(),
            Bid("bid_id3", pendulum.now(), bid[2], 1, "B",
                buyer_origin="S").serializable_dict(),
            Bid("bid_id4", pendulum.now(), bid[3], 1, "B",
                buyer_origin="S").serializable_dict(),
            Bid("bid_id5", pendulum.now(), bid[4], 1, "B",
                buyer_origin="S").serializable_dict(),
            Bid("bid_id6", pendulum.now(), bid[5], 1, "B",
                buyer_origin="S").serializable_dict(),
            Bid("bid_id7", pendulum.now(), bid[6], 1, "B",
                buyer_origin="S").serializable_dict()
        ]

        matched_rate, matched_energy = pac_market.get_clearing_point(
            bids, offers, pendulum.now())
        assert matched_rate == mcp_rate
        assert matched_energy == mcp_energy
def bid():
    return Bid("bid_id", now(), 9, 10, "B", 9)
    def test_double_sided_performs_pay_as_bid_matching(self,
                                                       market: TwoSidedMarket,
                                                       market_matcher):
        market.offers = {
            "offer1": Offer("id", pendulum.now(), 2, 2, "other", 2)
        }

        market.bids = {
            "bid1": Bid("bid_id", pendulum.now(), 9, 10, "B", buyer_origin="S")
        }
        matched = market_matcher.get_matches_recommendations({
            market.id: {
                "bids":
                [bid.serializable_dict() for bid in market.bids.values()],
                "offers": [
                    offer.serializable_dict()
                    for offer in market.offers.values()
                ]
            }
        })
        assert len(matched) == 0
        market.bids = {
            "bid1": Bid("bid_id",
                        pendulum.now(),
                        11,
                        10,
                        "B",
                        buyer_origin="S")
        }
        matched = market_matcher.get_matches_recommendations({
            market.id: {
                "bids":
                [bid.serializable_dict() for bid in market.bids.values()],
                "offers": [
                    offer.serializable_dict()
                    for offer in market.offers.values()
                ]
            }
        })
        assert len(matched) == 1

        assert len(matched[0]["bids"]) == 1
        assert len(matched[0]["offers"]) == 1
        assert matched[0]["bids"][0] == list(
            market.bids.values())[0].serializable_dict()
        assert matched[0]["offers"][0] == list(
            market.offers.values())[0].serializable_dict()

        market.bids = {
            "bid1": Bid("bid_id1",
                        pendulum.now(),
                        11,
                        10,
                        "B",
                        buyer_origin="S"),
            "bid2": Bid("bid_id2",
                        pendulum.now(),
                        9,
                        10,
                        "B",
                        buyer_origin="S"),
            "bid3": Bid("bid_id3",
                        pendulum.now(),
                        12,
                        10,
                        "B",
                        buyer_origin="S")
        }
        matched = market_matcher.get_matches_recommendations({
            market.id: {
                "bids":
                [bid.serializable_dict() for bid in market.bids.values()],
                "offers": [
                    offer.serializable_dict()
                    for offer in market.offers.values()
                ]
            }
        })
        assert len(matched) == 1
        assert matched[0]["bids"][0]["id"] == "bid_id3"
        assert matched[0]["bids"][0]["energy_rate"] == 1.2
        assert matched[0]["bids"][0]["energy"] == 10
        assert matched[0]["offers"][0] == list(
            market.offers.values())[0].serializable_dict()