ราคา DEX OHLC และ VWAP รายวันสำหรับโทเค็น พร้อมเศษส่วนแม่นยำสูง
คิวรีราคา DEX OHLC และ VWAP รายวันจาก Data API, จัดการเศษส่วนตรรกยะที่แม่นยำใน TypeScript และ Python ตลอดจนดึงข้อมูลย้อนหลังอย่างมีประสิทธิภาพ
ชุดข้อมูลราคา DEX รายวันคืออะไร
ชุดข้อมูล DEX ของ BlockVectra ทำดัชนีกิจกรรมการซื้อขายบนกระเป๋าเงินและตลาดซื้อขายแบบกระจายศูนย์ (DEX) และคำนวณเมตริกราคาแบบสรุปรายวัน endpoint ราคา DEX รายวัน (getDexPrices) ให้บริการราคาเฉลี่ยถ่วงน้ำหนักด้วยปริมาณการซื้อขายรายวัน (VWAP), ตัวชี้วัดราคา (ฟิลด์ first_price, last_price, min_price และ max_price) ตลอดจนเมตริกปริมาณการซื้อขายสำหรับโทเค็นที่ระบุในช่วงวันที่กำหนด
ความพร้อมใช้งานของชุดข้อมูลนี้จะแตกต่างกันไปตามแต่ละเครือข่าย; เชนที่ให้บริการชุดข้อมูลนี้เป็นไปตามหน้ารายการ เชนที่รองรับ
endpoint นี้ไม่มีการแบ่งหน้า (pagination): แถวข้อมูลรายวันทั้งหมดที่ตรงกันภายในช่วงวันที่ที่ร้องขอจะถูกส่งกลับโดยตรงใน data และจะไม่มี next_cursor ปรากฏ หากแอปพลิเคชันของคุณต้องการธุรกรรม swap แบบละเอียดรายธุรกรรมแทนที่จะเป็นข้อมูลสรุปรายวัน ให้ใช้ GET /{chain}/dex/swaps (ดู ข้อมูลอ้างอิง Data API)
พารามิเตอร์และขีดจำกัดของคำขอ
เส้นทาง endpoint คือ GET https://api.blockvectra.com/v1/data/{chain}/dex/prices ทุกคำขอต้องมีการยืนยันตัวตนโดยส่ง API key ของคุณในส่วนหัว x-api-key
endpoint รองรับ query parameter ดังต่อไปนี้:
| พารามิเตอร์ | ตำแหน่ง | ประเภท | จำเป็น | คำอธิบาย |
|---|---|---|---|---|
chain | path | string | ใช่ | ตัวระบุเชน เช่น robinhood_mainnet |
token | query | string | ใช่ | แอดเดรส base token ขนาด 20 ไบต์, ใส่ 0x หรือไม่ก็ได้, ตัวพิมพ์เล็กหรือใหญ่ก็ได้ |
quote | query | string | ไม่ | แอดเดรส quote token ขนาด 20 ไบต์ (ระบุหรือไม่ก็ได้) เพื่อจำกัดเฉพาะคู่ base/quote เดียว |
from | query | date string | ใช่ | วันที่เริ่มต้นตามเวลา UTC (รวมวันนั้นด้วย), รูปแบบ YYYY-MM-DD |
to | query | date string | ใช่ | วันที่สิ้นสุดตามเวลา UTC (รวมวันนั้นด้วย), รูปแบบ YYYY-MM-DD โดย to - from ต้อง <= 90 วัน |
ข้อจำกัดและรหัสข้อผิดพลาด
เมื่อคำขอละเมิดข้อจำกัด API จะส่งกลับโครงสร้างข้อผิดพลาด {"error":{"code","message"}}:
- HTTP 400 (
bad_request): พารามิเตอร์ที่จำเป็นขาดหายไป (token,fromหรือto), ไวยากรณ์ของแอดเดรสtoken/quoteไม่ถูกต้อง, รูปแบบวันที่ปฏิทินYYYY-MM-DDไม่ถูกต้อง หรือfromอยู่หลังto - HTTP 409 (
span_exceeded):to - fromเกิน 90 วัน - HTTP 404 (
unknown_chain):{chain}ไม่ใช่เชนที่แสดงอยู่ในรายการของGET /chains - HTTP 422 (
no_coverage): เชนไม่รองรับความสามารถของชุดข้อมูลdex_prices - HTTP 503 (
unavailable): บริการไม่พร้อมใช้งานชั่วคราว; ให้ลองใหม่อีกครั้งตามส่วนหัวRetry-After
ตัวอย่างคำขอ
ตัวอย่างต่อไปนี้จะคิวรีราคา DEX รายวันสำหรับ base token ตลอดช่วงเดือนกันยายน 2026:
curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/dex/prices?token=0x1Cdad396DB64BDa184d5182A97Dd9B3C62100b7D&from=2026-09-01&to=2026-09-30" \
-H "x-api-key: $BLOCKVECTRA_API_KEY"ข้อมูลอ้างอิงฟิลด์โดยละเอียด
แต่ละรายการใน data แสดงถึงเมตริก DEX รายวันแบบสรุปสำหรับคู่โทเค็นในวันที่นั้นตามเวลา UTC:
สินทรัพย์โทเค็นและ quote
day(string): วันที่ตามเวลา UTC ในรูปแบบYYYY-MM-DDtoken(string): แอดเดรส base token ขนาด 20 ไบต์ในรูปแบบเลขฐานสิบหกนำหน้าด้วย0xตัวพิมพ์เล็กtoken_symbol(string หรือnull): สัญลักษณ์ของ base tokentoken_name(string หรือnull): ชื่อที่แสดงของ base tokenquote_token(string): แอดเดรสของสินทรัพย์ quote โดยแอดเดรสที่เป็นศูนย์ทั้งหมด (0x0000000000000000000000000000000000000000) จะแสดงถึง native ETH ในฐานะสินทรัพย์ quotequote_symbol(string หรือnull): สัญลักษณ์ของสินทรัพย์ quote ("ETH"เมื่อquote_tokenเป็นแอดเดรสศูนย์ทั้งหมด)quote_name(string หรือnull): ชื่อที่แสดงของสินทรัพย์ quote ("Ether"เมื่อquote_tokenเป็นแอดเดรสศูนย์ทั้งหมด)base_decimals(integer หรือnull): ทศนิยมของ base token (0–255)quote_decimals(integer หรือnull): ทศนิยมของสินทรัพย์ quote (18เมื่อquote_tokenเป็นแอดเดรสศูนย์ทั้งหมด)
ปริมาณและจำนวนการซื้อขาย
swap_count(integer): จำนวนครั้งของ swap สำหรับแถวนี้base_volume_raw(string): ปริมาณ base ระดับอะตอมในรูปแบบสตริงทศนิยมจำนวนเต็มแบบไม่มีเครื่องหมาย (UInt256String)quote_volume_raw(string): ปริมาณ quote ระดับอะตอมในรูปแบบสตริงทศนิยมจำนวนเต็มแบบไม่มีเครื่องหมาย (UInt256String)base_volume(string หรือnull): ปริมาณ base token ที่มนุษย์อ่านได้ซึ่งปรับขนาดตามbase_decimalsในรูปแบบDecimalString; เป็นnullเมื่อไม่ทราบbase_decimalsquote_volume(string หรือnull): ปริมาณ quote ที่ปรับขนาดตามทศนิยมของ quote ในรูปแบบDecimalStringหรือnull
ตัวชี้วัดราคาและ VWAP
vwap(string หรือnull): ราคาเฉลี่ยถ่วงน้ำหนักด้วยปริมาณการซื้อขายในรูปแบบDecimalStringหรือnullfirst_price(string หรือnull): ตัวชี้วัดราคาแรกในรูปแบบDecimalStringหรือnulllast_price(string หรือnull): ตัวชี้วัดราคาสุดท้ายในรูปแบบDecimalStringหรือnullmin_price(string หรือnull): ตัวชี้วัดราคาต่ำสุดในรูปแบบDecimalStringหรือnullmax_price(string หรือnull): ตัวชี้วัดราคาสูงสุดในรูปแบบDecimalStringหรือnull
ฟิลด์เศษส่วนแม่นยำสูง
first_price_numerator/first_price_denominator(string): ตัวเศษและตัวส่วนจำนวนเต็มที่แม่นยำสำหรับfirst_price(UInt256String)last_price_numerator/last_price_denominator(string): ตัวเศษและตัวส่วนจำนวนเต็มที่แม่นยำสำหรับlast_price(UInt256String)min_price_numerator/min_price_denominator(string): ตัวเศษและตัวส่วนจำนวนเต็มที่แม่นยำสำหรับmin_price(UInt256String)max_price_numerator/max_price_denominator(string): ตัวเศษและตัวส่วนจำนวนเต็มที่แม่นยำสำหรับmax_price(UInt256String)refreshed_at(string): การประทับเวลาการรีเฟรชสำหรับแถวนี้ (การประทับเวลา ISO-8601 UTC)
ข้อมูลเมทาดาทาของ Envelope (meta)
chain: ตัวระบุเชนchain_slug: slug ของเชนตัวพิมพ์ใหญ่ตามรูปแบบมาตรฐานchain_external_id: ตัวระบุเชนในรูปแบบ CAIP-2as_of_block: บล็อกใหม่ล่าสุดที่เขียนสมบูรณ์แล้วของเชน (รายงานโดยชุดข้อมูลนี้ ไม่ได้ตรวจสอบเทียบกับพารามิเตอร์ของคำขอ)coverage: การจัดระดับความครอบคลุม (รายงาน"full"สำหรับ endpoint นี้)refreshed_at: การประทับเวลารีเฟรชของเมทาดาทา อาจเป็นnull: ค่าnullหมายถึงไม่ทราบเวลาอัปเดตของข้อมูลนี้และควรปฏิบัติเสมือนว่าเป็นข้อมูลเก่า; endpoint ที่อิงตามบล็อกจะส่งคืนค่าเสมอ
เหตุใดราคาจึงใช้ตัวเศษและตัวส่วนที่แม่นยำ
ตัวเลข JSON มาตรฐานใช้เลขทศนิยมความแม่นยำสองเท่า (double-precision float) ตามมาตรฐาน IEEE-754 ซึ่งมีข้อจำกัดด้านความแม่นยำ:
- การตัดทอนและการคลาดเคลื่อนของเลขทศนิยม (Floating-point truncation and drift): ค่า Float64 ให้ความแม่นยำเพียง 53 บิต และการหารปริมาณโทเค็นจะทำให้เกิดการปัดเศษคลาดเคลื่อนซึ่งจะสะสมทับถมกันในการคำนวณหลายขั้นตอน
- ความปลอดภัยในการส่งผ่านข้อมูล (Transport safety): การจัดรูปแบบค่าเป็นสตริงทศนิยม (
UInt256String) ช่วยให้มั่นใจได้ว่าตัวเลขจะถูกส่งผ่าน HTTP โดยไม่สูญเสียความแม่นยำในตัวแจงส่วน JSON
ด้วยการให้ตัวเศษและตัวส่วนจำนวนเต็มที่แม่นยำสำหรับตัวชี้วัดราคา BlockVectra ช่วยให้สามารถคำนวณทางคณิตศาสตร์ได้อย่างแม่นยำโดยไม่ต้องแปลงเป็นเลขทศนิยม
การจัดการเศษส่วนที่แม่นยำใน TypeScript (BigInt)
ใน TypeScript คุณสามารถใช้ BigInt ดั้งเดิมสำหรับการเปรียบเทียบด้วยการคูณไขว้และการแปลงเป็น fixed-point ได้โดยไม่ต้องแปลงเป็นเลขทศนิยม:
interface DexDailyPrice {
first_price_numerator: string;
first_price_denominator: string;
last_price_numerator: string;
last_price_denominator: string;
}
// 1. Ratio comparison without floating-point conversion: check if close price is higher than open price
// a / b > c / d is equivalent to a * d > c * b
export function isPriceUp(row: DexDailyPrice): boolean {
const openNum = BigInt(row.first_price_numerator);
const openDen = BigInt(row.first_price_denominator);
const closeNum = BigInt(row.last_price_numerator);
const closeDen = BigInt(row.last_price_denominator);
return closeNum * openDen > openNum * closeDen;
}
// 2. Convert fraction to a fixed-point decimal string with arbitrary scale (without floating-point loss)
export function fractionToFixedString(
numeratorStr: string,
denominatorStr: string,
decimals = 18
): string {
const num = BigInt(numeratorStr);
const den = BigInt(denominatorStr);
if (decimals === 0) {
return (num / den).toString();
}
const scaleFactor = 10n ** BigInt(decimals);
const scaled = (num * scaleFactor) / den;
const intPart = scaled / scaleFactor;
const remainder = scaled % scaleFactor;
const fracPart = remainder.toString().padStart(decimals, "0");
return `${intPart}.${fracPart}`;
}การจัดการเศษส่วนที่แม่นยำใน Python
Python มีโมดูลไลบรารีมาตรฐานที่สร้างขึ้นโดยเฉพาะสำหรับการคำนวณจำนวนตรรกยะและเลขทศนิยม: fractions.Fraction และ decimal.Decimal
from decimal import Decimal, getcontext
from fractions import Fraction
# 1. Exact rational calculations with fractions.Fraction
open_price = Fraction(
int(row["first_price_numerator"]),
int(row["first_price_denominator"])
)
close_price = Fraction(
int(row["last_price_numerator"]),
int(row["last_price_denominator"])
)
# Exact price delta without floating-point rounding error
price_delta = close_price - open_price
print(f"Price delta (fraction): {price_delta}")
if open_price != 0:
percentage_change = (price_delta / open_price) * 100
print(f"Percentage change: {float(percentage_change):.4f}%")
# 2. Arbitrary-precision decimal arithmetic with decimal.Decimal
getcontext().prec = 50
if int(row["first_price_denominator"]) != 0:
open_decimal = Decimal(row["first_price_numerator"]) / Decimal(row["first_price_denominator"])
print(f"High-precision open: {open_decimal}")การดึงข้อมูลราคารายวันย้อนหลังหนึ่งปี
ในการดึงข้อมูลย้อนหลังหนึ่งปี (365 วัน) ให้อยู่ภายในขีดจำกัดช่วง 90 วัน ให้แบ่งช่วงวันที่ทั้งหมดออกเป็นกรอบเวลาต่อเนื่องกันไม่เกิน 90 วัน แล้วส่งคำขอแบบแบ่งส่วน (chunked requests):
interface DateSpan {
from: string;
to: string;
}
/**
* Split a large date range into consecutive spans of at most maxDays (default: 90)
*/
export function splitDateRange(startDateStr: string, endDateStr: string, maxDays = 90): DateSpan[] {
const spans: DateSpan[] = [];
let currentStart = new Date(startDateStr);
const end = new Date(endDateStr);
while (currentStart <= end) {
const chunkEnd = new Date(currentStart);
chunkEnd.setUTCDate(chunkEnd.getUTCDate() + (maxDays - 1));
const effectiveEnd = chunkEnd < end ? chunkEnd : end;
spans.push({
from: currentStart.toISOString().slice(0, 10),
to: effectiveEnd.toISOString().slice(0, 10),
});
const nextStart = new Date(effectiveEnd);
nextStart.setUTCDate(nextStart.getUTCDate() + 1);
currentStart = nextStart;
}
return spans;
}
/**
* Backfill token daily prices across multiple 90-day chunks
*/
export async function backfillTokenDailyPrices(
chain: string,
token: string,
startDate: string,
endDate: string,
apiKey: string
) {
const chunks = splitDateRange(startDate, endDate, 90);
const allDailyPrices = [];
for (const chunk of chunks) {
const url = new URL(`https://api.blockvectra.com/v1/data/${chain}/dex/prices`);
url.searchParams.set("token", token);
url.searchParams.set("from", chunk.from);
url.searchParams.set("to", chunk.to);
const res = await fetch(url, {
headers: { "x-api-key": apiKey },
});
if (!res.ok) {
throw new Error(`Failed to fetch span ${chunk.from}..${chunk.to}: HTTP ${res.status}`);
}
const json = await res.json();
allDailyPrices.push(...json.data);
}
return allDailyPrices;
}การคำนวณความจุและการใช้งาน CU
ทุก endpoint ของ Data API จะวัดปริมาณการใช้งานเป็น Compute Units (CU) ค่าน้ำหนัก CU ต่อการเรียกสำหรับ data.dex_prices และการประมาณการปริมาณการใช้งานสำหรับการดึงข้อมูลโทเค็นย้อนหลังได้รับการคำนวณด้านล่างนี้:
data.dex_prices: 15 CU / call- ดึงข้อมูลย้อนหลัง 1 ปีของราคารายวันสำหรับ 200 โทเค็น: ด้วยช่วงสูงสุด 90 วันต่อคำขอ การครอบคลุม 365 วันใช้ 5 ส่วนต่อโทเค็น รวมเป็น 1,000 คำขอ การใช้งานทั้งหมดคือ 15,000 CU (ประมาณ <0.1% ของโควตารอบแพ็กเกจฟรี), ประมาณ <$0.01 ตามราคามาตรฐาน.
- การบำรุงรักษารายวัน (รีเฟรช 200 โทเค็นวันละครั้ง): 200 คำขอ/วัน (3,000 CU/วัน), รวมประมาณ 6,000 คำขอต่อรอบ 30 วัน (90,000 CU, ประมาณ 0.3% ของโควตาฟรี), ประมาณ <$0.01/เดือน ตามราคามาตรฐาน.
เมื่อขยายปริมาณการดึงข้อมูลย้อนหลังหรือต้องการความพร้อมกันของคำขอที่สูงขึ้น ให้เติมเงิน on-chain ที่คอนโซล หน้าการเรียกเก็บเงิน เพื่ออัปเกรดเป็นบัญชีแบบชำระเงิน สำหรับอัตราปัจจุบันและการแปลงหน่วย โปรดดู หน้าราคา
ขั้นตอนถัดไป
- เลือกดูสารบบชุดข้อมูล เพื่อดูทุกชุดข้อมูลที่ BlockVectra ทำดัชนี
- ดูแผนบริการฟรีและราคา เพื่อตรวจสอบสิ่งที่รวมอยู่ในบัญชีของคุณ
- เข้าสู่ระบบคอนโซล เพื่อสร้าง API key
อัปเดตล่าสุด: