ML-powered exotic derivatives pricing with a retro BlackBerry quant terminal.
Neural Pricer is an experimental pricing platform for exotic and structured derivatives. It uses Monte Carlo simulation to produce reference prices and trained ML surrogate models, currently LightGBM-based, to return fast pricing estimates through a FastAPI backend, a Streamlit frontend, and a local BlackBerry Bold 9780-compatible terminal interface.
This is an educational/demo system. It is not production trading infrastructure, financial advice, or a risk system suitable for live capital allocation.
- Prices structured/exotic products with reusable payoff classes.
- Compares model-backed prices against Monte Carlo reference results.
- Serves pricing through FastAPI.
- Provides a Streamlit UI for desktop experimentation.
- Provides a plain HTML BlackBerry terminal at
/bb. - Supports multiple artifact-backed products in the BlackBerry terminal.
- Supports BlackBerry scenario shocks:
- spot percentage shock
- volatility absolute shock
- rate basis-point shock
- Stores pricing and scenario runs in SQLite.
- Shows recent runs and model status in a compact terminal UI.
- Caches loaded model/scaler bundles in backend process memory.
The BlackBerry is a thin client. It does not run the model locally. It sends simple HTTP requests over local Wi-Fi to the backend, which performs pricing, scenario analysis, validation, and storage.
BlackBerry Bold 9780
-> local HTTP over Wi-Fi
-> FastAPI backend
-> pricing/evaluator/model layer
-> SQLite run store
-> compact terminal result page
The same backend also supports the existing Streamlit frontend and legacy JSON pricing routes.
app/
backend.py FastAPI app and legacy routes
frontend.py Streamlit desktop frontend
api/v1.py Read-only product/model status API
bb/routes.py BlackBerry terminal routes
bb/rendering.py Terminal HTML/formatting helpers
services/ Product registry, pricing, scenario, run storage
src/final/
payoffs.py Core payoff implementations
inherited_payoffs.py Extended payoff variants
data_generator.py Monte Carlo path/data generation
model_trainer.py LightGBM training and model loading
evaluator.py Model vs Monte Carlo evaluation
pipeline.py Training/evaluation orchestration
final/results/
*/model.joblib Saved demo surrogate models
*/scaler.joblib Saved feature scalers
*/results.json Training/evaluation metadata
data/
training/history data Demo data and pricing history
docs/
blackberry-terminal.md BlackBerry terminal details and testing guide
unittests/
pytest coverage for pricing, routes, storage, and terminal helpers
Create and activate an environment:
python -m venv venv
.\venv\Scripts\Activate.ps1Install dependencies:
python -m pip install --upgrade pip
python -m pip install -r requirements.txtRun tests:
python -m pytest -qStart the FastAPI backend locally:
python -m uvicorn app.backend:app --reload --host 127.0.0.1 --port 8000Open the BlackBerry terminal in a desktop browser first:
http://127.0.0.1:8000/bb
Start the Streamlit frontend:
$env:API_URL="http://127.0.0.1:8000"
streamlit run app/frontend.pyStreamlit opens at:
http://127.0.0.1:8501
- Open
/bb. - Select
[1] PRICE NOTE. - Select a product.
- Submit the product pricing form.
- View
/bb/result/{run_id}. - Select
[1] SCENARIO SHOCK. - Enter one or more shocks.
- View the scenario result.
- Open
/bb/recent-runsto revisit price and scenario runs. - Open
/bb/model-statusto check available artifacts and cache state.
Currently enabled BlackBerry products:
phoenix(PHOENIX)accumulator(ACCUM)barrier(BARRIER)decumulator(DECUM)phoenix_stepdown(STEP-PHX)reverse_accumulator(REV-ACC)
The BlackBerry UI is intentionally plain:
- server-rendered HTML
- no JavaScript
- no external CSS or fonts
- compact monospace layout
- simple forms and links
Run the backend on all local network interfaces:
python -m uvicorn app.backend:app --reload --host 0.0.0.0 --port 8000Find the PC local IP:
ipconfigConfirm from a desktop browser:
http://<PC_LOCAL_IP>:8000/bb
Then connect the BlackBerry to the same Wi-Fi network and open:
http://<PC_LOCAL_IP>:8000/bb
If the BlackBerry browser fails:
- use plain HTTP, not HTTPS
- use the raw IP address, not a hostname
- confirm both devices are on the same Wi-Fi network
- allow inbound port
8000on the PC private-network firewall - test
/bb/model-statusfirst - simplify the page further if rendering looks broken
Do not expose the MVP publicly. Treat the BlackBerry as an insecure legacy client on a trusted local network only.
BlackBerry terminal:
GET /bbGET /bb/pricePOST /bb/priceGET /bb/result/{run_id}GET /bb/scenario/{run_id}POST /bb/scenario/{run_id}GET /bb/recent-runsGET /bb/model-status
Read-only API v1:
GET /api/v1/productsGET /api/v1/model-info
Legacy routes kept for compatibility:
POST /price/GET /historyPOST /history/appendGET /training/{payoff_type}GET /payoff_explanation/{payoff_type}GET /
- The MVP uses local-only HTTP.
- There is no authentication or PIN enforcement yet.
- There is no native BlackBerry/WebWorks app yet.
- Model/scaler artifacts are committed for demo usage.
- Model caching is in-process only and clears on backend restart.
- Scenario explanations are simple and rule-based.
- Old BlackBerry browser rendering may require further simplification after more device testing.
- Add JSON
POST /api/v1/priceandPOST /api/v1/scenario. - Improve payoff explanations and risk summaries.
- Add optional PIN or gateway-based access control for non-local deployments.
- Improve model registry/versioning.
- Explore an optional WebWorks or native wrapper after the browser MVP is stable.
Build and run backend/frontend containers:
docker compose up --buildBackend:
http://127.0.0.1:8000
Streamlit:
http://127.0.0.1:8501
See docs/DOCKER_WINDOWS.md for Windows-specific Docker notes.
- Keep payoff formulas, Monte Carlo logic, evaluator semantics, and trained artifacts stable unless a change explicitly targets pricing behavior.
- Keep BlackBerry pages plain and local-network friendly.
- Do not put secrets on the BlackBerry.
- Prefer small service-layer changes over route-level pricing logic.