feat: Smart AI Trading Bot for XAUUSD with ML and SMC
- XGBoost ML model with 37 features for market direction prediction - Smart Money Concepts (SMC): Order Blocks, FVG, BOS, CHoCH - HMM market regime detection (trending/ranging/volatile) - ATR-based stop loss with 1.5 ATR minimum distance - Broker-level SL protection with fallback - Time-based exit (max 6 hours per trade) - Session-aware trading optimized for London/NY overlap - Auto-retraining based on market conditions - Telegram notifications and web dashboard - Backtest results: 63.9% win rate, 2.64 profit factor, 4.83 Sharpe Backtest period: Jan 2025 - Feb 2026, 654 trades, $4,189 net P/L Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,459 @@
|
||||
-- ============================================================
|
||||
-- Trading Bot Database Schema
|
||||
-- ============================================================
|
||||
-- Version: 1.0.0
|
||||
-- Created: 2026-02-05
|
||||
-- Description: PostgreSQL schema for AI Trading Bot data persistence
|
||||
-- ============================================================
|
||||
|
||||
-- Enable UUID extension
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
|
||||
-- ============================================================
|
||||
-- TRADES TABLE - Main trade history
|
||||
-- ============================================================
|
||||
CREATE TABLE IF NOT EXISTS trades (
|
||||
id SERIAL PRIMARY KEY,
|
||||
ticket BIGINT UNIQUE NOT NULL,
|
||||
symbol VARCHAR(20) NOT NULL DEFAULT 'XAUUSD',
|
||||
direction VARCHAR(4) NOT NULL CHECK (direction IN ('BUY', 'SELL')),
|
||||
|
||||
-- Prices
|
||||
entry_price DECIMAL(12,5) NOT NULL,
|
||||
exit_price DECIMAL(12,5),
|
||||
stop_loss DECIMAL(12,5) DEFAULT 0,
|
||||
take_profit DECIMAL(12,5) DEFAULT 0,
|
||||
|
||||
-- Size & Result
|
||||
lot_size DECIMAL(8,4) NOT NULL,
|
||||
profit_usd DECIMAL(12,2),
|
||||
profit_pips DECIMAL(10,2),
|
||||
|
||||
-- Timing
|
||||
opened_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
closed_at TIMESTAMPTZ,
|
||||
duration_seconds INT,
|
||||
|
||||
-- Market Context at Entry
|
||||
entry_regime VARCHAR(30),
|
||||
entry_volatility VARCHAR(20),
|
||||
entry_session VARCHAR(30),
|
||||
entry_spread DECIMAL(8,2),
|
||||
entry_atr DECIMAL(10,5),
|
||||
|
||||
-- SMC Signals
|
||||
smc_signal VARCHAR(10),
|
||||
smc_confidence DECIMAL(5,4),
|
||||
smc_reason TEXT,
|
||||
smc_fvg_detected BOOLEAN DEFAULT FALSE,
|
||||
smc_ob_detected BOOLEAN DEFAULT FALSE,
|
||||
smc_bos_detected BOOLEAN DEFAULT FALSE,
|
||||
smc_choch_detected BOOLEAN DEFAULT FALSE,
|
||||
|
||||
-- ML Signals
|
||||
ml_signal VARCHAR(10),
|
||||
ml_confidence DECIMAL(5,4),
|
||||
|
||||
-- Dynamic Analysis
|
||||
market_quality VARCHAR(20),
|
||||
market_score INT,
|
||||
dynamic_threshold DECIMAL(5,4),
|
||||
|
||||
-- Exit Details
|
||||
exit_reason VARCHAR(50),
|
||||
exit_regime VARCHAR(30),
|
||||
exit_ml_signal VARCHAR(10),
|
||||
exit_ml_confidence DECIMAL(5,4),
|
||||
|
||||
-- Balance Tracking
|
||||
balance_before DECIMAL(12,2),
|
||||
balance_after DECIMAL(12,2),
|
||||
equity_at_entry DECIMAL(12,2),
|
||||
|
||||
-- Features (JSONB for flexibility)
|
||||
features_entry JSONB DEFAULT '{}',
|
||||
features_exit JSONB DEFAULT '{}',
|
||||
|
||||
-- Meta
|
||||
bot_version VARCHAR(20) DEFAULT '2.1',
|
||||
trade_mode VARCHAR(30) DEFAULT 'SMC-ONLY',
|
||||
|
||||
-- Timestamps
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- TRAINING_RUNS TABLE - ML model training history
|
||||
-- ============================================================
|
||||
CREATE TABLE IF NOT EXISTS training_runs (
|
||||
id SERIAL PRIMARY KEY,
|
||||
run_id UUID DEFAULT uuid_generate_v4(),
|
||||
|
||||
-- Timing
|
||||
started_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
completed_at TIMESTAMPTZ,
|
||||
duration_seconds INT,
|
||||
|
||||
-- Configuration
|
||||
training_type VARCHAR(20) NOT NULL CHECK (training_type IN ('daily', 'weekend', 'manual', 'initial')),
|
||||
bars_used INT,
|
||||
num_boost_rounds INT,
|
||||
|
||||
-- Results - HMM
|
||||
hmm_trained BOOLEAN DEFAULT FALSE,
|
||||
hmm_n_regimes INT,
|
||||
|
||||
-- Results - XGBoost
|
||||
xgb_trained BOOLEAN DEFAULT FALSE,
|
||||
train_auc DECIMAL(6,5),
|
||||
test_auc DECIMAL(6,5),
|
||||
train_accuracy DECIMAL(6,5),
|
||||
test_accuracy DECIMAL(6,5),
|
||||
|
||||
-- Model Paths
|
||||
model_path VARCHAR(255),
|
||||
backup_path VARCHAR(255),
|
||||
|
||||
-- Status
|
||||
success BOOLEAN DEFAULT FALSE,
|
||||
error_message TEXT,
|
||||
|
||||
-- Rollback
|
||||
rolled_back BOOLEAN DEFAULT FALSE,
|
||||
rollback_reason TEXT,
|
||||
rollback_at TIMESTAMPTZ,
|
||||
|
||||
-- Meta
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- MARKET_SNAPSHOTS TABLE - Periodic market state (time-series)
|
||||
-- ============================================================
|
||||
CREATE TABLE IF NOT EXISTS market_snapshots (
|
||||
id SERIAL PRIMARY KEY,
|
||||
snapshot_time TIMESTAMPTZ NOT NULL,
|
||||
symbol VARCHAR(20) NOT NULL DEFAULT 'XAUUSD',
|
||||
|
||||
-- Price
|
||||
price DECIMAL(12,5) NOT NULL,
|
||||
|
||||
-- OHLC (current candle)
|
||||
open_price DECIMAL(12,5),
|
||||
high_price DECIMAL(12,5),
|
||||
low_price DECIMAL(12,5),
|
||||
close_price DECIMAL(12,5),
|
||||
|
||||
-- Market State
|
||||
regime VARCHAR(30),
|
||||
volatility VARCHAR(20),
|
||||
session VARCHAR(30),
|
||||
atr DECIMAL(10,5),
|
||||
spread DECIMAL(8,2),
|
||||
|
||||
-- Signals
|
||||
ml_signal VARCHAR(10),
|
||||
ml_confidence DECIMAL(5,4),
|
||||
smc_signal VARCHAR(10),
|
||||
smc_confidence DECIMAL(5,4),
|
||||
|
||||
-- Position State
|
||||
open_positions INT DEFAULT 0,
|
||||
floating_pnl DECIMAL(12,2) DEFAULT 0,
|
||||
|
||||
-- Features Snapshot
|
||||
features JSONB DEFAULT '{}',
|
||||
|
||||
-- Meta
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
|
||||
-- Composite unique constraint
|
||||
UNIQUE (snapshot_time, symbol)
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- SIGNALS TABLE - Every signal generated
|
||||
-- ============================================================
|
||||
CREATE TABLE IF NOT EXISTS signals (
|
||||
id SERIAL PRIMARY KEY,
|
||||
signal_time TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
symbol VARCHAR(20) NOT NULL DEFAULT 'XAUUSD',
|
||||
price DECIMAL(12,5) NOT NULL,
|
||||
|
||||
-- Signal Details
|
||||
signal_type VARCHAR(10) CHECK (signal_type IN ('BUY', 'SELL', 'NONE', 'HOLD')),
|
||||
signal_source VARCHAR(20), -- 'SMC', 'ML', 'COMBINED', 'SMC-ONLY'
|
||||
combined_confidence DECIMAL(5,4),
|
||||
|
||||
-- SMC Analysis
|
||||
smc_signal VARCHAR(10),
|
||||
smc_confidence DECIMAL(5,4),
|
||||
smc_fvg BOOLEAN DEFAULT FALSE,
|
||||
smc_ob BOOLEAN DEFAULT FALSE,
|
||||
smc_bos BOOLEAN DEFAULT FALSE,
|
||||
smc_choch BOOLEAN DEFAULT FALSE,
|
||||
smc_reason TEXT,
|
||||
|
||||
-- ML Analysis
|
||||
ml_signal VARCHAR(10),
|
||||
ml_confidence DECIMAL(5,4),
|
||||
|
||||
-- Market Context
|
||||
regime VARCHAR(30),
|
||||
session VARCHAR(30),
|
||||
volatility VARCHAR(20),
|
||||
market_score INT,
|
||||
dynamic_threshold DECIMAL(5,4),
|
||||
|
||||
-- Execution
|
||||
executed BOOLEAN DEFAULT FALSE,
|
||||
execution_reason VARCHAR(100),
|
||||
trade_ticket BIGINT,
|
||||
|
||||
-- Meta
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- DAILY_SUMMARIES TABLE - Daily performance tracking
|
||||
-- ============================================================
|
||||
CREATE TABLE IF NOT EXISTS daily_summaries (
|
||||
id SERIAL PRIMARY KEY,
|
||||
summary_date DATE UNIQUE NOT NULL,
|
||||
|
||||
-- Trades
|
||||
total_trades INT DEFAULT 0,
|
||||
winning_trades INT DEFAULT 0,
|
||||
losing_trades INT DEFAULT 0,
|
||||
breakeven_trades INT DEFAULT 0,
|
||||
|
||||
-- P/L
|
||||
gross_profit DECIMAL(12,2) DEFAULT 0,
|
||||
gross_loss DECIMAL(12,2) DEFAULT 0,
|
||||
net_profit DECIMAL(12,2) DEFAULT 0,
|
||||
|
||||
-- Balance
|
||||
start_balance DECIMAL(12,2),
|
||||
end_balance DECIMAL(12,2),
|
||||
|
||||
-- Metrics
|
||||
win_rate DECIMAL(5,2),
|
||||
profit_factor DECIMAL(8,4),
|
||||
average_win DECIMAL(12,2),
|
||||
average_loss DECIMAL(12,2),
|
||||
largest_win DECIMAL(12,2),
|
||||
largest_loss DECIMAL(12,2),
|
||||
|
||||
-- Sessions
|
||||
trades_sydney INT DEFAULT 0,
|
||||
trades_tokyo INT DEFAULT 0,
|
||||
trades_london INT DEFAULT 0,
|
||||
trades_ny INT DEFAULT 0,
|
||||
trades_golden INT DEFAULT 0,
|
||||
|
||||
-- SMC Performance
|
||||
fvg_trades INT DEFAULT 0,
|
||||
fvg_wins INT DEFAULT 0,
|
||||
ob_trades INT DEFAULT 0,
|
||||
ob_wins INT DEFAULT 0,
|
||||
|
||||
-- Meta
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- BOT_STATUS TABLE - Bot health and status tracking
|
||||
-- ============================================================
|
||||
CREATE TABLE IF NOT EXISTS bot_status (
|
||||
id SERIAL PRIMARY KEY,
|
||||
status_time TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
|
||||
-- Status
|
||||
is_running BOOLEAN DEFAULT TRUE,
|
||||
status VARCHAR(20) DEFAULT 'active', -- 'active', 'paused', 'stopped', 'error'
|
||||
|
||||
-- Performance
|
||||
loop_count INT DEFAULT 0,
|
||||
avg_execution_ms DECIMAL(10,2),
|
||||
uptime_seconds INT DEFAULT 0,
|
||||
|
||||
-- Account
|
||||
balance DECIMAL(12,2),
|
||||
equity DECIMAL(12,2),
|
||||
margin_used DECIMAL(12,2),
|
||||
|
||||
-- Positions
|
||||
open_positions INT DEFAULT 0,
|
||||
floating_pnl DECIMAL(12,2),
|
||||
|
||||
-- Risk State
|
||||
daily_pnl DECIMAL(12,2),
|
||||
risk_mode VARCHAR(20), -- 'normal', 'recovery', 'protected', 'stopped'
|
||||
|
||||
-- Session
|
||||
current_session VARCHAR(30),
|
||||
is_golden_time BOOLEAN DEFAULT FALSE,
|
||||
|
||||
-- Error
|
||||
last_error TEXT,
|
||||
last_error_at TIMESTAMPTZ,
|
||||
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- INDEXES for fast queries
|
||||
-- ============================================================
|
||||
|
||||
-- Trades indexes
|
||||
CREATE INDEX IF NOT EXISTS idx_trades_opened_at ON trades(opened_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_trades_closed_at ON trades(closed_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_trades_symbol ON trades(symbol);
|
||||
CREATE INDEX IF NOT EXISTS idx_trades_direction ON trades(direction);
|
||||
CREATE INDEX IF NOT EXISTS idx_trades_profit ON trades(profit_usd);
|
||||
CREATE INDEX IF NOT EXISTS idx_trades_exit_reason ON trades(exit_reason);
|
||||
CREATE INDEX IF NOT EXISTS idx_trades_entry_session ON trades(entry_session);
|
||||
|
||||
-- Training runs indexes
|
||||
CREATE INDEX IF NOT EXISTS idx_training_started_at ON training_runs(started_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_training_type ON training_runs(training_type);
|
||||
|
||||
-- Snapshots indexes
|
||||
CREATE INDEX IF NOT EXISTS idx_snapshots_time ON market_snapshots(snapshot_time DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_snapshots_symbol_time ON market_snapshots(symbol, snapshot_time DESC);
|
||||
|
||||
-- Signals indexes
|
||||
CREATE INDEX IF NOT EXISTS idx_signals_time ON signals(signal_time DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_signals_executed ON signals(executed);
|
||||
CREATE INDEX IF NOT EXISTS idx_signals_type ON signals(signal_type);
|
||||
|
||||
-- Daily summaries index
|
||||
CREATE INDEX IF NOT EXISTS idx_daily_date ON daily_summaries(summary_date DESC);
|
||||
|
||||
-- Bot status index
|
||||
CREATE INDEX IF NOT EXISTS idx_bot_status_time ON bot_status(status_time DESC);
|
||||
|
||||
-- ============================================================
|
||||
-- FUNCTIONS for automatic updates
|
||||
-- ============================================================
|
||||
|
||||
-- Function to update updated_at timestamp
|
||||
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = NOW();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ language 'plpgsql';
|
||||
|
||||
-- Trigger for trades table
|
||||
DROP TRIGGER IF EXISTS update_trades_updated_at ON trades;
|
||||
CREATE TRIGGER update_trades_updated_at
|
||||
BEFORE UPDATE ON trades
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
-- Trigger for daily_summaries table
|
||||
DROP TRIGGER IF EXISTS update_daily_summaries_updated_at ON daily_summaries;
|
||||
CREATE TRIGGER update_daily_summaries_updated_at
|
||||
BEFORE UPDATE ON daily_summaries
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
-- ============================================================
|
||||
-- VIEWS for easy querying
|
||||
-- ============================================================
|
||||
|
||||
-- Recent trades view
|
||||
CREATE OR REPLACE VIEW v_recent_trades AS
|
||||
SELECT
|
||||
ticket,
|
||||
direction,
|
||||
entry_price,
|
||||
exit_price,
|
||||
lot_size,
|
||||
profit_usd,
|
||||
profit_pips,
|
||||
duration_seconds,
|
||||
entry_session,
|
||||
smc_reason,
|
||||
ml_confidence,
|
||||
exit_reason,
|
||||
opened_at,
|
||||
closed_at
|
||||
FROM trades
|
||||
WHERE closed_at IS NOT NULL
|
||||
ORDER BY closed_at DESC
|
||||
LIMIT 100;
|
||||
|
||||
-- Daily performance view
|
||||
CREATE OR REPLACE VIEW v_daily_performance AS
|
||||
SELECT
|
||||
DATE(closed_at) as trade_date,
|
||||
COUNT(*) as total_trades,
|
||||
SUM(CASE WHEN profit_usd > 0 THEN 1 ELSE 0 END) as wins,
|
||||
SUM(CASE WHEN profit_usd < 0 THEN 1 ELSE 0 END) as losses,
|
||||
SUM(profit_usd) as net_profit,
|
||||
ROUND(AVG(profit_usd)::numeric, 2) as avg_profit,
|
||||
ROUND((SUM(CASE WHEN profit_usd > 0 THEN 1 ELSE 0 END)::numeric /
|
||||
NULLIF(COUNT(*), 0) * 100), 1) as win_rate
|
||||
FROM trades
|
||||
WHERE closed_at IS NOT NULL
|
||||
GROUP BY DATE(closed_at)
|
||||
ORDER BY trade_date DESC;
|
||||
|
||||
-- SMC performance view
|
||||
CREATE OR REPLACE VIEW v_smc_performance AS
|
||||
SELECT
|
||||
CASE
|
||||
WHEN smc_fvg_detected THEN 'FVG'
|
||||
WHEN smc_ob_detected THEN 'OB'
|
||||
WHEN smc_bos_detected THEN 'BOS'
|
||||
ELSE 'OTHER'
|
||||
END as pattern_type,
|
||||
COUNT(*) as total_trades,
|
||||
SUM(CASE WHEN profit_usd > 0 THEN 1 ELSE 0 END) as wins,
|
||||
SUM(profit_usd) as total_profit,
|
||||
ROUND(AVG(profit_usd)::numeric, 2) as avg_profit,
|
||||
ROUND((SUM(CASE WHEN profit_usd > 0 THEN 1 ELSE 0 END)::numeric /
|
||||
NULLIF(COUNT(*), 0) * 100), 1) as win_rate
|
||||
FROM trades
|
||||
WHERE closed_at IS NOT NULL
|
||||
GROUP BY pattern_type
|
||||
ORDER BY total_trades DESC;
|
||||
|
||||
-- Session performance view
|
||||
CREATE OR REPLACE VIEW v_session_performance AS
|
||||
SELECT
|
||||
entry_session,
|
||||
COUNT(*) as total_trades,
|
||||
SUM(CASE WHEN profit_usd > 0 THEN 1 ELSE 0 END) as wins,
|
||||
SUM(profit_usd) as total_profit,
|
||||
ROUND(AVG(profit_usd)::numeric, 2) as avg_profit,
|
||||
ROUND((SUM(CASE WHEN profit_usd > 0 THEN 1 ELSE 0 END)::numeric /
|
||||
NULLIF(COUNT(*), 0) * 100), 1) as win_rate
|
||||
FROM trades
|
||||
WHERE closed_at IS NOT NULL AND entry_session IS NOT NULL
|
||||
GROUP BY entry_session
|
||||
ORDER BY total_trades DESC;
|
||||
|
||||
-- ============================================================
|
||||
-- INITIAL DATA / SEED
|
||||
-- ============================================================
|
||||
|
||||
-- Insert initial bot status
|
||||
INSERT INTO bot_status (status, is_running, risk_mode)
|
||||
VALUES ('initialized', false, 'normal')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
-- ============================================================
|
||||
-- GRANTS (if needed for specific users)
|
||||
-- ============================================================
|
||||
-- GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO trading_bot;
|
||||
-- GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO trading_bot;
|
||||
|
||||
-- ============================================================
|
||||
-- Done!
|
||||
-- ============================================================
|
||||
Reference in New Issue
Block a user