00001
00002
00003
00004
00005
00007
00008 package de.pik.lagom.generic;
00009
00010 import static de.pik.lagom.annotations.Initialization.EQUAL;
00011 import static de.pik.lagom.annotations.Origin.*;
00012 import static de.pik.lagom.annotations.Variability.*;
00013
00014 import net.sf.oval.constraint.GreaterOrApproxZero;
00015 import net.sf.oval.constraint.NotNull;
00016 import net.sf.oval.guard.Guarded;
00017 import net.sf.oval.guard.PostValidateThis;
00018 import de.pik.lagom.annotations.*;
00019 import de.pik.lagom.generic.initvalues.FinancialInitValues;
00020 import de.pik.lagom.toolbox.ProbeBase;
00021 import de.pik.lagom.toolbox.StepManager.Callback;
00022 import de.pik.lagom.toolbox.math.FloatMath;
00023 import de.pik.lagom.toolbox.math.ValueMemory;
00024
00029 @Guarded
00030 @Initialization(EQUAL)
00031 public class Financial {
00032 @Variability(PERIOD)
00033 public class Probe extends ProbeBase {
00034 @Description("Sum of all monetary holdings (available cash) of households, firms and the government")
00035 @Origin(TECHNICAL)
00036 private double monetaryHoldingsAggregate = 0.d;
00037
00038 @Description("Sum of all monetary holdings (available cash) and all savings of households, firms (no savings) and the government (no savings)")
00039 @Origin(TECHNICAL)
00040 private double monetaryHoldingsAndSavingsAggregate = 0.d;
00041
00042 @Description("Sum of all debts of firms (currently, households and the government are not allowed to take debts")
00043 @Origin(TECHNICAL)
00044 private double debtAggregate = 0.d;
00045
00046 @Description("The total amount of money created")
00047 @Origin(TECHNICAL)
00048 private double createdMoney = 0.d;
00049
00050 @Description("The total goldstock")
00051 @Origin(TECHNICAL)
00052 private double goldStock = 0.d;
00053
00054 @Description("The total amount of consumption by the households (products bought from firms)")
00055 @Origin(TECHNICAL)
00056 private double finalConsumption = 0.d;
00057
00058 @Description("The total amount of sales by the firms")
00059 @Origin(TECHNICAL)
00060 private double sales = 0.d;
00061
00062 @Description("The total amount of consumption by the firms (products bought from other firms)")
00063 @Origin(TECHNICAL)
00064 @Comment("Actually, we should have sales = intermediaryConsumption + finalConsumption")
00065 private double intermediaryConsumption = 0.d;
00066
00067 @Description("The total amount of investments by the firms")
00068 @Origin(TECHNICAL)
00069 private double investment = 0.d;
00070
00071 @Description("The total amount of wages paid by the firms")
00072 @Origin(TECHNICAL)
00073 private double wagesPaid = 0.d;
00074
00075 @Description("The total amount of wages received by the households (from firms).")
00076 @Origin(TECHNICAL)
00077 private double wagesReceived = 0.d;
00078
00079 @Description("The total amount of taxes paid by the households.")
00080 @Origin(TECHNICAL)
00081 private double taxesPaid = 0.d;
00082
00083 @Description("The total amount of wages for unemployed people.")
00084 @Origin(TECHNICAL)
00085 private double unemploymentCost = 0.d;
00086
00087 @Description("The total amount of dividendes paid by firms.")
00088 @Origin(TECHNICAL)
00089 private double dividendsPaid = 0.d;
00090
00091 @Description("The total amount of dividendes received by households.")
00092 @Origin(TECHNICAL)
00093 @Comment("Should we have dividendsPaid = dividendsReceived?")
00094 private double dividendsReceived = 0.d;
00095
00096 @Description("The total amount of interests received by households (for their savings).")
00097 @Origin(TECHNICAL)
00098 private double interestsPaid = 0.d;
00099
00100 @Description("The total amount of interests paid by firms (for their debts).")
00101 @Origin(TECHNICAL)
00102 private double interestsReceived = 0.d;
00103
00104 void init() {
00105 createdMoney = 0.d;
00106 goldStock = 0.d;
00107 debtAggregate = 0.d;
00108 monetaryHoldingsAndSavingsAggregate = 0.d;
00109 monetaryHoldingsAggregate = 0.d;
00110 foundation.getStepManager().registerEndOfPeriodCallback(1, new Callback() {
00111 @Override
00112 public void endOfPeriod() {
00113 updateMonetaryAggregates();
00114 }
00115
00116 @Override
00117 public Object getOwner() {
00118 return Financial.Probe.this;
00119 }
00120 });
00121
00122 foundation.getStepManager().registerInitFinishedCallback(1, new Callback() {
00123 @Override
00124 public void endOfInit() {
00125 updateMonetaryAggregates();
00126 }
00127
00128 @Override
00129 public Object getOwner() {
00130 return Financial.Probe.this;
00131 }
00132 });
00133 }
00134
00135 @WriteToFile
00136 @NameInUI("Interest Rate")
00137 public double getInterestRate() {
00138 return interestRate;
00139 }
00140
00141 @WriteToFile
00142 @NameInUI("Inflation Rate")
00143 public double getInflationRate() {
00144 return inflationRate;
00145 }
00146
00147 @WriteToFile
00148 @NameInUI("Monetary Holdings")
00149 @Description("The aggregated monetary holdings of firms and households")
00150 public double getMonetaryHoldings() {
00151 return monetaryHoldingsAggregate;
00152 }
00153
00154 @WriteToFile
00155 @NameInUI("Monetary Holdings and Savings")
00156 @Description("Sum of Monetary Holdings and Savings")
00157 public double getMonetaryHoldingsAndSavings() {
00158 return monetaryHoldingsAndSavingsAggregate;
00159 }
00160
00161 @WriteToFile
00162 @NameInUI("Savings")
00163 @Description("The aggregated savings of households")
00164 public double getSavingsAggregate() {
00165 return savingsAggregate;
00166 }
00167
00168 @WriteToFile
00169 @NameInUI("Debt")
00170 @Description("The aggregated debts of firms")
00171 public double getDebtAggregate() {
00172 return debtAggregate;
00173 }
00174
00175 @WriteToFile
00176 @NameInUI("Created Money")
00177 @Description("The created money equals Debt - Savings")
00178 public double getCreatedMoney() {
00179 return createdMoney;
00180 }
00181
00182 @WriteToFile
00183 @NameInUI("Gold Stock")
00184 @Description("The intial stock of money +exports value-imports value")
00185 public double getGoldStock() {
00186 return goldStock ;
00187 }
00188
00189 @WriteToFile
00190 @NameInUI("Price Index")
00191 @Description("The Laspeyre price index")
00192 public double getPriceIndex() {
00193 return priceIndex;
00194 }
00195
00196 @WriteToFile
00197 @NameInUI("Investment")
00198 @Description("Total investment value")
00199 public double getInvestment() {
00200 return investment;
00201 }
00202
00203 @WriteToFile
00204 @NameInUI("Intermediary consumption")
00205 @Description("Total intermediary consumption value")
00206 public double getIntermediaryConsumption() {
00207 return intermediaryConsumption;
00208 }
00209
00210 @Override
00211 public String toString() {
00212 return "Financial";
00213 }
00214
00216 void updateMonetaryAggregates() {
00217 double lOldDebtAggregate = debtAggregate;
00218 double lOldSavingsAggregate = savingsAggregate;
00219 double lOldGoldStock= goldStock;
00220 double lOldMonetaryHoldingsAggregate= monetaryHoldingsAggregate;
00221
00222 monetaryHoldingsAggregate = 0;
00223 monetaryHoldingsAndSavingsAggregate = 0;
00224 debtAggregate = 0;
00225 savingsAggregate = 0;
00226 finalConsumption = 0.d;
00227 sales = 0.d;
00228 intermediaryConsumption = 0.d;
00229 investment = 0.d;
00230 wagesPaid = 0.d;
00231 wagesReceived = 0.d;
00232 taxesPaid = 0.d;
00233 unemploymentCost = 0.d;
00234 dividendsPaid = 0.d;
00235 dividendsReceived = 0.d;
00236 interestsPaid = 0.d;
00237 interestsReceived = 0.d;
00238
00239 double lDebtVariationsAggregate =0;
00240 double lHouseholdMoneyVariation=0;
00241 double lFirmMoneyVariation=0;
00242 double lFirmMoney=0;
00243
00244
00245
00246 for (final Household lHousehold : foundation.getHouseholds()) {
00247 monetaryHoldingsAggregate += lHousehold.getMoney();
00248 savingsAggregate += lHousehold.getSavings();
00249 finalConsumption += lHousehold.getConsumptionValue();
00250 wagesReceived += lHousehold.getEmploymentIncome();
00251 unemploymentCost += lHousehold.getUnemploymentIncome();
00252 taxesPaid += lHousehold.getTaxesPaid();
00253 dividendsReceived += lHousehold.getDividends();
00254 interestsReceived += lHousehold.getInterestsOnSavings();
00255 lHouseholdMoneyVariation+=lHousehold.getMoneyVariation();
00256 }
00257
00258 for (final Firm lFirm : foundation.generateFirmList()) {
00259 monetaryHoldingsAggregate += lFirm.getMoney();
00260 debtAggregate += lFirm.getDebt();
00261 sales +=lFirm.getSalesValue() ;
00262 intermediaryConsumption +=lFirm.getIntermediaryConsumptionValue();
00263 investment +=lFirm.getInvestmentValue();
00264 wagesPaid +=lFirm.getWagesPaid();
00265 dividendsPaid +=lFirm.getDividend();
00266 interestsPaid +=lFirm.getInterestsOnDebt();
00267
00268 lDebtVariationsAggregate += lFirm.getDebtVariation();
00269 lFirmMoneyVariation+=lFirm.getMoneyVariation();
00270 lFirmMoney +=lFirm.getMoney();
00271 }
00272
00273 monetaryHoldingsAndSavingsAggregate = monetaryHoldingsAggregate + savingsAggregate;
00274 createdMoney += (debtAggregate-lOldDebtAggregate) - (savingsAggregate-lOldSavingsAggregate);
00275 createdMoney += liquidationMissingDebts;
00276 createdMoney += memoryInterestRate.last()*(lOldSavingsAggregate-lOldDebtAggregate);
00277
00278 goldStock = monetaryHoldingsAggregate- createdMoney;
00279 if (foundation.getPeriod()>2){
00280
00281 }
00282
00283 savingsInvested = 0;
00284 if (foundation.getPeriod() >= 2) {
00285 liquidationMissingDebts = 0;
00286 }
00287 }
00288 }
00289
00290 @Description("The probe of financial system")
00291 @Origin(TECHNICAL)
00292 @Variability("?")
00293 public final Financial.Probe probe = new Probe();
00294
00295 @NotNull
00296 @Description("A reference to the foundation")
00297 @Origin(TECHNICAL)
00298 @Variability(CONSTANT)
00299 private final Foundation foundation;
00300
00301 @NotNull
00302 @Description("The initialization values for the Financial System")
00303 @Origin(TECHNICAL)
00304 @Variability(CONSTANT)
00305 private final FinancialInitValues initValues;
00306
00307 @GreaterOrApproxZero
00308 @Description("The actual interest rate, calculated in Financial::updateInterestRate using the Taylor-rule.")
00309 @Origin(THEORETICAL)
00310 @Variability(N_PERIODS)
00311 private double interestRate;
00312
00313 @Description("The actual inflation rate, calculated in Financial::updateInflationRate.")
00314 @Origin(THEORETICAL)
00315 @Variability(PERIOD)
00316 private double inflationRate;
00317
00318 @Description("The actual price index, calculated in Financial::updatePriceIndex.")
00319 @Origin(THEORETICAL)
00320 @Variability(PERIOD)
00321 private double priceIndex;
00322
00323 @Description("the total amount of debts lost by firms going bankrupt")
00324 @Origin(TECHNICAL)
00325 @Variability(VOLATILE)
00326 private double liquidationMissingDebts;
00327
00328 @Description("the total amount of savings invested (as debts)")
00329 @Origin(TECHNICAL)
00330 @Variability(PERIOD)
00331 private double savingsInvested;
00332
00333 @Description("the total amount of savings")
00334 @Origin(TECHNICAL)
00335 @Variability(PERIOD)
00336 private double savingsAggregate;
00337
00338 @Description("a memory for recording the enemployment rate")
00339 @Origin(TECHNICAL)
00340 @Variability(PERIOD)
00341 private ValueMemory memoryUnemploymentRate;
00342
00343 @Description("a memory for recording the inflation rate")
00344 @Origin(TECHNICAL)
00345 @Variability(PERIOD)
00346 private ValueMemory memoryInflationRate;
00347
00348 @Description("a memory for recording the interest rate")
00349 @Origin(TECHNICAL)
00350 @Variability(PERIOD)
00351 private ValueMemory memoryInterestRate;
00352
00359 Financial(Foundation pFoundation, FinancialInitValues pInitValues)
00360 {
00361 foundation = pFoundation;
00362 initValues = pInitValues;
00363 }
00364
00365
00367 void init(){
00368 final int lInterestRateInterval = Foundation.getInitValues().getInterestRateInterval();
00369 memoryUnemploymentRate = new ValueMemory(lInterestRateInterval);
00370 memoryInflationRate = new ValueMemory(lInterestRateInterval);
00371 memoryInterestRate = new ValueMemory(lInterestRateInterval);
00372
00373 interestRate = initValues.getEquilibriumInterestRate();
00374 inflationRate = 0.d;
00375 priceIndex = 100.d;
00376 liquidationMissingDebts = 0.d;
00377 savingsInvested = 0.d;
00378 savingsAggregate = 0.d;
00379
00380 probe.init();
00381 foundation.getProbeManager().addProbe(probe);
00382 foundation.getStepManager().registerEndOfPeriodCallback(2, new Callback(){
00383 @Override
00384 public void endOfPeriod() {
00385 memoryUnemploymentRate.add(foundation.calcUnemploymentRate());
00386 memoryInflationRate.add(inflationRate);
00387 memoryInterestRate.add(interestRate);
00388 }
00389 @Override
00390 public Object getOwner() {
00391 return Financial.this;
00392 }}
00393 );
00394 }
00395
00397 @PostValidateThis
00398 void updateInterestRate() {
00399 interestRate = Math.max(0,initValues.getEquilibriumInterestRate() +
00400 initValues.getTargetInflationRate() +
00401 initValues.getInflationRateAdaptionCoefficient() *
00402 (memoryInflationRate.average() - initValues.getTargetInflationRate()) +
00403 initValues.getUnemploymentRateAdaptionCoefficient() *
00404 (initValues.getNaturalUnemploymentRate() -
00405 memoryUnemploymentRate.average()));
00406 }
00407
00409 void updateInflationRate() {
00410 updatePriceIndex();
00411 inflationRate = priceIndex / 100.f - 1.f;
00412 }
00413
00418 private void updatePriceIndex() {
00419
00420 double lTotalValueLastPeriod = 0.f;
00421 for (final Sector lSector : foundation.getSectorList()) {
00422 lTotalValueLastPeriod += lSector.getStats().getTradeValueLastPeriod();
00423 }
00424
00425
00426 if (lTotalValueLastPeriod > 0.f) {
00427
00428 priceIndex = 0.f;
00429 for (final Sector lSector : foundation.getSectorList()) {
00430 final Sector.Stats lStats = lSector.getStats();
00431 if (lStats.getAverageTradePrice() * lStats.getTradeValueLastPeriod() > 0.f) {
00432
00433 priceIndex += lStats.getAverageTradePrice() * lStats.getTradeValueLastPeriod() /
00434 lStats.getAverageTradePriceLastPeriod();
00435 }
00436 }
00437
00438 priceIndex /= lTotalValueLastPeriod / 100.f;
00439 }
00440 }
00441
00442 public double calcMoneyStock(){
00443 double lSum = 0;
00444
00445 for (final Household lHousehold : foundation.getHouseholds()) {
00446 lSum += lHousehold.getMoney();
00447 }
00448
00449 for (final Firm lFirm : foundation.generateFirmList()) {
00450 lSum += lFirm.getMoney();
00451 }
00452
00453 return lSum;
00454 }
00455
00456 public double askForDebt(Firm pFirm, double pAmount) {
00457
00458
00459
00460
00461 return pAmount;
00462 }
00463
00464 public void save(Household pHousehold, double pAmount) {
00465
00466 savingsAggregate += pAmount;
00467 }
00468
00469 public double handOut(Household pHousehold, double pAmount) {
00470
00471 savingsAggregate -= pAmount;
00472 return pAmount;
00473 }
00474
00475 public double askForDebt(Household pHousehold, double pAmount) {
00476
00477 savingsAggregate -= pAmount;
00478 return pAmount;
00479 }
00480
00481
00482 public Financial.Probe getProbe() {
00483 return probe;
00484 }
00485
00486 FinancialInitValues getInitValues() {
00487 return initValues;
00488 }
00489
00490 @GreaterOrApproxZero
00491 double getInterestRate() {
00492 return interestRate;
00493 }
00494
00495 double getInflationRate() {
00496 return inflationRate;
00497 }
00498
00499 public double getLiquidationMissingDebts() {
00500 return liquidationMissingDebts;
00501 }
00502
00503 public void addToLiquidationMissingDebts(double pLiquidationMoney) {
00504 liquidationMissingDebts += pLiquidationMoney;
00505 }
00506
00507 public void setLiquidationMissingDebts(double pLiquidationMoney) {
00508 liquidationMissingDebts = pLiquidationMoney;
00509 }
00510
00511 public double getSavingsInvested() {
00512 return savingsInvested;
00513 }
00514
00515 public void setSavingsInvested(double pSavingsInvested) {
00516 savingsInvested = pSavingsInvested;
00517 }
00518 }
00519
00521