diff --git a/apps/visualizer/src/App.tsx b/apps/visualizer/src/App.tsx
index 10c1989..5e529b3 100644
--- a/apps/visualizer/src/App.tsx
+++ b/apps/visualizer/src/App.tsx
@@ -107,6 +107,7 @@ function TradeApp({ user, onLogout }: { user: string; onLogout: () => void }) {
const [pollMs, setPollMs] = useLocalStorageState('trade.pollMs', envNumber('VITE_POLL_MS', 1000));
const [limit, setLimit] = useLocalStorageState('trade.limit', envNumber('VITE_LIMIT', 300));
const [showIndicators, setShowIndicators] = useLocalStorageState('trade.showIndicators', true);
+ const [showBuild, setShowBuild] = useLocalStorageState('trade.showBuild', false);
const [tab, setTab] = useLocalStorageState<'orderbook' | 'trades'>('trade.sidebarTab', 'orderbook');
const [bottomTab, setBottomTab] = useLocalStorageState<
'positions' | 'orders' | 'balances' | 'orderHistory' | 'positionHistory'
@@ -288,6 +289,8 @@ function TradeApp({ user, onLogout }: { user: string; onLogout: () => void }) {
onTimeframeChange={setTf}
showIndicators={showIndicators}
onToggleIndicators={() => setShowIndicators((v) => !v)}
+ showBuild={showBuild}
+ onToggleBuild={() => setShowBuild((v) => !v)}
seriesLabel={seriesLabel}
/>
diff --git a/apps/visualizer/src/features/chart/ChartPanel.tsx b/apps/visualizer/src/features/chart/ChartPanel.tsx
index 8b0815e..02b5557 100644
--- a/apps/visualizer/src/features/chart/ChartPanel.tsx
+++ b/apps/visualizer/src/features/chart/ChartPanel.tsx
@@ -18,6 +18,8 @@ type Props = {
onTimeframeChange: (tf: string) => void;
showIndicators: boolean;
onToggleIndicators: () => void;
+ showBuild: boolean;
+ onToggleBuild: () => void;
seriesLabel: string;
};
@@ -49,6 +51,8 @@ export default function ChartPanel({
onTimeframeChange,
showIndicators,
onToggleIndicators,
+ showBuild,
+ onToggleBuild,
seriesLabel,
}: Props) {
const [isFullscreen, setIsFullscreen] = useState(false);
@@ -272,6 +276,8 @@ export default function ChartPanel({
onTimeframeChange={onTimeframeChange}
showIndicators={showIndicators}
onToggleIndicators={onToggleIndicators}
+ showBuild={showBuild}
+ onToggleBuild={onToggleBuild}
priceAutoScale={priceAutoScale}
onTogglePriceAutoScale={() => setPriceAutoScale((v) => !v)}
seriesLabel={seriesLabel}
@@ -300,6 +306,7 @@ export default function ChartPanel({
ema20={indicators.ema20}
bb20={indicators.bb20}
showIndicators={showIndicators}
+ showBuild={showBuild}
bucketSeconds={bucketSeconds}
seriesKey={seriesKey}
fib={fibRenderable}
diff --git a/apps/visualizer/src/features/chart/ChartToolbar.tsx b/apps/visualizer/src/features/chart/ChartToolbar.tsx
index e4dcb39..638dc76 100644
--- a/apps/visualizer/src/features/chart/ChartToolbar.tsx
+++ b/apps/visualizer/src/features/chart/ChartToolbar.tsx
@@ -5,6 +5,8 @@ type Props = {
onTimeframeChange: (tf: string) => void;
showIndicators: boolean;
onToggleIndicators: () => void;
+ showBuild: boolean;
+ onToggleBuild: () => void;
priceAutoScale: boolean;
onTogglePriceAutoScale: () => void;
seriesLabel: string;
@@ -19,6 +21,8 @@ export default function ChartToolbar({
onTimeframeChange,
showIndicators,
onToggleIndicators,
+ showBuild,
+ onToggleBuild,
priceAutoScale,
onTogglePriceAutoScale,
seriesLabel,
@@ -45,6 +49,9 @@ export default function ChartToolbar({
+
diff --git a/apps/visualizer/src/features/chart/TradingChart.tsx b/apps/visualizer/src/features/chart/TradingChart.tsx
index 44044b2..cfecb61 100644
--- a/apps/visualizer/src/features/chart/TradingChart.tsx
+++ b/apps/visualizer/src/features/chart/TradingChart.tsx
@@ -25,6 +25,7 @@ type Props = {
ema20?: SeriesPoint[];
bb20?: { upper: SeriesPoint[]; lower: SeriesPoint[]; mid: SeriesPoint[] };
showIndicators: boolean;
+ showBuild: boolean;
bucketSeconds: number;
seriesKey: string;
fib?: FibRetracement | null;
@@ -116,6 +117,7 @@ export default function TradingChart({
ema20,
bb20,
showIndicators,
+ showBuild,
bucketSeconds,
seriesKey,
fib,
@@ -596,12 +598,29 @@ export default function TradingChart({
s.bbLower?.setData(bbLower);
s.bbMid?.setData(bbMid);
+ s.build.applyOptions({ visible: showBuild });
+ if (!showBuild) {
+ buildSamplesRef.current.clear();
+ buildKeyRef.current = seriesKey;
+ lastBuildCandleStartRef.current = null;
+ s.build.setData([]);
+ }
+
if (buildKeyRef.current !== seriesKey) {
buildSamplesRef.current.clear();
buildKeyRef.current = seriesKey;
lastBuildCandleStartRef.current = null;
}
+ if (!showBuild) {
+ s.sma20?.applyOptions({ visible: showIndicators });
+ s.ema20?.applyOptions({ visible: showIndicators });
+ s.bbUpper?.applyOptions({ visible: showIndicators });
+ s.bbLower?.applyOptions({ visible: showIndicators });
+ s.bbMid?.applyOptions({ visible: showIndicators });
+ return;
+ }
+
const bs = resolveBucketSeconds(bucketSeconds, candles);
const eps = 1e-3;
const maxPointsPerCandle = 600;
@@ -714,7 +733,21 @@ export default function TradingChart({
s.bbUpper?.applyOptions({ visible: showIndicators });
s.bbLower?.applyOptions({ visible: showIndicators });
s.bbMid?.applyOptions({ visible: showIndicators });
- }, [candleData, volumeData, oracleData, smaData, emaData, bbUpper, bbLower, bbMid, showIndicators, candles, bucketSeconds, seriesKey]);
+ }, [
+ candleData,
+ volumeData,
+ oracleData,
+ smaData,
+ emaData,
+ bbUpper,
+ bbLower,
+ bbMid,
+ showIndicators,
+ showBuild,
+ candles,
+ bucketSeconds,
+ seriesKey,
+ ]);
useEffect(() => {
const s = seriesRef.current;