OHLC.dev editorialMARKET

XAUUSD Trading Analysis with Python and MarketFlow API

Build an XAUUSD trading analysis system using Python and MarketFlow API. Explore EMA, RSI, MACD, ATR, trading signals, risk management, and technical dashboards to identify market trends and potential gold trading opportunities.

October 18, 202617 min readRafatar
XAUUSD Trading Analysis with Python and MarketFlow API

Financial markets require systematic analysis because price movements alone are not sufficient to determine reliable trading opportunities. In gold trading, particularly XAUUSD, market participants must evaluate trend direction, momentum, volatility, and important price levels before making trading decisions. Relying on a single indicator can produce incomplete information, especially when prices fluctuate around significant support and resistance zones.

This project develops an XAUUSD Trading Analysis System using Python and the MarketFlow All-in-One Market Finance API. The system is designed to retrieve historical gold prices, calculate multiple technical indicators, evaluate bullish and bearish market conditions, generate conditional trading signals, and estimate risk-management parameters.

The analysis is organized into five Python cells that implement a complete workflow, beginning with API authentication and market discovery, followed by historical data retrieval, indicator calculation, trading decision analysis, and dashboard visualization.

The system uses the OANDA:XAUUSD instrument with a daily timeframe and requests 200 historical candles. Technical analysis incorporates Exponential Moving Average (EMA20 and EMA50), Relative Strength Index (RSI14), Moving Average Convergence Divergence (MACD), Average True Range (ATR14), and 20-period support and resistance.

Rather than generating trading signals based on a single indicator, the system applies a directional scoring mechanism. This evaluates price relationships, moving-average structure, MACD momentum, and RSI conditions to classify the market as BULLISH, BEARISH, or NEUTRAL. Support and resistance levels are subsequently used to determine whether potential breakout or breakdown trading setups have emerged.

The risk-management component calculates hypothetical entry references, ATR-based stop-loss levels, two take-profit targets, and estimated position sizes using a USD 1,000 example account with 1% risk allocation.

The final output includes a technical analysis dashboard, trading interpretation report, and exported CSV datasets. These outputs establish a practical foundation for data-driven gold market analysis while maintaining a clear distinction between technical trading signals and actual trade execution.

Cell 1 — API Configuration and Market Discovery

The first cell establishes the Python environment and initializes the connection to the MarketFlow API. Requests provides HTTP communication, Pandas handles market datasets, NumPy supports numerical operations, and Matplotlib supplies visualization capabilities.

API authentication is managed through the RapidAPI key. The system first attempts to retrieve the key from an environment variable and otherwise requests it interactively using getpass. This allows authentication credentials to be supplied without permanently placing them directly in the Python source code.

A reusable api_get() function is implemented to send authenticated GET requests, enforce a 30-second timeout, verify HTTP response status, and return JSON data.

The system then interacts with two API endpoints. The /v2/how-to-use endpoint provides information about API usage, while /v2/search/market searches for the XAUUSD instrument.

Both requests include exception handling to display connectivity or retrieval errors without immediately terminating the entire notebook.

Code — Cell 1


import requests
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import os
from getpass import getpass

# Konfigurasi RapidAPI
BASE_URL = "https://marketflow-all-in-one-market-finance-api.p.rapidapi.com"
API_KEY = os.getenv("RAPIDAPI_KEY") or getpass("Masukkan RapidAPI Key: ")

HEADERS = {
    "x-rapidapi-key": API_KEY,
    "x-rapidapi-host": "marketflow-all-in-one-market-finance-api.p.rapidapi.com"
}

def api_get(endpoint, params=None):
    response = requests.get(
        f"{BASE_URL}{endpoint}",
        headers=HEADERS,
        params=params,
        timeout=30
    )
    response.raise_for_status()
    return response.json()

# 1. Periksa petunjuk penggunaan API
try:
    guide = api_get("/v2/how-to-use")
    print("✅ API berhasil terhubung")
    print("Panduan API:", str(guide)[:1200])
except Exception as e:
    print("❌ Gagal memuat panduan:", e)

# 2. Cari instrumen XAUUSD
try:
    market_data = api_get(
        "/v2/search/market",
        {"query": "XAUUSD"}
    )
    print("\n✅ Hasil pencarian XAUUSD:")
    print(market_data)
except Exception as e:
    print("❌ Gagal mengambil data market:", e)

Cell 1 prepares the API environment and performs the initial market discovery process. The system is able to identify whether the API documentation endpoint can be accessed and whether the XAUUSD query returns market information.

This stage does not calculate trading indicators or generate trading decisions. Its primary purpose is to establish connectivity and prepare the functions required by subsequent cells.

Cell 2 — Historical XAUUSD Market Data Retrieval and Normalization

The second cell retrieves historical gold market data through the /v2/chart/price endpoint. The instrument is configured as OANDA:XAUUSD, with a daily timeframe, a requested range of 200 candles, and the Asia/Jakarta timezone parameter.

The API response is processed through a recursive function named extract_candles(). This function searches nested JSON objects and lists to identify historical OHLC data, including responses where price fields are arranged as separate arrays.

Once the candle data have been extracted, they are converted into a Pandas DataFrame. Open, high, low, and close fields are standardized as numeric values, while available timestamps are converted into UTC-aware datetime objects.

The dataset is then sorted chronologically, duplicate timestamps are removed, and incomplete or logically inconsistent price observations are filtered out. The system requires at least 60 valid candles before proceeding with further analysis.

Code — Cell 2


# CELL 2 — XAUUSD HISTORICAL MARKET DATA

import json
from IPython.display import display

SYMBOL = "OANDA:XAUUSD"
TIMEFRAME = "D"
CANDLE_LIMIT = 200

raw = api_get(
    "/v2/chart/price",
    {
        "symbol": SYMBOL,
        "timeframe": TIMEFRAME,
        "range": CANDLE_LIMIT,
        "timezone": "Asia/Jakarta"
    }
)

# Cari struktur OHLC secara fleksibel
def extract_candles(obj):
    if isinstance(obj, list):
        if obj and isinstance(obj[0], dict):
            cols = set(obj[0].keys())
            if {"open", "high", "low", "close"}.issubset(cols):
                return obj
        for item in obj:
            result = extract_candles(item)
            if result is not None:
                return result

    if isinstance(obj, dict):
        # Format array terpisah
        keys = {"open", "high", "low", "close"}
        if keys.issubset(obj):
            if all(isinstance(obj[k], list) for k in keys):
                n = min(len(obj[k]) for k in keys)
                timestamps = obj.get("time", obj.get("timestamp", []))
                return [
                    {
                        "open": obj["open"][i],
                        "high": obj["high"][i],
                        "low": obj["low"][i],
                        "close": obj["close"][i],
                        "time": timestamps[i] if i < len(timestamps) else i
                    }
                    for i in range(n)
                ]

        for value in obj.values():
            result = extract_candles(value)
            if result is not None:
                return result

    return None

candles = extract_candles(raw)

if not candles:
    print(json.dumps(raw, indent=2, default=str)[:3000])
    raise ValueError("Format OHLC tidak ditemukan pada respons API.")

df = pd.DataFrame(candles)
df.columns = df.columns.str.lower()

for col in ["open", "high", "low", "close"]:
    df[col] = pd.to_numeric(df[col], errors="coerce")

# Normalisasi waktu
time_col = next(
    (c for c in ["time", "timestamp", "datetime", "date", "t"] if c in df),
    None
)

if time_col:
    t = df[time_col]
    if pd.api.types.is_numeric_dtype(t):
        numeric_t = pd.to_numeric(t, errors="coerce")
        unit = "ms" if numeric_t.dropna().median() > 1e11 else "s"
        df["datetime"] = pd.to_datetime(numeric_t, unit=unit, utc=True, errors="coerce")
    else:
        df["datetime"] = pd.to_datetime(t, utc=True, errors="coerce")

    df = df.dropna(subset=["datetime"])
    df = df.sort_values("datetime").set_index("datetime")
else:
    raise ValueError("Data tidak mengandung timestamp yang valid.")

df = df.dropna(subset=["open", "high", "low", "close"])
df = df[~df.index.duplicated(keep="last")].copy()

df = df[
    (df["high"] >= df[["open", "close", "low"]].max(axis=1)) &
    (df["low"] <= df[["open", "close", "high"]].min(axis=1)) &
    (df["low"] > 0)
]

if len(df) < 60:
    raise ValueError(f"Data tidak cukup: hanya {len(df)} candle.")

print("XAUUSD DATA LOADED")
print("Symbol:", SYMBOL)
print("Jumlah Candle:", len(df))
print("Harga Terakhir:", round(df["close"].iloc[-1], 2))
print("Waktu Candle Terakhir:", df.index[-1])
display(df.tail(10))

Cell 2 produces a validated historical OHLC dataset containing timestamps and corresponding market prices. The last ten observations are displayed to provide a preliminary view of the retrieved market information.

Data normalization is an essential step because incorrect timestamps, duplicate observations, and invalid OHLC values can distort subsequent technical indicators.

Although the request specifies 200 candles, the number of valid observations may be lower after normalization and filtering. The code explicitly checks that the resulting dataset is sufficiently large for its intended calculations.

The standardized DataFrame becomes the primary data source for the technical indicator engine in Cell 3.

Cell 3 — Technical Indicator Calculation

Cell 3 transforms the validated OHLC dataset into a series of technical measurements used to assess XAUUSD market behavior.

The system incorporates EMA20 and EMA50 to evaluate short-term and medium-term price direction. RSI14 measures the relative strength of recent price increases and decreases, while MACD provides an additional measurement of directional momentum.

ATR14 is calculated from the true range to estimate market volatility. Historical support and resistance levels are determined from the lowest low and highest high of the previous 20 candles, excluding the current candle through a one-period shift.

These indicators provide complementary analytical information. Moving averages describe price trends, RSI and MACD evaluate momentum, ATR measures volatility, and support and resistance identify historically significant price boundaries.

Code — Cell 3


# CELL 3 — TECHNICAL INDICATORS

# EMA
df["EMA20"] = df["close"].ewm(span=20, adjust=False).mean()
df["EMA50"] = df["close"].ewm(span=50, adjust=False).mean()

# RSI 14 (Wilder smoothing)
delta = df["close"].diff()
gain = delta.clip(lower=0)
loss = -delta.clip(upper=0)

avg_gain = gain.ewm(alpha=1/14, adjust=False, min_periods=14).mean()
avg_loss = loss.ewm(alpha=1/14, adjust=False, min_periods=14).mean()

rs = avg_gain / avg_loss.replace(0, np.nan)
df["RSI"] = 100 - (100 / (1 + rs))
df.loc[(avg_loss == 0) & (avg_gain > 0), "RSI"] = 100
df.loc[(avg_gain == 0) & (avg_loss > 0), "RSI"] = 0
df.loc[(avg_gain == 0) & (avg_loss == 0), "RSI"] = 50

# MACD
ema12 = df["close"].ewm(span=12, adjust=False).mean()
ema26 = df["close"].ewm(span=26, adjust=False).mean()

df["MACD"] = ema12 - ema26
df["MACD_SIGNAL"] = df["MACD"].ewm(
    span=9, adjust=False
).mean()
df["MACD_HIST"] = df["MACD"] - df["MACD_SIGNAL"]

# ATR 14 (Wilder smoothing)
previous_close = df["close"].shift(1)

tr = pd.concat([
    df["high"] - df["low"],
    (df["high"] - previous_close).abs(),
    (df["low"] - previous_close).abs()
], axis=1).max(axis=1)

df["ATR"] = tr.ewm(
    alpha=1/14,
    adjust=False,
    min_periods=14
).mean()

# Support dan resistance dari 20 candle sebelumnya
df["SUPPORT"] = df["low"].shift(1).rolling(20).min()
df["RESISTANCE"] = df["high"].shift(1).rolling(20).max()

last = df.iloc[-1]

print("=" * 50)
print("XAUUSD TECHNICAL INDICATORS")
print("=" * 50)

indicators = {
    "Close": last["close"],
    "EMA20": last["EMA20"],
    "EMA50": last["EMA50"],
    "RSI14": last["RSI"],
    "MACD": last["MACD"],
    "MACD Signal": last["MACD_SIGNAL"],
    "ATR14": last["ATR"],
    "Support": last["SUPPORT"],
    "Resistance": last["RESISTANCE"]
}

for name, value in indicators.items():
    print(f"{name:<18}: {value:,.2f}")

display(df[[
    "close", "EMA20", "EMA50", "RSI",
    "MACD", "MACD_SIGNAL", "ATR",
    "SUPPORT", "RESISTANCE"
]].tail(10).round(2))

The output from Cell 3 contains a technical summary for the most recent observation and a table showing the latest ten rows of calculated indicators.

EMA20 and EMA50 provide a reference for determining whether shorter-term prices are moving above or below the medium-term trend. RSI14 supplies a momentum measurement, while MACD and its signal line help evaluate changes in price acceleration.

ATR14 quantifies recent price volatility and becomes the basis for stop-loss calculations in Cell 4. Support and resistance establish historical price references used to evaluate potential breakout or breakdown conditions.

By combining these measurements, the system develops a more comprehensive technical representation of XAUUSD than can be obtained from price movements alone.

Cell 4 — Trading Decision Engine and Risk Management

Cell 4 implements the decision-making component of the XAUUSD Trading Analysis System. It converts technical indicators into a directional market bias, evaluates possible trading setups, and calculates hypothetical risk-management parameters.

The trading engine uses a scoring mechanism incorporating the latest closing price, EMA20, EMA50, MACD histogram, and RSI14. A positive score is assigned when the specified bullish conditions are satisfied, while bearish conditions contribute negative values.

The first three conditions evaluate the closing price relative to EMA20, EMA20 relative to EMA50, and the direction of the MACD histogram. RSI adds a positive point when its value exceeds 55 and subtracts one point when its value falls below 45. Values between those thresholds do not change the score.

A total score of at least +3 generates a BULLISH market bias, while a score of −3 or lower generates a BEARISH bias. Scores between these thresholds are classified as NEUTRAL.

The engine then compares the closing price with historical support and resistance. Bullish conditions below resistance produce a waiting signal because an upside breakout has not been confirmed. Bearish conditions above support similarly indicate that a downside breakdown has not been confirmed.

When price reaches or crosses the relevant historical boundary, the system identifies a potential BUY or SELL setup while still requiring candle confirmation.

Risk management is calculated using a stop-loss distance of 1.5 times ATR14. Two take-profit objectives are established at 1.5 and 2 times the initial risk distance. A hypothetical USD 1,000 account with 1% risk allocation is used to calculate an estimated position size.

Code — Cell 4


# CELL 4 — XAUUSD TRADING DECISION ENGINE

last = df.iloc[-1]

price = float(last["close"])
ema20 = float(last["EMA20"])
ema50 = float(last["EMA50"])
rsi = float(last["RSI"])
macd_hist = float(last["MACD_HIST"])
atr = float(last["ATR"])
support = float(last["SUPPORT"])
resistance = float(last["RESISTANCE"])

if not np.isfinite(
    [price, ema20, ema50, rsi, macd_hist, atr, support, resistance]
).all() or atr <= 0:
    raise ValueError("Indikator belum valid untuk dianalisis.")

# Skoring arah tren
score = 0
score += 1 if price > ema20 else -1
score += 1 if ema20 > ema50 else -1
score += 1 if macd_hist > 0 else -1

if rsi > 55:
    score += 1
elif rsi < 45:
    score -= 1

# Penentuan bias
if score >= 3:
    bias = "BULLISH"
elif score <= -3:
    bias = "BEARISH"
else:
    bias = "NEUTRAL"

# Konfirmasi terhadap support dan resistance
if bias == "BULLISH" and price < resistance:
    signal = "WAIT BUY - BREAKOUT BELUM TERKONFIRMASI"
elif bias == "BULLISH":
    signal = "BUY SETUP - TUNGGU KONFIRMASI CANDLE"
elif bias == "BEARISH" and price > support:
    signal = "WAIT SELL - BREAKDOWN BELUM TERKONFIRMASI"
elif bias == "BEARISH":
    signal = "SELL SETUP - TUNGGU KONFIRMASI CANDLE"
else:
    signal = "WAIT / NO TRADE"

# Entry hipotetis pada harga penutupan
entry = price
risk_distance = 1.5 * atr

if bias == "BULLISH":
    sl = entry - risk_distance
    tp1 = entry + risk_distance * 1.5
    tp2 = entry + risk_distance * 2.0
elif bias == "BEARISH":
    sl = entry + risk_distance
    tp1 = entry - risk_distance * 1.5
    tp2 = entry - risk_distance * 2.0
else:
    sl = np.nan
    tp1 = np.nan
    tp2 = np.nan

# Contoh manajemen risiko
account_balance = 1000.0
risk_percent = 1.0
risk_usd = account_balance * risk_percent / 100

# Estimasi ukuran posisi dalam troy ounces
# Tidak otomatis sama dengan lot broker
position_oz = (
    risk_usd / risk_distance
    if bias != "NEUTRAL" else 0
)

# Kondisi pasar
if rsi >= 70:
    momentum = "OVERBOUGHT"
elif rsi <= 30:
    momentum = "OVERSOLD"
elif rsi > 50:
    momentum = "POSITIVE"
else:
    momentum = "NEGATIVE"

analysis = {
    "Symbol": SYMBOL,
    "Timeframe": TIMEFRAME,
    "Candle Time": str(df.index[-1]),
    "Last Close": round(price, 2),
    "Market Bias": bias,
    "Trading Signal": signal,
    "Technical Score": score,
    "Momentum": momentum,
    "Support": round(support, 2),
    "Resistance": round(resistance, 2),
    "Entry Reference": round(entry, 2),
    "Stop Loss": round(sl, 2),
    "Take Profit 1": round(tp1, 2),
    "Take Profit 2": round(tp2, 2),
    "Risk Reward TP1": "1:1.5" if bias != "NEUTRAL" else "N/A",
    "Risk Reward TP2": "1:2" if bias != "NEUTRAL" else "N/A",
    "Risk Budget USD": risk_usd,
    "Position Size (oz)": round(position_oz, 4)
}

print("=" * 58)
print("XAUUSD TRADING ANALYSIS REPORT")
print("=" * 58)

for key, value in analysis.items():
    print(f"{key:<23}: {value}")

print("\nPERINGATAN:")
print("Entry adalah referensi, bukan harga eksekusi.")
print("Periksa candle yang sudah closed, spread, dan slippage.")
print("Position size hanya estimasi, bukan ukuran lot broker.")
print("Sinyal belum divalidasi melalui backtesting.")

The output from Cell 4 provides a structured trading analysis report containing market bias, technical score, momentum classification, support and resistance levels, entry reference, stop-loss, take-profit targets, risk budget, and estimated position size.

The system differentiates between directional market conditions and potential trading setups. For example, bullish indicator alignment does not automatically generate an immediate BUY instruction. When price remains below resistance, the signal indicates that breakout confirmation is still required.

The risk-management calculations also remain hypothetical. Entry is based on the latest closing price in the dataset, while the calculated position size represents estimated exposure in troy ounces rather than standardized broker lots.

This distinction is important because actual execution conditions depend on candle completion, transaction spread, contract specifications, and slippage. The strategy has not been validated through historical backtesting.

Cell 5 — Trading Dashboard, Export, and Final Market Interpretation

The fifth cell transforms the technical calculations into a graphical trading dashboard and generates the final analytical report.

The dashboard uses the latest 100 observations and displays three vertically arranged panels. The first panel visualizes XAUUSD closing prices, EMA20, EMA50, support, resistance, and hypothetical trade levels. The second panel presents RSI14 with horizontal reference lines at 30, 50, and 70. The third panel displays MACD, its signal line, and a histogram representing the difference between the two.

For bullish or bearish market conditions, the price chart includes additional horizontal lines identifying the entry reference, stop-loss, and two take-profit targets. These graphical elements allow users to inspect the relationship between current market structure and the calculated trading plan.

The dashboard is saved as a PNG file using a resolution of 180 DPI. The system also exports the final trading report and complete indicator dataset into separate CSV files.

Finally, the code produces a narrative interpretation based on the calculated market bias. Bullish conditions emphasize potential upward movement and resistance breakouts, bearish conditions emphasize downward movement and support breakdowns, while neutral conditions prioritize waiting for clearer directional confirmation.

Code — Cell 5


# CELL 5 — TRADING DASHBOARD & FINAL REPORT

from IPython.display import display
from datetime import datetime

view = df.tail(100).copy()

fig, axes = plt.subplots(
    3, 1,
    figsize=(15, 12),
    sharex=True,
    gridspec_kw={"height_ratios": [3, 1, 1.2]}
)

# 1. PRICE + EMA + SUPPORT/RESISTANCE
ax = axes[0]

ax.plot(view.index, view["close"],
        label="XAUUSD Close", color="black", linewidth=1.7)
ax.plot(view.index, view["EMA20"],
        label="EMA20", color="royalblue")
ax.plot(view.index, view["EMA50"],
        label="EMA50", color="darkorange")

ax.axhline(support, color="green", linestyle="--",
           label=f"Support {support:.2f}")
ax.axhline(resistance, color="red", linestyle="--",
           label=f"Resistance {resistance:.2f}")

if bias != "NEUTRAL":
    ax.axhline(entry, color="purple", linestyle=":",
               label=f"Entry Ref {entry:.2f}")
    ax.axhline(sl, color="red", linestyle=":",
               label=f"SL {sl:.2f}")
    ax.axhline(tp1, color="green", linestyle=":",
               label=f"TP1 {tp1:.2f}")
    ax.axhline(tp2, color="teal", linestyle=":",
               label=f"TP2 {tp2:.2f}")

ax.set_title(
    f"XAUUSD Technical Trading Dashboard | {bias}\n{signal}",
    fontsize=14, fontweight="bold"
)
ax.set_ylabel("Gold Price (USD/oz)")
ax.legend(loc="best", fontsize=8, ncol=2)
ax.grid(alpha=0.2)

# 2. RSI
ax = axes[1]
ax.plot(view.index, view["RSI"],
        color="purple", label="RSI 14")
ax.axhline(70, color="red", linestyle="--")
ax.axhline(30, color="green", linestyle="--")
ax.axhline(50, color="gray", linestyle=":")
ax.set_ylim(0, 100)
ax.set_ylabel("RSI")
ax.legend()
ax.grid(alpha=0.2)

# 3. MACD
ax = axes[2]
ax.plot(view.index, view["MACD"],
        label="MACD", color="blue")
ax.plot(view.index, view["MACD_SIGNAL"],
        label="Signal", color="orange")

bar_colors = np.where(
    view["MACD_HIST"] >= 0, "green", "red"
)
ax.bar(view.index, view["MACD_HIST"],
       color=bar_colors, alpha=0.45, width=0.7)

ax.axhline(0, color="black", linewidth=0.8)
ax.set_ylabel("MACD")
ax.legend()
ax.grid(alpha=0.2)

plt.xlabel("Date")
plt.tight_layout()
plt.savefig("XAUUSD_Trading_Dashboard.png", dpi=180)
plt.show()

# Export hasil analisis
report = pd.DataFrame(
    [{"Metric": k, "Value": v} for k, v in analysis.items()]
)

report.to_csv(
    "XAUUSD_Trading_Report.csv",
    index=False
)

df.to_csv("XAUUSD_Indicators.csv")

print("\n" + "=" * 55)
print("FINAL XAUUSD TRADING INTERPRETATION")
print("=" * 55)
print(f"Market Bias : {bias}")
print(f"Signal      : {signal}")
print(f"RSI         : {rsi:.2f}")
print(f"MACD Hist   : {macd_hist:.4f}")
print(f"ATR         : {atr:.2f}")

if bias == "BULLISH":
    print("Interpretasi: dominasi indikator mengarah naik.")
    print("Perhatikan breakout resistance dan pullback.")
elif bias == "BEARISH":
    print("Interpretasi: dominasi indikator mengarah turun.")
    print("Perhatikan breakdown support dan pullback.")
else:
    print("Interpretasi: arah belum cukup jelas.")
    print("Prioritaskan WAIT sampai ada konfirmasi.")

print("\nFiles generated:")
print("- XAUUSD_Trading_Dashboard.png")
print("- XAUUSD_Trading_Report.csv")
print("- XAUUSD_Indicators.csv")

display(report)

Cell 5 provides both graphical and numerical representations of the technical analysis. The dashboard enables users to visually examine the relationship between market price, moving averages, momentum indicators, and hypothetical trading levels.

The export functionality produces three files:

Output file

Description

XAUUSD_Trading_Dashboard.png

Technical visualization of XAUUSD price, RSI, and MACD

XAUUSD_Trading_Report.csv

Structured trading analysis, signals, and risk parameters

XAUUSD_Indicators.csv

Historical market data and calculated indicators

The final interpretation reinforces the system's conditional approach to trading. Bullish or bearish market bias identifies directional dominance, whereas the actual trading signal reflects whether the associated support or resistance conditions have been satisfied.

When the indicators do not establish a sufficiently strong directional bias, the system prioritizes WAIT rather than generating a trade recommendation.

Result — XAUUSD Technical Trading Analysis

The five-cell workflow provides an integrated analytical framework for evaluating the XAUUSD market through historical price data, technical indicators, conditional trading signals, and risk-management calculations.

The system retrieves up to 200 daily candles from MarketFlow and applies data validation before calculating EMA20, EMA50, RSI14, MACD, ATR14, and historical support and resistance.

The resulting indicators are combined through a directional scoring model that classifies the market as BULLISH, BEARISH, or NEUTRAL. Additional support and resistance conditions are used to distinguish potential breakout and breakdown setups from situations where price confirmation is incomplete.

The technical analysis report contains the following principal outputs:

Analysis component

Generated information

Market information

XAUUSD symbol, timeframe, candle timestamp

Trend assessment

Bullish, bearish, or neutral market bias

Technical evaluation

Directional score and momentum classification

Price structure

Historical support and resistance

Trading decision

BUY setup, SELL setup, or WAIT

Risk management

Entry reference, stop-loss, TP1, and TP2

Position sizing

Estimated exposure using a 1% risk budget

Visualization

Price, EMA, RSI, and MACD dashboard

The risk-management model applies a stop-loss distance equal to 1.5 times ATR14, with take-profit objectives equivalent to 1.5R and 2R. For the example USD 1,000 account, a 1% allocation establishes a theoretical risk budget of USD 10 per trade.

The system also generates a three-panel dashboard and exports the final trading report and indicator dataset for further evaluation.

Actual market prices, indicator readings, generated signals, and historical performance statistics are not included here because the uploaded source file contains the implementation code rather than saved execution results. Therefore, the described outputs represent the system's programmed analytical capabilities, not independently verified trading outcomes.

Conclusion

The XAUUSD Trading Analysis System demonstrates how Python and the MarketFlow API can be integrated to construct a systematic gold market analysis workflow.

The project begins with API authentication and market discovery, proceeds through historical OHLC data retrieval and validation, and applies multiple technical indicators to evaluate trend direction, momentum, volatility, and historical price structure.

A rule-based scoring mechanism converts these indicators into bullish, bearish, or neutral market classifications. The trading decision engine subsequently evaluates support and resistance to identify potential breakout or breakdown setups while distinguishing unconfirmed market conditions from potential trading opportunities.

The system incorporates ATR-based risk calculations, predetermined reward-to-risk targets, and estimated position sizing. These features establish a consistent framework for assessing hypothetical trade exposure rather than relying entirely on discretionary judgments.

The final dashboard provides a visual representation of the analytical results, while CSV exports allow the calculated indicators and trading parameters to be reviewed or processed in other analytical environments.

Nevertheless, the project remains a technical decision-support system. Its calculated entry levels are references rather than guaranteed execution prices, and the position-sizing methodology does not automatically account for broker-specific lot sizes, spreads, commissions, or slippage. The latest returned candle is also not explicitly checked for completion, making timestamp verification important before interpreting signals.

Furthermore, the strategy has not been validated through backtesting or out-of-sample evaluation. Consequently, its technical scores and potential setups should not be interpreted as evidence of predictive accuracy or guaranteed trading profitability.

Overall, the project establishes a reproducible foundation for XAUUSD technical analysis by combining historical market data, multiple technical indicators, conditional signal generation, risk-management calculations, and graphical reporting within a five-cell Python workflow.