如何计算混合费用?

时间:2019-02-28 20:22:01

标签: javascript math

我正在尝试使用费用表来计算投资管理费。例如,假设投资额为$ 5,000,000,这是费用表:

  • 1,000,000及以下:1.00%
  • 2,000,000:0.75%
  • 3,000,000:0.50%
  • 3,000,001+:0.25%

其中,不足1,000,000美元的部分收取1.00%,超过3,000,000美元的部分收取0.25%。我需要使用javascript得出混合价格(在这种情况下,答案是0.55%或27,500美元)。

如果我们作为示例使用的金额为$ 5,000,000并且上面的费用表,您如何得到答案?

  • 1,000,000美元* 0.0100 = 10,000美元(前100万美元的费用)
  • $ 1,000,000 * 0.0075 = $ 7,500(第二个100万美元的费用)
  • $ 1,000,000 * 0.0050 = $ 5,000(第三百万美元的费用)
  • 2,000,000美元* 0.0025 = 5,000美元(超过300万美元的一切)

因此,要管理这500万美元,费用将是以上费用的总和(27,500美元)。而$ 27,500 / $ 5,000,000 = 0.55%,这就是我们的“混合费用”。

需要注意的是,并非每个收费表都完全像这样。有些有不同的费用和限额。

到目前为止,我对这个问题的研究结果是什么?我还没有找到可以在SO上完成此功能的质量示例。像我试图在此处实现的那样,似乎所有基于SO的分层定价计算只能确定给定数量的商品的单一价格,而不是混合价格。

我的费用表可能类似于以下数组:

fee_schedule: [
{ fee: 0.0100, limit: 1000000},
{ fee: 0.0075, limit: 2000000},
{ fee: 0.0050, limit: 3000000},
{ fee: 0.0025, limit: Infinity}
]

这是我开始的方向,但是因为看到自己编写了一个荒谬的长函数,所以撞上了墙。

function determineFee(schedule, amount) {
   schedule.forEach(tier => {
    if (amount <= tier.limit) {
     // is this a path I should go down?
    }
   }
  //
}

2 个答案:

答案 0 :(得分:1)

您可以建立最后或零个实际限制的差额,或者如果它是最后一个元素,则取Infinity,以将费用用于剩余的剩余价值。

然后检查该值是否小于增量。如果为true,请计算剩余价值的费用并结束循环。

否则,从增量中计算费用,将增量减去该值,然后将限制分配为最后一个值,以使该值可用于下一个循环。

function getFee(value) {
    var fee = 0;

    fee_schedule.some((o, i, a) => {
        var delta = i + 1 === a.length
                ? Infinity
                : o.limit - (a[i - 1] && a[i - 1].limit || 0);

        if (value < delta) {
            fee += value * o.fee;
            return true;
        }
        fee += delta * o.fee;
        value -= delta;
    });

    return fee;
}

var fee_schedule = [{ fee: 0.0100, limit: 1000000 }, { fee: 0.0075, limit: 2000000 }, { fee: 0.0050, limit: 3000000 }, { fee: 0.0025, limit: 4000000 }],
    value = 5000000,
    fee = getFee(value);

console.log(fee);

对于较短的方法,您可以更改数据集,并仅使用限制的槽位大小,前三个Itime为一百万,最后一个为Infinity

function getFee(value) {
    var sum = 0;

    fee_schedule.some(({ fee, limit }) => {
        var v = value < limit ? value : limit;
        sum += v * fee;
        return !(value -= v);
    });

    return sum;
}

var fee_schedule = [{ fee: 0.0100, limit: 1000000 }, { fee: 0.0075, limit: 1000000 }, { fee: 0.0050, limit: 1000000 }, { fee: 0.0025, limit: Infinity }],
    value = 5000000,
    fee = getFee(value);

console.log(fee);

答案 1 :(得分:1)

这是另一种可能性:

const blended = (schedule) => (amount) =>
  schedule.reduce ((sum, {fee, limit}, idx, sched) => {
    const top = Math.min (limit, amount)
    const bottom = idx == 0 ? 0 : sched[idx - 1].limit
  
    return sum + (top > bottom ? fee * (top - bottom) : 0)
  }, 0)

const blendedFee = (schedule) => {
  const calc = blended(schedule)
  return (amount) => calc(amount) / amount
}

const fee_schedule = [
  { fee: 0.0100, limit: 1000000},
  { fee: 0.0075, limit: 2000000},
  { fee: 0.0050, limit: 3000000},
  { fee: 0.0025, limit: Infinity}
]

console.log (blended (fee_schedule) (5000000))
console.log (blendedFee (fee_schedule) (5000000))

请注意,这些都是经过咖喱处理的,因此,如果您需要将其重复用于各种贷款金额,则可以存储对blended (fee_schedule)blendedFee (fee_schedule)的引用。

这不包括妮娜(Nina)的答案的早期机智,但我认为这样做更容易。