Skip to content

Add same-day TSLA intraday strategy (tsladay profile) - #10

Merged
utkarshp845 merged 1 commit into
masterfrom
claude/trading-bot-version-error-dd1a9b
Aug 5, 2026
Merged

Add same-day TSLA intraday strategy (tsladay profile)#10
utkarshp845 merged 1 commit into
masterfrom
claude/trading-bot-version-error-dd1a9b

Conversation

@utkarshp845

Copy link
Copy Markdown
Owner

New market profile alongside the existing swing config: config/paper_tsladay.env and config/live_tsladay.env (bot/profile.py market "tsladay"), wired into docker-compose.yml (trade-tsladay/paper-tsladay/paper-tsladay-monitor).

This is a deliberately different strategy from the spy-market swing config (~1 trade/5-6 weeks, multi-day holds), built because that config doesn't capture TSLA's frequent intraday swings by design:

  • Bidirectional (ALLOW_SHORTS=true): a position that's always flat by close carries no overnight gap risk, so shorting TSLA's down-legs is as safe as going long its up-legs, and backtests about as profitable (short side actually outperformed: $16.29/30 trades vs long $8.58/25).
  • Capped at MAX_TRADES_PER_DAY=1: the account is $150 in a cash account, so more than ~1 buy+sell cycle/day risks reusing unsettled (T+1) proceeds and tripping a good-faith violation. This is an account-mechanics constraint the strategy is designed around, not a signal-quality choice.
  • 15m bars, 2h intraday regime gate (vs the swing config's daily-EMA gate), 09:45-15:30 ET entry window, FLATTEN_BEFORE_CLOSE_MINUTES=15.

Backtest: bot/optimize_strategy.py walk-forward grid search fed 15m TSLA bars via yfinance (no Alpaca keys available outside EC2; free intraday history caps at ~60 trading days, so this is a much thinner, single-regime validation than the swing config's 2.9yr one - flagged throughout). Shipped config (65%/70% target/max notional, trimmed down from what the 60-day backtest could have supported as a margin of safety): 55 trades, win rate 53%, PF 2.01 (1.99 under 2x slippage), net +$20.01 (+13.3%) on $150, max drawdown 3.7%, positive in 3 of 4 walk-forward test windows. Full methodology, sizing sweep, and caveats: docs/strategy_tsla_day_2026-08.md.

Also fixes a replay/live parity gap this surfaced: bot/research.py::run_replay never simulated ALLOW_OVERNIGHT_HOLDING=false / FLATTEN_BEFORE_CLOSE_MINUTES (only the live loop did, via bot/trade_controls.py::evaluate_session_exit) - every prior backtest had overnight holding enabled so it never mattered. run_replay now calls evaluate_session_exit every bar a position is open. Regression tests in tests/test_research_replay.py. Also made two optimizer knobs configurable that were previously hardcoded for swing-style signals (bot/optimize_strategy.py): ALLOW_SHORTS as a grid dimension (OPT_ALLOW_SHORTS_VALUES) and the trades/day acceptance band (OPT_SCORE_MIN/MAX_TRADES_PER_DAY, OPT_ACCEPT_MIN/MAX_TRADES_PER_DAY) - both default to prior behavior, no change for existing configs.

Recommendation: paper only (paper-tsladay) for a real stretch across different market conditions before ever considering live capital, per the doc.

New market profile alongside the existing swing config: config/paper_tsladay.env
and config/live_tsladay.env (bot/profile.py market "tsladay"), wired into
docker-compose.yml (trade-tsladay/paper-tsladay/paper-tsladay-monitor).

This is a deliberately different strategy from the spy-market swing config
(~1 trade/5-6 weeks, multi-day holds), built because that config doesn't
capture TSLA's frequent intraday swings by design:

- Bidirectional (ALLOW_SHORTS=true): a position that's always flat by close
  carries no overnight gap risk, so shorting TSLA's down-legs is as safe as
  going long its up-legs, and backtests about as profitable (short side
  actually outperformed: $16.29/30 trades vs long $8.58/25).
- Capped at MAX_TRADES_PER_DAY=1: the account is $150 in a cash account, so
  more than ~1 buy+sell cycle/day risks reusing unsettled (T+1) proceeds and
  tripping a good-faith violation. This is an account-mechanics constraint
  the strategy is designed around, not a signal-quality choice.
- 15m bars, 2h intraday regime gate (vs the swing config's daily-EMA gate),
  09:45-15:30 ET entry window, FLATTEN_BEFORE_CLOSE_MINUTES=15.

Backtest: bot/optimize_strategy.py walk-forward grid search fed 15m TSLA
bars via yfinance (no Alpaca keys available outside EC2; free intraday
history caps at ~60 trading days, so this is a much thinner, single-regime
validation than the swing config's 2.9yr one - flagged throughout). Shipped
config (65%/70% target/max notional, trimmed down from what the 60-day
backtest could have supported as a margin of safety): 55 trades, win rate
53%, PF 2.01 (1.99 under 2x slippage), net +$20.01 (+13.3%) on $150, max
drawdown 3.7%, positive in 3 of 4 walk-forward test windows. Full
methodology, sizing sweep, and caveats: docs/strategy_tsla_day_2026-08.md.

Also fixes a replay/live parity gap this surfaced: bot/research.py::run_replay
never simulated ALLOW_OVERNIGHT_HOLDING=false / FLATTEN_BEFORE_CLOSE_MINUTES
(only the live loop did, via bot/trade_controls.py::evaluate_session_exit) -
every prior backtest had overnight holding enabled so it never mattered.
run_replay now calls evaluate_session_exit every bar a position is open.
Regression tests in tests/test_research_replay.py. Also made two optimizer
knobs configurable that were previously hardcoded for swing-style signals
(bot/optimize_strategy.py): ALLOW_SHORTS as a grid dimension
(OPT_ALLOW_SHORTS_VALUES) and the trades/day acceptance band
(OPT_SCORE_MIN/MAX_TRADES_PER_DAY, OPT_ACCEPT_MIN/MAX_TRADES_PER_DAY) -
both default to prior behavior, no change for existing configs.

Recommendation: paper only (paper-tsladay) for a real stretch across
different market conditions before ever considering live capital, per the
doc.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@utkarshp845
utkarshp845 merged commit 10de62a into master Aug 5, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant