Ejemplo n.º 1
0
    def test_get_reference_year_total_capacity(self, reference_year,
                                               expected_output):

        model = Mock()
        plant1 = create_power_plant("plant1", 1990, "CCGT", 1200)
        plant2 = create_power_plant("plant2", 2010, "Onshore", 60)
        plant3 = create_power_plant("plant3", 1990, "Offshore", 120)
        plant4 = create_power_plant("plant4", 1980, "Coal", 120)

        agent1 = GenCo(1, model, "Test", 0.06, [plant1, plant2, plant3])
        agent2 = GenCo(1, model, "Test", 0.06, [plant4])

        model.year_number = 2018
        agent1.operate_constructed_plants()
        agent2.operate_constructed_plants()
        agent1.dismantle_old_plants()
        agent2.dismantle_old_plants()
        schedule = Mock()
        schedule.agents = [agent1, agent2]
        model.schedule = schedule

        calculate_capacity = WorldPlantCapacity(model)

        assert calculate_capacity.get_reference_year_total_capacity(
            reference_year) == expected_output
Ejemplo n.º 2
0
    def test_get_power_plants_running_in_reference_year(
            self, reference_year, expected_output):

        model = Mock()
        plant1 = create_power_plant("plant1", 1990, "CCGT", 1200)
        plant2 = create_power_plant("plant2", 2010, "Onshore", 60)
        plant3 = create_power_plant("plant3", 1990, "Offshore", 120)
        plant4 = create_power_plant("plant4", 1980, "Coal", 120)

        agent1 = GenCo(1, model, "Test", 0.06, [plant1, plant2, plant3])
        agent2 = GenCo(1, model, "Test", 0.06, [plant4])

        model.year_number = 2018
        agent1.operate_constructed_plants()
        agent2.operate_constructed_plants()
        agent1.dismantle_old_plants()
        agent2.dismantle_old_plants()
        schedule = Mock()
        schedule.agents = [agent1, agent2]
        model.schedule = schedule

        calculate_capacity = WorldPlantCapacity(model)
        plant_list = calculate_capacity.get_power_plants_running_in_reference_year(
            reference_year)
        for plant, expected_name in zip(plant_list, expected_output):
            logger.debug("{}, {}".format(plant.name, expected_name))
            assert plant.name == expected_name
Ejemplo n.º 3
0
 def test_calculate_expected_yearly_outflow(self, calculate_latest_NPV, year, plant_type, capacity, expected_output):
     power_plant = create_power_plant("Test", year, plant_type, capacity)
     SHORT_RUN_MARGINAL_COST = 8.9
     TOTAL_RUNNING_HOURS = 8752.42
     TOTAL_YEARLY_INCOME = 1646133520
     YEARLY_CAPITAL_COST = 514111666.67
     yearly_outflow = calculate_latest_NPV._calculate_yearly_operation_cashflow(power_plant, SHORT_RUN_MARGINAL_COST, TOTAL_RUNNING_HOURS, TOTAL_YEARLY_INCOME, YEARLY_CAPITAL_COST)
     assert yearly_outflow == pytest.approx(expected_output)
Ejemplo n.º 4
0
    def power_exchange(self):
        model = Mock()

        gen_co1 = GenCo(1, model, "Test", 0.06)
        gen_co1.plants = [create_power_plant("Test", )]
        gen_co1 = GenCo(1, model, "Test", 0.06)
        gen_co1 = GenCo(1, model, "Test", 0.06)
        gen_co1 = GenCo(1, model, "Test", 0.06)

        model.schedule.agents = []
        power_exchange = PowerExchange(model)
        return power_exchange
Ejemplo n.º 5
0
    def test_get_predicted_marginal_cost(self, plant_type, capacity,
                                         look_back_years, expected_output):
        model = Mock()
        model.step_number = 5
        model.year_number = 2018

        power_plant = create_power_plant("estimate_variable",
                                         model.year_number, plant_type,
                                         capacity)

        latest_market_data = LatestMarketData(model)
        assert latest_market_data.get_predicted_marginal_cost(
            power_plant, look_back_years) == approx(expected_output)
Ejemplo n.º 6
0
 def test_check_if_operating_in_certain_year(self):
     power_plant = create_power_plant("test_plant", 2018, "CCGT", 1200)
     assert power_plant.check_if_operating_in_certain_year(2018, 2) == False
     assert power_plant.check_if_operating_in_certain_year(2018, 3) == False
     assert power_plant.check_if_operating_in_certain_year(2018, 4) == False
     assert power_plant.check_if_operating_in_certain_year(2018, 5) == False
     assert power_plant.check_if_operating_in_certain_year(2018, 6) == False
     assert power_plant.check_if_operating_in_certain_year(2018, 7) == True
     assert power_plant.check_if_operating_in_certain_year(2018, 8) == True
     assert power_plant.check_if_operating_in_certain_year(2018, 9) == True
     assert power_plant.check_if_operating_in_certain_year(2018, 10) == True
     assert power_plant.check_if_operating_in_certain_year(2018, 11) == True
     assert power_plant.check_if_operating_in_certain_year(2018, 12) == True
     assert power_plant.check_if_operating_in_certain_year(2018, 13) == True
     assert power_plant.check_if_operating_in_certain_year(2018, 14) == True
     assert power_plant.check_if_operating_in_certain_year(2018, 31) == True
     assert power_plant.check_if_operating_in_certain_year(2018, 32) == False
     assert power_plant.check_if_operating_in_certain_year(2018, 33) == False
Ejemplo n.º 7
0
    def test_predict_load_curve_price(self):

        model = Mock()
        model.year_number = 2025
        model.step_number = 6

        model.Demand.segment_consumption = [52152, 45209, 42206, 39585, 37480, 35505, 34182, 33188, 32315, 31567, 30721, 29865, 28935, 27888, 26760, 25520, 24327, 23127, 21964, 17568]
        model.Demand.segment_hours = [8752.5, 8291.83, 7831.17, 7370.5, 6909.92, 6449.25, 5988.58, 5527.92, 5067.25, 4606.58, 4146, 3685.33, 3224.67, 2764, 2303.33, 1842.67, 1382.08, 921.42, 460.75, 0.08]


        plant1 = create_power_plant("plant1", 2016, "CCGT", 1200)
        plant2 = create_power_plant("plant2", 2015, "CCGT", 1200)
        plant3 = create_power_plant("plant3", 2014, "CCGT", 1200)
        plant4 = create_power_plant("plant4", 2020, "CCGT", 1200)
        plant5 = create_power_plant("plant5", 2021, "CCGT", 1200)
        plant6 = create_power_plant("plant6", 2035, "CCGT", 1200)

        plants = [plant1, plant2, plant3, plant4, plant5, plant6]
        all_variable_costs = [plant1.variable_o_and_m_per_mwh, plant2.variable_o_and_m_per_mwh, plant3.variable_o_and_m_per_mwh, plant4.variable_o_and_m_per_mwh, plant5.variable_o_and_m_per_mwh, plant6.variable_o_and_m_per_mwh]
        index_of_max_var_o_m_costs = np.argmax(all_variable_costs)
        plant_with_highest_o_m = plants[index_of_max_var_o_m_costs]
        gen_co1 = GenCo(1, model, "genco1", 0.02, 4)
        gen_co1.plants = [plant1, plant2]

        gen_co2 = GenCo(1, model, "genco2", 0.02, 4)
        gen_co2.plants = [plant3, plant4, plant5, plant6]

        model.schedule.agents = [gen_co1, gen_co2]

        predict_price_duration_curve = PredictPriceDurationCurve(model=model)
        predicted_price_duration_curve = predict_price_duration_curve.predict_price_duration_curve(1.1)
        assert predicted_price_duration_curve.accepted_price.iloc[0] == pytest.approx(plant_with_highest_o_m.variable_o_and_m_per_mwh + 18.977/plant_with_highest_o_m.efficiency+25.085*plant_with_highest_o_m.fuel.mwh_to_co2e_conversion_factor*(1/plant_with_highest_o_m.efficiency))
        assert predicted_price_duration_curve.accepted_price.iloc[1] == pytest.approx(plant_with_highest_o_m.variable_o_and_m_per_mwh + 18.977/plant_with_highest_o_m.efficiency+25.085*plant_with_highest_o_m.fuel.mwh_to_co2e_conversion_factor*(1/plant_with_highest_o_m.efficiency))
        assert predicted_price_duration_curve.accepted_price.iloc[2] == pytest.approx(plant_with_highest_o_m.variable_o_and_m_per_mwh + 18.977/plant_with_highest_o_m.efficiency+25.085*plant_with_highest_o_m.fuel.mwh_to_co2e_conversion_factor*(1/plant_with_highest_o_m.efficiency))
        assert predicted_price_duration_curve.accepted_price.iloc[3] == pytest.approx(plant_with_highest_o_m.variable_o_and_m_per_mwh + 18.977/plant_with_highest_o_m.efficiency+25.085*plant_with_highest_o_m.fuel.mwh_to_co2e_conversion_factor*(1/plant_with_highest_o_m.efficiency))
        assert predicted_price_duration_curve.accepted_price.iloc[4] == pytest.approx(plant_with_highest_o_m.variable_o_and_m_per_mwh + 18.977/plant_with_highest_o_m.efficiency+25.085*plant_with_highest_o_m.fuel.mwh_to_co2e_conversion_factor*(1/plant_with_highest_o_m.efficiency))
        assert predicted_price_duration_curve.accepted_price.iloc[5] == pytest.approx(plant_with_highest_o_m.variable_o_and_m_per_mwh + 18.977/plant_with_highest_o_m.efficiency+25.085*plant_with_highest_o_m.fuel.mwh_to_co2e_conversion_factor*(1/plant_with_highest_o_m.efficiency))
        assert predicted_price_duration_curve.accepted_price.iloc[6] == pytest.approx(plant_with_highest_o_m.variable_o_and_m_per_mwh + 18.977/plant_with_highest_o_m.efficiency+25.085*plant_with_highest_o_m.fuel.mwh_to_co2e_conversion_factor*(1/plant_with_highest_o_m.efficiency))
        assert predicted_price_duration_curve.accepted_price.iloc[7] == pytest.approx(plant_with_highest_o_m.variable_o_and_m_per_mwh + 18.977/plant_with_highest_o_m.efficiency+25.085*plant_with_highest_o_m.fuel.mwh_to_co2e_conversion_factor*(1/plant_with_highest_o_m.efficiency))
        assert predicted_price_duration_curve.accepted_price.iloc[8] == pytest.approx(plant_with_highest_o_m.variable_o_and_m_per_mwh + 18.977/plant_with_highest_o_m.efficiency+25.085*plant_with_highest_o_m.fuel.mwh_to_co2e_conversion_factor*(1/plant_with_highest_o_m.efficiency))
        assert predicted_price_duration_curve.accepted_price.iloc[9] == pytest.approx(plant_with_highest_o_m.variable_o_and_m_per_mwh + 18.977/plant_with_highest_o_m.efficiency+25.085*plant_with_highest_o_m.fuel.mwh_to_co2e_conversion_factor*(1/plant_with_highest_o_m.efficiency))
Ejemplo n.º 8
0
    def invest(self):

        # capacity_of_invested_plants = 0
        lowest_upfront_cost = 0
        down_payment = 0
        counter = 0
        total_capacity = 0
        number_of_plants_to_purchase = 1
        # while self.money > lowest_upfront_cost and total_capacity < 1500:
        while self.money > lowest_upfront_cost:
            # while number_of_plants_to_purchase > 0:

            # counter += 1
            # if counter>3:
            #     break
            # potential_plant_data = npv_calculation.get_positive_npv_plants_list()
            potential_plant_data = get_most_profitable_plants_by_npv(
                self.model, self.difference_in_discount_rate,
                self.look_back_period)

            # logger.info("potential_plant_data: {}".format(potential_plant_data))
            if potential_plant_data:
                potential_plant_list = []
                for plant_data in potential_plant_data:
                    power_plant_trial = create_power_plant(
                        "invested_plant", self.model.year_number,
                        plant_data[1], plant_data[0])
                    potential_plant_list.append(power_plant_trial)
                lowest_upfront_cost = min(
                    plant.get_upfront_costs() *
                    elecsim.scenario.scenario_data.upfront_investment_costs
                    for plant in potential_plant_list)
            else:
                return 1, False

            for plant_data in potential_plant_list:

                # power_plant_trial = create_power_plant("invested_plant", self.model.year_number, plant_data[1], plant_data[0])
                power_plant_trial = create_power_plant("invested_plant",
                                                       self.model.year_number,
                                                       plant_data.plant_type,
                                                       plant_data.capacity_mw)
                down_payment = power_plant_trial.get_upfront_costs(
                ) * elecsim.scenario.scenario_data.upfront_investment_costs
                number_of_plants_to_purchase = int(self.money / down_payment)
                if number_of_plants_to_purchase == 0:
                    continue

                capacity_to_purchase = number_of_plants_to_purchase * power_plant_trial.capacity_mw
                if capacity_to_purchase > 20000:
                    number_of_plants_to_purchase = int(
                        20000 / power_plant_trial.capacity_mw)

                power_plant_trial_group = create_power_plant_group(
                    name="invested_plant_group",
                    start_date=self.model.year_number,
                    simplified_type=plant_data.plant_type,
                    capacity=plant_data.capacity_mw,
                    number_of_plants_to_purchase=number_of_plants_to_purchase)
                down_payment_of_plant_array = number_of_plants_to_purchase * down_payment
                # logger.info(create_power_plant.cache_info())
                if self.money > down_payment_of_plant_array and number_of_plants_to_purchase >= 1:
                    logger.debug(
                        "investing in {}, company: {}, size: {}, number: {}, self.money: {}"
                        .format(power_plant_trial_group.plant_type, self.name,
                                power_plant_trial_group.capacity_mw,
                                number_of_plants_to_purchase, self.money))
                    self.plants.append(power_plant_trial_group)
                    self.money -= down_payment_of_plant_array
                    total_capacity += power_plant_trial_group.capacity_mw
                    if total_capacity > 400000:  # 20000000:
                        return 1, True
                    break
        else:
            return 0, False
Ejemplo n.º 9
0
 def test_calculate_yearly_loan_payment(self, calculate_latest_NPV, year, plant_type, capacity, expected_output):
     power_plant = create_power_plant("Test", year, plant_type, capacity)
     monthly_rate = get_yearly_payment(power_plant, 0.06)
     logger.debug("monthly_rate: {}".format(monthly_rate))
Ejemplo n.º 10
0
 def test_calculate_expected_yearly_profit_per_mwh(self, calculate_latest_NPV, year, plant_type, capacity, expected_output):
     power_plant = create_power_plant("Test", year, plant_type, capacity)
     TOTAL_RUNNING_HOURS = 8752.42
     YEARLY_OUTFLOW = 874963277.93
     yearly_profit_per_mwh = calculate_latest_NPV._get_yearly_profit_per_mwh(power_plant=power_plant, total_running_hours=TOTAL_RUNNING_HOURS, yearly_cash_flow=YEARLY_OUTFLOW)
     assert yearly_profit_per_mwh == pytest.approx(expected_output, abs=0.01)
Ejemplo n.º 11
0
 def test_calculate_expected_capital_cost(self, calculate_latest_NPV, year, plant_type, capacity, expected_output):
     power_plant = create_power_plant("Test", year, plant_type, capacity)
     yearly_capital_cost = calculate_latest_NPV._get_capital_outflow(power_plant)
     logger.debug(yearly_capital_cost)
     assert yearly_capital_cost == pytest.approx(expected_output)
Ejemplo n.º 12
0
 def test_select_yearly_payback_payment_for_year(self, year, plant_type, capacity, expected_output):
     power_plant = create_power_plant("Test", year, plant_type, capacity)
     model = Mock()
     model.year_number=2020
     select_yearly_payback_payment_for_year(power_plant, 0.6, model)
Ejemplo n.º 13
0
        sorted_npv = npv_results.sort_values(by='npv_per_mw', ascending=False)
        logger.debug("sorted_npv: \n {}".format(sorted_npv))
        return sorted_npv

    # @lru_cache(maxsize=10000)
    def calculate_npv(self, plant_type, plant_size):
        # Forecast segment prices

<<<<<<< HEAD
=======

>>>>>>> 5f3c373861c398621fed06ebb3fe989ceb1733a9
        forecasted_segment_prices = self._get_price_duration_predictions()
        # logger.info("Forecasted price duration curve: {}".format(forecasted_segment_prices))

        power_plant = create_power_plant("PowerPlantName", self.model.year_number, plant_type, plant_size)

        # Forecast marginal costs
        short_run_marginal_cost = self._get_predicted_marginal_cost(power_plant)
        logger.debug("short run marginal cost: {}".format(short_run_marginal_cost))

        forecasted_segment_prices = self._clean_segment_prices(forecasted_segment_prices)
        logger.debug("forecasted_segment_prices: \n {}".format(forecasted_segment_prices))

        self._get_profit_per_mwh(forecasted_segment_prices, short_run_marginal_cost)

        self._get_profit_per_segment(forecasted_segment_prices, power_plant=power_plant)

        self._get_total_hours_to_run(forecasted_segment_prices, power_plant)

        self._get_total_yearly_income(forecasted_segment_prices, power_plant)
Ejemplo n.º 14
0
    def calculate_npv(self, plant_type, plant_size):
        # Forecast segment prices
        if self.price_curve_parameters is None:
            forecasted_segment_prices = self._get_price_duration_predictions()
        elif self.price_curve_parameters:
            forecasted_segment_prices = self.price_curve_parameters

        logger.debug(
            "forecasted_segment_prices: {}".format(forecasted_segment_prices))

        if plant_type == "Nuclear" and self.model.nuclear_subsidy is not None:
            forecasted_segment_prices[
                'accepted_price'] = forecasted_segment_prices[
                    'accepted_price'] + self.model.nuclear_subsidy

        logger.debug("Forecasted price duration curve: \n{}".format(
            forecasted_segment_prices))

        power_plant = create_power_plant("PowerPlantName",
                                         self.model.year_number, plant_type,
                                         plant_size)

        # Forecast marginal costs
        short_run_marginal_cost = self._get_predicted_marginal_cost(
            power_plant)
        logger.debug(
            "short run marginal cost: {}".format(short_run_marginal_cost))

        forecasted_segment_prices = self._clean_segment_prices(
            forecasted_segment_prices)
        logger.debug("forecasted_segment_prices: \n {}".format(
            forecasted_segment_prices))

        self._get_profit_per_mwh(forecasted_segment_prices,
                                 short_run_marginal_cost)

        self._get_profit_per_segment(forecasted_segment_prices,
                                     power_plant=power_plant)

        self._get_total_hours_to_run(forecasted_segment_prices, power_plant)

        self._get_total_yearly_income(forecasted_segment_prices, power_plant)

        logger.debug("total_hours_predicted_to_run: \n {}".format(
            forecasted_segment_prices))

        # total_profit_for_year = sum(forecasted_segment_prices['_total_profit_per_segment'])
        total_running_hours = sum(
            forecasted_segment_prices['_total_running_hours'])
        total_yearly_income = sum(forecasted_segment_prices['total_income'])
        logger.debug("total_yearly_income: {}".format(total_yearly_income))
        yearly_capital_cost = self._get_capital_outflow(power_plant)

        logger.debug("yearly_capital_cost: {}".format(yearly_capital_cost))

        yearly_operating_cash_flow = self._calculate_yearly_operation_cashflow(
            power_plant, short_run_marginal_cost, total_running_hours,
            total_yearly_income, yearly_capital_cost)

        total_cash_flow = yearly_capital_cost + yearly_operating_cash_flow

        logger.debug('total_cash_flow: {}'.format(total_cash_flow))

        if power_plant.plant_type == "Nuclear":
            self.weighted_average_cost_capital = elecsim.scenario.scenario_data.nuclear_wacc + self.difference_in_discount_rate
        else:
            self.weighted_average_cost_capital = elecsim.scenario.scenario_data.non_nuclear_wacc + self.difference_in_discount_rate

        # logger.debug("cash_flow_wacc: {}".format(cash_flow_wacc))
        logger.debug("discount rate: {}".format(
            self.weighted_average_cost_capital))

        npv_power_plant = npv(self.weighted_average_cost_capital,
                              total_cash_flow)

        logger.debug("npv_power_plant: {}".format(npv_power_plant))

        NPVp = divide(npv_power_plant,
                      (power_plant.capacity_mw * total_running_hours))
        return NPVp
Ejemplo n.º 15
0
    def initialize_gencos(self, financial_data, plant_data, gencos_rl):
        """
        Creates generation company agents based on financial data and power plants owned. Estimates cost parameters
         of each power plant if data not for power plant not available.
        :param financial_data: Data containing information about generation company's financial status
        :param plant_data: Data containing information about generation company's plants owned, start year and name.
        """

        financial_data = pd.merge(financial_data, plant_data, on="Company", how="inner")
        financial_data = financial_data[["Company", "cash_in_bank"]]

        # Initialising generator company data
        financial_data.cash_in_bank = financial_data.cash_in_bank.replace("nan", np.nan)
        financial_data.cash_in_bank = financial_data.cash_in_bank.fillna(0)
        companies_groups = plant_data.groupby("Company")
        company_financials = financial_data.groupby("Company")

        logger.info("Initialising generation companies with their power plants.")

        # Initialize generation companies with their respective power plants
        for gen_id, ((name, data), (_, financials)) in enumerate(
            zip(companies_groups, company_financials), 0
        ):
            rl_bidding = False
            if financials.Company.iloc[0] != name:
                raise ValueError(
                    "Company financials name ({}) and agent name ({}) do not match.".format(
                        financials.Company.iloc[0], name
                    )
                )
            elif financials.Company.iloc[0] in gencos_rl:
                rl_bidding = True

            gen_co = GenCo(
                unique_id=gen_id,
                model=self,
                difference_in_discount_rate=round(uniform(-0.03, 0.03), 3),
                look_back_period=randint(3, 7),
                name=name,
                money=financials.cash_in_bank.iloc[0],
                rl_bidding=rl_bidding,
            )
            self.unique_id_generator += 1
            # Add power plants to generation company portfolio
            # parent_directory = os.path.dirname(os.getcwd())
            pickle_directory = (
                "{}/../elecsim/data/processed/pickled_data/power_plants/".format(
                    ROOT_DIR
                )
            )

            for plant in data.itertuples():
                try:
                    power_plant = pickle.load(
                        open(
                            "{}{}-{}.pickle".format(
                                pickle_directory, plant.Name, plant.Start_date
                            ),
                            "rb",
                        )
                    )
                except (OSError, IOError, FileNotFoundError, EOFError) as e:
                    logger.info("plant: {}".format(plant))
                    power_plant = create_power_plant(
                        plant.Name,
                        plant.Start_date,
                        plant.Simplified_Type,
                        plant.Capacity,
                    )
                    pickle.dump(
                        power_plant,
                        open(
                            "{}{}-{}.pickle".format(
                                pickle_directory, plant.Name, plant.Start_date
                            ),
                            "wb",
                        ),
                    )
                gen_co.plants.append(power_plant)
            logger.debug("Adding generation company: {}".format(gen_co.name))
            self.schedule.add(gen_co)
        logger.info("Added generation companies.")