OHLC.dev editorialIDX

Tender Offer Calendar and Economic Calendar Dashboard Using Python

Tender Offer Calendar and Economic Calendar Dashboard is a Python-based workflow that combines Tender Offer Calendar data and Economic Calendar data from the IDX API. The workflow helps investors monitor corporate actions, track economic events, organize market information, and generate insights through a centralized dashboard for research and market monitoring.

June 6, 20265 min readRafatar
Tender Offer Calendar and Economic Calendar Dashboard Using Python

Markets are influenced by more than price movements alone. Corporate actions and economic events often provide important signals that help investors understand potential opportunities and risks before they appear in stock charts.

Tender offers can indicate strategic corporate activities such as acquisitions, ownership changes, or restructuring initiatives. Meanwhile, economic calendar events provide visibility into macroeconomic announcements that may affect market sentiment, investor expectations, and overall market direction.

Rather than monitoring these data sources separately, this notebook combines both datasets into a single dashboard. By integrating Tender Offer Calendar data and Economic Calendar data, investors can gain a broader understanding of both corporate developments and economic conditions from one centralized view.

This project demonstrates how to build a practical market intelligence dashboard using Python and the IDX API.

CELL 1 — Import Library

import requests
import pandas as pd
import time
from IPython.display import display, Markdown

Explanation

Cell 1 imports the libraries required throughout the notebook.

The notebook uses:

  • requests for API communication.

  • pandas for dataframe creation and data processing.

  • time for handling delays between API requests.

  • display and Markdown for building a cleaner dashboard presentation.

Together, these libraries provide the foundation for retrieving, processing, and displaying market intelligence data.

CELL 2 — Konfigurasi API

RAPIDAPI_KEY = "YOUR_API_KEY"

BASE_URL = "https://indonesia-stock-exchange-idx.p.rapidapi.com"

HEADERS = {
    "Content-Type": "application/json",
    "x-rapidapi-host": "indonesia-stock-exchange-idx.p.rapidapi.com",
    "x-rapidapi-key": RAPIDAPI_KEY
}

Explanation

Cell 2 configures the API connection.

The notebook defines the API key, base URL, and request headers required to access the Indonesia Stock Exchange API.

By centralizing these settings, future endpoint calls become easier to manage and maintain throughout the project.

CELL 3 — Function API Aman

def fetch_api(endpoint, params=None, retries=3, delay=3):
    url = f"{BASE_URL}{endpoint}"

    for attempt in range(retries):
        response = requests.get(url, headers=HEADERS, params=params)

        if response.status_code == 200:
            return response.json()

        if response.status_code == 429:
            print(f"Rate limit terkena. Menunggu {delay} detik...")
            time.sleep(delay)
            delay *= 2
            continue

        print("Error:", response.status_code)
        print(response.text)
        return None

    return None


def find_first_list(obj):
    if isinstance(obj, list):
        return obj

    if isinstance(obj, dict):
        for value in obj.values():
            result = find_first_list(value)
            if isinstance(result, list):
                return result

    return []


def safe_dataframe(response):
    data = find_first_list(response)

    if data:
        return pd.DataFrame(data)

    if isinstance(response, dict):
        try:
            return pd.json_normalize(response)
        except:
            return pd.DataFrame()

    return pd.DataFrame()

Explanation

Cell 3 creates several helper functions used throughout the workflow.

The fetch_api() function is responsible for communicating with the API and includes retry logic when rate limits are encountered. If the API temporarily rejects requests because of usage limits, the function automatically waits before trying again.

The find_first_list() function searches through nested response structures and returns the first available list. This is useful because different API endpoints may return data using different JSON formats.

The safe_dataframe() function converts API responses into pandas dataframes while handling various response structures safely. This ensures that the dashboard can display data consistently even when endpoint responses vary.

CELL 4 — Ambil & Gabungkan 2 API

tender_offer = fetch_api("/api/calendar/tender-offer")

time.sleep(5)

economic_calendar = fetch_api("/api/calendar/economic")

api_result = {
    "getTenderOfferCalendar": tender_offer,
    "getEconomicCalendar": economic_calendar
}

print("Data berhasil diambil dan digabung")

Explanation

Cell 4 retrieves data from two IDX API endpoints.

Tender Offer Calendar

The Tender Offer Calendar endpoint provides information related to tender offer activities and corporate action events.

These events may help investors monitor ownership changes, acquisition activity, and other strategic corporate developments.

Economic Calendar

The Economic Calendar endpoint provides information about upcoming economic events that may influence market sentiment and trading activity.

The notebook waits briefly between requests to reduce the possibility of rate-limit issues.

After both API requests are completed, the responses are stored inside a single dictionary named api_result.

This structure creates a centralized data source for dashboard generation and future analysis.

CELL 5 — Dashboard Rapi & Mudah Dibaca

display(Markdown("# 📊 IDX Corporate Action & Economic Calendar Dashboard"))

# =========================
# TENDER OFFER CALENDAR
# =========================
display(Markdown("## 🤝 Tender Offer Calendar"))

tender_df = safe_dataframe(api_result["getTenderOfferCalendar"])

if tender_df.empty:
    display(Markdown("✅ Tidak ada data tender offer yang tersedia."))
else:
    display(tender_df)

# =========================
# ECONOMIC CALENDAR
# =========================
display(Markdown("## 🗓️ Economic Calendar"))

economic_raw = api_result["getEconomicCalendar"]
economic_content = {}

if isinstance(economic_raw, dict):
    economic_content = economic_raw.get("data", {}).get("data", {})

today = economic_content.get("today", "-")
timezone = economic_content.get("timezone", "-")

display(Markdown(f"""
**Tanggal Data:** {today}
**Timezone:** {timezone}
"""))

economic_df = safe_dataframe(economic_raw)

if economic_df.empty:
    display(Markdown("✅ Tidak ada event kalender ekonomi yang tersedia."))
else:
    display(economic_df)

# =========================
# RINGKASAN PROJECT
# =========================
display(Markdown("## 📌 Ringkasan Project"))

summary_df = pd.DataFrame([{
    "Tender Offer Data": len(tender_df),
    "Economic Calendar Data": len(economic_df),
    "Tanggal Economic Calendar": today,
    "Project Type": "Corporate Action + Economic Calendar"
}])

display(summary_df)

Explanation

Cell 5 generates the final dashboard.

The dashboard begins by displaying Tender Offer Calendar data. The notebook converts the API response into a dataframe and displays the results. If no records are available, a notification message is shown instead.

The second section displays Economic Calendar data. The notebook extracts additional information such as the reporting date and timezone before displaying the available economic events.

Finally, the dashboard creates a project summary table containing:

  • Total Tender Offer records.

  • Total Economic Calendar records.

  • Economic Calendar date.

  • Project category.

This summary provides a quick overview of the retrieved datasets and helps users understand the overall scope of the dashboard.

Result:

result

OVERALL WORKFLOW

This notebook follows a simple market intelligence workflow.

First, it imports the required Python libraries.

Second, it configures API authentication and request settings.

Third, it creates reusable helper functions for API communication and dataframe generation.

Fourth, it retrieves Tender Offer Calendar and Economic Calendar data from the IDX API.

Fifth, it combines both datasets into a centralized structure.

Finally, it generates a dashboard containing corporate action information, economic calendar events, and a project summary.

WHY THIS CASE MATTERS

Investors often analyze corporate actions and economic events separately.

However, market behavior is frequently influenced by both company-level developments and broader economic conditions.

Tender Offer Calendar data helps investors monitor important corporate activities, while Economic Calendar data provides visibility into upcoming events that may affect market sentiment.

By combining these datasets into a single workflow, investors can improve market awareness and gain a more complete understanding of the factors influencing investment decisions.

CONCLUSION

This tutorial demonstrates how to build a Tender Offer Calendar and Economic Calendar Dashboard using Python and the IDX API.

The notebook retrieves corporate action data, collects economic calendar information, transforms API responses into structured dataframes, and presents the results through a clean dashboard.

The final workflow provides:

  • Tender Offer monitoring

  • Economic Calendar tracking

  • Corporate action visibility

  • Market event monitoring

  • Dashboard reporting

For investors, analysts, and fintech developers, this project provides a practical foundation for building corporate action and economic event monitoring systems.