EMlab-generation Documentation  1.0
Documentation of the EMLab-Generation model.
InvestInPowerGenerationTechnologiesRole.java
1 /*******************************************************************************
2  * Copyright 2013 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  ******************************************************************************/
16 package emlab.gen.role.investment;
17 
18 import java.util.HashMap;
19 import java.util.Map;
20 import java.util.Map.Entry;
21 import java.util.Set;
22 import java.util.TreeMap;
23 
24 import org.springframework.beans.factory.annotation.Autowired;
25 import org.springframework.beans.factory.annotation.Configurable;
26 import org.springframework.data.annotation.Transient;
27 import org.springframework.data.neo4j.annotation.NodeEntity;
28 import org.springframework.data.neo4j.aspects.core.NodeBacked;
29 import org.springframework.data.neo4j.support.Neo4jTemplate;
30 import org.springframework.transaction.annotation.Transactional;
31 
32 import agentspring.role.Role;
55 
62 @Configurable
63 @NodeEntity
64 public class InvestInPowerGenerationTechnologiesRole<T extends EnergyProducer> extends GenericInvestmentRole<T>
65 implements
66 Role<T>,
67 NodeBacked {
68 
69  @Transient
70  @Autowired
71  Reps reps;
72 
73  @Transient
74  @Autowired
75  Neo4jTemplate template;
76 
77  @Transient
78  @Autowired
79  StrategicReserveOperatorRepository strategicReserveOperatorRepository;
80 
81  // market expectations
82  @Transient
83  Map<ElectricitySpotMarket, MarketInformation> marketInfoMap = new HashMap<ElectricitySpotMarket, MarketInformation>();
84 
85  @Override
86  public void act(T agent) {
87 
88  long futureTimePoint = getCurrentTick() + agent.getInvestmentFutureTimeHorizon();
89  // logger.warn(agent + " is looking at timepoint " + futureTimePoint);
90 
91  // ==== Expectations ===
92 
93  Map<Substance, Double> expectedFuelPrices = predictFuelPrices(agent, futureTimePoint);
94 
95  // CO2
96  Map<ElectricitySpotMarket, Double> expectedCO2Price = determineExpectedCO2PriceInclTax(futureTimePoint,
97  agent.getNumberOfYearsBacklookingForForecasting(), getCurrentTick());
98 
99  // logger.warn(expectedCO2Price.toString());
100 
101  //Demand
102  Map<ElectricitySpotMarket, Double> expectedDemand = new HashMap<ElectricitySpotMarket, Double>();
103  for(ElectricitySpotMarket elm : reps.template.findAll(ElectricitySpotMarket.class)){
105  for(long time = getCurrentTick(); time>getCurrentTick()-agent.getNumberOfYearsBacklookingForForecasting() && time>=0; time=time-1){
106  gtr.addData(time, elm.getDemandGrowthTrend().getValue(time));
107  }
108  expectedDemand.put(elm, gtr.predict(futureTimePoint));
109  }
110 
111 
112 
113  // Investment decision
114  // for (ElectricitySpotMarket market :
115  // reps.genericRepository.findAllAtRandom(ElectricitySpotMarket.class))
116  // {
117  ElectricitySpotMarket market = agent.getInvestorMarket();
118  MarketInformation marketInformation = new MarketInformation(market, expectedDemand, expectedFuelPrices, expectedCO2Price.get(market)
119  .doubleValue(), futureTimePoint);
120  /*
121  * if (marketInfoMap.containsKey(market) && marketInfoMap.get(market).time == futureTimePoint) { marketInformation = marketInfoMap.get(market); } else { marketInformation = new
122  * MarketInformation(market, expectedFuelPrices, expectedCO2Price, futureTimePoint); marketInfoMap.put(market, marketInformation); }
123  */
124 
125  // logger.warn(agent + " is expecting a CO2 price of " +
126  // expectedCO2Price.get(market) + " Euro/MWh at timepoint "
127  // + futureTimePoint + " in Market " + market);
128 
129  // logger.warn("Agent {} found the expected prices to be {}", agent,
130  // marketInformation.expectedElectricityPricesPerSegment);
131 
132  // logger.warn("Agent {} found that the installed capacity in the market {} in future to be "
133  // + marketInformation.capacitySum +
134  // "and expectde maximum demand to be "
135  // + marketInformation.maxExpectedLoad, agent, market);
136 
137  double highestValue = Double.MIN_VALUE;
138  PowerGeneratingTechnology bestTechnology = null;
139 
140  for (PowerGeneratingTechnology technology : reps.genericRepository.findAll(PowerGeneratingTechnology.class)) {
141 
142  PowerPlant plant = new PowerPlant();
143  plant.specifyNotPersist(getCurrentTick(), agent, getNodeForZone(market.getZone()), technology);
144  // if too much capacity of this technology in the pipeline (not
145  // limited to the 5 years)
146  double expectedInstalledCapacityOfTechnology = reps.powerPlantRepository
147  .calculateCapacityOfExpectedOperationalPowerPlantsInMarketAndTechnology(market, technology, futureTimePoint);
148  PowerGeneratingTechnologyTarget technologyTarget = reps.powerGenerationTechnologyTargetRepository.findOneByTechnologyAndMarket(technology, market);
149  if(technologyTarget!=null){
150  double technologyTargetCapacity = technologyTarget.getTrend().getValue(futureTimePoint);
151  expectedInstalledCapacityOfTechnology = (technologyTargetCapacity > expectedInstalledCapacityOfTechnology) ? technologyTargetCapacity : expectedInstalledCapacityOfTechnology;
152  }
153  double pgtNodeLimit = Double.MAX_VALUE;
154  PowerGeneratingTechnologyNodeLimit pgtLimit = reps.powerGeneratingTechnologyNodeLimitRepository
155  .findOneByTechnologyAndNode(technology, plant.getLocation());
156  if (pgtLimit != null) {
157  pgtNodeLimit = pgtLimit.getUpperCapacityLimit(futureTimePoint);
158  }
159  double expectedInstalledCapacityOfTechnologyInNode = reps.powerPlantRepository
160  .calculateCapacityOfExpectedOperationalPowerPlantsByNodeAndTechnology(plant.getLocation(),
161  technology, futureTimePoint);
162  double expectedOwnedTotalCapacityInMarket = reps.powerPlantRepository
163  .calculateCapacityOfExpectedOperationalPowerPlantsInMarketByOwner(market, futureTimePoint, agent);
164  double expectedOwnedCapacityInMarketOfThisTechnology = reps.powerPlantRepository
165  .calculateCapacityOfExpectedOperationalPowerPlantsInMarketByOwnerAndTechnology(market, technology, futureTimePoint,
166  agent);
167  double capacityOfTechnologyInPipeline = reps.powerPlantRepository.calculateCapacityOfPowerPlantsByTechnologyInPipeline(
168  technology, getCurrentTick());
169  double operationalCapacityOfTechnology = reps.powerPlantRepository.calculateCapacityOfOperationalPowerPlantsByTechnology(
170  technology, getCurrentTick());
171  double capacityInPipelineInMarket = reps.powerPlantRepository
172  .calculateCapacityOfPowerPlantsByMarketInPipeline(market, getCurrentTick());
173 
174  if ((expectedInstalledCapacityOfTechnology + plant.getActualNominalCapacity())
175  / (marketInformation.maxExpectedLoad + plant.getActualNominalCapacity()) > technology
176  .getMaximumInstalledCapacityFractionInCountry()) {
177  // logger.warn(agent +
178  // " will not invest in {} technology because there's too much of this type in the market",
179  // technology);
180  } else if ((expectedInstalledCapacityOfTechnologyInNode + plant.getActualNominalCapacity()) > pgtNodeLimit) {
181 
182  } else if (expectedOwnedCapacityInMarketOfThisTechnology > expectedOwnedTotalCapacityInMarket
183  * technology.getMaximumInstalledCapacityFractionPerAgent()) {
184  // logger.warn(agent +
185  // " will not invest in {} technology because there's too much capacity planned by him",
186  // technology);
187  } else if (capacityInPipelineInMarket > 0.2 * marketInformation.maxExpectedLoad) {
188  // logger.warn("Not investing because more than 20% of demand in pipeline.");
189 
190  } else if ((capacityOfTechnologyInPipeline > 2.0 * operationalCapacityOfTechnology)
191  && capacityOfTechnologyInPipeline > 9000) { // TODO:
192  // reflects that you cannot expand a technology out of zero.
193  // logger.warn(agent +
194  // " will not invest in {} technology because there's too much capacity in the pipeline",
195  // technology);
196  } else if (plant.getActualInvestedCapital() * (1 - agent.getDebtRatioOfInvestments()) > agent
197  .getDownpaymentFractionOfCash() * agent.getCash()) {
198  // logger.warn(agent +
199  // " will not invest in {} technology as he does not have enough money for downpayment",
200  // technology);
201  } else {
202 
203  Map<Substance, Double> myFuelPrices = new HashMap<Substance, Double>();
204  for (Substance fuel : technology.getFuels()) {
205  myFuelPrices.put(fuel, expectedFuelPrices.get(fuel));
206  }
207  Set<SubstanceShareInFuelMix> fuelMix = calculateFuelMix(plant, myFuelPrices, expectedCO2Price.get(market));
208  plant.setFuelMix(fuelMix);
209 
210  double expectedMarginalCost = determineExpectedMarginalCost(plant, expectedFuelPrices, expectedCO2Price.get(market));
211  double runningHours = 0d;
212  double expectedGrossProfit = 0d;
213 
214  long numberOfSegments = reps.segmentRepository.count();
215 
216  // TODO somehow the prices of long-term contracts could also
217  // be used here to determine the expected profit. Maybe not
218  // though...
219  for (SegmentLoad segmentLoad : market.getLoadDurationCurve()) {
220  double expectedElectricityPrice = marketInformation.expectedElectricityPricesPerSegment.get(segmentLoad
221  .getSegment());
222  double hours = segmentLoad.getSegment().getLengthInHours();
223  if (expectedMarginalCost <= expectedElectricityPrice) {
224  runningHours += hours;
225  expectedGrossProfit += (expectedElectricityPrice - expectedMarginalCost) * hours
226  * plant.getAvailableCapacity(futureTimePoint, segmentLoad.getSegment(), numberOfSegments);
227  }
228  }
229 
230  // logger.warn(agent +
231  // "expects technology {} to have {} running", technology,
232  // runningHours);
233  // expect to meet minimum running hours?
234  if (runningHours < plant.getTechnology().getMinimumRunningHours()) {
235  // logger.warn(agent+
236  // " will not invest in {} technology as he expect to have {} running, which is lower then required",
237  // technology, runningHours);
238  } else {
239 
240  double fixedOMCost = calculateFixedOperatingCost(plant, getCurrentTick());// /
241  // plant.getActualNominalCapacity();
242 
243  double operatingProfit = expectedGrossProfit - fixedOMCost;
244 
245  // TODO Alter discount rate on the basis of the amount
246  // in long-term contracts?
247  // TODO Alter discount rate on the basis of other stuff,
248  // such as amount of money, market share, portfolio
249  // size.
250 
251  // Calculation of weighted average cost of capital,
252  // based on the companies debt-ratio
253  double wacc = (1 - agent.getDebtRatioOfInvestments()) * agent.getEquityInterestRate()
254  + agent.getDebtRatioOfInvestments() * agent.getLoanInterestRate();
255 
256  // Creation of out cash-flow during power plant building
257  // phase (note that the cash-flow is negative!)
258  TreeMap<Integer, Double> discountedProjectCapitalOutflow = calculateSimplePowerPlantInvestmentCashFlow(
259  technology.getDepreciationTime(), (int) plant.getActualLeadtime(),
260  plant.getActualInvestedCapital(), 0);
261  // Creation of in cashflow during operation
262  TreeMap<Integer, Double> discountedProjectCashInflow = calculateSimplePowerPlantInvestmentCashFlow(
263  technology.getDepreciationTime(), (int) plant.getActualLeadtime(), 0, operatingProfit);
264 
265  double discountedCapitalCosts = npv(discountedProjectCapitalOutflow, wacc);// are
266  // defined
267  // negative!!
268  // plant.getActualNominalCapacity();
269 
270  // logger.warn("Agent {} found that the discounted capital for technology {} to be "
271  // + discountedCapitalCosts, agent,
272  // technology);
273 
274  double discountedOpProfit = npv(discountedProjectCashInflow, wacc);
275 
276  // logger.warn("Agent {} found that the projected discounted inflows for technology {} to be "
277  // + discountedOpProfit,
278  // agent, technology);
279 
280  double projectValue = discountedOpProfit + discountedCapitalCosts;
281 
282  // logger.warn(
283  // "Agent {} found the project value for technology {} to be "
284  // + Math.round(projectValue /
285  // plant.getActualNominalCapacity()) +
286  // " EUR/kW (running hours: "
287  // + runningHours + "", agent, technology);
288 
289  // double projectTotalValue = projectValuePerMW *
290  // plant.getActualNominalCapacity();
291 
292  // double projectReturnOnInvestment = discountedOpProfit
293  // / (-discountedCapitalCosts);
294 
295  /*
296  * Divide by capacity, in order not to favour large power
297  * plants (which have the single largest NPV
298  */
299 
300  if (projectValue > 0 && projectValue / plant.getActualNominalCapacity() > highestValue) {
301  highestValue = projectValue / plant.getActualNominalCapacity();
302  bestTechnology = plant.getTechnology();
303  }
304  }
305 
306  }
307  }
308 
309  if (bestTechnology != null) {
310  // logger.warn("Agent {} invested in technology {} at tick " + getCurrentTick(), agent, bestTechnology);
311 
312  PowerPlant plant = new PowerPlant();
313  plant.specifyAndPersist(getCurrentTick(), agent, getNodeForZone(market.getZone()), bestTechnology);
314  PowerPlantManufacturer manufacturer = reps.genericRepository.findFirst(PowerPlantManufacturer.class);
315  BigBank bigbank = reps.genericRepository.findFirst(BigBank.class);
316 
317  double investmentCostPayedByEquity = plant.getActualInvestedCapital() * (1 - agent.getDebtRatioOfInvestments());
318  double investmentCostPayedByDebt = plant.getActualInvestedCapital() * agent.getDebtRatioOfInvestments();
319  double downPayment = investmentCostPayedByEquity;
320  createSpreadOutDownPayments(agent, manufacturer, downPayment, plant);
321 
322  double amount = determineLoanAnnuities(investmentCostPayedByDebt, plant.getTechnology().getDepreciationTime(),
323  agent.getLoanInterestRate());
324  // logger.warn("Loan amount is: " + amount);
325  Loan loan = reps.loanRepository.createLoan(agent, bigbank, amount, plant.getTechnology().getDepreciationTime(),
326  getCurrentTick(), plant);
327  // Create the loan
328  plant.createOrUpdateLoan(loan);
329 
330  } else {
331  // logger.warn("{} found no suitable technology anymore to invest in at tick "
332  // + getCurrentTick(), agent);
333  // agent will not participate in the next round of investment if
334  // he does not invest now
335  setNotWillingToInvest(agent);
336  }
337  }
338 
339  // }
340 
341  // Creates n downpayments of equal size in each of the n building years of a
342  // power plant
343  @Transactional
344  private void createSpreadOutDownPayments(EnergyProducer agent, PowerPlantManufacturer manufacturer, double totalDownPayment,
345  PowerPlant plant) {
346  int buildingTime = (int) plant.getActualLeadtime();
347  reps.nonTransactionalCreateRepository.createCashFlow(agent, manufacturer, totalDownPayment / buildingTime,
348  CashFlow.DOWNPAYMENT, getCurrentTick(), plant);
349  Loan downpayment = reps.loanRepository.createLoan(agent, manufacturer, totalDownPayment / buildingTime,
350  buildingTime - 1, getCurrentTick(), plant);
351  plant.createOrUpdateDownPayment(downpayment);
352  }
353 
354  @Transactional
355  private void setNotWillingToInvest(EnergyProducer agent) {
356  agent.setWillingToInvest(false);
357  }
358 
366  public Map<Substance, Double> predictFuelPrices(EnergyProducer agent, long futureTimePoint){
367  // Fuel Prices
368  Map<Substance, Double> expectedFuelPrices = new HashMap<Substance, Double>();
369  for (Substance substance : reps.substanceRepository.findAllSubstancesTradedOnCommodityMarkets()) {
370  //Find Clearing Points for the last 5 years (counting current year as one of the last 5 years).
371  Iterable<ClearingPoint> cps = reps.clearingPointRepository
372  .findAllClearingPointsForSubstanceTradedOnCommodityMarkesAndTimeRange(substance, getCurrentTick()
373  - (agent.getNumberOfYearsBacklookingForForecasting() - 1), getCurrentTick(), false);
374  //logger.warn("{}, {}", getCurrentTick()-(agent.getNumberOfYearsBacklookingForForecasting()-1), getCurrentTick());
375  //Create regression object
377  for (ClearingPoint clearingPoint : cps) {
378  //logger.warn("CP {}: {} , in" + clearingPoint.getTime(), substance.getName(), clearingPoint.getPrice());
379  gtr.addData(clearingPoint.getTime(), clearingPoint.getPrice());
380  }
381  expectedFuelPrices.put(substance, gtr.predict(futureTimePoint));
382  //logger.warn("Forecast {}: {}, in Step " + futureTimePoint, substance, expectedFuelPrices.get(substance));
383  }
384  return expectedFuelPrices;
385  }
386 
387  // Create a powerplant investment and operation cash-flow in the form of a
388  // map. If only investment, or operation costs should be considered set
389  // totalInvestment or operatingProfit to 0
390  private TreeMap<Integer, Double> calculateSimplePowerPlantInvestmentCashFlow(int depriacationTime, int buildingTime,
391  double totalInvestment, double operatingProfit) {
392  TreeMap<Integer, Double> investmentCashFlow = new TreeMap<Integer, Double>();
393  double equalTotalDownPaymentInstallement = totalInvestment / buildingTime;
394  for (int i = 0; i < buildingTime; i++) {
395  investmentCashFlow.put(new Integer(i), -equalTotalDownPaymentInstallement);
396  }
397  for (int i = buildingTime; i < depriacationTime + buildingTime; i++) {
398  investmentCashFlow.put(new Integer(i), operatingProfit);
399  }
400 
401  return investmentCashFlow;
402  }
403 
404  private double npv(TreeMap<Integer, Double> netCashFlow, double wacc) {
405  double npv = 0;
406  for (Integer iterator : netCashFlow.keySet()) {
407  npv += netCashFlow.get(iterator).doubleValue() / Math.pow(1 + wacc, iterator.intValue());
408  }
409  return npv;
410  }
411 
412  public double determineExpectedMarginalCost(PowerPlant plant, Map<Substance, Double> expectedFuelPrices, double expectedCO2Price) {
413  double mc = determineExpectedMarginalFuelCost(plant, expectedFuelPrices);
414  double co2Intensity = plant.calculateEmissionIntensity();
415  mc += co2Intensity * expectedCO2Price;
416  return mc;
417  }
418 
419  public double determineExpectedMarginalFuelCost(PowerPlant powerPlant, Map<Substance, Double> expectedFuelPrices) {
420  double fc = 0d;
421  for (SubstanceShareInFuelMix mix : powerPlant.getFuelMix()) {
422  double amount = mix.getShare();
423  double fuelPrice = expectedFuelPrices.get(mix.getSubstance());
424  fc += amount * fuelPrice;
425  }
426  return fc;
427  }
428 
429  private PowerGridNode getNodeForZone(Zone zone) {
430  for (PowerGridNode node : reps.genericRepository.findAll(PowerGridNode.class)) {
431  if (node.getZone().equals(zone)) {
432  return node;
433  }
434  }
435  return null;
436  }
437 
438  private class MarketInformation {
439 
440  Map<Segment, Double> expectedElectricityPricesPerSegment;
441  double maxExpectedLoad = 0d;
442  Map<PowerPlant, Double> meritOrder;
443  double capacitySum;
444 
445  MarketInformation(ElectricitySpotMarket market, Map<ElectricitySpotMarket, Double> expectedDemand, Map<Substance, Double> fuelPrices, double co2price, long time) {
446  // determine expected power prices
447  expectedElectricityPricesPerSegment = new HashMap<Segment, Double>();
448  Map<PowerPlant, Double> marginalCostMap = new HashMap<PowerPlant, Double>();
449  capacitySum = 0d;
450 
451  // get merit order for this market
452  for (PowerPlant plant : reps.powerPlantRepository.findExpectedOperationalPowerPlantsInMarket(market, time)) {
453 
454  double plantMarginalCost = determineExpectedMarginalCost(plant, fuelPrices, co2price);
455  marginalCostMap.put(plant, plantMarginalCost);
456  capacitySum += plant.getActualNominalCapacity();
457  }
458 
459  //get difference between technology target and expected operational capacity
460  for(PowerGeneratingTechnologyTarget pggt : reps.powerGenerationTechnologyTargetRepository.findAllByMarket(market)){
461  double expectedTechnologyCapacity = reps.powerPlantRepository.calculateCapacityOfExpectedOperationalPowerPlantsInMarketAndTechnology(market, pggt.getPowerGeneratingTechnology(), time);
462  double targetDifference = pggt.getTrend().getValue(time) - expectedTechnologyCapacity;
463  if(targetDifference > 0){
464  PowerPlant plant = new PowerPlant();
465  plant.specifyNotPersist(getCurrentTick(), new EnergyProducer(), reps.powerGridNodeRepository.findFirstPowerGridNodeByElectricitySpotMarket(market), pggt.getPowerGeneratingTechnology());
466  plant.setActualNominalCapacity(targetDifference);
467  double plantMarginalCost = determineExpectedMarginalCost(plant, fuelPrices, co2price);
468  marginalCostMap.put(plant, plantMarginalCost);
469  capacitySum += targetDifference;
470  }
471  }
472 
473  MapValueComparator comp = new MapValueComparator(marginalCostMap);
474  meritOrder = new TreeMap<PowerPlant, Double>(comp);
475  meritOrder.putAll(marginalCostMap);
476 
477  long numberOfSegments = reps.segmentRepository.count();
478 
479  double demandFactor = expectedDemand.get(market).doubleValue();
480 
481  // find expected prices per segment given merit order
482  for (SegmentLoad segmentLoad : market.getLoadDurationCurve()) {
483 
484  double expectedSegmentLoad = segmentLoad.getBaseLoad() * demandFactor;
485 
486  if (expectedSegmentLoad > maxExpectedLoad) {
487  maxExpectedLoad = expectedSegmentLoad;
488  }
489 
490  double segmentSupply = 0d;
491  double segmentPrice = 0d;
492  double totalCapacityAvailable = 0d;
493 
494  for (Entry<PowerPlant, Double> plantCost : meritOrder.entrySet()) {
495  PowerPlant plant = plantCost.getKey();
496  double plantCapacity = 0d;
497  // Determine available capacity in the future in this
498  // segment
499  plantCapacity = plant.getExpectedAvailableCapacity(time, segmentLoad.getSegment(), numberOfSegments);
500  totalCapacityAvailable += plantCapacity;
501  // logger.warn("Capacity of plant " + plant.toString() +
502  // " is " +
503  // plantCapacity/plant.getActualNominalCapacity());
504  if (segmentSupply < expectedSegmentLoad) {
505  segmentSupply += plantCapacity;
506  segmentPrice = plantCost.getValue();
507  }
508 
509  }
510 
511  // logger.warn("Segment " +
512  // segmentLoad.getSegment().getSegmentID() + " supply equals " +
513  // segmentSupply + " and segment demand equals " +
514  // expectedSegmentLoad);
515 
516  // Find strategic reserve operator for the market.
517  double reservePrice = 0;
518  double reserveVolume = 0;
519  for (StrategicReserveOperator operator : strategicReserveOperatorRepository.findAll()) {
520  ElectricitySpotMarket market1 = reps.marketRepository.findElectricitySpotMarketForZone(operator
521  .getZone());
522  if (market.getNodeId().intValue() == market1.getNodeId().intValue()) {
523  reservePrice = operator.getReservePriceSR();
524  reserveVolume = operator.getReserveVolume();
525  }
526  }
527 
528  if (segmentSupply >= expectedSegmentLoad
529  && ((totalCapacityAvailable - expectedSegmentLoad) <= (reserveVolume))) {
530  expectedElectricityPricesPerSegment.put(segmentLoad.getSegment(), reservePrice);
531  // logger.warn("Price: "+
532  // expectedElectricityPricesPerSegment);
533  } else if (segmentSupply >= expectedSegmentLoad
534  && ((totalCapacityAvailable - expectedSegmentLoad) > (reserveVolume))) {
535  expectedElectricityPricesPerSegment.put(segmentLoad.getSegment(), segmentPrice);
536  // logger.warn("Price: "+
537  // expectedElectricityPricesPerSegment);
538  } else {
539  expectedElectricityPricesPerSegment.put(segmentLoad.getSegment(), market.getValueOfLostLoad());
540  }
541 
542  }
543  }
544  }
545 
546 }