MetalAPI
XAU3,997.89−1.54%XAG53.936−1.51%XPT1,554.47−0.83%XPD1,047.03−0.44%XCU6.5080+2.29%WTI103.27+3.82%BRENT111.70−1.30%EUR1.120400−0.01%GBP1.337500−0.01%JPY0.0063761+0.14%CHF1.213445−0.25%TRY0.020125−0.12%BTC80,652.59−0.15%ETH2,354.86−0.04%
All articles
GoldSilverMarketsHistorical Data

Gold Silver Ratio: What It Is and How to Calculate It

What the gold silver ratio measures, how to calculate it from live gold and silver prices, and how to chart its history with an API in Python and JavaScript.

By MetalAPI Team··11 min read

What is the gold silver ratio?

The gold silver ratio is the number of troy ounces of silver it takes to buy one troy ounce of gold. You get it by dividing the gold price by the silver price, both in the same currency and for the same weight. With the example prices used throughout the MetalAPI documentation, gold at 3,997.89 US dollars and silver at 53.94 US dollars per troy ounce, the ratio is about 74.1: at those prices, one ounce of gold is worth roughly 74 ounces of silver.

Because both prices are in the same currency, the currency cancels out and the ratio has no unit, which makes it a compact way to compare the two metals directly. It reads like this:

  • A rising ratio means gold has gained relative to silver: either gold rose more than silver, or it fell less.
  • A falling ratio means silver has gained relative to gold.
  • The ratio says nothing about the direction of either price on its own. Both metals can fall while the ratio rises, and both can rise while it falls.

The sections below cover how to calculate the ratio correctly, why the base currency doesn't matter, and how to track and chart it with the MetalAPI REST API.

This is an educational article about how the ratio is defined and calculated. It is not financial or investment advice, and the prices in it are example values from the MetalAPI documentation, not market data.

How to calculate the gold silver ratio

The formula is a single division:

Worked example
gold/silver ratio = gold price ÷ silver price   (same currency, same unit)

3,997.89 ÷ 53.94 ≈ 74.12

silver/gold ratio = 1 ÷ 74.12 ≈ 0.0135   (ounces of gold per ounce of silver)

The division is trivial; the inputs are where mistakes happen:

  • Same unit for both metals. Divide a price per ounce by a price per ounce, or per gram by per gram. Gold per gram divided by silver per troy ounce is off by a factor of 31.1, the number of grams in a troy ounce (31.1034768).
  • Same moment. Take both prices from the same response or the same day's close. Dividing a live gold price by yesterday's silver close mixes two different market states.
  • Same kind of price. Divide a mid price by a mid price, or a close by a close. Mixing a dealer's selling price for one metal with a spot price for the other adds the dealer's spread and premium to the ratio.
  • Round at the end. Divide the unrounded prices and round the ratio only for display, usually to one or two decimals.

In a MetalAPI response, the prices are the keys prefixed with the base currency: USDXAU and USDXAG with the default base USD. The plain XAU and XAG keys are inverses (ounces per dollar). Dividing XAG by XAU gives the same ratio, but reading the prefixed keys avoids treating an inverse as a price.

Why the base currency doesn't matter

Gold and silver are usually quoted in US dollars, but the ratio is the same in every currency. With base=EUR, MetalAPI expresses both prices in euros by dividing the dollar prices by the dollar price of one euro, and that common factor cancels in the division:

text
EURXAU = USDXAU ÷ USDEUR
EURXAG = USDXAG ÷ USDEUR

EURXAU ÷ EURXAG = USDXAU ÷ USDXAG

MetalAPI calculates all cross rates from one snapshot, so base=EUR, base=INR or base=JPY give the same ratio as dollars, apart from rounding in the last of the ten significant digits. The same is true for unit: with unit=gram, both metal prices are divided by 31.1034768 and the ratio doesn't change.

Currency does matter when the two prices come from different sources or times, such as a gold price in one currency and a silver price taken hours later in another: then the exchange rate doesn't cancel exactly. Taking both prices from one response avoids that.

You can also let the API do the division. base accepts any supported symbol, metals included. With base=XAG, every price is expressed in troy ounces of silver, so XAGXAU, the price of one ounce of gold in silver, is the ratio itself:

bash
curl "https://metalapi.com/api/v1/latest?base=XAG&currencies=XAU" \
  -H "X-API-Key: $METALAPI_KEY"

In that response, the plain XAU key is the inverse: ounces of gold per ounce of silver. The rest of this article computes the ratio from the dollar prices instead, because you usually want to show or store the two prices next to it.

Get the current gold silver ratio from the API

One /latest request with currencies=XAU,XAG returns both prices from the same snapshot and counts as a single request. In Node.js 18 or later, save this as ratio.mjs and run node ratio.mjs:

ratio.mjs
const params = new URLSearchParams({ currencies: "XAU,XAG" });
const res = await fetch(`https://metalapi.com/api/v1/latest?${params}`, {
  headers: { "X-API-Key": process.env.METALAPI_KEY },
  signal: AbortSignal.timeout(10_000),
});
const data = await res.json();
if (!data.success) {
  throw new Error(`MetalAPI ${data.error.code} (${data.error.type}): ${data.error.info}`);
}

const gold = data.rates[`${data.base}XAU`];
const silver = data.rates[`${data.base}XAG`];
const ratio = gold / silver;
const asOf = new Date(data.timestamp * 1000).toISOString();

console.log(`Gold:   ${gold} ${data.base} per troy ounce`);
console.log(`Silver: ${silver} ${data.base} per troy ounce`);
console.log(`Gold/silver ratio: ${ratio.toFixed(2)} (data from ${asOf})`);

With the example prices, the last line prints a ratio of 74.12. Freshness follows your plan's update interval: daily on Free, every 30 minutes on Lite, every 10 minutes on Standard, every 60 seconds on Advanced and Pro, and down to 5 seconds on Enterprise. From Friday 17:00 to Sunday 17:00 New York time the spot market is closed and the ratio stays at Friday's close.

The ratio from /latest is a mid-price ratio. If you want the rate at which metal can actually be exchanged, use bid and ask prices, available on the Standard plan and above by adding XAU-BID, XAU-ASK, XAG-BID and XAG-ASK to currencies:

  • Selling one ounce of gold at the bid buys USDXAU-BID ÷ USDXAG-ASK ounces of silver.
  • Buying one ounce of gold with silver takes USDXAU-ASK ÷ USDXAG-BID ounces of silver.

Both numbers are less favourable than the mid ratio by the two spreads, and a dealer's own premiums come on top. Spot, bid, ask and spread explains how those quotes are built.

How to chart the gold silver ratio history

For a historical chart you need daily closes of both metals. /timeframe (alias /timeseries) returns them for a date range in one request: up to 30 days per request on the Free plan and 365 days on paid plans. Daily metal history starts in 2000, and every plan can query all of it; plans only differ in how many days one request may span.

This Python script downloads the last five years in 365-day chunks (five requests), computes the ratio for every day that has both prices, writes a CSV file, prints a few statistics and saves a chart with a 50-day moving average. On the Free plan, set MAX_DAYS = 30 and DAYS_BACK = 90, which takes three requests.

ratio_history.py
import csv
import os
import statistics
from datetime import date, datetime, timedelta, timezone

import matplotlib.pyplot as plt
import requests

API = "https://metalapi.com/api/v1"
MAX_DAYS = 365       # longest range per request: 365 on paid plans, 30 on Free
DAYS_BACK = 5 * 365  # on Free, keep this to a few months

session = requests.Session()
session.headers["X-API-Key"] = os.environ["METALAPI_KEY"]


def daily_closes(start: date, end: date) -> dict:
    """Daily closes of gold and silver from start to end (inclusive), keyed by date."""
    rates = {}
    while start <= end:
        chunk_end = min(start + timedelta(days=MAX_DAYS), end)
        r = session.get(
            f"{API}/timeframe",
            params={"start_date": start.isoformat(), "end_date": chunk_end.isoformat(), "currencies": "XAU,XAG"},
            timeout=30,
        )
        data = r.json()
        if not data["success"]:
            err = data["error"]
            raise RuntimeError(f"MetalAPI {err['code']} ({err['type']}): {err['info']}")
        rates.update(data["rates"])
        start = chunk_end + timedelta(days=1)
    return rates


end = datetime.now(timezone.utc).date() - timedelta(days=1)  # yesterday's close is final
rates = daily_closes(end - timedelta(days=DAYS_BACK), end)

rows = []
for day in sorted(rates):
    values = rates[day]
    if "USDXAU" in values and "USDXAG" in values:  # skip days that lack either metal
        gold, silver = values["USDXAU"], values["USDXAG"]
        rows.append((day, gold, silver, gold / silver))

with open("gold-silver-ratio.csv", "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(["date", "gold_usd_oz", "silver_usd_oz", "ratio"])
    writer.writerows(rows)

ratios = [r[3] for r in rows]
print(f"{len(rows)} trading days, {rows[0][0]} to {rows[-1][0]}")
print(f"latest {ratios[-1]:.2f}, min {min(ratios):.2f}, max {max(ratios):.2f}, median {statistics.median(ratios):.2f}")

window = 50
days = [date.fromisoformat(r[0]) for r in rows]
moving = [sum(ratios[i - window + 1 : i + 1]) / window for i in range(window - 1, len(ratios))]

plt.figure(figsize=(10, 4))
plt.plot(days, ratios, linewidth=1, label="Gold/silver ratio")
plt.plot(days[window - 1 :], moving, linewidth=1, label=f"{window}-day moving average")
plt.ylabel("Ounces of silver per ounce of gold")
plt.legend()
plt.tight_layout()
plt.savefig("gold-silver-ratio.png", dpi=150)

A few details are deliberate:

  • It iterates over the dates returned, not the calendar. /timeframe leaves out weekends and market holidays.
  • It ends at yesterday's UTC date. Today's bar is still moving, and a future end_date returns error 205.
  • It stores both prices next to the ratio, so you can check any row without downloading again.
  • The statistics describe only the period you downloaded. Change DAYS_BACK and they change with it.

The same series in JavaScript is one map over the rates object of a /timeframe response, for example from the range helper in the historical data guide:

javascript
// rates = the "rates" object of /timeframe?currencies=XAU,XAG
const series = Object.entries(rates)
  .filter(([, r]) => r.USDXAU && r.USDXAG)
  .sort(([a], [b]) => a.localeCompare(b))
  .map(([day, r]) => ({ day, gold: r.USDXAU, silver: r.USDXAG, ratio: r.USDXAU / r.USDXAG }));

Closing prices of past days don't change, so download a range once and top it up with a short request for the latest days. For a full backfill to 2000 (about 27 requests on a paid plan), a SQLite archive and a matplotlib chart of gold with the ratio, see Historical gold and silver prices via API.

Metal prices before October 2026 are derived from front-month futures, so they can differ slightly from spot prices on the same day. Both metals are derived the same way, but keep it in mind when you compare your series with a ratio chart from another source.

How people use the gold silver ratio

The ratio is a relative measure. It describes how gold and silver have moved against each other, not where either is heading. Common uses:

  • Relative performance. The ratio at the end of a period divided by the ratio at the start equals gold's growth factor divided by silver's. A ratio that rose 5% means gold gained 5% relative to silver over that period, whatever the two prices did in absolute terms.
  • Context on dashboards and in reports. Price trackers, dealer sites and newsletters show the ratio next to the two prices; the same /latest request supplies it at no extra cost.
  • Comparison with its own past. Some people compare the current ratio with its average, median or range over a period they choose, to describe whether it is high or low relative to that period. The script above prints those numbers for whatever range you download.
  • Swapping between metals. Some holders of physical metal exchange gold for silver, or back, when the ratio reaches a level they picked in advance. Whether that leaves them with more metal depends on the ratio later moving the way they expected, which nothing guarantees, and every swap pays the dealer spreads and premiums described above.
  • Other ratios. The same division works for any two prices in one currency: gold to platinum (USDXAU ÷ USDXPT), or gold to oil (USDXAU ÷ USDWTI, barrels of oil per ounce of gold). For cross-asset ratios leave unit at its default, because unit changes metal prices but not energy prices.

None of these uses is a forecast. The ratio has no fixed normal level it has to return to, and a high or low reading is not, by itself, a reason to buy or sell either metal. If you are making investment decisions, talk to a qualified financial adviser.

Track the gold silver ratio in your app

Create a free account to get an API key. The Free plan's 100 requests a month, daily prices and 30-day ranges are enough for a daily ratio and a few months of history. Paid plans add fresher prices, 365-day ranges for long backfills and bid/ask prices from Standard up; compare them on the pricing page. For silver prices on their own, see the silver price API guide.

FAQ

What does a gold silver ratio of 74 mean?

It means one troy ounce of gold costs as much as about 74 troy ounces of silver at the prices used. It describes the relative price of the two metals only. It doesn't tell you whether either metal is expensive or cheap in any absolute sense.

Is the gold silver ratio the same in every currency and unit?

Yes, as long as both prices come from the same moment and are for the same weight, because currency and unit cancel in the division. MetalAPI derives all currencies and units from one snapshot, so any base and unit give the same ratio, apart from tiny rounding differences.

How often does the gold silver ratio change?

Whenever either price moves, which is continuously while the markets are open. Through the API you see it at your plan's update interval, from daily on Free to every 5 seconds on Enterprise. It stays at Friday's value over the weekend.

How far back can I calculate the ratio?

Daily closes for gold and silver go back to 2000 on every plan. A single /timeframe request covers up to 30 days on Free and 365 days on paid plans, so the complete history takes about 27 requests on a paid plan. Prices before October 2026 are derived from front-month futures.

Is a high gold silver ratio a signal to buy silver?

This article doesn't give investment advice. A high ratio only means gold is expensive relative to silver compared with whatever period you are comparing against. It doesn't predict how either price, or the ratio, will move next.

Try it with your own data

Create a free account and make your first request in under two minutes. 100 requests a month, no credit card.

Keep reading