Training the brain
🦉 AthenaAI is an AI-powered ensemble machine-learning trading bot for PocketOption, built on BinaryOptionsToolsV2 → Get it on GitLab
💬 Need help? Join the Chipa Discord · ⚡ Go no-code with ChipaEditor
train.py is the standalone trainer. It builds the bot’s model state (the “brain”) from a historical candle CSV — no PocketOption connection, no session ID, no network access required. The resulting brain file is what main.py loads at startup via PO_BRAIN_PATH.
The trainer automatically uses your GPU for the neural model when PyTorch with CUDA (NVIDIA) or MPS (Apple Silicon) is available; everything else runs on CPU with scikit-learn. See GPU training.
Quick start
python train.py # EURUSD_M1.csv → athena_brain.pkl
python train.py --data GBPUSD_M1.csv --out brains/gbpusd.pkl
python train.py --expiry 120 # label for 2-minute trades
python train.py --no-nn # skip the neural model
python train.py --cpu --epochs 50 # force CPU, train longer
python train.py --check-gpu # show detected device and exit
A successful run ends with a walk-forward report and:
✅ Training complete — brain saved to athena_brain.pkl
Point the bot at it (this is already the default path):
PO_BRAIN_PATH=athena_brain.pkl python main.pyCommand-line overview
Each flag has its own page in the CLI reference; this table is the summary.
| Flag | Default | Description |
|---|---|---|
--data | EURUSD_M1.csv | Input candle CSV. HistData semicolon format or any headered CSV (see Data formats). |
--out | athena_brain.pkl | Output brain file. Must match the bot’s PO_BRAIN_PATH. Parent directories are created automatically. |
--timeframe | 60 | Seconds per candle in the dataset. Must match the data (e.g. 60 for M1). |
--expiry | 300 | Trade duration to label for, in seconds. Train for the expiry you actually intend to trade — a brain labeled for 5-minute outcomes is not optimal for 1-minute trades. |
--window | 20 | Rolling window (in candles) used by the feature engine’s indicators. |
--lookback | 200 | Maximum candle history fed into each feature vector. |
--max-candles | 500000 | Keep only the N most recent candles. Bounds memory and training time on large histories. |
--test-split | 0.30 | Fraction of samples (the most recent, chronologically) held out for the walk-forward test. Never trained on. |
--no-nn | off | Skip the neural model entirely; train the sklearn ensemble only. |
--cpu | off | Force CPU even when a GPU is detected. |
--epochs | 30 | Neural model training epochs. |
--batch-size | 2048 | Neural model mini-batch size. Lower it if you hit GPU out-of-memory errors. |
--lr | 0.001 | Neural model learning rate (AdamW). |
--hidden | 128,64 | Neural hidden layer sizes, comma-separated (e.g. 256,128,64). |
--check-gpu | — | Print the detected training device and exit without training. |
How --expiry and --timeframe interact
Each sample is labeled by looking expiry / timeframe candles into the future (the label horizon). With the defaults, 300 s expiry on 60 s candles means: “did the close rise 5 candles later?” If you retrain for a different expiry, keep --timeframe matched to the dataset’s actual candle period — it describes the data, not a preference.
Data formats
The trainer’s load_candles() (src/training/dataset.py) auto-detects HistData semicolon files and headered CSVs (comma or semicolon delimited), covering histdata.com and MetaTrader 5 exports out of the box. Malformed rows are skipped silently. Full column/timestamp specification: Data formats.
Requirements: at least 50 parsed candles to run at all, and at least 200 valid samples after feature generation. Realistically you want tens of thousands of candles — a month of M1 data (~30k candles) is a reasonable minimum, a year or more is better.
What the trainer does
The pipeline in src/training/trainer.py:
- Load & trim — parse the CSV, keep the most recent
--max-candles. - Build samples — slide over the candles; for each position, compute a feature vector from the preceding
--lookbackcandles and label it1if the close is higher after the label horizon (a CALL would win) or0if lower. Flat closes are skipped. On datasets above ~20k samples this fans out across up to 16 CPU worker processes. - Chronological split — the last
--test-splitfraction is held out. There is no shuffling: the model is always tested on data strictly newer than anything it trained on (walk-forward), which prevents look-ahead leakage and gives an honest estimate. - Train online models — SGD, Passive-Aggressive, and Naive Bayes are fed the training samples in chunks via
partial_fit, mirroring how they learn incrementally during live trading. - Train batch models — Gradient Boosting and Random Forest are fit on the full training set (Random Forest uses all CPU cores).
- Train the neural model (unless
--no-nn) — a PyTorch MLP (TorchMLPClassifier) with ReLU + dropout layers trains on the GPU when available. Its holdout accuracy becomes its vote weight inside the ensemble, so a weak net simply gets less say rather than poisoning predictions. - Walk-forward evaluation — the full ensemble predicts every holdout sample and reports the honest win rate (see below).
- Save — the entire ensemble is pickled to
--out. See Persistence for exactly what’s inside.
Reading the walk-forward report
🧪 WALK-FORWARD TEST (30% holdout): 41780 trades
Win: 22120 | Loss: 19660 | HONEST WR: 52.9%
✅ EDGE: +0.8% above breakeven (52.1%)
- HONEST WR is the win rate on data the models never saw, in chronological order — the closest offline proxy for live performance.
- Breakeven is derived from the payout (default
0.92inTrainerConfig): with a 92% payout you must win1 / 1.92 ≈ 52.1%of trades just to break even. - EDGE is the margin above breakeven. Even +1–2% is meaningful at volume; a result below breakeven means the brain would lose money on this data — don’t deploy it, get more/better data or adjust parameters.
Note that live results will differ: the bot additionally applies confidence gating (PO_MIN_CONF/PO_MAX_CONF) and indicator alignment, which filter out the weakest signals the walk-forward test still counts.
GPU training
python train.py --check-gpu
# Device: cuda (GPU: NVIDIA GeForce RTX 4070 (12.0 GB VRAM))
- NVIDIA: install a CUDA build of PyTorch, e.g.
pip install torch --index-url https://download.pytorch.org/whl/cu121. - Apple Silicon: plain
pip install torch— MPS is detected automatically. - No PyTorch at all: the trainer logs
PyTorch not installed — skipping neural modeland the sklearn ensemble still trains fine.
Only the neural model uses the GPU. Sample generation and the sklearn models are CPU-bound regardless.
Portability: the MLP stores its weights as a CPU state dict inside the brain file, so a brain trained on a GPU machine loads and predicts on a CPU-only machine. If PyTorch is missing on the loading machine, the MLP degrades to a neutral 0.5 vote instead of breaking the brain. Details: GPU training.
Recipes
Retrain for a different asset:
python train.py --data GBPUSD_M1.csv --out gbpusd_brain.pkl
PO_ASSET=GBPUSD PO_BRAIN_PATH=gbpusd_brain.pkl python main.py
Match training to your live expiry — if the bot trades with PO_DEFAULT_EXPIRY=120, label for that duration:
python train.py --expiry 120
Fast iteration while experimenting:
python train.py --max-candles 100000 --no-nn
Squeeze out more from the neural model:
python train.py --epochs 60 --hidden 256,128,64 --lr 5e-4Troubleshooting
| Symptom | Cause / fix |
|---|---|
Dataset too small (N candles) | Fewer than 50 candles parsed. Check the file path and that the format matches Data formats — the log prints which columns/format were detected. |
Only N valid samples — need at least 200 | Data parsed but too short after the feature warm-up and horizon are trimmed. Use a longer history. |
| Parsed far fewer candles than expected | Timestamp format not recognized; rows are skipped silently. Compare the file’s date column with Data formats. |
PyTorch not installed — skipping neural model | Informational, not an error. pip install torch to enable it, or pass --no-nn to silence it intentionally. |
--check-gpu says CPU despite having an NVIDIA GPU | You have the CPU-only PyTorch wheel. Reinstall from the CUDA index URL above. |
| CUDA out of memory | Lower --batch-size (e.g. 512), or shrink --hidden. |
Holdout too small — skipping walk-forward test | Fewer than 100 holdout samples. Use more data or a larger --test-split. |
| Training is slow on sample generation | It parallelizes automatically above ~20k samples; cap the data with --max-candles or reduce --lookback if it’s still too slow. |
| Walk-forward WR below breakeven | The models found no edge on this data. Try more history, a different --expiry, or a different asset — do not deploy the brain live. |
More general problems: Troubleshooting.
See also
- CLI reference — every flag in depth
- Data formats — CSV specification and data sources
- GPU training
- Ensemble — what the trained models actually are
💬 Questions about running AthenaAI? Ask in the #trading-bots channel on the Chipa Discord — and if you’d rather design strategies without touching Python, try ChipaEditor.