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%
Todos os artigos
OuroPrataUnidades

Onças troy, gramas e quilogramas: como converter preços de metais preciosos corretamente

Onça troy vs. onça avoirdupois, fatores exatos para grama e quilo, o parâmetro unit da API, regras de arredondamento e os bugs que erram preços em quase 10%.

Por MetalAPI Team··9 min de leitura

Por que a unidade importa

Os metais preciosos são cotados por onça troy em quase todo lugar: nos mercados atacadistas, nas tabelas de preços dos revendedores de barras e moedas e nas APIs de preços. Já as pessoas que compram e vendem metal pensam em gramas, quilogramas, tolas ou taéis, dependendo de onde vivem e do que negociam. Por isso, qualquer produto que mostre um preço de metal para pessoas contém pelo menos uma conversão de unidade, e essa conversão é uma fonte comum de erros silenciosos e de aparência plausível.

O erro clássico é tratar uma onça troy como uma onça comum. As duas diferem em quase 10%, o suficiente para fazer diferença em cada nota fiscal, mas pouco o bastante para ninguém perceber em uma demonstração. Este artigo aborda as definições exatas, os fatores de conversão, como deixar a API converter para você, como arredondar e exibir os resultados, e uma lista de bugs que merecem testes.

Onça troy vs. onça avoirdupois

As duas onças são definidas em grãos, e o grão tem uma definição métrica exata: 1 grão = 64,79891 miligramas. Todo o resto decorre disso:

  • Uma onça troy tem 480 grãos, exatamente 31,1034768 gramas. É a unidade em que ouro, prata, platina e paládio são cotados.
  • Uma onça avoirdupois, a onça do dia a dia para alimentos e encomendas nos EUA e no Reino Unido, tem 437,5 grãos, exatamente 28,349523125 gramas.
  • Uma libra troy tem 12 onças troy (373,2417216 g), enquanto a libra avoirdupois tem 16 onças avoirdupois (453,59237 g). Ou seja, a onça troy é a onça mais pesada, mas a libra troy é a libra mais leve.
UnidadeGrãosGramas (exato)Onças troy
Grão10,064798910,0020833…
Pennyweight (dwt)241,555173840,05
Onça avoirdupois437,528,3495231250,9114583…
Onça troy48031,10347681
Libra troy5.760373,241721612
Libra avoirdupois7.000453,5923714,5833…

Uma onça troy é cerca de 9,7% mais pesada que uma onça avoirdupois (480 ÷ 437,5 ≈ 1,0971). Essa razão é exatamente o tamanho do erro que você comete quando as duas são confundidas.

A menos que a fonte diga o contrário, a onça de um preço de metal precioso é uma onça troy, muitas vezes escrita oz t ou ozt. Na MetalAPI, a unidade padrão é troy_oz, e todo preço de metal é por onça troy, a menos que você peça outra coisa.

Fatores de conversão exatos

Como todas essas unidades têm definição exata, as conversões não precisam de aproximações. Para transformar um preço por onça troy em um preço por outra unidade, multiplique pelo número de onças troy que cabem nessa unidade:

preço por unidade = preço por onça troy × gramas por unidade ÷ 31,1034768

Preço porGramas em uma unidadeMultiplique o preço da onça troy por
Grama10,0321507466
Quilograma1.00032,1507466
Onça avoirdupois28,3495231250,9114583333
Libra avoirdupois453,5923714,5833333
Tonelada métrica1.000.00032.150,7466
Tonelada curta (2.000 lb)907.184,7429.166,6667
Tola11,66380380,375
Pennyweight1,555173840,05

A tola, ainda muito usada para o ouro no Sul da Ásia e no Golfo, é definida como 180 grãos: exatamente 11,6638038 g, ou três oitavos de uma onça troy. O tael é menos organizado, porque o seu peso depende do mercado: cerca de 37,4 g no comércio de ouro de Hong Kong, 37,5 g em Taiwan e 50 g na China continental. Se você oferece suporte a taéis, torne o peso em gramas um valor de configuração e indique a qual tael você se refere.

As barras de um quilo são um bom teste de sanidade. Um quilograma tem cerca de 32,15 onças troy, então o preço do quilo deve ser sempre aproximadamente 32 vezes o preço da onça. Se estiver mais perto de 35 vezes, alguém usou o fator avoirdupois.

Convertendo manualmente

Se você já tem um preço por onça troy, convertê-lo por conta própria é uma única multiplicação. Mantenha as constantes exatas em um único módulo e converta passando pelos gramas, para que todos os pares de unidades funcionem da mesma forma:

units.mjs
// Gramas em uma unidade de cada tipo. Todos exatos: 1 grão = 64.79891 mg.
const GRAMS_PER_UNIT = {
  troy_oz: 31.1034768, // 480 grãos
  gram: 1,
  kilogram: 1000,
  ounce: 28.349523125, // avoirdupois, 437.5 grãos
  pound: 453.59237, // avoirdupois, 7,000 grãos
  metric_ton: 1_000_000,
  short_ton: 907_184.74, // 2,000 lb
  tola: 11.6638038, // 180 grãos
  pennyweight: 1.55517384, // 24 grãos
};

/** Converte um preço por unidade `from` em um preço por unidade `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

Em Python, use Decimal quando o resultado for parar em uma nota fiscal ou em um livro contábil. O requests repassa parse_float ao parser de JSON, então os preços nunca passam por um float binário:

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"]  # p. ex. 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 com o preço de exemplo
print(per_kg.quantize(CENT, rounding=ROUND_HALF_UP))  # 128535.15

As cotações inversas exigem a operação oposta. rates.XAU é a quantidade de onças troy por uma unidade da moeda base, então os gramas por unidade de moeda são rates.XAU × 31,1034768, e não ÷. Essa armadilha é mais um motivo para trabalhar com as chaves de preço com prefixo, como USDXAU, e deixar as chaves inversas de lado.

Deixando a API converter: o parâmetro unit

Você também pode pedir à MetalAPI a unidade de que precisa. /latest, os endpoints históricos, /timeframe, /ohlc, /convert e /carat aceitam um parâmetro unit: troy_oz (padrão), gram, kilogram, ounce, pound, metric_ton ou short_ton. Esta requisição retorna ouro e prata em euros por grama:

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

Quando a unidade não é a padrão, a resposta a repete em um campo unit no nível superior. Os valores abaixo são um exemplo da documentação, não preços ao vivo:

Exemplo de resposta
{
  "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
  }
}

A API usa os mesmos fatores exatos das tabelas acima, e a chave inversa também acompanha a unidade: com unit=gram, rates.XAU é a quantidade de gramas de ouro por euro. Algumas regras que vale a pena conhecer:

  • Formas curtas são aceitas, como g, kg, lb e tonne. oz significa a onça avoirdupois, então nunca o use como abreviação de onça troy.
  • Uma unidade desconhecida retorna o erro 209 (invalid_unit).
  • unit se aplica apenas aos metais preciosos e industriais. A energia continua por barril, MMBtu ou galão, e moedas e cripto não são afetadas, então misturar símbolos em uma mesma requisição é seguro.
  • Os metais industriais também são cotados por onça troy por padrão, para que todos os metais possam ser comparados diretamente. Passe unit=pound para o cobre, unit=metric_ton para o alumínio e o zinco, e unit=short_ton para o aço para obter as unidades em que esses mercados negociam.

/convert também aceita unit, o que transforma um peso em dinheiro em um único passo. Isto avalia 250 gramas de ouro em dólares americanos:

Valor de 250 g de ouro
curl "https://metalapi.com/api/v1/convert?from=XAU&to=USD&amount=250&unit=gram" \
  -H "X-API-Key: $METALAPI_KEY"

info.rate é o preço de um grama em dólares americanos e result é o valor da quantidade inteira. Com o preço do ouro de exemplo, a resposta fica assim:

Exemplo de resposta
{
  "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
}

Arredondamento e exibição

As cotações chegam como números JSON com até 10 algarismos significativos. Essa precisão existe para que os valores derivados continuem exatos, então mantenha-a até o último momento possível:

  • Converta primeiro, arredonde por último. Arredondar o preço do grama para centavos e depois multiplicar por 1.000 para uma barra de um quilo transforma um erro de arredondamento de meio centavo em um erro de até cinco unidades da moeda.
  • Arredonde conforme a moeda. A maioria das moedas usa duas casas decimais, o iene japonês nenhuma e o dinar kuwaitiano três. Deixe o Intl.NumberFormat ou a sua biblioteca de localização escolher os padrões em vez de fixar duas casas no código.
  • Permita dígitos extras para preços pequenos. Com o preço de exemplo de 53,94 USD por onça troy, a prata custa cerca de 1,73 USD por grama, e duas casas decimais escondem a maior parte da sua variação diária.
  • Use tipos decimais para dinheiro. Decimal em Python, BigDecimal em Java, ou unidades menores inteiras (centavos) no seu banco de dados para tudo o que for faturado ou contabilizado. Floats binários servem bem para gráficos.
  • Identifique a unidade. Coloque por onça troy, por grama ou por kg ao lado de cada preço. Um simples “por onça” é ambíguo para muitos leitores.

Um pequeno helper que obtém do Intl as casas decimais padrão da moeda e, opcionalmente, acrescenta algumas:

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"   ouro por grama
formatPrice(1.7342112699117933, "USD", "en-US", 2); // "$1.7342"   prata por grama
formatPrice(110.4064149, "EUR", "de-DE"); // "110,41 €"

Uma tabela de conversão rápida

A tabela converte os preços de exemplo usados na documentação da MetalAPI: 3.997,89 USD por onça troy para o ouro e 53,94 USD por onça troy para a prata. Eles ilustram a aritmética e não são preços de mercado atuais:

Preço porOuro (USD)Prata (USD)
Onça troy3.997,8953,94
Grama128,541,7342
Quilograma128.535,151.734,21
Tola (11,6638 g)1.499,2120,23
Pennyweight (1,5552 g)199,892,697
Libra troy (12 oz t)47.974,68647,28
Onça avoirdupois3.643,9149,16

Observe a última linha. Se uma página identifica o valor avoirdupois como o preço da onça, ela subestima o preço do metal em quase 9%. O erro inverso, dividir um preço por onça troy por 28,35 para obter o preço do grama, superestima o valor em cerca de 9,7%: 141,02 em vez de 128,54 por grama de ouro.

Bugs comuns de conversão e como testá-los

A maioria dos bugs de unidade se encaixa em alguns poucos padrões:

  • Dividir por 28,35. Usar o fator avoirdupois para um preço por onça troy. Use 31,1034768.
  • Tratar `oz` como troy. Na MetalAPI, como na maioria das bibliotecas de unidades, oz é a onça avoirdupois. Preços de metais preciosos precisam de troy_oz, ou de nenhum unit.
  • Converter a chave inversa. rates.XAU é a quantidade de onças por unidade de moeda, não um preço. Convertê-la para gramas significa multiplicar por 31,1034768, o que parece errado para quem está acostumado a dividir.
  • Converter duas vezes. Pedir unit=gram e depois dividir de novo por 31,1034768 resulta em um preço cerca de 31 vezes menor. Decida se a conversão acontece na API ou no seu código, nunca nos dois.
  • Arredondar cedo demais. Arredonde uma única vez, na hora de exibir.
  • Cache misturando unidades. Se a sua chave de cache ignora a query string, uma resposta por grama pode ser servida onde se esperava um preço por onça. Inclua unit e base na chave.
  • Aplicar unidades de peso à energia. unit não tem efeito sobre petróleo ou gás, e dividir um preço por barril por 31,1 não faz sentido. Proteja as conversões por categoria, que /symbols?details=1 retorna para cada símbolo.

Alguns testes de propriedades pegam a maioria desses bugs antes que cheguem à produção. Eles usam o executor de testes nativo do Node e a função convertPrice acima; execute-os com 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; // preço de exemplo, USD por onça troy

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);
});

Se você precifica joias, o próximo passo é o teor: Preços do ouro por quilate explicados monta os preços de 22K e 18K sobre essas conversões. O guia de formatos de dados e a seção de unidades da documentação da API documentam todos os valores de unidade, e a página de símbolos mostra a unidade em que cada mercado negocia.

Experimente com seus próprios dados

Crie uma conta grátis e faça sua primeira requisição em menos de dois minutos. 100 requisições por mês, sem cartão de crédito.

Continue lendo