Skip to content

Market Data

The PyArrow SDK provides comprehensive market data access including real-time quotes, historical candles, instruments, and option chain information.

Quote Modes

Mode Code Description Data Included
LTP QuoteMode.LTP Last Traded Price LTP, change
OHLCV QuoteMode.OHLCV OHLC & Volume Open, High, Low, Close, Volume
FULL QuoteMode.FULL Complete market depth All data + bid/ask levels

Single Instrument Quote

Get real-time market data for a single instrument.

LTP Quote

from pyarrow import ArrowClient, QuoteMode, Exchange

client = ArrowClient(app_id="your_app_id")
# ... authenticate ...

# Get last traded price
quote = client.get_quote(QuoteMode.LTP, "RELIANCE-EQ", Exchange.NSE)
print(f"LTP: ₹{quote['ltp']}")
print(f"Change: {quote['change']}%")

OHLCV Quote

# Get OHLC and volume data
quote = client.get_quote(QuoteMode.OHLCV, "RELIANCE-EQ", Exchange.NSE)

print(f"Open:   ₹{quote['open']}")
print(f"High:   ₹{quote['high']}")
print(f"Low:    ₹{quote['low']}")
print(f"Close:  ₹{quote['close']}")
print(f"Volume: {quote['volume']}")

Full Quote (Market Depth)

# Get complete market depth
quote = client.get_quote(QuoteMode.FULL, "RELIANCE-EQ", Exchange.NSE)

print(f"LTP: ₹{quote['ltp']}")
print(f"Volume: {quote['volume']}")
print(f"Open Interest: {quote.get('oi', 'N/A')}")

# Bid-Ask spread
print(f"\nBest Bid: ₹{quote['bids'][0]['price']} x {quote['bids'][0]['quantity']}")
print(f"Best Ask: ₹{quote['asks'][0]['price']} x {quote['asks'][0]['quantity']}")

# Full depth (5 levels)
print("\n--- BID DEPTH ---")
for i, bid in enumerate(quote['bids'][:5]):
    print(f"Level {i+1}: ₹{bid['price']:>10} x {bid['quantity']:>8}")

print("\n--- ASK DEPTH ---")
for i, ask in enumerate(quote['asks'][:5]):
    print(f"Level {i+1}: ₹{ask['price']:>10} x {ask['quantity']:>8}")

Multiple Instrument Quotes

Get quotes for multiple instruments in a single API call.

LTP for Multiple Symbols

# Get LTP for multiple symbols
quotes = client.get_quotes(
    QuoteMode.LTP,
    symbols=[
        ("RELIANCE-EQ", Exchange.NSE),
        ("INFY-EQ", Exchange.NSE),
        ("TCS-EQ", Exchange.NSE),
        ("IDEA-EQ", Exchange.BSE)
    ]
)

for quote in quotes:
    print(f"{quote['symbol']}: ₹{quote['ltp']} ({quote['change']}%)")

OHLCV for Multiple Symbols

# Get OHLCV for multiple symbols
quotes = client.get_quotes(
    QuoteMode.OHLCV,
    symbols=[
        ("RELIANCE-EQ", Exchange.NSE),
        ("IDEA-EQ", Exchange.BSE)
    ]
)

for quote in quotes:
    print(f"\n{quote['symbol']} ({quote['exchange']})")
    print(f"  O: {quote['open']} | H: {quote['high']} | L: {quote['low']} | C: {quote['close']}")
    print(f"  Volume: {quote['volume']}")

Full Quote for Multiple Symbols

# Get full market depth for multiple symbols
quotes = client.get_quotes(
    QuoteMode.FULL,
    symbols=[
        ("RELIANCE-EQ", Exchange.NSE),
        ("IDEA-EQ", Exchange.BSE)
    ]
)

for quote in quotes:
    print(f"\n{quote['symbol']} - LTP: ₹{quote['ltp']}")
    print(f"  Bid: ₹{quote['bids'][0]['price']} | Ask: ₹{quote['asks'][0]['price']}")

Historical Candle Data

Retrieve historical OHLCV candle data for technical analysis.

Available Intervals

Interval Code Description
1 Minute min 1-minute candles
3 Minutes 3min 3-minute candles
5 Minutes 5min 5-minute candles
15 Minutes 15min 15-minute candles
30 Minutes 30min 30-minute candles
1 Hour hour Hourly candles
1 Day day Daily candles

Basic Usage

from pyarrow import Exchange

# Get 5-minute candle data
candles = client.candle_data(
    exchange=Exchange.NSE,
    token="3045",  # RELIANCE token
    interval="5min",
    from_timestamp="2024-01-15T09:15:00",
    to_timestamp="2024-01-15T15:30:00",
    oi=False  # Include Open Interest (for F&O)
)

print(f"Candles: {candles}")

Intraday Candles

from datetime import datetime, timedelta

# Get today's 5-minute candles
today = datetime.now()
market_open = today.replace(hour=9, minute=15, second=0)
market_close = today.replace(hour=15, minute=30, second=0)

candles = client.candle_data(
    exchange=Exchange.NSE,
    token="3045",
    interval="5min",
    from_timestamp=market_open.strftime("%Y-%m-%dT%H:%M:%S"),
    to_timestamp=market_close.strftime("%Y-%m-%dT%H:%M:%S"),
    oi=False
)

# Process candles
for candle in candles.get('data', []):
    print(f"Time: {candle['time']}")
    print(f"  O: {candle['open']} H: {candle['high']} L: {candle['low']} C: {candle['close']}")
    print(f"  Volume: {candle['volume']}")

Daily Candles

# Get daily candles for the past month
from datetime import datetime, timedelta

end_date = datetime.now()
start_date = end_date - timedelta(days=30)

candles = client.candle_data(
    exchange=Exchange.NSE,
    token="3045",
    interval="day",
    from_timestamp=start_date.strftime("%Y-%m-%dT09:15:00"),
    to_timestamp=end_date.strftime("%Y-%m-%dT15:30:00"),
    oi=False
)

print(f"Retrieved {len(candles.get('data', []))} daily candles")

F&O Candles with Open Interest

# Get F&O candles with OI data
candles = client.candle_data(
    exchange=Exchange.NFO,
    token="46799",  # NIFTY option token
    interval="15min",
    from_timestamp="2024-01-15T09:15:00",
    to_timestamp="2024-01-15T15:30:00",
    oi=True  # Include Open Interest
)

for candle in candles.get('data', []):
    print(f"Time: {candle['time']} | OI: {candle.get('oi', 'N/A')}")

Instruments

Get the complete list of tradable instruments.

# Get all instruments
instruments = client.get_instruments()

# Filter NSE equity instruments
nse_equity = [i for i in instruments if i.get('exchange') == 'NSE' and i.get('segment') == 'EQ']
print(f"NSE Equity instruments: {len(nse_equity)}")

# Find specific instrument
reliance = next((i for i in instruments if i.get('symbol') == 'RELIANCE-EQ'), None)
if reliance:
    print(f"RELIANCE Token: {reliance['token']}")
    print(f"Lot Size: {reliance['lotSize']}")
    print(f"Tick Size: {reliance['tickSize']}")

Instrument Fields

Field Description
token Unique instrument token
symbol Trading symbol
name Instrument name
exchange Exchange code
segment Market segment
lotSize Minimum trading lot
tickSize Minimum price movement
expiry Expiry date (for derivatives)
strike Strike price (for options)
optionType CE (Call) / PE (Put)

Option Chain

Get option chain symbols and data.

Get Option Chain Symbols

# Get all option chain symbols
option_symbols = client.get_option_chain_symbols()
print(f"Available option chains: {option_symbols}")

Get Expiry Dates

# Get expiry dates for NIFTY options (static method)
expiries = ArrowClient.get_expiry_dates("NIFTY", 2024)
print(f"NIFTY Expiries: {expiries}")

Index List

Get available index listings.

# Get all indices
indices = client.get_index_list()

for index in indices:
    print(f"{index['name']}: {index['symbol']}")

Market Holidays

Get market holiday calendar.

# Get market holidays
holidays = client.get_holidays()

print("Market Holidays:")
for holiday in holidays.get('data', []):
    print(f"  {holiday['date']}: {holiday['description']}")

Example: Market Scanner

from pyarrow import ArrowClient, QuoteMode, Exchange

def market_scanner(client, symbols):
    """Scan multiple stocks and identify opportunities."""

    # Build symbol list for quotes
    symbol_list = [(sym, Exchange.NSE) for sym in symbols]

    # Get OHLCV quotes
    quotes = client.get_quotes(QuoteMode.OHLCV, symbols=symbol_list)

    gainers = []
    losers = []
    high_volume = []

    for quote in quotes:
        symbol = quote['symbol']
        change = float(quote.get('change', 0))
        volume = int(quote.get('volume', 0))
        high = float(quote.get('high', 0))
        low = float(quote.get('low', 0))
        ltp = float(quote.get('ltp', 0))

        # Categorize
        if change > 2:
            gainers.append((symbol, change))
        elif change < -2:
            losers.append((symbol, change))

        # High volume check (example threshold)
        if volume > 1000000:
            high_volume.append((symbol, volume))

    # Display results
    print("\n📈 TOP GAINERS (>2%)")
    for sym, chg in sorted(gainers, key=lambda x: x[1], reverse=True)[:5]:
        print(f"  {sym}: +{chg:.2f}%")

    print("\n📉 TOP LOSERS (<-2%)")
    for sym, chg in sorted(losers, key=lambda x: x[1])[:5]:
        print(f"  {sym}: {chg:.2f}%")

    print("\n📊 HIGH VOLUME")
    for sym, vol in sorted(high_volume, key=lambda x: x[1], reverse=True)[:5]:
        print(f"  {sym}: {vol:,}")

# Usage
watchlist = ["RELIANCE-EQ", "TCS-EQ", "INFY-EQ", "HDFCBANK-EQ", "ICICIBANK-EQ"]
market_scanner(client, watchlist)

Example: Technical Analysis Setup

from pyarrow import ArrowClient, Exchange
from datetime import datetime, timedelta

def get_technical_data(client, symbol, token, days=30):
    """Fetch data for technical analysis."""

    end_date = datetime.now()
    start_date = end_date - timedelta(days=days)

    # Get daily candles
    candles = client.candle_data(
        exchange=Exchange.NSE,
        token=token,
        interval="day",
        from_timestamp=start_date.strftime("%Y-%m-%dT09:15:00"),
        to_timestamp=end_date.strftime("%Y-%m-%dT15:30:00"),
        oi=False
    )

    data = candles.get('data', [])

    if not data:
        print(f"No data for {symbol}")
        return None

    # Calculate simple moving averages
    closes = [float(c['close']) for c in data]

    def sma(prices, period):
        if len(prices) < period:
            return None
        return sum(prices[-period:]) / period

    sma_5 = sma(closes, 5)
    sma_20 = sma(closes, 20)

    latest = data[-1]

    print(f"\n📊 {symbol} Technical Summary")
    print("=" * 40)
    print(f"Latest Close: ₹{latest['close']}")
    print(f"5-Day SMA:    ₹{sma_5:.2f}" if sma_5 else "5-Day SMA: N/A")
    print(f"20-Day SMA:   ₹{sma_20:.2f}" if sma_20 else "20-Day SMA: N/A")

    # Simple trend detection
    if sma_5 and sma_20:
        if sma_5 > sma_20:
            print("Trend: 📈 BULLISH (5 SMA > 20 SMA)")
        else:
            print("Trend: 📉 BEARISH (5 SMA < 20 SMA)")

    # 52-week high/low from available data
    highs = [float(c['high']) for c in data]
    lows = [float(c['low']) for c in data]

    print(f"\n{days}-Day High: ₹{max(highs):.2f}")
    print(f"{days}-Day Low:  ₹{min(lows):.2f}")

    return {
        'symbol': symbol,
        'close': float(latest['close']),
        'sma_5': sma_5,
        'sma_20': sma_20,
        'period_high': max(highs),
        'period_low': min(lows)
    }

# Usage
tech_data = get_technical_data(client, "RELIANCE-EQ", "3045", days=30)

Quote Response Fields

LTP Mode Fields

Field Type Description
symbol string Trading symbol
ltp number Last traded price
change number Price change %
timestamp string Quote timestamp

OHLCV Mode Fields

Field Type Description
open number Opening price
high number Day's high
low number Day's low
close number Previous close
ltp number Last traded price
volume number Traded volume

Full Mode Additional Fields

Field Type Description
oi number Open Interest
oi_day_high number OI day high
oi_day_low number OI day low
upper_limit number Upper circuit limit
lower_limit number Lower circuit limit
bids array 5 bid levels
asks array 5 ask levels
total_buy_quantity number Total buy quantity
total_sell_quantity number Total sell quantity