OHLC.dev editorialMARKET

XAUUSD Market Analysis Using MarketFlow API and IPO Event Data

This article presents an XAUUSD Market Analysis system using MarketFlow API to combine market search, IPO event analysis, event statistics, and trader-focused market context.

October 1, 20268 min readRafatar
XAUUSD Market Analysis Using MarketFlow API and IPO Event Data

Market and IPO Event Analysis for XAUUSD Using MarketFlow API

Introduction

Market analysis requires reliable identification of the instrument being analyzed and sufficient market context before interpreting trading conditions. This project develops a Python-based Market and IPO Event Analysis System using the MarketFlow financial API. The system searches for the requested market instrument, retrieves IPO event data within a defined period, normalizes the API responses into structured DataFrames, processes event statistics, and generates a trader-oriented market context report.

The analysis uses XAUUSD as the market query and evaluates IPO events from November 2, 2025 to November 9, 2025. The API key is requested securely through getpass() rather than being hard-coded into the analysis workflow.

Cell 1 — Library, API Key, and Analysis Parameters

The first cell imports the required libraries and defines the MarketFlow API configuration. It also establishes the market query and IPO analysis period.

# ==============================================================
# CELL 1 - SETUP & CONFIGURATION
# MARKET + IPO EVENT ANALYSIS
# ==============================================================

import requests
import pandas as pd
import numpy as np

from getpass import getpass
from IPython.display import display


# ==============================================================
# RAPIDAPI CONFIG
# ==============================================================

RAPIDAPI_KEY = getpass("Masukkan RapidAPI Key: ")

RAPIDAPI_HOST = "marketflow-all-in-one-market-finance-api.p.rapidapi.com"

HEADERS = {
    "x-rapidapi-key": RAPIDAPI_KEY,
    "x-rapidapi-host": RAPIDAPI_HOST
}


# ==============================================================
# ANALYSIS PARAMETERS
# ==============================================================

SYMBOL_QUERY = "XAUUSD"

START_DATE = "2025-11-02"
END_DATE   = "2025-11-09"


print("=" * 70)
print("MARKET & IPO EVENT ANALYSIS")
print("=" * 70)

print("Market Query :", SYMBOL_QUERY)
print("IPO Period   :", START_DATE, "s/d", END_DATE)

Cell 2 — Data Collection from Market and IPO APIs

The second cell connects to two API endpoints. The first endpoint searches for the requested market instrument, while the second retrieves IPO events during the specified period. A reusable get_api_data() function handles the HTTP request, timeout, response validation, and JSON conversion.

# ==============================================================
# CELL 2 - DATA COLLECTION
# ==============================================================

BASE_URL = "https://marketflow-all-in-one-market-finance-api.p.rapidapi.com"


# ==============================================================
# MARKET SEARCH
# ==============================================================

market_url = f"{BASE_URL}/v2/search/market"

market_params = {
    "query": SYMBOL_QUERY
}


# ==============================================================
# IPO EVENTS
# ==============================================================

ipo_url = f"{BASE_URL}/ipos-events"

ipo_params = {
    "skip": 0,
    "start_date": START_DATE,
    "end_date": END_DATE
}


# ==============================================================
# REQUEST FUNCTION
# ==============================================================

def get_api_data(url, params=None):

    try:

        response = requests.get(
            url,
            headers=HEADERS,
            params=params,
            timeout=30
        )

        print("\nURL:", response.url)
        print("Status:", response.status_code)

        response.raise_for_status()

        return response.json()

    except requests.exceptions.RequestException as e:

        print("API Request Error:", e)

        return None


# ==============================================================
# GET DATA
# ==============================================================

print("=" * 70)
print("MENGAMBIL MARKET DATA")
print("=" * 70)

market_raw = get_api_data(
    market_url,
    market_params
)


print("\n" + "=" * 70)
print("MENGAMBIL IPO EVENTS")
print("=" * 70)

ipo_raw = get_api_data(
    ipo_url,
    ipo_params
)


print("\nData berhasil diambil.")

Cell 3 — JSON Normalization

The third cell converts the API responses into Pandas DataFrames. Because API structures can vary, extract_records() checks common keys such as data, results, result, items, events, quotes, and symbols before converting the records with pd.json_normalize(). This makes the processing more robust to different JSON response structures.

# ==============================================================
# CELL 3 - JSON NORMALIZATION
# ==============================================================

def extract_records(data):

    if data is None:
        return []

    # Jika langsung list
    if isinstance(data, list):
        return data

    # Jika dictionary
    if isinstance(data, dict):

        preferred_keys = [
            "data",
            "results",
            "result",
            "items",
            "events",
            "quotes",
            "symbols"
        ]

        # Cari key umum
        for key in preferred_keys:

            if key in data:

                value = data[key]

                if isinstance(value, list):
                    return value

                if isinstance(value, dict):

                    nested = extract_records(value)

                    if nested:
                        return nested

        # Cari list apa pun di dalam dictionary
        for value in data.values():

            if isinstance(value, list):

                if len(value) > 0:
                    return value

        # Jika dictionary merupakan satu record
        return [data]

    return []


# ==============================================================
# MARKET DATAFRAME
# ==============================================================

market_records = extract_records(market_raw)

if market_records:

    market_df = pd.json_normalize(market_records)

else:

    market_df = pd.DataFrame()


# ==============================================================
# IPO DATAFRAME
# ==============================================================

ipo_records = extract_records(ipo_raw)

if ipo_records:

    ipo_df = pd.json_normalize(ipo_records)

else:

    ipo_df = pd.DataFrame()


# ==============================================================
# RESULT
# ==============================================================

print("=" * 70)
print("MARKET SEARCH RESULT")
print("=" * 70)

print("Jumlah Market Result :", len(market_df))
print("Jumlah Kolom         :", len(market_df.columns))

display(market_df)


print("\n" + "=" * 70)
print("IPO EVENT RESULT")
print("=" * 70)

print("Jumlah IPO Event :", len(ipo_df))
print("Jumlah Kolom     :", len(ipo_df.columns))

display(ipo_df)

Cell 4 — Trader Data Processing

The fourth cell prepares the market and IPO datasets for trader-oriented analysis. Because some API fields can contain lists or dictionaries, the make_hashable() function converts these structures into strings before drop_duplicates() is applied.

For IPO events, the system automatically searches for possible date columns, converts the detected column to datetime, and generates additional features such as event day, event month, and cleaned event date.

The system then calculates total IPO events, analysis-period length, average IPO events per day, and event activity classification. The classification is based on event intensity: NO EVENT, LOW, MODERATE, or HIGH.

# ==============================================================
# CELL 4 - TRADER DATA PROCESSING
# REVISI: HANDLE LIST / DICT COLUMN
# ==============================================================

import json


# ==============================================================
# FUNCTION: UBAH LIST / DICT AGAR AMAN UNTUK PANDAS
# ==============================================================

def make_hashable(value):

    if isinstance(value, (list, dict)):

        return json.dumps(
            value,
            sort_keys=True,
            default=str
        )

    return value


# ==============================================================
# MARKET INFORMATION
# ==============================================================

market_summary = pd.DataFrame()

if not market_df.empty:

    market_summary = market_df.copy()

    # UBAH KOLOM LIST / DICT MENJADI STRING
    for col in market_summary.columns:

        market_summary[col] = market_summary[col].apply(
            make_hashable
        )

    # Hapus duplikat
    market_summary = market_summary.drop_duplicates().reset_index(
        drop=True
    )

    # Tambahkan query pencarian
    market_summary["search_query"] = SYMBOL_QUERY


# ==============================================================
# IPO EVENT PROCESSING
# ==============================================================

ipo_analysis = ipo_df.copy()

if not ipo_analysis.empty:

    # HANDLE LIST / DICT
    for col in ipo_analysis.columns:

        ipo_analysis[col] = ipo_analysis[col].apply(
            make_hashable
        )

    # Hapus duplikat
    ipo_analysis = ipo_analysis.drop_duplicates().reset_index(
        drop=True
    )

    # DETEKSI KOLOM TANGGAL
    possible_date_columns = [
        "date",
        "event_date",
        "ipo_date",
        "expected_date",
        "start_date",
        "listing_date",
        "priced_date",
        "expectedDate",
        "ipoDate",
        "listingDate"
    ]

    detected_date_column = None

    for col in possible_date_columns:

        if col in ipo_analysis.columns:

            detected_date_column = col

            ipo_analysis[col] = pd.to_datetime(
                ipo_analysis[col],
                errors="coerce"
            )

            break


    # DATE FEATURES
    if detected_date_column is not None:

        ipo_analysis["event_day"] = (
            ipo_analysis[detected_date_column]
            .dt.day_name()
        )

        ipo_analysis["event_month"] = (
            ipo_analysis[detected_date_column]
            .dt.month_name()
        )

        ipo_analysis["event_date_clean"] = (
            ipo_analysis[detected_date_column]
            .dt.date
        )

        ipo_analysis = (
            ipo_analysis
            .sort_values(
                detected_date_column,
                na_position="last"
            )
            .reset_index(drop=True)
        )


# ==============================================================
# IPO STATISTICS
# ==============================================================

total_ipo = len(ipo_analysis)

period_days = (
    pd.to_datetime(END_DATE)
    -
    pd.to_datetime(START_DATE)
).days + 1


ipo_per_day = (
    total_ipo / period_days
    if period_days > 0
    else np.nan
)


# ==============================================================
# TRADER EVENT INTENSITY
# ==============================================================

if total_ipo == 0:

    event_activity = "NO EVENT"

elif ipo_per_day < 1:

    event_activity = "LOW"

elif ipo_per_day < 3:

    event_activity = "MODERATE"

else:

    event_activity = "HIGH"


# ==============================================================
# SUMMARY TABLE
# ==============================================================

ipo_stats = pd.DataFrame({

    "Metric": [
        "Market Query",
        "Analysis Start",
        "Analysis End",
        "Period (Days)",
        "Total IPO Events",
        "Average IPO Events / Day",
        "IPO Event Activity"
    ],

    "Value": [
        SYMBOL_QUERY,
        START_DATE,
        END_DATE,
        period_days,
        total_ipo,
        round(ipo_per_day, 2),
        event_activity
    ]

})


# ==============================================================
# OUTPUT
# ==============================================================

print("=" * 75)
print("MARKET RESULT")
print("=" * 75)

print(
    "Jumlah Market Result :",
    len(market_summary)
)

print(
    "Jumlah Kolom         :",
    len(market_summary.columns)
)

display(market_summary)


print("\n" + "=" * 75)
print("IPO CALENDAR")
print("=" * 75)

print(
    "Jumlah IPO Event :",
    total_ipo
)

if detected_date_column is not None:

    print(
        "Kolom Tanggal   :",
        detected_date_column
    )

else:

    print(
        "Kolom Tanggal   :",
        "Tidak terdeteksi"
    )

display(ipo_analysis)


print("\n" + "=" * 75)
print("EVENT STATISTICS")
print("=" * 75)

display(ipo_stats)

Cell 5 — Final Trader Analysis and Export

The final cell produces the trader market context report. The report identifies the queried instrument, summarizes the IPO calendar, calculates event distribution by day, and explains how the IPO information should be interpreted in relation to XAUUSD.

An important limitation is explicitly stated in the source code: IPO events cannot be used directly as an indicator of XAUUSD price direction. Their relevance to gold is indirect and requires combination with macroeconomic variables.

The code also identifies additional data required for a stronger XAUUSD trading analysis, including OHLC data, volume or tick volume, moving averages, RSI, MACD, ATR, support and resistance, US Dollar Index, US Treasury yields, Fed/FOMC events, CPI, NFP, and interest-rate expectations. Finally, the system exports three CSV files.

# ==============================================================
# CELL 5 - FINAL TRADER ANALYSIS
# ==============================================================

print("=" * 75)
print("TRADER MARKET CONTEXT REPORT")
print("=" * 75)


# ==============================================================
# 1. INSTRUMENT IDENTIFICATION
# ==============================================================

print("\n[1] INSTRUMENT")

print("Search Query :", SYMBOL_QUERY)

if not market_summary.empty:

    print(
        "Market Result:",
        len(market_summary),
        "instrument ditemukan"
    )

else:

    print(
        "Market Result: Tidak ditemukan"
    )


# ==============================================================
# 2. IPO EVENT CALENDAR
# ==============================================================

print("\n[2] IPO EVENT CALENDAR")

print(
    "Periode :",
    START_DATE,
    "s/d",
    END_DATE
)

print(
    "Total IPO Event :",
    total_ipo
)

print(
    "Rata-rata Event per Hari :",
    round(ipo_per_day, 2)
)


# ==============================================================
# 3. EVENT DISTRIBUTION
# ==============================================================

print("\n[3] EVENT DISTRIBUTION")

if (
    not ipo_analysis.empty
    and "event_day" in ipo_analysis.columns
):

    day_distribution = (
        ipo_analysis["event_day"]
        .value_counts()
        .rename_axis("Day")
        .reset_index(name="IPO_Count")
    )

    display(day_distribution)

else:

    day_distribution = pd.DataFrame()

    print(
        "Distribusi tanggal tidak tersedia."
    )


# ==============================================================
# 4. TRADER INTERPRETATION
# ==============================================================

print("\n[4] INTERPRETASI UNTUK TRADER")

print("""
A. MARKET IDENTIFICATION
Endpoint market search digunakan untuk memastikan identitas,
symbol, exchange, dan metadata instrumen XAUUSD yang tersedia
di provider.

B. EVENT CALENDAR
IPO calendar memberikan konteks aktivitas pasar ekuitas selama
periode analisis.

C. EVENT CONCENTRATION
Jumlah IPO per hari dapat digunakan untuk melihat hari dengan
konsentrasi corporate event lebih tinggi.

D. XAUUSD
IPO event tidak dapat digunakan secara langsung sebagai indikator
arah harga XAUUSD. Dampaknya terhadap emas bersifat tidak langsung
dan harus dikombinasikan dengan faktor makroekonomi.

E. DATA YANG MASIH DIPERLUKAN
Untuk menghasilkan analisis trading XAUUSD yang kuat diperlukan:

- OHLC historical price
- Volume / tick volume
- Moving Average
- RSI
- MACD
- ATR
- Support & Resistance
- US Dollar Index
- US Treasury Yield
- Fed / FOMC calendar
- CPI
- NFP
- Interest-rate expectations
""")


# ==============================================================
# 5. EXPORT
# ==============================================================

market_summary.to_csv(
    "market_search_XAUUSD.csv",
    index=False
)

ipo_analysis.to_csv(
    "ipo_events.csv",
    index=False
)

ipo_stats.to_csv(
    "trader_event_summary.csv",
    index=False
)


print("\n" + "=" * 75)
print("FILE OUTPUT")
print("=" * 75)

print("1. market_search_XAUUSD.csv")
print("2. ipo_events.csv")
print("3. trader_event_summary.csv")

print("\nAnalisis selesai.")

Conclusion

This project develops a Market and IPO Event Analysis System that combines market instrument identification with IPO event monitoring through the MarketFlow API. The workflow retrieves market search results and IPO events, normalizes heterogeneous JSON responses, removes duplicate records, detects event dates, calculates event intensity, and generates a trader-oriented market context report.

For the selected XAUUSD query, the IPO calendar functions primarily as contextual information rather than a direct price-direction indicator. The source code explicitly recognizes that IPO activity relates to equity-market events and does not directly determine the direction of gold prices. A stronger XAUUSD trading framework therefore requires historical OHLC data, volume, technical indicators, support and resistance, and macroeconomic variables such as the US Dollar Index, Treasury yields, Fed/FOMC events, CPI, NFP, and interest-rate expectations.

The final workflow also exports three datasets: market_search_XAUUSD.csv, ipo_events.csv, and trader_event_summary.csv, allowing the processed results to be used for further analysis outside the notebook.