- Added display_name and description to BaseStrategy - Updated MA44 and MA125 strategies with metadata - Added /api/v1/strategies endpoint for dynamic discovery - Added Strategy Simulation panel to dashboard with date picker and tooltips - Implemented JS polling for backtest results in dashboard - Added performance test scripts and DB connection guide - Expanded indicator config to all 15 timeframes
88 lines
2.9 KiB
Bash
88 lines
2.9 KiB
Bash
#!/bin/bash
|
|
# Apply schema updates to a running TimescaleDB container without wiping data
|
|
|
|
echo "Applying schema updates to btc_timescale container..."
|
|
|
|
# Execute the schema SQL inside the container
|
|
# We use psql with the environment variables set in docker-compose
|
|
docker exec -i btc_timescale psql -U btc_bot -d btc_data <<EOF
|
|
-- 1. Unique constraint for indicators (if not exists)
|
|
DO \$\$
|
|
BEGIN
|
|
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'indicators_unique') THEN
|
|
ALTER TABLE indicators ADD CONSTRAINT indicators_unique UNIQUE (time, symbol, interval, indicator_name);
|
|
END IF;
|
|
END \$\$;
|
|
|
|
-- 2. Index for indicators
|
|
CREATE INDEX IF NOT EXISTS idx_indicators_lookup ON indicators (symbol, interval, indicator_name, time DESC);
|
|
|
|
-- 3. Data health view update
|
|
CREATE OR REPLACE VIEW data_health AS
|
|
SELECT
|
|
symbol,
|
|
COUNT(*) as total_candles,
|
|
COUNT(*) FILTER (WHERE validated) as validated_candles,
|
|
MAX(time) as latest_candle,
|
|
MIN(time) as earliest_candle,
|
|
NOW() - MAX(time) as time_since_last
|
|
FROM candles
|
|
GROUP BY symbol;
|
|
|
|
-- 4. Decisions table
|
|
CREATE TABLE IF NOT EXISTS decisions (
|
|
time TIMESTAMPTZ NOT NULL,
|
|
symbol TEXT NOT NULL,
|
|
interval TEXT NOT NULL,
|
|
decision_type TEXT NOT NULL,
|
|
strategy TEXT NOT NULL,
|
|
confidence DECIMAL(5,4),
|
|
price_at_decision DECIMAL(18,8),
|
|
indicator_snapshot JSONB NOT NULL,
|
|
candle_snapshot JSONB NOT NULL,
|
|
reasoning TEXT,
|
|
backtest_id TEXT,
|
|
executed BOOLEAN DEFAULT FALSE,
|
|
execution_price DECIMAL(18,8),
|
|
execution_time TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- 5. Decisions hypertable (ignore error if already exists)
|
|
DO \$\$
|
|
BEGIN
|
|
PERFORM create_hypertable('decisions', 'time', chunk_time_interval => INTERVAL '7 days', if_not_exists => TRUE);
|
|
EXCEPTION WHEN OTHERS THEN
|
|
NULL; -- Ignore if already hypertable
|
|
END \$\$;
|
|
|
|
-- 6. Decisions indexes
|
|
CREATE INDEX IF NOT EXISTS idx_decisions_live ON decisions (symbol, interval, time DESC) WHERE backtest_id IS NULL;
|
|
CREATE INDEX IF NOT EXISTS idx_decisions_backtest ON decisions (backtest_id, symbol, time DESC) WHERE backtest_id IS NOT NULL;
|
|
CREATE INDEX IF NOT EXISTS idx_decisions_type ON decisions (symbol, decision_type, time DESC);
|
|
|
|
-- 7. Backtest runs table
|
|
CREATE TABLE IF NOT EXISTS backtest_runs (
|
|
id TEXT PRIMARY KEY,
|
|
strategy TEXT NOT NULL,
|
|
symbol TEXT NOT NULL DEFAULT 'BTC',
|
|
start_time TIMESTAMPTZ NOT NULL,
|
|
end_time TIMESTAMPTZ NOT NULL,
|
|
intervals TEXT[] NOT NULL,
|
|
config JSONB,
|
|
results JSONB,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- 8. Compression policies
|
|
DO \$\$
|
|
BEGIN
|
|
ALTER TABLE decisions SET (timescaledb.compress, timescaledb.compress_segmentby = 'symbol,interval,strategy');
|
|
PERFORM add_compression_policy('decisions', INTERVAL '7 days', if_not_exists => TRUE);
|
|
EXCEPTION WHEN OTHERS THEN
|
|
NULL; -- Ignore compression errors if already set
|
|
END \$\$;
|
|
|
|
SELECT 'Schema update completed successfully' as status;
|
|
EOF
|