Files
momentum-system/deploy/docker/overrides.live.seed.env
T
momentum devandClaude Opus 5 9034839661 fix: a zero equity reading sized off the $100k default
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
2026-09-13 13:34:53 -05:00

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