EMlab-generation Documentation  1.0
Documentation of the EMLab-Generation model.
StochasticTargetInvestmentRole.java
1 /*******************************************************************************
2  * Copyright 2012 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 org.springframework.beans.factory.annotation.Autowired;
19 import org.springframework.beans.factory.annotation.Configurable;
20 import org.springframework.data.annotation.Transient;
21 import org.springframework.data.neo4j.annotation.NodeEntity;
22 import org.springframework.transaction.annotation.Transactional;
23 
37 
42 @Configurable
43 @NodeEntity
44 public class StochasticTargetInvestmentRole extends GenericInvestmentRole<StochasticTargetInvestor> {
45 
46  @Transient
47  @Autowired Reps reps;
48 
49  @Override
50  @Transactional
51  public void act(StochasticTargetInvestor targetInvestor) {
52 
53  // logger.warn(targetInvestor.getName() + " making investments.");
54 
55  for(PowerGeneratingTechnologyTarget target : targetInvestor.getPowerGenerationTechnologyTargets()){
56  PowerGeneratingTechnology pgt = target.getPowerGeneratingTechnology();
57  // logger.warn("\t looking at" + pgt.getName());
58  PowerGeneratingTechnologyTargetFulfillment targetFulfillment = null;
59  for (PowerGeneratingTechnologyTargetFulfillment tgtFulfillment : targetInvestor
60  .getPowerGeneratingTechnologyPercentageOfYearlyTargetFulfillments()) {
61  if(tgtFulfillment.getPowerGeneratingTechnology().getName().equals(pgt.getName()))
62  targetFulfillment = tgtFulfillment;
63  }
64 
65  PowerGridNode installationNode = targetInvestor.getSpecificPowerGridNode();
66 
67  if (installationNode == null)
68  reps.powerGeneratingTechnologyNodeLimitRepository.findOneByTechnologyAndMarket(pgt,
69  targetInvestor.getInvestorMarket());
70 
71  long futureTimePoint = getCurrentTick()+pgt.getExpectedLeadtime()+pgt.getExpectedPermittime();
72  double expectedInstalledCapacity = reps.powerPlantRepository.calculateCapacityOfExpectedOperationalPowerPlantsInMarketAndTechnology(targetInvestor.getInvestorMarket(), pgt, futureTimePoint);
73  double pgtNodeLimit = Double.MAX_VALUE;
74  // For simplicity using the market, instead of the node here. Needs
75  // to be changed, if more than one node per market exists.
76  PowerGeneratingTechnologyNodeLimit pgtLimit = reps.powerGeneratingTechnologyNodeLimitRepository
77  .findOneByTechnologyAndNode(pgt, installationNode);
78  if (pgtLimit != null) {
79  pgtNodeLimit = pgtLimit.getUpperCapacityLimit(futureTimePoint);
80  }
81  // logger.warn("TechName: " + pgt.getName() + ", EnergyProducer" +
82  // targetInvestor + ", time: "
83  // + futureTimePoint);
84  double expectedDismantledPowerPlantCapacityOfTechnologyAndOwner = reps.powerPlantRepository
85  .calculateCapacityOfExpectedDismantledPowerPlantsByOwnerByTechnology(futureTimePoint, targetInvestor, pgt);
86  double targetInstallationDelta = (target.getTrend().getValue(futureTimePoint) - target.getTrend().getValue(
87  futureTimePoint - 1))
88  + expectedDismantledPowerPlantCapacityOfTechnologyAndOwner;
89  // logger.warn(target.getPowerGeneratingTechnology().getName() +
90  // ": " + targetInstallationDelta
91  // + " of which repowering: " +
92  // expectedDismantledPowerPlantCapacityOfTechnologyAndOwner);
93  targetInstallationDelta = targetInstallationDelta * targetFulfillment.getTrend().getValue(futureTimePoint);
94  // logger.warn(target.getPowerGeneratingTechnology().getName() +
95  // " Stochastic: " + targetInstallationDelta);
96  double installedCapacityDeviation = 0;
97  if (pgtNodeLimit > expectedInstalledCapacity + targetInstallationDelta) {
98  installedCapacityDeviation = targetInstallationDelta;
99  } else {
100  installedCapacityDeviation = pgtNodeLimit - expectedInstalledCapacity;
101  }
102 
103  if (installedCapacityDeviation > 0) {
104 
105  double powerPlantCapacityRatio = installedCapacityDeviation/pgt.getCapacity();
106 
107  PowerPlant plant = new PowerPlant();
108  plant.specifyNotPersist(getCurrentTick(), targetInvestor, installationNode, pgt);
109  plant.setActualNominalCapacity(pgt.getCapacity()*powerPlantCapacityRatio);
110  PowerPlantManufacturer manufacturer = reps.genericRepository.findFirst(PowerPlantManufacturer.class);
111  BigBank bigbank = reps.genericRepository.findFirst(BigBank.class);
112 
113  double investmentCostPayedByEquity = plant.getActualInvestedCapital() * (1 - targetInvestor.getDebtRatioOfInvestments())*powerPlantCapacityRatio;
114  double investmentCostPayedByDebt = plant.getActualInvestedCapital() * targetInvestor.getDebtRatioOfInvestments()*powerPlantCapacityRatio;
115  double downPayment = investmentCostPayedByEquity;
116  createSpreadOutDownPayments(targetInvestor, manufacturer, downPayment, plant);
117 
118  double amount = determineLoanAnnuities(investmentCostPayedByDebt, plant.getTechnology().getDepreciationTime(),
119  targetInvestor.getLoanInterestRate());
120  // logger.warn("Loan amount is: " + amount);
121  Loan loan = reps.loanRepository.createLoan(targetInvestor, bigbank, amount, plant.getTechnology().getDepreciationTime(),
122  getCurrentTick(), plant);
123  // Create the loan
124  plant.createOrUpdateLoan(loan);
125 
126  }
127  }
128 
129  }
130 
131  private void createSpreadOutDownPayments(EnergyProducer agent, PowerPlantManufacturer manufacturer, double totalDownPayment,
132  PowerPlant plant) {
133  int buildingTime = (int) plant.getActualLeadtime();
134  for (int i = 0; i < buildingTime; i++) {
135  reps.nonTransactionalCreateRepository.createCashFlow(agent, manufacturer, totalDownPayment / buildingTime,
136  CashFlow.DOWNPAYMENT, getCurrentTick() + i, plant);
137  }
138  }
139 
140  @Override
141  public double determineLoanAnnuities(double totalLoan, double payBackTime, double interestRate) {
142 
143  double q = 1 + interestRate;
144  double annuity = totalLoan * (Math.pow(q, payBackTime) * (q - 1)) / (Math.pow(q, payBackTime) - 1);
145 
146  return annuity;
147  }
148 
149 }