Skip to content

Instantly share code, notes, and snippets.

@mdaniel
Created April 3, 2015 06:18
Show Gist options
  • Save mdaniel/28b147484a9f647663ed to your computer and use it in GitHub Desktop.
Save mdaniel/28b147484a9f647663ed to your computer and use it in GitHub Desktop.
Calculates the monthly payment, with taxes and HOA if applicable, for a listing on cleanoffer.com. This script is San Francisco Ready(tm) in that it will show you the list price, as well as the actual price (estimated at 20% over list).
// ==UserScript==
// @name show mortgage cost on cleanoffer
// @author mdaniel
// @version 1.7.0
// @namespace http://MatthewDaniel.com/greasemonkey/cleanoffer.com
// @include http://re.cleanoffer.com/b/zephyr/mybriefcase/viewnewmatch.htm*
// @match http://re.cleanoffer.com/b/zephyr/mybriefcase/viewnewmatch.htm*
// @include http://re.cleanoffer.com/b/zephyr/listing.htm*
// @match http://re.cleanoffer.com/b/zephyr/listing.htm*
// ==/UserScript==
/**
* The "percent" APR for your 30 year fixed mortgage.
* @type {Number}
*/
var MORTGAGE_APR = 3.875;
/**
* Just what it says.
* @type {Number}
*/
var DOWN_PAYMENT = 300000;
/**
* The property tax "percentage".
* @type {Number}
*/
var TAX_RATE = 1.188;
/**
* Poached from http://stackoverflow.com/a/22385930.
* @param {Number} ir - interest rate per month
* @param {Number} np - number of periods (months)
* @param {Number} pv - present value
* @param {Number} fv - future value
* @param {Number} type - when the payments are due:
* 0: end of the period, e.g. end of month (default)
* 1: beginning of period
*/
function PMT(ir, np, pv, fv, type) {
var pmt, pvif;
fv || (fv = 0);
type || (type = 0);
if (ir === 0) {
return -(pv + fv)/np;
}
pvif = Math.pow(1 + ir, np);
pmt = - ir * pv * (pvif + fv) / (pvif - 1);
if (type === 1) {
pmt /= (1 + ir);
}
return pmt;
}
// wrap in a function for easier try-catch
var injectCosts = function() {
var priceH3NL = [].map.call(
document.querySelectorAll('h3'),
function(it) {
var ma = /Price: *[$]([0-9,]+)/.exec(it.innerHTML);
if (!ma) return null;
return [it, new Number(ma[1].replace(',', ''))];
}).filter(function (it) { return null != it; });
if (0 === priceH3NL.length) {
return;
}
var h3 = priceH3NL[0][0];
var cost = priceH3NL[0][1];
var mortgages = [cost, cost * 1.20].map(
function(it) {
return -1 * PMT(
(MORTGAGE_APR / 100) / 12,
30 * 12,
it - DOWN_PAYMENT
);
}
);
var taxes = (cost * (TAX_RATE / 100)) / 12;
var duesList = [].map.call(
document.querySelectorAll('#listing-details .hd')
, function (it) {
if (null == /Dues/.exec(it.innerHTML)) {
return null;
}
var numberTD = it.parentNode.querySelector('td ~ td');
if (null == numberTD) {
return null;
}
return new Number(numberTD.innerHTML);
}).filter(function(it){ return null != it; });
var dues = (0 === duesList.length) ? 0 : duesList[0];
var mortgage1str =
' $'+(mortgages[0] + taxes + dues).toFixed();
var mortgage2str =
' +20 $'+(mortgages[1] + taxes + dues).toFixed();
var hoastr = (0 === dues) ? '' : ' HOA $'+dues;
var s = document.createElement('span');
s.style.color = 'green';
s.style.paddingLeft = '20px';
s.appendChild(
document.createTextNode(
mortgage1str + mortgage2str + hoastr
)
);
h3.appendChild(s);
};
try {
injectCosts();
} catch (ex) {
console.error('Kaboom', ex);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment