Skip to main content

StockAPIS SDK - Python client for cryptocurrency historical data (trades, klines)

Project description

StockAPIs

Fully typed Python SDK for cryptocurrency historical data (trades, klines) from Binance, Bybit, and OKX.

Features

  • All kline intervals — 1m, 5m, 15m, 1h, 4h, 1d and more
  • Full type safety — Pydantic models with IDE autocomplete
  • Typed data objectsOHLCV and Trade with numpy arrays
  • Async & sync — Both StockAPIs and StockAPIsSync clients
  • CLI — Command-line interface for quick exports
  • Progress tracking — Callbacks for long-running operations
  • Auto-caching — Local disk cache for repeated queries

Installation

pip install stockapis

Quick Start

Typed OHLCV Data (Recommended)

from stockapis import StockAPIs, Exchange

async with StockAPIs(api_key="your-api-key") as api:
    ohlcv = await api.exports.export_to_ohlcv(
        symbol="BTCUSDT",
        exchange=Exchange.BINANCE,
        from_date="2025-01-01",
        to_date="2025-01-07",
        interval="1h",
    )

    # Typed access with autocomplete
    print(f"Symbol: {ohlcv.symbol}")           # str
    print(f"Candles: {len(ohlcv)}")            # int
    print(f"Latest close: {ohlcv.close[-1]}")  # numpy float64
    print(f"Latest time: {ohlcv.datetime[-1]}")  # datetime
    print(f"Volatility: {ohlcv.volatility:.2%}")  # float (computed)

Sync Client

from stockapis import StockAPIsSync, Exchange

with StockAPIsSync(api_key="your-api-key") as api:
    ohlcv = api.exports.export_to_ohlcv(
        symbol="BTCUSDT",
        exchange=Exchange.BINANCE,
        from_date="2025-01-01",
        to_date="2025-01-07",
        interval="1h",
    )
    print(f"Loaded {len(ohlcv)} candles")

Type Safety

All API responses are Pydantic models with full type hints:

from stockapis import StockAPIs, Exchange, DataType

async with StockAPIs(api_key="your-key") as api:
    # Create a download request
    request = await api.downloads.create(
        symbol="BTCUSDT",
        exchange=Exchange.BINANCE,
        data_type=DataType.KLINES,
        from_date="2025-01-01",
        to_date="2025-01-07",
        interval="1m",
    )

    # DownloadRequest is a Pydantic model - full IDE support
    print(request.id)              # int
    print(request.symbol.symbol)   # str (nested SymbolNested model)
    print(request.symbol.exchange) # SymbolNestedExchange enum
    print(request.from_date)       # date
    print(request.to_date)         # date
    print(request.created_at)      # datetime
    print(request.status)          # DownloadRequestStatus enum
    print(request.progress_percent)  # float

    # Access segments (list of typed DownloadSegment)
    for segment in request.segments:
        print(segment.target_date)      # date
        print(segment.status)           # DownloadSegmentStatus enum
        print(segment.records_ingested) # int
        print(segment.completed_at)     # datetime | None

Response Models

Model Description
DownloadRequest Download job with segments
DownloadSegment Individual day segment
ExportJob Export job status
DataAvailabilityResponse Coverage info
AvailabilityGridResponse Monthly grid
SymbolsWithDataResponse Available symbols

All models have proper types: date, datetime, enums, nested models.

Typed Data Objects

OHLCV (Candlestick Data)

from stockapis import OHLCV

ohlcv = await api.exports.export_to_ohlcv(...)

# Typed numpy arrays
ohlcv.timestamp   # NDArray[np.int64]  — Unix ms
ohlcv.datetime    # list[datetime]    — Python datetime
ohlcv.open        # NDArray[np.float64]
ohlcv.high        # NDArray[np.float64]
ohlcv.low         # NDArray[np.float64]
ohlcv.close       # NDArray[np.float64]
ohlcv.volume      # NDArray[np.float64]

# Metadata
ohlcv.symbol      # str
ohlcv.exchange    # str
ohlcv.interval    # str

# Computed properties
ohlcv.returns     # NDArray[np.float64] — log returns
ohlcv.volatility  # float — annualized volatility
len(ohlcv)        # int — number of candles

Trade Data

from stockapis import Trade

trades = await api.exports.export_to_trades(...)

# Typed numpy arrays
trades.timestamp      # NDArray[np.int64]
trades.datetime       # list[datetime]
trades.price          # NDArray[np.float64]
trades.quantity       # NDArray[np.float64]
trades.is_buyer_maker # NDArray[np.bool_]

# Metadata
trades.symbol         # str
trades.exchange       # str
len(trades)           # int — number of trades

Status Handling

SDK properly handles all statuses including partial data availability:

from stockapis import (
    DownloadRequestStatus,
    SUCCESS_DOWNLOAD_STATUSES,
    TERMINAL_REQUEST_STATUSES,
)

# Wait for download
request = await api.downloads.download_and_wait(...)

# Check status with enums
status = DownloadRequestStatus(request.status)

if status in SUCCESS_DOWNLOAD_STATUSES:
    # COMPLETED, SKIPPED, or PARTIAL — data is available
    print(f"Success: {request.total_records_ingested} records")

elif status == DownloadRequestStatus.DEFERRED:
    # Data not yet available from exchange (1-2 day delay)
    print("Data will be available tomorrow")

elif status == DownloadRequestStatus.FAILED:
    # Check error in segments
    for seg in request.segments:
        if seg.error_message:
            print(f"{seg.target_date}: {seg.error_message}")

Status Reference

Request statuses (DownloadRequestStatus):

Status Description
PENDING Not started
PROCESSING In progress
COMPLETED All done
SKIPPED Data already exists
PARTIAL Some completed, some deferred
DEFERRED All segments deferred
FAILED At least one failed

Note: PARTIAL is a success — available data was downloaded. DEFERRED occurs when requesting data too close to today (exchanges publish with 1-2 day delay).

Export Methods

To DataFrame (Polars)

df = await api.exports.export_to_dataframe(
    symbol="BTCUSDT",
    exchange=Exchange.BINANCE,
    data_type=DataType.KLINES,
    from_date="2025-01-01",
    to_date="2025-01-07",
    interval="1m",
)
print(f"Loaded {len(df)} rows")

To File

path = await api.exports.export_to_file(
    symbol="BTCUSDT",
    exchange=Exchange.BINANCE,
    data_type=DataType.KLINES,
    from_date="2025-01-01",
    to_date="2025-01-07",
    interval="1m",
    output_path="btcusdt.csv",
    on_progress=lambda p: print(f"Progress: {p}%"),
)

Download to QuestDB

result = await api.downloads.download_to_questdb(
    symbol="BTCUSDT",
    exchange=Exchange.BINANCE,
    data_type=DataType.TRADES,
    from_date="2025-01-01",
    to_date="2025-01-31",
)
print(f"Records: {result['total_records']}")

CLI

# Set API key
export STOCKAPIS_API_KEY=your-api-key

# Export klines to file
stockapis export BTCUSDT -e binance --from 2025-01-01 --to 2025-01-07 -i 1m -o data.csv

# Download trades to QuestDB
stockapis download BTCUSDT -e binance --from 2025-01-01 --to 2025-01-31 --type trades

# Check availability
stockapis availability BTCUSDT -e binance --from 2024-01-01 --to 2024-12-31

# List jobs
stockapis list downloads
stockapis list exports

# Check status
stockapis status 123

Low-Level API

For fine-grained control:

# Create request
request = await api.downloads.create(
    symbol="BTCUSDT",
    exchange=Exchange.BINANCE,
    data_type=DataType.TRADES,
    from_date="2025-01-01",
    to_date="2025-01-07",
)

# Poll progress
async for req in api.downloads.poll_progress(request.id):
    print(f"Progress: {req.progress_percent}%")

# Or wait for completion
completed = await api.downloads.wait_for_completion(
    request.id,
    poll_interval=5.0,
    timeout=3600,
)

Check Data Availability

# Range availability (with interval for klines)
avail = await api.downloads.check_availability(
    symbol="BTCUSDT",
    exchange=Exchange.BINANCE,
    data_type=DataType.KLINES,
    from_date="2024-01-01",
    to_date="2024-12-31",
    interval="1m",  # Check specific interval
)
print(f"Coverage: {avail.coverage_percent}%")
print(f"Missing days: {avail.missing_days}")  # list[date]

# Monthly grid
grid = await api.downloads.get_availability_grid(
    symbol="BTCUSDT",
    exchange=Exchange.BINANCE,
    data_type=DataType.KLINES,
    interval="1m",
    year=2024,
)
for month in grid.months:
    print(f"{month.month}/{month.year}: {month.status}")

Configuration

# Production (default)
api = StockAPIs(api_key="sk_live_xxx")

# Development
api = StockAPIs(api_key="demo_stockapis_2024", mode="dev")

# Custom URL
api = StockAPIs(api_key="your-key", base_url="http://custom:9000")

API Keys

Type Prefix Usage
Demo demo_ Testing
Production sk_ Production

Supported Intervals

All standard kline intervals are supported:

Interval Description
1m 1 minute
3m 3 minutes
5m 5 minutes
15m 15 minutes
30m 30 minutes
1h 1 hour
2h 2 hours
4h 4 hours
6h 6 hours
8h 8 hours
12h 12 hours
1d 1 day
3d 3 days
1w 1 week
1M 1 month

Enums

from stockapis import (
    Exchange,           # BINANCE, BYBIT, OKX
    MarketType,         # SPOT, LINEAR, INVERSE
    DataType,           # KLINES, TRADES
    Granularity,        # DAILY, MONTHLY
    FileFormat,         # CSV, PARQUET, JSON
    Compression,        # NONE, GZIP, ZIP
    DownloadStatus,     # Segment statuses
    DownloadRequestStatus,  # Request statuses
    ExportJobStatus,    # Export statuses
    AvailabilityStatus, # COMPLETE, PARTIAL, EMPTY
    KlineInterval,      # Type alias for intervals
)

Error Handling

import httpx

try:
    df = await api.exports.export_to_dataframe(...)
except httpx.HTTPStatusError as e:
    print(f"API error {e.response.status_code}")
except ValueError as e:
    print(f"Validation error: {e}")
except TimeoutError as e:
    print(f"Timeout: {e}")
except ImportError as e:
    print(f"Missing polars: {e}")

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

stockapis-0.1.7.tar.gz (49.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

stockapis-0.1.7-py3-none-any.whl (75.1 kB view details)

Uploaded Python 3

File details

Details for the file stockapis-0.1.7.tar.gz.

File metadata

  • Download URL: stockapis-0.1.7.tar.gz
  • Upload date:
  • Size: 49.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.18

File hashes

Hashes for stockapis-0.1.7.tar.gz
Algorithm Hash digest
SHA256 b1045a0f3668db9e6b13ce9ce6c25a3ea97d50cb4a46e403e481cf9666557167
MD5 8d732389438f34415d0de44cf73b4ada
BLAKE2b-256 aac431a5bf952828cb886bab57904486c837fedbb4e17e92d2bd05e34ff8d4cc

See more details on using hashes here.

File details

Details for the file stockapis-0.1.7-py3-none-any.whl.

File metadata

  • Download URL: stockapis-0.1.7-py3-none-any.whl
  • Upload date:
  • Size: 75.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.18

File hashes

Hashes for stockapis-0.1.7-py3-none-any.whl
Algorithm Hash digest
SHA256 48361c4a300b8dae7be9b6896d170123091c28d3911ce654e561f6a698770b10
MD5 eb4cb7391143942b4b64b5095ef3f6bd
BLAKE2b-256 f03fdf12341115d8e4c9bcc1d94e41f24fa1673c0173d121ece5dde59e37277d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page