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‎%‎
جميع المقالات
الذهبالفضةالوحدات

أونصة التروي والغرام والكيلوغرام: كيف تحوّل أسعار المعادن الثمينة بشكل صحيح

أونصة التروي مقابل أونصة الأفوارديبوا، ومعاملات الغرام والكيلوغرام الدقيقة، ومعامل unit في الواجهة، وقواعد التقريب، والأخطاء التي تحرف أسعار المعادن بنحو 10%.

بقلم MetalAPI Team··وقت القراءة: 9 دقيقة

لماذا تهم الوحدة

تُسعَّر المعادن الثمينة بأونصة التروي في كل مكان تقريبًا: في أسواق الجملة، وفي قوائم أسعار تجار السبائك، وفي واجهات API للأسعار. أما من يشترون المعادن ويبيعونها فيفكرون بالغرام أو الكيلوغرام أو التولة أو التايل، بحسب مكان إقامتهم وما يتداولونه. لذا فإن أي منتج يعرض سعر معدن على الناس يتضمن تحويلًا واحدًا على الأقل بين الوحدات، وهذا التحويل مصدر شائع لأخطاء صامتة تبدو معقولة.

الخطأ الكلاسيكي هو معاملة أونصة التروي على أنها أونصة عادية. فالفرق بينهما يقارب 10%، وهو كبير بما يكفي ليؤثر في كل فاتورة، لكنه صغير بما يكفي كي لا يلاحظه أحد في عرض تجريبي. تتناول هذه المقالة التعريفات الدقيقة، ومعاملات التحويل، وكيف تدع الواجهة تُجري التحويل نيابةً عنك، وكيف تقرّب النتائج وتعرضها، إضافةً إلى قائمة بالأخطاء التي تستحق كتابة اختبارات لها.

أونصة التروي مقابل أونصة الأفوارديبوا

تُعرَّف الأونصتان كلتاهما بالقمحة (grain)، وللقمحة تعريف متري دقيق: 1 قمحة = 64.79891 ملليغرام. وكل ما عدا ذلك ينتج من هذا التعريف:

  • أونصة التروي تساوي 480 قمحة، أي 31.1034768 غرامًا بالضبط. وهي الوحدة التي يُسعَّر بها الذهب والفضة والبلاتين والبلاديوم.
  • أونصة الأفوارديبوا، وهي الأونصة المستخدمة يوميًا للأغذية والطرود في الولايات المتحدة والمملكة المتحدة، تساوي 437.5 قمحة، أي 28.349523125 غرامًا بالضبط.
  • رطل التروي يضم 12 أونصة تروي (373.2417216 غرامًا)، بينما يضم رطل الأفوارديبوا 16 أونصة أفوارديبوا (453.59237 غرامًا). لذا فإن أونصة التروي هي الأونصة الأثقل، لكن رطل التروي هو الرطل الأخف.
الوحدةالقمحاتالغرامات (بدقة)أونصات التروي
القمحة (Grain)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

التولة، التي لا تزال شائعة الاستخدام للذهب في جنوب آسيا والخليج، تُعرَّف بأنها 180 قمحة: أي 11.6638038 غرامًا بالضبط، أو ثلاثة أثمان أونصة التروي. أما التايل فأقل انتظامًا، لأن وزنه يعتمد على السوق: نحو 37.4 غرامًا في تجارة الذهب في هونغ كونغ، و37.5 غرامًا في تايوان، و50 غرامًا في البر الرئيسي للصين. وإذا كنت تدعم التايل، فاجعل وزنه بالغرام قيمة قابلة للضبط في الإعدادات ووضّح أي تايل تقصد.

سبائك الكيلوغرام وسيلة سهلة للتحقق من معقولية الأرقام. فالكيلوغرام يساوي نحو 32.15 أونصة تروي، لذا يجب أن يكون سعر الكيلو دائمًا نحو 32 ضعف سعر الأونصة. فإذا كان أقرب إلى 35 ضعفًا، فقد استخدم أحدهم معامل الأفوارديبوا.

التحويل يدويًا

إذا كان لديك سعر لكل أونصة تروي، فتحويله بنفسك عملية ضرب واحدة. احتفظ بالثوابت الدقيقة في وحدة برمجية واحدة وحوّل عبر الغرامات، حتى يعمل كل زوج من الوحدات بالطريقة نفسها:

units.mjs
// Grams in one of each unit. All exact: 1 grain = 64.79891 mg.
const GRAMS_PER_UNIT = {
  troy_oz: 31.1034768, // 480 grains
  gram: 1,
  kilogram: 1000,
  ounce: 28.349523125, // avoirdupois, 437.5 grains
  pound: 453.59237, // avoirdupois, 7,000 grains
  metric_ton: 1_000_000,
  short_ton: 907_184.74, // 2,000 lb
  tola: 11.6638038, // 180 grains
  pennyweight: 1.55517384, // 24 grains
};

/** Convert a price per `from` unit into a price per `to` unit. */
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"]  # e.g. 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 at the example price
print(per_kg.quantize(CENT, rounding=ROUND_HALF_UP))  # 128535.15

الأسعار المقلوبة تحتاج إلى العملية المعاكسة. فـ rates.XAU هو عدد أونصات التروي لكل وحدة واحدة من عملة الأساس، لذا فإن عدد الغرامات لكل وحدة عملة هو rates.XAU × 31.1034768، لا ÷. وهذا الفخ سبب إضافي للعمل بمفاتيح الأسعار ذات البادئة مثل USDXAU وترك المفاتيح المقلوبة جانبًا.

دع الواجهة تُجري التحويل: المعامل 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
  }
}

تستخدم الواجهة المعاملات الدقيقة نفسها الواردة في الجداول أعلاه، ويتبع المفتاح المقلوب الوحدة أيضًا: فمع unit=gram يكون rates.XAU عدد غرامات الذهب لكل يورو. وإليك بعض القواعد التي تستحق المعرفة:

  • تُقبل الصيغ المختصرة، مثل 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 هو سعر غرام واحد بالدولار الأمريكي، و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 لسبيكة الكيلو يحوّل خطأ تقريب قدره نصف سنت إلى خطأ يصل إلى خمس وحدات من العملة.
  • قرّب حسب العملة. تستخدم معظم العملات منزلتين عشريتين، والين الياباني لا يستخدم أي منزلة، والدينار الكويتي ثلاث منازل. دع Intl.NumberFormat أو مكتبة الإعدادات المحلية لديك تختار القيم الافتراضية بدلًا من تثبيت منزلتين في الشيفرة.
  • اسمح بأرقام إضافية للأسعار الصغيرة. بالسعر النموذجي البالغ 53.94 دولارًا أمريكيًا لأونصة التروي، يكلّف غرام الفضة نحو 1.73 دولار، والمنزلتان العشريتان تُخفيان معظم حركته اليومية.
  • استخدم الأنواع العشرية للمبالغ المالية. Decimal في Python، وBigDecimal في Java، أو الوحدات الصغرى الصحيحة في قاعدة بياناتك لكل ما يُفوتَر أو يُقيَّد محاسبيًا. أما أعداد الفاصلة العائمة الثنائية فلا بأس بها في الرسوم البيانية.
  • سمِّ الوحدة. ضع «لكل أونصة تروي» أو «لكل غرام» أو «لكل كغ» بجوار كل سعر. فعبارة «لكل أونصة» وحدها ملتبسة لدى كثير من القراء.

إليك دالة مساعدة صغيرة تأخذ المنازل العشرية القياسية للعملة من 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"   gold per gram
formatPrice(1.7342112699117933, "USD", "en-US", 2); // "$1.7342"   silver per gram
formatPrice(110.4064149, "EUR", "de-DE"); // "110,41 €"

جدول تحويل في لمحة

يحوّل الجدول الأسعار النموذجية المستخدمة في توثيق MetalAPI، وهي 3,997.89 دولارًا أمريكيًا لأونصة التروي من الذهب و53.94 دولارًا أمريكيًا لأونصة التروي من الفضة. وهي توضّح العمليات الحسابية وليست أسعار السوق الحالية:

السعر لكلالذهب (USD)الفضة (USD)
أونصة تروي3,997.8953.94
غرام128.541.7342
كيلوغرام128,535.151,734.21
تولة (11.6638 غ)1,499.2120.23
بنيويت (1.5552 غ)199.892.697
رطل تروي (12 أونصة تروي)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 مرة. قرّر هل يجري التحويل في الواجهة أم في شيفرتك، ولا تجمع بينهما أبدًا.
  • التقريب المبكر. قرّب مرة واحدة، عند العرض.
  • التخزين المؤقت عبر الوحدات. إذا كان مفتاح التخزين المؤقت لديك يتجاهل سلسلة الاستعلام، فقد تُقدَّم استجابة بالغرام حيث يُتوقع سعر بالأونصة. ضمّن 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; // example price, USD per troy ounce

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

إذا كنت تسعّر المجوهرات، فالخطوة التالية هي النقاء: يبني مقال شرح أسعار الذهب حسب العيار أسعار عيار 22 وعيار 18 على أساس هذه التحويلات. ويوثّق دليل صيغ البيانات وقسم الوحدات في توثيق API جميع قيم الوحدات، وتعرض صفحة الرموز الوحدة التي تُتداول بها كل سوق.

جرّبه مع بياناتك الخاصة

أنشئ حسابًا مجانيًا وأرسل طلبك الأول في أقل من دقيقتين. 100 طلب شهريًا، دون بطاقة ائتمان.

تابع القراءة