Memory-augmented agentic discovery for daily Qlib OHLCV/VWAP alpha factors.
This release exposes only the generated_pool workflow. LLM agents propose compact daily factor expressions; deterministic local tools materialize panels, evaluate standalone validation RankIC, apply BH-FDR, and append accepted candidates to a generated factor library.
seed memory / prior project memory
-> Planner proposes one hypothesis
-> Researcher refines the hypothesis
-> Engineer writes one Qlib expression
-> local expression validation and Qlib preflight
-> factor panel materialization
-> train-split dedup against the generated library
-> single-factor train/val/test evaluation
-> validation daily RankIC bootstrap + Benjamini-Hochberg false discovery rate (BH-FDR) control
-> discovered_fdr / watchlist / failure ledger
-> memory-card derivation and report
LLMs produce hypotheses, rationales, and expressions. Metrics and acceptance decisions come from deterministic tools.
- Python 3.11
- Conda environment named
factor - Qlib CN daily data with
csi300instruments - An OpenAI-compatible LLM endpoint
Create or update the environment:
conda env create -f environment.yaml
conda activate factor
pip install -e ".[dev]"Copy the example file and fill in values for your machine:
cp .env.example .envThe CLI and scripts/run_discovery_4h.sh load .env from the repository root. Values already exported in the shell take precedence over values in .env. Do not commit .env.
Minimum .env values:
LLM_PROVIDER=deepseek
DEEPSEEK_API_KEY=
DEEPSEEK_BASE_URL=https://api.deepseek.com
DATA_ROOT=/absolute/path/to/alpha-agent-data
QLIB_CN_DATA=/absolute/path/to/qlib-cn-dataUse absolute paths outside this repository for DATA_ROOT, QLIB_CN_DATA, downloaded archives, logs, generated panels, and run artifacts.
The recommended entrypoint is scripts/run_discovery_4h.sh. It loads .env, checks the Qlib data path, builds the registry data pack if it is missing, runs the generated-pool loop for the requested wall-clock budget, and writes factor outputs under $DATA_ROOT.
The pipeline expects daily CN Qlib data at QLIB_CN_DATA. One common source is the community qlib_bin.tar.gz archive:
export QLIB_RAW_DIR=/absolute/path/to/qlib-raw
export QLIB_CN_DATA=/absolute/path/to/qlib-cn-data
mkdir -p "$QLIB_RAW_DIR" "$QLIB_CN_DATA"
wget -O "$QLIB_RAW_DIR/qlib_bin.tar.gz" \
https://github.com/chenditc/investment_data/releases/latest/download/qlib_bin.tar.gz
tar -xzf "$QLIB_RAW_DIR/qlib_bin.tar.gz" \
-C "$QLIB_CN_DATA" \
--strip-components=1Alternatively, use Qlib's downloader:
python -m qlib.cli.data qlib_data \
--target_dir "$QLIB_CN_DATA" \
--region cnSet the same QLIB_CN_DATA path in .env before running discovery.
conda activate factor
bash scripts/run_discovery_4h.sh --dry-runHOURS controls how long the agent keeps proposing and evaluating candidates. This example runs for four hours:
PROJECT=discovery_$(date -u +%Y%m%d_%H%M%S) \
REGISTRY=csi300_daily_2018_2024_v1 \
HOURS=4 \
ACCEPT_SF_VAL_RANK_IC_FLOOR=0.003 \
ACCEPT_SF_VAL_TURNOVER_CEILING=3.0 \
ACCEPT_BH_Q_THRESHOLD=0.10 \
ACCEPT_MAX_ABS_CORR_TRAIN_CEILING=0.80 \
bash scripts/run_discovery_4h.sh \
--end 2024-12-31 \
--train-start 2018-01-01 \
--train-end 2021-12-31 \
--val-start 2022-01-01 \
--val-end 2023-12-31 \
--test-start 2024-01-01 \
--test-end 2024-12-31By default this is a true cold start: no curated JSONL memory seed is bundled or loaded. The wrapper uses a compressed mechanism prior in THEME so the agents still start with useful daily OHLCV/VWAP search directions. Override THEME when you want a different research agenda.
To continue from a previous project, set these in .env or in the shell before the command:
MEMORY_PROJECT=previous_discovery_project_id
ACCEPTED_PROJECT=previous_discovery_project_idIf you have your own JSONL memory seed, pass it explicitly:
MEMORY_SEED_FILE=/absolute/path/to/your-memory-seed.jsonl \
bash scripts/run_discovery_4h.sh --dry-runGenerated-pool acceptance uses standalone validation RankIC, BH-FDR q-value, turnover, and generated-library correlation gates. The internal unit-test tree is not included in the slim release.
The two primary outputs are the accepted-factor manifest and the candidate ledger:
$DATA_ROOT/accepted_factors/$PROJECT/manifest.jsonl
$DATA_ROOT/candidate_ledger/$PROJECT/ledger.jsonl
accepted_factors/$PROJECT/manifest.jsonl: append-only generated-factor manifest. Read the latest rows with statusdiscovered_fdr; these are the active generated-factor library for future runs. Each row includes the candidate id, expression, panel path, acceptance status, acceptance timestamp, and deterministic evidence used by the gates.candidate_ledger/$PROJECT/ledger.jsonl: append-only record of every candidate attempt. Use this file to inspect validation status, train/validation/test RankIC metrics, turnover, correlation dedup results, bootstrap/BH-FDR evidence, rejection reasons, and watchlist/failure outcomes.
For summary, open:
$DATA_ROOT/artifacts/$PROJECT/reports/discovery_report.md
The report summarizes the candidate funnel, accepted-factor quality, failure patterns, warnings, and follow-up notes.
Other run artifacts are mainly operational:
$DATA_ROOT/artifacts/$PROJECT/agentic_long_run/agentic_long_run_summary.json
$DATA_ROOT/artifacts/$PROJECT/agentic_long_run/discovery_memory_monitor.json
$DATA_ROOT/memory_cards/$PROJECT/{factors,hypotheses,lessons}.jsonl
agentic_long_run_summary.json and discovery_memory_monitor.json are compact machine-readable run/health summaries. memory_cards are derived state for later runs, not the main factor result.
alpha_agent/
agents/ Researcher, Engineer, near-accept Critic
cli/ public discovery CLI
data/ append-only events, candidate ledger, accepted store, memory cards
eval/ eval config, acceptance policy, cache keys
infra/ paths and OpenAI-compatible LLM client
orchestration/ generated-pool discovery loop, reporting, observability
tools/ Qlib data pack, panels, dedup, single-factor eval, stats, memory
scripts/
run_discovery_4h.sh 4h discovery wrapper
discovery_long_run.py wall-clock long-run driver
discovery_memory_monitor.py compact memory/quality monitor
docs/
PROJECT_DESIGN_OVERVIEW.md generated-pool method overview
ARCHITECTURE.md storage and module architecture
