【问题标题】:FIFO Days Past Due logic pseudo-code in ExcelExcel中的FIFO过期天数逻辑伪代码
【发布时间】:2020-02-18 12:07:02
【问题描述】:

我正在尝试在 excel 中创建一些伪代码逻辑,以便在 Alteryx/SAS/Python 中实现,但我无法理解这些逻辑。

我有以下虚拟交易的借方和贷方,我正在尝试计算每笔交易的逾期天数 (DPD)。在现实世界中,我们也会有交易日期。

问题的简单版本:D 列和 E 列是我的输入。 G列是我的目标。 H是我们目前做的,这是不正确的。

我们当前的实现将这些数据重新连接到自身,因此我们能够识别最旧的未付借记交易 - 但未来的实现不能使用这种逻辑,因为它与我们的数据的连接太大。

我正在尝试一种更有效的方法。一种想法是获取最后 X 次借方金额,并查看累计未付金额是否大于最后 1、2、3、4... 借方的总和。我们不关心的任何 >5 次借记(因为它们会 >90DPD,这是我们需要的最多信息)。

这是我正在尝试的:

我试图在 5 列 (Q--U) 中获取最后一个借记金额(和滞后版本),但我没有走得太远。

【问题讨论】:

  • 当有部分信用支付时应该发生什么?数据是否按客户 ID 和交易日期 (day) 预先排序?客户 ID 的最大交易数(最大 N)是多少? _temporary_ 数组可用于跟踪状态,如果假定 N 很大,或者如果动态/未知 N 将成为实现的一部分,则可以使用散列。
  • 部分付款意味着借方仍到期。数据是按客户 ID 和交易日期预先排序的,是的。目前我只是想让伪代码版本在没有任何 VBA(只是列)的情况下在 excel 中工作。
  • 请以文本形式发布数据。图片并不是特别有用,尤其是在它们很小的时候。
  • 你有 SAS/OR 许可吗?
  • 我猜你有几个可用的包给你标签。在 Alteryx 中,它将是多行公式和运行总计的组合。理想的情况是通过迭代宏。

标签: excel python-3.x sas fifo alteryx


【解决方案1】:

在组中,您需要跟踪实际交易(以数组形式)、运行余额、最早借记的“已付”索引以及到期还款,并在遇到贷记时汇总“已付”索引。

例如,SAS 数据步解决方案:

data have;
  cid=1;
  txid+1;
  input day type $ amt; datalines;
  0 DR 100
 30 DR 100
 45 CR 100
 60 DR 100
 75 CR 100
 90 DR 100
105 CR   .
120 DR 100
135 CR 100
run;

data want 
;*/ debug;
  array days[1000] _temporary_;
  array amts[1000] _temporary_;
  array types[1000] $2 _temporary_;

  set have;
  by cid;

  if first.cid then do;        * reset ledger tracking;
    call missing(of days(*));
    call missing(of amts(*));
    call missing(of types(*));
    tx_index = 0;              retain tx_index;
    balance = 0;               retain balance;
    pd_index = 1;              retain pd_index;
    dr_remnant = 0;            retain dr_remnant;
    days_past_due = 0;         retain days_past_due;
  end;

  * track ledger entry and update running balance;

  tx_index + 1;

  days[tx_index] = day;
  amts[tx_index] = amt;
  types[tx_index] = type;

  select (type);
    when ('DR') balance + -amt; /* debit entry, update running balance. tyvm says the bank */
    when ('CR') balance +  amt; /* credit entry, apply to running balance. bank is 'interested' */
    otherwise;
  end;

  if type = 'CR' then do;    
    if balance < 0 then do;  /* determine earliest unpaid debit after applying credit (FIFO) */
      cr_applied = 0;
      do while (cr_applied < amt and pd_index < tx_index);
        if types[pd_index] = 'CR' then continue; /* earlier credit entry will have already been dealt with */

        if dr_remnant > 0 then do;
          dr_remnant = dr_remnant - amt;
          cr_applied + amt;
        end;

        if dr_remnant > 0 then leave;  * do not advance pd_index, still chipping away at a single DR entry;

        cr_applied + amts[pd_index];   * CR covers DR remnant or an entire DR;
        pd_index + 1;
      end;
    end;

    /* fnd: /* find next debit where payment is due */
    do pd_index = pd_index by 1 while (types[pd_index] ne 'DR' and pd_index < tx_index);
    end;

    if types[pd_index] = 'DR' and dr_remnant = 0 then 
      dr_remnant = amts[pd_index];
  end;

  debit_due_start_date = days[pd_index];
  days_past_due = days[tx_index] - days[pd_index];
run;

您可能还会发现 Embedded Implicit Loops in SAS with two Set Statements 有点相似且具有指导意义:

一个强大的解决方案需要一种交易分类账方法,以便正确处理获取每个优惠券的多个兑换和跟踪超额以及在获取额外兑换之前将超额应用于优惠券的替代方案。

【讨论】:

  • 嗨,Richard - 我知道已经有一段时间了,但实际上我终于摸清了这个逻辑。外部 IF 块末尾的“fnd:”循环在做什么?直接跳到下一个到期付款的借记处?
  • 是的。 do pd_index 循环在types[] 数组中前进,直到找到非借记交易。对于可靠的数据,非借记(或ne 'DR')意味着CR 交易类型。我针对非稳健数据的情况进行编码,其中可能存在DRCR 以外的虚假事务类型
猜你喜欢
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-23
  • 1970-01-01
  • 1970-01-01
  • 2017-08-28
相关资源
最近更新 更多