Tradier returns total_equity 0.0 during its overnight maintenance window -- sixteen times in the last fourteen days, all around 01:06. Three defects compounded so that a zero could size a position off default_equity: account_equity = equity or config.default_equity `or` cannot tell "not supplied" from "read as zero", so a real 0.0 became 100000. Then the position-value cap, derived from the same equity, was itself 0 -- and the guard if max_position_value is not None and max_position_value > 0: SKIPPED the cap precisely when the cap said "no room". Finally the auto path (~96% of approval requests) had no `pos_cap <= 0` early-out, unlike the manual path at request_entry_approval. Net effect on a ~$250 account: risk 5% of 100k = $5,000, capped only by liquidity. The broker would have rejected it for buying power, which is luck rather than design. Never fired in live hours -- every zero read landed with the market closed, and _current_equity caches the last good value -- so this is latent, not a realised loss. The reachable path is a boot that coincides with the maintenance window, when no good read has been cached yet. Distinguish None from zero, refuse to size on non-positive equity, treat a zero cap as "no room" rather than "no cap", and mirror the manual path's early-out. TRADING_DEFAULT_EQUITY is set to 300 on the live stack so even the untested fallback cannot oversize. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A2LepdJfPCfK5Q8uznjFBM
103 lines
4.1 KiB
Bash
103 lines
4.1 KiB
Bash
# Seed for /app/data/overrides.env on the LIVE stack — the admin panel
|
|
# (port 8867.. n/a on live; edit via file or add admin service) manages this.
|
|
# Every service loads it at boot; overrides BEAT compose env.
|
|
|
|
ALPACA_DATA_FEED=sip
|
|
DISCOVER_INTERVAL_SECONDS=120
|
|
DISCOVER_THREAD_ENABLED=1
|
|
LIVE_BARS_INTERVAL_SECONDS=5
|
|
LIVE_BARS_REFRESH_MINUTES=20
|
|
NEWS_CATALYST_SCORE_ENABLED=1
|
|
NEWS_DILUTION_VETO_ENABLED=1
|
|
NEWS_ENRICH_BATCH_LIMIT=50
|
|
NEWS_ENRICH_ENABLED=1
|
|
NEWS_ENRICH_INTERVAL_SECONDS=120
|
|
NEWS_ENRICH_LOOKBACK_HOURS=12
|
|
NEWS_FEEDS=prnewswire=https://www.prnewswire.com/rss/news-releases-list.rss,businesswire=https://feed.businesswire.com/rss/home/?rss=G1QFDERJXkJeGVtRWQ==,globenewswire=https://www.globenewswire.com/RssFeed/orgclass/1/feedTitle/GlobeNewswire%20-%20News%20about%20Public%20Companies
|
|
NEWS_LOOKBACK_HOURS=8
|
|
NEWS_RANK_BOOST=2.0
|
|
# Ollama lives on 11434 (the standard port). The stack pointed at 30068/4000 with
|
|
# a model that was never pulled, so catalyst enrichment produced nothing from
|
|
# 2026-08-03 to 2026-09-13 — silently, because enrich_recent_news reports failure
|
|
# in its return value rather than raising. Smoke-tested 2026-09-13: tools:latest
|
|
# parses 8/8 headlines in ~2.8s each and classifies offering_dilution / fda_approval
|
|
# correctly. Verify the model is pulled before changing either line.
|
|
OLLAMA_ENABLED=true
|
|
OLLAMA_HOST=http://192.168.1.5:11434
|
|
OLLAMA_MODEL=tools:latest
|
|
OLLAMA_TEMPERATURE=0.1
|
|
OLLAMA_TIMEOUT_SECONDS=60
|
|
TRADING_AUTO_APPROVE=1
|
|
TRADING_BACKOUT_COOLDOWN_SECONDS=180
|
|
TRADING_BLOCK_REENTRY_AFTER_EXIT=1
|
|
TRADING_ENTRY_CONFIRM_BY_MINUTE=0
|
|
TRADING_ENTRY_FILL_MODEL=marketable
|
|
TRADING_ENTRY_INVALIDATE_PCT=0.015
|
|
TRADING_ENTRY_ORDER_TYPE=limit
|
|
TRADING_ENTRY_TIMEOUT_BARS=2
|
|
TRADING_EOD_FLATTEN_ENABLED=1
|
|
TRADING_EOD_FLATTEN_TIME=15:55
|
|
TRADING_EXECUTION_ENABLED=1
|
|
# EXIT MANAGEMENT — retuned 2026-09-13. The previous config stacked FOUR
|
|
# independent ratchets (BE@+5% from the env default, step-trail every 0.25R,
|
|
# prior-low trail, and profit-lock tiers). Together they capped every winner at
|
|
# ~1R: over 62 live + 172 paper trades the bot kept only 9.3% of the move on
|
|
# trades that ran >=20%, and held winners a median 10 min vs 19 min for losers.
|
|
# Replaced with a single percentage giveback that starts only after +1R. The
|
|
# 8/12/15/20% neighbourhood all beat the old config on BOTH stacks in BOTH
|
|
# train and test splits (mean R 0.20-0.25 vs 0.125), so 12% is a plateau pick,
|
|
# not a fitted one. Re-sweep with sweep_exits.py before changing.
|
|
TRADING_EXIT_BREAKEVEN_R=1.0
|
|
TRADING_EXIT_BREAKEVEN_PCT=0.0
|
|
TRADING_EXIT_MANAGE_INTERVAL_SECONDS=4
|
|
TRADING_EXIT_PROFIT_TIERS=
|
|
TRADING_EXIT_THREAD_ENABLED=1
|
|
TRADING_EXIT_THREAD_INTERVAL_SECONDS=1.0
|
|
TRADING_EXIT_TRAIL_AFTER_R=1.0
|
|
TRADING_EXIT_TRAIL_MODE=pct
|
|
TRADING_EXIT_TRAIL_PCT=0.12
|
|
TRADING_EXIT_TRAIL_R_STEP=0.0
|
|
TRADING_LIQUIDITY_MAX_VOLUME_PCT=0.025
|
|
TRADING_MAX_BACKOUTS_PER_SYMBOL=3
|
|
TRADING_MAX_CONCURRENT_POSITIONS=10
|
|
TRADING_MAX_DAILY_LOSS_PCT=0.05
|
|
TRADING_MAX_FRESH_ENTRIES_PER_DAY=10
|
|
TRADING_MAX_GROSS_NOTIONAL_PCT=0.60
|
|
TRADING_MAX_ORDERS_PER_TICK=1
|
|
TRADING_MAX_POSITION_PCT=0.16
|
|
# Boot-time sizing fallback. calculate_position_size falls back to this only when
|
|
# equity was never readable; at the old 100000 a boot inside Tradier's ~01:06
|
|
# maintenance window (equity reads 0.0 there — 16 times in 14 days) would have
|
|
# sized 5% of 100k on a ~$250 account. Keep it near real account size.
|
|
TRADING_DEFAULT_EQUITY=300
|
|
TRADING_MAX_RISK_DOLLARS=50000
|
|
TRADING_MIN_DAY_VOLUME=300000
|
|
TRADING_MIN_ENTRY_GAP_PCT=0.10
|
|
TRADING_MIN_QUALITY_SCORE=0.60
|
|
TRADING_PRICE_MAX=20.0
|
|
TRADING_PRICE_MIN=2.0
|
|
TRADING_REENTRY_MIN_LOSS_PCT=0.01
|
|
TRADING_REGIME_GATE_ENABLED=0
|
|
TRADING_REGIME_GATE_P_MIN=0.5
|
|
TRADING_REQUIRE_ABOVE_VWAP=1
|
|
TRADING_REWARD_MULTIPLE=10.0
|
|
TRADING_RISK_PER_TRADE_PCT=0.05
|
|
TRADING_SESSION_ONLY=1
|
|
TRADING_TRIGGER_SLIP_PCT=0.004
|
|
TRADING_UNIFIED_ENTRY=1
|
|
TRIGGER_ARM_INTERVAL_SECONDS=8
|
|
TRIGGER_ENABLED=1
|
|
TRIGGER_GAP_MAX=35
|
|
TRIGGER_GAP_MIN=10.0
|
|
TRIGGER_GAP_SQUEEZE_MIN=150
|
|
TRIGGER_GAP_SQUEEZE_RVOL=5.0
|
|
TRIGGER_INTERVAL_SECONDS=2
|
|
TRIGGER_MAX_ARMED=10
|
|
TRIGGER_MIN_DOLLAR_VOL=8000
|
|
TRIGGER_PRICE_MAX_AGE=12
|
|
TRIGGER_RVOL_MIN=2.0
|
|
WATCHER_ENABLED=1
|
|
WATCHER_INTERVAL_SECONDS=8
|
|
WATCHER_PRICE_MAX=20
|
|
WATCHER_PRICE_MIN=2
|