Привет всем, я Дон Ге.
В области контроля кредитного риска часто используется отчет о старении. Это одна из трудностей для новичков, поскольку он включает в себя различные действия, такие как погашение пользователем, просрочка платежа и различные статистические показатели в бизнесе. Не могу четко разобраться в логике. На этот раз я подробно познакомлю вас с базовой логикой вычислений отчетов Vintage.
Если взять в качестве примера кредитный месяц 2022-11, то ставка просрочки M2+, соответствующая каждому MOB, равна:
M2+ставка просрочки MOB1 = M2+сумма просрочки MOB1/общая сумма кредита в ноябре 2022 г. = 0
Коэффициент просрочки М2+МОБ2 = сумма просроченной задолженности М2+МОБ2/общая сумма кредита в ноябре 2022 г. = 0,95%.
…
M2+ставка просрочки MOB12 = M2+сумма просрочки MOB12/общая сумма кредита в ноябре 2022 г. = 3,22%
общая формула:M2+процент просроченной задолженности MOB(N)=M2+сумма просроченной задолженности MOB(N)/общая сумма кредита в xx кредитном месяце
Чтобы рассчитать процент просроченной задолженности для каждой ячейки, вам необходимо сначала понять четыре статистических момента времени: дату наступления срока погашения, фактическую дату погашения, дату наблюдения MOB и текущую дату наблюдения.
Подводя итог, есть несколько вещей, которые вам необходимо подтвердить, прежде чем выполнять расчеты Vintage:
В реальных бизнес-сценариях чаще используется калибр ставки просроченной задолженности: «Наблюдение за моментом времени на конец месяца MOB + текущий калибр просрочки + просроченный неурегулированный баланс».
После того, как определены четыре вышеуказанных пункта, остальное зависит от даты погашения и фактической даты погашения. Дата погашения определяется на основе конструкции продукта, поэтому неопределенной является только фактическая дата погашения. Фактическая дата погашения определяется поведением клиента и может произойти в любой момент времени. Таким образом, в зависимости от местоположения фактической даты погашения могут возникать различные ситуации.
Во-первых, когда срок родов превышает текущий день наблюдения, то есть срок родов еще находится в будущем и еще не наступил, поэтому мы не можем судить.
Во-вторых, срок исполнения находится в пределах текущего дня наблюдения, то есть исторических данных, которые мы можем наблюдать. В настоящее время, если фактическая дата погашения приходится на дату платежа или раньше, это означает, что погашение является нормальным и никакой просрочки не произошло, поэтому количество просроченных дней равно 0.
Третий тип заключается в том, что фактическая дата погашения находится между датой платежа и датой наблюдения за толпой, что означает, что, хотя он и просрочен, он был погашен до даты наблюдения за толпой. При этом, если калибр в данный момент просрочен, то если в конце моб просрочки не возникает, то количество дней просрочки равно 0, если просрочен именно калибр, то он просрочен, и количество; дней просрочки = фактическая дата погашения - дата погашения = 5
В-четвертых, фактическая дата погашения наступает после даты наблюдения MOB, хотя она и погашается, но позже, чем точка наблюдения MOB. Таким образом, текущая дата просрочки совпадает с предыдущей датой просрочки. = Дата наблюдения МОБ – дата погашения =21.
Пятый тип - это то, что с наступления срока платежа до текущей даты наблюдения клиент не совершил никаких действий по погашению, то есть не был произведен расчет. Таким образом, текущие стандарты просроченной и прошлой просрочки одинаковы. Количество дней просрочки = дата наблюдения МОБ - дата погашения = 21.
Ранее мы рассчитывали статус просрочки и дни просрочки каждого клиента по каждому мобу на основе 4 статистических моментов времени.
Код Python для расчета дней и сумм просрочки в основной части показан ниже.
###########################Просроченная идентификация#################### #####################
# Обработать просроченный знак
data_all_1['odu_flag'] = 0
data_all_1.loc[(data_all_1['actual_repay_date']>data_all_1['obser_month_end'])|(data_all_1['actual_repay_date'].isnull()),'odu_flag'] = 1
data_all_1['odu_flag_sft'] = data_all_1.groupby('order_id')['odu_flag'].transform(lambda x:x.shift(1))
data_all_1['actual_repay_date_sft'] = data_all_1.groupby('order_id')['actual_repay_date'].transform(lambda x:x.shift(1))
data_all_1['odu_first_flag'] = 0
data_all_1.loc[(data_all_1['odu_flag_sft']==1)&(data_all_1['odu_flag']==1)&(data_all_1['actual_repay_date_sft']>data_all_1['obser_month_end']),'odu_first_flag'] = 2
data_all_1.loc[(data_all_1['odu_flag_sft']==1)&(data_all_1['odu_flag']==1)&(data_all_1['actual_repay_date_sft']<=data_all_1['obser_month_end']),'odu_first_flag'] = 1
# Обновить оставшуюся сумму основного долга
data_all_1.loc[data_all_1['odu_first_flag']==1,'balance'] = data_all_1['balance_sft']
data_all_1.loc[(data_all_1['odu_first_flag']==2),'balance'] = np.nan
data_all_1['balance'] = data_all_1.groupby('order_id')['balance'].transform(lambda x:x.ffill())
##########################Количество дней просрочки################### # ####################
# Фактически дата наблюдения в конце месяца еще не прошла.
data_all_1.loc[(data_all_1['actual_repay_date'].isnull()==False)&(data_all_1['actual_repay_date']<=data_all_1['obser_month_end']),'odu_days'] = 0
# Просрочено - просрочено впервые.
data_all_1.loc[(data_all_1['odu_first_flag']==1),'odu_days'] = (data_all_1['obser_month_end']-data_all_1['expected_date']).dt.days
# по-прежнему просрочено
data_all_1['expected_date_2'] = data_all_1['expected_date']
data_all_1.loc[(data_all_1['odu_first_flag']==2),'expected_date_2'] = np.nan
data_all_1['expected_date_2'] = data_all_1.groupby('order_id')['expected_date_2'].transform(lambda x:x.ffill())
data_all_1.loc[(data_all_1['odu_first_flag']==2),'odu_days'] = (data_all_1['obser_month_end']-data_all_1['expected_date_2']).dt.days
Вот и все.
Полный код выглядит следующим образом (реальные бизнес-данные + практика написания кода):