from __future__ import annotations from pathlib import Path import pytest from crypto_spot_bot.config import Settings @pytest.fixture def make_settings(): def factory(tmp_path: Path, **overrides) -> Settings: values = dict( trading_mode="paper", host="127.0.0.1", port=8787, bybit_testnet=False, bybit_api_key="", bybit_api_secret="", starting_balance_usdt=100.0, auto_select_symbols=True, top_symbols_count=6, symbols=(), strategy_mode="legacy", base_interval="60", kline_limit=240, trend_interval="D", trend_kline_limit=260, loop_interval_seconds=5, fast_trading_enabled=False, fast_loop_interval_seconds=1.0, fast_entry_cooldown_seconds=20, max_entries_per_minute=12, websocket_enabled=False, min_signal_confidence=0.64, max_spread_percent=0.18, min_24h_turnover_usdt=1_000_000.0, pattern_analysis_enabled=True, pattern_score_weight=0.18, learning_enabled=True, learning_lookback_trades=120, learning_min_samples=3, learning_max_adjustment=0.12, learning_max_position_multiplier=1.6, llm_advisor_enabled=False, ollama_base_url="http://192.168.0.210:11434", ollama_model="gemma4:e4b", llm_advisor_min_interval_seconds=180, llm_advisor_timeout_seconds=45, llm_advisor_max_adjustment=0.06, min_position_usdt=1.0, max_position_usdt=20.0, max_symbol_exposure_usdt=20.0, max_total_exposure_usdt=80.0, max_open_positions=6, max_positions_per_symbol=1, grid_trading_enabled=True, grid_entry_confidence=0.58, grid_buy_zone=0.45, grid_max_position_usdt=8.0, rebound_trading_enabled=True, rebound_entry_confidence=0.58, rebound_min_probability=0.58, rebound_max_position_usdt=6.0, kelly_sizing_enabled=True, kelly_fraction=0.25, kelly_max_fraction=0.20, risk_per_trade_percent=0.01, risk_guard_enabled=True, risk_symbol_guard_enabled=True, risk_recent_trade_window=20, risk_max_consecutive_losses=4, risk_min_recent_profit_factor=0.85, risk_reduce_multiplier=0.50, atr_trailing_multiplier=2.2, trend_rsi_min=45.0, trend_rsi_max=65.0, time_series_forecast_enabled=True, time_series_min_candles=120, time_series_forecast_horizon=3, time_series_min_edge_percent=0.08, time_series_min_probability_up=0.58, time_series_min_confidence=0.4, time_series_max_adjustment=0.08, time_series_lstm_enabled=True, time_series_lstm_model_path=tmp_path / "lstm_forecaster.json", time_series_probe_enabled=True, time_series_probe_min_edge_percent=0.02, time_series_probe_min_probability_up=0.55, time_series_probe_size_multiplier=0.40, time_series_rebound_fallback_enabled=True, stop_loss_percent=0.02, take_profit_percent=0.035, trailing_stop_percent=0.015, min_hold_seconds=180, entry_cooldown_seconds=180, max_daily_drawdown_usdt=6.0, min_cash_reserve_usdt=5.0, taker_fee_rate=0.001, slippage_rate=0.0003, enable_live_trading=False, live_trading_confirm="", live_order_max_usdt=10.0, database_path=tmp_path / "tradebot.sqlite3", log_path=tmp_path / "tradebot.log", env_file_path=tmp_path / ".env", ) values.update(overrides) return Settings(**values) return factory