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,329.75−0.55%ETH2,329.36−1.13%
全部文章
黄金白银单位

金衡盎司、克与千克:正确换算贵金属价格

详解金衡盎司与常衡盎司的区别、精确的克与千克换算系数、API 的 unit 参数和取整规则,以及会让金属价格偏差近 10% 的常见错误。

作者:MetalAPI Team··阅读约 9 分钟

为什么单位很重要

几乎在任何地方,贵金属都以金衡盎司报价:批发市场、金银条交易商的价目表以及价格 API 都是如此。而买卖金属的人则根据所在地区和交易品种,习惯使用克、千克、托拉(tola)或两(tael)。因此,任何向用户展示金属价格的产品都至少包含一次单位换算,而这种换算常常是一些悄无声息、看似合理的错误的根源。

最典型的错误是把金衡盎司当作普通盎司。两者相差近 10%,这个差距大到足以影响每一张发票,却又小到在演示中没人察觉。本文将介绍精确的定义、换算系数、如何让 API 替您完成换算、如何对结果取整和展示,并列出一份值得编写测试的错误清单。

金衡盎司与常衡盎司

两种盎司都以格令(grain)定义,而格令有精确的公制定义:1 格令 = 64.79891 毫克。其他一切都由此推出:

  • 金衡盎司为 480 格令,恰好等于 31.1034768 克。黄金、白银、铂金和钯金都以它计价。
  • 常衡盎司是美国和英国日常用于食品和包裹的盎司,为 437.5 格令,恰好等于 28.349523125 克。
  • 金衡磅为 12 金衡盎司(373.2417216 克),而常衡磅为 16 常衡盎司(453.59237 克)。因此,金衡盎司是较重的盎司,金衡磅却是较轻的磅。
单位格令克(精确值)金衡盎司
格令10.064798910.0020833…
英钱(dwt)241.555173840.05
常衡盎司437.528.3495231250.9114583…
金衡盎司48031.10347681
金衡磅5,760373.241721612
常衡磅7,000453.5923714.5833…

金衡盎司比常衡盎司重约 9.7%(480 ÷ 437.5 ≈ 1.0971)。混淆两者时产生的误差恰好就是这个比例。

除非来源另有说明,贵金属价格中的盎司都是指金衡盎司,常写作 oz t 或 ozt。在 MetalAPI 中,默认单位为 troy_oz,除非您另行指定,所有金属价格都以金衡盎司计。

精确的换算系数

由于这些单位都有精确定义,换算时无需任何近似。要将每金衡盎司的价格换算为另一单位的价格,只需乘以该单位所含的金衡盎司数:

每单位价格 = 每金衡盎司价格 × 每单位克数 ÷ 31.1034768

计价单位每单位克数金衡盎司价格乘以
克10.0321507466
千克1,00032.1507466
常衡盎司28.3495231250.9114583333
常衡磅453.5923714.5833333
公吨1,000,00032,150.7466
短吨(2,000 磅)907,184.7429,166.6667
托拉11.66380380.375
英钱1.555173840.05

托拉(tola)在南亚和海湾地区仍被广泛用于黄金交易,其定义为 180 格令,恰好等于 11.6638038 克,即八分之三金衡盎司。两(tael)则没那么规整,因为它的重量取决于市场:香港黄金交易中约为 37.4 克,台湾为 37.5 克,中国大陆为 50 克。如果您支持以“两”计价,请将其克重设为可配置项,并标明所指的是哪一种“两”。

千克金条是一个便捷的合理性检查。1 千克约等于 32.15 金衡盎司,因此千克价格应始终约为盎司价格的 32 倍。如果接近 35 倍,说明有人用了常衡盎司的系数。

手动换算

如果您已经有每金衡盎司的价格,自行换算只需一次乘法。请将精确常数集中放在一个模块中,并统一以克为中间单位进行换算,这样任意两种单位之间的换算方式都相同:

units.mjs
// 每种单位所含的克数,均为精确值:1 格令 = 64.79891 毫克。
const GRAMS_PER_UNIT = {
  troy_oz: 31.1034768, // 480 格令
  gram: 1,
  kilogram: 1000,
  ounce: 28.349523125, // 常衡,437.5 格令
  pound: 453.59237, // 常衡,7,000 格令
  metric_ton: 1_000_000,
  short_ton: 907_184.74, // 2,000 磅
  tola: 11.6638038, // 180 格令
  pennyweight: 1.55517384, // 24 格令
};

/** 将每 `from` 单位的价格换算为每 `to` 单位的价格。 */
export function convertPrice(price, from, to) {
  const a = GRAMS_PER_UNIT[from];
  const b = GRAMS_PER_UNIT[to];
  if (a === undefined || b === undefined) throw new Error(`Unknown unit: ${a === undefined ? from : to}`);
  return (price / a) * b;
}

console.log(convertPrice(3997.89, "troy_oz", "gram")); // 128.535148…
console.log(convertPrice(3997.89, "troy_oz", "kilogram")); // 128535.148…
console.log(convertPrice(3997.89, "troy_oz", "tola")); // 1499.20875

在 Python 中,如果结果要写入发票或账簿,请使用 Decimal。requests 会将 parse_float 传递给 JSON 解析器,因此价格永远不会经过二进制浮点数:

per_gram.py
import os
from decimal import Decimal, ROUND_HALF_UP

import requests

GRAMS_PER_TROY_OZ = Decimal("31.1034768")
CENT = Decimal("0.01")

r = requests.get(
    "https://metalapi.com/api/v1/latest",
    params={"currencies": "XAU"},
    headers={"X-API-Key": os.environ["METALAPI_KEY"]},
    timeout=10,
)
data = r.json(parse_float=Decimal)
if not data["success"]:
    raise RuntimeError(data["error"])

per_oz = data["rates"]["USDXAU"]  # 例如 Decimal("3997.89")
per_gram = per_oz / GRAMS_PER_TROY_OZ
per_kg = per_gram * 1000

print(per_gram.quantize(CENT, rounding=ROUND_HALF_UP))  # 按示例价格为 128.54
print(per_kg.quantize(CENT, rounding=ROUND_HALF_UP))  # 128535.15

倒数汇率需要相反的运算。rates.XAU 是 1 单位基础货币可买到的金衡盎司数,因此每单位货币可买到的克数是 rates.XAU × 31.1034768,而不是 ÷。这个陷阱也是应当使用 USDXAU 等带前缀的价格键、不去碰倒数键的又一个理由。

让 API 来换算:unit 参数

您也可以直接向 MetalAPI 请求所需的单位。/latest、历史端点、/timeframe、/ohlc、/convert 和 /carat 都接受 unit 参数:troy_oz(默认)、gram、kilogram、ounce、pound、metric_ton 或 short_ton。下面的请求返回以欧元/克计的黄金和白银价格:

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

当单位不是默认值时,响应会在顶层的 unit 字段中重复该单位。以下数值是文档中的示例,并非实时价格:

响应示例
{
  "success": true,
  "timestamp": 1792765800,
  "date": "2026-10-23",
  "base": "EUR",
  "unit": "gram",
  "rates": {
    "XAU": 0.009057444725,
    "EURXAU": 110.4064149,
    "XAG": 0.6713138244,
    "EURXAG": 1.489616277
  }
}

API 使用与上表相同的精确系数,倒数键也会随单位变化:使用 unit=gram 时,rates.XAU 表示 1 欧元可买到的黄金克数。以下几条规则值得了解:

  • 接受 g、kg、lb 和 tonne 等简写。oz 表示常衡盎司,因此切勿将其用作金衡盎司的简写。
  • 未知单位会返回错误 209(invalid_unit)。
  • unit 仅适用于贵金属和工业金属。能源仍按桶、MMBtu 或加仑计价,货币和加密货币不受影响,因此在一次请求中混合多种品种是安全的。
  • 工业金属默认同样以金衡盎司报价,因此所有金属可以直接比较。铜请传入 unit=pound,铝和锌请传入 unit=metric_ton,钢材请传入 unit=short_ton,即可获得这些市场交易时使用的单位。

/convert 同样接受 unit,一步即可将重量换算为金额。下面的请求计算 250 克黄金的美元价值:

计算 250 克黄金的价值
curl "https://metalapi.com/api/v1/convert?from=XAU&to=USD&amount=250&unit=gram" \
  -H "X-API-Key: $METALAPI_KEY"

info.rate 是 1 克黄金的美元价格,result 是全部数量的价值。按示例金价,响应如下:

响应示例
{
  "success": true,
  "query": { "from": "XAU", "to": "USD", "amount": 250, "unit": "gram" },
  "info": { "timestamp": 1792834892, "rate": 128.5351482, "quote": 128.5351482 },
  "date": "2026-10-24",
  "result": 32133.78705
}

取整与展示

汇率以 JSON 数字返回,最多 10 位有效数字。保留这样的精度是为了让派生数值保持准确,因此请尽可能晚地取整:

  • 先换算,后取整。如果先将每克价格取整到分,再乘以 1,000 得到千克金条的价格,半分的取整误差就会变成最多 5 个货币单位的误差。
  • 按货币取整。大多数货币使用两位小数,日元没有小数,科威特第纳尔则使用三位小数。请让 Intl.NumberFormat 或您所用的本地化库来选择默认位数,而不要写死两位。
  • 为低价品种保留更多位数。按每金衡盎司 53.94 美元的示例价格,白银每克约 1.73 美元,只保留两位小数会掩盖其大部分日常波动。
  • 金额使用十进制类型。凡是需要开票或记账的内容,请在 Python 中使用 Decimal,在 Java 中使用 BigDecimal,或在数据库中使用以最小货币单位计的整数。图表使用二进制浮点数则没有问题。
  • 标注单位。在每个价格旁边注明“每金衡盎司”“每克”或“每千克”。仅写“每盎司”,对许多读者来说含义不明。

下面这个小辅助函数从 Intl 获取货币的标准小数位数,并可选择额外增加几位:

format.mjs
function formatPrice(value, currency, locale = "en-US", extraDigits = 0) {
  const { maximumFractionDigits } = new Intl.NumberFormat(locale, { style: "currency", currency }).resolvedOptions();
  const digits = maximumFractionDigits + extraDigits;
  return new Intl.NumberFormat(locale, {
    style: "currency",
    currency,
    minimumFractionDigits: digits,
    maximumFractionDigits: digits,
  }).format(value);
}

formatPrice(128.53514819925212, "USD"); // "$128.54"   每克黄金
formatPrice(1.7342112699117933, "USD", "en-US", 2); // "$1.7342"   每克白银
formatPrice(110.4064149, "EUR", "de-DE"); // "110,41 €"

换算速查表

下表换算的是 MetalAPI 文档中使用的示例价格:黄金每金衡盎司 3,997.89 美元,白银每金衡盎司 53.94 美元。它们用于说明计算过程,并非当前市场价格:

计价单位黄金(美元)白银(美元)
金衡盎司3,997.8953.94
克128.541.7342
千克128,535.151,734.21
托拉(11.6638 克)1,499.2120.23
英钱(1.5552 克)199.892.697
金衡磅(12 oz t)47,974.68647.28
常衡盎司3,643.9149.16

请看最后一行。如果页面把常衡盎司的数字标为盎司价格,就会把金银条价格低估近 9%。反过来的错误,即用金衡盎司价格除以 28.35 来得到每克价格,则会高估约 9.7%:每克黄金显示为 141.02,而不是 128.54。

常见换算错误及其测试方法

大多数单位错误可以归为以下几种模式:

  • 除以 28.35。对金衡盎司价格使用了常衡盎司的系数。请使用 31.1034768。
  • 把 `oz` 当作金衡盎司。在 MetalAPI 中,和大多数单位库一样,oz 表示常衡盎司。金银条价格需要使用 troy_oz,或者干脆不传 unit。
  • 换算倒数键。rates.XAU 是每单位货币可买到的盎司数,而不是价格。将其换算为克需要乘以 31.1034768,这在习惯做除法的人看来像是写错了。
  • 重复换算。请求 unit=gram 后又除以一次 31.1034768,得到的价格会小约 31 倍。请确定换算是在 API 中完成还是在您的代码中完成,切勿两处都做。
  • 过早取整。只在展示时取整一次。
  • 跨单位缓存。如果缓存键忽略了查询字符串,本应返回盎司价格的地方可能会拿到每克价格的响应。请将 unit 和 base 纳入缓存键。
  • 对能源套用重量单位。unit 对原油和天然气无效,而用桶价除以 31.1 毫无意义。请按类别限制换算,/symbols?details=1 会返回每个品种的类别。

几个属性测试就能在上线前发现其中大部分问题。它们使用 Node 内置的测试运行器和上文的 convertPrice 函数,可通过 node --test 运行:

units.test.mjs
import { test } from "node:test";
import assert from "node:assert/strict";
import { convertPrice } from "./units.mjs";

const PER_OZ = 3997.89; // 示例价格,美元/金衡盎司

test("a kilogram price is 1,000 gram prices", () => {
  const g = convertPrice(PER_OZ, "troy_oz", "gram");
  const kg = convertPrice(PER_OZ, "troy_oz", "kilogram");
  assert.ok(Math.abs(kg - g * 1000) < 1e-6);
});

test("converting there and back returns the original price", () => {
  const g = convertPrice(PER_OZ, "troy_oz", "gram");
  assert.ok(Math.abs(convertPrice(g, "gram", "troy_oz") - PER_OZ) < 1e-9);
});

test("an avoirdupois ounce costs less than a troy ounce", () => {
  assert.ok(convertPrice(PER_OZ, "troy_oz", "ounce") < PER_OZ);
});

test("a kilogram holds about 32.15 troy ounces", () => {
  const kg = convertPrice(PER_OZ, "troy_oz", "kilogram");
  assert.ok(Math.abs(kg / PER_OZ - 32.1507466) < 1e-6);
});

如果您为首饰定价,下一步就是纯度:K 金价格详解在这些换算的基础上计算 22K 和 18K 金价。数据格式指南和 API 文档的单位部分列出了所有单位取值,品种页面则显示了各市场交易所用的单位。

用您自己的数据试一试

创建免费账户,两分钟内即可发起第一次请求。每月 100 次请求,无需信用卡。

继续阅读