> For the complete documentation index, see [llms.txt](https://noodles-finance.gitbook.io/docs.noodles.fi/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://noodles-finance.gitbook.io/docs.noodles.fi/websocket/room-ohlc.md).

# Room OHLC

## Overview

The OHLC (Open, High, Low, Close) room provides candlestick/OHLC data for specific coins at various time intervals.

## Channel Format

`OHLC.{bucket_minutes}-{coin_id}`

**Example**: `OHLC.5-0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC` (5-minute candlesticks)

## Supported Time Buckets

| Bucket | Description |
| ------ | ----------- |
| 1      | 1 minute    |
| 5      | 5 minutes   |
| 15     | 15 minutes  |
| 30     | 30 minutes  |
| 60     | 1 hour      |
| 240    | 4 hours     |
| 1440   | 1 day       |
| 10080  | 1 week      |
| 43200  | 1 month     |

## Subscription

**See:** [WebSocket Setup](/docs.noodles.fi/websocket/websocket-setup.md) for general WebSocket connection and management details.

### Client Subscription Message

```json
{
  "type": "subscribe",
  "room": "OHLC",
  "data": {
    "coin": "0x2::sui::SUI",
    "bucket": 5
  }
}
```

## Server Response Data Format

OHLC candlestick data:

```json
{
  "type": "data",
  "channel": "OHLC.5-0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC",
  "room": "OHLC",
  "data": {
    "timestamp": 1635724800000,
    "open": 3.456,
    "high": 3.567,
    "low": 3.123,
    "close": 3.234,
    "volume": 1000.50
  }
}
```

## Data Fields

| Field       | Type   | Description                       |
| ----------- | ------ | --------------------------------- |
| `timestamp` | number | Candle start time in milliseconds |
| `open`      | number | Opening price for the period      |
| `high`      | number | Highest price during the period   |
| `low`       | number | Lowest price during the period    |
| `close`     | number | Closing price for the period      |
| `volume`    | number | Trading volume during the period  |

## Example Usage

### JavaScript - Price Chart

```javascript
const ws = new WebSocket('wss://ws.noodles.fi/ws/coin-update');

// Store candles for chart display
const candles = [];

ws.onopen = function() {
    // Subscribe to 5-minute OHLC for SUI
    ws.send(JSON.stringify({
        type: 'subscribe',
        room: 'OHLC',
        data: {
            coin: '0x2::sui::SUI',
            bucket: 5
        }
    }));
};

ws.onmessage = function(event) {
    const message = JSON.parse(event.data);
    
    if (message.type === 'data' && message.room === 'OHLC') {
        const candle = message.data;
        
        // Update or add candle
        const existingIndex = candles.findIndex(c => c.timestamp === candle.timestamp);
        if (existingIndex >= 0) {
            candles[existingIndex] = candle;
        } else {
            candles.push(candle);
        }
        
        // Keep only last 100 candles
        if (candles.length > 100) {
            candles.shift();
        }
        
        // Update chart
        updateChart(candles);
    }
};

function updateChart(candles) {
    console.log('Latest candle:', {
        time: new Date(candles[candles.length - 1].timestamp).toLocaleString(),
        open: candles[candles.length - 1].open,
        high: candles[candles.length - 1].high,
        low: candles[candles.length - 1].low,
        close: candles[candles.length - 1].close,
        volume: candles[candles.length - 1].volume
    });
}
```

### TypeScript - Chart Component

```typescript
interface OHLCData {
  timestamp: number;
  open: number;
  high: number;
  low: number;
  close: number;
  volume: number;
}

class CandlestickChart {
  private candles: Map<number, OHLCData> = new Map();
  private client: NoodlesWebSocketClient;
  
  constructor(coinId: string, bucket: number) {
    this.client = new NoodlesWebSocketClient();
    
    this.client.onOHLCData = (channel: string, data: OHLCData) => {
      this.updateCandle(data);
    };
    
    this.client.connect().then(() => {
      this.client.subscribe('OHLC', coinId, bucket);
    });
  }
  
  private updateCandle(data: OHLCData): void {
    this.candles.set(data.timestamp, data);
    this.render();
  }
  
  private render(): void {
    const sortedCandles = Array.from(this.candles.values())
      .sort((a, b) => a.timestamp - b.timestamp);
    
    // Render to your chart library (e.g., Chart.js, TradingView, etc.)
    console.log('Chart data updated:', sortedCandles.length, 'candles');
  }
  
  public destroy(): void {
    this.client.disconnect();
  }
}

// Usage
const chart = new CandlestickChart('0x2::sui::SUI', 5);
```

### React + TradingView Lightweight Charts

```typescript
import { useEffect, useRef, useState } from 'react';
import { createChart, IChartApi } from 'lightweight-charts';

interface OHLCChartProps {
  coinId: string;
  bucket: number;
}

export function OHLCChart({ coinId, bucket }: OHLCChartProps) {
  const chartContainerRef = useRef<HTMLDivElement>(null);
  const chartRef = useRef<IChartApi | null>(null);
  const [client, setClient] = useState<NoodlesWebSocketClient | null>(null);

  useEffect(() => {
    if (!chartContainerRef.current) return;

    // Create chart
    const chart = createChart(chartContainerRef.current, {
      width: chartContainerRef.current.clientWidth,
      height: 400,
    });

    const candlestickSeries = chart.addCandlestickSeries();
    chartRef.current = chart;

    // Setup WebSocket
    const wsClient = new NoodlesWebSocketClient();
    
    wsClient.onOHLCData = (channel: string, data: OHLCData) => {
      candlestickSeries.update({
        time: Math.floor(data.timestamp / 1000), // Convert to seconds
        open: data.open,
        high: data.high,
        low: data.low,
        close: data.close,
      });
    };

    wsClient.connect().then(() => {
      wsClient.subscribe('OHLC', coinId, bucket);
    });

    setClient(wsClient);

    return () => {
      wsClient.disconnect();
      chart.remove();
    };
  }, [coinId, bucket]);

  return <div ref={chartContainerRef} />;
}

// Usage
<OHLCChart coinId="0x2::sui::SUI" bucket={5} />
```

### Multiple Timeframes

```javascript
// Subscribe to multiple timeframes for the same coin
const timeframes = [5, 15, 60, 1440]; // 5min, 15min, 1hour, 1day

timeframes.forEach(bucket => {
    ws.send(JSON.stringify({
        type: 'subscribe',
        room: 'OHLC',
        data: {
            coin: '0x2::sui::SUI',
            bucket: bucket
        }
    }));
});

// Handle messages with timeframe detection
ws.onmessage = function(event) {
    const message = JSON.parse(event.data);
    
    if (message.type === 'data' && message.room === 'OHLC') {
        // Extract bucket from channel name: OHLC.5-coinId
        const bucket = parseInt(message.channel.split('.')[1].split('-')[0]);
        
        console.log(`${bucket}min candle:`, message.data);
        updateChartForTimeframe(bucket, message.data);
    }
};
```

## Unsubscription

### Client Unsubscription Message

```json
{
  "type": "unsubscribe",
  "room": "OHLC",
  "data": {
    "coin": "0x2::sui::SUI",
    "bucket": 5
  }
}
```

> **See also:** [WebSocket Setup](/docs.noodles.fi/websocket/websocket-setup.md) for general WebSocket connection and management details.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://noodles-finance.gitbook.io/docs.noodles.fi/websocket/room-ohlc.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
