Configuration Reference
All configuration is via environment variables in ~/.config/edgeproof/.env
(the EdgeProof home; override its location with the EDGEPROOF_HOME
environment variable; EDGEPROOF_HOME itself must be set in your shell, not
in .env). Run edgeproof configure to create and edit it interactively.
The home directory also holds activated license tokens and the output/ directory (databases, logs, and PID files).
Broker
| Variable |
Default |
Description |
BROKER |
alpaca |
Broker to trade through: alpaca or schwab. |
Choosing a broker
| Broker |
Paper trading |
Setup |
| Alpaca (default) |
Yes (full paper environment) |
edgeproof init |
| Schwab |
No (every order is real money) |
edgeproof broker setup schwab |
| Robinhood |
No (every order is real money) |
.env + edgeproof broker auth robinhood |
| tastytrade |
Yes (real certification sandbox) |
.env + edgeproof broker auth tastytrade |
| Interactive Brokers |
Yes (paper accounts) |
.env + run the Client Portal Gateway |
Schwab's Trader API has no sandbox, so EdgeProof cannot rehearse a strategy against it.
Choosing Schwab means giving up the paper period EdgeProof normally requires before live
trading, and it must be confirmed explicitly (see SCHWAB_LIVE_ONLY_ACKNOWLEDGED below).
If you want to prove a signal source before risking money, use Alpaca paper trading.
Alpaca
| Variable |
Default |
Description |
APCA_API_KEY_ID |
(required) |
Alpaca API key ID |
APCA_API_SECRET_KEY |
(required) |
Alpaca API secret key |
ALPACA_PAPER_TRADE |
True |
Set False for live trading (requires license) |
APCA_API_BASE_URL |
auto |
Override broker URL (paper or live) |
Schwab
Required when BROKER=schwab. Set these with edgeproof broker setup schwab rather than
by hand: it validates them and runs the authorisation flow.
| Variable |
Default |
Description |
SCHWAB_CLIENT_ID |
(required) |
App Key from your app at developer.schwab.com |
SCHWAB_CLIENT_SECRET |
(required) |
App Secret |
SCHWAB_ACCOUNT_HASH |
(required) |
Opaque account id from GET /trader/v1/accounts/accountNumbers. Check edgeproof doctor prints the account number you expect: a valid-looking hash can address a different account on the same login. |
SCHWAB_LIVE_ONLY_ACKNOWLEDGED |
false |
Must be true to trade. Confirms you understand Schwab has no paper mode and every order is real. EdgeProof refuses to place entries without it. |
SCHWAB_CALLBACK_URL |
https://127.0.0.1 |
OAuth redirect. Must match the callback registered on your Schwab app. |
tastytrade
Required when BROKER=tastytrade. Options-native and paper-capable: its
certification environment (api.cert.tastyworks.com) is a real sandbox, so EdgeProof's
normal paper-first discipline applies. Note the sandbox needs its own separate
tastytrade certification account; live credentials do not work against it.
| Variable |
Default |
Description |
TASTYTRADE_CLIENT_ID |
(required) |
OAuth client id, from your registered tastytrade OAuth client |
TASTYTRADE_CLIENT_SECRET |
(required) |
OAuth client secret |
TASTYTRADE_ACCOUNT_NUMBER |
(required) |
Account to trade (e.g. 5WX12345) |
TASTYTRADE_PAPER_TRADE |
true |
true uses the certification sandbox; false trades real money |
TASTYTRADE_API_BASE_URL |
auto |
Override the base URL (paper or live) |
Access tokens last 15 minutes and refresh automatically. Unlike Schwab there is no
fixed refresh-token cliff, so an always-on install should not need re-authorising.
Interactive Brokers
Required when BROKER=ibkr. EdgeProof talks to IBKR's Client Portal Gateway, which
you run and log into yourself: EdgeProof never sees your IBKR password, and there are
no API keys.
| Variable |
Default |
Description |
IBKR_ACCOUNT_ID |
(required) |
Account to trade. Paper accounts are prefixed DU. |
IBKR_PAPER_TRADE |
true |
Must match the account: true requires a DU… account. |
IBKR_GATEWAY_URL |
gateway default |
Override if the gateway runs on another port. |
Paper and live share one gateway, so unlike every other broker the URL cannot tell
them apart: the account id is the boundary. EdgeProof refuses to start if
IBKR_PAPER_TRADE=true with a live account, or false with a DU… account, and it
makes no API call before that check. Keep the gateway logged into the account matching
your setting.
Robinhood
Required when BROKER=robinhood. Robinhood speaks MCP, not REST: EdgeProof
connects to Robinhood's agentic-trading endpoint. There are no API keys to copy: run
edgeproof broker auth robinhood, approve in the browser, and the grant is stored for you.
| Variable |
Default |
Description |
ROBINHOOD_ACCOUNT_NUMBER |
(required) |
Brokerage account to trade. Robinhood requires it explicitly and EdgeProof never defaults it. |
ROBINHOOD_LIVE_ONLY_ACKNOWLEDGED |
false |
Must be true to trade. Confirms you understand Robinhood has no paper mode. |
ROBINHOOD_MCP_URL |
Robinhood's endpoint |
Override the MCP server URL (testing only). |
Account requirements. Agentic trading runs in a dedicated Agentic account,
opened during edgeproof broker auth robinhood (desktop browser only); use that
account's number here. The account must be agentic-enabled and have options level 2
or higher; EdgeProof checks both at startup rather than failing on the first order.
Single-leg only. Robinhood's endpoint supports single-leg option orders, which is
what EdgeProof places. Spreads are not available through it.
Workflow note. Robinhood documents its trading tools for agents that confirm each
order with a human. EdgeProof runs unattended. The endpoint accepts the orders either
way, but you should be comfortable with that difference before enabling it.
Schwab token expiry
Schwab tokens expire after 7 days. Schwab does not allow programmatic renewal. While
EdgeProof is running it refreshes itself; if it stays offline longer than 7 days, run
edgeproof broker auth schwab again. edgeproof doctor warns 24 hours ahead.
Discord Source
| Variable |
Default |
Description |
DISCORD_SOURCE_MODE |
auto |
puppeteer (browser scraping) or bot (Gateway API). If unset, auto-detects: bot when DISCORD_BOT_TOKEN is present, otherwise puppeteer. Set explicitly to override. |
DISCORD_CHANNEL_URL |
(empty) |
Single channel URL (puppeteer mode) |
DISCORD_CHANNEL_URLS |
(empty) |
Comma-separated channel URLs (puppeteer mode) |
DISCORD_BOT_TOKEN |
(optional) |
Discord bot token (bot mode) |
DISCORD_CHANNEL_IDS |
(empty) |
Comma-separated channel IDs (bot mode) |
DISCORD_CHANNEL_FILTERS |
(empty) |
Only process messages matching these keywords |
DISCORD_MAX_MESSAGE_LENGTH |
500 |
Skip messages longer than this |
CHROME_DEBUGGING_URL |
http://localhost:9222 |
Chrome DevTools endpoint (puppeteer mode). Change the port here: CHROME_DEBUGGING_PORT is parsed but not used by the scraper, so setting it alone has no effect. Use http://127.0.0.1:9222 if your machine resolves localhost to IPv6 and the connection is refused. |
LLM
edgeproof configure sets these for you. The default and recommended path is openai-compatible, which works with any hosted provider and requires no local hardware.
Hosted providers (openai-compatible)
Set LLM_PROVIDER=openai-compatible and fill in the three keys below. edgeproof configure writes these automatically when you choose a hosted provider.
| Variable |
Default |
Description |
LLM_PROVIDER |
ollama |
Provider mode. openai-compatible, ollama, or lmstudio. edgeproof configure writes openai-compatible when you pick a hosted provider (the recommended path). |
LLM_API_BASE_URL |
https://api.openai.com/v1 |
Base URL for the OpenAI-compatible endpoint |
LLM_API_KEY |
(required) |
API key for the hosted endpoint |
LLM_MODEL |
(required) |
Model name (e.g. gpt-4o-mini, claude-haiku-4-5, gemini-3.5-flash) |
LLM_API_COMPAT_MODE |
openai-responses |
Wire format for the endpoint. edgeproof configure writes openai-chat-compatible for the hosted providers (OpenAI, Anthropic, Gemini); leave it as init set it unless your endpoint requires otherwise. |
Common base URLs set by edgeproof configure:
| Provider |
LLM_API_BASE_URL |
| OpenAI |
https://api.openai.com/v1 |
| Anthropic (Claude) |
https://api.anthropic.com/v1/ |
| Gemini |
https://generativelanguage.googleapis.com/v1beta/openai/ |
Local models (Ollama / LM Studio)
Use these if you prefer to keep data on your machine. See Installation -- local model path for hardware requirements.
| Variable |
Default |
Description |
OLLAMA_BASE_URL |
http://localhost:11434/v1 |
Ollama endpoint |
OLLAMA_MODEL |
gemma4:latest |
Ollama model name |
LMSTUDIO_BASE_URL |
http://localhost:1234/v1 |
LM Studio endpoint |
LMSTUDIO_MODEL |
gemma-4-26b-a4b-it |
LM Studio model name |
LMSTUDIO_TIMEOUT_MS |
180000 |
Per-completion timeout for slow local models |
Trading Guardrails
These keys control what trades the system will take. All of them have safe defaults; adjust only what you understand.
Position sizing
| Variable |
Default |
Description |
TRADING_POSITION_SIZE_USD |
500 |
Dollar budget per position; qty = floor(budget / (price x 100)) |
TRADING_MAX_CONTRACTS_PER_UNDERLYING |
2 |
Max open contracts on a single underlying |
TRADING_FOLLOW_CHANNEL_EXITS |
false |
Let a channel's own exit calls close or trim the positions it opened. See Guardrails. |
TRADING_VAGUE_TRIM_FRACTION |
0 |
Fraction sold when a followed channel trims without stating a size ("taking a trim here"). 0 = notify only, never execute. Must be below 1. |
TRADING_MAX_OPEN_POSITIONS |
10 |
Global cap on concurrent open positions across all underlyings |
TRADING_ADD_ON_CAP |
3 |
Max contracts allowed when adding to an existing position |
TRADING_MAX_CONTRACTS_PER_TRADE |
0 |
Optional liquidity ceiling on contracts per single trade (0 = uncapped, the default; dollar budget remains the sizing control) |
TRADING_LOTTO_SIZE_FRACTION |
0.25 |
Fraction of the budget a lotto signal may size against (its "lane") |
TRADING_STARTER_SIZE_FRACTION |
0.33 |
Fraction of the budget a starter signal may size against (its "lane") |
Entry filters
| Variable |
Default |
Description |
TRADING_ALLOW_0DTE |
false |
Allow entries on options expiring the same trading day |
TRADING_ALLOW_LOTTOS |
false |
Allow lotto / low-conviction long-shot entries |
TRADING_ALLOW_LOW_CONVICTION |
false |
Allow entries flagged as low-conviction by the signal extractor |
TRADING_REQUIRE_ENTRY_PRICE |
true |
Skip entries with no stated entry price: without one, the sanity ratio and hard cap below have nothing to anchor to |
TRADING_ENTRY_SANITY_RATIO |
3 |
Reject a signal if its price is more than this multiple above or below the current market price (e.g. 3 rejects anything >3x or <1/3 of market) |
TRADING_SLIPPAGE_PCT |
0.07 |
Max slippage tolerance (7%) for limit order placement |
TRADING_HARD_CAP_PCT |
0.10 |
Skip buy if market price is >10% above signal entry |
TRADING_MAX_SIGNAL_AGE_MINUTES |
60 |
Discard signals older than this |
TRADING_LOOKBACK_DAYS |
14 |
Lookback window for dedup and P&L queries |
MONITOR_INTERVAL_MINUTES |
0.5 |
How often the monitor checks for new signals |
Position Exit Rules
| Variable |
Default |
Description |
POSITION_TAKE_PROFIT_PCT |
75 |
Close at +75% gain |
POSITION_STOP_LOSS_PCT |
-50 |
Close at −50% loss |
POSITION_TRAILING_STOP_PCT |
40 |
Trailing stop: close if price falls 40% from peak |
POSITION_TRAILING_STOP_ACTIVATION_PCT |
30 |
Trailing stop activates after +30% gain |
POSITION_POLL_INTERVAL_MS |
10000 |
How often positions are polled |
POSITION_OPEN_BLACKOUT_SECONDS |
300 |
Suppress stop-loss/exit evaluation for this many seconds after the 8:30 CT market open: quotes at the open gap and settle |
Notifications
| Variable |
Default |
Description |
TELEGRAM_BOT_TOKEN |
(optional) |
Telegram bot token for trade alerts |
TELEGRAM_CHAT_ID |
(optional) |
Telegram chat/channel ID |
Streaming
| Variable |
Default |
Description |
STREAMING_ENABLED |
true |
Enable WebSocket streaming for real-time position updates |
STREAMING_OPTIONS_FEED |
indicative |
indicative (free) or opra (subscription required) |
Licensing
| Variable |
Default |
Description |
EDGEPROOF_WORKER_BASE_URL |
https://api.edgeproof.net |
License/worker API base URL. Override for testing. |
Output
| Variable |
Default |
Description |
OUTPUT_DIRECTORY |
~/.config/edgeproof/output |
Directory for logs, trade database, PID file. A relative value resolves against the EdgeProof home, not the current directory. |
| Variable |
Default |
Description |
EXTRACTION_CHANNEL_HINTS |
(optional) |
JSON blob describing your channel's signal format. Normally leave this unset: on the first monitor run EdgeProof learns the format from live messages and persists it to <output>/channel-hints.json, reused automatically afterward. Set this env var only to pin a format explicitly (it overrides the learned file). To re-learn, delete <output>/channel-hints.json. |
Privacy
| Variable |
Default |
Description |
EDGEPROOF_NO_UPDATE_CHECK |
(unset) |
Set to 1 to disable the daily version check |
Tunable Settings (generated)
The table below is generated from the settings registry by edgeproof configure docs. Do not edit it by hand.
LLM / model
| Variable |
Default |
Description |
LLM_PROVIDER |
ollama |
LLM provider mode. |
LLM_MODEL |
(empty) |
Model name the extractor calls (openai-compatible path). |
LLM_API_BASE_URL |
https://api.openai.com/v1 |
Base URL for the OpenAI-compatible endpoint. |
LLM_API_KEY |
(empty) |
API key for the hosted endpoint. |
LMSTUDIO_TIMEOUT_MS |
180000 |
Per-completion timeout for a local LM Studio server. |
Trading limits
| Variable |
Default |
Description |
TRADING_POSITION_SIZE_USD |
500 |
Dollar budget per position. |
TRADING_MAX_OPEN_POSITIONS |
10 |
Cap on concurrent open positions. |
TRADING_HARD_CAP_PCT |
0.10 |
Skip a buy if market price is already this fraction above the alert (0.10 = +10%). |
TRADING_MAX_CONTRACTS_PER_UNDERLYING |
2 |
Cap on contracts held per underlying symbol. |
TRADING_ALLOW_0DTE |
false |
Allow same-day-expiry options. |
TRADING_ALLOW_LOTTOS |
false |
Allow low-cost long-shot options flagged as lottos. |
TRADING_DAILY_LOSS_LIMIT_USD |
0 |
Halt new entries when intraday P/L drops below this dollar amount. 0 = disabled. |
TRADING_SOURCE_WEIGHTING_ENABLED |
false |
Scale position size by source win rate (requires ≥ min trips of history). |
TRADING_SOURCE_WEIGHTING_MIN_TRIPS |
10 |
Minimum closed round trips before win-rate sizing applies to a source. |
Exit rules
| Variable |
Default |
Description |
POSITION_TAKE_PROFIT_PCT |
75 |
Take-profit target, percent gain. |
POSITION_STOP_LOSS_PCT |
-50 |
Stop-loss threshold, percent (negative). |
POSITION_TRAILING_STOP_PCT |
40 |
Trailing-stop giveback, percent from peak. |
POSITION_TRAILING_STOP_ACTIVATION_PCT |
30 |
Gain at which the trailing stop activates. |
TRADING_FOLLOW_CHANNEL_EXITS |
false |
Let a channel's own exit calls close or trim the positions it opened. Your take-profit/stop still apply to what remains. |
TRADING_VAGUE_TRIM_FRACTION |
0 |
Fraction sold when a followed channel trims without stating a size ("taking a trim here"). 0 = notify only, never execute. Applies to sizeless trims only; runners calls still sell down to the runner count. |
TRADING_RUNNER_CONTRACTS |
1 |
Contracts kept when a followed channel goes to runners ("leave a few to run"). 0 = close fully on a runners call. |
TRADING_EXIT_CHASE_PCT |
0.10 |
Withhold an author-priced exit when the bid is this fraction below the author's stated exit price; stops are tightened instead. 0 = guard off. |
TRADING_SOURCE_EXIT_CALIBRATION |
false |
Tighten trailing stops per source toward where that source's winners actually exit (from your ledger history). Tighten-only; needs min closed trips. |
Discord channels
| Variable |
Default |
Description |
DISCORD_CHANNEL_URLS |
(empty) |
Comma-separated channel URLs (puppeteer mode). |
DISCORD_CHANNEL_NAMES |
(empty) |
Comma-separated channelId:label pairs for leaderboard attribution. |
Notifications
| Variable |
Default |
Description |
TELEGRAM_BOT_TOKEN |
(empty) |
Telegram bot token for trade notifications. |
TELEGRAM_CHAT_ID |
(empty) |
Telegram chat ID to notify. |
Privacy
| Variable |
Default |
Description |
EDGEPROOF_TELEMETRY |
false |
Opt in to sending version, uptime and open-position counts so silent failures are visible. Never includes trading data. Run edgeproof telemetry --show to see the exact payload. |