top of page
Gambar penulisCornellius Yudha Wijaya

Corporate Credit Risk Modelling dengan Python dan Financial Modeling Prep

Diperbarui: 16 Jul

Corporate Credit Risk Modelling dengan Python dan Financial Modeling Prep

Di bidang keuangan, analisis kredit telah menjadi aktivitas penting. Pemberi pinjaman dapat menghindari peminjam dengan risiko kredit yang buruk dan memperoleh keuntungan dengan melakukan analisis tersebut.


Salah satu spesifikasi analisis kredit adalah corporate credit analysis. Ini bisa didefinisikan sebagai proses untuk menilai kelayakan kredit dari peminjam korporat. Tidak seperti peminjam individu, analisis korporat biasanya menekankan pada arus kas bisnis (business cash flow) dan kemampuan korporat untuk memenuhi perjanjian pinjaman.


Analis kredit dapat menggunakan berbagai teknik untuk menilai risiko kredit bisnis berdasarkan informasi keuangan bisnis, baik kuantitatif maupun kualitatif. Salah satunya dengan melihat pola data dan mengelompokkannya.


Artikel ini akan mengajarkan kita bagaimana mengembangkan analisis unsupervised machine learning pada data bisnis. Kita akan mengumpulkan data yang relevan melalui Financial Modelling Prep API dan membuat model untuk mengelompokkannya.

Mari kita bahas.



Pengumpulan Data Pasar Keuangan Korporat

Corporate risk analysis memerlukan informasi berbeda untuk menilai risiko kredit dibandingkan dengan analisis risiko kredit individu. Beberapa informasi yang bisa digunakan, seperti Financial Statements, operational metrics, atau macroeconomic indicators.


Artikel ini akan menggunakan data Financial Statements untuk menilai tingkat risiko kredit perusahaan. Untuk mendapatkan data tersebut, saya akan menggunakan Financial Modeling Prep gratis. API ini memiliki akses ke berbagai data keuangan untuk mendapatkan data keuangan lengkap, termasuk Company Financial Statements. Anda dapat melihat semua data yang dapat Anda peroleh dalam dokumentasinya.

Corporate Credit Risk Modelling dengan Python dan Financial Modeling Prep

Dashboard-nya memungkinkan Anda melihat API mana yang sesuai untuk kasus tertentu. Pada contoh ini, kita akan mengambil data Financial statement perusahaan, yang mencakup Income Statement, Balance Sheet Statement, dan Cashflow Statement.


Sebagai contoh, saya akan menggunakan perusahaan yang terdaftar di NASDAQ sebagai sampel. Selain itu, saya akan mengambil sampel secara acak sebanyak 50 perusahaan karena kita hanya memerlukan sejumlah kecil data.


Saya akan menggunakan kode berikut untuk mendapatkan data simbol NASDAQ untuk analisis lebih lanjut.

import pandas as pd
import numpy as np
import requests

api_key = 'YOUR FINANCIAL MODELLING API KEY'
url = "https://financialmodelingprep.com/api/v3/symbol/NASDAQ"
headers = {
    'apikey': api_key
}

response = requests.get(url, params=headers) 
    
data = response.json()
data = pd.DataFrame(data)

symbol_nasdaq = data['symbol'].sample(50, random_state = 42)
all_symbols = list(symbol_nasdaq.values)

Hasilnya adalah 50 perusahaan berbeda yang terdaftar dengan simbol NASDAQ.


Selanjutnya, kita akan melakukan pengulangan untuk mendapatkan annual financial statements dari perusahaan-perusahaan ini.


  • Income Statement

income_statement = pd.DataFrame([])
for comp in all_symbols:
    url = f"https://financialmodelingprep.com/api/v3/income-statement/{comp}?period=annual"
    headers = {
        'apikey': api_key,
    }
    
    response = requests.get(url, params=headers) 
        
    inc = response.json()
    inc = pd.DataFrame(inc)
    income_statement = pd.concat([income_statement, inc])
  • Balance Sheet Statement

balance_sheet = pd.DataFrame([])
for comp in all_symbols:
    url = f"https://financialmodelingprep.com/api/v3/balance-sheet-statement/{comp}?period=annual"
    headers = {
        'apikey': api_key,
    }
    
    response = requests.get(url, params=headers) 
        
    bsh = response.json()
    bsh = pd.DataFrame(bsh)
    balance_sheet = pd.concat([balance_sheet, bsh])
  • Cashflow Statement

cash_flow = pd.DataFrame([])
for comp in all_symbols:
    url = f"https://financialmodelingprep.com/api/v3/cash-flow-statement/{comp}?period=annual"
    headers = {
        'apikey': api_key,
    }
    
    response = requests.get(url, params=headers) 
        
    csf = response.json()
    csf = pd.DataFrame(csf)
    cash_flow = pd.concat([cash_flow, csf])

Dari data di atas, kita akan menggabungkannya dan membuat fitur baru.

financial_data = pd.merge(pd.merge(income_statement, balance_sheet, on = ['calendarYear', 'symbol'], suffixes = ('_inc', '_bsh')), cash_flow, on = ['calendarYear', 'symbol'], suffixes = ('_incbsh', '_csf'))

Kita dapat menggunakan data keuangan sebagai indikator untuk memahami kesehatan perusahaan. Berikut adalah beberapa fitur yang akan kita gunakan sebagai indikator tersebut.


Current Ratio: Current Ratio dihitung sebagai perbandingan aset lancar dibagi dengan kewajiban lancar. Current Ration digunakan untuk mengukur kemampuan perusahaan untuk membayar kewajiban jangka pendek dengan aset yang dimilikinya. Rasio di atas 1 umumnya lebih disukai, tetapi rasio terlalu tinggi dapat menunjukkan perusahaan kurang efisien dalam mengelola asetnya.


Debt to Equity Ratio: Rasio keuangan ini dihitung sebagai perbandingan total kewajiban dibagi dengan ekuitas pemegang saham. Debt-to-equity ratio yang lebih rendah berarti perusahaan tidak terlalu bergantung pada peminjam untuk membiayai operasinya.


Gross Profit Margin: Gross profit margin dihitung sebagai laba kotor dibagi dengan pendapatan. Kita lebih suka rasio gross profit margin yang tinggi karena ini menunjukkan efisiensi dalam mengelola penjualan.


Operating Margin: Rasio ini dihitung sebagai pendapatan operasional dibagi dengan penjualan bersih, mengukur proporsi pendapatan perusahaan yang tersisa setelah membayar operasional. Kita lebih suka rasio yang tinggi karena ini menunjukkan bahwa perusahaan menghasilkan lebih banyak keuntungan per penjualan dan menunjukkan efisiensi operasional.


Return on Assets (ROA): ROA adalah pendapatan bersih dibagi dengan total aset. Kita lebih suka ROA yang tinggi karena ini menunjukkan seberapa efektif manajemen perusahaan menggunakan asetnya untuk menghasilkan pendapatan.


Operating Cash Flow to Sales Ratio: Rasio ini adalah kas bersih yang disediakan oleh aktivitas operasi dibagi dengan penjualan. Kita menginginkan rasio yang lebih tinggi karena ini menunjukkan bahwa perusahaan bagus dalam mengubah penjualan menjadi kas dan memiliki operasi yang kuat.


Free Cash Flow to Net Income Ratio: Menghitung free cash flow dengan pendapatan bersih. Rasio di atas 1 menunjukkan perusahaan mampu menghasilkan lebih banyak kas daripada yang dilaporkan sebagai pendapatan bersih.


Debt Coverage Ratio: Rasio ini mengukur free cash flow relatif terhadap total utang, menunjukkan kemampuan perusahaan untuk menutupi utangnya dengan aliran kas yang dihasilkan. Rasio yang lebih tinggi lebih disukai.


Data di atas merupakan sampel kecil dari indikator dan penjelasan umumnya.


Saya akan sedikit mengubah data kita saat ini untuk mendapatkan semua data di atas. Khususnya untuk menghindari missing data dan hasil yang tak terhingga, saya akan menambahkan nilai 1 ke kolom numerik.

financial_data[financial_data.select_dtypes('number').columns] = financial_data.select_dtypes('number') + 1

Kemudian, kita bisa menggunakan kode berikut untuk mendapatkan rasio data:

financial_data['current_ratio'] = financial_data["totalCurrentAssets"] / financial_data["totalCurrentLiabilities"]
financial_data['debt_to_equity_ratio'] = financial_data["totalLiabilities"] / financial_data["totalStockholdersEquity"]
financial_data['gross_profit_margin'] = financial_data["grossProfit"] / financial_data["revenue"]
financial_data['operating_margin'] = financial_data["operatingIncome"] / financial_data["revenue"]
financial_data['return_on_assets'] = financial_data["netIncome_csf"] / financial_data["totalAssets"]
financial_data['operating_cash_flow_to_sales_ratio'] = financial_data['netCashUsedProvidedByFinancingActivities'] / financial_data["revenue"]
financial_data['free_cash_flow_to_net_income_ratio'] = financial_data['freeCashFlow'] / financial_data["netIncome_csf"]
financial_data['debt_coverage_ratio'] = financial_data['freeCashFlow'] / financial_data['totalDebt']

Sekarang datanya telah siap digunakan. Jika Anda ingin melihat seperti apa data tersebut dari waktu ke waktu untuk perusahaan tertentu, Anda bisa menggunakan kode berikut. Contoh di bawah ini akan menggunakan contoh WETF (WisdomTree Inc.).

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

financial_cols = ['calendarYear', 'current_ratio', 'debt_to_equity_ratio', 'gross_profit_margin','operating_margin' , 'return_on_assets', 'operating_cash_flow_to_sales_ratio',
                 'free_cash_flow_to_net_income_ratio', 'debt_coverage_ratio']

data = financial_data[financial_data['symbol'] == 'WETF'][financial_cols]
df_long = pd.melt(data, id_vars=['calendarYear'], var_name='Metric', value_name='Value')

df_long['calendarYear'] = pd.to_datetime(df_long['calendarYear'])


plt.figure(figsize=(10, 6))
sns.lineplot(data=df_long, x='calendarYear', y='Value', hue='Metric', marker='o')

plt.title('Financial Ratios of company WETF Over Time', fontsize=16)
plt.xlabel('Date', fontsize=14)
plt.ylabel('Ratio Value', fontsize=14)
plt.xticks(rotation=45, fontsize=12)  # Rotate the x-axis labels for readability
plt.yticks(fontsize=12)

plt.legend(title='Financial Metric', fontsize=12, title_fontsize='13', loc='upper left', bbox_to_anchor=(1, 1))

plt.tight_layout()
plt.show()
Corporate Credit Risk Modelling dengan Python dan Financial Modeling Prep

Hasilnya adalah tampilan tahunan dari indikator kesehatan keuangan perusahaan.


Selanjutnya, mari kita mulai mencoba proses segmentasi.




Financial Data Credit Risk Modelling

Kita akan melakukan unsupervised analysis pada data di atas dan mengelompokkannya untuk memahami perusahaan mana yang mungkin memiliki risiko lebih tinggi dibandingkan yang lain.

Segmentasi dengan Data dari Tahun 2022

Pada contoh pertama, kita akan menggunakan data dari tahun 2022 saja. Kita akan belajar bagaimana segmentasi bekerja dengan hanya menggunakan informasi terbaru. Untuk proses segmentasi, kita akan menggunakan algoritma K-Means. Kita juga akan menormalisasi data untuk memastikan mereka berada dalam unit yang sama.


Saya juga akan menggunakan paket Yellowbricks untuk menemukan K-kluster terbaik.

pip install yellowbricks

Keseluruhan kode dapat dilihat di bawah ini.

from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
from yellowbrick.cluster import KElbowVisualizer

ratio_cols = ['current_ratio', 'debt_to_equity_ratio', 'gross_profit_margin','operating_margin' , 'return_on_assets', 'operating_cash_flow_to_sales_ratio',
                 'free_cash_flow_to_net_income_ratio', 'debt_coverage_ratio']

X = financial_data[financial_data['calendarYear'] == '2023'][ratio_cols]

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

model = KMeans(random_state=42)
visualizer = KElbowVisualizer(model, k=(2,10), timings=False)

visualizer.fit(X_scaled)
visualizer.show(
Corporate Credit Risk Modelling dengan Python dan Financial Modeling Prep

Dengan menggunakan K-Means, hasilnya menunjukkan bahwa jumlah K terbaik untuk segmentasi data kita adalah 5. Mari kita terapkan nilai ini ke data asli kita dan menilai statistik segmentasinya.

kmeans = KMeans(n_clusters=5, random_state=42)
X_2022['Cluster'] = kmeans.fit_predict(X_scaled)

X_2022['Cluster'].value_counts()
Corporate Credit Risk Modelling dengan Python dan Financial Modeling Prep

Hasil segmentasinya menunjukkan 5 segmen berbeda, tetapi dua kluster hanya memiliki 1 representasi. Ini berarti satu perusahaan mewakili seluruh kluster.


Mari kita ambil rata-rata statistik dan ranking berdasarkan rata-rata. Ini adalah pendekatan sederhana karena setiap fitur indikator keuangan yang kita gunakan lebih baik jika memiliki nilai yang lebih tinggi. Ada pengecualian, seperti current ratio, yang mungkin tidak baik jika terlalu tinggi, tetapi mari kita anggap itu tidak terjadi sekarang.

ratio_cols.append('Cluster')

# Calculate mean values for each cluster
cluster_means = X_2022[ratio_cols].groupby('Cluster').mean()
Corporate Credit Risk Modelling dengan Python dan Financial Modeling Prep

Dengan data rata-rata, mari kita ranking mereka.

ratio_cols = ['current_ratio', 'debt_to_equity_ratio', 'gross_profit_margin','operating_margin' , 'return_on_assets', 'operating_cash_flow_to_sales_ratio',
                 'free_cash_flow_to_net_income_ratio', 'debt_coverage_ratio']
for i in ratio_cols:
    # Lower score is better
    if i == 'debt_to_equity_ratio':
        cluster_means[f'{i}_rank'] = cluster_means[i].rank(method='average', ascending=True)
    else:
        #Higher score is better
        cluster_means[f'{i}_rank'] = cluster_means[i].rank(method='average', ascending=False)

Bagian intuitif dari ranking dalam segmentasi ini adalah menemukan kluster mana yang memiliki risiko kredit lebih tinggi. Semakin rendah ranking-nya, semakin baik indikator keuangan mereka. Jika kita mengambil rata-rata dari semua peringkat, kita bisa melihat kluster mana yang memiliki kesehatan keuangan lebih baik dibandingkan yang lain.

cluster_means[ratio_rank_cols].mean(axis = 1).sort_values()
Corporate Credit Risk Modelling dengan Python dan Financial Modeling Prep

Seperti yang bisa kita lihat pada hasil di atas, kluster 2 menunjukkan risiko kredit terendah sementara kluster 3 melakukan yang terburuk. Dengan model segmentasi ini, kita bisa menerapkan model ke data yang belum terlihat, atau Anda bisa meningkatkan model dengan menambahkan lebih banyak sampel.


Segmentasi dengan Rata-rata Tahunan

Kita telah menggunakan dataset dari tahun tertentu. Karena Financial Modeling Prep menyediakan laporan tahunan perusahaan, kita bisa menggunakan indikator keuangan rata-rata untuk mendapatkan informasi keseluruhan dari waktu ke waktu.


Mari kita dapatkan data indikator keuangan rata-rata untuk setiap perusahaan.

ratio_cols = ['symbol','current_ratio', 'debt_to_equity_ratio', 'gross_profit_margin','operating_margin' , 'return_on_assets', 'operating_cash_flow_to_sales_ratio',
                 'free_cash_flow_to_net_income_ratio', 'debt_coverage_ratio']

annual_means = financial_data[ratio_cols].groupby('symbol').mean()

Kita akan menemukan segmen terbaik menggunakan pendekatan yang sama seperti sebelumnya.

from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
from yellowbrick.cluster import KElbowVisualizer

scaler = StandardScaler()
X_scaled = scaler.fit_transform(annual_means)

model = KMeans(random_state=42)
visualizer = KElbowVisualizer(model, k=(2,10), timings=False)

visualizer.fit(X_scaled)
visualizer.show()
Corporate Credit Risk Modelling dengan Python dan Financial Modeling Prep

Kluster lima segmen masih menjadi yang terbaik. Mari kita bawa kluster ini ke data asli dan lihat hasil kluster.

kmeans = KMeans(n_clusters=5, random_state=42)
annual_means['Cluster'] = kmeans.fit_predict(X_scaled)
annual_means['Cluster'].value_counts()

Sebagian besar kluster terfokus pada kluster 1, dan kita memiliki tiga kluster berbeda yang hanya terdiri dari satu pengamatan. Kita mungkin memerlukan lebih banyak sampel untuk meningkatkan hasil, tetapi mari kita lanjutkan dengan data saat ini.


Selanjutnya, kita akan mencoba proses ranking seperti dataset sebelumnya. Pertama, kita akan mengambil rata-rata untuk setiap kluster.

ratio_cols = ['Cluster','current_ratio', 'debt_to_equity_ratio', 'gross_profit_margin','operating_margin' , 'return_on_assets', 'operating_cash_flow_to_sales_ratio',
                 'free_cash_flow_to_net_income_ratio', 'debt_coverage_ratio']
ann_cluster_means = annual_means[ratio_cols].groupby('Cluster').mean()
ann_cluster_means
Corporate Credit Risk Modelling dengan Python dan Financial Modeling Prep

Kemudian, kita akan meranking dan mengambil rata-rata dari ranking.

ratio_cols = ['current_ratio', 'debt_to_equity_ratio', 'gross_profit_margin','operating_margin' , 'return_on_assets', 'operating_cash_flow_to_sales_ratio',
                 'free_cash_flow_to_net_income_ratio', 'debt_coverage_ratio']
for i in ratio_cols:
    # Lower score is better
    if i == 'debt_to_equity_ratio':
       ann_cluster_means[f'{i}_rank'] = cluster_means[i].rank(method='average', ascending=True)
    else:
        #Higher score is better
        ann_cluster_means[f'{i}_rank'] = cluster_means[i].rank(method='average', ascending=False)

ann_cluster_means[ratio_rank_cols].mean(axis = 1).sort_values()
Corporate Credit Risk Modelling dengan Python dan Financial Modeling Prep

Setelah kita ranking, sebagian besar perusahaan mungkin memiliki risiko kredit lebih tinggi berdasarkan data rata-rata laporan tahunan. Tentu saja, sampelnya mungkin terlalu kecil, dan kita mungkin memerlukan pengukuran/algoritma kluster lain untuk hasil yang lebih baik.


Namun demikian, belajar memodelkan corporate credit risk menggunakan teknik unsupervised analysis akan menjadi yang terbaik.

Kesimpulan

Corporate Credit Risk analysis berbeda dengan analisis individu karena kita perlu mengukur kesehatan keuangan perusahaan. Dalam artikel ini, kita membuat pemodelan unsupervised analysis dengan data indikator keuangan dari Financial Modeling Prep.

Semoga bermanfaat!



29 tampilan0 komentar

Postingan Terkait

Lihat Semua

Komentarze


bottom of page