# WickBot โ€” Configuration Reference Every setting WickBot reads, grouped by subsystem. This mirrors `config.py` exactly (that file is the source of truth โ€” if this doc and the code ever disagree, trust the code and flag it for a doc fix). All are set via `.env`; every one has a working default, so `.env.example` copied as-is runs, just conservatively. **Two tiers, since the live settings dashboard was added:** - **Static** settings below require an `.env` edit + restart, always. This includes every secret, everything the dashboard itself needs before it can start, and โ€” deliberately โ€” the entire real-trading safety gate. - **Dynamic** settings (marked ๐Ÿ”ง below) can *also* be changed live from the dashboard's Settings card, or via `/api/settings/update`, with no restart โ€” they're read fresh (through a short cache) from `runtime_config.py`'s store on every access. The `.env` value for these is just the factory default they fall back to; changing `.env` for one after it's been overridden from the dashboard won't do anything until you reset it back to default first. **Legend:** ๐Ÿ”ง = dashboard-editable (dynamic). No marker = `.env`-only (static, restart required). --- ## Telegram | Variable | Default | Notes | |---|---|---| | `TELEGRAM_BOT_TOKEN` | *(required)* | From [@BotFather](https://t.me/BotFather) | | `TELEGRAM_OWNER_ID` | *(required)* | Your numeric Telegram user ID from [@userinfobot](https://t.me/userinfobot) โ€” the only ID the bot will respond to | ## MT5 connection | Variable | Default | Notes | |---|---|---| | `MT5_BACKEND` | `auto` | `auto` picks native Windows or `mt5linux`/Wine automatically; force with `native` or `linux` | | `MT5LINUX_HOST` | `localhost` | Only used on the `linux` backend | | `MT5LINUX_PORT` | `18812` | Only used on the `linux` backend | | `MT5_LOGIN` / `MT5_PASSWORD` / `MT5_SERVER` | blank | Leave blank to use whatever's already logged into the terminal (recommended). Only needed if you want WickBot to log in itself | | `MT5_PATH` | blank | Optional explicit path to `terminal64.exe` (native backend only) | ## Symbols & timeframe | Variable | Default | Notes | |---|---|---| | ๐Ÿ”ง `SYMBOLS` | `EURUSD` | Comma-separated, must match Market Watch names exactly | | ๐Ÿ”ง `TIMEFRAME` | `H1` | One of `M1, M5, M15, M30, H1, H4, D1` | ## Risk & signal quality | Variable | Default | Notes | |---|---|---| | ๐Ÿ”ง `RISK_PERCENT_PER_TRADE` | `0.5` | % of account balance risked per trade | | ๐Ÿ”ง `MAX_OPEN_POSITIONS` | `3` | Hard cap on concurrent positions | | ๐Ÿ”ง `MIN_SIGNAL_SCORE` | `65` | Minimum confluence score (0โ€“100, see `rating.py`) before a signal is even considered | ## Real-trading safety gate | Variable | Default | Notes | |---|---|---| | `ALLOW_REAL_TRADING` | `false` | Must be explicitly `true` โ€” one of four independent conditions (see `README.md`) | | `MIN_DEMO_TRADES` | `100` | Closed demo trades required before real trading is even eligible | | `MIN_DEMO_WIN_RATE` | `0.50` | Minimum demo win rate required | | `MIN_DEMO_EXPECTANCY_R` | `0.25` | Minimum demo expectancy (in R) required | None of these bypass the session-only `/arm_real` confirmation โ€” they're a floor, not a substitute. ## Mini App dashboard | Variable | Default | Notes | |---|---|---| | `WEBAPP_ENABLED` | `true` | Turns the whole dashboard subsystem on/off | | `WEBAPP_HOST` | `0.0.0.0` | Bind address for the FastAPI server | | `WEBAPP_PORT` | `8000` (local) / `7860` (Docker, HF convention) | | | `WEBAPP_PUBLIC_URL` | blank | Must be a public HTTPS URL for the Telegram `/dashboard` button to work โ€” see `docs/SETUP.md` ยง4 | | `DASHBOARD_ACCESS_TOKEN` | auto-generated per restart | Pin a value here to keep it stable across restarts instead | ## Live news calendar | Variable | Default | Notes | |---|---|---| | ๐Ÿ”ง `NEWS_CALENDAR_ENABLED` | `true` | Falls back to the static `BLACKOUT_UTC_HOURS` list (in `config.py`, not `.env`) if the live feed is unreachable | | ๐Ÿ”ง `NEWS_BUFFER_MINUTES` | `30` | Blackout window on each side of a qualifying event | | ๐Ÿ”ง `NEWS_MIN_IMPACT` | `High` | `High` or `Medium` | | ๐Ÿ”ง `NEWS_CACHE_SECONDS` | `3600` | How often the calendar feed is re-fetched | ## OpenRouter (goal parsing + advisory commentary) | Variable | Default | Notes | |---|---|---| | ๐Ÿ”ง `OPENROUTER_ENABLED` | `true` | | | `OPENROUTER_API_KEY` | blank | Get one at [openrouter.ai/keys](https://openrouter.ai/keys) โ€” everything degrades gracefully without it | | ๐Ÿ”ง `OPENROUTER_MODEL_CACHE_HOURS` | `6` | How often the model/price catalog refreshes | | ๐Ÿ”ง `OPENROUTER_MAX_OUTPUT_PRICE` | `0.15` | USD per million output tokens โ€” paid fallback ceiling | | ๐Ÿ”ง `OPENROUTER_PRICE_TOLERANCE` | `0.08` | Added to the ceiling above (effective max: $0.23/M by default) | Free models (both prompt and completion priced at $0) are always tried first, in catalog order, before any paid fallback. ## Goal tracker | Variable | Default | Notes | |---|---|---| | ๐Ÿ”ง `GOAL_MAX_DRAWDOWN_PCT` | `0.20` | Hard kill-switch โ€” auto-pauses trading if equity falls this far below the balance at goal-set time | | ๐Ÿ”ง `GOAL_AUTO_PAUSE_ON_HIT` | `false` | If true, auto-pauses trading once the goal's target P&L is reached | **Deliberately absent:** any setting that would lower `MIN_SIGNAL_SCORE` or raise risk automatically based on goal pace. This is a design choice, not an oversight โ€” see `README.md`. ## Position management | Variable | Default | Notes | |---|---|---| | `MAGIC_NUMBER` | `990099` | Tags every WickBot order; position management only ever touches positions carrying this | | ๐Ÿ”ง `POSITION_MANAGEMENT_ENABLED` | `true` | | | ๐Ÿ”ง `POSITION_MANAGE_INTERVAL_SECONDS` | `30` | How often the background check runs (independent of candle-close) | | ๐Ÿ”ง `BREAKEVEN_TRIGGER_R` | `1.0` | Profit multiple of initial risk (R) that triggers the breakeven move | | ๐Ÿ”ง `BREAKEVEN_BUFFER_R` | `0.1` | Flat-fraction component of the breakeven buffer (one of three โ€” see below) | | ๐Ÿ”ง `TRAILING_ACTIVATION_R` | `1.5` | Profit (R) at which trailing starts | | ๐Ÿ”ง `TRAILING_DISTANCE_R` | `1.0` | How much open profit (R) trailing always keeps locked in | | ๐Ÿ”ง `ATR_BUFFER_MULTIPLIER` | `0.10` | ATR-scaled component of the breakeven buffer | | ๐Ÿ”ง `COMMISSION_PER_LOT_ROUNDTRIP` | `0.0` | Your broker's round-trip commission per lot, in account currency โ€” set this if your broker charges commission separately from spread | | ๐Ÿ”ง `INCLUDE_SPREAD_IN_BREAKEVEN` | `true` | Whether current spread counts toward the cost-based buffer component | | ๐Ÿ”ง `VOLATILITY_CACHE_SECONDS` | `300` | How long ATR/bias lookups are cached per symbol | | ๐Ÿ”ง `HIGHER_TF_BIAS_ENABLED` | `true` | Whether trailing distance tightens when the next timeframe up has flipped against the trade | | ๐Ÿ”ง `TRAILING_TIGHTEN_FACTOR` | `0.5` | Multiplier applied to `TRAILING_DISTANCE_R` when the higher-TF bias opposes the trade | | ๐Ÿ”ง `TIME_DECAY_HOURS` | `12.0` | Hours open without reaching breakeven before the stop starts tightening | | ๐Ÿ”ง `TIME_DECAY_MAX_TIGHTEN_PCT` | `0.5` | Cap on how much of the current SL-to-entry gap time decay can close | The actual breakeven buffer used is `max(R-based, ATR-based, cost-based)` โ€” see `position_manager._dynamic_buffer_price()`. ## Strategy control | Variable | Default | Notes | |---|---|---| | ๐Ÿ”ง `DISABLED_STRATEGY_SYMBOL_PAIRS` | blank | Comma-separated `strategy_name:SYMBOL` pairs to skip entirely, e.g. `liquidity_sweep_reversal:XAUUSD`. Usually populated by applying an auto-tuner suggestion, not hand-edited | ## Scalp strategy (`scalp_strategy.py`) | Variable | Default | Notes | |---|---|---| | ๐Ÿ”ง `SCALP_LOOKBACK` | `30` | Bars searched for the impulse move's swing high/low | | ๐Ÿ”ง `SCALP_STOCH_OVERBOUGHT` | `80` | Stochastic level a cross-down must originate from or near | | ๐Ÿ”ง `SCALP_STOCH_OVERSOLD` | `20` | Stochastic level a cross-up must originate from or near | | ๐Ÿ”ง `SCALP_FIB_TP_PCT` | `0.25` | TP distance from entry, as a fraction of the impulse range | See `scalp_strategy.py`'s module docstring for the design decisions made translating a video's text description into concrete logic โ€” several specifics (the trend-filter proxy, the exact TP interpretation) weren't literally specified and required an explicit, documented choice. ## Multi-account (`account_manager.py`) | Variable | Default | Notes | |---|---|---| | `ACCOUNT_ENCRYPTION_KEY` | auto-generated once, saved to `.account_key` | **Must persist across restarts** โ€” pin this explicitly or back up `.account_key`. Losing it makes every stored account password permanently unrecoverable | See `docs/MULTI_ACCOUNT.md` for the real constraint on cross-broker account switching. ## AI tuning advisor (`auto_tuner.py`) | Variable | Default | Notes | |---|---|---| | `AUTO_TUNER_MIN_SAMPLE_SIZE` | `30` | Minimum closed trades in a bucket before a suggestion is even generated | | `AUTO_TUNER_NEGATIVE_EXPECTANCY_THRESHOLD` | `0.0` | Expectancy (R) below which a bucket is considered "net negative" | | `AUTO_TUNER_CHECK_INTERVAL_HOURS` | `6` | How often the background loop checks for new suggestions | These three are deliberately **static/.env-only** โ€” same reasoning as the real-trading gate: they define how easily the tuner itself proposes changes, so they shouldn't be editable through the same dashboard the tuner's suggestions get applied from. Suggestions themselves always require explicit approval regardless โ€” see the README's "AI tuning advisor" section. The tuner also calibrates strategy-specific TP fractions (currently just `SCALP_FIB_TP_PCT`) against real exit data โ€” see `TP_CALIBRATION_TARGETS`, `TP_HIT_RATE_HIGH_THRESHOLD`, `SL_HIT_RATE_HIGH_THRESHOLD`, `TP_PCT_STEP`/`MIN`/`MAX` near the top of `auto_tuner.py`. These aren't in `.env` at all (module-level constants) โ€” same "don't let the tuner's own sensitivity be dashboard-editable" reasoning. --- ## Not in `.env` (edit `config.py` directly) - `BLACKOUT_UTC_HOURS` โ€” static fallback blackout hours, a Python `set`, not a simple string โ€” edit in `config.py` if the live news calendar is unreachable in your deployment and you want a different fallback window than the default `{12, 13, 18}` UTC.