> ## Documentation Index
> Fetch the complete documentation index at: https://docs.0xmonaco.com/llms.txt
> Use this file to discover all available pages before exploring further.

# useOHLCV

> Subscribe to real-time candlestick data

<Note>
  **New in v0.5.5** - Real-time candlestick data with WebSocket updates
</Note>

Hook for subscribing to real-time OHLCV (Open, High, Low, Close, Volume) candlestick data via WebSocket.

## Usage

```tsx theme={null}
import { useOHLCV } from "@0xmonaco/react";

function CandlestickChart() {
  const { candlesticks, loading, subscribed, error, clearError } = useOHLCV({
    tradingPairId: "123e4567-e89b-12d3-a456-426614174000",
    tradingMode: "SPOT",
    interval: "1m",
    initialFetchParams: { limit: 100 }
  });

  if (loading) return <p>Loading candlesticks...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <div>
      <p>OHLCV handler: {subscribed ? 'Registered' : 'Not registered'}</p>
      <p>Candlesticks: {candlesticks.length}</p>
      {candlesticks.map((candle, i) => (
        <div key={i}>
          O: {candle.o} H: {candle.h} L: {candle.l} C: {candle.c} V: {candle.v}
        </div>
      ))}
    </div>
  );
}
```

## Parameters

<ParamField path="tradingPairId" type="string" required>
  UUID of the trading pair. Get from `sdk.market.getTradingPairBySymbol()`.
</ParamField>

<ParamField path="tradingMode" type="'SPOT' | 'MARGIN'" required>
  Trading mode for OHLCV data. Pass `"MARGIN"` for a perp market's candles.
</ParamField>

<ParamField path="interval" type="'1m' | '5m' | '15m' | '1h' | '4h' | '1d'" required>
  Candlestick time interval.
</ParamField>

<ParamField path="initialFetchParams" type="GetCandlesticksParams" optional>
  Optional parameters for initial data fetch:

  * `limit` - Number of candlesticks to fetch (max 500)
  * `startTime` - Start timestamp for range
  * `endTime` - End timestamp for range
</ParamField>

## Return Values

<ResponseField name="candlesticks" type="Candlestick[]">
  Array of candlestick data, sorted by time (oldest first). Updates in real-time via WebSocket.
</ResponseField>

<ResponseField name="loading" type="boolean">
  `true` while fetching initial candlestick data from REST API, `false` once loaded.
</ResponseField>

<ResponseField name="subscribed" type="boolean">
  `true` after the OHLCV channel handler is registered, `false` otherwise. This does not report socket connection or channel delivery state.
</ResponseField>

<ResponseField name="error" type="Error | null">
  Error object if subscription or fetch fails, `null` otherwise.
</ResponseField>

<ResponseField name="clearError" type="() => void">
  Dismisses the current error. It does not retry the fetch or re-register the handler.
</ResponseField>

## Candlestick Data Structure

```typescript theme={null}
interface Candlestick {
  T: number;        // Candle start time (Unix timestamp in milliseconds)
  t: number;        // Candle end time (Unix timestamp in milliseconds)
  o: string;        // Open price
  h: string;        // High price
  l: string;        // Low price
  c: string;        // Close price
  v: string;        // Volume (base token)
  s: string;        // Symbol
  i: string;        // Interval
  n: number;        // Number of trades
  openInterestBase?: string | null;       // One-sided LONG quantity in base-asset units
  openInterestNotional?: string | null;   // Quote notional using the same sample's price
}
```

## Features

### Hybrid Data Loading

1. **Initial REST Fetch**: Fetches historical candlesticks via REST API
2. **WebSocket Updates**: Subscribes to real-time updates after initial load
3. **Automatic Merging**: New candlesticks are automatically appended or update the last candle if timestamps match

### Stable Subscriptions

* **No data jitter**: Prevents state updates after component unmount
* **Proper cleanup**: WebSocket automatically unsubscribes when component unmounts
* **Race condition prevention**: Cancellation flag prevents stale updates

## Basic Example

```tsx theme={null}
import { useOHLCV } from "@0xmonaco/react";

function PriceChart() {
  const { candlesticks, loading, subscribed } = useOHLCV({
    tradingPairId: "pair-uuid-here",
    tradingMode: "SPOT",
    interval: "5m"
  });

  if (loading) return <div>Loading chart...</div>;

  return (
    <div>
      <div>OHLCV handler: {subscribed ? 'Registered' : 'Not registered'}</div>
      <div>Latest Price: {candlesticks[candlesticks.length - 1]?.c}</div>
    </div>
  );
}
```

## Different Time Intervals

```tsx theme={null}
function MultiTimeframeChart() {
  const oneMinute = useOHLCV({
    tradingPairId: "pair-uuid",
    tradingMode: "SPOT",
    interval: "1m"
  });

  const oneHour = useOHLCV({
    tradingPairId: "pair-uuid",
    tradingMode: "SPOT",
    interval: "1h"
  });

  return (
    <div>
      <h3>1m Chart ({oneMinute.candlesticks.length} candles)</h3>
      <h3>1h Chart ({oneHour.candlesticks.length} candles)</h3>
    </div>
  );
}
```

## Fetch Historical Data

```tsx theme={null}
function HistoricalChart() {
  const endTime = Date.now();
  const startTime = endTime - (24 * 60 * 60 * 1000); // 24 hours ago

  const { candlesticks, loading } = useOHLCV({
    tradingPairId: "pair-uuid",
    tradingMode: "SPOT",
    interval: "1h",
    initialFetchParams: {
      startTime,
      endTime,
      limit: 100
    }
  });

  if (loading) return <div>Loading...</div>;

  return <div>Loaded {candlesticks.length} historical candles</div>;
}
```

## Error Handling

```tsx theme={null}
function ChartWithErrorHandling() {
  const { candlesticks, error, clearError, loading } = useOHLCV({
    tradingPairId: "pair-uuid",
    tradingMode: "SPOT",
    interval: "1m"
  });

  if (error) {
    return (
      <div>
        <p>Failed to load chart: {error.message}</p>
        <button onClick={clearError}>Dismiss Error</button>
      </div>
    );
  }

  if (loading) return <div>Loading...</div>;

  return <div>{candlesticks.length} candles loaded</div>;
}
```

## Display Latest Price

```tsx theme={null}
function LivePrice() {
  const { candlesticks, subscribed } = useOHLCV({
    tradingPairId: "pair-uuid",
    tradingMode: "SPOT",
    interval: "1m"
  });

  const latestCandle = candlesticks[candlesticks.length - 1];

  if (!latestCandle) return <div>No data</div>;

  return (
    <div>
      <h2>${latestCandle.c}</h2>
      <p>
        O: {latestCandle.o} H: {latestCandle.h} L: {latestCandle.l}
      </p>
      <p>OHLCV handler: {subscribed ? 'Registered' : 'Not registered'}</p>
    </div>
  );
}
```

## Calculate Price Change

```tsx theme={null}
function PriceChange() {
  const { candlesticks } = useOHLCV({
    tradingPairId: "pair-uuid",
    tradingMode: "SPOT",
    interval: "1d"
  });

  const [previousCandle, currentCandle] = candlesticks.slice(-2);
  if (!previousCandle || !currentCandle) return <div>Not enough data</div>;

  const current = parseFloat(currentCandle.c);
  const previous = parseFloat(previousCandle.c);
  const change = ((current - previous) / previous) * 100;

  return (
    <div>
      <p>24h Change: {change.toFixed(2)}%</p>
      <p style={{ color: change >= 0 ? 'green' : 'red' }}>
        ${current.toFixed(2)}
      </p>
    </div>
  );
}
```

## Integration with Chart Libraries

```tsx theme={null}
import { useOHLCV } from "@0xmonaco/react";
import { Chart } from "react-chartjs-2";

function TradingViewChart() {
  const { candlesticks, loading } = useOHLCV({
    tradingPairId: "pair-uuid",
    tradingMode: "SPOT",
    interval: "1h",
    initialFetchParams: { limit: 100 }
  });

  if (loading) return <div>Loading chart...</div>;

  const chartData = {
    labels: candlesticks.map(c => new Date(c.T).toLocaleTimeString()),
    datasets: [{
      label: 'Price',
      data: candlesticks.map(c => parseFloat(c.c)),
      borderColor: 'rgb(75, 192, 192)',
      tension: 0.1
    }]
  };

  return <Chart type="line" data={chartData} />;
}
```

## Notes

* The hook automatically manages WebSocket subscriptions and cleanup
* Candlesticks are updated in real-time when the WebSocket receives new events
* If the last candlestick has the same timestamp as an incoming update, it's replaced; otherwise, a new candle is appended
* Component unmounting automatically unsubscribes from the WebSocket channel

## See Also

* [WebSocket API](/websocket) - Low-level OHLCV WebSocket channel
* [TypeScript SDK](/sdk/typescript/websockets) - Core SDK WebSocket methods
* [useMarket](/sdk/react/hooks/use-market) - Get trading pair metadata


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.