Back to articles
DocumentationSource: backend/agents/notes/agent_decision_technical_guide.md

AUTHOR: Tony Mudau

Agent Force 1 Decision Technical Guide

This document explains, in implementation-level detail, how the agents transform raw market data into a trade decision, then into either a market order or a pending order.

It focuses on:

  • the exact formula logic used by the technical_agent
  • how the portfolio_agent and risk_agent modify the proposal
  • how the orchestration_agent routes the final execution mode
  • how the execution_agent maps execution type to MT5 order actions

1) End-to-end decision pipeline

At runtime, run_cycle in orchestration_agent executes this chain:

  1. Fetch market inputs (ohlcv, tick, portfolio) from MT5.
  2. Build technical context and trade hypothesis (technical_agent).
  3. Apply portfolio-aware confidence and directional filters (portfolio_agent).
  4. Apply hard risk shaping and lot sizing (risk_agent).
  5. Pass to execution with explicit execution_type:
    • market -> immediate order
    • pending -> place limit/stop pending order

The key architectural shift is that entry is now price-level driven instead of always using current bid/ask.


2) Technical Agent formulas

File: backend/agents/technical_agent/main.py

2.1 Market context construction

build_market_context(df) computes:

  • RSI(14)
  • MACD and MACD signal
  • EMA50, EMA200
  • ATR(14)

Derived states:

  • trend
    • bullish if EMA50 > EMA200
    • bearish if EMA50 < EMA200
  • rsi_state
    • oversold if RSI < 30
    • overbought if RSI > 70
    • neutral otherwise
  • macd_signal
    • bullish if MACD > MACD_signal
    • bearish otherwise
  • volatility bucket
    • low/medium/high using ATR / price thresholds

This context is the base feature vector used by all later scoring.

2.2 Strategy regime selection

choose_strategy_mode(context, volatility, mtf_stack) outputs one of:

  • trend
  • htf_pullback
  • mean_reversion

Core logic:

  • strong aligned directional context + non-compression volatility -> trend
  • entry timeframe moving opposite H1 context -> htf_pullback
  • otherwise -> mean_reversion

This mode influences direction gates and confidence adjustment.

2.3 Direction gate (buy/sell)

Inside generate_trade_hypothesis(...):

  • In trend/htf_pullback mode:
    • buy when bullish trend + bullish MACD (or reversal exception) and RSI not overbought
    • sell when bearish trend + bearish MACD and RSI not oversold
  • In mean_reversion mode:
    • buy when oversold and MACD not bearish
    • sell when overbought and MACD not bullish

If no directional gate passes, no proposal is emitted.

2.4 Entry price engine (new pending/optimal-entry logic)

calculate_entry_price(df, context, direction) returns:

  • entry_price
  • entry_strategy in {market_entry, pullback_entry, breakout_entry}
  • execution_type in {market, pending}
  • pending_order_type in {buy_limit, sell_limit, buy_stop, sell_stop, none}

Inputs used:

  • EMA50, EMA200 (trend strength proxy)
  • ATR-derived buffer (max(price*0.00005, ATR*0.05))
  • support/resistance from recent candles (lookback bounded to 20..50)
  • volatility bucket

Decision logic:

  1. Compute trend_strength = abs(EMA50 - EMA200) / price.
  2. If trend is strong and volatility is not low:
    • prefer breakout logic:
      • buy: entry = resistance + buffer (buy_stop)
      • sell: entry = support - buffer (sell_stop)
    • if breakout level is very close to current price, downgrade to market_entry.
  3. Otherwise prefer pullback logic:
    • buy pullback near EMA50 inside support/resistance zone (buy_limit)
    • sell pullback near EMA50 inside support/resistance zone (sell_limit)
    • if pullback level is too close to current price, downgrade to market_entry.

This is the mechanism that converts signal trading into level-based execution.

2.5 SL/TP formula

Risk distance:

  • stop_distance = max(ATR * 1.5, price * 0.001)

TP multiplier:

  • default: _TP_MULT_DEFAULT
  • for htf_pullback: _TP_MULT_HTF_PULLBACK

Stops and targets are anchored from the selected entry:

  • buy:
    • SL = entry - stop_distance
    • TP = entry + stop_distance * tp_mult
  • sell:
    • SL = entry + stop_distance
    • TP = entry - stop_distance * tp_mult

2.6 Confidence formula

confidence is clamped to [0, 1] and built from weighted components:

  • base constant
  • pattern memory win-rate contribution
  • indicator alignment score contribution
  • trend strength contribution
  • multi-timeframe alignment contribution
  • volatility regime adjustment
  • memory lift/penalty
  • correlation penalty

Form:

confidence = clamp(0, 1, c0 + w1*pattern_win_rate + w2*alignment + w3*trend_strength + w4*mtf_alignment + adjustments - corr_penalty)

The generated payload includes:

  • direction, entry, stop_loss, take_profit
  • entry_strategy, execution_type, pending_order_type
  • confidence, reasoning, diagnostics

3) Portfolio Agent adjustments

File: backend/agents/portfolio_agent/main.py

The portfolio layer does not size lot. It shapes directional confidence based on:

  • recent same-direction symbol performance
  • symbol rollup win-rate and PnL
  • current open position concentration for that symbol
  • optional LLM suggestion (bounded adjustments)

Important behavior:

  • can reduce confidence when recent directional edge is weak
  • may block if too many same-symbol positions are open
  • can apply bounded confidence adjustment from LLM (-0.2..+0.2)
  • optional directional override only when LLM aggressiveness is sufficiently high

Output remains a proposal object with updated confidence and analysis metadata.


4) Risk Agent formulas

File: backend/agents/risk_agent/main.py

The risk layer keeps direction intact and controls position size + risk validity.

4.1 SL/TP sanity

Hard checks:

  • buy requires SL < entry and TP > entry
  • sell requires SL > entry and TP < entry

Invalid geometry rejects proposal.

4.2 Risk budget

  • equity_ref = portfolio.equity (fallback balance)
  • risk_budget = equity_ref * max_risk_per_trade

4.3 Risk per 1 lot

Primary:

  • use MT5 order_calc_profit from entry to stop for 1.0 lot

Fallback if unavailable:

  • risk_per_lot = abs(entry - stop_loss) * contract_size

4.4 Base lot and scaling

Base lot:

  • base_lot = risk_budget / risk_per_lot

Then apply multipliers:

  • confidence factor
  • correlation factor (same thematic USD exposure stacking)
  • exposure concentration factor (currency weight concentration)

Final:

  • clamp to min/max lot
  • enforce final risk budget cap

This guarantees lot sizing is consistent with account risk and current book structure.


5) Orchestration Agent responsibilities

File: backend/agents/orchestration_agent/main.py

The orchestrator is the coordinator, not the entry-logic owner.

Current behavior (important):

  • receives technical proposal fields including:
    • entry, entry_strategy, execution_type, pending_order_type
  • preserves technical entry (falls back to tick only if entry missing)
  • passes execution metadata unchanged through portfolio/risk chain
  • calls execution dispatch via _execution.execute_trade(...) instead of forcing market-only path

For scheduled trades:

  • scheduler reloads stored proposal context
  • reconstructs execution_type and pending_order_type
  • executes through same dispatch path

This ensures deferred execution still respects pending-vs-market intent.


6) Execution Agent and MT5 mapping

Files:

  • backend/agents/execution_agent/main.py
  • backend/agents/common.py

6.1 Dispatch logic

execute_trade(...) routes by execution_type:

  • market -> execute_market_order(...)
  • pending -> execute_pending_order(...)

6.2 Market order path

  • uses MT5 TRADE_ACTION_DEAL
  • order type:
    • buy -> ORDER_TYPE_BUY
    • sell -> ORDER_TYPE_SELL
  • executes at live ask/bid

6.3 Pending order path

  • uses MT5 TRADE_ACTION_PENDING
  • maps pending type:
    • buy_limit -> ORDER_TYPE_BUY_LIMIT
    • sell_limit -> ORDER_TYPE_SELL_LIMIT
    • buy_stop -> ORDER_TYPE_BUY_STOP
    • sell_stop -> ORDER_TYPE_SELL_STOP
  • uses proposal entry as pending trigger price

6.4 Persistence and status

Execution writes status into history/scheduled tables, including pending metadata:

  • execution_type
  • pending_order_type
  • entry/SL/TP context

This keeps analytics and post-trade learning aligned with actual order intent.


7) Practical interpretation of entry strategies

  • market_entry
    • used when entry edge is near current price or immediate participation is preferred
  • pullback_entry (limit orders)
    • used when system wants discounted entry in trend/moderate conditions
    • helps reduce initial stop distance and improve R:R
  • breakout_entry (stop orders)
    • used when system expects continuation after structure break
    • avoided in low-volatility regimes to reduce false breakouts

8) Why this improves decision quality

Compared to always entering at market, the new design:

  • separates signal direction from execution timing
  • allows patient entries at statistically better levels
  • avoids chasing in compressed/low-volatility conditions
  • preserves risk geometry relative to intended entry price

This is the core upgrade from pure signal execution to institutional-style price-level execution.


9) Important limitation

No formula can guarantee a trade will "definitely" move in the expected direction.

What the system can do is maximize expected edge by combining:

  • multi-factor signal alignment
  • context-aware entry placement
  • strict risk sizing and exposure controls
  • controlled execution mode routing

That is exactly what the current architecture now enforces.