Configuration Guide
Complete reference for configuration settings
Overview
The bot uses a unified configuration system with support for TOML configuration files and environment variables. All variables have sensible defaults and are validated on startup.
Configuration Loading Flow
flowchart TD
subgraph Priority["Configuration Loading Priority"]
direction TB
ENV["π΄ Environment Variables<br/>WEALTH__SECTION__FIELD<br/>(Highest Priority)"]
TOML["π‘ TOML/JSON Config File<br/>config.toml or config.json"]
DEF["π’ Default Values<br/>(Fallback)"]
end
ENV --> TOML --> DEF
style ENV fill:#ffcdd2
style TOML fill:#fff9c4
style DEF fill:#c8e6c9
Configuration Structure
flowchart LR
subgraph Config["AppConfig Structure"]
direction TB
APP[AppConfig]
APP --> INST[instruments]
APP --> DISC[instrument_discovery]
APP --> LEV[leverage]
APP --> TRADE[trading]
APP --> RISK[risk]
APP --> EXEC[execution]
APP --> OBS[observability]
APP --> LIC[licensing]
end
style APP fill:#e3f2fd
style TRADE fill:#fff3e0
style RISK fill:#ffcdd2
Current Version: The bot uses a simplified configuration structure with direct field access.
Configuration Files:
config.toml- Main configuration file (instruments, leverage, trading params) - Preferredconfig.json- Legacy JSON format (still supported for backward compatibility).env- Local environment configuration for sensitive values
Hot-Reload Support: The bot supports runtime configuration updates for safe parameters without requiring a restart. See Configuration Hot-Reload for details on which parameters can be hot-reloaded.
Configuration Architecture:
AppConfig- Single unified configuration structure- Direct field access:
config.trading.*,config.risk.*,config.leverage.* - Environment variables with
WEALTH__prefix override TOML/JSON settings
Loading Priority:
- Environment variables with
WEALTH__prefix (highest priority) - TOML/JSON configuration file (
config.tomlorconfig.json) - Default values (fallback)
Configuration Sections
The configuration is organized into clear sections:
| Section | Description |
|---|---|
instruments | Trading pairs to monitor |
instrument_discovery | Dynamic pair discovery settings |
leverage | Per-symbol leverage settings |
trading | Strategy parameters (spread thresholds, position sizing) |
risk | Risk management (slippage, trailing stops, fees) |
pair_health | Pair health monitoring and auto-disable thresholds |
execution | Execution mode (paper/live), resilience, and reconciliation |
observability | Metrics, logging, telemetry |
licensing | License configuration |
Environment Variable Overrides:
- All configuration can be overridden via environment variables
- Prefix pattern:
WEALTH__SECTION__FIELD(e.g.,WEALTH__TRADING__MIN_FUNDING_SPREAD)
Trading Configuration
WEALTH__TRADING__MIN_FUNDING_SPREAD
Minimum funding rate spread required to open a position.
- Type: Decimal (0.0-1.0)
- Default:
0.04(0.04% = 4 bps) - TOML Path:
trading.min_funding_spread - Example:
WEALTH__TRADING__MIN_FUNDING_SPREAD=0.05
WEALTH__TRADING__MAX_POSITION_USD
Maximum position size cap in USD (safety limit).
- Type: Decimal
- Default:
10000($10,000) - TOML Path:
trading.max_position_usd - Example:
WEALTH__TRADING__MAX_POSITION_USD=20000
WEALTH__TRADING__POSITION_SIZE_PERCENT
Percentage of available balance to use per position.
- Type: Decimal (0.0 - 1.0)
- Default:
0.3(30%) - TOML Path:
trading.position_size_percent - Example:
WEALTH__TRADING__POSITION_SIZE_PERCENT=0.25
WEALTH__TRADING__TARGET_PROFIT_PERCENT
Target profit percentage per position.
- Type: Decimal (0.0 - 1.0)
- Default:
0.05(5%) - TOML Path:
trading.target_profit_percent - Example:
WEALTH__TRADING__TARGET_PROFIT_PERCENT=0.08
WEALTH__TRADING__MAX_POSITION_DURATION_HOURS
Maximum position duration in hours before forced exit. Prevents capital from being tied up indefinitely.
- Type: Integer
- Default:
168(7 days) - TOML Path:
trading.max_position_duration_hours - Example:
WEALTH__TRADING__MAX_POSITION_DURATION_HOURS=336 - Note: Set to
0to disable duration-based exits
WEALTH__TRADING__NARROW_SPREAD_EXIT_PERIODS
Number of consecutive narrow spread periods (8-hour intervals) before closing position.
- Type: Integer
- Default:
3(24 hours of narrow spread) - TOML Path:
trading.narrow_spread_exit_periods - Example:
WEALTH__TRADING__NARROW_SPREAD_EXIT_PERIODS=2 - Note: Set to
0for immediate spread narrowing exit
WEALTH__TRADING__MAX_CONCURRENT_POSITIONS
Maximum number of concurrent arbitrage pairs.
- Type: Integer
- Default:
5 - TOML Path:
trading.max_concurrent_positions - Example:
WEALTH__TRADING__MAX_CONCURRENT_POSITIONS=3
WEALTH__TRADING__UPDATE_INTERVAL_SECS
Funding rate update interval in seconds.
- Type: Integer
- Default:
60 - TOML Path:
trading.update_interval_secs - Example:
WEALTH__TRADING__UPDATE_INTERVAL_SECS=30
WEALTH__TRADING__MAX_HEDGE_ATTEMPTS
Maximum number of hedging attempts for partial fills.
- Type: Integer
- Default:
5 - TOML Path:
trading.max_hedge_attempts - Example:
WEALTH__TRADING__MAX_HEDGE_ATTEMPTS=3 - Purpose: Prevents infinite hedging loops when orders partially fill
WEALTH__TRADING__HEDGE_TOLERANCE_PERCENT
Hedging tolerance as percentage (when to stop hedging).
- Type: Decimal (0.0-1.0)
- Default:
0.001(0.1%) - TOML Path:
trading.hedge_tolerance_percent - Example:
WEALTH__TRADING__HEDGE_TOLERANCE_PERCENT=0.0005 - Purpose: Allows small quantity mismatches without additional hedging orders
WEALTH__TRADING__FALLBACK_PRICE_USD
Fallback price in USD used when real-time price data is unavailable.
- Type: Decimal
- Default:
100000($100,000) - TOML Path:
trading.fallback_price_usd - Example:
WEALTH__TRADING__FALLBACK_PRICE_USD=95000 - Purpose: Last-resort value for position sizing calculations when WebSocket price feeds fail
- Note: Set to approximately current BTC price for reasonable position sizing. An error is logged when fallback is used.
WEALTH__TRADING__SYMBOL_FALLBACK_PRICES
Per-symbol fallback prices when real-time data is unavailable.
- Type: Map<String, Decimal>
- Default: Empty (uses global
fallback_price_usd) - TOML Path:
trading.symbol_fallback_prices - Purpose: Provides accurate fallback prices for non-BTC symbols, improving position sizing accuracy
Example TOML Configuration:
[trading.symbol_fallback_prices]
BTCUSDT = 100000
ETHUSDT = 3500
SOLUSDT = 200
XRPUSDT = 2.5
Note: Symbol-specific fallback prices take precedence over the global fallback_price_usd. Only configure symbols you actively trade.
Note: Leverage is configured per-symbol in the [leverage] section, not as a global trading parameter.
Expected Value (EV) Gating
The bot uses expected value analysis to filter opportunities before execution. Only opportunities with positive risk-adjusted EV after costs are considered.
WEALTH__TRADING__MIN_EXPECTED_VALUE
Minimum expected value threshold (net profit after costs).
- Type: Decimal (0.0-1.0)
- Default:
0.05(0.05% = 5 bps) - TOML Path:
trading.min_expected_value - Example:
WEALTH__TRADING__MIN_EXPECTED_VALUE=0.08 - Purpose: Filters out low-quality opportunities with insufficient edge
- Formula:
EV = (time_weighted_spread Γ 3 funding payments) - (entry_fees + exit_fees + slippage) - Note: Time weighting applies linear decay based on minutes until next funding payment
WEALTH__TRADING__STALENESS_PENALTY
Discount applied to EV calculation when data age exceeds staleness haircut threshold.
- Type: Decimal (0.0-1.0)
- Default:
0.03(0.03% = 3 bps) - TOML Path:
trading.staleness_penalty - Example:
WEALTH__TRADING__STALENESS_PENALTY=0.05 - Purpose: Conservative adjustment for potential data lag
- When Applied: Reduces gross EV when funding rate data age exceeds
staleness_haircut_threshold_secs(default: 120s)
WEALTH__TRADING__STALENESS_HAIRCUT_THRESHOLD_SECS
Data age threshold (in seconds) for applying staleness penalty.
- Type: Integer (seconds)
- Default:
120(2 minutes) - TOML Path:
trading.staleness_haircut_threshold_secs - Example:
WEALTH__TRADING__STALENESS_HAIRCUT_THRESHOLD_SECS=180 - Purpose: Defines when funding rate data is considered "semi-stale" and warrants a penalty
- Note: Distinct from data rejection threshold - data older than 5 minutes is rejected entirely
Example EV Calculation:
Funding spread: 90 bps (0.0090)
Time to funding: 240 minutes (50% of 8h period)
Time weight: 0.5
Gross EV: 90 bps Γ 0.5 = 45 bps
Entry fees (both sides): 4 bps
Exit fees (both sides): 4 bps
Estimated slippage: 10 bps
Total costs: 18 bps
Adjusted EV: 45 - 18 = 27 bps
Passes threshold: 27 bps > 5 bps β
Kelly Position Sizing
The bot supports two position sizing modes: Kelly Criterion (dynamic, risk-adjusted) or Fixed Percentage (simple, predictable).
WEALTH__TRADING__USE_KELLY_CRITERION
Enable or disable Kelly Criterion for position sizing.
- Type: Boolean
- Default:
true - TOML Path:
trading.use_kelly_criterion - Example:
WEALTH__TRADING__USE_KELLY_CRITERION=false - When
true: Uses Kelly Criterion formula for dynamic sizing based on EV and variance - When
false: Uses fixed percentage sizing:size = min(balance) Γ max_exchange_utilization Γ leverage - Recommendation:
truefor optimal capital allocation,falsefor simpler, predictable sizing
WEALTH__TRADING__KELLY_FRACTION
Fraction of full Kelly size to use (0.0 - 1.0).
- Type: Decimal
- Default:
0.25(quarter-Kelly for conservative sizing) - TOML Path:
trading.kelly_fraction - Example:
WEALTH__TRADING__KELLY_FRACTION=0.5 - Purpose: Reduces risk by using only a fraction of the mathematically optimal Kelly size
- Recommendation: Keep at 0.25 or lower for funding rate arbitrage
WEALTH__TRADING__MAX_NOTIONAL_PER_SYMBOL
Maximum notional value per symbol across all exchanges in USD.
- Type: Decimal
- Default:
10000($10,000) - TOML Path:
trading.max_notional_per_symbol - Example:
WEALTH__TRADING__MAX_NOTIONAL_PER_SYMBOL=20000 - Purpose: Hard cap on position size regardless of Kelly calculation
- Applied: Per symbol across all exchanges (e.g., total BTC exposure)
WEALTH__TRADING__MAX_EXCHANGE_UTILIZATION
Maximum percentage of free balance to use for a single position (0.0 - 1.0).
- Type: Decimal
- Default:
0.5(50%) - TOML Path:
trading.max_exchange_utilization - Example:
WEALTH__TRADING__MAX_EXCHANGE_UTILIZATION=0.3 - Purpose: Prevents over-concentration on one exchange
- Reference Capital: Uses
min(long_exchange_balance, short_exchange_balance)for sizing
Example Kelly Sizing:
EV: 30 bps per 8h (0.003)
Variance: 0.0001 (estimated spread volatility)
Kelly fraction: EV / variance = 0.003 / 0.0001 = 30
Reference capital: min($50,000, $80,000) = $50,000
Leverage: 10x
Full Kelly size: $50,000 Γ 30 Γ 10 = $15,000,000 (unrealistic)
Apply kelly_cap (0.25): $15,000,000 Γ 0.25 = $3,750,000
Apply max_notional cap: min($3,750,000, $10,000) = $10,000
Apply utilization cap: min($10,000, $50,000 Γ 0.5) = $10,000
Final position size: $10,000 (binding constraint: notional cap)
Leverage Configuration
Leverage multiplies your position size relative to margin. Higher leverage means higher potential returns AND higher risk of liquidation.
WEALTH__LEVERAGE__DEFAULT
Default leverage for all symbols.
- Type: Integer OR
"max" - Default:
3 - TOML Path:
leverage.default - Example:
WEALTH__LEVERAGE__DEFAULT=10orWEALTH__LEVERAGE__DEFAULT=max
Supported Values:
- Numbers: Fixed leverage (e.g.,
3,5,10,20) "max": Automatically use the maximum leverage allowed by each exchange
Per-Symbol Overrides
You can configure different leverage for specific symbols using the [leverage.overrides] section:
[leverage]
default = 10 # Default 10x for most symbols
[leverage.overrides]
BTCUSDT = 5 # Lower leverage for BTC (less volatile)
ETHUSDT = 8 # Medium leverage for ETH
SOLUSDT = "max" # Use max allowed for SOL
Symmetric Leverage for Hedged Positions
When trading hedged positions across exchanges, the bot automatically ensures consistent leverage:
- If config is a fixed number: Uses that value (clamped to exchange max if needed)
- If config is
"max": Usesmin(max_exchange_A, max_exchange_B)
Example:
- Config:
SOLUSDT = "max" - Binance max for SOL: 75x
- HyperLiquid max for SOL: 50x
- Result: Bot uses 50x on both exchanges
This ensures the hedge ratio remains balanced regardless of differing exchange limits.
Max Leverage Caching
When using "max" leverage:
- Max leverage is fetched from exchange APIs on startup
- Results are cached to avoid API rate limits
- Cache is refreshed when bot restarts
Exchange API Sources:
- Binance:
/fapi/v1/leverageBracket(uses first tier max) - Bybit:
/v5/market/instruments-info(leverageFilter.maxLeverage) - HyperLiquid:
/infometa endpoint (universe[].maxLeverage) - Aster: Binance-compatible API
Recommended Settings
| Risk Profile | Default | High-Volume (BTC/ETH) | Mid-Cap (SOL/XRP) |
|---|---|---|---|
| Conservative | 3 | 3 | 2 |
| Moderate | 10 | 5-8 | 10 |
| Aggressive | "max" | 20 | "max" |
Note: Higher leverage increases both potential gains and liquidation risk. The bot does NOT automatically manage position size based on leverageβthat's controlled by position_size_percent and max_position_usd.
Slippage Protection Configuration
WEALTH__RISK__MAX_SLIPPAGE_BPS
Maximum allowed slippage in basis points.
- Type: Integer
- Default:
50(0.5%) - TOML Path:
risk.max_slippage_bps - Example:
WEALTH__RISK__MAX_SLIPPAGE_BPS=30
WEALTH__RISK__MIN_SLIPPAGE_BPS
Minimum slippage buffer in basis points (always applied).
- Type: Integer
- Default:
10(0.1%) - TOML Path:
risk.min_slippage_bps - Example:
WEALTH__RISK__MIN_SLIPPAGE_BPS=5
WEALTH__RISK__MARKET_ORDER_FALLBACK_ENABLED
Whether to fall back to MARKET orders if LIMIT order doesn't fill.
- Type: Boolean
- Default:
true - TOML Path:
risk.market_order_fallback_enabled - Values:
true|false - Example:
WEALTH__RISK__MARKET_ORDER_FALLBACK_ENABLED=false
WEALTH__RISK__LIMIT_ORDER_TIMEOUT_SECS
Timeout before falling back to MARKET order (seconds).
- Type: Integer
- Default:
5 - TOML Path:
risk.limit_order_timeout_secs - Example:
WEALTH__RISK__LIMIT_ORDER_TIMEOUT_SECS=10
WEALTH__RISK__SLIPPAGE_VOLATILITY_MULTIPLIER
Multiplier to increase slippage tolerance in volatile markets.
- Type: Float
- Default:
1.5(50% wider) - TOML Path:
risk.slippage_volatility_multiplier - Example:
WEALTH__RISK__SLIPPAGE_VOLATILITY_MULTIPLIER=2.0
Post-Only (Maker) Order Configuration
Post-only orders ensure you always pay maker fees instead of taker fees, significantly reducing execution costs.
WEALTH__RISK__USE_POST_ONLY
Enable post-only (maker) order execution.
- Type: Boolean
- Default:
false - TOML Path:
risk.use_post_only - Values:
true|false - Example:
WEALTH__RISK__USE_POST_ONLY=true
Exchange-Specific Order Types:
| Exchange | Post-Only Type | API Parameter |
|---|---|---|
| Binance Futures | GTX (Good-Til-Crossing) | timeInForce=GTX |
| Bybit Perpetuals | PostOnly | timeInForce=PostOnly |
| HyperLiquid | Alo (Add Liquidity Only) | tif=Alo |
| Aster Futures | GTX | timeInForce=GTX |
WEALTH__RISK__LIMIT_PRICE_OFFSET_BPS
Price offset from market for post-only orders (basis points).
- Type: Integer
- Default:
10(0.10%) - TOML Path:
risk.limit_price_offset_bps - Example:
WEALTH__RISK__LIMIT_PRICE_OFFSET_BPS=15
How it works:
- Buy orders: Place at
market_price Γ (1 - offset_bps/10000) - Sell orders: Place at
market_price Γ (1 + offset_bps/10000)
WEALTH__RISK__POST_ONLY_RETRY_COUNT
Number of retry attempts when post-only order is rejected.
- Type: Integer
- Default:
3 - TOML Path:
risk.post_only_retry_count - Example:
WEALTH__RISK__POST_ONLY_RETRY_COUNT=5
Retry Logic:
- Post-only order placed at calculated price
- If rejected (would cross spread), price adjusted deeper into book
- Repeat up to
post_only_retry_counttimes - If all retries fail and
market_order_fallback_enabled=true, fall back to market order
Fee Savings Example:
| Exchange | Maker Fee | Taker Fee | Savings per $10k Trade |
|---|---|---|---|
| Binance VIP 0 | 0.02% | 0.05% | $3.00 |
| Bybit Regular | 0.02% | 0.055% | $3.50 |
| HyperLiquid Tier 0 | 0.015% | 0.045% | $3.00 |
Trailing Stop Configuration
Note: Trailing stop configuration is defined in config.toml or via environment variables below.
WEALTH__RISK__TRAILING_STOPS_ENABLED
Enable trailing stop loss functionality.
- Type: Boolean
- Default:
true - TOML Path:
risk.trailing_stops_enabled - Values:
true|false - Example:
WEALTH__RISK__TRAILING_STOPS_ENABLED=true
WEALTH__RISK__TRAILING_STOP_ACTIVATION
Profit threshold to activate trailing stop (as decimal percentage).
- Type: Decimal (0.0-1.0)
- Default:
0.03(3%) - TOML Path:
risk.trailing_stop_activation - Example:
WEALTH__RISK__TRAILING_STOP_ACTIVATION=0.05
WEALTH__RISK__TRAILING_STOP_DISTANCE
Maximum allowed profit retracement before exit (as decimal percentage).
- Type: Decimal (0.0-1.0)
- Default:
0.40(40% from peak) - TOML Path:
risk.trailing_stop_distance - Example:
WEALTH__RISK__TRAILING_STOP_DISTANCE=0.3
WEALTH__RISK__TRAILING_STOP_MIN_LOCK
Minimum profit to lock in (prevents exit below this level).
- Type: Decimal (0.0-1.0)
- Default:
0.02(2%) - TOML Path:
risk.trailing_stop_min_lock - Example:
WEALTH__RISK__TRAILING_STOP_MIN_LOCK=0.015
WEALTH__RISK__SLIPPAGE_AWARE_EXITS
Consider estimated slippage cost in exit decisions. When enabled, positions with remaining potential profit less than expected closing costs may be held for one more funding period.
- Type: Boolean
- Default:
true - TOML Path:
risk.slippage_aware_exits - Example:
WEALTH__RISK__SLIPPAGE_AWARE_EXITS=false
Fee Configuration
WEALTH__RISK__FEES__ESTIMATED_SLIPPAGE
Estimated slippage for market orders (as decimal).
- Type: Decimal (0.0-1.0)
- Default:
0.001(0.1%) - TOML Path:
risk.fees.estimated_slippage - Example:
WEALTH__RISK__FEES__ESTIMATED_SLIPPAGE=0.002
Exchange Fee Overrides
Override default exchange fee rates in config.toml under [risk.fees.<exchange>]:
Binance
[risk.fees.binance]
maker = 0.0002 # 0.02% - Maker fee
taker = 0.0004 # 0.04% - Taker fee
funding_interval_hours = 8
Bybit
[risk.fees.bybit]
maker = 0.0001 # 0.01% - Maker fee
taker = 0.0006 # 0.06% - Taker fee
funding_interval_hours = 8
HyperLiquid
[risk.fees.hyperliquid]
maker = 0.0000 # 0.00% - Maker rebate
taker = 0.00035 # 0.035% - Taker fee
funding_interval_hours = 1 # HyperLiquid uses hourly funding (24x daily)
Note: HyperLiquid processes funding every hour, unlike most CEXes which use 8-hour intervals. This affects EV calculations and provides more frequent profit collection opportunities.
Aster
[risk.fees.aster]
maker = 0.0002 # 0.02% - Maker fee
taker = 0.0005 # 0.05% - Taker fee
funding_interval_hours = 4 # Aster uses 4h or 8h per-symbol (fetched dynamically)
Note: Aster funding intervals vary by symbol (4h or 8h). The bot automatically fetches per-symbol intervals via the API and caches them. The config value is a fallback only.
Instrument Discovery Configuration
Dynamic pair discovery settings for automatic symbol detection (v0.30+). These settings control how the bot discovers and manages trading pairs from external sources like Loris.tools.
WEALTH__INSTRUMENT_DISCOVERY__USE_LORIS_RANKINGS
Enable Loris.tools-based pair discovery for top funding rate opportunities.
- Type: Boolean
- Default:
false - TOML Path:
instrument_discovery.use_loris_rankings - Example:
WEALTH__INSTRUMENT_DISCOVERY__USE_LORIS_RANKINGS=true - Prerequisite: Requires
enabled = trueor--discoverCLI flag
WEALTH__INSTRUMENT_DISCOVERY__REFRESH_INTERVAL_HOURS
Periodic refresh interval for Loris.tools pair discovery (hours, 0 = disabled).
- Type: Integer (hours)
- Default:
0(disabled - discovery runs only at startup) - TOML Path:
instrument_discovery.refresh_interval_hours - Example:
WEALTH__INSTRUMENT_DISCOVERY__REFRESH_INTERVAL_HOURS=6 - Prerequisite: Requires
use_loris_rankings = trueand discovery enabled
Behavior:
- When
> 0: Periodically queries Loris.tools API to discover new high-opportunity pairs - Add-only strategy: New pairs are added automatically; pairs with active positions are never removed
- Jitter protection: Random 0-30 minute delay added to prevent synchronized API requests across multiple bot instances
- WebSocket integration: Automatically registers new pairs with price and funding rate streams
When to Enable:
| Scenario | Recommended Value |
|---|---|
| Long-running production bot that should adapt to market changes | 6 (6 hours) |
| Short-term trading sessions or manual pair management | 0 (disabled) |
| Stable, predictable instrument sets preferred | 0 (disabled) |
Note: The instrument list may grow over time with add-only logic. Use hot-reload config changes to manually prune symbols if needed.
WEALTH__INSTRUMENT_DISCOVERY__MAX_SYMBOLS
Maximum number of symbols to discover from Loris.tools rankings.
- Type: Integer
- Default:
20 - TOML Path:
instrument_discovery.max_symbols - Example:
WEALTH__INSTRUMENT_DISCOVERY__MAX_SYMBOLS=30
WEALTH__INSTRUMENT_DISCOVERY__ENABLED
Enable dynamic pair discovery (requires both config and CLI flag for safety).
- Type: Boolean
- Default:
false - TOML Path:
instrument_discovery.enabled - Example:
WEALTH__INSTRUMENT_DISCOVERY__ENABLED=true
When enabled, the bot discovers trading pairs automatically instead of using static [[instruments]] configuration. Requires double opt-in: set enabled = true in config AND use --enable-discovery CLI flag.
WEALTH__INSTRUMENT_DISCOVERY__EXCHANGES
Exchanges to use for pair discovery. If empty, all exchanges with credentials are used.
- Type: Array of strings
- Default:
[](all available exchanges) - TOML Path:
instrument_discovery.exchanges - Example:
WEALTH__INSTRUMENT_DISCOVERY__EXCHANGES=binance_futures,hyper_liquid
Options: binance_futures, bybit_perpetuals_usd, hyper_liquid
WEALTH__INSTRUMENT_DISCOVERY__MIN_24H_VOLUME_USD
Minimum 24-hour trading volume in USD for discovered pairs.
- Type: Integer (USD)
- Default:
1000000($1M) - TOML Path:
instrument_discovery.min_24h_volume_usd - Example:
WEALTH__INSTRUMENT_DISCOVERY__MIN_24H_VOLUME_USD=5000000
Higher values select more liquid pairs with lower slippage. Recommended range: $1M-$10M depending on position sizes.
WEALTH__INSTRUMENT_DISCOVERY__QUOTE_ASSET
Quote asset filter for discovered pairs.
- Type: String
- Default:
USDT - TOML Path:
instrument_discovery.quote_asset - Example:
WEALTH__INSTRUMENT_DISCOVERY__QUOTE_ASSET=USDC
Options: USDT, USDC, BUSD
WEALTH__INSTRUMENT_DISCOVERY__EXCLUDE
Symbols to exclude from discovery (substring matching, case-sensitive).
- Type: Array of strings
- Default:
["BULL", "BEAR", "UP", "DOWN", "HEDGE", "DEFI"] - TOML Path:
instrument_discovery.exclude - Example:
WEALTH__INSTRUMENT_DISCOVERY__EXCLUDE=BULL,BEAR,SHIB
Use to manually block leveraged tokens, sector baskets, or specific pairs. Example: "BULL" matches "BULLISH", "BULLUSDT", "ETHBULL".
WEALTH__INSTRUMENT_DISCOVERY__MIN_EXCHANGES
Minimum number of exchanges that must support a symbol for it to be discovered.
- Type: Integer
- Default:
2 - TOML Path:
instrument_discovery.min_exchanges - Example:
WEALTH__INSTRUMENT_DISCOVERY__MIN_EXCHANGES=3
Ensures arbitrage is possible (need at least 2 exchanges). Set higher to only trade pairs available on 3+ exchanges.
WEALTH__INSTRUMENT_DISCOVERY__LORIS_SORT_BY
Sorting strategy when using Loris.tools API for discovery.
- Type: String
- Default:
arbitrage - TOML Path:
instrument_discovery.loris_sort_by - Example:
WEALTH__INSTRUMENT_DISCOVERY__LORIS_SORT_BY=oi_rank
Options:
arbitrage- Sort by funding rate spread (highest arbitrage opportunity first)oi_rank- Sort by Binance open interest ranking (most liquid first)
Only applies when use_loris_rankings = true.
WEALTH__INSTRUMENT_DISCOVERY__FORCE_REMOVE_PAIRS
Force removal of pairs during hot-reload even if they have pending orders.
- Type: Boolean
- Default:
false - TOML Path:
instrument_discovery.force_remove_pairs - Example:
WEALTH__INSTRUMENT_DISCOVERY__FORCE_REMOVE_PAIRS=true
Behavior:
- When
true: Auto-cancels all pending orders for removed symbols - When
false: Blocks removal if symbol has pending orders or active positions
β οΈ Use with caution - may result in unhedged positions if orders are cancelled mid-execution.
Example Configuration
[instrument_discovery]
enabled = true
use_loris_rankings = true
loris_sort_by = "arbitrage"
refresh_interval_hours = 6
max_symbols = 20
min_24h_volume_usd = 1000000
quote_asset = "USDT"
min_exchanges = 2
exclude = ["BULL", "BEAR", "UP", "DOWN", "HEDGE", "DEFI"]
force_remove_pairs = false
# exchanges = ["binance_futures", "hyper_liquid"] # Optional: limit to specific exchanges
Metrics Server Configuration
WEALTH__OBSERVABILITY__METRICS_PORT
Port for metrics and health check server.
- Type: Integer
- Default:
9090 - TOML Path:
observability.metrics_port - Example:
WEALTH__OBSERVABILITY__METRICS_PORT=8080
WEALTH__OBSERVABILITY__METRICS_BIND_ADDRESS
Bind address for metrics server.
- Type: String (IP address)
- Default:
0.0.0.0(all interfaces) - TOML Path:
observability.metrics_bind_address - Example:
WEALTH__OBSERVABILITY__METRICS_BIND_ADDRESS=127.0.0.1
Execution Mode
WEALTH__EXECUTION__MODE
Execution mode for order placement.
- Type: String ("paper" | "live" | "dryrun")
- Default:
paper - TOML Path:
execution.mode - Example:
WEALTH__EXECUTION__MODE=live
Modes:
paper- Simulated trading with mock order fillslive- Real trading with actual exchange ordersdryrun- Logs order intent but doesn't execute (useful for testing strategy logic)
Note: The old PAPER_TRADING and DRY_RUN boolean flags have been replaced with WEALTH__EXECUTION__MODE in v0.33.0 for clearer semantics.
Exchange Credentials
Credential Loading Strategy
The bot automatically tries to load credentials in the following order:
-
Encrypted Credentials File (if
CREDENTIALS_PASSPHRASEis set)- Uses
credentials.encrypted.jsonand.credentials.salt - Most secure, recommended for production
- Managed via
wealth credentialsCLI commands
- Uses
-
Environment Variables (fallback)
- Exchange-specific variables documented below
- Simpler for development and testing
No configuration needed - the bot seamlessly uses whichever method you set up.
Setup Option 1: Encrypted Credentials (Recommended)
Initial Setup:
# 1. Set passphrase in .env
echo "CREDENTIALS_PASSPHRASE=your-secure-passphrase" >> .env
# 2. Create encrypted credentials file
wealth credentials create
# 3. Add exchange credentials (interactive mode - recommended)
wealth credentials add binance
# Or with flags (less secure - visible in shell history)
wealth credentials add binance --api-key YOUR_API_KEY --secret-key YOUR_SECRET_KEY
wealth credentials add bybit --api-key YOUR_API_KEY --secret-key YOUR_SECRET_KEY
wealth credentials add hyperliquid --api-key 0xWALLET_ADDRESS --secret-key 0xPRIVATE_KEY
# 4. Verify
wealth verify --encrypted
Advantages:
- AES-256-GCM encryption
- Credentials never stored in plaintext
- Secure key derivation from passphrase (PBKDF2 with 100,000 iterations)
- Isolated from source code and version control
Security:
- Never commit
credentials.encrypted.jsonor.credentials.saltto version control - Use a strong passphrase (12+ characters, mix of types)
- Store passphrase securely (password manager, secrets vault)
CREDENTIALS_PASSPHRASE
Passphrase for encrypting/decrypting the credentials file.
- Type: String
- Default: None (not set)
- Example:
CREDENTIALS_PASSPHRASE=my-super-secure-passphrase-2024 - Required for: Encrypted credentials (Option 1)
- Not needed for: Direct environment variables (Option 2)
When set: Bot loads credentials from credentials.encrypted.json
When not set: Bot will fail to start (encrypted credentials are required since v0.21.0)
Note: Direct exchange credential environment variables (e.g.,
BINANCE_API_KEY) were deprecated in v0.21.0 and have been removed. Use encrypted credentials for all deployments. See Security Guide for setup instructions.
Resilience Configuration
WEALTH__EXECUTION__RESILIENCE__CIRCUIT_BREAKER_FAILURES
Number of failures before circuit breaker opens.
- Type: Integer
- Default:
5 - TOML Path:
execution.resilience.circuit_breaker_failures - Example:
WEALTH__EXECUTION__RESILIENCE__CIRCUIT_BREAKER_FAILURES=10
WEALTH__EXECUTION__RESILIENCE__CIRCUIT_BREAKER_TIMEOUT_SECS
Time to wait before testing recovery.
- Type: Integer
- Default:
60 - TOML Path:
execution.resilience.circuit_breaker_timeout_secs - Example:
WEALTH__EXECUTION__RESILIENCE__CIRCUIT_BREAKER_TIMEOUT_SECS=120
WEALTH__EXECUTION__RESILIENCE__CIRCUIT_BREAKER_SUCCESS_THRESHOLD
Number of successful calls needed to close circuit breaker.
- Type: Integer
- Default:
2 - TOML Path:
execution.resilience.circuit_breaker_success_threshold - Example:
WEALTH__EXECUTION__RESILIENCE__CIRCUIT_BREAKER_SUCCESS_THRESHOLD=3
WEALTH__EXECUTION__RESILIENCE__MAX_RETRIES
Maximum retry attempts for API calls.
- Type: Integer
- Default:
3 - TOML Path:
execution.resilience.max_retries - Example:
WEALTH__EXECUTION__RESILIENCE__MAX_RETRIES=5
WEALTH__EXECUTION__RESILIENCE__RETRY_INITIAL_BACKOFF_MS
Initial retry backoff in milliseconds.
- Type: Integer
- Default:
100 - TOML Path:
execution.resilience.retry_initial_backoff_ms - Example:
WEALTH__EXECUTION__RESILIENCE__RETRY_INITIAL_BACKOFF_MS=200
WEALTH__EXECUTION__RESILIENCE__RETRY_MAX_BACKOFF_SECS
Maximum retry backoff in seconds.
- Type: Integer
- Default:
10 - TOML Path:
execution.resilience.retry_max_backoff_secs - Example:
WEALTH__EXECUTION__RESILIENCE__RETRY_MAX_BACKOFF_SECS=30
WEALTH__EXECUTION__RESILIENCE__WEBSOCKET_MAX_RECONNECTS
Maximum WebSocket reconnection attempts.
- Type: Integer
- Default:
100 - TOML Path:
execution.resilience.websocket_max_reconnects - Example:
WEALTH__EXECUTION__RESILIENCE__WEBSOCKET_MAX_RECONNECTS=50
Position Reconciliation Configuration
Position reconciliation is a background task that monitors for unhedged positions and can automatically fix them. This is recommended for live trading to catch issues like partial fills that weren't properly hedged.
The reconciliation task monitors two types of positions:
- Tracked positions - Positions opened by the bot and tracked by the AtomicOrderExecutor
- Orphan positions - Positions found on exchanges but NOT tracked by the bot (requires explicit opt-in)
WEALTH__EXECUTION__RECONCILIATION__ENABLED
Enable background position reconciliation task.
- Type: Boolean
- Default:
false - TOML Path:
execution.reconciliation.enabled - Example:
WEALTH__EXECUTION__RECONCILIATION__ENABLED=true
Note: Reconciliation only runs in live trading mode. Paper trading doesn't have real positions to reconcile.
WEALTH__EXECUTION__RECONCILIATION__CHECK_INTERVAL_SECS
Interval between reconciliation checks in seconds.
- Type: Integer
- Default:
30 - TOML Path:
execution.reconciliation.check_interval_secs - Example:
WEALTH__EXECUTION__RECONCILIATION__CHECK_INTERVAL_SECS=60
Lower values detect issues faster but use more CPU. Typical range: 15-60 seconds.
WEALTH__EXECUTION__RECONCILIATION__AUTO_FIX_ENABLED
Enable automatic fixing of unhedged positions tracked by the bot.
- Type: Boolean
- Default:
true - TOML Path:
execution.reconciliation.auto_fix_enabled - Example:
WEALTH__EXECUTION__RECONCILIATION__AUTO_FIX_ENABLED=false
When enabled, unhedged positions that are tracked by the AtomicOrderExecutor are automatically closed via emergency close. When disabled, only alerts are triggered and manual intervention is required.
WEALTH__EXECUTION__RECONCILIATION__AUTO_CLOSE_ORPHANS
Enable automatic closing of orphan positions not tracked by the bot.
- Type: Boolean
- Default:
false - TOML Path:
execution.reconciliation.auto_close_orphans - Example:
WEALTH__EXECUTION__RECONCILIATION__AUTO_CLOSE_ORPHANS=true
β οΈ CAUTION: When enabled, the reconciliation task will automatically close ANY unhedged position found on exchanges that is NOT being tracked by the bot. This includes positions:
- Created manually outside the bot
- Left over from a previous bot session that crashed
- Opened by other trading systems on the same account
Only enable this if you exclusively use this bot for trading on the configured exchanges. When disabled (default), orphan positions trigger critical alerts but require manual intervention.
WEALTH__EXECUTION__RECONCILIATION__STUCK_EXECUTION_THRESHOLD_SECS
Threshold for stuck execution alerts in seconds.
- Type: Integer
- Default:
60 - TOML Path:
execution.reconciliation.stuck_execution_threshold_secs - Example:
WEALTH__EXECUTION__RECONCILIATION__STUCK_EXECUTION_THRESHOLD_SECS=60
Alert when an execution has been running longer than this threshold. Reduced from 300s to 60s for faster detection of stuck executions that could lead to liquidation. Typical range: 30-120 seconds.
WEALTH__EXECUTION__RECONCILIATION__EMERGENCY_CLOSE_FAILURE_THRESHOLD
Maximum consecutive emergency close failures before auto-shutdown.
- Type: Integer
- Default:
3 - TOML Path:
execution.reconciliation.emergency_close_failure_threshold - Example:
WEALTH__EXECUTION__RECONCILIATION__EMERGENCY_CLOSE_FAILURE_THRESHOLD=3
When this threshold is reached, the bot will automatically initiate a graceful shutdown to prevent further losses from unhedged positions. This is a critical safety feature to prevent liquidation during cascading failures. Set to 0 to disable auto-shutdown (not recommended).
WEALTH__EXECUTION__RECONCILIATION__HYPERLIQUID_CLOSE_SLIPPAGE
Slippage percentage for HyperLiquid force close operations.
- Type: Float (0.0 - 1.0)
- Default:
0.05(5%) - TOML Path:
execution.reconciliation.hyperliquid_close_slippage - Example:
WEALTH__EXECUTION__RECONCILIATION__HYPERLIQUID_CLOSE_SLIPPAGE=0.05
This slippage setting is used in two scenarios:
- Orphan Position Closing: When closing orphan positions on HyperLiquid during reconciliation
- Atomic Executor Fallback: When
reduce_onlyclose orders return zero fill but positions still exist (v0.52+)
Higher values increase the chance of fill but may result in worse execution prices. The default 5% is recommended for reliable closes.
Note: This uses HyperLiquid's SDK market_close function which fetches the current position state directly from the exchange before closing, making it more reliable than standard reduce_only orders.
Pair Health Configuration
The pair health system monitors trading pair health to detect degraded or broken data feeds. Unhealthy pairs can be automatically disabled to prevent bad trades.
WEALTH__PAIR_HEALTH__ENABLED
Enable automatic health monitoring for trading pairs.
- Type: Boolean
- Default:
true - TOML Path:
pair_health.enabled - Example:
WEALTH__PAIR_HEALTH__ENABLED=false
When enabled, the system tracks WebSocket disconnections, API errors, and data staleness for each trading pair.
WEALTH__PAIR_HEALTH__MAX_WS_DISCONNECTIONS
Maximum consecutive WebSocket disconnections before marking pair unhealthy.
- Type: Integer
- Default:
5 - TOML Path:
pair_health.max_ws_disconnections - Example:
WEALTH__PAIR_HEALTH__MAX_WS_DISCONNECTIONS=10
WEALTH__PAIR_HEALTH__MAX_API_ERRORS
Maximum consecutive API errors before marking pair unhealthy.
- Type: Integer
- Default:
10 - TOML Path:
pair_health.max_api_errors - Example:
WEALTH__PAIR_HEALTH__MAX_API_ERRORS=15
WEALTH__PAIR_HEALTH__MAX_FUNDING_RATE_STALENESS_SECS
Maximum age of funding rate data in seconds before considered stale.
- Type: Integer
- Default:
300(5 minutes) - TOML Path:
pair_health.max_funding_rate_staleness_secs - Example:
WEALTH__PAIR_HEALTH__MAX_FUNDING_RATE_STALENESS_SECS=600
Funding rate data older than this threshold is excluded from opportunity detection. This prevents trading on outdated market data.
WEALTH__PAIR_HEALTH__MAX_PRICE_STALENESS_SECS
Maximum age of price data in seconds before considered stale.
- Type: Integer
- Default:
60(1 minute) - TOML Path:
pair_health.max_price_staleness_secs - Example:
WEALTH__PAIR_HEALTH__MAX_PRICE_STALENESS_SECS=120
WEALTH__PAIR_HEALTH__AUTO_DISABLE_UNHEALTHY
Automatically disable pairs that become unhealthy.
- Type: Boolean
- Default:
false - TOML Path:
pair_health.auto_disable_unhealthy - Example:
WEALTH__PAIR_HEALTH__AUTO_DISABLE_UNHEALTHY=true
When true, pairs are auto-disabled when health thresholds are exceeded. When false (default), pairs stay enabled but show unhealthy status in TUI.
WEALTH__PAIR_HEALTH__AUTO_REENABLE_HEALTHY
Automatically re-enable pairs after they become healthy again.
- Type: Boolean
- Default:
true - TOML Path:
pair_health.auto_reenable_healthy - Example:
WEALTH__PAIR_HEALTH__AUTO_REENABLE_HEALTHY=false
WEALTH__PAIR_HEALTH__HEALTHY_CHECKS_FOR_REENABLE
Number of consecutive healthy checks before re-enabling auto-disabled pair.
- Type: Integer
- Default:
3 - TOML Path:
pair_health.healthy_checks_for_reenable - Example:
WEALTH__PAIR_HEALTH__HEALTHY_CHECKS_FOR_REENABLE=5
WEALTH__PAIR_HEALTH__CHECK_INTERVAL_SECS
Health check interval in seconds.
- Type: Integer
- Default:
30 - TOML Path:
pair_health.check_interval_secs - Example:
WEALTH__PAIR_HEALTH__CHECK_INTERVAL_SECS=60
Example Configuration:
[pair_health]
enabled = true
max_ws_disconnections = 5
max_api_errors = 10
max_funding_rate_staleness_secs = 300
max_price_staleness_secs = 60
auto_disable_unhealthy = false
auto_reenable_healthy = true
healthy_checks_for_reenable = 3
check_interval_secs = 30
Observability Configuration
WEALTH__OBSERVABILITY__METRICS_PORT
Port number for the metrics/API server.
- Type: u16
- Default:
9090 - TOML Path:
observability.metrics_port - Example:
WEALTH__OBSERVABILITY__METRICS_PORT=9090
The metrics server exposes:
/metrics- OpenTelemetry metrics info (JSON)/health,/ready,/live- Health check endpoints/api/positions,/api/funding_rates,/api/balances- HTTP API for querying bot state/api/arbitrage_positions- Cached arbitrage positions with funding collected (fast, no API quota)
WEALTH__OBSERVABILITY__METRICS_BIND_ADDRESS
IP address for the metrics/API server to bind to.
- Type: IP Address
- Default:
0.0.0.0(all network interfaces) - TOML Path:
observability.metrics_bind_address - Example:
WEALTH__OBSERVABILITY__METRICS_BIND_ADDRESS=127.0.0.1
Set to 127.0.0.1 for localhost-only access (recommended for production with external proxy).
WEALTH__OBSERVABILITY__OTLP_ENDPOINT
OpenTelemetry Protocol (OTLP) endpoint URL for exporting traces, metrics, and logs.
- Type: String (URL)
- Default: None (OTLP export disabled, local logging only)
- TOML Path:
observability.otlp_endpoint - Example:
WEALTH__OBSERVABILITY__OTLP_ENDPOINT=http://localhost:4317
When set, the bot will export all telemetry (traces, metrics, logs) to an OpenTelemetry Collector or compatible backend (Tempo, Jaeger, etc.) via gRPC. This replaces the previous Loki push logging with a unified observability pipeline.
URL Validation:
- Must start with
http://orhttps:// - Default port for OTLP gRPC is
4317 - Supports authentication via standard OTLP headers (configure in collector)
Resource Attributes:
You can add custom resource attributes via the OTEL_RESOURCE_ATTRIBUTES environment variable:
export OTEL_RESOURCE_ATTRIBUTES="service.name=wealth-bot,deployment.environment=production,service.version=0.16.0"
WEALTH__OBSERVABILITY__SERVICE_NAME
Service name for telemetry resource attributes.
- Type: String
- Default:
wealth - TOML Path:
observability.service_name - Example:
WEALTH__OBSERVABILITY__SERVICE_NAME=wealth-prod
Used as the service.name resource attribute in OpenTelemetry spans, metrics, and logs. Useful when running multiple bot instances.
WEALTH__OBSERVABILITY__ENVIRONMENT
Environment name for telemetry resource attributes (e.g., production, development, staging).
- Type: String
- Default:
development - TOML Path:
observability.environment - Example:
WEALTH__OBSERVABILITY__ENVIRONMENT=production
Used as a custom resource attribute for environment-based filtering in observability backends.
WEALTH__OBSERVABILITY__ENABLE_TRACES
Enable distributed tracing via OTLP.
- Type: Boolean
- Default:
true - TOML Path:
observability.enable_traces - Example:
WEALTH__OBSERVABILITY__ENABLE_TRACES=false
When enabled alongside otlp_endpoint, exports trace spans to the OTLP endpoint for distributed tracing visualization in Tempo, Jaeger, or similar backends.
WEALTH__OBSERVABILITY__TRACE_SAMPLE_RATE
Trace sampling rate (0.0 = never sample, 1.0 = always sample).
- Type: Decimal (0.0 - 1.0)
- Default:
1.0(100% of traces) - TOML Path:
observability.trace_sample_rate - Example:
WEALTH__OBSERVABILITY__TRACE_SAMPLE_RATE=0.1
Lower values reduce observability costs in high-throughput scenarios. Recommended: 1.0 for development, 0.1-0.01 for high-volume production.
WEALTH__OBSERVABILITY__LOG_FILE
Path to log file for file-based logging.
- Type: String (file path)
- Default: None (logs to stdout only)
- TOML Path:
observability.log_file - Example:
WEALTH__OBSERVABILITY__LOG_FILE=/var/log/wealth.log
When set, logs are written to both stdout and the specified file. Useful for debugging without disrupting OTLP telemetry.
Configuration Methods:
-
Environment Variables:
export WEALTH__OBSERVABILITY__OTLP_ENDPOINT=http://localhost:4317 export WEALTH__OBSERVABILITY__SERVICE_NAME=wealth-prod export WEALTH__OBSERVABILITY__ENVIRONMENT=production -
TOML Config:
[observability] otlp_endpoint = "http://localhost:4317" service_name = "wealth-prod" environment = "production" -
JSON Config (Legacy):
{ "observability": { "otlp_endpoint": "http://localhost:4317", "service_name": "wealth-prod", "environment": "production" } }
Configuration Precedence: Environment variables > TOML config > JSON config (legacy) > Defaults
See Logging Guide for complete OpenTelemetry setup instructions.
Configuration Examples
Development (Paper Trading)
# Trading
WEALTH__TRADING__MIN_FUNDING_SPREAD=0.04
WEALTH__TRADING__MAX_POSITION_USD=10000
WEALTH__TRADING__POSITION_SIZE_PERCENT=0.3
WEALTH__TRADING__TARGET_PROFIT_PERCENT=0.05
# Execution
WEALTH__EXECUTION__MODE=paper
# Observability
RUST_LOG=info
# Optional: Enable OTLP export for development
WEALTH__OBSERVABILITY__OTLP_ENDPOINT=http://localhost:4317
WEALTH__OBSERVABILITY__SERVICE_NAME=wealth-dev
WEALTH__OBSERVABILITY__ENVIRONMENT=development
Production (Live Trading)
# Trading
WEALTH__TRADING__MIN_FUNDING_SPREAD=0.04
WEALTH__TRADING__MAX_POSITION_USD=50000
WEALTH__TRADING__POSITION_SIZE_PERCENT=0.25
WEALTH__TRADING__TARGET_PROFIT_PERCENT=0.05
# Execution
WEALTH__EXECUTION__MODE=live
# Exchange Credentials (use encrypted credentials file instead)
CREDENTIALS_PASSPHRASE="your-secure-passphrase"
# Observability
RUST_LOG=info
WEALTH__OBSERVABILITY__OTLP_ENDPOINT=https://otlp.example.com:4317
WEALTH__OBSERVABILITY__SERVICE_NAME=wealth-prod
WEALTH__OBSERVABILITY__ENVIRONMENT=production
Testing Configuration
# Execution
WEALTH__EXECUTION__MODE=paper
# Conservative settings
WEALTH__TRADING__MAX_POSITION_USD=100
WEALTH__TRADING__POSITION_SIZE_PERCENT=0.1
# Verbose logging
RUST_LOG=debug
Configuration Validation
All configuration is validated on startup with fail-fast behavior.
Validation Process:
- Type validation during JSON parsing (serde)
- Cross-field validation after loading
- Clear error messages indicating which rule failed
Validated Constraints:
- All numeric thresholds must be positive
- Percentages must be between 0 and 1
- Port numbers must be non-zero
- At least one instrument must be configured
- Retry counts and timeouts must be valid
Example Error:
ERROR Configuration validation failed: Metrics port must be non-zero
ERROR Configuration validation failed: At least one instrument must be configured
Debugging Configuration
Use the config show --show-sources command to see where each configuration value comes from:
$ wealth config show --show-sources
π Configuration Sources
Shows: default β file (config.toml) β env vars β β final value
π― Trading Configuration:
min_funding_spread:
default: 0.0004
file: 0.0005
env: 0.0006
β final: 0.0006 β using environment override
max_position_usd:
default: 10000
β final: 10000 β using default
This helps identify configuration issues and understand which values are active.
Environment Variable Precedence
Configuration loading happens in this order:
- Environment variables with
WEALTH__prefix (highest priority) - Override all other settings - TOML/JSON configuration file (
config.tomlorconfig.json) - Provides structured config - Default values (lowest priority) - Built-in sensible defaults
Example: If you set WEALTH__TRADING__MIN_FUNDING_SPREAD=0.001 in .env and min_funding_spread = 0.04 in config.toml, the environment variable takes precedence.
Best Practices:
- Use
config.tomlfor static configuration (instruments, leverage, strategy parameters) - Use environment variables with
WEALTH__prefix for deployment-specific settings - Use encrypted credentials file for API keys (safer than environment variables)
- Use
.envfile for local development overrides
Using with Different Tools
Systemd
[Service]
Environment="WEALTH__EXECUTION__MODE=live"
Environment="CREDENTIALS_PASSPHRASE=your-passphrase"
Docker
docker run -e WEALTH__EXECUTION__MODE=live \
-e CREDENTIALS_PASSPHRASE=xxx \
-v $(pwd)/config.toml:/app/config.toml \
wealth
Docker Compose
environment:
- WEALTH__EXECUTION__MODE=live
- CREDENTIALS_PASSPHRASE=${CREDENTIALS_PASSPHRASE}
volumes:
- ./config.toml:/app/config.toml:ro
- ./credentials.encrypted.json:/app/credentials.encrypted.json:ro
Kubernetes
env:
- name: WEALTH__EXECUTION__MODE
value: "live"
- name: CREDENTIALS_PASSPHRASE
valueFrom:
secretKeyRef:
name: wealth-secrets
key: credentials-passphrase
volumeMounts:
- name: config
mountPath: /app/config.toml
subPath: config.toml
Configuration Debugging
Config Show Sources Command
Display where each configuration value comes from (default β file β env):
wealth config --show-sources
Example Output:
π Configuration Sources
Shows: default β file (config.toml) β env vars β β final value
π― Trading Configuration:
min_funding_spread:
default: 0.0004
env: 0.0008
β final: 0.0008 β using environment override
max_position_usd:
default: 10000
file: 15000
β final: 15000 β from config file
Use cases:
- Debug which source is being used for each config value
- Verify environment variable overrides are working
- Identify misconfigured values before running the bot
Validation Error Messages
Configuration errors now include source tracking (v0.33.0+):
File-based error:
Error: Invalid value for leverage.default: Must be greater than 0
(from config file: config.toml)
Environment variable error:
Error: Invalid value for trading.min_funding_spread: Cannot be negative
(from environment variable: WEALTH__TRADING__MIN_FUNDING_SPREAD)
Default value error:
Error: Invalid value for risk.max_slippage_bps: must be positive
(using default value)
Benefits:
- Quickly identify where the problematic value is configured
- Avoid checking multiple configuration sources manually
- Clear distinction between file errors and env var errors
Config Validation
Validate configuration without starting the bot:
wealth config --validate
Output:
π Validating configuration...
β Loading config.toml
β TOML parsing successful
β Environment variable parsing successful
β Validating configuration... OK
β
Configuration is valid!
Instruments: 6
Metrics Port: 9090
Execution Mode: Paper
Common validation errors:
- Negative values (spreads, slippage, leverage)
- Out-of-range percentages (must be 0.0-1.0)
- Invalid exchange names (must be: binance, bybit, hyperliquid, aster)
- Missing required instruments
See Also
- CLI Reference - Command-line options
- Security Guide - Encrypted credentials
- Getting Started - Installation and setup