Quant Copilot is a quantitative trading strategy platform that allows users to generate, backtest, and manage trading strategies using AI. The backend is built with FastAPI and provides comprehensive endpoints for strategy management, backtesting, and leaderboard functionality.
- FastAPI Application: Main web framework
- SQLModel: Database ORM with SQLite/PostgreSQL support
- Redis: Caching and OTP storage
- Backtrader: Strategy backtesting engine
- Google Gemini: LLM for strategy generation and explanation
- JWT Authentication: Token-based auth with email OTP verification
- User: User management
- Strategy: Strategy storage
- LeaderboardEntry: Performance tracking
- StrategyBlueprint: Visual strategy builder schema
The application uses email-based OTP authentication instead of traditional passwords.
- User requests OTP with email
- System generates 6-digit OTP, stores in Redis (10min expiry)
- OTP sent via SMTP email
- User verifies OTP
- System issues JWT token (15-day expiry)
- Token required for protected endpoints
POST /auth/request-otpPOST /auth/verify-otp
POST /auth/request-otp
Content-Type: application/json
{
"email": "user@example.com"
}Response:
{
"message": "OTP sent to your email."
}POST /auth/verify-otp
Content-Type: application/json
{
"email": "user@example.com",
"otp_code": "123456"
}Response:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"token_type": "bearer"
}POST /generate
Content-Type: application/json
{
"user_prompt": "Create a moving average crossover strategy"
}Response:
{
"generated_code": "import backtrader as bt\n\nclass Strategy(bt.Strategy):\n ..."
}POST /builder/translate
Content-Type: application/json
{
"asset": "RELIANCE.NS",
"timeframe": "1d",
"entry": [
{
"indicator": "sma",
"operator": "crosses_above",
"value": null,
"params": {
"lookback": 20
}
}
],
"exit": [
{
"indicator": "sma",
"operator": "crosses_below",
"value": null,
"params": {
"lookback": 50
}
}
],
"risk": {
"stop_loss": 5.0,
"take_profit": 10.0
},
"position_sizing": "fixed"
}Response:
{
"prompt": "Build a strategy on RELIANCE.NS using 1d candles...",
"generated_code": "import backtrader as bt\n..."
}POST /strategy/save
Authorization: Bearer <token>
Content-Type: application/json
{
"name": "My Strategy",
"prompt": "Moving average strategy",
"code": "import backtrader as bt\n..."
}Response:
{
"message": "Strategy saved successfully",
"strategy_id": 123
}GET /strategy/list?strategy_id=123Response:
[
{
"id": 1,
"name": "MA Crossover",
"prompt": "Create moving average strategy",
"code": "import backtrader as bt\n...",
"created_at": "2023-12-01T10:00:00"
}
]GET /strategy/{strategy_id}Response:
{
"id": 1,
"name": "MA Crossover",
"prompt": "Create moving average strategy",
"code": "import backtrader as bt\n...",
"created_at": "2023-12-01T10:00:00"
}DELETE /strategy/{strategy_id}Response:
{
"status": "deleted"
}POST /backtest
Content-Type: application/json
{
"strategy_code": "import backtrader as bt\n...",
"ticker": "RELIANCE.NS"
}Response:
{
"start_value": 100000,
"end_value": 110000,
"pnl": 10000
}POST /plot
Content-Type: application/json
{
"strategy_code": "import backtrader as bt\n...",
"ticker": "RELIANCE.NS"
}Response:
{
"data": [...],
"layout": {...}
}POST /explain
Content-Type: application/json
{
"strategy_code": "import backtrader as bt\n..."
}Response:
{
"explanation": "This strategy uses moving average crossover..."
}GET /export/code/{strategy_id}Response: File download (.py)
GET /export/csv/{strategy_id}Response: File download (.csv)
POST /leaderboard/submit
Authorization: Bearer <token>
Content-Type: application/json
{
"strategy_id": 123,
"strategy_name": "My Strategy",
"code": "import backtrader as bt\n...",
"dataset": "default",
"ticker": "RELIANCE.NS"
}Response:
{
"entry_id": 456,
"metrics": {
"Sharpe Ratio": 1.5,
"Max Drawdown": -0.05,
"Total Return": 0.15
},
"score": 85.2
}GET /leaderboard/top?period=daily&dataset=default&limit=50Query Parameters:
period: "daily" | "weekly" | "alltime" (default: "daily")dataset: Filter by dataset (optional)limit: Number of results (default: 50, max: 50)
Response:
{
"period": "daily",
"dataset": "default",
"top": [
{
"id": 1,
"user_id": 123,
"username": "user@example.com",
"strategy_id": 456,
"strategy_name": "Top Strategy",
"dataset": "default",
"run_at": "2023-12-01T10:00:00",
"return_pct": 15.5,
"sharpe": 1.8,
"max_drawdown": -5.2,
"score": 92.1
}
]
}interface User {
id?: number;
email: string;
created_at: string;
}interface Strategy {
id?: number;
name: string;
prompt: string;
code: string;
created_at: string;
}interface StrategyBlueprint {
asset: string;
timeframe?: string;
entry: EntryCondition[];
exit: ExitCondition[];
risk?: RiskManagement;
position_sizing?: "fixed" | "percent" | "risk_adjusted";
}
interface EntryCondition {
indicator: "sma" | "ema" | "rsi" | "zscore" | "macd" | "bollinger";
operator: ">" | "<" | ">=" | "<=" | "crosses_above" | "crosses_below";
value?: number;
params: IndicatorParams;
}
interface ExitCondition {
indicator: "sma" | "ema" | "rsi" | "atr" | "macd";
operator: ">" | "<" | ">=" | "<=" | "crosses_above" | "crosses_below";
value?: number;
params: IndicatorParams;
}
interface IndicatorParams {
lookback?: number;
threshold?: number;
multiplier?: number;
}
interface RiskManagement {
stop_loss?: number | string;
take_profit?: number;
trailing_stop?: number;
}interface LeaderboardEntry {
id: number;
user_id?: number;
username?: string;
strategy_id?: number;
strategy_name?: string;
dataset?: string;
run_at: string;
return_pct: number;
sharpe?: number;
max_drawdown?: number;
score: number;
notes?: string;
}{
"error": "Error message description"
}200: Success400: Bad Request (validation errors)401: Unauthorized (invalid/missing token)404: Not Found500: Internal Server Error
- Store JWT token in localStorage/sessionStorage
- Include
Authorization: Bearer <token>header for protected routes - Handle token expiry (15 days) and redirect to login
- Implement OTP input UI with 6-digit verification
- Visual form for StrategyBlueprint creation
- Dropdown selections for indicators and operators
- Dynamic parameter inputs based on indicator selection
- Real-time preview of generated prompt
- Code editor component for strategy editing
- Chart component for plot visualization (Plotly.js)
- Results display with key metrics
- Export functionality for code and CSV
- Filterable table with sorting
- Period selection (daily/weekly/alltime)
- Dataset filtering
- User strategy submission interface
- Global error boundary for API errors
- Form validation matching backend validators
- Loading states for async operations
- User-friendly error messages
DATABASE_URL=sqlite:///./database.db
REDIS_URL=redis://localhost:6379
JWT_SECRET=your-secret-key
GOOGLE_API_KEY=your-gemini-api-key
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email
SMTP_PASS=your-app-password- All strategy code is validated for dangerous imports
- AST parsing ensures valid Python syntax
- Sandboxed execution environment for backtesting
- JWT tokens with expiration
- OTP-based verification
- Redis-stored temporary tokens
Consider implementing rate limiting for:
- OTP requests (prevent spam)
- Strategy generation (API costs)
- Backtest execution (resource intensive)
- Authentication flow end-to-end
- Strategy generation and editing
- Backtest execution and visualization
- Leaderboard submission and display
- Export functionality
- Token refresh handling
- Error state management
- File upload/download
- Real-time data updates
This documentation provides a complete reference for frontend development. Let me know if you need clarification on any specific endpoint, data model, or integration pattern!