The Hedge Fund Backend is built around a first-class plugin architecture that makes extending the platform a matter of dropping a single Python module into the right package. Every pluggable component — feature transforms, ML models, signal generators, and backtest engines — implements a thin abstract interface and registers itself withDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/najmulhossainnj/Hedge-fund-backend/llms.txt
Use this file to discover all available pages before exploring further.
@registry.register("plugin.key") at import time. The core engine code never needs to be modified; as long as the new module is imported in the relevant package’s __init__.py, the framework discovers and routes to it automatically.
Plugin Categories
Feature Plugins
Transform raw OHLCV and alternative data into named feature columns. Registered in
app/plugins/features/ and surfaced at GET /features/plugins/available.Model Plugins
Trainable predictive models: tree ensembles, neural networks, statistical models. Registered in
app/plugins/models/ and surfaced at GET /models/plugins/available.Signal Plugins
Convert model predictions into actionable trade signals (BUY / SELL / HOLD or +1 / 0 / -1). Registered in
app/plugins/signals/ and surfaced at GET /signals/plugins/available.Backtest Engine Plugins
Adapters over concrete backtesting libraries (vectorbt, Backtrader). Registered in
app/plugins/engines/. Each engine receives prices and signals and returns a metrics dictionary.Base Interfaces
All plugins inherit from abstract base classes defined inapp/plugins/base.py. You must implement every @abstractmethod; optional methods (save, load) have default raise NotImplementedError bodies.
BaseFeature
data is always a standard OHLCV DataFrame with columns open, high, low, close, volume. The returned DataFrame’s index must align with data.index.
BaseModel
BaseSignalGenerator
BaseBacktestEngine
Writing a Feature Plugin
The following example creates a new technical indicator — an Exponential Moving Average crossover — and registers it astechnical.ema_cross. The implementation follows the exact same pattern as the built-in RSIFeature and ATRFeature plugins.
app/plugins/features/__init__.py so the class self-registers when the package is loaded:
Writing a Model Plugin
The following example wraps scikit-learn’sRidge regressor as a plugin, demonstrating the save/load contract using joblib:
app/plugins/models/__init__.py:
Registering Plugins
ThePluginRegistry class lives in app/plugins/registry.py and is a generic, typed container:
__init__.py creates a singleton registry and imports all plugin modules immediately after:
app.plugins.features, the @feature_registry.register(...) decorators on each class body fire immediately, populating the registry before any route handler runs. The same pattern applies to models and signals:
Built-in Plugins
| Category | Plugin key | Description |
|---|---|---|
| Feature | technical.rsi | Relative Strength Index (Wilder’s smoothing, default period 14) |
| Feature | technical.atr | Average True Range (default period 14) |
| Feature | statistical.momentum | Rate-of-change over a rolling window (pct_change(window)) |
| Feature | statistical.mean_reversion | Distance from rolling mean in rolling std units |
| Feature | statistical.z_score | Rolling z-score of any price column |
| Feature | statistical.hurst_exponent | Hurst exponent via R/S analysis — detects trending vs mean-reverting regimes |
| Feature | statistical.volatility_regime | Classifies rolling realised vol into low / mid / high regime labels |
| Feature | automated.tsfresh | tsfresh automated feature extraction from rolling price windows (minimal/efficient/comprehensive feature sets) |
| Feature | news.finbert_sentiment | Full FinBERT sentiment feature set: positive, negative, neutral, uncertainty scores and article volume |
| Feature | news.sentiment_momentum | Rolling mean of composite (positive − negative) FinBERT sentiment score |
| Feature | news.sentiment_divergence | Signed sentiment spread (positive − negative), optionally z-score normalised |
| Model | ml.xgboost | XGBoost gradient-boosted trees (XGBRegressor) |
| Model | ml.lightgbm | LightGBM gradient-boosted trees (LGBMRegressor) |
| Model | ml.catboost | CatBoost gradient-boosted trees |
| Model | ml.random_forest | Scikit-learn RandomForestRegressor |
| Model | dl.lstm | PyTorch LSTM sequence model |
| Signal | signal.threshold | Emits BUY/SELL/HOLD based on upper and lower prediction thresholds |
| Signal | signal.long_short | Long-only, short-only, or long-short signal generation |
| Signal | signal.ranking | Cross-sectional ranking of predictions across a universe |
| Signal | signal.portfolio | Portfolio-level signal aggregation with position sizing |
| Engine | vectorbt | VectorBT vectorised backtesting engine |
| Engine | backtrader | Backtrader event-driven backtesting engine |
Discovery Endpoints
The API exposes read-only endpoints that return the live list of registered plugin keys. These are populated at runtime from the registry singletons, so newly added plugins appear immediately without redeployment (as long as the module is imported):/models/plugins/available:
Plugin keys must be globally unique within each registry. Attempting to register the same key twice raises a Use a namespaced convention such as
ValueError at startup:vendor.category.name (e.g. acme.technical.macd_histogram) to avoid collisions with built-in keys or other third-party plugins.