mirror of
https://github.com/NicolasBohn/NexQuant.git
synced 2026-08-08 04:27:44 +00:00
chore: Remove unnecessary files for v1.0.0 release
Removed: - Makefile (RD-Agent specific, not fully functional) - predix.py (duplicates rdagent CLI) - QWEN.md (internal dev guide - now in .gitignore) - TODO.md (internal tracking - now in .gitignore) Kept: - pyproject.toml (required for pip install) - start_loop.sh (useful for 24/7 trading) - data_config.yaml (central configuration) - start_loop.sh (24/7 trading) .gitignore updated to exclude internal docs. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
@@ -78,3 +78,6 @@ QWEN.md
|
|||||||
|
|
||||||
# AI Agent Files (generated by Qwen Code)
|
# AI Agent Files (generated by Qwen Code)
|
||||||
.qwen/
|
.qwen/
|
||||||
|
|
||||||
|
# Internal documentation (not for public)
|
||||||
|
TODO.md
|
||||||
|
|||||||
@@ -1,222 +0,0 @@
|
|||||||
.PHONY: clean deepclean install init-qlib-env dev constraints black isort mypy ruff toml-sort lint pre-commit test-run test build upload docs-autobuild changelog docs-gen docs-mypy docs-coverage docs
|
|
||||||
#You can modify it according to your terminal
|
|
||||||
SHELL := /bin/bash
|
|
||||||
|
|
||||||
########################################################################################
|
|
||||||
# Variables
|
|
||||||
########################################################################################
|
|
||||||
|
|
||||||
# Determine whether to invoke pipenv based on CI environment variable and the availability of pipenv.
|
|
||||||
PIPRUN := $(shell [ "$$CI" != "true" ] && command -v pipenv > /dev/null 2>&1 && echo "pipenv run")
|
|
||||||
|
|
||||||
# Get the Python version in `major.minor` format, using the environment variable or the virtual environment if exists.
|
|
||||||
PYTHON_VERSION := $(shell echo $${PYTHON_VERSION:-$$(python -V 2>&1 | cut -d ' ' -f 2)} | cut -d '.' -f 1,2)
|
|
||||||
|
|
||||||
# Determine the constraints file based on the Python version.
|
|
||||||
CONSTRAINTS_FILE := constraints/$(PYTHON_VERSION).txt
|
|
||||||
|
|
||||||
# Documentation target directory, will be adapted to specific folder for readthedocs.
|
|
||||||
PUBLIC_DIR := $(shell [ "$$READTHEDOCS" = "True" ] && echo "$$READTHEDOCS_OUTPUT/html" || echo "public")
|
|
||||||
|
|
||||||
# URL and Path of changelog source code.
|
|
||||||
CHANGELOG_URL := $(shell echo $${CI_PAGES_URL:-https://predixai.github.io/predix}/_sources/changelog.md.txt)
|
|
||||||
CHANGELOG_PATH := docs/changelog.md
|
|
||||||
|
|
||||||
########################################################################################
|
|
||||||
# Development Environment Management
|
|
||||||
########################################################################################
|
|
||||||
|
|
||||||
# Remove common intermediate files.
|
|
||||||
clean:
|
|
||||||
-rm -rf \
|
|
||||||
$(PUBLIC_DIR) \
|
|
||||||
.coverage \
|
|
||||||
.mypy_cache \
|
|
||||||
.pytest_cache \
|
|
||||||
.ruff_cache \
|
|
||||||
Pipfile* \
|
|
||||||
coverage.xml \
|
|
||||||
dist \
|
|
||||||
release-notes.md
|
|
||||||
find . -name '*.egg-info' -print0 | xargs -0 rm -rf
|
|
||||||
find . -name '*.pyc' -print0 | xargs -0 rm -f
|
|
||||||
find . -name '*.swp' -print0 | xargs -0 rm -f
|
|
||||||
find . -name '.DS_Store' -print0 | xargs -0 rm -f
|
|
||||||
find . -name '__pycache__' -print0 | xargs -0 rm -rf
|
|
||||||
|
|
||||||
# Remove pre-commit hook, virtual environment alongside itermediate files.
|
|
||||||
deepclean: clean
|
|
||||||
if command -v pre-commit > /dev/null 2>&1; then pre-commit uninstall --hook-type pre-push; fi
|
|
||||||
if command -v pipenv >/dev/null 2>&1 && pipenv --venv >/dev/null 2>&1; then pipenv --rm; fi
|
|
||||||
|
|
||||||
# Install the package in editable mode.
|
|
||||||
install:
|
|
||||||
$(PIPRUN) pip install -e . -c $(CONSTRAINTS_FILE)
|
|
||||||
|
|
||||||
# Install the package in editable mode with specific optional dependencies.
|
|
||||||
dev-%:
|
|
||||||
$(PIPRUN) pip install -e .[$*] -c $(CONSTRAINTS_FILE)
|
|
||||||
|
|
||||||
# Prepare the development environment.
|
|
||||||
# Build submodules.
|
|
||||||
# Install the pacakge in editable mode with all optional dependencies and pre-commit hook.
|
|
||||||
init-qlib-env:
|
|
||||||
# note: You may need to install torch manually
|
|
||||||
# todo: downgrade ruamel.yaml in pyqlib
|
|
||||||
conda create -n qlibRDAgent python=3.8 -y
|
|
||||||
@source $$(conda info --base)/etc/profile.d/conda.sh && conda activate qlibRDAgent && which pip && pip install pyqlib && pip install ruamel-yaml==0.17.21 && pip install torch==2.1.1 && pip install catboost==0.24.3 && conda deactivate
|
|
||||||
|
|
||||||
dev:
|
|
||||||
$(PIPRUN) pip install -U pip setuptools wheel
|
|
||||||
$(PIPRUN) pip install -e .[docs,lint,package,test] -c $(CONSTRAINTS_FILE)
|
|
||||||
$(PIPRUN) pip install -U kaggle
|
|
||||||
if [ "$(CI)" != "true" ] && command -v pre-commit > /dev/null 2>&1; then pre-commit install --hook-type pre-push; fi
|
|
||||||
|
|
||||||
# Generate constraints for current Python version.
|
|
||||||
constraints: deepclean
|
|
||||||
$(PIPRUN) --python $(PYTHON_VERSION) pip install --upgrade -e .[docs,lint,package,test]
|
|
||||||
$(PIPRUN) pip freeze --exclude-editable > $(CONSTRAINTS_FILE)
|
|
||||||
|
|
||||||
########################################################################################
|
|
||||||
# Lint and pre-commit
|
|
||||||
########################################################################################
|
|
||||||
|
|
||||||
# Check lint with black.
|
|
||||||
black:
|
|
||||||
$(PIPRUN) python -m black --check --diff . --extend-exclude "(test/scripts|test/notebook/testfiles|git_ignore_folder|web)" -l 120
|
|
||||||
|
|
||||||
# Check lint with isort.
|
|
||||||
isort:
|
|
||||||
$(PIPRUN) python -m isort --check . -s git_ignore_folder -s test/scripts -s test/notebook/testfiles -s web
|
|
||||||
|
|
||||||
# Check lint with mypy.
|
|
||||||
# First deal with the core folder, and then gradually increase the scope of detection,
|
|
||||||
# and eventually realize the detection of the complete project.
|
|
||||||
mypy:
|
|
||||||
$(PIPRUN) python -m mypy rdagent/core
|
|
||||||
|
|
||||||
# Check lint with ruff.
|
|
||||||
# First deal with the core folder, and then gradually increase the scope of detection,
|
|
||||||
# and eventually realize the detection of the complete project.
|
|
||||||
ruff:
|
|
||||||
$(PIPRUN) ruff check rdagent/core --ignore FBT001,FBT002,I001,E501 # --exclude rdagent/scripts,git_ignore_folder
|
|
||||||
|
|
||||||
# Check lint with toml-sort.
|
|
||||||
toml-sort:
|
|
||||||
$(PIPRUN) toml-sort --check pyproject.toml
|
|
||||||
|
|
||||||
# Check lint with all linters.
|
|
||||||
# Prioritize fixing isort, then black, otherwise you'll get weird and unfixable black errors.
|
|
||||||
# lint: mypy ruff
|
|
||||||
lint: mypy ruff isort black toml-sort
|
|
||||||
|
|
||||||
# Run pre-commit with autofix against all files.
|
|
||||||
pre-commit:
|
|
||||||
pre-commit run --all-files
|
|
||||||
|
|
||||||
########################################################################################
|
|
||||||
# Auto Lint
|
|
||||||
########################################################################################
|
|
||||||
|
|
||||||
# Auto lint with black.
|
|
||||||
auto-black:
|
|
||||||
$(PIPRUN) python -m black . --extend-exclude "(test/scripts|test/notebook/testfiles|git_ignore_folder|.venv|web)" -l 120
|
|
||||||
|
|
||||||
# Auto lint with isort.
|
|
||||||
auto-isort:
|
|
||||||
$(PIPRUN) python -m isort . -s git_ignore_folder -s test/scripts -s test/notebook/testfiles -s .venv -s web
|
|
||||||
|
|
||||||
# Auto lint with toml-sort.
|
|
||||||
auto-toml-sort:
|
|
||||||
$(PIPRUN) toml-sort pyproject.toml
|
|
||||||
|
|
||||||
# Auto lint with all linters.
|
|
||||||
auto-lint: auto-isort auto-black auto-toml-sort
|
|
||||||
|
|
||||||
########################################################################################
|
|
||||||
# Test
|
|
||||||
########################################################################################
|
|
||||||
|
|
||||||
# Clean and run test with coverage.
|
|
||||||
test-run:
|
|
||||||
$(PIPRUN) python -m coverage erase
|
|
||||||
$(PIPRUN) python -m coverage run --concurrency=multiprocessing -m pytest --ignore test/scripts
|
|
||||||
$(PIPRUN) python -m coverage combine
|
|
||||||
|
|
||||||
test-run-offline:
|
|
||||||
# some test that does not require api calling
|
|
||||||
$(PIPRUN) python -m coverage erase
|
|
||||||
$(PIPRUN) python -m coverage run --concurrency=multiprocessing -m pytest -m "offline" --ignore test/scripts
|
|
||||||
$(PIPRUN) python -m coverage combine
|
|
||||||
|
|
||||||
# Generate coverage report for terminal and xml.
|
|
||||||
# TODO: we may have higher coverage rate if we have more test
|
|
||||||
test: test-run
|
|
||||||
$(PIPRUN) python -m coverage report --fail-under 20 # 80
|
|
||||||
$(PIPRUN) python -m coverage xml --fail-under 20 # 80
|
|
||||||
|
|
||||||
test-offline: test-run-offline
|
|
||||||
$(PIPRUN) python -m coverage report --fail-under 20 # 80
|
|
||||||
$(PIPRUN) python -m coverage xml --fail-under 20 # 80
|
|
||||||
|
|
||||||
########################################################################################
|
|
||||||
# Package
|
|
||||||
########################################################################################
|
|
||||||
|
|
||||||
# Build the package.
|
|
||||||
build:
|
|
||||||
$(PIPRUN) python -m build
|
|
||||||
|
|
||||||
# Upload the package.
|
|
||||||
upload:
|
|
||||||
$(PIPRUN) python -m twine upload dist/*
|
|
||||||
|
|
||||||
########################################################################################
|
|
||||||
# Documentation
|
|
||||||
########################################################################################
|
|
||||||
|
|
||||||
# Generate documentation with auto build when changes happen.
|
|
||||||
docs-autobuild:
|
|
||||||
$(PIPRUN) python -m sphinx_autobuild docs $(PUBLIC_DIR) \
|
|
||||||
--watch README.md \
|
|
||||||
--watch rdagent
|
|
||||||
|
|
||||||
# Generate changelog from git commits.
|
|
||||||
# The -c and -s arguments should match
|
|
||||||
# If -c uses Basic (default, inherits from base class), -s optional argument: # If -c uses conventional (inherits from base class), -s optional parameter: add,fix,change,remove,merge,doc
|
|
||||||
# If -c uses conventional (inherits from base class), -s is optional: build,chore,ci,deps,doc,docs,feat,fix,perf,ref,refactor,revert,style,test,tests
|
|
||||||
# If -c uses angular (inherits from conventional), -s optional argument: build,chore,ci,deps,doc,docs,feat,fix,perf,ref,refactor,revert,style,test,tests
|
|
||||||
# NOTE(xuan.hu): Need to be run before document generation to take effect.
|
|
||||||
# $(PIPRUN) git-changelog -ETrio $(CHANGELOG_PATH) -c conventional -s build,chore,ci,docs,feat,fix,perf,refactor,revert,style,test
|
|
||||||
changelog:
|
|
||||||
@if wget -q --spider $(CHANGELOG_URL); then \
|
|
||||||
echo "Existing Changelog found at '$(CHANGELOG_URL)', download for incremental generation."; \
|
|
||||||
wget -q -O $(CHANGELOG_PATH) $(CHANGELOG_URL); \
|
|
||||||
fi
|
|
||||||
$(PIPRUN) LATEST_TAG=$$(git tag --sort=-creatordate | head -n 1); \
|
|
||||||
git-changelog --bump $$LATEST_TAG -Tio docs/changelog.md -c conventional -s build,chore,ci,deps,doc,docs,feat,fix,perf,ref,refactor,revert,style,test,tests
|
|
||||||
|
|
||||||
# Generate release notes from changelog.
|
|
||||||
release-notes:
|
|
||||||
@$(PIPRUN) git-changelog --input $(CHANGELOG_PATH) --release-notes
|
|
||||||
|
|
||||||
# Build documentation only from rdagent.
|
|
||||||
docs-gen:
|
|
||||||
$(PIPRUN) python -m sphinx.cmd.build -W docs $(PUBLIC_DIR)
|
|
||||||
|
|
||||||
# Generate mypy reports.
|
|
||||||
docs-mypy: docs-gen
|
|
||||||
$(PIPRUN) python -m mypy rdagent test --exclude git_ignore_folder --exclude rdagent/scripts --html-report $(PUBLIC_DIR)/reports/mypy
|
|
||||||
|
|
||||||
# Generate html coverage reports with badge.
|
|
||||||
docs-coverage: test-run docs-gen
|
|
||||||
$(PIPRUN) python -m coverage html -d $(PUBLIC_DIR)/reports/coverage --fail-under 80
|
|
||||||
$(PIPRUN) bash scripts/generate-coverage-badge.sh $(PUBLIC_DIR)/_static/badges
|
|
||||||
|
|
||||||
# Generate all documentation with reports.
|
|
||||||
docs: changelog docs-gen docs-mypy docs-coverage
|
|
||||||
|
|
||||||
|
|
||||||
########################################################################################
|
|
||||||
# End
|
|
||||||
########################################################################################
|
|
||||||
@@ -1,528 +0,0 @@
|
|||||||
# Predix - QWEN.md Context File
|
|
||||||
|
|
||||||
## Project Overview
|
|
||||||
|
|
||||||
**Predix** is an autonomous AI-powered quantitative trading agent for EUR/USD forex markets. Built on the RD-Agent framework, it automates the full research and development cycle for trading strategies.
|
|
||||||
|
|
||||||
### Core Purpose
|
|
||||||
- Generate trading factors (signals) autonomously using LLMs
|
|
||||||
- Backtest and validate factors on 1-minute EUR/USD data
|
|
||||||
- Optimize portfolios using modern portfolio theory
|
|
||||||
- Target: 1-3% monthly returns with Sharpe > 2.0
|
|
||||||
|
|
||||||
### Key Technologies
|
|
||||||
- **Python 3.10/3.11** - Primary language
|
|
||||||
- **PyTorch** - Deep learning models
|
|
||||||
- **Qlib** - Backtesting engine
|
|
||||||
- **LLM (Qwen3.5-35B)** - Factor generation via local llama.cpp
|
|
||||||
- **Flask** - Web dashboard API
|
|
||||||
- **SQLite** - Results database
|
|
||||||
- **Rich/Typer** - CLI interface
|
|
||||||
|
|
||||||
### Architecture
|
|
||||||
|
|
||||||
```
|
|
||||||
Predix/
|
|
||||||
├── rdagent/ # Core agent framework
|
|
||||||
│ ├── app/
|
|
||||||
│ │ └── cli.py # Main CLI entry point (rdagent command)
|
|
||||||
│ ├── components/
|
|
||||||
│ │ ├── backtesting/ # Backtest engine, metrics, database
|
|
||||||
│ │ ├── coder/
|
|
||||||
│ │ │ └── factor_coder/ # Factor generation & EURUSD-specific modules
|
|
||||||
│ │ └── ...
|
|
||||||
│ └── scenarios/
|
|
||||||
│ └── qlib/ # Qlib integration for FX trading
|
|
||||||
├── results/ # Backtest results (NOT in git)
|
|
||||||
│ ├── backtests/ # Individual factor backtests (JSON/CSV)
|
|
||||||
│ ├── db/ # SQLite database
|
|
||||||
│ ├── factors/ # Factor analysis
|
|
||||||
│ ├── runs/ # Run results & risk reports
|
|
||||||
│ └── logs/ # Backtest logs
|
|
||||||
├── web/ # Dashboard frontend
|
|
||||||
│ ├── dashboard_api.py # Flask API backend
|
|
||||||
│ └── dashboard.html # Web UI
|
|
||||||
├── .env # Environment config (API keys, etc.)
|
|
||||||
├── data_config.yaml # EURUSD data configuration
|
|
||||||
└── requirements.txt # Python dependencies
|
|
||||||
```
|
|
||||||
|
|
||||||
## Building and Running
|
|
||||||
|
|
||||||
### Installation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Clone repository
|
|
||||||
git clone https://github.com/PredixAI/predix
|
|
||||||
cd predix
|
|
||||||
|
|
||||||
# Create conda environment
|
|
||||||
conda create -n predix python=3.10
|
|
||||||
conda activate predix
|
|
||||||
|
|
||||||
# Install in editable mode
|
|
||||||
pip install -e .[test,lint]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Configuration
|
|
||||||
|
|
||||||
1. **Create `.env` file:**
|
|
||||||
```bash
|
|
||||||
# Local LLM (llama.cpp)
|
|
||||||
OPENAI_API_KEY=local
|
|
||||||
OPENAI_API_BASE=http://localhost:8081/v1
|
|
||||||
CHAT_MODEL=qwen3.5-35b
|
|
||||||
|
|
||||||
# Embedding (Ollama)
|
|
||||||
LITELLM_PROXY_API_KEY=local
|
|
||||||
LITELLM_PROXY_API_BASE=http://localhost:11434/v1
|
|
||||||
EMBEDDING_MODEL=nomic-embed-text
|
|
||||||
|
|
||||||
# Paths
|
|
||||||
QLIB_DATA_DIR=~/.qlib/qlib_data/eurusd_1min_data
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Start LLM server (llama.cpp):**
|
|
||||||
```bash
|
|
||||||
~/llama.cpp/build/bin/llama-server \
|
|
||||||
--model ~/models/qwen3.5/Qwen3.5-35B-A3B-Q3_K_M.gguf \
|
|
||||||
--n-gpu-layers 36 \
|
|
||||||
--ctx-size 80000 \
|
|
||||||
--port 8081
|
|
||||||
```
|
|
||||||
|
|
||||||
### Running the Trading Loop
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Start trading loop (24/7)
|
|
||||||
./start_loop.sh
|
|
||||||
|
|
||||||
# Or single run
|
|
||||||
rdagent fin_quant
|
|
||||||
|
|
||||||
# With dashboard
|
|
||||||
rdagent fin_quant --with-dashboard
|
|
||||||
|
|
||||||
# With CLI dashboard
|
|
||||||
rdagent fin_quant --cli-dashboard
|
|
||||||
```
|
|
||||||
|
|
||||||
### Running the Dashboard
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Web dashboard (runs with fin_quant --with-dashboard)
|
|
||||||
# Access at: http://localhost:5000/dashboard.html
|
|
||||||
|
|
||||||
# Or standalone
|
|
||||||
python web/dashboard_api.py
|
|
||||||
```
|
|
||||||
|
|
||||||
### Testing
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Run all tests
|
|
||||||
pytest test/
|
|
||||||
|
|
||||||
# Run with coverage
|
|
||||||
pytest --cov=rdagent --cov-report=html
|
|
||||||
|
|
||||||
# Test backtesting module
|
|
||||||
python rdagent/components/backtesting/backtest_engine.py
|
|
||||||
python rdagent/components/backtesting/results_db.py
|
|
||||||
python rdagent/components/backtesting/risk_management.py
|
|
||||||
```
|
|
||||||
|
|
||||||
### Code Quality
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Linting
|
|
||||||
ruff check rdagent/
|
|
||||||
|
|
||||||
# Type checking
|
|
||||||
mypy rdagent/
|
|
||||||
|
|
||||||
# Format
|
|
||||||
black rdagent/
|
|
||||||
|
|
||||||
# Pre-commit (install first)
|
|
||||||
pre-commit install
|
|
||||||
pre-commit run --all-files
|
|
||||||
```
|
|
||||||
|
|
||||||
## Development Conventions
|
|
||||||
|
|
||||||
### Language Policy
|
|
||||||
|
|
||||||
**ALL code comments and documentation MUST be in English.**
|
|
||||||
|
|
||||||
❌ **Wrong (German):**
|
|
||||||
```python
|
|
||||||
# Inspiriert von: TradingAgents
|
|
||||||
# Berechnet den Sharpe Ratio
|
|
||||||
# Achtung: Division durch Null möglich!
|
|
||||||
# Hinweis: Diese Funktion ist experimentell
|
|
||||||
```
|
|
||||||
|
|
||||||
✅ **Correct (English):**
|
|
||||||
```python
|
|
||||||
# Inspired by: TradingAgents
|
|
||||||
# Calculates the Sharpe ratio
|
|
||||||
# Warning: Division by zero possible!
|
|
||||||
# Note: This function is experimental
|
|
||||||
```
|
|
||||||
|
|
||||||
**Rationale:**
|
|
||||||
- International collaboration
|
|
||||||
- Better searchability
|
|
||||||
- Professional codebase
|
|
||||||
- Consistent with commit messages (also English-only)
|
|
||||||
|
|
||||||
**Enforcement:**
|
|
||||||
- All new code must have English comments
|
|
||||||
- Existing German comments should be translated when modified
|
|
||||||
- PRs with German comments will be rejected
|
|
||||||
|
|
||||||
### Code Style
|
|
||||||
|
|
||||||
- **Line length:** 120 characters (configured in pyproject.toml)
|
|
||||||
- **Type hints:** Required for all public functions
|
|
||||||
- **Docstrings:** Google style for public APIs
|
|
||||||
- **Imports:** Sorted automatically with isort
|
|
||||||
|
|
||||||
### Testing Practices
|
|
||||||
- Unit tests in `test/` directory
|
|
||||||
- Test files named `test_*.py`
|
|
||||||
- Use pytest fixtures for common setup
|
|
||||||
- Mock external APIs (LLM, yfinance)
|
|
||||||
- Minimum 80% coverage target
|
|
||||||
|
|
||||||
### Commit Conventions
|
|
||||||
```bash
|
|
||||||
git commit --author="TPTBusiness <tpt.requests@pm.me>" -m "type: description"
|
|
||||||
|
|
||||||
# Types:
|
|
||||||
# - feat: New feature
|
|
||||||
# - fix: Bug fix
|
|
||||||
# - docs: Documentation
|
|
||||||
# - style: Formatting
|
|
||||||
# - refactor: Code restructuring
|
|
||||||
# - test: Tests
|
|
||||||
# - chore: Maintenance
|
|
||||||
```
|
|
||||||
|
|
||||||
### Module Structure
|
|
||||||
```python
|
|
||||||
"""
|
|
||||||
Module Name - Brief description
|
|
||||||
|
|
||||||
Longer description if needed.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
import pandas as pd
|
|
||||||
from typing import Dict, List, Optional
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
class ClassName:
|
|
||||||
"""Class docstring."""
|
|
||||||
|
|
||||||
def __init__(self, param: type) -> None:
|
|
||||||
"""Initialize."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def method(self, param: type) -> ReturnType:
|
|
||||||
"""
|
|
||||||
Method docstring.
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
param : type
|
|
||||||
Description
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
ReturnType
|
|
||||||
Description
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
```
|
|
||||||
|
|
||||||
### Backtesting Module Usage
|
|
||||||
|
|
||||||
```python
|
|
||||||
from rdagent.components.backtesting import (
|
|
||||||
FactorBacktester,
|
|
||||||
ResultsDatabase,
|
|
||||||
PortfolioOptimizer,
|
|
||||||
AdvancedRiskManager
|
|
||||||
)
|
|
||||||
|
|
||||||
# Run backtest
|
|
||||||
backtester = FactorBacktester()
|
|
||||||
metrics = backtester.run_backtest(
|
|
||||||
factor_values=factor_series,
|
|
||||||
forward_returns=forward_returns,
|
|
||||||
factor_name="MyFactor"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Save to database
|
|
||||||
db = ResultsDatabase()
|
|
||||||
db.add_backtest("MyFactor", metrics)
|
|
||||||
|
|
||||||
# Query top factors
|
|
||||||
top = db.get_top_factors('sharpe_ratio', limit=20)
|
|
||||||
|
|
||||||
# Portfolio optimization
|
|
||||||
optimizer = PortfolioOptimizer()
|
|
||||||
weights = optimizer.mean_variance(expected_returns, cov_matrix)
|
|
||||||
|
|
||||||
# Risk management
|
|
||||||
risk_manager = AdvancedRiskManager()
|
|
||||||
report = risk_manager.generate_risk_report(returns, weights)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Key Metrics
|
|
||||||
|
|
||||||
| Metric | Target | Minimum |
|
|
||||||
|--------|--------|---------|
|
|
||||||
| IC (Information Coefficient) | > 0.05 | > 0.02 |
|
|
||||||
| Sharpe Ratio | > 2.0 | > 1.0 |
|
|
||||||
| Max Drawdown | < 15% | < 25% |
|
|
||||||
| Win Rate | > 55% | > 45% |
|
|
||||||
| Annualized Return | > 10% | > 5% |
|
|
||||||
|
|
||||||
### Important Files
|
|
||||||
|
|
||||||
- `rdagent/app/cli.py` - Main CLI entry point
|
|
||||||
- `rdagent/components/backtesting/` - Backtest engine
|
|
||||||
- `rdagent/components/coder/factor_coder/` - Factor generation
|
|
||||||
- `results/README.md` - Results documentation
|
|
||||||
- `data_config.yaml` - EURUSD configuration
|
|
||||||
- `web/dashboard_api.py` - Dashboard API
|
|
||||||
- `requirements.txt` - Dependencies
|
|
||||||
|
|
||||||
### External Dependencies
|
|
||||||
|
|
||||||
- **llama.cpp** - Local LLM inference (Qwen3.5-35B)
|
|
||||||
- **Ollama** - Embedding models
|
|
||||||
- **Qlib** - Backtesting engine
|
|
||||||
- **yfinance** - Live market data
|
|
||||||
|
|
||||||
### Common Issues
|
|
||||||
|
|
||||||
1. **LLM Connection Errors:** Ensure llama.cpp server is running on port 8081
|
|
||||||
2. **Embedding Errors:** Check Ollama is running with nomic-embed-text loaded
|
|
||||||
3. **Database Lock:** Close all connections before running multiple processes
|
|
||||||
4. **Memory Issues:** Reduce batch size or context length for LLM
|
|
||||||
|
|
||||||
### Project Status
|
|
||||||
|
|
||||||
- ✅ Factor Generation (110+ factors created)
|
|
||||||
- ✅ Backtesting Engine (IC, Sharpe, Drawdown)
|
|
||||||
- ✅ Results Database (SQLite with queries)
|
|
||||||
- ✅ Risk Management (Correlation, Portfolio Optimization)
|
|
||||||
- ✅ Dashboards (Web + CLI)
|
|
||||||
- ⏳ Live Trading (Paper trading pending)
|
|
||||||
|
|
||||||
### Next Steps
|
|
||||||
|
|
||||||
1. Backtest all 110 factors
|
|
||||||
2. Select top 20 by IC/Sharpe
|
|
||||||
3. Portfolio optimization
|
|
||||||
4. 4 weeks paper trading
|
|
||||||
5. Live trading with small capital
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Git Commit Guidelines
|
|
||||||
|
|
||||||
### Language Policy
|
|
||||||
|
|
||||||
**ALL commit messages MUST be in English.**
|
|
||||||
|
|
||||||
❌ **Wrong (German):**
|
|
||||||
```bash
|
|
||||||
git commit -m "feat: Neue Funktion hinzugefügt"
|
|
||||||
git commit -m "fix: Fehler behoben"
|
|
||||||
git commit -m "chore: QWEN.md zu .gitignore hinzugefügt"
|
|
||||||
```
|
|
||||||
|
|
||||||
✅ **Correct (English):**
|
|
||||||
```bash
|
|
||||||
git commit -m "feat: Add new feature"
|
|
||||||
git commit -m "fix: Fix bug"
|
|
||||||
git commit -m "chore: Add QWEN.md to .gitignore"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Pre-Commit Checklist
|
|
||||||
|
|
||||||
**BEFORE every commit, you MUST:**
|
|
||||||
|
|
||||||
1. **Run `git status`** and verify:
|
|
||||||
- Only intended files are staged
|
|
||||||
- No generated files (.qwen/, results/, *.db, etc.)
|
|
||||||
- No sensitive data (.env, API keys, etc.)
|
|
||||||
|
|
||||||
2. **Check .gitignore** is working:
|
|
||||||
```bash
|
|
||||||
git status
|
|
||||||
# Verify .qwen/, results/, *.db are NOT shown
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Review staged changes:**
|
|
||||||
```bash
|
|
||||||
git diff --staged
|
|
||||||
# Review what will be committed
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Run tests** (if applicable):
|
|
||||||
```bash
|
|
||||||
pytest test/backtesting/ -v
|
|
||||||
# Ensure all tests pass
|
|
||||||
```
|
|
||||||
|
|
||||||
### Commit Message Format
|
|
||||||
|
|
||||||
Use [Conventional Commits](https://www.conventionalcommits.org/):
|
|
||||||
|
|
||||||
```
|
|
||||||
<type>: <description in English>
|
|
||||||
|
|
||||||
[optional body]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Types:**
|
|
||||||
- `feat:` - New feature
|
|
||||||
- `fix:` - Bug fix
|
|
||||||
- `test:` - Tests
|
|
||||||
- `docs:` - Documentation
|
|
||||||
- `chore:` - Maintenance
|
|
||||||
- `style:` - Formatting
|
|
||||||
- `refactor:` - Code restructuring
|
|
||||||
|
|
||||||
**Examples:**
|
|
||||||
```bash
|
|
||||||
feat: Add backtesting tests with 98% coverage
|
|
||||||
fix: Remove .qwen/ from Git tracking
|
|
||||||
test: Add unit tests for ResultsDatabase
|
|
||||||
docs: Update QWEN.md with commit guidelines
|
|
||||||
chore: Add pytest to requirements.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
### Protected Files (NEVER commit)
|
|
||||||
|
|
||||||
These files/directories MUST NEVER be committed:
|
|
||||||
|
|
||||||
```
|
|
||||||
.qwen/ # AI agent files (generated)
|
|
||||||
results/ # Backtest results (sensitive data)
|
|
||||||
*.db # SQLite databases
|
|
||||||
.env # Environment variables (API keys!)
|
|
||||||
git_ignore_folder/ # Generated data
|
|
||||||
*.log # Log files
|
|
||||||
```
|
|
||||||
|
|
||||||
If you accidentally commit any of these:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Remove from last commit (keeps files locally)
|
|
||||||
git reset HEAD~1
|
|
||||||
|
|
||||||
# Or remove from tracking
|
|
||||||
git rm -r --cached .qwen/
|
|
||||||
git commit -m "chore: Remove .qwen/ from tracking"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Fixing Past Commits
|
|
||||||
|
|
||||||
**To fix the last 3-5 commits:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# For last 5 commits
|
|
||||||
git rebase -i HEAD~5
|
|
||||||
|
|
||||||
# In the editor, change 'pick' to 'reword' for commits to rename
|
|
||||||
# Save and close
|
|
||||||
# Write new English message for each commit
|
|
||||||
```
|
|
||||||
|
|
||||||
**To fix older commits (advanced):**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Find the commit hash
|
|
||||||
git log --oneline
|
|
||||||
|
|
||||||
# Start rebase from that commit
|
|
||||||
git rebase -i <commit-hash>^
|
|
||||||
|
|
||||||
# Follow same process as above
|
|
||||||
```
|
|
||||||
|
|
||||||
**Current German commits to fix (as of April 2026):**
|
|
||||||
```
|
|
||||||
73140b68 test: Backtesting Tests mit 98.77% Coverage
|
|
||||||
→ test: Add backtesting tests with 98.77% coverage
|
|
||||||
|
|
||||||
5148d17d chore: QWEN.md zu .gitignore hinzugefügt
|
|
||||||
→ chore: Add QWEN.md to .gitignore
|
|
||||||
|
|
||||||
df93e162 feat: Intelligent Embedding Chunking statt Kürzung
|
|
||||||
→ feat: Intelligent embedding chunking instead of truncation
|
|
||||||
|
|
||||||
01aa183a fix: CLI Dashboard in separatem Terminal-Fenster
|
|
||||||
→ fix: CLI dashboard in separate terminal window
|
|
||||||
|
|
||||||
df356978 feat: predix.py Wrapper für Dashboard-Support
|
|
||||||
→ feat: predix.py wrapper for dashboard support
|
|
||||||
|
|
||||||
89d01f5d feat: Beautiful CLI Dashboard + korrigierter Start-Befehl
|
|
||||||
→ feat: Beautiful CLI dashboard + corrected start command
|
|
||||||
|
|
||||||
48e4f44e feat: Auto-Start Dashboard für fin_quant
|
|
||||||
→ feat: Auto-start dashboard for fin_quant
|
|
||||||
|
|
||||||
59122a19 feat: Dashboard + Live-Daten Integration (Phase 4)
|
|
||||||
→ feat: Dashboard + live data integration (Phase 4)
|
|
||||||
|
|
||||||
a0f414ed feat: EURUSD Trading-Verbesserungen (Phase 2 & 3)
|
|
||||||
→ feat: EURUSD trading improvements (Phase 2 & 3)
|
|
||||||
|
|
||||||
e8b962b5 feat: EURUSD Trading-Verbesserungen implementiert (Phase 1)
|
|
||||||
→ feat: Implement EURUSD trading improvements (Phase 1)
|
|
||||||
```
|
|
||||||
|
|
||||||
**⚠️ Warning:** Rewriting history changes commit hashes. If you've already pushed:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# After rebasing locally
|
|
||||||
git push --force-with-lease origin master
|
|
||||||
|
|
||||||
# Tell team members to re-clone:
|
|
||||||
git clone <repo-url>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Push Policy
|
|
||||||
|
|
||||||
**BEFORE pushing:**
|
|
||||||
|
|
||||||
1. Verify commit messages are in English
|
|
||||||
2. Verify no protected files are included
|
|
||||||
3. Run tests one final time
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git status
|
|
||||||
git log -3 --oneline # Verify last 3 commits
|
|
||||||
pytest test/backtesting/ -v # Quick test
|
|
||||||
git push origin master
|
|
||||||
```
|
|
||||||
|
|
||||||
### Enforcement
|
|
||||||
|
|
||||||
- All PRs will be rejected if commit messages are not in English
|
|
||||||
- Protected files in commits will be rejected
|
|
||||||
- Tests must pass before merging
|
|
||||||
|
|
||||||
**Remember:** Consistent English commit messages ensure:
|
|
||||||
- International collaboration
|
|
||||||
- Better searchability
|
|
||||||
- Professional project history
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
# TODOs
|
|
||||||
|
|
||||||
This file tracks global TODOs for the Predix project. Individual TODOs in code should be addressed in their respective modules.
|
|
||||||
|
|
||||||
## Current Global TODOs
|
|
||||||
|
|
||||||
### Low Priority (Post-v1.0.0)
|
|
||||||
|
|
||||||
- [ ] Align naming conventions for files in `components/` and `scenarios/` directories
|
|
||||||
- Current mismatch: `coder` in `components/` vs `developer` in `scenarios/`
|
|
||||||
- **Status:** Inherited from RD-Agent upstream, works as-is
|
|
||||||
- **Priority:** Low - cosmetic only, no functional impact
|
|
||||||
|
|
||||||
- [ ] Clean up folder naming inconsistencies
|
|
||||||
- Investigate why some scenario-related code is in `experiments/` folders
|
|
||||||
- **Status:** Historical structure from RD-Agent
|
|
||||||
- **Priority:** Low - works correctly, can refactor later
|
|
||||||
|
|
||||||
## Completed
|
|
||||||
|
|
||||||
### v1.0.0 Release (2026-04-02)
|
|
||||||
|
|
||||||
- [x] Rebrand from RD-Agent to Predix for EUR/USD focus
|
|
||||||
- [x] Remove Microsoft-specific references
|
|
||||||
- [x] Update documentation for PredixAI organization
|
|
||||||
- [x] Translate all code comments to English
|
|
||||||
- [x] Create comprehensive QWEN.md (development guide)
|
|
||||||
- [x] Create ATTRIBUTION.md (usage guidelines)
|
|
||||||
- [x] Update README.md with installation and quick start
|
|
||||||
- [x] Create CHANGELOG.md with v1.0.0 release notes
|
|
||||||
- [x] Create changelog/ directory structure (changelog/v1.0.0.md)
|
|
||||||
- [x] Prepare GitHub Release v1.0.0
|
|
||||||
- [x] Pass all tests (97/97, 98.77% coverage)
|
|
||||||
- [x] Complete .gitignore for sensitive files
|
|
||||||
- [x] Clean up git history (remove logs, test artifacts)
|
|
||||||
- [x] Add English-only commit message policy to QWEN.md
|
|
||||||
- [x] Add comprehensive Acknowledgments (RD-Agent, TradingAgents, ai-hedge-fund)
|
|
||||||
|
|
||||||
### Future Releases
|
|
||||||
|
|
||||||
- [ ] v1.1.0: Live paper-trading integration
|
|
||||||
- [ ] v1.1.0: Additional ML-based factor types
|
|
||||||
- [ ] v1.2.0: Docker containerization
|
|
||||||
- [ ] v1.2.0: CI/CD pipeline
|
|
||||||
- [ ] v1.3.0: Performance optimization
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
Predix CLI Wrapper - Startet fin_quant mit Dashboard-Unterstützung
|
|
||||||
|
|
||||||
Verwendung:
|
|
||||||
python predix.py fin_quant # Normal
|
|
||||||
python predix.py fin_quant -d # Web Dashboard
|
|
||||||
python predix.py fin_quant -c # CLI Dashboard
|
|
||||||
python predix.py fin_quant -d -c # Beide
|
|
||||||
python predix.py fin_quant --help # Hilfe
|
|
||||||
"""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
# Parent-Directory zum Path hinzufügen
|
|
||||||
sys.path.insert(0, str(Path(__file__).parent))
|
|
||||||
|
|
||||||
# Environment laden
|
|
||||||
from dotenv import load_dotenv
|
|
||||||
load_dotenv(".env")
|
|
||||||
|
|
||||||
import subprocess
|
|
||||||
import threading
|
|
||||||
import time
|
|
||||||
from rich.console import Console
|
|
||||||
|
|
||||||
console = Console()
|
|
||||||
|
|
||||||
def start_web_dashboard(port=5000):
|
|
||||||
"""Starte Web Dashboard."""
|
|
||||||
console.print(f"\n[bold green]🚀 Starting Web Dashboard on http://localhost:{port}...[/bold green]")
|
|
||||||
console.print(f" [cyan]Open: http://localhost:{port}/dashboard.html[/cyan]\n")
|
|
||||||
subprocess.run(
|
|
||||||
["python", "web/dashboard_api.py"],
|
|
||||||
cwd=str(Path(__file__).parent),
|
|
||||||
env={**os.environ, "FLASK_ENV": "development"}
|
|
||||||
)
|
|
||||||
|
|
||||||
def start_cli_dashboard():
|
|
||||||
"""Starte CLI Dashboard."""
|
|
||||||
from rdagent.log.ui.predix_dashboard import run_dashboard
|
|
||||||
run_dashboard(log_path="fin_quant.log", refresh_interval=3)
|
|
||||||
|
|
||||||
def fin_quant(path=None, step_n=None, loop_n=None, all_duration=None, checkout=True):
|
|
||||||
"""Starte fin_quant."""
|
|
||||||
from rdagent.app.qlib_rd_loop.quant import main
|
|
||||||
main(path=path, step_n=step_n, loop_n=loop_n, all_duration=all_duration, checkout=checkout)
|
|
||||||
|
|
||||||
def start_cli_dashboard_standalone():
|
|
||||||
"""
|
|
||||||
Startet CLI Dashboard in einem SEPARATEN Terminal-Fenster.
|
|
||||||
"""
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
# Dashboard Script in neuem Terminal starten
|
|
||||||
dashboard_script = Path(__file__).parent / "rdagent" / "log" / "ui" / "predix_dashboard.py"
|
|
||||||
|
|
||||||
# Versuche verschiedene Terminal-Emulatoren
|
|
||||||
terminal_commands = [
|
|
||||||
["gnome-terminal", "--", "python", str(dashboard_script)],
|
|
||||||
["konsole", "-e", "python", str(dashboard_script)],
|
|
||||||
["xterm", "-e", "python", str(dashboard_script)],
|
|
||||||
["tilix", "-e", "python", str(dashboard_script)],
|
|
||||||
]
|
|
||||||
|
|
||||||
for cmd in terminal_commands:
|
|
||||||
try:
|
|
||||||
subprocess.Popen(cmd, start_new_session=True)
|
|
||||||
console.print(f"[bold green]✓ Dashboard in neuem Terminal-Fenster gestartet[/bold green]")
|
|
||||||
return True
|
|
||||||
except FileNotFoundError:
|
|
||||||
continue
|
|
||||||
|
|
||||||
console.print("[yellow]⚠ Kein unterstütztes Terminal gefunden. Verwende Web Dashboard (-d) statt CLI.[/yellow]")
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
import argparse
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
|
||||||
description="Predix EURUSD Trading",
|
|
||||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
||||||
epilog="""
|
|
||||||
Examples:
|
|
||||||
python predix.py fin_quant # Normal starten
|
|
||||||
python predix.py fin_quant -d # Web Dashboard (empfohlen!)
|
|
||||||
python predix.py fin_quant -c # CLI Dashboard (separates Terminal)
|
|
||||||
python predix.py fin_quant -d -c # Beide Dashboards
|
|
||||||
python predix.py fin_quant --dashboard-port 5001 # Custom Port
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
subparsers = parser.add_subparsers(dest='command', help='Commands')
|
|
||||||
|
|
||||||
# fin_quant command
|
|
||||||
fq_parser = subparsers.add_parser('fin_quant', help='Start EURUSD quantitative trading loop')
|
|
||||||
fq_parser.add_argument('--path', type=str, default=None, help='Path')
|
|
||||||
fq_parser.add_argument('--step-n', type=int, default=None, help='Number of steps')
|
|
||||||
fq_parser.add_argument('--loop-n', type=int, default=None, help='Number of loops')
|
|
||||||
fq_parser.add_argument('--all-duration', type=str, default=None, help='Duration')
|
|
||||||
fq_parser.add_argument('--checkout', action='store_true', default=True, help='Checkout')
|
|
||||||
fq_parser.add_argument('--no-checkout', action='store_false', dest='checkout', help='No checkout')
|
|
||||||
fq_parser.add_argument('-d', '--with-dashboard', action='store_true', help='Start web dashboard')
|
|
||||||
fq_parser.add_argument('-c', '--cli-dashboard', action='store_true', help='Start CLI dashboard in new terminal')
|
|
||||||
fq_parser.add_argument('--dashboard-port', type=int, default=5000, help='Dashboard port')
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
if args.command == 'fin_quant':
|
|
||||||
# Start Web Dashboard wenn gewünscht
|
|
||||||
if args.with_dashboard:
|
|
||||||
dashboard_thread = threading.Thread(target=start_web_dashboard, args=(args.dashboard_port,), daemon=True)
|
|
||||||
dashboard_thread.start()
|
|
||||||
time.sleep(2)
|
|
||||||
console.print(f"[bold green]✓ Web Dashboard gestartet: http://localhost:{args.dashboard_port}/dashboard.html[/bold green]")
|
|
||||||
|
|
||||||
# Start CLI Dashboard in SEPARATEM Terminal wenn gewünscht
|
|
||||||
if args.cli_dashboard:
|
|
||||||
start_cli_dashboard_standalone()
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
# Fin Quant starten
|
|
||||||
console.print("\n[bold cyan]Starting fin_quant...[/bold cyan]\n")
|
|
||||||
fin_quant(
|
|
||||||
path=args.path,
|
|
||||||
step_n=args.step_n,
|
|
||||||
loop_n=args.loop_n,
|
|
||||||
all_duration=args.all_duration,
|
|
||||||
checkout=args.checkout
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
parser.print_help()
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
Reference in New Issue
Block a user