The Problem
LuxAlgo produces great signals in TradingView, but executing them manually means missing entries while away, emotional decisions overriding signals, and inconsistent position sizing.
The Solution
A Python system that receives TradingView webhook alerts and automatically executes bracket orders through Alpaca. Built as a complete, production-ready system in 1,721 lines of code.
Architecture
TradingView (LuxAlgo) -> Webhook -> Receiver -> Trade Manager -> Alpaca Paper
+-------------------------------------------------------------+
| TradingView |
| (LuxAlgo indicator + alerts) |
+---------------------------+---------------------------------+
| Webhook
+---------------------------v---------------------------------+
| WebSocket Receiver (Flask) |
| (Validates, parses signals) |
+---------------------------+---------------------------------+
|
+---------------------------v---------------------------------+
| Trade Manager |
| +-------------+ +--------------+ +-----------------+ |
| | Entry | | Trailing | | EOD Close | |
| | Logic | | Stops | | (Time-based) | |
| +-------------+ +--------------+ +-----------------+ |
+---------------------------+---------------------------------+
|
+---------------------------v---------------------------------+
| Alpaca API |
| (Bracket orders + position tracking) |
+-------------------------------------------------------------+
Core Components
| Component | Lines | Purpose |
|---|---|---|
| receiver.py | 240 | Flask server receiving TradingView alerts |
| trade_manager.py | 366 | Signal processing, position sizing, trade lifecycle |
| executor.py | 310 | Order execution with bracket orders |
| position_manager.py | 492 | Trailing stops, partial exits, EOD close |
LuxAlgo Signal Parsing
The webhook receiver parses LuxAlgo JSON alert format:
- Signal types: Bullish, Bullish+, Bearish, Bearish+ (+ variants = stronger signals)
- Price data: Full OHLCV from TradingView
- Risk levels: sl1/sl2 (stop losses), tp1/tp2 (take profit targets)
- Smart trail: LuxAlgo dynamic trailing stop level
- Fallback: Text-based parsing for non-JSON alerts
Marketable Limit Orders
Rather than market orders, the system uses marketable limits – limit orders priced through the market:
- Buys: Limit at ask + $0.05 offset
- Sells: Limit at bid – $0.05 offset
Ensures fills while avoiding unfavorable slippage.
Risk-Based Position Sizing
risk_dollars = account_value * 0.02 # 2% risk per trade qty = risk_dollars / abs(entry - stop) qty = min(qty, max_position_value / entry) # Cap at $10k per trade
Trailing Stop Modes
The Position Manager runs in a background thread with multiple trailing stop styles:
| Style | Description |
|---|---|
| FIXED_PERCENT | Trail by fixed % (default 1%) |
| FIXED_AMOUNT | Trail by fixed $ amount |
| ATR_BASED | Trail by ATR multiple (adapts to volatility) |
| SMART_TRAIL | Use LuxAlgo dynamic level |
Activation logic:
- Trailing only activates after 0.5% profit
- Breakeven lock when trailing activates
- Stops only move in favorable direction (ratchet)
Stop modification: Alpaca does not support direct bracket leg modification, so the system uses cancel-and-replace:
def modify_stop_order(self, order_id, new_stop_price):
self.trading_client.cancel_order_by_id(order_id)
new_order = StopOrderRequest(...)
return self.trading_client.submit_order(new_order)
Partial Profit Taking
Configured partial exits at LuxAlgo targets:
- 50% of position exits at tp1
- 25% of position exits at tp2
- Remaining 25% rides with trailing stop
Time-Based Exits
- EOD Close: All positions closed at 3:55 PM ET
- Trade cutoff: No new trades after 3:30 PM ET
- Weekday-only logic (skips weekends)
Discovery Mode
The receiver can run in discovery mode (without –execute flag) to log and save all incoming alerts for analysis before enabling live trading. Each alert saved with timestamp, headers, and parsed data.
TradingView Webhook Setup
{
"alert": "{default}",
"ticker": "{ticker}",
"tf": "{tf}",
"ohlcv": {"open": {open}, "high": {high}, "low": {low}, "close": {close}, "volume": {volume}},
"bartime": {time},
"tp1": {tp1}, "tp2": {tp2},
"sl1": {sl1}, "sl2": {sl2},
"smart_trail": {smart_trail}
}
State Persistence
Trade state persists to disk (trade_state.json):
- Current open trade with all details
- Last 100 historical trades
- Survives restarts