Overview
The SL/TP Watcher is an automated monitoring system that continuously tracks Stop Loss (SL) and Take Profit (TP) orders for all active trading positions. It ensures your risk management orders are properly executed and handles edge cases where orders might fail.
Purpose
The watcher's main responsibilities:
- π Monitor SL/TP order statuses every 20 seconds
- β Process filled orders and close positions
- π¨ Handle rejected/cancelled orders with emergency actions
- π Update bot statistics and trading history
- π‘οΈ Protect your positions from slippage and missed exits
Order Placement Strategy
Initial Order Type: LIMIT (Post-Only)
When the bot places orders with Stop Loss and Take Profit, it prioritizes placing LIMIT orders with post_only = true for both SL and TP.
What is Post-Only?
- Post-only orders are maker orders that add liquidity to the order book
- They will never execute immediately as taker orders
- If they would match immediately, they are rejected instead of filled
- This ensures you always get maker fees (usually lower or even rebates)
Order Placement Priority:
- Place Main Entry Order (Market/Limit)
- Place LIMIT Take Profit (
post_only = true) β Preferred - Place LIMIT Stop Loss (
post_only = true) β Preferred - Watcher monitors all three orders continuously
LIMIT vs MARKET Orders: Deep Dive
LIMIT Orders (Post-Only = True)
How They Work:
- Order sits in the order book at your specified price
- Executes only when market price reaches your level
- You become a maker (adding liquidity)
- Order might not fill if price gaps through your level
β Pros of LIMIT SL/TP Orders
| Benefit | Description | Example |
|---|---|---|
| Lower Fees | Maker fees are typically 0.02% vs 0.05% taker fees | On $10,000 trade: Save $3 per order |
| Fee Rebates | Some exchanges give rebates to makers (negative fees) | Earn $2 per $10,000 trade instead of paying |
| Better Pricing | Guaranteed execution at your price or better | TP at $110 might fill at $110.50 |
| No Slippage | Exact price execution, no worse fills | You get exactly what you set |
| Reduced Costs | Lower cumulative fees over hundreds of trades | Save $300-500 monthly on active trading |
| Profit Optimization | Every dollar saved in fees = more net profit | 3% annual return boost from fee savings |
Real-World Impact:
Scenario: 100 trades per month, $5,000 average position
MARKET Orders:
- Entry: 0.05% = $2.50
- TP: 0.05% = $2.50
- Total per trade: $5.00
- Monthly cost: $500
LIMIT Orders (Post-Only):
- Entry: 0.02% = $1.00
- TP: 0.02% = $1.00
- Total per trade: $2.00
- Monthly cost: $200
SAVINGS: $300/month or $3,600/year! π°
β Cons of LIMIT SL/TP Orders
| Risk | Description | Example |
|---|---|---|
| No Execution Guarantee | Order might not fill if price gaps through | SL at $95, price drops $100β$92 (skipped) |
| Missed Exits | In volatile moves, your order may be bypassed | Fast pump/dump leaves your TP unfilled |
| Post-Only Rejection | Rejected if would execute immediately | Market at $109.99, TP at $110 = rejected |
| Slippage on Miss | If unfilled, later exit at worse price | Missed TP at $110, forced exit at $108 |
| Gap Risk | Price gaps overnight or during news | Weekend gap skips your stop loss |
| Requires Monitoring | Need watcher system to catch failures | Without watcher, manual intervention needed |
Critical Scenarios:
β Scenario 1: Stop Loss Missed (LONG)
- Entry: $100
- Stop Loss: $95 (LIMIT, post-only)
- Event: Flash crash $100 β $90 in seconds
- Result: SL order never filled, position still open at $90
- Loss: -$10 per unit instead of -$5
β Scenario 2: Take Profit Rejection (SHORT)
- Entry: $100
- Take Profit: $95 (LIMIT, post-only)
- Current: $95.10
- Event: Price hits $94.90, TP rejected (would execute immediately)
- Result: Profit target missed due to post-only requirement
MARKET Orders
How They Work:
- Execute immediately at best available price
- Match with existing orders in the book
- You become a taker (removing liquidity)
- Guaranteed execution (assuming liquidity)
β Pros of MARKET SL/TP Orders
| Benefit | Description |
|---|---|
| Guaranteed Execution | Always fills (if liquidity exists) |
| Immediate Action | No waiting in order book |
| Gap Protection | Catches you even in fast moves |
| Simplicity | No post-only rejection issues |
| Emergency Exits | Perfect for urgent situations |
β Cons of MARKET SL/TP Orders
| Risk | Description |
|---|---|
| Higher Fees | Taker fees typically 2.5x maker fees |
| Slippage | Might execute at worse price than expected |
| Reduced Profit | Fees eat into your gains |
| Flash Crashes | Can execute at terrible prices during low liquidity |
Why We Need the SL/TP Watcher
The Core Problem
While LIMIT orders offer significant cost benefits, they come with no execution guarantee. This creates risks:
Risk Matrix:
- Stop Loss Missed
- Position continues losing money
- Drawdown exceeds risk tolerance
- Account damage
- Take Profit Missed
- Price reverses after hitting target
- Profit opportunity lost
- Win becomes loss or smaller win
- Orders Rejected
- Post-only rejection when price is "too close"
- No protection while rejection is processed
- Exposure window
The Solution: Active Monitoring
The SL/TP Watcher bridges the gap between LIMIT order benefits and MARKET order safety:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β The Watcher's Role β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β 1. Start with LIMIT orders (lower fees) β
β
β β β
β 2. Monitor continuously (every 20s) ποΈ β
β β β
β 3. Detect problems (rejection/cancellation) π¨ β
β β β
β 4. Assess situation: β
β a) Price breached? β Emergency MARKET exit π¨ β
β b) Price still safe? β Replace with MARKET order π β
β β β
β 5. Update state and continue monitoring π β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Monitoring Scope
The watcher monitors orders when:
- Take Profit is set (TP > 0)
- Stop Loss is set (SL > 0)
- Order status is Active
What It Monitors:
- Main Order - The original entry order (to ensure it filled)
- TP Order - Take profit order status
- SL Order - Stop loss order status
Rejection Handling Strategy
Decision Tree for Rejected Orders
When a LIMIT (post-only) order is rejected, the watcher follows this logic:
Order Rejected (SL or TP)
|
β
Check Current Price
|
ββββββ΄βββββ
| |
β β
BREACHED STILL SAFE
| |
β β
EMERGENCY REPLACE
EXIT ORDER
| |
β β
MARKET MARKET
ORDER ORDER
(100%) (post_only=false)
Case 1: Force Sell (Price Breached)
When: Current position has already moved beyond SL/TP level
Stop Loss Example (LONG):
- Entry: $100
- SL Order: $95 (LIMIT, rejected)
- Current: $93 β οΈ BELOW STOP LOSS!
Action: π¨ IMMEDIATE MARKET SELL
- Cannot wait for new limit order
- Every second = more loss
- Execute market order NOW
- Close 100% of position
- Accept current price ($93)
- Calculate loss: -$7 per unit
Why: Price already through stop = emergency mode
Take Profit Example (SHORT):
- Entry: $100
- TP Order: $95 (LIMIT, rejected)
- Current: $94 β BELOW TAKE PROFIT!
Action: π― IMMEDIATE MARKET BUY
- Profit target already reached
- Risk of reversal if we wait
- Execute market order NOW
- Close 100% of position
- Lock in profit at ~$94
- Calculate gain: +$6 per unit
Why: Profit available NOW, might disappear
Case 2: Replace Order (Price Still Safe)
When: Current price hasn't reached SL/TP level yet
Stop Loss Example (LONG):
- Entry: $100
- SL Order: $95 (LIMIT, rejected - post-only issue)
- Current: $98 β STILL ABOVE STOP LOSS
Action: π REPLACE WITH MARKET ORDER
- Cancel rejected LIMIT order
- Place new SL order at $95
- Set
post_only = false(market order) - Update
order_idin state - Mark
sl_post_only = false - Continue monitoring
Why: Still safe, just need working order
Cost: Slightly higher fees when it triggers later
Benefit: Guaranteed execution when price hits $95
Take Profit Example (LONG):
- Entry: $100
- TP Order: $110 (LIMIT, rejected - post-only issue)
- Current: $105 β STILL BELOW TAKE PROFIT
Action: π REPLACE WITH MARKET ORDER
- Cancel rejected LIMIT order
- Place new TP order at $110
- Set
post_only = false(market order) - Update
order_idin state - Mark
tp_post_only = false - Continue monitoring
Why: Profit target not reached yet
Cost: Higher fee when TP hits (0.05% vs 0.02%)
Benefit: Won't miss the profit target
Trade-off: Pay 0.03% more fee vs risk missing entire TP
State Updates After Replacement
When replacing orders, the system updates:
// For Stop Loss replacement
tx.stop_loss_order_id = new_order_id;
tx.sl_post_only = false; // Now a market order
// For Take Profit replacement
tx.take_profit_order_id = new_order_id;
tx.tp_post_only = false; // Now a market order
// Save updated state
mgr.update_trade_bot(all_bots).await;
Hybrid Strategy: Best of Both Worlds
The bot's approach combines LIMIT and MARKET orders intelligently:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Optimal Order Strategy β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Phase 1: Initial Placement β
β β
Use LIMIT (post_only=true) for SL/TP β
β β Lower fees β
β β Better pricing β
β β Maker rebates β
β Phase 2: Active Monitoring (Watcher) β
β ποΈ Check status every 20 seconds β
β β Detect rejections β
β β Detect cancellations β
β β Verify execution β
β Phase 3: Problem Resolution β
β π If rejected but safe: β
β β Replace with MARKET order β
β β Slightly higher fee, but guaranteed execution β
β π¨ If rejected AND breached: β
β β Emergency MARKET exit immediately β
β β Accept current price to stop bleeding β
β Result: 90%+ trades use cheap LIMIT orders β
β 10%- trades escalate to MARKET orders β
β = Maximum fee savings with full protection β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Real-World Performance
Expected Outcome (100 trades):
LIMIT Orders Successfully Executed: 85-90 trades
- Low fees (0.02%)
- Good pricing
- Maker rebates
- Total fee cost: ~$170
MARKET Orders (Watcher Intervention): 10-15 trades
- Higher fees (0.05%)
- Guaranteed execution
- Safety ensured
- Total fee cost: ~$75
Combined: $245 total fees
Pure MARKET: $500 total fees
SAVINGS: $255 (51% reduction) π°
Plus: Zero missed stops, zero unprotected positions
How It Works
1. Monitoring Cycle
The watcher runs every 20 seconds and performs these steps:
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. Fetch all active bots with running orders β
β 2. Collect SL/TP order IDs to check β
β 3. Query exchange for order statuses β
β 4. Categorize orders (Active/Filled/Failed) β
β 5. Take appropriate actions β
β 6. Update bot states and save β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
2. Order Status Categories
| Status | Meaning | Action |
|---|---|---|
| New | Order placed, waiting in order book | β Continue monitoring |
| PartiallyFilled | Part of order executed | β Continue monitoring |
| Filled | Order completely executed | β Close position & update PnL |
| Canceled | Order cancelled by exchange/user | π¨ Emergency market exit |
| Rejected | Order rejected by exchange | π¨ Emergency market exit |
Key Features
Feature 1: Filled Order Processing
When an SL or TP order is filled:
β
Order Filled β Close Position (100%)
β
Calculate Realized PnL
β
Update Transaction Status
β
Move from Running β Completed Orders
β
Update Bot Statistics
β
Save State
What gets updated:
- Transaction status: Win or Loss
- Realized PnL calculated
- Close reason: "Stop Loss Hit" or "Take Profit Hit"
- Bot statistics: Total trades, win rate, profits/losses
- Running orders cleared if position fully closed
Feature 2: Emergency Exit Logic
When an SL or TP order is rejected or cancelled, the watcher automatically handles it:
Scenario A: Price Already Breached
If the current price has moved beyond the SL/TP level:
Stop Loss Example (Long Position):
- Entry: $100
- SL Order: $95 (REJECTED)
- Current Price: $94 β οΈ Already below SL!
Action: π¨ IMMEDIATE MARKET EXIT
- Places market sell order instantly
- Prevents further losses
- Calculates PnL at current price
- Closes position completely
Take Profit Example (Long Position):
- Entry: $100
- TP Order: $110 (REJECTED)
- Current Price: $112 β Already above TP!
Action: π― IMMEDIATE MARKET EXIT
- Places market sell order instantly
- Captures the profit
- Calculates PnL at current price
- Closes position completely
Scenario B: Price Still Valid
If the current price hasn't breached the SL/TP level yet:
Stop Loss Example (Long Position):
- Entry: $100
- SL Order: $95 (REJECTED)
- Current Price: $98 β Still above SL
Action: π REPLACE WITH MARKET ORDER
- Places new SL order (non-post-only)
- Uses same price: $95
- Marks as market order
- Continues monitoring
Logic:
- Post-only orders might get rejected if they would execute immediately
- Replacing with market orders ensures they execute when triggered
- No slippage risk since price hasn't reached target yet
Decision Logic
Stop Loss Force Exit
For LONG positions:
if current_price <= stop_loss_price:
β Emergency market exit (price breached)
else if current_price > stop_loss_price:
β Replace with market SL order (still safe)
For SHORT positions:
if current_price >= stop_loss_price:
β Emergency market exit (price breached)
else if current_price < stop_loss_price:
β Replace with market SL order (still safe)
Take Profit Force Exit
For LONG positions:
if current_price >= take_profit_price:
β Emergency market exit (profit target reached)
else if current_price < take_profit_price:
β Replace with market TP order (not there yet)
For SHORT positions:
if current_price <= take_profit_price:
β Emergency market exit (profit target reached)
else if current_price > take_profit_price:
β Replace with market TP order (not there yet)
Statistics & Tracking
The watcher maintains these statistics for each bot:
| Metric | Description |
|---|---|
| Total Trades | Count of all completed trades |
| Profitable Trades | Count of winning trades |
| Losing Trades | Count of losing trades |
| Win Rate | Percentage of winning trades |
| Total Profit | Sum of all positive PnL |
| Total Loss | Sum of all negative PnL |
| Net PnL | Total Profit - Total Loss |
Update Timing:
- Statistics updated immediately when position closes
- All bots updated in a single batch operation
- Efficient state management prevents race conditions
Logging & Monitoring
Log Messages Guide
Info Messages (β Green/Normal):
- β Order Filled [order_123] on BTCUSDT
- β Successfully closed position for BTCUSDT (Stop Loss Hit)
- β All trade bots state updated successfully
Warning Messages (β οΈ Yellow):
- β οΈ Failed to fetch SL order [order_456] status for ETHUSDT
- β οΈ Close operation returned false for BNBUSDT
- β οΈ Replacement SL returned None for ADAUSDT
Critical Messages (π¨ Red):
- π¨ SL Order Cancelled/Rejected [order_789] on SOLUSDT β Requires force exit
- π¨ SL REJECTED & BREACHED: Current 94 <= SL 95 - IMMEDIATE MARKET EXIT
- β CRITICAL: Force SL Market Order Failed for DOTUSDT
Summary Messages (π):
- π Order Status Summary: 5 active, 2 filled, 1 cancelled/rejected
- π Bot stats updated: BTCUSDT | Win Rate: 65.50% | Total PnL: 1250.45
Configuration
Performance Settings
// Monitoring interval
const CHECK_INTERVAL: Duration = Duration::from_secs(20);
// Concurrent API calls limit
const MAX_CONCURRENT_CHECKS: usize = 10;
// Delay between batches (API rate limiting)
const BATCH_DELAY: Duration = Duration::from_millis(100);
Demo Mode
When demo_mode = true:
- β Watcher is disabled (skipped entirely)
- Reason: Demo mode doesn't place real exchange orders
- Demo orders are handled differently in the system
Best Practices
1. Monitor Logs Regularly
- Watch for rejected/cancelled order patterns
- Investigate if you see frequent force exits
- Check win rate and PnL trends
2. Exchange Configuration
- Ensure API keys have order query permissions
- Configure rate limits appropriately
- Use market orders for SL/TP (not post-only) if experiencing rejections
3. Risk Management
- The watcher is a safety net, not a replacement for good strategy
- Always set appropriate SL/TP levels
- Monitor position sizes and leverage
4. System Health
- Watch for "still running" warnings (indicates watcher taking >20s)
- Ensure stable network connection
- Monitor exchange API status
Troubleshooting
Issue: "Skipping: SL/TP Order Status Tracker still running"
Cause: Previous watcher cycle hasn't completed
Solution:
- Check network latency to exchange
- Reduce number of concurrent positions
- Increase check interval if needed
Issue: Frequent "Order Rejected" messages
Cause: Post-only orders being rejected
Solution:
- Watcher automatically replaces with market orders
- Consider using market orders by default for SL/TP
- Check exchange-specific order rules
Issue: "Failed to update all trade bots"
Cause: Database/state manager error
Solution:
- Check database connectivity
- Review error logs for specific failure
- Ensure state manager is properly initialized
Issue: PnL calculation seems incorrect
Cause: Price data or quantity precision issues
Solution:
- Verify
get_last_price_or_zero()returns correct prices - Check
quantity_precisionfor your symbol - Review exchange fee calculations
Safety Features
1. Concurrent Processing Protection
- Only one watcher instance runs at a time (mutex lock)
- Prevents duplicate order processing
- Avoids race conditions
2. Batch Operations
- All bot updates done in single operation
- Atomic state changes
- Consistent data across all bots
3. Error Handling
- Failed order checks don't stop other checks
- Continues processing even if some orders fail
- Comprehensive error logging
4. API Rate Limiting
- Controlled concurrent requests (max 10)
- Delays between batches
- Respects exchange limits
Example Scenarios
Scenario 1: Normal TP Hit
- 9:00:00 - Order placed: Long BTCUSDT @ $50,000, TP @ $51,000
- 9:15:30 - Price reaches $51,000
- 9:15:31 - TP order filled by exchange
- 9:15:40 - Watcher detects filled order
- 9:15:41 - Executes close (100%), PnL: +$100
- 9:15:42 - Updates bot: Win, moves to completed orders
- 9:15:43 - Bot stats: Win rate 68% β 69%
Result: β Clean profit taking
Scenario 2: SL Rejected but Recoverable
- 9:00:00 - Order placed: Long ETHUSDT @ $3,000, SL @ $2,950
- 9:10:20 - SL order rejected (post-only issue)
- 9:10:40 - Watcher detects rejection
- 9:10:41 - Current price: $3,020 (still safe)
- 9:10:42 - Places new market SL @ $2,950
- 9:10:43 - New SL order active
Result: β Protection restored without exit
Scenario 3: SL Rejected & Breached (Emergency)
- 9:00:00 - Order placed: Short SOLUSDT @ $100, SL @ $102
- 9:05:15 - Price spikes to $103
- 9:05:16 - SL order rejected
- 9:05:40 - Watcher detects rejection
- 9:05:41 - Current price: $103 (breached SL!)
- 9:05:42 - π¨ EMERGENCY MARKET EXIT
- 9:05:43 - Market order executed @ $103
- 9:05:44 - Position closed, PnL: -$300
- 9:05:45 - Updates bot: Loss, moves to completed
Result: β οΈ Loss minimized by immediate exit
Summary
The SL/TP Watcher is a critical component that:
- β Ensures your risk management orders execute properly
- π‘οΈ Protects against order failures and edge cases
- π Maintains accurate trading statistics
- π¨ Takes emergency action when needed
- π Runs automatically without user intervention