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_agentandrisk_agentmodify the proposal - how the
orchestration_agentroutes the final execution mode - how the
execution_agentmaps execution type to MT5 order actions
1) End-to-end decision pipeline
At runtime, run_cycle in orchestration_agent executes this chain:
- Fetch market inputs (
ohlcv,tick,portfolio) from MT5. - Build technical context and trade hypothesis (
technical_agent). - Apply portfolio-aware confidence and directional filters (
portfolio_agent). - Apply hard risk shaping and lot sizing (
risk_agent). - Pass to execution with explicit
execution_type:market-> immediate orderpending-> 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)MACDandMACD signalEMA50,EMA200ATR(14)
Derived states:
- trend
- bullish if
EMA50 > EMA200 - bearish if
EMA50 < EMA200
- bullish if
- rsi_state
- oversold if
RSI < 30 - overbought if
RSI > 70 - neutral otherwise
- oversold if
- macd_signal
- bullish if
MACD > MACD_signal - bearish otherwise
- bullish if
- volatility bucket
- low/medium/high using
ATR / pricethresholds
- low/medium/high using
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:
trendhtf_pullbackmean_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_pullbackmode:- 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_reversionmode:- 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_priceentry_strategyin{market_entry, pullback_entry, breakout_entry}execution_typein{market, pending}pending_order_typein{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 (
lookbackbounded to 20..50) - volatility bucket
Decision logic:
- Compute
trend_strength = abs(EMA50 - EMA200) / price. - If trend is strong and volatility is not low:
- prefer breakout logic:
- buy:
entry = resistance + buffer(buy_stop) - sell:
entry = support - buffer(sell_stop)
- buy:
- if breakout level is very close to current price, downgrade to
market_entry.
- prefer breakout logic:
- 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.
- buy pullback near EMA50 inside support/resistance zone (
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_distanceTP = entry + stop_distance * tp_mult
- sell:
SL = entry + stop_distanceTP = 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_profitentry_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 < entryandTP > entry - sell requires
SL > entryandTP < 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_profitfrom 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_typeandpending_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.pybackend/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
- buy ->
- executes at live ask/bid
6.3 Pending order path
- uses MT5
TRADE_ACTION_PENDING - maps pending type:
buy_limit->ORDER_TYPE_BUY_LIMITsell_limit->ORDER_TYPE_SELL_LIMITbuy_stop->ORDER_TYPE_BUY_STOPsell_stop->ORDER_TYPE_SELL_STOP
- uses proposal
entryas pending trigger price
6.4 Persistence and status
Execution writes status into history/scheduled tables, including pending metadata:
execution_typepending_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.