Files
auto-trade/features/trade/components/chart/stock-line-chart-meta.ts

156 lines
4.4 KiB
TypeScript

import type { DashboardChartTimeframe } from "@/features/trade/types/trade.types";
import type { ChartBar } from "./chart-utils";
export const UP_COLOR = "#ef4444";
export const MINUTE_SYNC_INTERVAL_MS = 30000;
export const REALTIME_STALE_THRESHOLD_MS = 12000;
export const CHART_MIN_HEIGHT = 220;
export const HISTORY_LOAD_TRIGGER_BARS_BEFORE = 40;
export const INITIAL_MINUTE_PREFETCH_BUDGET_MS = 12000;
export interface ChartPalette {
backgroundColor: string;
downColor: string;
volumeDownColor: string;
textColor: string;
borderColor: string;
gridColor: string;
crosshairColor: string;
}
export const DEFAULT_CHART_PALETTE: ChartPalette = {
backgroundColor: "#ffffff",
downColor: "#2563eb",
volumeDownColor: "rgba(37, 99, 235, 0.45)",
textColor: "#6d28d9",
borderColor: "#e9d5ff",
gridColor: "#f3e8ff",
crosshairColor: "#c084fc",
};
export const MINUTE_TIMEFRAMES: Array<{
value: DashboardChartTimeframe;
label: string;
}> = [
{ value: "1m", label: "1분" },
{ value: "5m", label: "5분" },
{ value: "10m", label: "10분" },
{ value: "15m", label: "15분" },
{ value: "30m", label: "30분" },
{ value: "1h", label: "1시간" },
];
export const PERIOD_TIMEFRAMES: Array<{
value: DashboardChartTimeframe;
label: string;
}> = [
{ value: "1d", label: "일" },
{ value: "1w", label: "주" },
];
export function resolveInitialMinuteTargetBars(
timeframe: DashboardChartTimeframe,
) {
if (timeframe === "1m") return 260;
if (timeframe === "5m") return 240;
if (timeframe === "10m") return 220;
if (timeframe === "15m") return 200;
if (timeframe === "30m") return 180;
if (timeframe === "1h") return 260;
return 140;
}
export function resolveInitialMinutePrefetchPages(
timeframe: DashboardChartTimeframe,
) {
if (timeframe === "1m") return 24;
if (timeframe === "5m") return 28;
if (timeframe === "10m") return 32;
if (timeframe === "15m") return 36;
if (timeframe === "30m") return 44;
if (timeframe === "1h") return 80;
return 20;
}
/**
* @description 브랜드 CSS 변수에서 차트 팔레트를 읽어옵니다.
* @see features/trade/components/chart/StockLineChart.tsx 차트 생성/테마 반영
*/
export function getChartPaletteFromCssVars(
themeMode: "light" | "dark",
): ChartPalette {
const isDark = themeMode === "dark";
const backgroundVar = isDark
? "--brand-chart-background-dark"
: "--brand-chart-background-light";
const textVar = isDark
? "--brand-chart-text-dark"
: "--brand-chart-text-light";
const borderVar = isDark
? "--brand-chart-border-dark"
: "--brand-chart-border-light";
const gridVar = isDark
? "--brand-chart-grid-dark"
: "--brand-chart-grid-light";
const crosshairVar = isDark
? "--brand-chart-crosshair-dark"
: "--brand-chart-crosshair-light";
return {
backgroundColor: readCssVar(
backgroundVar,
DEFAULT_CHART_PALETTE.backgroundColor,
),
downColor: readCssVar(
"--brand-chart-down",
DEFAULT_CHART_PALETTE.downColor,
),
volumeDownColor: readCssVar(
"--brand-chart-volume-down",
DEFAULT_CHART_PALETTE.volumeDownColor,
),
textColor: readCssVar(textVar, DEFAULT_CHART_PALETTE.textColor),
borderColor: readCssVar(borderVar, DEFAULT_CHART_PALETTE.borderColor),
gridColor: readCssVar(gridVar, DEFAULT_CHART_PALETTE.gridColor),
crosshairColor: readCssVar(
crosshairVar,
DEFAULT_CHART_PALETTE.crosshairColor,
),
};
}
/**
* @description 차트 데이터 배열이 동일한지 비교합니다.
* @see features/trade/components/chart/StockLineChart.tsx 분봉 동기화 시 불필요한 상태 업데이트 방지
*/
export function areBarsEqual(left: ChartBar[], right: ChartBar[]) {
if (left.length !== right.length) return false;
for (let index = 0; index < left.length; index += 1) {
const lhs = left[index];
const rhs = right[index];
if (!lhs || !rhs) return false;
if (
lhs.time !== rhs.time ||
lhs.open !== rhs.open ||
lhs.high !== rhs.high ||
lhs.low !== rhs.low ||
lhs.close !== rhs.close ||
lhs.volume !== rhs.volume
) {
return false;
}
}
return true;
}
function readCssVar(name: string, fallback: string) {
if (typeof window === "undefined") return fallback;
const value = window
.getComputedStyle(document.documentElement)
.getPropertyValue(name)
.trim();
return value || fallback;
}