Files
biggfish/config/auto_config.json
T
sami7777 e02a7e3453 Risk management overhaul: prevent 13-shorts blowup scenario
CRITICAL FIXES (would have prevented the $194K crisis):

1. HARD MAX SHORT POSITION CAP (safety.py + executor.py)
   - new config: max_short_positions=4 (hard limit)
   - new config: max_total_positions=8 (hard limit)
   - executor now queries broker.get_positions() for AUTHORITATIVE count
   - BEFORE opening any short, checks broker directly (not just store)
   - validate_trade() now accepts broker_positions and blocks at hard cap
   - This directly prevents the 13-shorts scenario

2. YESTERDAY-CLOSE DRAWDC OWN CIRCUIT BREAKER (safety.py)
   - new config: yesterday_close_drawdown_limit=3%
   - new config: yesterday_close_drawdown_reduction=50%
   - Separate from peak-equity tracking (which is too slow)
   - At $194K from $200K initial = 3% → fires IMMEDIATELY, cuts 50% of positions
   - Tested: check_yesterday_close_drawdown($194K) → triggers with 50% reduction

3. PER-POSITION STOP LOSS DEFAULTS (safety.py + executor.py)
   - new config: stop_loss_default_pct_long=1.0%, short=1.5%
   - new config: stop_loss_max_pct=3.0% (never wider than this)
   - new config: take_profit_default_pct=2.0%
   - NEW: get_default_stop_loss() + get_default_take_profit() methods
   - executor.execute_signal() now ALWAYS sets stop loss (even if GA provides None)
   - Previously stops were often None → exits never triggered
   - Tested: get_default_stop_loss($100, 'short') = $101.50 ✓

4. BROKER/STORE SYNC VALIDATION (safety.py + main_auto.py)
   - new: validate_broker_position_count() detects discrepancies
   - new: _trade_symbol() now passes combined_equity to executor
   - new: _trading_cycle() validates broker vs store BEFORE evaluating new trades
   - Logs warning when broker has positions not tracked in store
   - Blocks new trades if broker position count already at hard cap

5. CRISIS MODE: 10+ LOSING POSITIONS (executor.py check_exits)
   - If 8+ of 10+ positions are losing money → force reduce 50% of ALL positions
   - Catches cascading blowups before drawdown thresholds are hit
   - Logs CRITICAL warning when triggered

6. DEFAULT STOP LOSS ENFORCEMENT (executor.py)
   - _enforce_stop_loss_tightness() was overriding None stops to None
   - Now executor ALWAYS applies safety defaults if GA provides no stop
   - Every new position gets a stop loss on entry

Config changes (auto_config.json):
- Added max_short_positions, max_total_positions
- Added stop_loss_default_pct_long/short, take_profit_default_pct
- Added stop_loss_atr_multiplier, stop_loss_max_pct
- Added yesterday_close_drawdown_limit=3%, yesterday_close_drawdown_reduction=50%

HOW THIS WOULD HAVE HELPED THE $194,940 PORTFOLIO:
- At $194,940 from $200K = 2.53% drawdown from initial
- If yesterday closed at $200K: 2.53% < 3% limit → NOT triggered
- But at open today if equity dropped to $194,000 → 3.00% → TRIGGERS IMMEDIATELY
- Hard cap at 4 shorts: after 4 shorts, executor blocks action 5/6
- Stop losses: each of the 4 shorts would have had 1.5% stop → 2 shorts would
  have been stopped out before they lost further, limiting damage
- Crisis mode: if 8 positions were losing, 50% of all positions closed
2026-04-06 03:21:15 -07:00

156 lines
3.4 KiB
JSON

{
"alpaca": {
"api_key": "PKIJPFNMNZ3YKYP765XD6ZPPJY",
"secret_key": "42PuPEYG2nGbeMJiogiFKKLyPtkEHKtwwXJamRKpf4tL",
"base_url": "https://paper-api.alpaca.markets"
},
"oanda": {
"api_token": "860db6509bc2f430b0cbfe197012a628-310ea40d575131302e6a30c958260837",
"account_id": "101-001-38661051-001",
"practice": true
},
"trading": {
"symbols": [
"SPY",
"QQQ",
"IWM",
"DIA",
"AAPL",
"MSFT",
"GOOGL",
"AMZN",
"NVDA",
"TSLA",
"META",
"JPM",
"BAC",
"GS",
"MS",
"JNJ",
"UNH",
"WMT",
"PG",
"XLE",
"CVX",
"XOM",
"LMT",
"RTX",
"NOC",
"GD",
"USO",
"GLD"
],
"forex_symbols": [
"USD_JPY",
"EUR_JPY",
"GBP_JPY",
"CAD_JPY",
"AUD_JPY",
"EUR_USD",
"GBP_USD",
"AUD_USD",
"NZD_USD",
"USD_CAD",
"USD_CHF",
"EUR_GBP",
"EUR_CHF"
],
"cycle_interval_seconds": 60,
"initial_capital": 200000,
"target_capital": 250000,
"commission_rate": 0.0,
"min_trade_value": 50,
"require_approval": false,
"max_position_pct": 8,
"max_concurrent_positions": 8,
"stop_loss_pct": 1.0,
"take_profit_pct": 1.5,
"min_backtest_sharpe": 0.3,
"max_correlated_positions": 3,
"max_same_direction": 4,
"max_daily_trades": 30
},
"safety": {
"max_position_pct": 8,
"max_concurrent_positions": 8,
"max_total_positions": 8,
"max_daily_trades": 30,
"max_daily_loss_pct": 3,
"max_total_loss_pct": 15,
"min_trade_value": 50,
"initial_capital": 200000,
"max_same_direction": 4,
"max_correlated_positions": 3,
"max_short_positions": 4,
"stop_loss_default_pct_long": 1.0,
"stop_loss_default_pct_short": 1.5,
"stop_loss_max_pct": 3.0,
"take_profit_default_pct": 2.0,
"stop_loss_atr_multiplier": 2.0,
"yesterday_close_drawdown_limit": 0.03,
"yesterday_close_drawdown_reduction": 0.50,
"max_drawdown_stop_pct": 0.06,
"max_drawdown_stop_reduction": 0.50,
"volatility_lookback": 20,
"volatility_max_multiplier": 1.5,
"volatility_min_multiplier": 0.5,
"drawdown_position_scale": {
"0.02": 1.0,
"0.05": 0.75,
"0.10": 0.50,
"0.15": 0.25,
"0.20": 0.10
}
},
"rl": {
"gamma": 0.95,
"epsilon_start": 0.8,
"epsilon_min": 0.08,
"epsilon_decay": 0.9995,
"learning_rate": 0.0005,
"batch_size": 128,
"memory_size": 250000,
"target_update_freq": 50,
"hidden_dim": 256,
"live_epsilon": 0.12,
"train_interval_hours": 0.1,
"checkpoint_interval_hours": 1
},
"ga": {
"population_size": 150,
"elite_count": 8,
"mutation_rate": 0.4,
"mutation_strength": 0.3,
"crossover_rate": 0.7,
"tournament_size": 5,
"evolution_interval_hours": 0.5,
"generations_per_cycle": 30
},
"backtest": {
"interval_seconds": 600,
"lookback_days": 14,
"initial_capital": 200000
},
"cache": {
"warmup_lookback_days": 60,
"update_interval_seconds": 60,
"timeframes": [
"5m",
"1h"
]
},
"database": {
"path": "data/biggfish.db"
},
"reporting": {
"dashboard_interval_seconds": 60,
"save_to_file": true
},
"telegram": {
"enabled": true,
"bot_token": "8499352620:AAGVxZ2krfHS219xGRb-1-yGthMs45GjNg4",
"chat_id": "637130179",
"daily_report_hour": 21,
"trade_alerts": true
}
}