Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify config #40

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@
<artifactId>mason</artifactId>
<version>19</version>
</dependency>
<dependency>
<groupId>com.typesafe</groupId>
<artifactId>config</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
Expand Down
211 changes: 105 additions & 106 deletions src/main/java/collectors/CreditSupply.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,30 @@
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;

public class CreditSupply extends CollectorBase {
private static final long serialVersionUID = 1630707025974306844L;

private Config config = Model.config; // Passes the Model's configuration parameters object to a private field

public CreditSupply() {
mortgageCounter = 0;
ftbCounter = 0;
btlCounter = 0;
// TODO: This limit in the number of events taken into account to build statistics is not explained in the paper (affects oo_lti, oo_ltv, btl_ltv, btl_icr, downpayments)
setArchiveLength(10000);
}
private static final long serialVersionUID = 1630707025974306844L;


public CreditSupply() {
mortgageCounter = 0;
ftbCounter = 0;
btlCounter = 0;
// TODO: This limit in the number of events taken into account to build statistics is not explained in the paper (affects oo_lti, oo_ltv, btl_ltv, btl_icr, downpayments)
setArchiveLength(10000);
}

/***
* collect information for this timestep
*/
public void step() {
/***
* collect information for this timestep
*/
public void step() {
double oldTotalCredit = totalOOCredit + totalBTLCredit;
totalOOCredit = 0.0;
totalBTLCredit = 0.0;
for(MortgageAgreement m : Model.bank.mortgages) {
if(m.isBuyToLet) {
totalBTLCredit += m.principal;
} else {
totalOOCredit += m.principal;
}
if(m.isBuyToLet) {
totalBTLCredit += m.principal;
} else {
totalOOCredit += m.principal;
}
}
netCreditGrowth = (totalOOCredit + totalBTLCredit - oldTotalCredit)/oldTotalCredit;
nApprovedMortgages = mortgageCounter;
Expand All @@ -41,55 +40,55 @@ public void step() {
mortgageCounter = 0;
ftbCounter = 0;
btlCounter = 0;
}
}

/***
* record information for a newly issued mortgage
* @param h
* @param approval
*/
public void recordLoan(Household h, MortgageAgreement approval, House house) {
double housePrice;
if(config.isMortgageDiagnosticsActive()) {
housePrice = approval.principal + approval.downPayment;
affordability = config.derivedParams.getAffordabilityDecay()*affordability + (1.0-config.derivedParams.getAffordabilityDecay())*approval.monthlyPayment/(h.monthlyEmploymentIncome);
if(approval.principal > 1.0) {
if(approval.isBuyToLet) {
btl_ltv.addValue(100.0*approval.principal/housePrice);
// double icr = Model.rentalMarket.getAverageSalePrice(house.getQuality())*12.0/(approval.principal*Model.bank.getBtLStressedMortgageInterestRate());
double icr = Model.rentalMarket.averageSoldGrossYield*approval.purchasePrice/(approval.principal*config.getCentralBankBTLStressedInterest());
btl_icr.addValue(icr);
} else {
oo_ltv.addValue(100.0*approval.principal/housePrice);
oo_lti.addValue(approval.principal/h.annualEmploymentIncome());
}
downpayments.addValue(approval.downPayment);
}
// approved_mortgages[0][approved_mortgages_index] = approval.principal/(h.annualEmploymentIncome());
// approved_mortgages[1][approved_mortgages_index] = approval.downPayment/(h.annualEmploymentIncome());
// approved_mortgages_index += 1;
// if(approved_mortgages_index == ARCHIVE_LEN) approved_mortgages_index = 0;
mortgageCounter += 1;
if(approval.isFirstTimeBuyer) ftbCounter += 1;
if(approval.isBuyToLet) btlCounter += 1;
}
}
/***
* record information for a newly issued mortgage
* @param h
* @param approval
*/
public void recordLoan(Household h, MortgageAgreement approval, House house) {
double housePrice;
if(config.isMortgageDiagnosticsActive()) {
housePrice = approval.principal + approval.downPayment;
affordability = config.derivedParams.getAffordabilityDecay()*affordability + (1.0-config.derivedParams.getAffordabilityDecay())*approval.monthlyPayment/(h.monthlyEmploymentIncome);
if(approval.principal > 1.0) {
if(approval.isBuyToLet) {
btl_ltv.addValue(100.0*approval.principal/housePrice);
// double icr = Model.rentalMarket.getAverageSalePrice(house.getQuality())*12.0/(approval.principal*Model.bank.getBtLStressedMortgageInterestRate());
double icr = Model.rentalMarket.averageSoldGrossYield*approval.purchasePrice/(approval.principal*config.getCentralBankBTLStressedInterest());
btl_icr.addValue(icr);
} else {
oo_ltv.addValue(100.0*approval.principal/housePrice);
oo_lti.addValue(approval.principal/h.annualEmploymentIncome());
}
downpayments.addValue(approval.downPayment);
}
// approved_mortgages[0][approved_mortgages_index] = approval.principal/(h.annualEmploymentIncome());
// approved_mortgages[1][approved_mortgages_index] = approval.downPayment/(h.annualEmploymentIncome());
// approved_mortgages_index += 1;
// if(approved_mortgages_index == ARCHIVE_LEN) approved_mortgages_index = 0;
mortgageCounter += 1;
if(approval.isFirstTimeBuyer) ftbCounter += 1;
if(approval.isBuyToLet) btlCounter += 1;
}
}

// ---- Mason stuff
// ----------------
public String desLTI() {return("Loan to Income constraint on mortgages");}
public String desTHETA_FTB() {return("Loan to Value haircut for first time buyers");}
public String desTHETA_HOME() {return("Loan to Value haircut for homeowners");}
public String desTHETA_BTL() {return("Loan to Value haircut for buy-to-let investors");}
public String desN_PAYMENTS() {return("Number of monthly repayments in a mortgage");}
public double getBaseRate() {
return Model.bank.getBaseRate();
}
public void setBaseRate(double rate) {
Model.bank.setBaseRate(rate);
}
// ---- Mason stuff
// ----------------
public String desLTI() {return("Loan to Income constraint on mortgages");}
public String desTHETA_FTB() {return("Loan to Value haircut for first time buyers");}
public String desTHETA_HOME() {return("Loan to Value haircut for homeowners");}
public String desTHETA_BTL() {return("Loan to Value haircut for buy-to-let investors");}
public String desN_PAYMENTS() {return("Number of monthly repayments in a mortgage");}
public double getBaseRate() {
return Model.bank.getBaseRate();
}
public void setBaseRate(double rate) {
Model.bank.setBaseRate(rate);
}
public double [] getOOLTVDistribution() {return(oo_ltv.getValues());}
public double [] getOOLTIDistribution() {return(oo_lti.getValues());}
public double [] getBTLLTVDistribution() {return(btl_ltv.getValues());}
Expand All @@ -115,53 +114,53 @@ public void setSaveBTLICRDistribution(boolean doSave) throws FileNotFoundExcepti


public int getNRegisteredMortgages() {
return(Model.bank.mortgages.size());
return(Model.bank.mortgages.size());
}

public int getArchiveLength() {
return archiveLength;
}
public void writeDistributionToFile(double [] vals, String filename) throws FileNotFoundException, UnsupportedEncodingException {
public int getArchiveLength() {
return archiveLength;
}
public void writeDistributionToFile(double [] vals, String filename) throws FileNotFoundException, UnsupportedEncodingException {
PrintWriter dist = new PrintWriter(filename, "UTF-8");
if(vals.length > 0) {
dist.print(vals[0]);
for(int i=1; i<vals.length; ++i) {
dist.print(", "+vals[i]);
}
dist.print(vals[0]);
for(int i=1; i<vals.length; ++i) {
dist.print(", "+vals[i]);
}
}
dist.close();
}
}

public void setArchiveLength(int archiveLength) {
this.archiveLength = archiveLength;
oo_lti = new DescriptiveStatistics(archiveLength);
oo_ltv = new DescriptiveStatistics(archiveLength);
btl_ltv = new DescriptiveStatistics(archiveLength);
btl_icr = new DescriptiveStatistics(archiveLength);
downpayments = new DescriptiveStatistics(archiveLength);
}
public void setArchiveLength(int archiveLength) {
this.archiveLength = archiveLength;
oo_lti = new DescriptiveStatistics(archiveLength);
oo_ltv = new DescriptiveStatistics(archiveLength);
btl_ltv = new DescriptiveStatistics(archiveLength);
btl_icr = new DescriptiveStatistics(archiveLength);
downpayments = new DescriptiveStatistics(archiveLength);
}


//public double STATS_DECAY = 0.98; // Decay constant (per step) for exp averaging of stats
//public int HISTOGRAM_NBINS = 101;
//public double STATS_DECAY = 0.98; // Decay constant (per step) for exp averaging of stats
//public int HISTOGRAM_NBINS = 101;

public int archiveLength; // number of mortgage approvals to remember
public double affordability = 0.0;
public DescriptiveStatistics oo_lti;
public DescriptiveStatistics oo_ltv;
public DescriptiveStatistics btl_ltv;
public DescriptiveStatistics btl_icr;
public DescriptiveStatistics downpayments;
// public double [][] approved_mortgages = new double [2][ARCHIVE_LEN]; // (loan/income, downpayment/income) pairs
// public int approved_mortgages_index;
public int mortgageCounter;
public int ftbCounter;
public int btlCounter;
public int nApprovedMortgages; // total number of new mortgages
public int nFTBMortgages; // number of new first time buyer mortgages given
public int nBTLMortgages; // number of new buy to let mortages given
public double totalBTLCredit = 0.0; // buy to let mortgage credit
public double totalOOCredit = 0.0; // owner-occupier mortgage credit
public double netCreditGrowth; // rate of change of credit per month as percentage
public int archiveLength; // number of mortgage approvals to remember
public double affordability = 0.0;
public DescriptiveStatistics oo_lti;
public DescriptiveStatistics oo_ltv;
public DescriptiveStatistics btl_ltv;
public DescriptiveStatistics btl_icr;
public DescriptiveStatistics downpayments;
// public double [][] approved_mortgages = new double [2][ARCHIVE_LEN]; // (loan/income, downpayment/income) pairs
// public int approved_mortgages_index;
public int mortgageCounter;
public int ftbCounter;
public int btlCounter;
public int nApprovedMortgages; // total number of new mortgages
public int nFTBMortgages; // number of new first time buyer mortgages given
public int nBTLMortgages; // number of new buy to let mortages given
public double totalBTLCredit = 0.0; // buy to let mortgage credit
public double totalOOCredit = 0.0; // owner-occupier mortgage credit
public double netCreditGrowth; // rate of change of credit per month as percentage
}
34 changes: 34 additions & 0 deletions src/main/java/configuration/BankConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package configuration;


import com.typesafe.config.Config;


public class BankConfig {

private int mortgageDurationYears;
private double initialBaseRate;
private double creditSupplyTarget;

BankConfig(Config config) {
mortgageDurationYears = config.getInt("mortgage-duration-years");
initialBaseRate = config.getDouble("initial=base-rate");
creditSupplyTarget = config.getDouble("credit-supply-target");
}

/** Mortgage duration in years. */
public int getMortgageDurationYears() {
return mortgageDurationYears;
}

/** Bank initial base-rate, which remains currently unchanged. */
public double getInitialBaseRate() {
return initialBaseRate;
}

/** Bank's target supply of credit per household per month. */
public double getCreditSupplyTarget() {
return creditSupplyTarget;
}

}
60 changes: 60 additions & 0 deletions src/main/java/configuration/BuyToLetConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package configuration;

import com.typesafe.config.Config;

/** Class encapsulating the parameters for "buy-to-let" investors.
*
* @author davidrpugh
*/
public class BuyToLetConfig {

private double probabilityInvestor;
private double minIncomePercentile;
private double fundamentalistCapitalGainCoefficient;
private double trendFollowersCapitalGainCoefficient;
private double probabilityFundamentalist;
private boolean buyToLetYieldScaling;

BuyToLetConfig(Config config) {
probabilityInvestor = config.getDouble("probability-investor");
minIncomePercentile = config.getDouble("min-income-percentile");
fundamentalistCapitalGainCoefficient = config.getDouble("fundamentalist-capitalGain-coefficient");
trendFollowersCapitalGainCoefficient = config.getDouble("trend-followers-capital-gain-coefficient");
probabilityFundamentalist = config.getDouble("probability-fundamentalist");
buyToLetYieldScaling = config.getBoolean("buy-to-let-yield-scaling");
}

/** Prior probability of being (wanting to be) a BTL investor (double)
*
* TODO: 6/22/2017 Shouldn't this be 4% according to the article?
*/
public double getProbabilityInvestor() {
return probabilityInvestor;
}

/** Minimum income percentile for a household to be a BTL investor. */
public double getMinIncomePercentile() {
return minIncomePercentile;
}

/** Weight that fundamentalists put on cap gain. */
public double getFundamentalistCapitalGainCoefficient() {
return fundamentalistCapitalGainCoefficient;
}

/** Weight that trend-followers put on cap gain. */
public double getTrendFollowersCapitalGainCoefficient() {
return trendFollowersCapitalGainCoefficient;
}

/** Probability that a BTL investor is a fundamentalist versus a trend-follower. */
public double getProbabilityFundamentalist() {
return probabilityFundamentalist;
}

/** Chooses between two possible equations for BTL investors to make their buy/sell decisions (boolean) */
public boolean isBuyToLetYieldScaling() {
return buyToLetYieldScaling;
}

}
Loading