Posted in

Analisis Dekomposisi Time Series Harga Saham BBCA: Additive vs STL

Harga saham merupakan data time series yang bersifat dinamis, non-linier, dan dipengaruhi oleh berbagai faktor ekonomi maupun sentimen pasar. Dalam analisis time series, salah satu langkah penting sebelum pemodelan lanjutan adalah dekomposisi data untuk memahami struktur dasar yang membentuk pergerakan harga.

Pada artikel ini, dilakukan analisis dekomposisi harga penutupan saham BBCA periode 2015–2025 menggunakan dua pendekatan, yaitu Additive Decomposition klasik dan STL (Seasonal-Trend decomposition using LOESS). Tujuannya adalah membandingkan karakteristik hasil dekomposisi dan menentukan pendekatan yang lebih sesuai untuk data saham.

Apa itu Dekomposisi Time Series?

Dekomposisi time series memisahkan data menjadi tiga komponen utama:

  • Trend (T): arah pergerakan jangka panjang
  • Seasonal (S): pola berulang dalam periode tertentu
  • Residual/Error (R): fluktuasi acak yang tidak dapat dijelaskan

Secara umum, model additive dituliskan sebagai:

yt=Tt+St+Rtyₜ = Tₜ + Sₜ + Rₜ

Hasil Additive Decomposition

Komponen Trend

Hasil additive decomposition menunjukkan adanya tren naik jangka panjang pada saham BBCA. Namun, pola tren terlihat relatif kaku dan kurang adaptif terhadap perubahan ekstrem, terutama pada periode krisis tahun 2020.

Komponen Musiman

Komponen musiman pada model additive tampak statis dan berulang secara kaku, dengan amplitudo yang relatif konstan sepanjang waktu. Hal ini mengindikasikan bahwa model additive memaksakan adanya pola musiman, meskipun pada data saham pola tersebut tidak selalu nyata.

Komponen Residual

Residual dari additive decomposition menunjukkan variasi yang cukup besar dan mengandung banyak lonjakan ekstrem. Ini menandakan bahwa sebagian besar volatilitas pasar belum terakomodasi dengan baik oleh model.

Gambar-1 Hasil Dekomposisi dengan Metode Additive

Hasil STL Decomposition

Komponen Trend

Berbeda dengan additive, STL menghasilkan tren yang lebih halus dan adaptif. Perubahan rezim pasar seperti krisis COVID-19 dan fase pemulihan pasca-2020 dapat terlihat lebih jelas dan realistis.

Komponen Musiman

Komponen musiman pada STL bersifat dinamis, dengan amplitudo yang berubah mengikuti volatilitas pasar. Pada konteks saham, komponen ini lebih tepat dipahami sebagai fluktuasi jangka pendek daripada musiman kalender yang kaku.

Komponen Residual

Residual hasil STL memiliki variasi yang lebih terkendali dan lebih mendekati noise acak. Hal ini menunjukkan bahwa STL mampu mengekstraksi informasi sistematis dengan lebih baik dibanding additive decomposition.

Gambar-1 Hasil Dekomposisi dengan Metode STL

Perbandingan Additive vs STL

AspekAdditive DecompositionSTL Decomposition
Bentuk modelAdditive statisAdditive adaptif
Estimasi trenKurang halusHalus dan fleksibel
Pola musimanKaku dan konstanDinamis dan berubah
Sensitivitas terhadap outlierTinggiRendah (robust)
Respons terhadap shock pasarLemahBaik
Variansi residualBesarLebih kecil
Cocok untuk data sahamKurang sesuaiSangat sesuai
Kelayakan untuk risetTerbatasDirekomendasikan

Secara visual maupun konseptual, STL memberikan hasil yang lebih realistis untuk data keuangan yang volatil.

Kekuatan Tren dan Musiman

Untuk mengukur dominasi masing-masing komponen, digunakan pendekatan berbasis varians:

Trend Strength (TB) mengukur kontribusi tren terhadap variasi data

TB=1Var(Rt)Var(Tt+Rt)\boxed{ TB = 1 – \frac{\operatorname{Var}(R_t)}{\operatorname{Var}(T_t + R_t)} }

Seasonal Strength (SB) mengukur kontribusi komponen musiman

SB=1Var(Rt)Var(St+Rt)\boxed{ SB = 1 – \frac{\operatorname{Var}(R_t)}{\operatorname{Var}(S_t + R_t)} }
  • di mana: Var(Rt) adalah varians komponen residual
  • Var(Tt + Rt) adalah varians gabungan komponen tren dan residual
  • Var(St + Rt) adalah varians gabungan komponen sesional dan residual
AdditiveTSL
TB0.9974410.998064
SB0.0079330.308799

Hasil analisis menunjukkan bahwa TB jauh lebih besar dibanding SB, menandakan bahwa pergerakan harga saham BBCA lebih didominasi oleh tren jangka panjang dibandingkan pola musiman.


Implikasi untuk Machine Learning

Hasil dekomposisi ini memiliki implikasi penting untuk pemodelan lanjutan:

  • Trend STL sangat cocok dijadikan fitur utama untuk model RNN, LSTM, atau GRU
  • Komponen musiman STL dapat digunakan sebagai fitur tambahan
  • Residual sebaiknya tidak digunakan langsung karena bersifat noise

Kesimpulan

Dari analisis yang dilakukan, dapat disimpulkan bahwa:

  1. Additive decomposition kurang mampu merepresentasikan karakteristik data saham yang volatil.
  2. STL decomposition memberikan pemisahan komponen yang lebih adaptif dan robust.
  3. Harga saham BBCA periode 2015–2025 didominasi oleh tren jangka panjang, sementara musiman relatif lemah.
  4. STL merupakan pendekatan yang lebih tepat sebagai tahap pra-pemrosesan sebelum pemodelan machine learning.

Kode Python

Install Paket Statsmodels

pip install statsmodels –quiet

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sn
import matplotlib.ticker as mticker
from statsmodels.tsa.seasonal import seasonal_decompose
from statsmodels.tsa.seasonal import STL


df=pd.read_csv('bbca_close_2015-2025.csv')
df.set_index('Date', inplace=True)
df.index=pd.to_datetime(df.index)

series=df.Close
decomp_add=seasonal_decompose(series,period=30)
season_add=decomp_add.seasonal
trend_add=decomp_add.trend
residu_add=decomp_add.resid
observer_add=decomp_add.observed
fig, axs=plt.subplots(2,2, figsize=(13,8))

title="Additive Decomposition\n Harga Penutupan Saham BBCA\n Periode 2015–2025"
set_title={'Time Series':{'color':'royalblue','data':series},
           'Trend':{'color':'green','data':trend_add},
           'Komponen Musiman':{'color':'indigo','data':season_add},
           'Komponen Residu/Error':{'color':'darkred','data':residu_add}
          }
z=zip(axs.flatten(),set_title.items())

for ax,(t,val) in z:
  ax.set_xlabel('Tahun', fontsize=8, fontweight='bold',color='grey')
  ax.set_ylabel('Harga Penutupan', fontsize=8, fontweight='bold',color='grey' )
  ax.tick_params(axis='y', labelsize=8, colors='blue',grid_color='grey', grid_alpha=0.2 )
  ax.tick_params(axis='x', labelsize=8, colors='blue',grid_color='b', grid_alpha=0.2 )
  ax.set_title(f"{t} {title}",fontdict={'fontsize':12, 'fontweight':'bold', 'color':val['color']})
  ax.plot(val['data'], color=val['color'])


plt.tight_layout()
plt.show()

def decom_tbsb(t,r,s):
  df_tb = pd.concat([t, r,s], axis=1)
  df_tb.columns = ['trend', 'resid','sesion']
  df_tb = df_tb.dropna()
  var_resid = np.var(df_tb['resid'], ddof=1)
  var_trend_resid = np.var(
    df_tb['trend'] + df_tb['resid'],
    ddof=1
  )
  var_sesion_resid=np.var(df_tb['sesion']+df_tb['resid'], ddof=1)
  TB = 1 - (var_resid / var_trend_resid)
  SB = 1 - (var_resid / var_sesion_resid)
  return TB,SB

tb_add,sb_add=decom_tbsb(trend_add,residu_add,season_add)
print(f"Strength of Trend : {tb_add:.5f}")
print(f"Strength of Trend : {sb_add:.5f}")

stl=STL(series,period=30)
res = stl.fit()
season_stl=res.seasonal
trend_stl=res.trend
residu_stl=res.resid
observer_stl=res.observed
fig, axs=plt.subplots(2,2, figsize=(13,8))

title="STL Decomposition\n Harga Penutupan Saham BBCA\n Periode 2015–2025"
set_title={'Time Series':{'color':'royalblue','data':series},
           'Trend':{'color':'green','data':trend_stl},
           'Komponen Musiman':{'color':'indigo','data':season_stl},
           'Komponen Residu/Error':{'color':'darkred','data':residu_stl}
          }
z=zip(axs.flatten(),set_title.items())

for ax,(t,val) in z:
  ax.set_xlabel('Tahun', fontsize=8, fontweight='bold',color='grey')
  ax.set_ylabel('Harga Penutupan', fontsize=8, fontweight='bold',color='grey' )
  ax.tick_params(axis='y', labelsize=8, colors='blue',grid_color='grey', grid_alpha=0.2 )
  ax.tick_params(axis='x', labelsize=8, colors='blue',grid_color='b', grid_alpha=0.2 )
  ax.set_title(f"{t} {title}",fontdict={'fontsize':12, 'fontweight':'bold', 'color':val['color']})
  ax.plot(val['data'], color=val['color'])

plt.tight_layout()
plt.show()

tb_stl,sb_stl=decom_tbsb(trend_stl,residu_stl,season_stl)
print(f"Strength of Trend : {tb_stl:.5f}")
print(f"Strength of Trend : {sb_stl:.5f}")
model_decomp={'Additive':{'tb':tb_add,'sb':sb_add},'STL':{'tb':tb_stl,'sb':sb_stl}}
pd.DataFrame(model_decomp)

Leave a Reply

Your email address will not be published. Required fields are marked *