Dokumentasi Integrasi Data

Panduan Arsitektur & Langkah Koneksi API Riil

← Kembali ke Dashboard

1. Bagaimana Data Saat Ini Diperoleh?

Sesuai dengan spesifikasi awal proyek (non-API & non-database), seluruh data historis saham saat ini diperoleh dari **data lokal statis** (*mock/dummy data*) yang disimulasikan di dalam file: app/data/seasonalStocks.ts.

Metodologi Pembuatan Data

  • Seed-Based PRNG: Data dihasilkan menggunakan algoritma generator acak deterministik (memakai fungsi sinus dengan seed konstan). Ini menjamin bahwa angka return yang diperoleh akan selalu sama setiap kali halaman di-refresh, menjaga stabilitas tampilan grafik.
  • Box-Muller Transform: Digunakan untuk menghasilkan sebaran data return dengan distribusi normal. Formula ini sangat umum dipakai untuk memodelkan volatilitas harga saham riil.
  • Efek Musiman (Seasonal Bias): Agar mendekati karakteristik bursa Indonesia (IHSG), kami menyuntikkan parameter tambahan (*bias*) ke bulan-bulan spesifik, seperti:
    • Desember: Ditambah bias positif kuat (efek Window Dressing).
    • Mei: Ditambah bias negatif (pola musiman historis "Sell in May and Go Away").
    • Januari: Ditambah bias positif (efek January Effect).

2. Struktur Model Data (TypeScript)

Struktur data yang digunakan oleh kalkulator dan komponen didefinisikan secara statis di file app/types/seasonal.ts:

// Representasi satu baris data historis bulanan
export interface StockMonthlyData {
  year: number;
  month: number; // 1 s.d. 12
  returnVal: number; // Nilai persentase return (misal: 4.5 untuk +4.5%)
}

// Representasi satu kesatuan entitas saham
export interface StockData {
  code: string; // Kode ticker saham (contoh: 'BBCA', 'IHSG')
  name: string; // Nama lengkap emiten (contoh: 'PT Bank Central Asia Tbk')
  history: StockMonthlyData[]; // Koleksi data historis
}

3. Rencana Migrasi ke API Riil (Produksi)

Untuk menghubungkan dashboard ini dengan bursa data sesungguhnya, Anda dapat menggunakan API penyedia data keuangan seperti **Yahoo Finance (melalui library backend)**, **Goapi.id (spesialis IHSG/saham lokal)**, atau **EOD Historical Data**.

Arsitektur Aliran Data yang Direkomendasikan:

LANGKAH 1: Server Route

Buat server endpoint lokal di Nuxt 4 untuk mengambil data dari API eksternal (mencegah isu CORS browser dan melindungi API Key Anda).

File: server/api/stocks.ts
LANGKAH 2: Caching Data

Simpan respons API di memori cache server sementara (misal: 1 hari) untuk mengurangi beban kuota API eksternal Anda.

Fitur: useStorage() Nitro
LANGKAH 3: Front-End Fetch

Gunakan komposabel bawaan Nuxt untuk memuat data dari server endpoint dan perbarui state reaktif halaman.

Fitur: useFetch()

Implementasi Server Route (`server/api/seasonal.ts`):

Berikut adalah rancangan kode server route Nuxt untuk mengambil data riil dari API eksternal dan memformatnya agar sesuai dengan tipe data dashboard:

import { defineEventHandler, getQuery } from 'h3';

export default defineEventHandler(async (event) => {
  const query = getQuery(event);
  const stockCode = (query.code as string) || 'BBCA';

  // Contoh request ke pihak ketiga (misal: Goapi.id)
  const apiKey = process.env.STOCK_API_KEY;
  const apiUrl = `https://api.goapi.id/v1/stock/idx/${stockCode}/historical?api_key=${apiKey}`;

  try {
    const rawData = await $fetch<any>(apiUrl);
    
    // Transformasikan format respons API mentah menjadi tipe StockMonthlyData[]
    const formattedHistory = rawData.data.results.map((item: any) => {
      const date = new Date(item.date);
      return {
        year: date.getFullYear(),
        month: date.getMonth() + 1,
        returnVal: Number(item.return_percentage)
      };
    });

    return {
      code: stockCode,
      name: rawData.data.name,
      history: formattedHistory
    };
  } catch (error) {
    return createError({
      statusCode: 500,
      statusMessage: 'Gagal mengambil data dari server penyedia.',
    });
  }
});

Koneksi pada Halaman Front-End (`app/pages/seasonal/index.vue`):

Pada bagian script halaman utama, Anda tinggal menukar pemanggilan array lokal menjadi fungsi async fetch:

<script setup lang="ts">
const selectedStockCode = ref('BBCA');

// Panggil server route Nuxt secara reaktif setiap kali selectedStockCode berubah
const { data: activeStock, pending, error } = await useFetch(() => `/api/seasonal`, {
  params: { code: selectedStockCode }
});
</script>
Catatan Penting Penggunaan

Dokumen ini dirancang sebagai panduan pengembangan internal untuk mempermudah transisi dari tahap purwarupa (prototype) lokal ke tahap produksi dengan integrasi API komersial. Selalu lindungi rahasia kunci API eksternal Anda menggunakan berkas lingkungan .env dan jangan pernah menyebarkan kunci rahasia di dalam bundle client-side Anda.