Peru Stock API Guide: Fetch BVL Real-Time & Historical Data with Python

  1. iTick
  2. Tutorial
Peru Stock API Guide: Fetch BVL Real-Time & Historical Data with Python - iTick
Peru Stock API Guide: Fetch BVL Real-Time & Historical Data with Python

Introduction

Amid the accelerating trend toward global multi-asset allocation, Latin American capital markets — particularly Peru — have emerged as an increasingly relevant frontier for institutional and systematic investors. The Bolsa de Valores de Lima (BVL) hosts a concentrated universe of high-quality issuers, predominantly in the mining, financial services, and consumer sectors. However, reliable, low-latency, and programmatically accessible data coverage for the Peruvian market remains limited.

This guide demonstrates how to leverage the iTick Financial Data Platform to seamlessly obtain real-time Level 1 quotes, historical bar (K-line) series, and related market metrics from the BVL via clean, RESTful endpoints — enabling robust quantitative research, systematic strategy development, backtesting, and live execution workflows.


Why iTick for Peruvian Market Access?

iTick is a professional-grade market data vendor delivering unified API access across multiple asset classes and geographies. Key advantages relevant to emerging market equities include:

  • Broad geographic coverage — including major LatAm venues (Mexico, Brazil, Peru, Argentina, Chile) alongside developed markets (US, Hong Kong, A-shares, etc.)
  • Dual delivery protocols — REST for on-demand polling and historical retrieval; WebSocket for streaming real-time tick and market-by-order updates
  • Developer-first design — consistent request/response schema, comprehensive SDK examples, OpenAPI-compatible documentation
  • Institutional-grade customization — bespoke symbol universes, SLA-backed latency, and premium data entitlements available for enterprise clients

Prerequisites: Authentication & Environment Setup

All authenticated requests require an API Token obtained after registration on the iTick platform.

      API_TOKEN = "your_api_token_here"           # ← replace with your actual token
BASE_URL   = "https://api.itick.org"

    

REST API Protocol Overview

iTick REST endpoints follow HTTPS GET conventions with JSON payloads. Authentication is performed via HTTP header:

      headers = {
    "Accept":      "application/json",
    "Token":       API_TOKEN
}

    

Successful responses follow the envelope pattern:

      {
  "code": 0,
  "msg":  "ok",
  "data": {  }
}

    

Non-zero code values indicate business-level errors (rate limit, invalid symbol, subscription entitlement, etc.).

Use Case 1 – Real-Time Level 1 Quote

Retrieve current inside market, last trade, session statistics, and basic reference data for a single instrument.

Endpoint
GET /stock/quote

Required Query Parameters

  • region — ISO country/market code ("PE" for Peru)
  • code — local ticker symbol (e.g., "SCCO" – Southern Copper Corporation)

Example Implementation

      import requests

def fetch_realtime_quote(region: str, symbol: str) -> dict | None:
    """Retrieve Level 1 real-time quote for a Peruvian equity."""
    url = f"{BASE_URL}/stock/quote"
    params = {"region": region, "code": symbol}

    try:
        r = requests.get(url, headers=headers, params=params, timeout=5)
        r.raise_for_status()
        payload = r.json()

        if payload.get("code") != 0:
            print(f"API error: {payload.get('msg')}")
            return None

        quote = payload["data"]
        print(f"Ticker:        {quote.get('s')}")
        print(f"Last:          {quote.get('ld')}")
        print(f"Open:          {quote.get('o')}")
        print(f"High:          {quote.get('h')}")
        print(f"Low:           {quote.get('l')}")
        print(f"Change:        {quote.get('ch')}  ({quote.get('chp')}%)")
        print(f"Volume:        {quote.get('v'):,}")
        return quote

    except Exception as e:
        print(f"Request failed: {e}")
        return None


# Example: Southern Copper (SCCO.PE)
fetch_realtime_quote("PE", "SCCO")

    

Field reference (indicative; refer to latest docs):
ld = Last traded price
ch / chp = Absolute / percentage change from previous close
v = Session accumulated volume

Use Case 2 – Historical OHLCV Candlestick Series

Fetch time-barred aggregated data suitable for backtesting, technical analysis, and risk modeling.

Endpoint
GET /stock/kline

Key Parameters

  • region"PE"
  • code — symbol
  • kType — bar aggregation:
    1 = 1-min, 2 = 5-min, 3 = 15-min, 4 = 30-min, 5 = 60-min,
    6/8 = Daily, 7/9 = Weekly, 8/10 = Monthly (exact mapping may vary)
  • limit — number of bars to return (most recent first)
  • et — optional end timestamp (Unix ms) for anchoring the window

Example – Pandas Integration

      import requests
import pandas as pd

def fetch_ohlcv(region: str, symbol: str, ktype: int, limit: int = 200, end_ts: int = None) -> pd.DataFrame | None:
    url = f"{BASE_URL}/stock/kline"
    params = {"region": region, "code": symbol, "kType": ktype, "limit": limit}
    if end_ts:
        params["et"] = end_ts

    try:
        r = requests.get(url, headers=headers, params=params)
        r.raise_for_status()
        payload = r.json()

        if payload.get("code") != 0:
            print(f"API error: {payload.get('msg')}")
            return None

        bars = payload.get("data", [])
        if not bars:
            return None

        df = pd.DataFrame(bars)
        df.rename(columns={
            "t": "timestamp_ms",
            "o": "open",
            "h": "high",
            "l": "low",
            "c": "close",
            "v": "volume"
        }, inplace=True)

        df["datetime"] = pd.to_datetime(df["timestamp_ms"], unit="ms", utc=True)
        df.sort_values("timestamp_ms", inplace=True)
        df.set_index("datetime", inplace=True)

        print(f"Retrieved {len(df)} bars | Range: {df.index.min()}{df.index.max()}")
        return df[["open", "high", "low", "close", "volume"]]

    except Exception as e:
        print(f"Request failed: {e}")
        return None


# Example: Last 30 daily bars
df_daily = fetch_ohlcv("PE", "SCCO", ktype=8, limit=30)
if df_daily is not None:
    print(df_daily.tail())
    print("\nSummary statistics:")
    print(df_daily["close"].describe())

    

Use Case 3 – Batch Multi-Symbol Real-Time Quotes

Efficiently monitor a watchlist of Peruvian names in a single call.

Endpoint
GET /stock/quotes

Parameter

  • codes — comma-separated list of symbols

Implementation Snippet

      def fetch_batch_quotes(region: str, symbols: list[str]) -> dict | None:
    url = f"{BASE_URL}/stock/quotes"
    params = {"region": region, "codes": ",".join(symbols)}

    try:
        r = requests.get(url, headers=headers, params=params)
        r.raise_for_status()
        payload = r.json()

        if payload.get("code") != 0:
            return None

        return payload["data"]  # {symbol: quote_dict, ...}

    except Exception as e:
        print(e)
        return None


# Example watchlist
batch = fetch_batch_quotes("PE", ["SCCO", "BVN", "VOLCABC1"])

    

Important Considerations & Best Practices

  • Symbol Format & Coverage
    Peruvian tickers may require specific suffix or exchange prefix. Always validate the exact symbology via iTick’s /symbol/list endpoint or contact support (Telegram: @iticksupport | WhatsApp: +852 59046663).
  • Rate Limits & Quotas
    Free tier imposes strict call-per-minute restrictions. Production deployments typically require a paid subscription tier.
  • Latency & Data Sourcing
    REST polling introduces additional latency; high-frequency or execution-oriented strategies should migrate to WebSocket streaming. Historical data fidelity should be cross-validated when possible.
  • Error Handling & Resilience
    Implement exponential backoff, circuit breakers, and comprehensive logging around network, HTTP 4xx/5xx, and business-level (code ≠ 0) failures.

Conclusion

The Peruvian equity market offers attractive exposure to commodity super-cycles, prudent fiscal policy, and under-researched alpha opportunities. With iTick’s unified REST + WebSocket APIs, quantitative practitioners and fintech developers can efficiently incorporate BVL data into global multi-market models without building custom exchange integrations.

Start by registering at https://itick.org, obtain your token, and test the code samples above against live Peruvian symbols.

Further Reading