Persistence
π¦ 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
AthenaAI keeps three artifacts on disk so learned state and trade history survive restarts. All paths are relative to the working directory unless configured otherwise.
| File | Default path | Configured by |
|---|---|---|
| Brain (model state) | athena_brain.pkl | PO_BRAIN_PATH / --out (note: BotConfigβs own default is athena_po_brain.pkl if you bypass main.py) |
| Expiry stats | <brain>_expiry.pkl (e.g. athena_brain_expiry.pkl) | derived: brain_path.replace(".pkl", "_expiry.pkl") |
| Trade journal | trade_journal.db | BotConfig.db_path (config-only) |
The brain pickle
Written by EnsemblePredictor.save_brain() (src/core/models.py) as a single pickled dict:
| Key | Contents |
|---|---|
scaler | The fitted StandardScaler (its n_features_in_ defines the expected feature dimension) |
models | Online models as (name, classifier, accuracy_ema) tuples: SGD, PA, NB |
batch_models | Batch models as the same tuples: GBM, RF, and β if trained via train.py with PyTorch β MLP (a TorchMLPClassifier whose weights are stored as a CPU state dict; see GPU training) |
batch_fitted | Whether batch models are trained |
fitted | Whether the ensemble is usable at all |
save_brain refuses to write an unfitted ensemble (No trained models to save.). On load, saved online models replace the fresh ones positionally, and the batch-model list is rebuilt entirely from the file β which is how a trainer-produced MLP travels into the live bot. A failed load logs Failed to load brain: ... and returns False, sending the bot down the journal-reload + dataset path.
When it is written:
- End of every
train.pyrun (the output directory is created if missing). - After in-process dataset pre-training in the bot.
- Automatically every 10 completed trades during live trading.
- On clean shutdown (
Ctrl+Cβbot.stop()).
The expiry stats pickle (<brain>_expiry.pkl)
Whenever the bot saves the brain, _save_brain() in src/bot.py also pickles ExpirySelector.save_state() β the per-expiry win/loss counts the AI uses to pick trade durations (Expiry selection) β to the brain path with .pkl replaced by _expiry.pkl. On startup it is loaded if present (β± Expiry stats loaded: ...); a corrupt file just logs a warning and starts fresh. train.py does not produce this file β expiry stats come only from live results.
The trade journal (trade_journal.db)
SQLite database managed by TradeJournal (src/trading/journal.py). Two tables:
trades
| Column | Type | Meaning |
|---|---|---|
id | TEXT (primary key) | Broker trade ID |
direction | TEXT | call / put |
asset | TEXT | e.g. EURUSD |
stake | REAL | $ risked |
confidence | REAL | Model confidence at entry (0β1) |
regime | TEXT | Detected regime at entry |
entry_time | REAL | Unix epoch seconds |
exit_time | REAL | Unix epoch seconds (NULL until resolved) |
result | TEXT | win / loss / draw (NULL while pending) |
profit | REAL | Realized $ P&L |
features | TEXT | The entry feature vector as JSON (used for retraining) |
expiry | INTEGER | Chosen expiry in seconds |
model_snapshots
| Column | Type | Meaning |
|---|---|---|
ts | REAL | Snapshot time (epoch) |
win_rate | REAL | Overall win rate at snapshot |
total_trades | INTEGER | Trades so far |
daily_pnl | REAL | $ P&L for the UTC day |
regime | TEXT | Regime at snapshot time |
Migration: _init_db() runs on every startup with CREATE TABLE IF NOT EXISTS, then attempts ALTER TABLE trades ADD COLUMN for features and expiry, swallowing the error if they already exist β so journals from older versions upgrade in place.
When it is written: each trade is inserted (INSERT OR REPLACE) immediately when placed and rewritten when resolved; a model_snapshots row is added every 10 completed trades.
Journal reload on startup
When no brain loads, _reload_from_journal() (src/bot.py) rebuilds model state from history via load_completed_trades(), which selects direction, result, and features for all rows with result IN ('win','loss') and non-NULL features, ordered by entry time. For each trade:
- Feature-dimension filtering: the first tradeβs feature vector sets the expected dimension; any trade whose vector length differs is skipped. Trades matching the current engineβs full dimension also feed the Feature lab.
- Label derivation:
winβ the traded direction is the label (callβ1,putβ0);lossβ the opposite direction (1 β dir). The samples are fed to the ensemble andpartial_fitruns once at the end (π Reloaded N trades from journal β models retrained!). - Win/loss counts restore the performance tracker (
π Restored stats: W:.. L:.. WR:..%), and each trade is replayed into the adaptive strategy. Because the reload query only returns three columns, the adaptive replay uses fallback values for the rest (regimeranging, confidence0.6, hour12) β so restored adaptive stats are coarser than live ones. - Corrupted rows are skipped silently.
Resetting each artifact safely
Stop the bot first in all cases.
| Goal | Action | Consequence |
|---|---|---|
| Fresh models, keep history | Delete athena_brain.pkl and <brain>_expiry.pkl (or run once with PO_RETRAIN=1, which deletes the brain but not the expiry file) | Next startup retrains from journal + PO_DATASET |
| Fresh expiry preferences only | Delete <brain>_expiry.pkl | Expiry selection restarts from neutral stats |
| Full factory reset | Delete brain, expiry pickle, and trade_journal.db | All learning and trade history gone; only the dataset pre-train remains |
| Keep everything, new machine | Copy all three files | Brains are portable, including GPU-trained ones (GPU training) |
Never delete files while the bot runs: the journal is an open SQLite connection, and an autosave could recreate a half-written brain. Back up by copying the three files while the bot is stopped.
Security note: brain files are Python pickles β only load brain files you created yourself.
See also
- Architecture β where each write happens in the loops
- Training β producing a brain offline
- Live trading β autosave cadence in context
π¬ 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.