bankers-math
Advanced tools
Comparing version 0.2.4 to 0.2.5
213
Banker.js
@@ -1,13 +0,14 @@ | ||
// EU on Bankers' rounding: https://ec.europa.eu/economy_finance/publications/pages/publication1224_en.pdf | ||
const NA = 'NA' | ||
const E = 1e-8 | ||
const DIFFRA_EQ = 'Equilibrium' | ||
const DIFFRA_PROPORT = 'Proportionality' | ||
const DIFFRA_PAYOFF = 'Payoff' | ||
const NA = "NA"; | ||
const E = 1e-8; | ||
const DIFFRA_EQ = "Equilibrium"; | ||
const DIFFRA_PROPORT = "Proportionality"; | ||
const DIFFRA_PAYOFF = "Payoff"; | ||
const reducer = (accumulator, currentValue) => { return accumulator + currentValue } | ||
const reducer = (accumulator, currentValue) => { | ||
return accumulator + currentValue; | ||
}; | ||
const DIFF_TEMP = { min: 0, max: 0, fix: 0, percent: 0 } | ||
const DIFF_TEMP = { min: 0, max: 0, fix: 0, percent: 0 }; | ||
@@ -21,23 +22,31 @@ let Services = { | ||
sum (list) { | ||
return list.length > 0 ? list.reduce((acc, current) => acc + current, 0) : 0 | ||
sum(list) { | ||
return list.length > 0 | ||
? list.reduce((acc, current) => acc + current, 0) | ||
: 0; | ||
}, | ||
avg (list) { | ||
return list.length > 0 ? Services.sum(list) / list.length : 0 | ||
avg(list) { | ||
return list.length > 0 ? Services.sum(list) / list.length : 0; | ||
}, | ||
variance (list) { | ||
if (list.length === 0) return 0 | ||
variance(list) { | ||
if (list.length === 0) return 0; | ||
let avg = Services.avg(list) | ||
let avg = Services.avg(list); | ||
const squareDiffs = list.map((value) => { | ||
const diff = value - avg; | ||
return diff * diff; | ||
}) | ||
return Math.sqrt( squareDiffs.reduce((acc, current) => acc + current, 0) / list.length ) | ||
}); | ||
return Math.sqrt( | ||
squareDiffs.reduce((acc, current) => acc + current, 0) / | ||
list.length, | ||
); | ||
}, | ||
analyseValues ( list, decimalPlaces = 6 ) { | ||
let sum = Services.sum(list) | ||
let avg = Services.toFixedNumber( list.length > 0 ? sum / list.length : 0, decimalPlaces ) | ||
analyseValues(list, decimalPlaces = 6) { | ||
let sum = Services.sum(list); | ||
let avg = Services.toFixedNumber( | ||
list.length > 0 ? sum / list.length : 0, | ||
decimalPlaces, | ||
); | ||
let variance = 0 | ||
let variance = 0; | ||
if (list.length > 0) { | ||
@@ -47,4 +56,10 @@ const squareDiffs = list.map((value) => { | ||
return diff * diff; | ||
}) | ||
variance = Services.toFixedNumber( Math.sqrt( squareDiffs.reduce((acc, current) => acc + current, 0) / list.length ), decimalPlaces ) | ||
}); | ||
variance = Services.toFixedNumber( | ||
Math.sqrt( | ||
squareDiffs.reduce((acc, current) => acc + current, 0) / | ||
list.length, | ||
), | ||
decimalPlaces, | ||
); | ||
} | ||
@@ -55,73 +70,112 @@ | ||
avg, | ||
variance | ||
} | ||
variance, | ||
min: list.length > 0 ? Math.min(...list) : 0, | ||
max: list.length > 0 ? Math.max(...list) : 0, | ||
}; | ||
}, | ||
defined (value) { | ||
return value !== undefined && value !== null | ||
defined(value) { | ||
return value !== undefined && value !== null; | ||
}, | ||
definedNumber (value) { | ||
return value !== undefined && value !== null && ( value.isNaN ? (!value.isNaN() && (!value.isFinite || value.isFinite()) ) : !Number.isNaN(value) && Number.isFinite(value) ) | ||
definedNumber(value) { | ||
return ( | ||
value !== undefined && | ||
value !== null && | ||
(value.isNaN | ||
? !value.isNaN() && (!value.isFinite || value.isFinite()) | ||
: !Number.isNaN(value) && Number.isFinite(value)) | ||
); | ||
}, | ||
minmax (value, min, max) { | ||
return value < min ? min : (value > max ? max : value) | ||
minmax(value, min, max) { | ||
return value < min ? min : value > max ? max : value; | ||
}, | ||
bankersRounding ( num, decimalPlaces = 2, base = 10 ) { | ||
let pow = Math.pow(base, decimalPlaces) | ||
let powed = +(num * pow) | ||
let floor = Math.floor( powed ) | ||
let fDiff = powed - floor | ||
let r = (fDiff > 0.5 - E && fDiff < 0.5 + E) ? ((floor % 2 == 0) ? floor : floor + 1) : Math.round( powed ) | ||
return r / pow | ||
bankersRounding(num, decimalPlaces = 2, base = 10) { | ||
let pow = Math.pow(base, decimalPlaces); | ||
let powed = +(num * pow); | ||
let floor = Math.floor(powed); | ||
let fDiff = powed - floor; | ||
let r = | ||
fDiff > 0.5 - E && fDiff < 0.5 + E | ||
? floor % 2 == 0 | ||
? floor | ||
: floor + 1 | ||
: Math.round(powed); | ||
return r / pow; | ||
}, | ||
toFixedNumber (num, decimalPlaces = 2, base = 10) { | ||
const pow = Math.pow(base, decimalPlaces) | ||
return +(Math.round(num * pow) / pow) | ||
toFixedNumber(num, decimalPlaces = 2, base = 10) { | ||
const pow = Math.pow(base, decimalPlaces); | ||
return +(Math.round(num * pow) / pow); | ||
}, | ||
divide (amount, portions, decimalPlaces, total) { | ||
let finals = [] | ||
divide(amount, portions, decimalPlaces, total) { | ||
let finals = []; | ||
let sum = total || portions.reduce(reducer) | ||
let sum = total || portions.reduce(reducer); | ||
let numerator = 0, divident = 0, value = 0, iteration = amount | ||
let numerator = 0, | ||
divident = 0, | ||
value = 0, | ||
iteration = amount; | ||
for (let i = 0; i < portions.length; ++i) { | ||
divident = divident === 0 ? sum : divident - numerator | ||
if (divident === 0) divident = 1 | ||
numerator = portions[i] | ||
divident = divident === 0 ? sum : divident - numerator; | ||
if (divident === 0) divident = 1; | ||
numerator = portions[i]; | ||
value = Services.toFixedNumber( iteration * numerator / (divident || 1), decimalPlaces ) | ||
iteration = iteration - value | ||
value = Services.toFixedNumber( | ||
(iteration * numerator) / (divident || 1), | ||
decimalPlaces, | ||
); | ||
iteration = iteration - value; | ||
finals.push( value ) | ||
finals.push(value); | ||
} | ||
return finals | ||
return finals; | ||
}, | ||
calculateDiffraction ( amount, diffraction, normalisationMethod, rounding = 2 ) { | ||
let percentages = diffraction.map( (diff) => { return diff.percent } ) | ||
let percentageSum = percentages.reduce( (acc, percent) => { return acc + percent } ) | ||
let totalFee = Services.toFixedNumber( amount * percentageSum / 100, rounding ) | ||
let divisions = Services.divide( totalFee, percentages, rounding ) | ||
calculateDiffraction( | ||
amount, | ||
diffraction, | ||
normalisationMethod, | ||
rounding = 2, | ||
) { | ||
let percentages = diffraction.map((diff) => { | ||
return diff.percent; | ||
}); | ||
let percentageSum = percentages.reduce((acc, percent) => { | ||
return acc + percent; | ||
}); | ||
let totalFee = Services.toFixedNumber( | ||
(amount * percentageSum) / 100, | ||
rounding, | ||
); | ||
let divisions = Services.divide(totalFee, percentages, rounding); | ||
let feeValues = [], feeTotal = 0 | ||
let feeValues = [], | ||
feeTotal = 0; | ||
for (let i = 0; i < divisions.length; ++i) { | ||
let diff = Object.assign( {}, DIFF_TEMP, diffraction[i] ) | ||
let feeValue = Services.minmax( divisions[ i ] + diff.fix, diff.min || 0, diff.max || (totalFee + diff.fix) ) | ||
feeValues.push( feeValue ) | ||
feeTotal += feeValue | ||
let diff = Object.assign({}, DIFF_TEMP, diffraction[i]); | ||
let feeValue = Services.minmax( | ||
divisions[i] + diff.fix, | ||
diff.min || 0, | ||
diff.max || totalFee + diff.fix, | ||
); | ||
feeValues.push(feeValue); | ||
feeTotal += feeValue; | ||
} | ||
if ( normalisationMethod && normalisationMethod !== NA ) { | ||
if (normalisationMethod && normalisationMethod !== NA) { | ||
if (feeTotal < amount) { | ||
if ( normalisationMethod === DIFFRA_EQ ) | ||
feeValues = Services.divide( amount, feeValues, rounding ) | ||
} | ||
else if (feeTotal > amount) { | ||
if ( normalisationMethod === DIFFRA_PROPORT ) { | ||
feeValues = Services.divide( amount, feeValues, rounding ) | ||
} else if ( normalisationMethod === DIFFRA_PAYOFF ) { | ||
let toCut = feeTotal - amount | ||
for (let i = feeValues.length - 1; toCut > 0 && i >= 0; --i) { | ||
let tc = toCut <= feeValues[i] ? toCut : feeValues[i] | ||
feeValues[i] -= tc | ||
toCut -= tc | ||
if (normalisationMethod === DIFFRA_EQ) | ||
feeValues = Services.divide(amount, feeValues, rounding); | ||
} else if (feeTotal > amount) { | ||
if (normalisationMethod === DIFFRA_PROPORT) { | ||
feeValues = Services.divide(amount, feeValues, rounding); | ||
} else if (normalisationMethod === DIFFRA_PAYOFF) { | ||
let toCut = feeTotal - amount; | ||
for ( | ||
let i = feeValues.length - 1; | ||
toCut > 0 && i >= 0; | ||
--i | ||
) { | ||
let tc = toCut <= feeValues[i] ? toCut : feeValues[i]; | ||
feeValues[i] -= tc; | ||
toCut -= tc; | ||
} | ||
@@ -131,7 +185,6 @@ } | ||
} | ||
return { divisions, feeValues, feeTotal, diffraction } | ||
} | ||
return { divisions, feeValues, feeTotal, diffraction }; | ||
}, | ||
}; | ||
} | ||
module.exports = Services | ||
module.exports = Services; |
{ | ||
"name": "bankers-math", | ||
"version": "0.2.4", | ||
"version": "0.2.5", | ||
"description": "Helper function for Bankers' calculus", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
12663
389