Order flow
Delta, cumulative delta and relative volume
Order-flow indicators computed from aggressor volumes rather than guessed from the close.
Delta, cumulative delta and relative volume
@ortex-charts/financialLoading delta, cumulative delta and relative volume…
Order-flow indicators computed from aggressor volumes rather than guessed from the close.
delta-cvd.ts
import { createFinancialChart, footprintFromTicks, mergeFootprint } from "@ortex-charts/financial";
import { parseResolution, ticksToBars, type Bar, type Tick } from "@ortex-charts/math";
const RESOLUTION = parseResolution("15");
const bars = ticksToBars(prints, RESOLUTION, TIME_ZONE);
// Derived for this page: the sample feed reports no aggressor side, so the
// tick rule classifies each print. A feed that reports it sets `side` and
// every number below becomes exact rather than inferred.
const flow = footprintFromTicks(prints, RESOLUTION, 0.05, TIME_ZONE);
const chart = createFinancialChart(box, {
theme,
timeZone: TIME_ZONE,
resolution: "15",
// `mergeFootprint` writes buyVolume and sellVolume onto every bar. The
// indicators below read those columns; without them they fall back to
// the estimate and say so.
data: mergeFootprint(bars, flow),
volume: false,
seriesOptions: { priceFormat: { type: "price", precision: 2, minMove: 0.01 } },
});
const delta = chart.addIndicator("delta", { method: "auto" }, { paneHeightRatio: 0.22 });
const cvd = chart.addIndicator("cvd", { method: "auto" }, { paneHeightRatio: 0.22 });
chart.addIndicator("rvol", { length: 30 }, { paneHeightRatio: 0.22 });
chart.chart.subscribeCrosshairMove((e) => {
if (e.index === null) return;
const parts: string[] = [];
for (const [id, value] of e.seriesValues) {
const series = chart.chart.getSeries(id);
if (!series || "close" in value || !Number.isFinite(value.value)) continue;
parts.push(`${series.options.title} ${Math.round(value.value).toLocaleString()}`);
}
status(parts.join(" "));
});