565 lines
19 KiB
Markdown
565 lines
19 KiB
Markdown
---
|
|
description: "Complete Python API reference (DataAPI and ChartingAPI) with full source and docstrings for use in research scripts."
|
|
---
|
|
|
|
# Dexorder Research API Reference
|
|
|
|
This file contains the complete Python API source code with full docstrings.
|
|
These files are copied verbatim from `sandbox/dexorder/api/`.
|
|
|
|
The API provides access to market data and charting capabilities for research scripts.
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
Research scripts access the API via:
|
|
```python
|
|
from dexorder.api import get_api
|
|
api = get_api()
|
|
```
|
|
|
|
The API instance provides:
|
|
- `api.data` - DataAPI for fetching OHLC market data
|
|
- `api.charting` - ChartingAPI for creating financial charts
|
|
|
|
---
|
|
|
|
## Complete API Source Code
|
|
|
|
The following sections contain the verbatim Python source files with complete
|
|
type hints, docstrings, and examples.
|
|
|
|
|
|
### api.py
|
|
```python
|
|
"""
|
|
Main Dexorder API - provides access to market data and charting.
|
|
"""
|
|
|
|
import logging
|
|
|
|
from .charting_api import ChartingAPI
|
|
from .data_api import DataAPI
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
class API:
|
|
"""
|
|
Main API for accessing market data and creating charts.
|
|
|
|
This is the primary interface for research scripts and trading strategies.
|
|
Access this via get_api() in research scripts.
|
|
|
|
Attributes:
|
|
data: DataAPI for fetching historical and current market data
|
|
charting: ChartingAPI for creating candlestick charts and visualizations
|
|
|
|
Example:
|
|
from dexorder.api import get_api
|
|
import asyncio
|
|
|
|
api = get_api()
|
|
|
|
# Fetch data
|
|
df = asyncio.run(api.data.historical_ohlc(
|
|
ticker="BTC/USDT.BINANCE",
|
|
period_seconds=3600,
|
|
start_time="2021-12-20",
|
|
end_time="2021-12-21"
|
|
))
|
|
|
|
# Create chart
|
|
fig, ax = api.charting.plot_ohlc(df, title="BTC/USDT 1H")
|
|
"""
|
|
|
|
def __init__(self, charting: ChartingAPI, data: DataAPI):
|
|
self.charting: ChartingAPI = charting
|
|
self.data: DataAPI = data
|
|
```
|
|
|
|
|
|
### data_api.py
|
|
```python
|
|
from abc import ABC, abstractmethod
|
|
from typing import Optional, List
|
|
|
|
import pandas as pd
|
|
|
|
from dexorder.utils import TimestampInput
|
|
|
|
|
|
class DataAPI(ABC):
|
|
"""
|
|
API for accessing market data.
|
|
|
|
Provides methods to query OHLC (Open, High, Low, Close) candlestick data
|
|
for cryptocurrency markets.
|
|
"""
|
|
|
|
@abstractmethod
|
|
async def historical_ohlc(
|
|
self,
|
|
ticker: str,
|
|
period_seconds: int,
|
|
start_time: TimestampInput,
|
|
end_time: TimestampInput,
|
|
extra_columns: Optional[List[str]] = None,
|
|
) -> pd.DataFrame:
|
|
"""
|
|
Fetch historical OHLC candlestick data for a market.
|
|
|
|
Args:
|
|
ticker: Market identifier in format "MARKET.EXCHANGE"
|
|
Examples: "BTC/USDT.BINANCE", "ETH/USD.COINBASE"
|
|
period_seconds: Candle period in seconds
|
|
Common values:
|
|
- 60 (1 minute)
|
|
- 300 (5 minutes)
|
|
- 900 (15 minutes)
|
|
- 3600 (1 hour)
|
|
- 86400 (1 day)
|
|
- 604800 (1 week)
|
|
start_time: Start of time range. Accepts:
|
|
- Unix timestamp in seconds (int/float): 1640000000
|
|
- Date string: "2021-12-20" or "2021-12-20 12:00:00"
|
|
- datetime object: datetime(2021, 12, 20)
|
|
- pandas Timestamp: pd.Timestamp("2021-12-20")
|
|
end_time: End of time range. Same formats as start_time.
|
|
extra_columns: Optional additional columns to include beyond the standard
|
|
OHLC columns. Available options (all populated for Binance data):
|
|
- "volume" - Total base-asset volume (decimal float)
|
|
- "buy_vol" - Taker buy volume in base asset (decimal float)
|
|
- "sell_vol" - Taker sell volume in base asset (decimal float)
|
|
- "quote_volume" - Total quote-asset volume, e.g. USDT (decimal float)
|
|
- "num_trades" - Number of trades in the candle (integer)
|
|
- "open_time", "close_time" (nanosecond timestamps; Binance only)
|
|
- "high_time", "low_time" (not provided by any exchange; always null)
|
|
- "open_interest" (for futures markets)
|
|
- "ticker", "period_seconds"
|
|
|
|
Returns:
|
|
DataFrame with candlestick data sorted by timestamp (ascending).
|
|
Standard columns (always included):
|
|
- timestamp: Period start time in nanoseconds
|
|
- open: Opening price (decimal float)
|
|
- high: Highest price (decimal float)
|
|
- low: Lowest price (decimal float)
|
|
- close: Closing price (decimal float)
|
|
|
|
Plus any columns specified in extra_columns.
|
|
|
|
All prices and volumes are automatically converted to decimal floats
|
|
using market metadata. No manual conversion is needed.
|
|
|
|
Returns empty DataFrame if no data is available.
|
|
|
|
Examples:
|
|
# Basic OHLC with Unix timestamp
|
|
df = await api.historical_ohlc(
|
|
ticker="BTC/USDT.BINANCE",
|
|
period_seconds=3600,
|
|
start_time=1640000000,
|
|
end_time=1640086400
|
|
)
|
|
|
|
# Using date strings with volume
|
|
df = await api.historical_ohlc(
|
|
ticker="BTC/USDT.BINANCE",
|
|
period_seconds=3600,
|
|
start_time="2021-12-20",
|
|
end_time="2021-12-21",
|
|
extra_columns=["volume"]
|
|
)
|
|
|
|
# Using datetime objects
|
|
from datetime import datetime
|
|
df = await api.historical_ohlc(
|
|
ticker="ETH/USD.COINBASE",
|
|
period_seconds=300,
|
|
start_time=datetime(2021, 12, 20, 9, 30),
|
|
end_time=datetime(2021, 12, 20, 16, 30),
|
|
extra_columns=["volume", "buy_vol", "sell_vol"]
|
|
)
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def latest_ohlc(
|
|
self,
|
|
ticker: str,
|
|
period_seconds: int,
|
|
length: int = 1,
|
|
extra_columns: Optional[List[str]] = None,
|
|
) -> pd.DataFrame:
|
|
"""
|
|
Query the most recent OHLC candles for a ticker.
|
|
|
|
This method fetches the latest N completed candles without needing to
|
|
specify exact timestamps. Useful for real-time analysis and indicators.
|
|
|
|
Args:
|
|
ticker: Market identifier in format "MARKET.EXCHANGE"
|
|
Examples: "BTC/USDT.BINANCE", "ETH/USD.COINBASE"
|
|
period_seconds: OHLC candle period in seconds
|
|
Common values: 60 (1m), 300 (5m), 900 (15m), 3600 (1h),
|
|
86400 (1d), 604800 (1w)
|
|
length: Number of most recent candles to return (default: 1)
|
|
extra_columns: Optional list of additional column names to include.
|
|
Same column options as historical_ohlc:
|
|
- "volume", "buy_vol", "sell_vol", "quote_volume", "num_trades"
|
|
- "open_time", "close_time", "high_time", "low_time"
|
|
- "open_interest", "ticker", "period_seconds"
|
|
|
|
Returns:
|
|
Pandas DataFrame with the same column structure as historical_ohlc,
|
|
containing the N most recent completed candles sorted by timestamp.
|
|
Returns empty DataFrame if no data is available.
|
|
|
|
Examples:
|
|
# Get the last candle
|
|
df = await api.latest_ohlc(
|
|
ticker="BTC/USDT.BINANCE",
|
|
period_seconds=3600
|
|
)
|
|
# Returns: timestamp, open, high, low, close
|
|
|
|
# Get the last 50 5-minute candles with volume
|
|
df = await api.latest_ohlc(
|
|
ticker="ETH/USD.COINBASE",
|
|
period_seconds=300,
|
|
length=50,
|
|
extra_columns=["volume", "buy_vol", "sell_vol"]
|
|
)
|
|
|
|
# Get recent candles with all timing data
|
|
df = await api.latest_ohlc(
|
|
ticker="BTC/USDT.BINANCE",
|
|
period_seconds=60,
|
|
length=100,
|
|
extra_columns=["open_time", "high_time", "low_time", "close_time"]
|
|
)
|
|
|
|
Note:
|
|
This method returns only completed candles. The current (incomplete)
|
|
candle is not included.
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def get_ticker_24h(
|
|
self,
|
|
exchange: str,
|
|
limit: Optional[int] = None,
|
|
min_std_quote_volume: Optional[float] = None,
|
|
market_type: Optional[str] = None,
|
|
base_asset_contains: Optional[str] = None,
|
|
) -> pd.DataFrame:
|
|
"""
|
|
Retrieve 24h rolling market stats for all symbols on an exchange.
|
|
|
|
Data is refreshed hourly by the ingestor pipeline. Use this to build a
|
|
pre-filtered symbol universe before running a scanner — it avoids requesting
|
|
per-symbol OHLC data for thousands of symbols.
|
|
|
|
Args:
|
|
exchange: Exchange name (e.g., "BINANCE", "COINBASE", "KRAKEN")
|
|
limit: If set, return only the Top N symbols By Volume. None = return all.
|
|
min_std_quote_volume: Exclude symbols with USD volume below this threshold.
|
|
market_type: Filter by market type: "spot" or "perp". None = return all.
|
|
base_asset_contains: Filter to symbols whose base asset contains this string
|
|
(case-insensitive). E.g., "BTC" matches "BTC/USDT".
|
|
|
|
Returns:
|
|
DataFrame sorted by std_quote_volume descending (NULLs last). Columns:
|
|
- ticker: Full ticker (e.g., "BTC/USDT.BINANCE")
|
|
- exchange_id: Exchange name
|
|
- base_asset: Base currency (e.g., "BTC")
|
|
- quote_asset: Quote currency (e.g., "USDT")
|
|
- last_price: Last traded price in quote currency
|
|
- price_change_pct: 24h price change as percentage (e.g. 2.5 = +2.5%)
|
|
- quote_volume_24h: Raw 24h volume in quote asset
|
|
- std_quote_volume: quote_volume_24h normalized to USD (NaN if conversion unknown)
|
|
- bid_price, ask_price: Current best bid/ask (NaN if not provided by exchange)
|
|
- open_24h, high_24h, low_24h: 24h OHLC prices (NaN if not provided)
|
|
- volume_24h: Base-asset volume (NaN if not provided)
|
|
- num_trades: 24h trade count (NaN if not provided)
|
|
- timestamp_ms: Snapshot timestamp in milliseconds
|
|
|
|
Returns empty DataFrame if no data is available (e.g., not yet fetched).
|
|
|
|
Examples:
|
|
# Top 50 most liquid Binance spot symbols
|
|
df = await api.data.get_ticker_24h("BINANCE", limit=50, market_type="spot")
|
|
|
|
# All BTC pairs with at least $10M daily volume
|
|
df = await api.data.get_ticker_24h("BINANCE",
|
|
base_asset_contains="BTC",
|
|
min_std_quote_volume=10_000_000)
|
|
|
|
# Build a scanner universe: all Binance symbols, sorted by volume
|
|
universe = await api.data.get_ticker_24h("BINANCE")
|
|
top_100 = universe.head(100)["ticker"].tolist()
|
|
"""
|
|
pass
|
|
|
|
```
|
|
|
|
|
|
### charting_api.py
|
|
```python
|
|
import logging
|
|
from abc import abstractmethod, ABC
|
|
from typing import Optional, Tuple, List
|
|
|
|
import pandas as pd
|
|
from matplotlib import pyplot as plt
|
|
from matplotlib.figure import Figure
|
|
|
|
|
|
class ChartingAPI(ABC):
|
|
"""
|
|
API for creating financial charts and visualizations.
|
|
|
|
Provides methods to create candlestick charts, add technical indicator panels,
|
|
and build custom visualizations. All figures are automatically captured and
|
|
returned to the client as images.
|
|
|
|
Basic workflow:
|
|
1. Create a chart with plot_ohlc() → returns Figure and Axes
|
|
2. Optionally overlay indicators on the main axes (e.g., moving averages)
|
|
3. Optionally add indicator panels below with add_indicator_panel()
|
|
4. Figures are automatically captured (no need to save manually)
|
|
"""
|
|
|
|
@abstractmethod
|
|
def plot_ohlc(
|
|
self,
|
|
df: pd.DataFrame,
|
|
title: Optional[str] = None,
|
|
volume: bool = False,
|
|
style: str = "charles",
|
|
figsize: Tuple[int, int] = (12, 8),
|
|
**kwargs
|
|
) -> Tuple[Figure, plt.Axes]:
|
|
"""
|
|
Create a candlestick chart from OHLC data.
|
|
|
|
Args:
|
|
df: DataFrame with OHLC data. Required columns: open, high, low, close.
|
|
Column names are case-insensitive.
|
|
title: Chart title (optional)
|
|
volume: If True, shows volume bars below the candlesticks (requires 'volume' column)
|
|
style: Visual style for the chart. Available styles:
|
|
"charles" (default), "binance", "blueskies", "brasil", "checkers",
|
|
"classic", "mike", "nightclouds", "sas", "starsandstripes", "yahoo"
|
|
figsize: Figure size as (width, height) in inches. Default: (12, 8)
|
|
**kwargs: Additional styling arguments
|
|
|
|
Returns:
|
|
Tuple of (Figure, Axes):
|
|
- Figure: matplotlib Figure object
|
|
- Axes: Main candlestick axes (use for overlaying indicators)
|
|
|
|
Examples:
|
|
# Basic chart
|
|
fig, ax = api.plot_ohlc(df)
|
|
|
|
# With volume and title
|
|
fig, ax = api.plot_ohlc(
|
|
df,
|
|
title="BTC/USDT 1H",
|
|
volume=True,
|
|
style="binance"
|
|
)
|
|
|
|
# Overlay moving average
|
|
# NOTE: mplfinance uses integer x-positions (0..N-1) internally,
|
|
# so overlays must use range(len(df)), not df.index.
|
|
fig, ax = api.plot_ohlc(df)
|
|
ax.plot(range(len(df)), df['sma_20'], label="SMA 20", color="blue")
|
|
ax.legend()
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def add_indicator_panel(
|
|
self,
|
|
fig: Figure,
|
|
df: pd.DataFrame,
|
|
columns: Optional[List[str]] = None,
|
|
ylabel: Optional[str] = None,
|
|
height_ratio: float = 0.3,
|
|
ylim: Optional[Tuple[float, float]] = None,
|
|
**kwargs
|
|
) -> plt.Axes:
|
|
"""
|
|
Add an indicator panel below the chart with time-aligned x-axis.
|
|
|
|
Use this to display indicators that should be shown separately from the
|
|
price chart (e.g., RSI, MACD, volume).
|
|
|
|
Args:
|
|
fig: Figure object from plot_ohlc()
|
|
df: DataFrame with indicator data (must have same index as OHLC data)
|
|
columns: Column names to plot. If None, plots all numeric columns.
|
|
ylabel: Y-axis label (e.g., "RSI", "MACD")
|
|
height_ratio: Panel height relative to main chart (default: 0.3 = 30%)
|
|
ylim: Y-axis limits as (min, max). If None, auto-scales.
|
|
**kwargs: Line styling options (color, linewidth, linestyle, alpha)
|
|
|
|
Returns:
|
|
Axes object for the new panel (use for further customization)
|
|
|
|
Examples:
|
|
# Add RSI panel with reference lines
|
|
fig, ax = api.plot_ohlc(df)
|
|
rsi_ax = api.add_indicator_panel(
|
|
fig, df,
|
|
columns=["rsi"],
|
|
ylabel="RSI",
|
|
ylim=(0, 100)
|
|
)
|
|
rsi_ax.axhline(30, color='green', linestyle='--', alpha=0.5)
|
|
rsi_ax.axhline(70, color='red', linestyle='--', alpha=0.5)
|
|
|
|
# Add MACD panel
|
|
fig, ax = api.plot_ohlc(df)
|
|
api.add_indicator_panel(
|
|
fig, df,
|
|
columns=["macd", "macd_signal"],
|
|
ylabel="MACD"
|
|
)
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def create_figure(
|
|
self,
|
|
figsize: Tuple[int, int] = (12, 8),
|
|
style: str = "charles"
|
|
) -> Tuple[Figure, plt.Axes]:
|
|
"""
|
|
Create a styled figure for custom visualizations.
|
|
|
|
Use this when you want to create charts other than candlesticks
|
|
(e.g., histograms, scatter plots, heatmaps).
|
|
|
|
Args:
|
|
figsize: Figure size as (width, height) in inches. Default: (12, 8)
|
|
style: Style name for consistent theming. Default: "charles"
|
|
|
|
Returns:
|
|
Tuple of (Figure, Axes) ready for plotting
|
|
|
|
Examples:
|
|
# Histogram
|
|
fig, ax = api.create_figure()
|
|
ax.hist(returns, bins=50)
|
|
ax.set_title("Return Distribution")
|
|
|
|
# Heatmap
|
|
fig, ax = api.create_figure(figsize=(10, 10))
|
|
import seaborn as sns
|
|
sns.heatmap(correlation_matrix, ax=ax)
|
|
ax.set_title("Correlation Matrix")
|
|
"""
|
|
pass
|
|
```
|
|
|
|
|
|
### __init__.py
|
|
```python
|
|
"""
|
|
Dexorder API - market data and charting for research and trading.
|
|
|
|
For research scripts, import and use get_api() to access the API:
|
|
|
|
from dexorder.api import get_api
|
|
import asyncio
|
|
|
|
api = get_api()
|
|
df = asyncio.run(api.data.historical_ohlc(...))
|
|
fig, ax = api.charting.plot_ohlc(df)
|
|
"""
|
|
|
|
import logging
|
|
import threading
|
|
from typing import Optional
|
|
|
|
from dexorder.api.api import API
|
|
from dexorder.api.charting_api import ChartingAPI
|
|
from dexorder.api.data_api import DataAPI
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
# Global API instance - managed by main.py
|
|
_global_api: Optional[API] = None
|
|
|
|
# Thread-local API — used by harness threads so they don't overwrite the global
|
|
_thread_local = threading.local()
|
|
|
|
|
|
def get_api() -> API:
|
|
"""
|
|
Get the API instance for accessing market data and charts.
|
|
|
|
Use this in research scripts to access the data and charting APIs.
|
|
|
|
Returns:
|
|
API instance with data and charting capabilities
|
|
|
|
Raises:
|
|
RuntimeError: If called before API initialization (should not happen in research scripts)
|
|
|
|
Example:
|
|
from dexorder.api import get_api
|
|
import asyncio
|
|
|
|
api = get_api()
|
|
|
|
# Fetch data
|
|
df = asyncio.run(api.data.historical_ohlc(
|
|
ticker="BTC/USDT.BINANCE",
|
|
period_seconds=3600,
|
|
start_time="2021-12-20",
|
|
end_time="2021-12-21"
|
|
))
|
|
|
|
# Create chart
|
|
fig, ax = api.charting.plot_ohlc(df, title="BTC/USDT")
|
|
"""
|
|
# Thread-local takes priority (set by harness threads)
|
|
api = getattr(_thread_local, 'api', None)
|
|
if api is not None:
|
|
return api
|
|
if _global_api is None:
|
|
raise RuntimeError("API not initialized")
|
|
return _global_api
|
|
|
|
|
|
def set_api(api: API) -> None:
|
|
"""Set the API instance.
|
|
|
|
When called from the main thread, sets the global API used by all threads.
|
|
When called from a non-main thread (e.g. harness threads), sets a thread-local
|
|
API so the global is not overwritten.
|
|
"""
|
|
if threading.current_thread() is threading.main_thread():
|
|
global _global_api
|
|
_global_api = api
|
|
else:
|
|
_thread_local.api = api
|
|
|
|
|
|
__all__ = ['API', 'ChartingAPI', 'DataAPI', 'get_api', 'set_api']
|
|
```
|
|
|
|
|
|
---
|
|
|
|
For practical usage patterns and complete working examples, see [`usage-examples.md`](usage-examples.md).
|
|
|
|
For the pandas-ta indicator catalog used in research scripts, see [`pandas-ta-reference.md`](pandas-ta-reference.md).
|