DEV Community

Cover image for QuantDinger: An open-source local quantitative trading platform.
yuhang chen
yuhang chen

Posted on

QuantDinger: An open-source local quantitative trading platform.

  1. Project Background and Functionality Project Positioning:

QuantDinger aims to create a "Local-First" open-source AI quantitative trading workbench. Designed as a self-hosted alternative to TradingView and QuantConnect, its core principle is to return data ownership to the user. Addressing the pain points of expensive SaaS platforms, it provides a self-hosted solution that integrates data acquisition, AI-driven investment research, strategy backtesting, and live trading.
Core Functional Entities:

Multi-source Data Aggregation: Unified data interfaces for cryptocurrencies (CCXT), US stocks (YFinance/Finnhub), and Chinese A-shares (AkShare) are provided, offering a standardized OHLCV (Open, High, Low, Close, Volume) data format.

Strategy development environment: Features a built-in code editor based on Monaco Editor, supporting strategy development using the Python language.

Visualization Charts: Integrates TradingView's Lightweight Charts library for candlestick chart display and technical indicator analysis.

LLM-assisted tools: Utilize external large language models (via OpenRouter API calls) to assist in generating code snippets or interpreting market news (existing as a functional module, not a core part of the system).

Live/Simulated Trading: Supports connecting to exchange APIs for order routing and asset management.

  1. Technology Selection and Architecture Diagram Codebase directory structure (inferred based on common Flask/Vue projects):

codeText

downloadcontent_copy

expand_less

QuantDinger/
├── backend_api_python/        
│   ├── app/
│   │   ├── routes/             
│   │   ├── services/           
│   │   ├── models/             
│   │   └── utils/              
│   ├── quantdinger.db          
│   ├── requirements.txt        
│   └── run.py                  
├── quantdinger_vue/            
│   ├── src/                    
│   └── package.json            
└── docker-compose.yml          
Enter fullscreen mode Exit fullscreen mode

Technology Stack Details:

Frontend: Vue.js 3, Vite, TypeScript, Lightweight Charts (candlestick charts), Element Plus (UI components).

Backend: Python Flask (web framework), SQLAlchemy (ORM), Pydantic (data validation).

Data Adaptation Layer:

ccxt: Handles REST/WebSocket data from 100+ cryptocurrency exchanges.

akshare: Scrapes A-share financial data.

yfinance: Retrieves historical data for US stocks.

Persistence: SQLite (lightweight file-based database, no need for separate MySQL/PostgreSQL deployment).

Technology Stack Details:

Frontend: Vue.js 3, Vite, TypeScript, Lightweight Charts (candlestick charts), Element Plus (UI components).

  1. Database Design The project uses SQLite (quantdinger.db) to store metadata, avoiding heavy database maintenance. The main data table (Model) design is as follows:

users table

Used for basic authentication.

Fields: id, username, password_hash, api_token.

api_keys table

Stores exchange access credentials.

Fields: id, exchange_name, api_key (AES encrypted storage), secret_key (AES encrypted storage), user_id.

strategies table

Stores user-written strategy code and configuration.

Fields: id, name, code_content (Text type, stores Python source code), timeframe (e.g., '1h', '1d'), symbol (e.g., 'BTC/USDT'), status (RUNNING/STOPPED).

logs / trade_history table

Records signals and transaction history during strategy execution.

Fields: id, strategy_id, timestamp, action (BUY/SELL), price, amount, message.

  1. Detailed Implementation of Core Modules 4.1 Backend Interface Layer (app/routes) Based on Flask Blueprint, it implements RESTful APIs, mainly including:

Market Route (/api/market): Receives time range and symbol parameters from the frontend, calls the data service layer, and returns a JSON formatted candlestick chart array.

Strategy Route (/api/strategy):

POST /save: Receives a Python code string and stores it in the database.

POST /run: Triggers the strategy execution logic.

GET /logs: Polls to read strategy execution logs.

LLM Route (/api/llm): As a pass-through proxy, it encapsulates the frontend's Prompt and forwards it to the OpenRouter API, and then returns the returned Code or Text to the frontend. 4.2 Data Adaptation Service (app/services/data_factory.py)
This is a typical factory pattern implementation used to abstract away the differences between different data sources:

Defines a unified interface IDataSource, including the method fetch_ohlcv(symbol, timeframe, limit).

Crypto implementation class: Instantiates ccxt.binance() or ccxt.okx(), handling API signatures and network requests.

Stock implementation class: Calls functions from akshare or yfinance.download(), and converts the returned Pandas DataFrame into a unified [timestamp, open, high, low, close, volume] list format.

4.3 Strategy Execution Engine (app/services/execution_engine.py)
This is the core of the system, responsible for running the user's Python code.

Dynamic execution: Uses Python's built-in exec() function or importlib to dynamically load the user-written code string.

Sandbox/Context injection: When executing exec(), system-encapsulated API objects (such as buy(), sell(), get_data()) are injected through the locals parameter, allowing user code to directly call these functions without worrying about the underlying implementation.

Process management: To prevent strategy deadlocks from blocking the web service, each running strategy is usually started in a separate process or thread using multiprocessing.

  1. Deployment and Running Steps The project's dependencies are quite complex (involving Python data science libraries and a Node environment), so using Docker is strongly recommended.

Environment configuration:

Create a .env file in the project root directory.

Configure key variables:

codeIni
downloadcontent_copy

expand_less

FLASK_APP=run.py
FLASK_ENV=production
SECRET_KEY=your_secure_key
OPENROUTER_API_KEY=sk-xxx   
Enter fullscreen mode Exit fullscreen mode

2.Building and Starting:

codeBash
downloadcontent_copy

expand_less

docker-compose up -d --build
Enter fullscreen mode Exit fullscreen mode

Backend Container: Based on python:3.10-slim, automatically installs dependencies via pip and starts Flask (Gunicorn).

Frontend Container: Based on Nginx, builds Vue artifacts and hosts static files, while configuring a reverse proxy to forward /api requests to the Backend container.

Access:

Access via browser at http://localhost:80 (or the port mapped in docker-compose).

Initialize the administrator account (you may need to check docker logs for the initial password or create it manually on first startup).

  1. Project Summary and Optimization Directions Project Summary: QuantDinger is essentially a web-based Python quantitative trading script runner. It lowers the barrier to using ccxt and pandas through a web interface and uses SQLite for lightweight data persistence. Its decentralized architecture ensures that trading strategies and API keys remain entirely under the user's control, making it suitable for privacy-sensitive individual traders with some Python experience.

Optimization Directions (Code and Architecture Level):

Security Enhancement (Sandboxing): Currently, using exec() to execute user code poses security risks. It is recommended to introduce Docker-in-Docker (DinD) or use gVisor to allocate independent sandbox containers for each strategy to prevent malicious code from accessing the file system.

Data Storage Upgrade: SQLite is not suitable for storing massive amounts of tick-level financial data. It is recommended to introduce TimescaleDB or InfluxDB to replace SQLite as the backend for market data storage to improve query efficiency.

Event-Driven Engine: The current architecture is biased towards simple script polling. It is recommended to refactor to an event-driven architecture, introducing a message queue (Redis/RabbitMQ) to achieve a low-latency link of "market data update -> trigger event -> strategy response -> trade execution".

Code Reusability and Modularization: Allow users to upload custom Python libraries or modules (.py files), not just single-file scripts, to reuse complex indicator calculation logic.

https://github.com/brokermr810/QuantDinger?tab=readme-ov-file

Top comments (0)