From 986f5b74409b126daed87851731be6c47703746c Mon Sep 17 00:00:00 2001 From: Peter Alexander <p.m.w.alexander@gmail.com> Date: Wed, 17 Jul 2019 23:21:30 +0100 Subject: [PATCH] Bug fixes to stock level based price adjustment --- scripts/runPlum.sh | 2 +- src/ac/ed/lurg/InternationalMarket.java | 2 +- src/ac/ed/lurg/country/GlobalPrice.java | 44 ++++++++++++++++--------- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/scripts/runPlum.sh b/scripts/runPlum.sh index c2983c97..2fcb597e 100755 --- a/scripts/runPlum.sh +++ b/scripts/runPlum.sh @@ -76,7 +76,7 @@ fi cd $scenariodir echo "starting" -runcmd="java -Xmx1G -XX:+PrintGC -classpath $GAMSPATH/apifiles/Java/api/GAMSJavaAPI.jar:$classesdir -DBUILDVER=$buildver -DCONFIG_FILE=$scenariodir/config.properties ac.ed.lurg.ModelMain" +runcmd="java -Xmx2G -XX:+PrintGC -classpath $GAMSPATH/apifiles/Java/api/GAMSJavaAPI.jar:$classesdir -DBUILDVER=$buildver -DCONFIG_FILE=$scenariodir/config.properties ac.ed.lurg.ModelMain" echo $runcmd $runcmd echo "finished" diff --git a/src/ac/ed/lurg/InternationalMarket.java b/src/ac/ed/lurg/InternationalMarket.java index a34e824c..262531cd 100644 --- a/src/ac/ed/lurg/InternationalMarket.java +++ b/src/ac/ed/lurg/InternationalMarket.java @@ -68,7 +68,7 @@ public class InternationalMarket { GlobalPrice prevPrice = worldPrices.get(crop); double imports = totalImportCommodities.containsKey(crop) ? totalImportCommodities.get(crop) : 0.0; double exportsBeforeTransportLosses = totalExportCommodities.containsKey(crop) ? totalExportCommodities.get(crop) : 0.0; - LogWriter.print("Updating " + crop.getGamsName() + " prices : "); + LogWriter.print(timestep.getYear() + " Updating " + crop.getGamsName() + " prices : "); GlobalPrice adjustedPrice = prevPrice.createWithUpdatedMarketPrices(imports, exportsBeforeTransportLosses, timestep, totalProduction.get(crop)); LogWriter.println( String.format("Price for %s updated from %s to %s \n", crop.getGamsName(), prevPrice, adjustedPrice)); worldPrices.put(crop, adjustedPrice); diff --git a/src/ac/ed/lurg/country/GlobalPrice.java b/src/ac/ed/lurg/country/GlobalPrice.java index b4b30601..aee2d8f8 100644 --- a/src/ac/ed/lurg/country/GlobalPrice.java +++ b/src/ac/ed/lurg/country/GlobalPrice.java @@ -6,13 +6,15 @@ import ac.ed.lurg.types.Parameter; import ac.ed.lurg.utils.LogWriter; public class GlobalPrice { + private int timestepId; private double exportPrice; private double importAmount; private double exportAmountBeforeLoss; private double transportLosses; private double stockLevel; - private GlobalPrice(double exportPrice, double stockLevel, double importAmount, double exportAmountBeforeLoss, double transportLosses) { + private GlobalPrice(int timestepId, double exportPrice, double stockLevel, double importAmount, double exportAmountBeforeLoss, double transportLosses) { + this.timestepId = timestepId; this.exportPrice = exportPrice; this.stockLevel = stockLevel; this.importAmount = importAmount; @@ -21,7 +23,7 @@ public class GlobalPrice { } public static GlobalPrice createInitial(double exportPrice) { - return new GlobalPrice(exportPrice, Double.NaN, Double.NaN, Double.NaN, Double.NaN); + return new GlobalPrice(ModelConfig.START_TIMESTEP-1, exportPrice, Double.NaN, Double.NaN, Double.NaN, Double.NaN); } public double getExportPrice(){ @@ -61,18 +63,23 @@ public class GlobalPrice { return transportLosses; } - public GlobalPrice createWithUpdatedMarketPrices(double imports, double exportsBeforeTransportLosses, Timestep timestep, double production) { + public GlobalPrice createWithUpdatedMarketPrices(double newImports, double newExportAmountBeforeLoss, Timestep timestep, double production) { if (Double.isNaN(stockLevel)) stockLevel = ModelConfig.STOCK_TARGET_RATE * production; // set stock initially to target level, this is pretty horrible and should really be done on construction but don't easily have production value at that point double transportLossRate = (!ModelConfig.SHOCKS_POSSIBLE) ? ModelConfig.TRANSPORT_LOSSES : ModelConfig.getParameter(Parameter.TRANSPORT_LOSSES, timestep.getYear()); - double transportLosses = exportsBeforeTransportLosses * transportLossRate; - double exportsAfterTransportLosses = exportsBeforeTransportLosses - transportLosses; + double newTransportLosses = newExportAmountBeforeLoss * transportLossRate; + double exportsAfterTransportLosses = newExportAmountBeforeLoss - newTransportLosses; - if (imports > 0 || exportsAfterTransportLosses > 0) { - double updatedStock = stockLevel + exportsBeforeTransportLosses - transportLosses - imports; - LogWriter.println(String.format(" global stocks from %.2f to %.2f", stockLevel, updatedStock)); + if (newImports > 0 || exportsAfterTransportLosses > 0) { + double oldDiff = 0; + if (timestep.getTimestep() == timestepId) // if recomputing for same year need to back our previous adjustment + oldDiff = exportAmountBeforeLoss - transportLosses - importAmount; + double newDiff = newExportAmountBeforeLoss - newTransportLosses - newImports; + double updatedStock = stockLevel + newDiff - oldDiff; + + LogWriter.println(String.format(" global stocks from %.2f to %.2f due to newDiff %.2f oldDiff %.2f", stockLevel, updatedStock, newDiff, oldDiff)); if (updatedStock < 0) LogWriter.println(String.format("Global stocks are below zero")); @@ -83,24 +90,30 @@ public class GlobalPrice { adjustment = 1; } else if (ModelConfig.PRICE_UPDATE_BY_MARKET_IMBALANCE) { - double ratio = (imports-exportsAfterTransportLosses)/(imports-exportsAfterTransportLosses+production); + double ratio = (newImports-exportsAfterTransportLosses)/(newImports-exportsAfterTransportLosses+production); adjustment = Math.exp(ratio * ModelConfig.MARKET_LAMBA); - LogWriter.println(String.format("Price update market imbalance: adjustment= %s, imports %.1f, exports %.1f", adjustment, imports, getExportsAfterTransportLosses())); + LogWriter.println(String.format("Price update market imbalance: adjustment= %.4f, imports %.1f, exports %.1f", adjustment, newImports, getExportsAfterTransportLosses())); } else { double stockTarget = ModelConfig.STOCK_TARGET_RATE * production; double ratio = (stockTarget - updatedStock) / stockTarget; - if (Math.abs(ratio) >= 1) - adjustment = 10; // default to max change - else + if (ratio >= 0) { adjustment = 1 + ModelConfig.MARKET_LAMBA * ratio/(1 - ratio*ratio); + if (adjustment > 3 || ratio > 1) + adjustment = 3; // default to max up change + } + else { + adjustment = 1 / ( 1 - ModelConfig.MARKET_LAMBA * ratio/(1 - ratio*ratio)); + if (adjustment < 0.1 || ratio < -1) + adjustment = 0.1; // default to max down change + } - LogWriter.println(String.format("Price update from stock target: adjustment= %s, ratio= %s", adjustment, ratio)); + LogWriter.println(String.format("Price update from stock target: adjustment= %.4f, ratio= %.4f", adjustment, ratio)); } newPrice = exportPrice * adjustment * financialSpeculationMultiplier; - return new GlobalPrice(newPrice, updatedStock, imports, exportsBeforeTransportLosses, transportLosses); + return new GlobalPrice(timestep.getTimestep(), newPrice, updatedStock, newImports, newExportAmountBeforeLoss, newTransportLosses); } else { LogWriter.printlnError(String.format("Price for not updated (still %s), as no imports and no exports for it", exportPrice)); @@ -117,3 +130,4 @@ public class GlobalPrice { return exportAmountBeforeLoss - transportLosses - importAmount; } } + -- GitLab