feat(candles): support oracle OHLC basis

This commit is contained in:
u1
2026-02-03 12:51:29 +01:00
parent bd88eaa3c8
commit 9e7d7b88ac
3 changed files with 100 additions and 8 deletions

View File

@@ -1006,6 +1006,7 @@ async function handler(cfg, req, res) {
const symbol = (url.searchParams.get('symbol') || '').trim();
const source = (url.searchParams.get('source') || '').trim();
const basisRaw = (url.searchParams.get('basis') || '').trim().toLowerCase();
const tf = (url.searchParams.get('tf') || url.searchParams.get('timeframe') || '1m').trim();
const limit = clampInt(url.searchParams.get('limit') || '300', 10, 2000);
@@ -1023,6 +1024,11 @@ async function handler(cfg, req, res) {
}
const sourceKey = source || '';
const basis = basisRaw === 'mark' ? 'mark' : basisRaw === 'oracle' || !basisRaw ? 'oracle' : null;
if (!basis) {
sendJson(res, 400, { ok: false, error: 'invalid_basis' }, cfg.corsOrigin);
return;
}
try {
// Cache-first: read precomputed candles from `drift_candles_cache`.
@@ -1039,6 +1045,9 @@ async function handler(cfg, req, res) {
high
low
close
oracle_open
oracle_high
oracle_low
oracle_close
ticks
}
@@ -1064,6 +1073,9 @@ async function handler(cfg, req, res) {
high
low
close
oracle_open
oracle_high
oracle_low
oracle_close
ticks
}
@@ -1085,11 +1097,23 @@ async function handler(cfg, req, res) {
.reverse()
.map((r) => {
const time = Math.floor(Date.parse(r.bucket) / 1000);
const open = Number(r.open);
const high = Number(r.high);
const low = Number(r.low);
const close = Number(r.close);
const oracle = r.oracle_close == null ? null : Number(r.oracle_close);
const oracleClose = r.oracle_close == null ? null : Number(r.oracle_close);
const oracleOpen = r.oracle_open == null ? oracleClose : Number(r.oracle_open);
const oracleHigh = r.oracle_high == null ? oracleClose : Number(r.oracle_high);
const oracleLow = r.oracle_low == null ? oracleClose : Number(r.oracle_low);
const markOpen = Number(r.open);
const markHigh = Number(r.high);
const markLow = Number(r.low);
const markClose = Number(r.close);
const open = basis === 'oracle' ? oracleOpen : markOpen;
const high = basis === 'oracle' ? oracleHigh : markHigh;
const low = basis === 'oracle' ? oracleLow : markLow;
const close = basis === 'oracle' ? oracleClose : markClose;
// Always expose oracle close (even if basis=mark).
const oracle = oracleClose;
const volume = Number(r.ticks || 0);
return { time, open, high, low, close, volume, oracle };
})
@@ -1131,6 +1155,7 @@ async function handler(cfg, req, res) {
) {
bucket
close
oracle_close
}
}
`;
@@ -1151,7 +1176,10 @@ async function handler(cfg, req, res) {
for (const r of ptsRows) {
const t = tsToUnixSeconds(r.bucket);
if (t == null) continue;
const p = parseNumeric(r.close);
const p =
basis === 'oracle'
? parseNumeric(r.oracle_close) ?? parseNumeric(r.close)
: parseNumeric(r.close) ?? parseNumeric(r.oracle_close);
if (p == null) continue;
const idx = Math.floor((t - firstStart) / bucketSeconds);
const start = firstStart + idx * bucketSeconds;
@@ -1222,6 +1250,7 @@ async function handler(cfg, req, res) {
candlesFunction: cfg.candlesFunction,
symbol,
source: source || null,
basis,
tf,
bucketSeconds,
candles,