A professional, production-ready FastAPI service for fetching cryptocurrency OHLCV (Open, High, Low, Close, Volume) data and technical indicators using ccxt.
- π FastAPI - Modern, fast web framework for building APIs
- π Technical Indicators - EMA (20, 50, 200), RSI (14), ATR (14)
- π Multi-Exchange Support - Powered by ccxt library
- π WebSocket Streaming - Real-time data updates via WebSocket
- π³ Docker Ready - Easy deployment with Docker and docker-compose
- β Type Safe - Full type hints with mypy strict mode
- π§ͺ Tested - Comprehensive test suite with pytest (including mocked tests)
- π Well Documented - Clear API documentation with FastAPI's built-in docs
-
Clone the repository
git clone https://github.com/Nfectious/crypto-trade-analysis.git cd crypto-trade-analysis -
Create a virtual environment
python -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate
-
Install dependencies
pip install -e ".[dev]" -
Create environment file (optional)
cp .env.example .env # Edit .env to customize settings -
Run the application
uvicorn app.main:app --reload
-
Access the API
- API: http://localhost:8000
- Interactive docs: http://localhost:8000/docs
- Alternative docs: http://localhost:8000/redoc
-
Build and run with docker-compose
docker-compose up --build
-
Access the API
- API: http://localhost:8000
- Interactive docs: http://localhost:8000/docs
GET /Returns service status.
Response:
{
"status": "ok",
"message": "Simple Crypto Data API is running"
}GET /api/v1/live_dataQuery Parameters:
symbol(string, default: "BTC/USDT") - Trading pair symboltimeframe(string, default: "1h") - Candle timeframe (e.g., "1m", "5m", "1h", "1d")limit(integer, default: 250, range: 20-2000) - Number of candles to fetchexchange(string, default: "binance") - Exchange name
Example Request:
curl "http://localhost:8000/api/v1/live_data?symbol=BTC/USDT&timeframe=1h&limit=100"Response:
{
"symbol": "BTC/USDT",
"timeframe": "1h",
"exchange": "binance",
"last_price": 43250.5,
"last_timestamp": "2024-01-15T12:00:00Z",
"candles_count": 100,
"recent_candles": [
{
"timestamp": "2024-01-15T12:00:00Z",
"open": 43200.0,
"high": 43300.0,
"low": 43150.0,
"close": 43250.5,
"volume": 125.5,
"ema_20": 43180.2,
"ema_50": 43050.8,
"ema_200": null,
"rsi_14": 55.3,
"atr_14": 150.2
}
],
"latest_indicators": {
"ema_20": 43180.2,
"ema_50": 43050.8,
"ema_200": null,
"rsi_14": 55.3,
"atr_14": 150.2
},
"meta": {
"defaultType": "spot"
}
}WS /api/v1/live_data/wsQuery Parameters:
symbol(string, default: "BTC/USDT") - Trading pair symboltimeframe(string, default: "1h") - Candle timeframelimit(integer, default: 250, range: 20-2000) - Number of candles to fetchexchange(string, default: "binance") - Exchange nameinterval(integer, default: 30, range: 5-300) - Update interval in seconds
Description:
Streams live market data at regular intervals. The server will send updated candle data every interval seconds.
Example (using websocat):
websocat "ws://localhost:8000/api/v1/live_data/ws?symbol=BTC/USDT&interval=10"Example (using JavaScript):
const ws = new WebSocket("ws://localhost:8000/api/v1/live_data/ws?symbol=BTC/USDT&interval=10");
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log("Received update:", data);
};
ws.onerror = (error) => {
console.error("WebSocket error:", error);
};Response Format: Same as the REST endpoint - sends the full LiveDataResponse object every interval.
Note about null values: Technical indicators may return null for early candles where there isn't enough historical data to calculate the indicator. For example:
- EMA-20 requires at least 20 candles
- EMA-50 requires at least 50 candles
- EMA-200 requires at least 200 candles
- RSI-14 requires at least 14 candles
- ATR-14 requires at least 14 candles
The API calculates the following technical indicators using the ta library:
- EMA (Exponential Moving Average): 20, 50, and 200 periods
- RSI (Relative Strength Index): 14 period (momentum oscillator)
- ATR (Average True Range): 14 period (volatility indicator)
pytestruff check .mypy src/ruff check --fix .Configuration is managed through environment variables. Copy .env.example to .env and customize as needed:
# Application Configuration
APP_NAME="Simple Crypto Data API"
API_PREFIX="/api/v1"
# Exchange Configuration
DEFAULT_EXCHANGE="binance"
DEFAULT_MARKET_TYPE="spot"
# Rate Limiting
ENABLE_RATE_LIMIT=truecrypto-trade-analysis/
βββ src/
β βββ app/
β βββ __init__.py
β βββ main.py # FastAPI application
β βββ api/
β β βββ __init__.py
β β βββ v1/
β β βββ __init__.py
β β βββ routes_live_data.py # REST endpoints
β β βββ ws_live_data.py # WebSocket endpoint
β βββ core/
β β βββ __init__.py
β β βββ config.py # Application settings
β β βββ logging.py # Logging configuration
β βββ integrations/
β β βββ __init__.py
β β βββ exchanges.py # ccxt exchange wrapper
β βββ schemas/
β β βββ __init__.py
β β βββ live_data.py # Pydantic models
β βββ services/
β βββ __init__.py
β βββ indicators.py # Technical indicators
β βββ market_data.py # Market data processing
βββ tests/
β βββ __init__.py
β βββ test_health.py
β βββ test_live_data.py
β βββ test_live_data_mocked.py # Mocked tests for CI
βββ .github/
β βββ workflows/
β βββ ci.yml # GitHub Actions CI
βββ Dockerfile
βββ docker-compose.yml
βββ pyproject.toml
βββ .gitignore
βββ .env.example
βββ README.md
The project uses GitHub Actions for continuous integration. On every push and pull request, the workflow:
- Installs dependencies
- Runs ruff linting
- Runs mypy type checking
- Runs pytest tests
See .github/workflows/ci.yml for details.
The API handles various error conditions gracefully:
- Network Errors (503): Issues connecting to the exchange
- Exchange Errors (400): Invalid parameters or exchange-specific errors
- Validation Errors (422): Invalid query parameters
- Internal Errors (500): Unexpected server errors
This project is open source and available for educational and commercial use.
Contributions are welcome! Please feel free to submit a Pull Request.