Skip to content
This repository was archived by the owner on Aug 11, 2026. It is now read-only.

Repository files navigation

Delta Hedge

🚧 Archived — not actively maintained

This project was built during October–November 2025 as a portfolio piece demonstrating multi-exchange delta-neutral trading infrastructure. It is published as-is for reference. No active development, bug fixes, or maintenance are planned. See Project Status and docs/known-issues.md for the honest state of the codebase.

Python 3.12 React 18 TypeScript 5.5 FastAPI 0.115 License: MIT Status: Archived


What this is

Delta-neutral trading dashboard for perpetual futures across Hyperliquid, Paradex, and Lighter.

A delta-neutral position is a market-neutral trade: take the same notional exposure in opposite directions on two correlated assets (typically spot vs. perpetual, or perp vs. perp on different venues) so the portfolio's net delta is zero. The trade then earns from funding-rate spreads and small price dislocations rather than from directional price movement.

This project is a working dashboard for that workflow. It aggregates funding rates, market data, positions, and order books across three perpetual-futures exchanges, surfaces funding-spread opportunities, and executes paired trades through a FastAPI backend with a React/TypeScript front end.

The goal was to demonstrate full-stack trading infrastructure — exchange connectors, a real-time WebSocket layer, position/PnL analytics, and a deployable UI — end to end. It is not a production trading system and it never traded with real capital.


Project Status

This section is the part that matters. The project is unfinished, and the README would be doing a disservice by pretending otherwise.

Exchange connector coverage

Exchange Status Notes
Hyperliquid ✅ Complete Market data, account, orders, position close, leverage. Asset-specific size precision.
Paradex ✅ Complete Market data, account, orders, position close. Leverage setting not supported by exchange API (leverage is auto-determined; default testnet is 50x). Requires Python 3.12 for the SDK.
Lighter ⚠️ Partial (~50%) Market data, orders, position close, balance, history work. modify_order() and set_leverage() are stubs that raise NotImplementedError. Batch orders are a sequential loop, not a native batch.

What works

  • Delta-neutral execution. Simultaneous market orders across two exchanges, with automatic rollback (cancels the filled leg if the counterpart fails).
  • Real-time position management. Live positions, unrealized PnL, position close (full and partial) across exchanges.
  • Funding rate analysis. Cross-exchange funding comparison, spread identification, opportunity ranking, execution from the opportunity view.
  • PnL & volume analytics. Net / realized / unrealized PnL, funding received/paid, fees, volume by exchange / pair / side / time period, win rate, average profit per trade, best/worst trade.
  • Opportunity discovery. Funding-spread scanner and price-arbitrage signals with a click-through path to execution.
  • WebSocket updates. Live position, PnL, and execution notifications over a custom WebSocket manager.

What doesn't work (or works with caveats)

  • Funding & History tab in the front end is a placeholder. The UI components exist, but the backend never writes historical trade or funding data to the database (SQLModel models and Alembic migrations are defined, no write path), so the tab has no data to render.
  • Leverage selection is unreliable. The UI slider may be silently ignored or the backend call may fail.
  • Rapid trade execution can leave the front end out of sync with exchange state — there is no queuing or debouncing of state updates.
  • WebSocket reconnection is not implemented. If a connection drops, real-time updates stop until a manual page refresh.
  • Paradex token refresh has unhandled edge cases near JWT expiry.
  • Number formatting in PnL, trade profit, and fee displays has sign and precision bugs in several components (PnLTab, TransactionNotification, TradeExecutionDropdown).
  • Database persistence is effectively absent. Models exist; writes do not.

The full bug list, incomplete features, design debt, and "not implemented" backlog are documented in docs/known-issues.md.


Architecture

┌──────────────────────────┐         ┌──────────────────────────────────────┐
│  React 18 + TypeScript   │  HTTP   │            FastAPI Backend           │
│  (Vite, Recharts, Axios) │ ──────▶ │  (Python 3.12, SQLModel, Alembic)   │
│                          │         │                                      │
│  Dashboard tabs:         │  WS     │  Routers:                            │
│  • Opportunities         │ ◀─────  │  • /exchanges/hyperliquid/*          │
│  • Positions & Orders    │         │  • /exchanges/paradex/*              │
│  • PnL                   │         │  • /exchanges/lighter/*              │
│  • Funding & History ⚠   │         │  • /opportunities/funding/{pair}     │
│                          │         │  • /history/*                        │
└──────────────────────────┘         │  • /ws (WebSocket manager)           │
                                     │                                      │
                                     │  Connectors:                         │
                                     │  • hyperliquid-python-sdk  ✅        │
                                     │  • paradex-py             ✅        │
                                     │  • lighter-sdk            ⚠         │
                                     │                                      │
                                     │  Storage:                            │
                                     │  • SQLite (schema only, no writes)   │
                                     └──────────────────────────────────────┘

The back end exposes a versioned REST API per exchange plus a single WebSocket stream that fans out position, PnL, and execution events to subscribed clients. Each exchange has its own connector module that implements a shared ExchangeConnector interface, which is what made adding Lighter tractable.

The front end is a tabbed dashboard. Tabs render live data through Axios (HTTP) and a custom WebSocket client (push), with Recharts powering the analytics visualizations under a single terminal-style theme.


Tech Stack

Layer Technology
Backend language Python 3.12 (Paradex SDK paradex-py does not support 3.13)
Backend framework FastAPI 0.115
ASGI server Uvicorn
ORM / migrations SQLModel 0.0.21 + SQLAlchemy 2.0 + Alembic 1.13
Logging structlog 24.4 (JSON logs, automatic secret redaction)
Exchange SDKs hyperliquid-python-sdk 0.20, paradex-py (Python 3.12 only), lighter-sdk (via lighter-python)
Frontend framework React 18.3 + TypeScript 5.5
Build tool Vite 5.4
Charts Recharts 2.12
HTTP client Axios 1.7
Database SQLite (schema defined, write path not implemented)

Setup

Tested on macOS with Python 3.12 and Node.js 18+.

Prerequisites

  • Python 3.12 (required for paradex-py; the Paradex connector will not work on 3.13)
  • Node.js 18+ and npm
  • Homebrew (for brew install python@3.12 on macOS)

1. Clone the repository

git clone <repo-url> delta-hedge
cd delta-hedge

2. Backend

# Install Python 3.12 if you don't have it
brew install python@3.12

# Create a Python 3.12 virtual environment
cd backend
python3.12 -m venv .venv312
source .venv312/bin/activate

# Install dependencies
pip install -r requirements.txt

# Copy the environment template and fill in your real credentials
cp .env.example .env
# Edit .env with your wallet keys and exchange settings.
# The .env.example file lists every variable with placeholder values.

# Run database migrations
alembic upgrade head

# Start the API server
uvicorn app.main:app --reload

The API will be available at http://127.0.0.1:8000 and the auto-generated docs at http://127.0.0.1:8000/docs.

Why .venv312? The backend repo also has a .venv (Python 3.13) for the general path. The paradex-py SDK does not support Python 3.13, so the Paradex connector needs .venv312. Use .venv312 for everything to keep things simple — that is the supported configuration.

3. Frontend

In a separate terminal:

cd frontend
npm install
npm run dev

The dashboard will be available at http://localhost:3000. The Vite dev server is configured to proxy /api requests to the FastAPI backend, so no extra configuration is needed for local development.

4. Environment variables

Both .env.example files are the source of truth for which variables to set:

  • backend/.env.example — database path, log level, Hyperliquid wallet key, Paradex L1/L2 addresses and key, Lighter credentials, slippage and leverage limits.
  • .env.example (project root) — Lighter-specific credentials, kept separately because they are added in a different setup step.

Never commit real keys. The .gitignore excludes .env, *.bak, and similar files. Use only the .env.example files as a template.


Project Structure

delta-hedge/
├── backend/
│   ├── app/
│   │   ├── connectors/              # Exchange connectors
│   │   │   ├── base/                # ExchangeConnector interface
│   │   │   ├── hyperliquid/         # ✅ Full coverage
│   │   │   ├── paradex/             # ✅ Full coverage
│   │   │   └── lighter/             # ⚠ ~50% — 2 NotImplementedError stubs
│   │   ├── routers/                 # FastAPI route handlers
│   │   │   ├── hyperliquid.py
│   │   │   ├── paradex.py
│   │   │   ├── lighter.py
│   │   │   ├── strategies.py        # Delta-neutral execution
│   │   │   ├── history.py           # Historical / volume queries
│   │   │   ├── opportunities.py
│   │   │   └── websocket.py
│   │   ├── services/                # Exchange manager, data aggregator, persistence
│   │   ├── models.py                # SQLModel database models
│   │   └── main.py                  # FastAPI app entry point
│   ├── alembic/                     # Database migrations
│   ├── tests/                       # Pytest suite
│   ├── scripts/                     # Diagnostic and helper scripts
│   ├── requirements.txt
│   └── README.md                    # Backend-specific documentation
├── frontend/
│   ├── src/
│   │   ├── components/              # React components (Dashboard, PnLTab, …)
│   │   ├── services/                # API + WebSocket clients
│   │   └── styles/                  # Theme and component styles
│   ├── package.json
│   └── README.md                    # Frontend-specific documentation
├── docs/
│   └── known-issues.md              # Full bug list + design debt + "not implemented" backlog
├── .env.example                     # Lighter env template
├── PROJECT_SUMMARY.md               # Original project write-up (Oct–Nov 2025)
├── SETUP_INSTRUCTIONS.md            # Detailed Lighter onboarding steps
├── ADDING_NEW_EXCHANGES.md          # Connector authoring guide
├── WEBSOCKET_COMPARISON.md          # Per-exchange WebSocket behavior notes
└── README.md                        # ← you are here

Known Issues

The full list lives in docs/known-issues.md. The highlights:

Bugs (medium severity):

  • WebSocket reconnection is not implemented
  • Paradex token refresh has unhandled expiry edge cases
  • Rapid trade execution can desync the front end
  • PnL / fee / slippage number formatting has sign and precision bugs in PnLTab, TransactionNotification, TradeExecutionDropdown
  • Leverage selection in the UI is not reliably applied before order placement (high severity)

Incomplete features:

  • Lighter connector is ~50% complete (modify_order and set_leverage are stubs)
  • Funding & History tab is a placeholder (UI is there, no data is written to the database)
  • Paradex has no programmatic leverage API — leverage is always exchange-determined (50x on testnet)

Design debt:

  • 5 NotImplementedError stubs across Paradex and Lighter
  • 8 raw print() statements in the Paradex connector that bypass the structured logger
  • SQLModel schemas defined but no write path — the database is effectively empty
  • Inconsistent error formatting between Python tracebacks, generic 500s, and exchange-specific messages

Not implemented (scoped but never built):

  • Database persistence (would unblock the Funding & History tab and CSV export)
  • Full WebSocket push coverage across all three exchanges
  • Automated delta-neutral strategies (funding-rate and price-arbitrage bots)
  • Historical backtesting
  • Docker / CI-CD
  • Mobile responsiveness, dark/light theme toggle, alerting

See the linked doc for the prioritized list and source citations.


License

MIT


Disclaimer

This project is a portfolio piece, not a trading system. It was built for educational and demonstration purposes, was never used with real funds, and is published as-is. Nothing in this repository constitutes financial advice or a recommendation to trade on any of the integrated venues. Trading perpetual futures carries substantial risk of loss.

About

Multi-exchange delta-neutral trading dashboard for perpetual futures — FastAPI + React. Hyperliquid, Paradex, and Lighter connectors with funding rate arbitrage engine.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages