コード例 #1
0
 def test_market_accept_bid_yields_partial_bid_trade(
     self, market=TwoSidedMarket(bc=MagicMock(), time_slot=pendulum.now())):
     bid = market.bid(2.0, 4, "buyer", "buyer")
     trade_offer_info = TradeBidOfferInfo(2, 2, 1, 1, 2)
     trade = market.accept_bid(bid,
                               energy=1,
                               seller="seller",
                               trade_offer_info=trade_offer_info)
     assert trade.offer_bid.id == bid.id and trade.offer_bid.energy == 1
コード例 #2
0
ファイル: two_sided.py プロジェクト: rimaaugustine/d3a
    def match_recommendations(
            self,
            recommendations: List[BidOfferMatch.serializable_dict]) -> None:
        """Match a list of bid/offer pairs, create trades and residual offers/bids."""

        while recommendations:
            recommended_pair = recommendations.pop(0)
            recommended_pair = BidOfferMatch.from_dict(recommended_pair)
            selected_energy = recommended_pair.selected_energy
            clearing_rate = recommended_pair.trade_rate
            market_offers = [
                self.offers.get(offer["id"])
                for offer in recommended_pair.offers
            ]
            market_bids = [
                self.bids.get(bid["id"]) for bid in recommended_pair.bids
            ]

            if not all(market_offers) and all(market_bids):
                # If not all offers bids exist in the market, skip the current recommendation
                continue

            self.validate_bid_offer_match(market_bids, market_offers,
                                          clearing_rate, selected_energy)

            market_offers = iter(market_offers)
            market_bids = iter(market_bids)
            market_offer = next(market_offers, None)
            market_bid = next(market_bids, None)
            while market_bid and market_offer:
                original_bid_rate = market_bid.original_bid_price / market_bid.energy
                trade_bid_info = TradeBidOfferInfo(
                    original_bid_rate=original_bid_rate,
                    propagated_bid_rate=market_bid.energy_rate,
                    original_offer_rate=market_offer.original_offer_price /
                    market_offer.energy,
                    propagated_offer_rate=market_offer.energy_rate,
                    trade_rate=original_bid_rate)

                bid_trade, offer_trade = self.accept_bid_offer_pair(
                    market_bid, market_offer, clearing_rate, trade_bid_info,
                    min(selected_energy, market_offer.energy,
                        market_bid.energy))
                if offer_trade.residual:
                    market_offer = offer_trade.residual
                else:
                    market_offer = next(market_offers, None)
                if bid_trade.residual:
                    market_bid = bid_trade.residual
                else:
                    market_bid = next(market_bids, None)
                recommendations = (
                    self.
                    _replace_offers_bids_with_residual_in_recommendations_list(
                        recommendations, offer_trade, bid_trade))
コード例 #3
0
 def propagate_original_bid_info_on_offer_trade(self, trade_original_info):
     if trade_original_info is None:
         return None
     bid_rate = trade_original_info.propagated_bid_rate - self.grid_fee_rate
     trade_bid_info = TradeBidOfferInfo(
         original_bid_rate=trade_original_info.original_bid_rate,
         propagated_bid_rate=bid_rate,
         original_offer_rate=None,
         propagated_offer_rate=None,
         trade_rate=trade_original_info.trade_rate)
     return trade_bid_info
コード例 #4
0
 def propagate_original_offer_info_on_bid_trade(self,
                                                trade_original_info,
                                                ignore_fees=False):
     grid_fee_rate = self.grid_fee_rate if not ignore_fees else 0.0
     offer_rate = trade_original_info.propagated_offer_rate + grid_fee_rate
     trade_offer_info = TradeBidOfferInfo(
         original_bid_rate=None,
         propagated_bid_rate=None,
         original_offer_rate=trade_original_info.original_offer_rate,
         propagated_offer_rate=offer_rate,
         trade_rate=trade_original_info.trade_rate)
     return trade_offer_info
コード例 #5
0
 def update_forwarded_offer_trade_original_info(self, trade_original_info,
                                                market_offer):
     if not trade_original_info:
         return None
     trade_bid_info = TradeBidOfferInfo(
         original_bid_rate=trade_original_info.original_bid_rate,
         propagated_bid_rate=trade_original_info.propagated_bid_rate,
         original_offer_rate=market_offer.original_offer_price /
         market_offer.energy,
         propagated_offer_rate=market_offer.energy_rate,
         trade_rate=trade_original_info.trade_rate)
     return trade_bid_info
コード例 #6
0
 def test_market_trade_partial_bid_invalid(self,
                                           energy,
                                           market=TwoSidedMarket(
                                               bc=MagicMock(),
                                               time_slot=pendulum.now())):
     bid = market.bid(20, 20, "A", "A")
     trade_offer_info = TradeBidOfferInfo(1, 1, 1, 1, 1)
     with pytest.raises(InvalidTrade):
         market.accept_bid(bid,
                           energy=energy,
                           seller="A",
                           trade_offer_info=trade_offer_info)
コード例 #7
0
    def test_market_trade_bid_not_found(self,
                                        market=TwoSidedMarket(
                                            bc=MagicMock(),
                                            time_slot=pendulum.now())):
        bid = market.bid(20, 10, "A", "A")
        trade_offer_info = TradeBidOfferInfo(2, 2, 1, 1, 2)
        assert market.accept_bid(bid,
                                 10,
                                 "B",
                                 trade_offer_info=trade_offer_info)

        with pytest.raises(BidNotFoundException):
            market.accept_bid(bid, 10, "B", trade_offer_info=trade_offer_info)
コード例 #8
0
    def test_market_accept_bid_always_updates_trade_stats(
        self,
        called,
        market_method,
        market=TwoSidedMarket(bc=MagicMock(), time_slot=pendulum.now())):
        setattr(market, market_method, called)

        bid = market.bid(20, 20, "A", "A")
        trade_offer_info = TradeBidOfferInfo(1, 1, 1, 1, 1)
        trade = market.accept_bid(bid,
                                  energy=5,
                                  seller="B",
                                  trade_offer_info=trade_offer_info)
        assert trade
        assert len(getattr(market, market_method).calls) == 1
コード例 #9
0
 def test_market_bid_trade(self,
                           market=TwoSidedMarket(bc=MagicMock(),
                                                 time_slot=pendulum.now())):
     bid = market.bid(20, 10, "A", "A", original_bid_price=20)
     trade_offer_info = TradeBidOfferInfo(2, 2, 0.5, 0.5, 2)
     trade = market.accept_bid(bid,
                               energy=10,
                               seller="B",
                               trade_offer_info=trade_offer_info)
     assert trade
     assert trade.id == market.trades[0].id
     assert trade.id
     assert trade.offer_bid.price == bid.price
     assert trade.offer_bid.energy == bid.energy
     assert trade.seller == "B"
     assert trade.buyer == "A"
     assert not trade.residual
コード例 #10
0
 def test_market_accept_bid_emits_bid_split_on_partial_bid(
     self,
     called,
     market=TwoSidedMarket(bc=MagicMock(), time_slot=pendulum.now())):
     market.add_listener(called)
     bid = market.bid(20, 20, "A", "A")
     trade_offer_info = TradeBidOfferInfo(1, 1, 1, 1, 1)
     trade = market.accept_bid(bid,
                               energy=1,
                               trade_offer_info=trade_offer_info)
     assert all([
         ev != repr(MarketEvent.BID_DELETED) for c in called.calls
         for ev in c[0]
     ])
     assert len(called.calls) == 2
     assert called.calls[0][0] == (repr(MarketEvent.BID_SPLIT), )
     assert called.calls[1][0] == (repr(MarketEvent.BID_TRADED), )
     assert called.calls[1][1] == {
         "market_id": repr(market.id),
         "bid_trade": repr(trade),
     }
コード例 #11
0
 def test_market_trade_bid_partial(self,
                                   market=TwoSidedMarket(
                                       bc=MagicMock(),
                                       time_slot=pendulum.now())):
     bid = market.bid(20, 20, "A", "A", original_bid_price=20)
     trade_offer_info = TradeBidOfferInfo(1, 1, 1, 1, 1)
     trade = market.accept_bid(bid,
                               energy=5,
                               seller="B",
                               trade_offer_info=trade_offer_info)
     assert trade
     assert trade.id == market.trades[0].id
     assert trade.id
     assert trade.offer_bid is not bid
     assert trade.offer_bid.energy == 5
     assert trade.offer_bid.price == 5
     assert trade.seller == "B"
     assert trade.buyer == "A"
     assert trade.residual
     assert len(market.bids) == 1
     assert trade.residual.id in market.bids
     assert market.bids[trade.residual.id].energy == 15
     assert isclose(market.bids[trade.residual.id].price, 15)
     assert market.bids[trade.residual.id].buyer == "A"
コード例 #12
0
 def test_publish_event_converts_python_objects_to_json(self):
     offer = Offer("1", now(), 2, 3, "A")
     trade = Trade("2", now(), Offer("accepted", now(), 7, 8, "Z"), "B",
                   "C", None, None,
                   TradeBidOfferInfo(None, None, None, None, None))
     new_offer = Offer("3", now(), 4, 5, "D")
     existing_offer = Offer("4", now(), 5, 6, "E")
     kwargs = {
         "offer": offer,
         "trade": trade,
         "new_offer": new_offer,
         "existing_offer": existing_offer
     }
     for dispatcher in [
             self.area.dispatcher.market_event_dispatcher,
             self.device1.dispatcher.market_event_dispatcher,
             self.device2.dispatcher.market_event_dispatcher
     ]:
         dispatcher.publish_event(dispatcher.area.uuid, MarketEvent.OFFER,
                                  **kwargs)
         assert dispatcher.redis.publish.call_count == 1
         payload = json.loads(
             dispatcher.redis.publish.call_args_list[0][0][1])
         assert isinstance(payload["kwargs"]["offer"], str)
         assert offer_or_bid_from_json_string(payload["kwargs"]["offer"],
                                              offer.time) == offer
         assert isinstance(payload["kwargs"]["trade"], str)
         assert trade_from_json_string(payload["kwargs"]["trade"],
                                       trade.time) == trade
         assert isinstance(payload["kwargs"]["new_offer"], str)
         assert offer_or_bid_from_json_string(
             payload["kwargs"]["new_offer"], new_offer.time) == new_offer
         assert isinstance(payload["kwargs"]["existing_offer"], str)
         assert offer_or_bid_from_json_string(
             payload["kwargs"]["existing_offer"],
             existing_offer.time) == existing_offer