waitForFill now polls 60 times at 2s intervals (2 min total) instead
of 30x1s, and uses retry on the getOrder calls. The strategy wraps
the hold loop in try/finally so if anything fails after a buy, we
still sell the position instead of leaving it orphaned.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wraps all Alpaca API calls with automatic retries (up to 3 attempts
with increasing backoff) for transient errors like ECONNRESET, socket
hang up, ETIMEDOUT, and 429/502/503/504 responses. Non-transient
errors like 422 or auth failures are thrown immediately.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The buy order can return before filling, giving null price/qty. Now
buy polls getOrder until filled. Sell takes the actual qty from the
buy fill instead of the original dollar amount, which avoids the
"insufficient qty" error when the price moves between buy and sell.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
macOS sleep suspends the Docker VM, causing long setTimeout calls to
never fire. Replace the one-shot wait with a polling loop that checks
getClock every 30s (capped to time-until-open), so the bot resumes
promptly after the host wakes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Covers the two remaining uncovered lines: getAssets returning all
symbols from bar data, and createOrder throwing on unknown symbols.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
A failed trading cycle (e.g. sell rejected after close) previously
propagated to the top-level .catch() and process.exit(0), killing
the container permanently. Now errors are caught per-iteration so
the bot sleeps and retries on the next cycle.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevents sell orders from being rejected after market close by fetching
the market clock after entry and capping the hold deadline to next_close
minus a 2-minute buffer.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduces a BacktestClient that replays historical 1-min bars against the
existing strategy code, plus a CLI entry point (npm run backtest) that fetches
bars from Alpaca and runs the bot over a date range. Makes wait() pluggable
so the backtest resolves delays instantly while advancing simulated time.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduce logger infrastructure and add structured logging to every layer:
alpaca.ts (buy/sell/quote/clock), momentum-indicator.ts (evaluate flow),
momentum-strategy.ts (poll loop), index.ts (startup/cycle), and trading.ts
(market timing). Replace raw console.log calls with leveled logger. Update
all tests with appropriate console spies.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the Executor logging placeholder with real buy/sell methods on
the Alpaca class that place market orders via createOrder and return the
fill price. Strategies now receive their capital amount directly and
place orders themselves. Bot accepts StrategyAllocation[] to decouple
capital allocation from strategy definition.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements MomentumIndicator (samples QQQ direction) and
MomentumStrategy (buys TQQQ on up, SQQQ on down, exits at
+1% target or 1hr timeout). Wired into Bot via index.ts.
Also fixes vitest config to exclude dist/ from test discovery.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove node_modules/ and tsconfig.tsbuildinfo from git tracking
(both already in .gitignore). Add vitest.config.js which was
missing from version control.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Bot validates strategy capital allocations, waits for market open,
runs all strategies concurrently, and passes signals to the executor.
The main loop in index.ts now delegates to Bot.runDay().
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Executor receives strategy signals and calculates dollar amounts
from capital allocations. Currently logs intended trades rather than
placing real orders.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Introduce the typed interfaces that form the foundation of the
strategy framework: Indicator<T> for market analysis and Strategy
with Signal types for trading decisions.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move API keys from hardcoded values to .env via dotenv
- Extract business logic into src/trading.ts with dependency injection
- Add typed AlpacaClient interface, replace `any` on Alpaca class
- Add Vitest test suites for trading logic and Alpaca wrapper (14 tests)
- Set up ESLint with @typescript-eslint for linting
- Fix getAsset to pass symbol string directly to SDK
- Fix typo (alpacha -> alpaca), remove unused ws/node-fetch deps
- Update .gitignore for node_modules and .env
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>