Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

How Trade Execution Works

A concise end-to-end walkthrough of how OpenTrader goes from a market scan to a live bracket order on Binance.


The 5-layer pipeline

SCOUT → COO → BOSS → FINANCE → BOT API → BINANCE

Layer 1 — SCOUT scans the market (automatic, every 5 min)

Scout calls GET /scan?bot=ta_trend. The bot runs technical analysis (RSI, MACD, Bollinger Bands, volume ratio) across the full watchlist and returns a list of candidates that pass the filter.


Layer 2 — Signal submitted to COO

Scout calls POST /api/signal with a full JSON payload (symbol, price, SL %, TP %, TA checklist). The bot stores the signal in memory and automatically sends a Telegram message to BOSS with a summary and YES / NO prompt.

A 5-minute expiry is enforced from this point. If BOSS confirms after 5 minutes the signal is rejected and no trade is placed.


Layer 3 — BOSS confirms (human-in-the-loop)

BOSS replies 1-YES ETHUSDT or 0-NO ETHUSDT on Telegram. COO receives the reply, fetches the signal from GET /api/signal/ETHUSDT, and spawns the Finance agent.


Layer 4 — FINANCE runs AI confirmation

Finance receives the signal JSON from COO, performs an AI analysis, and outputs a structured result:

{
  "confirm": true,
  "ev": 32.5,
  "confidence": 8,
  "reason": "RSI oversold + MACD cross + volume spike",
  "stop_loss_pct": 3.0,
  "take_profit_pct": 6.5
}

Both conditions must be met to proceed:

CriterionThresholdResult if not met
Expected valueev > 25confirm=false, trade blocked
Confidenceconfidence >= 8confirm=false, trade blocked

Finance never calls /trade before outputting this JSON. This is a hard rule — not a guideline.


Layer 5 — Order execution on Binance

Finance calls POST /trade. The bot calculates position size from portfolio %, then places 3 orders simultaneously as a bracket:

BUY  ETHUSDT   ← entry (MARKET)
SELL ETHUSDT   ← stop-loss (STOP_LIMIT)   ┐ OCO pair
SELL ETHUSDT   ← take-profit (LIMIT)      ┘

After a successful fill, Finance calls POST /api/signal/ETHUSDT/confirm to remove the signal from memory. Scout can then signal again for the same symbol once the position closes.


After entry

EventHandled by
Price moves in favorTrailing stop raises SL automatically (every 1 min)
Stop-loss hitBinance closes automatically (OCO triggers)
Take-profit hitBinance closes automatically (OCO triggers)
Manual close by BOSSPOST /api/closeall → cancel OCO → MARKET SELL

Summary

Scout detects signal → Bot notifies BOSS via Telegram → BOSS confirms → Finance AI validates (EV + confidence) → Bot places bracket order on Binance → OCO pair manages SL/TP automatically.


Bracket order in detail

Binance Spot has no native bracket order type. OpenTrader simulates one by placing 3 separate orders in sequence.

Step 1 — Entry

MARKET BUY ETHUSDT

Fills immediately at the current market price. The next two orders are placed only after this fill is confirmed.

Step 2 — OCO (One-Cancels-the-Other)

A single OCO submission places two linked SELL orders simultaneously:

LIMIT_MAKER SELL @ tp_px        ← take-profit (above entry)
STOP_LOSS_LIMIT SELL @ sl_px    ← stop-loss   (below entry)

When either order fills, Binance automatically cancels the other. The two orders share one orderListId — they cannot exist independently.

Example

Entry:       BUY  ETH @ $2,450  (MARKET)
Stop-loss:   SELL ETH @ $2,377  (STOP_LOSS_LIMIT, -3%)
Take-profit: SELL ETH @ $2,622  (LIMIT_MAKER,     +7%)

Price rises to $2,622 → TP fills → SL is auto-cancelled.
Price drops to $2,377 → SL triggers → TP is auto-cancelled.


How SL and TP behave during fast moves

Take-profit — reliable

LIMIT_MAKER only fills at the specified price or better. If price spikes through the TP level the order fills immediately with no adverse slippage.

Stop-loss — has slippage risk

STOP_LOSS_LIMIT uses two price levels:

stopPrice = sl_px           ← trigger price
price     = sl_px × 0.998   ← actual limit price (−0.2% buffer)

When stopPrice is touched, Binance places a LIMIT SELL at price. That limit order then waits in the order book for a fill.

Risk: If the coin gaps down faster than the 0.2% buffer — for example on a sudden news dump — the limit order sits below the market and does not fill. The position stays open and the loss continues to grow.

Scenario0.2% buffer
BTC / ETH normal volatilitySufficient
Altcoin on sudden bad newsLikely insufficient (2–5% gap)
Market-wide flash crashLikely insufficient

Adjusting the buffer

The buffer is set in app/adapters/binance.py line 125:

stop_limit_px = round(sl_px * (0.998 if is_buy else 1.002), pd)

Increase to 0.995 (0.5%) or 0.99 (1%) for coins with higher volatility. The trade-off: a wider buffer guarantees a fill but sells at a slightly worse price than sl_px.


Why OCO must be cancelled before manual close

The two OCO orders lock the coin balance on Binance. Attempting a MARKET SELL while OCO orders are active will fail with APIError(-2010): Account has insufficient balance — the coins are already committed to the pending SELL orders.

POST /api/closeall handles this correctly: it cancels the OCO first, waits for the balance to free up, then places the MARKET SELL.