edgelord 0.0.6

A prediction market arbitrage detection and execution CLI.
Documentation
# Edgelord Configuration
# Copy this file to config.toml and customize for your setup.
# Sensitive values (private keys) should be set via environment variables.

# =============================================================================
# GENERAL
# =============================================================================

# Application profile: "local", "production", or "custom"
# - local: Conservative settings for development
# - production: Higher capacity for live trading
# - custom: Uses explicit resource settings below
profile = "local"

# Dry-run mode: detect opportunities but don't execute trades
# Useful for testing and validating configuration
dry_run = false

# Path to SQLite database for stats and persistence
database = "edgelord.db"

# Raw data retention (days). Older opportunities/trades are pruned.
# Aggregated daily_stats are kept forever for historical analysis.
# Use `edgelord statistics prune --days N` to manually prune.
# retention_days = 30

# =============================================================================
# EXCHANGE
# =============================================================================

# Which exchange to connect to (currently only "polymarket")
exchange = "polymarket"

# Exchange-specific configuration
[exchange_config]
type = "polymarket"
# Environment: "testnet" or "mainnet"
# IMPORTANT: Use testnet for testing, mainnet for real trading
environment = "testnet"

# Chain ID: 80002 (Amoy testnet) or 137 (Polygon mainnet)
chain_id = 80002

# WebSocket URL for market data (usually don't need to change)
ws_url = "wss://ws-subscriptions-clob.polymarket.com/ws/market"

# REST API URL (usually don't need to change)
api_url = "https://clob.polymarket.com"

# Connection management
[exchange_config.connections]
connection_ttl_secs = 120           # How long connections live
preemptive_reconnect_secs = 30      # Reconnect this many secs before TTL
max_connections = 10                # Max simultaneous connections
subscriptions_per_connection = 500  # Max subscriptions per connection

# HTTP client settings for REST calls
[exchange_config.http]
timeout_ms = 5000                    # Request timeout (ms)
connect_timeout_ms = 2000            # Connect timeout (ms)
retry_max_attempts = 3               # Retries on transient errors
retry_backoff_ms = 500               # Backoff between retries (ms)

# Market filtering - which markets to monitor
[exchange_config.market_filter]
max_markets = 500                   # Maximum markets to track
max_subscriptions = 2000            # Maximum token subscriptions
min_volume_24h = 1000.0             # Minimum 24h volume ($)
min_liquidity = 500.0               # Minimum liquidity ($)
max_spread_pct = 0.10               # Maximum spread (10%)
include_binary = true               # Include 2-outcome markets
include_multi_outcome = true        # Include 3+ outcome markets
max_outcomes = 20                   # Skip markets with more outcomes

# Scoring weights for market prioritization
[exchange_config.scoring.weights]
liquidity = 0.0                     # Disabled until Phase 2
spread = 0.0                        # Disabled until Phase 2
opportunity = 0.50                  # Primary factor (price imbalance)
outcome_count = 0.40                # More outcomes = more potential
activity = 0.10                     # Placeholder

# Bonus multipliers for outcome counts
[exchange_config.scoring.outcome_bonus]
binary = 1.0                        # 2-outcome markets
three_to_five = 1.5                 # 3-5 outcome markets
six_plus = 2.0                      # 6+ outcome markets

# Deduplication settings
[exchange_config.dedup]
enabled = true
strategy = "hash"                   # "hash", "timestamp", or "content"
fallback = "timestamp"
cache_ttl_secs = 5
max_cache_entries = 100000

# =============================================================================
# LOGGING
# =============================================================================

[logging]
# Log level: "debug", "info", "warn", "error"
level = "info"

# Log format: "pretty" (human-readable) or "json" (structured)
format = "pretty"

# =============================================================================
# STRATEGIES
# =============================================================================

[strategies]
# Which strategies to enable (list of names)
enabled = ["single_condition", "market_rebalancing"]

# Single-condition: YES + NO < $1 in binary markets
[strategies.single_condition]
min_edge = 0.05                     # Minimum edge (5%)
min_profit = 0.50                   # Minimum profit ($0.50)

# Market rebalancing: sum of all outcomes < $1 in multi-outcome markets
[strategies.market_rebalancing]
min_edge = 0.03                     # Minimum edge (3%)
min_profit = 1.00                   # Minimum profit ($1.00)
max_outcomes = 10                   # Skip markets with more outcomes

# Combinatorial: cross-market arbitrage via Frank-Wolfe + ILP
# NOTE: Requires dependency configuration (not yet implemented)
[strategies.combinatorial]
enabled = false                     # Disabled by default
max_iterations = 20                 # Frank-Wolfe iterations
tolerance = 0.0001                  # Convergence threshold
gap_threshold = 0.02                # Minimum gap to trade (2%)

# =============================================================================
# RISK MANAGEMENT
# =============================================================================

[risk]
# Maximum position size per market in dollars
max_position_per_market = 100.0

# Maximum total exposure across all positions
max_total_exposure = 500.0

# Minimum profit threshold to execute a trade
min_profit_threshold = 0.50

# Maximum slippage tolerance (e.g., 0.02 = 2%)
max_slippage = 0.02

# =============================================================================
# WALLET
# =============================================================================

# Private key is loaded from WALLET_PRIVATE_KEY environment variable.
# NEVER put your private key in this file!
#
# Set it via:
#   export WALLET_PRIVATE_KEY=your_key_without_0x_prefix
#
# Or in a .env file (chmod 600):
#   WALLET_PRIVATE_KEY=your_key_without_0x_prefix

[wallet]
# No settings here - private key comes from env var

# =============================================================================
# TELEGRAM NOTIFICATIONS
# =============================================================================

# Requires TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID environment variables.
# See docs/deployment/telegram.md for setup instructions.

[telegram]
enabled = false                     # Enable Telegram alerts
notify_opportunities = false        # Alert on opportunity detection (noisy!)
notify_executions = true            # Alert on trade execution
notify_risk_rejections = true       # Alert when risk manager rejects

# =============================================================================
# GOVERNOR (Adaptive Subscription Management)
# =============================================================================

[governor]
enabled = true                      # Enable adaptive scaling

# Latency targets in milliseconds
[governor.latency]
target_p50_ms = 10
target_p95_ms = 50
target_p99_ms = 100
max_p99_ms = 200                    # Max acceptable p99 latency

# Scaling behavior
[governor.scaling]
check_interval_secs = 10            # How often to check metrics
expand_threshold = 0.70             # Add subs when utilization below this
contract_threshold = 1.20           # Remove subs when utilization above this
expand_step = 50                    # Subscriptions to add
contract_step = 100                 # Subscriptions to remove
cooldown_secs = 60                  # Wait between scaling actions

# =============================================================================
# RECONNECTION
# =============================================================================

[reconnection]
initial_delay_ms = 1000             # First retry delay (1 second)
max_delay_ms = 60000                # Maximum retry delay (60 seconds)
backoff_multiplier = 2.0            # Exponential backoff multiplier
max_consecutive_failures = 10       # Circuit breaker threshold
circuit_breaker_cooldown_ms = 300000  # Cooldown after circuit break (5 min)

# =============================================================================
# CONNECTION POOL
# =============================================================================

[connection_pool]
num_shards = 3                      # Number of shards
connections_per_shard = 2           # Connections per shard
stagger_offset_secs = 60            # Stagger between connection attempts
health_check_interval_secs = 5      # Health check frequency
max_silent_secs = 10                # Max silence before unhealthy

# =============================================================================
# RESOURCES (for profile = "custom")
# =============================================================================

[resources]
auto_detect = false                 # Auto-detect system resources
# max_memory_mb = 4096              # Memory limit in MB (optional)
# worker_threads = 4                # Worker thread count (optional)
memory_usage_target = 0.80          # Target memory utilization
cpu_usage_target = 0.70             # Target CPU utilization

# =============================================================================
# LLM (Language Model for Relation Inference)
# =============================================================================

# API key is loaded from ANTHROPIC_API_KEY or OPENAI_API_KEY environment variable.
# NEVER put your API key in this file!

[llm]
# Provider: "anthropic" or "openai"
provider = "anthropic"

# Anthropic-specific settings
[llm.anthropic]
model = "claude-sonnet-4-6"  # Model to use
temperature = 0.2                      # Low for consistent JSON output
max_tokens = 4096                      # Max response tokens

# OpenAI-specific settings (used if provider = "openai")
[llm.openai]
model = "gpt-4-turbo"
temperature = 0.2
max_tokens = 4096

# =============================================================================
# INFERENCE (Relation Discovery Service)
# =============================================================================

[inference]
enabled = false                     # Enable automatic relation discovery
min_confidence = 0.7                # Minimum confidence to accept (0.0-1.0)
ttl_seconds = 3600                  # How long relations are valid (1 hour)
price_change_threshold = 0.05       # Re-infer on 5% price change
scan_interval_seconds = 3600        # Full scan every hour
batch_size = 30                     # Markets per LLM call

# =============================================================================
# CLUSTER DETECTION (Scalable Combinatorial Arbitrage)
# =============================================================================

[cluster_detection]
enabled = false                     # Enable real-time cluster detection
debounce_ms = 100                   # Minimum interval between detection runs
min_gap = 0.02                      # Minimum arbitrage gap (2%)
max_clusters_per_cycle = 50         # Max clusters to check per cycle
channel_capacity = 1024             # Order book update channel size