A Python-based algorithmic trading bot for US stocks (NYSE/NASDAQ) via the Alpaca brokerage API.
EMA + RSI + MACD + Bollinger Bands — multi-indicator confluence:
| Indicator | Role |
|---|---|
| EMA 9 / 21 | Fast trend direction & crossover entry/exit signals |
| EMA 50 | Long-term trend filter (only trade in uptrends) |
| RSI 14 | Momentum filter — avoid overbought entries (40–65 zone) |
| MACD (12/26/9) | Momentum confirmation — histogram turning positive |
| Bollinger Bands (20, 2σ) | Volatility context — price position within bands |
| ATR 14 | Volatility-adjusted position sizing & stop-loss distance |
All conditions are scored (0–100). A score ≥ 60 triggers a buy:
- Price above 50-EMA (macro uptrend)
- Fast EMA above or crossing above slow EMA
- RSI between 40 and 65
- MACD histogram positive or turning positive
- Price below upper Bollinger Band
- Stop-loss: 1× ATR below entry price (broker bracket order)
- Take-profit: 3× ATR above entry price (3:1 reward/risk)
- Signal exit: SELL score ≥ 60 (EMA death cross, overbought RSI, etc.)
| Parameter | Default | Description |
|---|---|---|
| Max position size | 5% of equity | Per stock |
| Stop-loss | 1× ATR (≈ 2%) | Per trade |
| Take-profit | 3× ATR (≈ 6%) | 3:1 R:R ratio |
| Max open positions | 10 | Concurrent |
| Daily loss limit | 5% | Halts trading for the day |
| Profit reinvestment | 100% | Full compounding |
stox/
├── main.py # Bot entry point / scheduler
├── config.py # All settings (reads from .env)
├── requirements.txt
├── .env.example # Copy to .env and add your keys
│
├── data/
│ └── fetcher.py # Alpaca market data (OHLCV bars)
│
├── analysis/
│ ├── indicators.py # EMA, RSI, MACD, Bollinger Bands, ATR
│ └── signals.py # BUY/SELL/HOLD signal scoring engine
│
├── strategy/
│ ├── base_strategy.py # Abstract base class
│ └── ema_rsi_macd.py # Main strategy implementation
│
├── trading/
│ ├── alpaca_client.py # Alpaca broker API wrapper
│ ├── risk_manager.py # Position sizing, daily loss limits
│ └── portfolio.py # Trade tracking & performance metrics
│
├── backtest/
│ ├── engine.py # Bar-by-bar backtesting engine
│ └── run_backtest.py # CLI backtest runner
│
└── utils/
└── logger.py # Logging (console + daily file)
pip install -r requirements.txtcp .env.example .env
# Edit .env — add your Alpaca API key and secretGet free API keys at alpaca.markets (paper trading is free).
# Backtest 10 stocks with 500 days of history
python backtest/run_backtest.py AAPL MSFT NVDA GOOGL AMZN --days 500
# Backtest entire watchlist
python backtest/run_backtest.pyEnsure ALPACA_MODE=paper in your .env, then:
python main.pypython main.py --dry-runSet ALPACA_MODE=live in .env and run:
python main.pyWarning: Only switch to live mode after validating the strategy with paper trading for at least 30 days.
With conservative compounding:
- All profits are reinvested — position sizes grow as equity grows
- 3:1 reward/risk means you can lose 3 out of 4 trades and still break even
- Daily loss limit protects capital during adverse market conditions
- ATR-based sizing automatically reduces position sizes in volatile markets
The default watchlist contains 45 large-cap S&P 500 stocks. Customise via Config.WATCHLIST in config.py or set in .env.
- Console: real-time output
- File:
logs/YYYY-MM-DD.log(daily rotation) - Portfolio:
logs/portfolio.json(persisted trade history)