Mintos.com is a P2P lending platform. One can invest in loans offered by various loan organizers from various countries. Most loans are short-term and personal loans from FSU countries such as Georgia, Armenia, Russia, but also Spain or Indonesia etc. Many loans are very short term (1 month) but there’s also some with longer terms (several years). The majority of loans are denominated in Euro but the share of loans in other currencies is increasing. Typical interest rates for Euro-loans is 11 to 13%.
More than 13 million loans were issued on Mintos as of mid 2019. The loan amount offered is over 3 billion EUR (Euro loans only).
Mintos grants access to the full loan book of all loans issued since inception. For this head to Statistics and look for the link Download Loan Book (might require having an account and being logged in). One gets a ZIP with (as of today) 27 individual Excel sheets. Unzipped it’s abozut 1 Gb.
Let’s have a look.
While Mintos hands out the data in several Excel sheets, Excel is not recommended for analysis. The maximum number of rows in Microsoft Excel is 1 048 576.
For using it in R, I recommend first converting and saving the sheets to csv’s. These csv’s can be loaded and row-bind. I use tidyR tibbles and dplyr but for performance reasons one could prefer to use data.table.
library(tidyverse)
library(readxl)
# converting xlsx to csv
files <- list.files("data/xlsx")
for (i in 1:length(files)) {
print(i)
data <- read_excel(paste0("data/", files[i]))
data %>% write_csv(paste0("data/", str_replace(files[i], ".xlsx", ".csv")))
print("done")
}
rm(data)
# read and bind together
csvfiles <- list.files("data/csv")
data <- tibble()
for (i in 1:length(csvfiles)) {
print(i)
data <- bind_rows(data, read_csv(paste0("data/csv/", csvfiles[i])))
print("done")
}
# check the size
object.size(data) %>% format(units = "auto")
# save for later use
data %>% saveRDS("data/data.RDS")
# save in two RDS (both <100Mb because of Github's restiction on file size)
nrows <- nrow(data)
half <- round(nrows/2)
data[1:half,] %>% saveRDS("data/data1.RDS")
data[(half+1):nrows,] %>% saveRDS("data/data2.RDS")
Yet better would be to use Apache Spark, e.g. with sparklyr. I tried it and it works fine, but at the end I chose to use my usual workflow with dplyr anyway (instead of dplyr commands with sparklyr).
library(sparklyr)
for (i in 1:length(csvfiles)) {
print(i)
sparklyr::spark_read_csv(sc,
name = paste0("data", i),
path = paste0("data/csv/", csvfiles[i]))
assign(paste0("sparkdata", i), tbl(sc, paste0("data", i)))
print("done")
}
data <- sdf_bind_rows(sparkdata1, sparkdata2, sparkdata3, sparkdata4, sparkdata5, sparkdata6, sparkdata7, sparkdata8, sparkdata9, sparkdata10,
sparkdata11, sparkdata12, sparkdata13, sparkdata14, sparkdata15, sparkdata16, sparkdata17, sparkdata18, sparkdata19, sparkdata20,
sparkdata21, sparkdata22, sparkdata23, sparkdata24, sparkdata25, sparkdata26, sparkdata27)
object.size(data) # should be tiny
A medium spec workstation is recommended (used here 16 Gb RAM + 16 Gb Swap, i7-4790 CPU @ 3.60GHz × 4). My laptop was not suited for the job.
First, let’s look at the available columns.
library(tidyverse)
library(lubridate)
library(magrittr)
data <- bind_rows(readRDS("data/data1.RDS"), readRDS("data/data2.RDS"))
data %>% glimpse()
## Observations: 13,314,969
## Variables: 19
## $ Id <chr> "8210540-02", "9657926-03", "13425646-01…
## $ `Issue Date` <dttm> 2019-04-14, 2019-04-04, 2019-04-10, 201…
## $ `Closing Date` <dttm> 2019-04-28, 2019-05-04, 2019-05-10, 201…
## $ `Listing Date` <dttm> 2019-04-14 19:26:03, 2019-04-14 19:26:0…
## $ Country <chr> "Ukraine", "Russian Federation", "Russia…
## $ `Loan Originator` <chr> "Dinero", "Dozarplati", "Dozarplati", "D…
## $ `Mintos Rating` <chr> "C+", "B-", "B-", "B-", "B-", "B-", "B-"…
## $ `Loan Type` <chr> "Short-Term Loan", "Short-Term Loan", "S…
## $ `Loan Rate Percent` <dbl> 14.0, 17.5, 17.5, 17.5, 17.5, 17.5, 17.5…
## $ Term <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
## $ Collateral <chr> "No", "No", "No", "No", "No", "No", "No"…
## $ `Initial LTV` <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
## $ LTV <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
## $ `Loan Status` <chr> "Finished prematurely", "Finished premat…
## $ `Buyback reason` <chr> "Agreement prolongation", "Agreement pro…
## $ `Initial Loan Amount` <dbl> 77.58, 8000.00, 4000.00, 10000.00, 1000.…
## $ `Remaining Loan Amount` <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
## $ Currency <chr> "EUR", "RUB", "RUB", "RUB", "RUB", "RUB"…
## $ Buyback <chr> "Yes", "Yes", "Yes", "Yes", "Yes", "Yes"…
https://www.mintos.com/en/<Id>
e.g. https://www.mintos.com/en/18218910-01One loan at random:
set.seed(2)
data %>%
sample_n(1) %>%
glimpse()
## Observations: 1
## Variables: 19
## $ Id <chr> "2089899-06"
## $ `Issue Date` <dttm> 2018-03-28
## $ `Closing Date` <dttm> 2018-04-27
## $ `Listing Date` <dttm> 2018-03-31 19:32:03
## $ Country <chr> "Latvia"
## $ `Loan Originator` <chr> "Bino"
## $ `Mintos Rating` <chr> "B-"
## $ `Loan Type` <chr> "Short-Term Loan"
## $ `Loan Rate Percent` <dbl> 13.1
## $ Term <dbl> 1
## $ Collateral <chr> "No"
## $ `Initial LTV` <dbl> 0
## $ LTV <dbl> 0
## $ `Loan Status` <chr> "Finished prematurely"
## $ `Buyback reason` <chr> "Agreement prolongation"
## $ `Initial Loan Amount` <dbl> 420.86
## $ `Remaining Loan Amount` <dbl> 0
## $ Currency <chr> "EUR"
## $ Buyback <chr> "Yes"
Due to the number of observations we resort to samples of 1 000 to 10 000 for some calculations.
# library(ggcorrplot)
library(GGally)
topcountries <- data %>%
group_by(Country) %>%
count() %>%
ungroup() %>%
arrange(-n) %>%
top_n(3) %>%
pull(Country)
toporigin <- data %>%
group_by(`Loan Originator`) %>%
count() %>%
ungroup() %>%
arrange(-n) %>%
top_n(3) %>%
pull(`Loan Originator`)
set.seed(15)
data %>%
select(Rate = `Loan Rate Percent`, Term, LTV0 = `Initial LTV`, Amount1000 =`Initial Loan Amount`, Currency, `Listing Date`, Buyback,
Country, Origin = `Loan Originator`, Collateral) %>%
mutate(Currency = recode_factor(Currency, "EUR" = "EUR", .default = "Other"),
Buyback = as.factor(Buyback),
Collateral = as.factor(Collateral),
Country = fct_other(Country, keep = topcountries, other_level = "Other"),
Origin = fct_other(Origin, keep = toporigin, other_level = "Other"),
ListingYear = year(`Listing Date`)) %>%
select(-`Listing Date`) %>%
select(-Country, -Origin) %>%
sample_n(10000) %>%
filter(!is.na(ListingYear)) -> quants_fct
mintoscolor <- "#78c8c7"
quants_fct %>%
# drop_na() %>%
mutate(ListYr = as.factor(ListingYear),
Amount1000 = Amount1000/1000) %>%
select(-ListingYear) %>%
ggpairs(
lower = list(
continuous = wrap("smooth_loess", alpha = 0.5, color = mintoscolor),
combo = wrap("box_no_facet", alpha = 0.5, fill = mintoscolor), #"facetdensity",
discrete = wrap("ratio", alpha = 0.5, fill = mintoscolor)
# mapping = aes(color = ListYr)
),
upper = list(
combo = wrap("facetdensity", color = mintoscolor),
discrete = wrap("ratio", alpha = 0.5, fill = mintoscolor)
),
diag = list(
continuous = wrap("densityDiag", alpha = 0.5),
discrete = "barDiag",
mapping = aes(color = ListYr)
),
switch = "y",
title = "Correlation of Mintos.com loan characteristics") -> cp
cp
What we see is that rates have droped since 2015 but most recently in 2019 have risen again. This might be partially caused by a higher share of non-EUR loans which generally offer higher interest rates.
# library(ggbeeswarm)
set.seed(12)
data %>%
filter(Currency == "EUR", !is.na(`Listing Date`)) %>%
mutate(ListYr = factor(year(`Listing Date`))) -> d
d %>% sample_n(30000) %>%
ggplot(aes(x = ListYr, y = `Loan Rate Percent`)) +
geom_boxplot() +
# geom_beeswarm(data = (d %>% sample_n(1000)), alpha = 0.1, color = mintoscolor)
geom_jitter(data = (d %>% sample_n(1000)), alpha = 0.2, color = mintoscolor) +
scale_y_continuous(breaks = seq(0,25,1)) +
labs(title = "Distribution of interest rate of newly listed loans") +
theme_bw()
Let’s compare the interest rates over originator, country, and currency.
topn <- 5
topcurrencies <- data %>%
group_by(Currency) %>%
count() %>%
ungroup() %>%
arrange(-n) %>%
top_n(topn) %>%
pull(Currency)
topcountries <- data %>%
group_by(Country) %>%
count() %>%
ungroup() %>%
arrange(-n) %>%
top_n(topn) %>%
pull(Country)
toporigin <- data %>%
group_by(`Loan Originator`) %>%
count() %>%
ungroup() %>%
arrange(-n) %>%
top_n(topn) %>%
pull(`Loan Originator`)
data %>%
mutate(Currency = fct_other(Currency, keep = topcurrencies, other_level = "Other"),
# Buyback = as.factor(Buyback),
# Collateral = as.factor(Collateral),
Country = fct_other(Country, keep = topcountries, other_level = "Other"),
Origin = fct_other(`Loan Originator`, keep = toporigin, other_level = "Other"),
ListingYear = year(`Listing Date`)) %>%
select(Rate = `Loan Rate Percent`, Country, Origin, Currency) %>%
sample_n(3000) %>%
drop_na() %>%
ggpairs(
lower = list(
continuous = wrap("smooth_loess", alpha = 0.5, color = mintoscolor),
combo = wrap("box_no_facet", alpha = 0.5, fill = mintoscolor), #"facetdensity",
discrete = wrap("ratio", alpha = 0.5, fill = mintoscolor)
# mapping = aes(color = ListYr)
),
upper = list(
combo = wrap("facetdensity", color = mintoscolor),
discrete = wrap("ratio", alpha = 0.5, fill = mintoscolor)
),
diag = list(
continuous = wrap("densityDiag", alpha = 0.5),
discrete = "barDiag"
),
switch = "y",
title = "Correlation of Mintos.com loan characteristics") -> cp
cp +
theme_bw()
Mintos’ default rating D
library(kableExtra)
data %>%
filter(`Closing Date` < (Sys.Date() - days(60))) %>%
mutate(Default = recode(`Mintos Rating`, "D" = "D", .default = "notD")) %>%
group_by(Default, ClYr = year(`Closing Date`)) %>%
count() %>%
spread(Default, n) %>%
ungroup() %>%
mutate(ClYr = as.character(ClYr)) %>%
knitr::kable(format = "html", format.args = list(big.mark = "'")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed")) %>%
row_spec(0, bold = T)
ClYr | D | notD | <NA> |
---|---|---|---|
2015 | NA | 10’589 | NA |
2016 | NA | 300’037 | 859 |
2017 | 380 | 1’176’765 | 24 |
2018 | 1’012 | 3’800’260 | 45 |
2019 | NA | 3’526’038 | 1 |
data %>%
filter(`Closing Date` < (Sys.Date() - days(60))) %>%
# mutate(Default = recode(`Mintos Rating`, "D" = "D", .default = "notD")) %>%
group_by(`Loan Status`, ClYr = year(`Closing Date`)) %>%
count() %>%
spread(`Loan Status`, n) %>%
ungroup() %>%
mutate(ClYr = as.character(ClYr)) %>%
knitr::kable(format = "html", format.args = list(big.mark = "'")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed")) %>%
row_spec(0, bold = T)
ClYr | Current | Default | Finished as scheduled | Finished - Bad Debt | Finished prematurely | Late 16-30 | Late 31-60 | Late 60+ | <NA> |
---|---|---|---|---|---|---|---|---|---|
2015 | NA | NA | 6’968 | NA | 3’621 | NA | NA | NA | NA |
2016 | NA | 7 | 97’935 | 3 | 202’950 | NA | NA | 1 | NA |
2017 | 1 | 22 | 139’526 | 15 | 1’037’320 | NA | NA | 285 | NA |
2018 | 174 | 22 | 433’766 | 30 | 3’366’739 | NA | NA | 581 | 5 |
2019 | 52 | 9 | 341’630 | 8 | 3’150’406 | 1 | 33’892 | 35 | 6 |
Let’s define default as loans that have not repaid at least 95% and are already past at least 60 days after their closing date.
data %>%
filter(Currency == "EUR",
`Closing Date` < (Sys.Date() - days(60))) %>%
# sample_n(1) %>% glimpse()
mutate(Lost95 = (`Remaining Loan Amount`/`Initial Loan Amount`)>=0.05) %>%
group_by(ClYr = year(`Closing Date`)) %>%
summarise(Count = n(), CountLoss = sum(Lost95),
Amount = sum(`Initial Loan Amount`),
AmountLost = sum(`Remaining Loan Amount`)) %>%
mutate(lostPerc = (AmountLost/Amount)*100,
lossPercCount = (CountLoss/Count)*100) %>%
ungroup() %>%
mutate(ClYr = as.character(ClYr)) %>%
knitr::kable(format = "html", format.args = list(big.mark = "'"), digits = 2) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed")) %>%
row_spec(0, bold = T)
ClYr | Count | CountLoss | Amount | AmountLost | lostPerc | lossPercCount |
---|---|---|---|---|---|---|
2015 | 10’589 | 2 | 2’588’797 | 692.30 | 0.03 | 0.02 |
2016 | 300’896 | 12 | 60’779’178 | 45’057.93 | 0.07 | 0.00 |
2017 | 1’086’214 | 296 | 198’827’294 | 237’980.96 | 0.12 | 0.03 |
2018 | 3’482’709 | 599 | 768’336’118 | 317’565.96 | 0.04 | 0.02 |
2019 | 3’321’869 | 26’311 | 679’377’978 | 3’894’735.41 | 0.57 | 0.79 |
By originator (2019):
data %>%
filter(Currency == "EUR",
`Closing Date` < (Sys.Date() - days(60)),
year(`Closing Date`) == 2019) %>%
# sample_n(1) %>% glimpse()
mutate(Lost95 = (`Remaining Loan Amount`/`Initial Loan Amount`)>=0.05) %>%
group_by(`Loan Originator`) %>%
summarise(Count = n(), CountLoss = sum(Lost95),
Amount = sum(`Initial Loan Amount`),
AmountLost = sum(`Remaining Loan Amount`)) %>%
mutate(lostPerc = (AmountLost/Amount)*100,
lossPercCount = (CountLoss/Count)*100) %>%
ungroup() %>%
# mutate(ClYr = as.character(ClYr)) %>%
knitr::kable(format = "html", format.args = list(big.mark = "'"), digits = 2) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed")) %>%
row_spec(0, bold = T)
Loan Originator | Count | CountLoss | Amount | AmountLost | lostPerc | lossPercCount |
---|---|---|---|---|---|---|
Aasa | 1’650 | 0 | 1’292’636.93 | 0.30 | 0.00 | 0.00 |
Aforti | 115 | 0 | 2’132’483.51 | 130.03 | 0.01 | 0.00 |
Akulaku | 72’812 | 53 | 4’738’875.70 | 3’637.95 | 0.08 | 0.07 |
Alfakredyt | 4’542 | 20 | 2’598’914.57 | 14’043.87 | 0.54 | 0.44 |
Banknote | 89’906 | 428 | 20’011’769.29 | 41’411.24 | 0.21 | 0.48 |
BB Finance Group | 8’134 | 4 | 2’241’850.00 | 392.86 | 0.02 | 0.05 |
Bino | 133’369 | 319 | 41’433’267.24 | 93’066.72 | 0.22 | 0.24 |
Capitalia | 378 | 7 | 3’262’270.34 | 20’666.21 | 0.63 | 1.85 |
Capital Service | 7’747 | 4 | 3’450’530.31 | 240.20 | 0.01 | 0.05 |
CashCredit | 7’045 | 3 | 2’533’764.41 | 201.92 | 0.01 | 0.04 |
Cashwagon | 165’398 | 3’338 | 15’819’175.90 | 303’436.42 | 1.92 | 2.02 |
Creamfinance | 7’835 | 6 | 4’879’834.66 | 3’459.62 | 0.07 | 0.08 |
Credissimo | 1’681 | 3 | 602’599.57 | 148.04 | 0.02 | 0.18 |
Creditstar | 28’300 | 107 | 12’171’291.06 | 38’236.58 | 0.31 | 0.38 |
Credius | 1’288 | 36 | 687’961.46 | 2’343.08 | 0.34 | 2.80 |
Debifo | 316 | 6 | 2’219’242.00 | 10’613.18 | 0.48 | 1.90 |
Dindin | 73 | 0 | 26’218.39 | 0.00 | 0.00 | 0.00 |
Dineo Credito | 5’913 | 122 | 1’620’380.00 | 36’440.00 | 2.25 | 2.06 |
Dinero | 405’664 | 2’430 | 52’225’033.01 | 362’876.16 | 0.69 | 0.60 |
Dozarplati | 136’898 | 1’751 | 9’710’667.78 | 121’620.83 | 1.25 | 1.28 |
EBV Finance | 25’018 | 0 | 30’985’218.45 | 0.00 | 0.00 | 0.00 |
EcoFinance | 15’830 | 62 | 2’732’277.12 | 13’655.76 | 0.50 | 0.39 |
ExpressCredit | 112 | 0 | 53’686.02 | 0.00 | 0.00 | 0.00 |
ExpressCredit Zambia | 44’327 | 960 | 8’386’069.35 | 176’887.72 | 2.11 | 2.17 |
Extra Finance | 4 | 0 | 71’238.91 | 0.02 | 0.00 | 0.00 |
Fireof | 3 | 0 | 100’200.00 | 0.00 | 0.00 | 0.00 |
Getbucks | 1’182 | 0 | 352’503.04 | 4.07 | 0.00 | 0.00 |
GetBucks | 12’489 | 65 | 3’504’240.46 | 11’295.42 | 0.32 | 0.52 |
Hipocredit | 27 | 0 | 321’483.57 | 0.00 | 0.00 | 0.00 |
ID Finance | 76’792 | 967 | 30’581’409.20 | 242’181.27 | 0.79 | 1.26 |
ITF Group | 7’810 | 45 | 1’818’455.20 | 7’322.22 | 0.40 | 0.58 |
IuteCredit | 20’390 | 10 | 5’645’257.36 | 747.10 | 0.01 | 0.05 |
Kredit24 | 2’864 | 31 | 450’171.92 | 7’400.38 | 1.64 | 1.08 |
Kredito garantas | 1 | 0 | 2’260.38 | 0.00 | 0.00 | 0.00 |
Kredit Pintar | 12’431 | 1’029 | 780’792.30 | 57’065.39 | 7.31 | 8.28 |
Kredo | 54’568 | 149 | 6’802’618.19 | 20’041.26 | 0.29 | 0.27 |
Kuki | 113’187 | 1’836 | 49’198’282.86 | 821’745.25 | 1.67 | 1.62 |
Kviku | 84’842 | 11 | 1’561’973.96 | 138.24 | 0.01 | 0.01 |
Leaselink | 137 | 0 | 230’353.62 | 0.00 | 0.00 | 0.00 |
Lendo | 250’963 | 235 | 42’113’626.90 | 34’503.31 | 0.08 | 0.09 |
LF TECH | 6’936 | 0 | 853’001.40 | 0.00 | 0.00 | 0.00 |
Lime Zaim | 55’125 | 2’042 | 6’334’809.48 | 106’073.85 | 1.67 | 3.70 |
Metrokredit | 217’556 | 2’155 | 25’942’811.35 | 283’811.29 | 1.09 | 0.99 |
Mogo | 15’522 | 19 | 27’126’223.54 | 16’735.71 | 0.06 | 0.12 |
Monego | 18’125 | 122 | 2’415’047.23 | 18’853.85 | 0.78 | 0.67 |
Moneyman | 1’900 | 286 | 444’411.70 | 63’226.81 | 14.23 | 15.05 |
Mozipo Group | 5’628 | 0 | 2’614’658.14 | 0.06 | 0.00 | 0.00 |
Peachy | 12’137 | 47 | 3’295’439.67 | 6’437.90 | 0.20 | 0.39 |
Placet | 2’404 | 0 | 1’064’337.16 | 0.00 | 0.00 | 0.00 |
Rapicredit | 29’640 | 982 | 1’988’400.00 | 66’175.88 | 3.33 | 3.31 |
Rapido Finance | 19’506 | 213 | 9’561’971.63 | 102’959.75 | 1.08 | 1.09 |
Sebo | 128’940 | 240 | 19’429’508.58 | 31’502.65 | 0.16 | 0.19 |
Simbo | 68’636 | 9 | 40’494’950.06 | 5’180.22 | 0.01 | 0.01 |
Tengo | 332’512 | 4’928 | 38’997’671.69 | 440’220.38 | 1.13 | 1.48 |
Tigo | 32’436 | 104 | 4’494’373.66 | 12’308.61 | 0.27 | 0.32 |
Varks | 570’299 | 1’124 | 123’484’185.92 | 295’080.11 | 0.24 | 0.20 |
VIZIA | 1’480 | 3 | 620’589.00 | 175.99 | 0.03 | 0.20 |
Watu Credit | 1’046 | 0 | 864’702.35 | 39.73 | 0.00 | 0.00 |
By country (2019):
data %>%
filter(Currency == "EUR",
`Closing Date` < (Sys.Date() - days(60)),
year(`Closing Date`) == 2019) %>%
# sample_n(1) %>% glimpse()
mutate(Lost95 = (`Remaining Loan Amount`/`Initial Loan Amount`)>=0.05) %>%
group_by(Country) %>%
summarise(Count = n(), CountLoss = sum(Lost95),
Amount = sum(`Initial Loan Amount`),
AmountLost = sum(`Remaining Loan Amount`)) %>%
mutate(lostPerc = (AmountLost/Amount)*100,
lossPercCount = (CountLoss/Count)*100) %>%
ungroup() %>%
# mutate(ClYr = as.character(ClYr)) %>%
knitr::kable(format = "html", format.args = list(big.mark = "'"), digits = 2) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed")) %>%
row_spec(0, bold = T)
Country | Count | CountLoss | Amount | AmountLost | lostPerc | lossPercCount |
---|---|---|---|---|---|---|
Albania | 67’362 | 152 | 10’763’618.04 | 20’352.39 | 0.19 | 0.23 |
Armenia | 570’299 | 1’124 | 123’484’185.92 | 295’080.11 | 0.24 | 0.20 |
Botswana | 7’363 | 48 | 1’502’845.05 | 7’706.55 | 0.51 | 0.65 |
Bulgaria | 16’868 | 51 | 5’852’580.61 | 7’708.58 | 0.13 | 0.30 |
Colombia | 29’640 | 982 | 1’988’400.00 | 66’175.88 | 3.33 | 3.31 |
Denmark | 74’947 | 15 | 43’975’252.41 | 8’634.54 | 0.02 | 0.02 |
Estonia | 1’941 | 9 | 6’813’949.87 | 12’194.65 | 0.18 | 0.46 |
Finland | 10’173 | 5 | 5’185’580.73 | 2’230.58 | 0.04 | 0.05 |
Georgia | 262’754 | 235 | 50’357’533.98 | 34’508.61 | 0.07 | 0.09 |
Indonesia | 135’442 | 2’445 | 10’245’255.18 | 175’278.09 | 1.71 | 1.81 |
Kazakhstan | 343’278 | 4’959 | 40’931’399.01 | 447’620.76 | 1.09 | 1.44 |
Kenya | 2’628 | 14 | 1’328’825.08 | 3’354.99 | 0.25 | 0.53 |
Kosovo | 19’629 | 128 | 2’677’680.73 | 19’253.85 | 0.72 | 0.65 |
Latvia | 233’075 | 759 | 74’484’436.85 | 149’356.40 | 0.20 | 0.33 |
Lithuania | 34’513 | 14 | 44’142’228.80 | 21’081.66 | 0.05 | 0.04 |
Mexico | 1’900 | 286 | 444’411.70 | 63’226.81 | 14.23 | 15.05 |
Moldova | 134’663 | 241 | 20’910’295.57 | 31’538.57 | 0.15 | 0.18 |
North Macedonia | 32’845 | 104 | 4’553’558.14 | 12’308.66 | 0.27 | 0.32 |
Philippines | 115’199 | 1’975 | 11’093’588.72 | 188’861.67 | 1.70 | 1.71 |
Poland | 140’699 | 1’905 | 63’745’326.96 | 852’222.26 | 1.34 | 1.35 |
Romania | 2’479 | 36 | 1’426’945.63 | 2’343.10 | 0.16 | 1.45 |
Russian Federation | 510’251 | 6’021 | 46’282’539.69 | 525’299.97 | 1.13 | 1.18 |
South Africa | 820 | 0 | 133’764.12 | 4.07 | 0.00 | 0.00 |
Spain | 107’090 | 1’363 | 41’363’182.79 | 401’917.27 | 0.97 | 1.27 |
Sweden | 2 | 0 | 4’688.99 | 0.00 | 0.00 | 0.00 |
Ukraine | 405’664 | 2’430 | 52’225’033.01 | 362’876.16 | 0.69 | 0.60 |
United Kingdom | 12’137 | 47 | 3’295’439.67 | 6’437.90 | 0.20 | 0.39 |
Zambia | 48’208 | 963 | 10’165’430.26 | 177’161.33 | 1.74 | 2.00 |
data %>%
filter(Currency != "EUR",
`Closing Date` < (Sys.Date() - days(60))) %>%
# sample_n(1) %>% glimpse()
mutate(Lost95 = (`Remaining Loan Amount`/`Initial Loan Amount`)>=0.05) %>%
group_by(ClYr = year(`Closing Date`)) %>%
summarise(Count = n(), CountLoss = sum(Lost95),
Amount = sum(`Initial Loan Amount`),
AmountLost = sum(`Remaining Loan Amount`)) %>%
mutate(lostPerc = (AmountLost/Amount)*100,
lossPercCount = (CountLoss/Count)*100) %>%
ungroup() %>%
mutate(ClYr = as.character(ClYr)) %>%
knitr::kable(format = "html", format.args = list(big.mark = "'"), digits = 2) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed")) %>%
row_spec(0, bold = T)
ClYr | Count | CountLoss | Amount | AmountLost | lostPerc | lossPercCount |
---|---|---|---|---|---|---|
2017 | 90’955 | 0 | 76’672’462 | 12.32 | 0.00 | 0.00 |
2018 | 318’608 | 1 | 2’265’239’076 | 722.37 | 0.00 | 0.00 |
2019 | 204’170 | 2’097 | 3’706’148’038 | 34’409’861.17 | 0.93 | 1.03 |
Seems like here we have slightly higher defaults in 2019. Let’s examine:
data %>%
filter(Currency != "EUR",
`Closing Date` < (Sys.Date() - days(60)),
year(`Closing Date`) == 2019) %>%
# sample_n(1) %>% glimpse()
mutate(Lost95 = (`Remaining Loan Amount`/`Initial Loan Amount`)>=0.05) %>%
group_by(Currency) %>%
summarise(Count = n(), CountLoss = sum(Lost95),
Amount = sum(`Initial Loan Amount`),
AmountLost = sum(`Remaining Loan Amount`)) %>%
mutate(lostPerc = (AmountLost/Amount)*100,
lossPercCount = (CountLoss/Count)*100) %>%
ungroup() %>%
# mutate(ClYr = as.character(ClYr)) %>%
knitr::kable(format = "html", format.args = list(big.mark = "'"), digits = 2) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed")) %>%
row_spec(0, bold = T)
Currency | Count | CountLoss | Amount | AmountLost | lostPerc | lossPercCount |
---|---|---|---|---|---|---|
CZK | 7’591 | 49 | 45’811’562.0 | 380’173.18 | 0.83 | 0.65 |
DKK | 2’336 | 0 | 10’418’500.0 | 0.00 | 0.00 | 0.00 |
GBP | 121 | 0 | 263’361.5 | 0.00 | 0.00 | 0.00 |
GEL | 8’662 | 1 | 7’132’936.5 | 202.62 | 0.00 | 0.01 |
KZT | 51’641 | 585 | 2’918’810’929.6 | 28’369’426.07 | 0.97 | 1.13 |
MXN | 1’623 | 107 | 7’138’687.7 | 473’155.37 | 6.63 | 6.59 |
PLN | 42’857 | 772 | 81’332’022.2 | 1’570’436.01 | 1.93 | 1.80 |
RUB | 89’277 | 583 | 635’204’316.1 | 3’616’467.92 | 0.57 | 0.65 |
USD | 62 | 0 | 35’722.5 | 0.00 | 0.00 | 0.00 |
data %>%
filter(Currency != "EUR",
`Closing Date` < (Sys.Date() - days(60)),
year(`Closing Date`) == 2019) %>%
# sample_n(1) %>% glimpse()
mutate(Lost95 = (`Remaining Loan Amount`/`Initial Loan Amount`)>=0.05) %>%
group_by(`Loan Originator`, Currency) %>%
summarise(Count = n(), CountLoss = sum(Lost95),
Amount = sum(`Initial Loan Amount`),
AmountLost = sum(`Remaining Loan Amount`)) %>%
mutate(lostPerc = (AmountLost/Amount)*100,
lossPercCount = (CountLoss/Count)*100) %>%
ungroup() %>%
# mutate(ClYr = as.character(ClYr)) %>%
knitr::kable(format = "html", format.args = list(big.mark = "'"), digits = 2) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed")) %>%
row_spec(0, bold = T)
Loan Originator | Currency | Count | CountLoss | Amount | AmountLost | lostPerc | lossPercCount |
---|---|---|---|---|---|---|---|
1pm | GBP | 5 | 0 | 1.758450e+05 | 0.00 | 0.00 | 0.00 |
Aasa | PLN | 151 | 0 | 5.489000e+05 | 1.89 | 0.00 | 0.00 |
Aforti | PLN | 34 | 0 | 1.125233e+06 | 0.00 | 0.00 | 0.00 |
Alfakredyt | PLN | 2’396 | 13 | 4.632150e+06 | 26’500.00 | 0.57 | 0.54 |
BIG | GEL | 387 | 0 | 8.625554e+05 | 0.00 | 0.00 | 0.00 |
Capital Service | PLN | 1’395 | 11 | 2.269750e+06 | 6’033.35 | 0.27 | 0.79 |
Creamfinance | CZK | 5’161 | 18 | 2.782831e+07 | 178’404.43 | 0.64 | 0.35 |
Creamfinance | GEL | 648 | 1 | 8.012000e+05 | 197.58 | 0.02 | 0.15 |
Credilikeme | MXN | 313 | 1 | 1.396688e+06 | 6’192.71 | 0.44 | 0.32 |
Creditstar | CZK | 2’430 | 31 | 1.798325e+07 | 201’768.75 | 1.12 | 1.28 |
Creditstar | PLN | 3’080 | 26 | 5.318030e+06 | 46’189.64 | 0.87 | 0.84 |
Dozarplati | RUB | 46’881 | 492 | 2.504827e+08 | 2’365’967.92 | 0.94 | 1.05 |
EcoFinance | RUB | 20’309 | 91 | 2.451075e+08 | 1’250’500.00 | 0.51 | 0.45 |
Efaktor | PLN | 46 | 1 | 5.594339e+05 | 3’585.46 | 0.64 | 2.17 |
GetBucks | USD | 62 | 0 | 3.572250e+04 | 0.00 | 0.00 | 0.00 |
ID Finance | GEL | 1’991 | 0 | 3.391050e+06 | 0.00 | 0.00 | 0.00 |
ID Finance | KZT | 220 | 0 | 6.121542e+07 | 0.00 | 0.00 | 0.00 |
Kredit24 | KZT | 21’167 | 124 | 1.259374e+09 | 8’737’684.18 | 0.69 | 0.59 |
Kuki | PLN | 35’653 | 721 | 6.613712e+07 | 1’488’125.67 | 2.25 | 2.02 |
Kviku | RUB | 20’879 | 0 | 9.494811e+07 | 0.00 | 0.00 | 0.00 |
Leaselink | PLN | 67 | 0 | 4.747804e+05 | 0.00 | 0.00 | 0.00 |
Lendo | GEL | 5’507 | 0 | 1.759044e+06 | 5.04 | 0.00 | 0.00 |
LF TECH | KZT | 8’673 | 0 | 4.675385e+08 | 0.00 | 0.00 | 0.00 |
Metrokredit | RUB | 1’134 | 0 | 8.416375e+06 | 0.00 | 0.00 | 0.00 |
Mikro Kapital | RUB | 1 | 0 | 5.000000e+05 | 0.00 | 0.00 | 0.00 |
Mogo | GBP | 116 | 0 | 8.751649e+04 | 0.00 | 0.00 | 0.00 |
Mogo | GEL | 129 | 0 | 3.190874e+05 | 0.00 | 0.00 | 0.00 |
Mogo | PLN | 35 | 0 | 2.666257e+05 | 0.00 | 0.00 | 0.00 |
Moneyman | MXN | 1’310 | 106 | 5.742000e+06 | 466’962.66 | 8.13 | 8.09 |
PimPay | RUB | 73 | 0 | 3.574958e+07 | 0.00 | 0.00 | 0.00 |
Simbo | DKK | 2’336 | 0 | 1.041850e+07 | 0.00 | 0.00 | 0.00 |
Tengo | KZT | 21’581 | 461 | 1.130683e+09 | 19’631’741.89 | 1.74 | 2.14 |