diff --git a/src/ac/ed/lurg/InternationalMarket.java b/src/ac/ed/lurg/InternationalMarket.java
index a3a4af7a8e8bdb960adeebdc404ff5a77cc08662..ac25b1f2639f67e1ca98ed252b11caa6c62669aa 100644
--- a/src/ac/ed/lurg/InternationalMarket.java
+++ b/src/ac/ed/lurg/InternationalMarket.java
@@ -152,6 +152,18 @@ public class InternationalMarket {
 		}
 	}
 
+	public boolean negativeStockLevelsExist() {
+		for (Map.Entry<CropType, GlobalPrice> entry : worldPrices.entrySet()) {
+			double stocklevel = entry.getValue().getStockLevel();
+			if (stocklevel < 0) {
+				LogWriter.println(String.format("negativeStockLevelsExist: %s has negative stock %.3f", entry.getKey().getFaoName(), stocklevel));
+				return true;
+			}
+		}
+		LogWriter.println(String.format("No negative stocks found"));
+		return false;
+	}
+
 	/*	public double findMaxPriceDiff(Map<CropType, Double> previousExportPrices) {
 		if (previousExportPrices == null)
 			return Double.MAX_VALUE;
diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java
index 97d12c6634395d0412bbab1a32728dfb32a6ac46..aba2b20c564415abbec68199f6f9e28ff830d3d2 100755
--- a/src/ac/ed/lurg/ModelConfig.java
+++ b/src/ac/ed/lurg/ModelConfig.java
@@ -267,8 +267,8 @@ public class ModelConfig {
 
 	// Temporal configuration
 	public static final int START_TIMESTEP = getIntProperty("START_TIMESTEP", 0);
-	public static final int END_TIMESTEP = getIntProperty("END_TIMESTEP", 18);
-	public static final int TIMESTEP_SIZE = getIntProperty("TIMESTEP_SIZE", 5);
+	public static final int END_TIMESTEP = getIntProperty("END_TIMESTEP", 90);
+	public static final int TIMESTEP_SIZE = getIntProperty("TIMESTEP_SIZE", 1);
 	public static final int BASE_YEAR = getIntProperty("BASE_YEAR", 2010);
 
 	// Import export limits
@@ -338,6 +338,7 @@ public class ModelConfig {
 	public static final double MAX_PRICE_INCREASE = getDoubleProperty("MAX_PRICE_INCREASE", 1.5);
 	public static final double MAX_PRICE_DECREASE = getDoubleProperty("MAX_PRICE_DECREASE", .75);
 	public static final int DEMAND_RECALC_MAX_ITERATIONS = IS_CALIBRATION_RUN ? 0 : getIntProperty("DEMAND_RECALC_MAX_ITERATIONS", 1);  // 0 is original behaviour
+	public static final boolean DEMAND_RECALC_ON_NEGATIVE_STOCK = IS_CALIBRATION_RUN ? false : getBooleanProperty("DEMAND_RECALC_ON_NEGATIVE_STOCK", false); 
 
 	public static final double POPULATION_AGGREG_LIMIT = getDoubleProperty("POPULATION_AGGREG_LIMIT", 30.0);  // in millions, smaller countries are aggregated on a regional basis
 	public static final boolean PREDEFINED_COUNTRY_GROUPING = getBooleanProperty("PREDEFINED_COUNTRY_GROUPING", true);
diff --git a/src/ac/ed/lurg/ModelMain.java b/src/ac/ed/lurg/ModelMain.java
index f863419d2876475169095e08ba695da2c51d4bb9..108914d29e35e8c5bb3900b72796c6cfc3aac5bb 100644
--- a/src/ac/ed/lurg/ModelMain.java
+++ b/src/ac/ed/lurg/ModelMain.java
@@ -51,7 +51,6 @@ import ac.ed.lurg.yield.LPJYieldResponseMapReader;
 import ac.ed.lurg.yield.YieldRaster;
 import ac.sac.raster.IntegerRasterItem;
 import ac.sac.raster.IntegerRasterReader;
-import ac.sac.raster.InterpolatingRasterSet;
 import ac.sac.raster.RasterHeaderDetails;
 import ac.sac.raster.RasterKey;
 import ac.sac.raster.RasterOutputer;
@@ -133,16 +132,18 @@ public class ModelMain {
 		countryAgents.determineProductionForAll(timestep, yieldSurfaces, currentIrrigationData);
 		internationalMarket.determineInternationalTrade(countryAgents.getAll(), timestep);
 		
-		// loop for iterations.  Could check within a tolerance using internationalMarket.findMaxPriceDiff, not doing so as doesn't find a solution due to inelastic consumption
-		for (int i=0; i < ModelConfig.DEMAND_RECALC_MAX_ITERATIONS; i++) {
-			LogWriter.println("\n++ Re-estimating prices and demand " + i);
+		int i = 0;		
+		while (i < ModelConfig.DEMAND_RECALC_MAX_ITERATIONS || 
+				(ModelConfig.DEMAND_RECALC_ON_NEGATIVE_STOCK && internationalMarket.negativeStockLevelsExist() && i<10)) { // loop if negative stock have we haven't tried 10 times already
+			LogWriter.println("\n++ Re-estimating prices and demand: timestep " + timestep.getTimestep() + ": interation " + i);
 			countryAgents.recalculateDemandAndNetImportsForAll(); // recalculate demand from new prices and calculate imports and exports
 			internationalMarket.determineInternationalTrade(countryAgents.getAll(), timestep); // calculate prices
+			i++;
 		}
 		internationalMarket.applyPriceShocks(timestep);
 		
 		// output results
-		outputTimestepResults(timestep, globalLandUseRaster);
+		outputTimestepResults(timestep);
 		
 		checkAndSaveCheckpoint(timestep);
 	}
@@ -157,7 +158,7 @@ public class ModelMain {
 				int year = Integer.parseInt(yearStr[i]);
 				if (timestep.getYear() == year) {
 					LogWriter.println("Saving checkpoint");
-					serializeCheckpoint(globalLandUseRaster);
+					serializeCheckpoint();
 				}
 			}
 		}
@@ -404,14 +405,14 @@ public class ModelMain {
 		}
 	}
 	
-	private void outputTimestepResults(Timestep timestep, RasterSet<LandUseItem> landUseRaster) {
+	private void outputTimestepResults(Timestep timestep) {
 
-		writeLandCoverFile(timestep, landUseRaster);
+		writeLandCoverFile(timestep, globalLandUseRaster);
 		writeGlobalMarketFile(timestep);
 		writeDemandFile(timestep);
 		writeDomesticProductionFile(timestep);
 		writeCountryDemandFile(timestep);
-		writeGlobalFoodBalanceSheet(timestep, landUseRaster);
+		writeGlobalFoodBalanceSheet(timestep, globalLandUseRaster);
 		writeAnimalNumber(timestep);
 
 		if (ModelConfig.OUTPUT_FOR_LPJG) {
@@ -420,17 +421,18 @@ public class ModelMain {
 				RasterSet<LandUseItem> landUseToOutput = null;
 
 				if (outputYear == timestep.getYear()) {
-					landUseToOutput = landUseRaster;
+					landUseToOutput = globalLandUseRaster;
 				} 
 				else if (ModelConfig.INTERPOLATE_OUTPUT_YEARS) {
-					InterpolatingRasterSet<LandUseItem> intermediateLandUse = new InterpolatingRasterSet<LandUseItem>( landUseRaster.getHeaderDetails()) {
+					// we run with 1 year time steps these days so this code is redundant and flawed
+			/*		InterpolatingRasterSet<LandUseItem> intermediateLandUse = new InterpolatingRasterSet<LandUseItem>( landUseRaster.getHeaderDetails()) {
 						private static final long serialVersionUID = 1306045141011047760L;
 						protected LandUseItem createRasterData() {
 							return new LandUseItem();
 						}
 					};
 					intermediateLandUse.setup(globalLandUseRaster, landUseRaster, timestep.getPreviousTimestep().getYear(), timestep.getYear(), outputYear);
-					landUseToOutput = intermediateLandUse;
+					landUseToOutput = intermediateLandUse; */
 				}
 
 				if (landUseToOutput != null) {
@@ -442,7 +444,7 @@ public class ModelMain {
 		}
 
 		if (ModelConfig.IS_CALIBRATION_RUN) {
-			serializeCheckpoint(landUseRaster);
+			serializeCheckpoint();
 		}
 
 		if (timestep.isInitialTimestep() && ModelConfig.GENERATE_NEW_YIELD_CLUSTERS)
@@ -450,7 +452,7 @@ public class ModelMain {
 
 		// Output LandUses to tabular file, for analysis (perhaps)
 		LogWriter.println("Outputing land uses Year: " + timestep.getYear());
-		LandUseOutputer landuseOutputer = new LandUseOutputer(timestep.getYear(), landUseRaster);
+		LandUseOutputer landuseOutputer = new LandUseOutputer(timestep.getYear(), globalLandUseRaster);
 		landuseOutputer.writeOutput();
 
 		// don't really need this a LPJ outputs have same data, although in a slightly different format
@@ -646,8 +648,8 @@ public class ModelMain {
 		}
 	}	
 	
-	private void serializeCheckpoint(RasterSet<LandUseItem> landUseRaster) {
-		serializeLandUse(landUseRaster);
+	private void serializeCheckpoint() {
+		serializeLandUse(globalLandUseRaster);
 		countryAgents.serializeCropUsageForAll();
 		internationalMarket.serializeGlobalPrices();
 	}