How to Fetch Historical Mark Price Candlestick Data Using OKX API in Python

·

When working with cryptocurrency derivatives, accurate and reliable market data is essential—especially when dealing with futures and perpetual contracts. One of the most critical data points for traders and developers alike is the mark price, which helps prevent unfair liquidations by reflecting the true fair value of a contract.

If you're using the OKX exchange API through the popular ccxt library in Python, you might have encountered a challenge when trying to retrieve historical mark price candlesticks. While fetch_mark_ohlcv seems like the right method, it may return empty results or not behave as expected. This article explains how to properly access historical mark price data using the OKX REST API, explores available methods, and provides actionable code examples.


Understanding Mark Price vs. Last Traded Price

Before diving into implementation, it's important to understand the difference between:

For risk management, backtesting, and strategy development, historical mark price OHLCV (Open, High, Low, Close, Volume) data is often more reliable than last traded prices.


Using fetch_mark_ohlcv in CCXT

The ccxt library provides a unified method called fetch_mark_ohlcv to retrieve mark price candles. However, as noted in your query, calling this method may result in an empty response:

import ccxt.async_support as ccxt
import time
import asyncio

async def fetch_data():
    exchange = ccxt.okx()
    since = int(time.time() - 300000) * 1000  # ~5 minutes ago
    ohlcv = await exchange.fetch_mark_ohlcv('ETH/USDT', '1m', since=since, limit=100)
    print(ohlcv)
    await exchange.close()

Despite correct parameters, the response body shows:

{"code":"0","msg":"","data":[]}

This happens because OKX’s /api/v5/market/mark-price-candles endpoint only returns recent data—typically within the last few minutes—and does not support deep historical queries.

👉 Access real-time and historical market data securely via OKX API


Solution: Use the History Mark Price Candles Endpoint

To retrieve older or extended historical mark price data, you must use the dedicated endpoint:

GET /api/v5/market/history-mark-price-candles

Unfortunately, as of CCXT version 2.2.80, this endpoint is not directly exposed via a high-level method like fetch_mark_ohlcv. However, you can still access it using CCXT’s built-in implicit methods.

✅ Correct Way to Call history-mark-price-candles

Here’s how to use the private method wrapper in CCXT to call this endpoint:

import ccxt.async_support as ccxt
import asyncio

async def fetch_historical_mark_candles():
    exchange = ccxt.okx({
        'enableRateLimit': True,
    })

    try:
        # Use implicit method: public_get_market_history_mark_price_candles
        params = {
            'instId': 'ETH-USDT',
            'bar': '1H',  # Timeframe: 1m, 5m, 1H, 1D, etc.
            'limit': '100',  # Max records to return
            # Optional: 'after', 'before' for pagination (in milliseconds)
        }

        response = await exchange.public_get_market_history_mark_price_candles(params)
        
        if response.get('code') == '0' and response.get('data'):
            candles = response['data']
            for candle in candles:
                timestamp = int(candle[0])  # Milliseconds
                open_price = float(candle[1])
                high_price = float(candle[2])
                low_price = float(candle[3])
                close_price = float(candle[4])
                print(f"{timestamp}: O={open_price}, H={high_price}, L={low_price}, C={close_price}")
        else:
            print("No data returned or error:", response.get('msg'))

    except Exception as e:
        print("Error:", str(e))
    finally:
        await exchange.close()

# Run the async function
asyncio.run(fetch_historical_mark_candles())
🔍 Note: The symbol format uses hyphens (ETH-USDT), not slashes (ETH/USDT), in request parameters.

Key Parameters for Historical Requests

ParameterDescription
instIdTrading pair (e.g., ETH-USDT, BTC-USDT)
barCandlestick interval (1m, 5m, 1H, 1D, etc.)
limitNumber of records (max usually 100)
afterReturn data newer than this timestamp (ms)
beforeReturn data older than this timestamp (ms)

You can paginate through large datasets by adjusting before and after.


When to Use Each Method?

MethodUse Case
fetch_mark_ohlcv()Real-time or near-real-time mark price candles (last few minutes)
public_get_market_history_mark_price_candles()Retrieving older historical mark price data beyond the live window

👉 Retrieve extended historical derivatives data with low-latency API access


Common Issues & Fixes

❌ Empty Data Array ("data": [])

❌ Invalid Symbol Format

❌ Rate Limiting


Core Keywords for SEO & Search Intent

To ensure visibility and relevance for developers searching for solutions:

These keywords are naturally integrated throughout this guide to align with common developer queries while maintaining readability and technical accuracy.


Frequently Asked Questions (FAQ)

Q: Does fetch_mark_ohlcv support historical data on OKX?

No. The fetch_mark_ohlcv method maps to /api/v5/market/mark-price-candles, which only returns recent data (typically within the last few minutes). For deeper history, use the /history-mark-price-candles endpoint via public_get_market_history_mark_price_candles.

Q: Why am I getting an empty array from OKX mark price API?

Empty responses usually occur when:

Switching to the history endpoint resolves most cases.

Q: Can I use CCXT to call undocumented or implicit APIs?

Yes. CCXT supports implicit API methods like public_get_{path} and private_post_{path}. These allow access to endpoints not yet wrapped in high-level functions.

Q: What timeframes are supported for mark price candles?

Supported bars include: 1m, 5m, 15m, 30m, 1H, 4H, 1D, 1W, 1M.

Q: Is authentication required to get historical mark price data?

No. The /market/history-mark-price-candles endpoint is public. No API keys are needed unless you're making high-frequency requests.

Q: How far back can I fetch historical mark price data?

OKX typically retains several months of historical mark price data, but exact retention varies. Always paginate using before/after timestamps to stream longer histories.


👉 Build robust trading bots with precise mark price data from OKX


By leveraging the correct endpoints and understanding the limitations of unified methods like fetch_mark_ohlcv, developers can reliably integrate high-quality historical mark price data into their trading systems. Whether you're building risk engines, backtesting frameworks, or analytics dashboards, using the proper API calls ensures accuracy and consistency across your applications.