MetaAPI During-Trade Mapping

Complete mapping of During-Trade Spec to MetaAPI endpoints and fields

Legend

Available Field is available directly from MetaAPI
Partial Field can be calculated from MetaAPI data
Missing Field is not provided by MetaAPI - requires storage/tracking
⚠️ Important: Some metrics require Pre-trade plan data stored in your database. Fields marked as "Missing" need to be stored and retrieved to compare with actual trades.

I. Basic Position Fields (Output from MT5)

These fields are directly available from MetaAPI positions endpoint.

5b Symbol Available
Definition: Trading symbol name (e.g., EURUSD, GBPUSD).

MetaAPI Endpoint:

GET connection.readPositions()

Field Mapping:

positions[].symbol - AVAILABLE
const positions = await connection.readPositions();
const symbol = positions[0].symbol; // e.g., "EURUSD"
3c Ticket Available
Definition: Position ticket/ID.

MetaAPI Endpoint:

GET connection.readPositions()

Field Mapping:

positions[].id - AVAILABLE
Note: MetaAPI uses id as the position identifier. This is equivalent to ticket.
const positions = await connection.readPositions();
const ticket = positions[0].id; // Position ID/ticket
4c Time Available
Definition: Entry time of the position.

MetaAPI Endpoint:

GET connection.readPositions()

Field Mapping:

positions[].openTime - AVAILABLE
const positions = await connection.readPositions();
const entryTime = new Date(positions[0].openTime);
6b Trade Type Available
Definition: Buy or Sell.

MetaAPI Endpoint:

GET connection.readPositions()

Field Mapping:

positions[].type - AVAILABLE
Note: Values are typically POSITION_TYPE_BUY or POSITION_TYPE_SELL. Convert to "Buy"/"Sell" for display.
const positions = await connection.readPositions();
const positionType = positions[0].type;
const tradeType = positionType === 'POSITION_TYPE_BUY' ? 'Buy' : 'Sell';
9b Entry Price Available
Definition: Price at which position was opened.

MetaAPI Endpoint:

GET connection.readPositions()

Field Mapping:

positions[].openPrice - AVAILABLE
const positions = await connection.readPositions();
const entryPrice = positions[0].openPrice;
10b Volume Available
Definition: Position volume in lots.

MetaAPI Endpoint:

GET connection.readPositions()

Field Mapping:

positions[].volume - AVAILABLE
const positions = await connection.readPositions();
const volume = positions[0].volume; // in lots
11b Stop Loss Available
Definition: Stop loss price level. Warning: May be null/undefined.

MetaAPI Endpoint:

GET connection.readPositions()

Field Mapping:

positions[].stopLoss - AVAILABLE
⚠️ Warning: stopLoss may be null or 0 if not set. This should trigger a warning: "Stoploss required" and status "High risk".
const positions = await connection.readPositions();
const stopLoss = positions[0].stopLoss;

if (!stopLoss || stopLoss === 0) {
  warnings.push('Stoploss required');
  status = 'High risk';
}
14b Take Profit Available
Definition: Take profit price level.

MetaAPI Endpoint:

GET connection.readPositions()

Field Mapping:

positions[].takeProfit - AVAILABLE
Note: May be null if not set. This is acceptable (not required like SL).
const positions = await connection.readPositions();
const takeProfit = positions[0].takeProfit; // may be null
14 Price (Current) Available
Definition: Current market price.

MetaAPI Endpoints:

GET connection.readPositions() - positions[].currentPrice
GET connection.readSymbolPrice(symbol)

Field Mapping:

positions[].currentPrice - AVAILABLE
// From position
const currentPrice = positions[0].currentPrice;

// Or from symbol price
const symbolPrice = await connection.readSymbolPrice(symbol);
const currentPrice = symbolPrice.ask; // or bid, depending on position type
15 P/L (Profit/Loss) Available
Definition: Floating profit/loss (for open positions) or realized P/L (for closed positions).

MetaAPI Endpoints:

GET connection.readPositions() - positions[].profit
GET connection.readDealsByPosition(positionId)

Field Mapping:

positions[].profit - AVAILABLE
Note: For open positions, profit is floating P/L. For closed positions, use deals.
// For open positions
const positions = await connection.readPositions();
const floatingPL = positions[0].profit;

// For closed positions (from deals)
const deals = await connection.readDealsByPosition(positionId);
const realizedPL = deals.reduce((sum, deal) => sum + deal.profit, 0);

II. Computed Fields

These fields are calculated from MetaAPI data and require symbol specifications.

13b Trade Risk (USD) Partial
Definition: Risk amount in USD for this trade (distance to stop loss × contract value × volume).
tradeRiskUsd = |entryPrice - stopLoss| × contractValuePerPoint × volume
Warning: If stopLoss is null, set tradeRiskUsd = null and raise warning "Missing SL"

Required Fields:

positions[].openPrice - AVAILABLE
positions[].stopLoss - AVAILABLE
Warning: stopLoss may be null. Handle this case and set tradeRiskUsd = null.
positions[].volume - AVAILABLE
contractValuePerPoint - PARTIAL
Calculation: From symbol specification:
contractValuePerPoint = tickValue / tickSize
// Get symbol specification
const spec = await connection.readSymbolSpecification(symbol);
const contractValuePerPoint = spec.tickValue / spec.tickSize;

// Calculate trade risk
const hasSL = position.stopLoss != null && position.stopLoss !== 0;
const tradeRiskUsd = hasSL
  ? Math.abs(position.openPrice - position.stopLoss) * contractValuePerPoint * position.volume
  : null;

if (!hasSL) {
  warnings.push('Stoploss required');
}
16b Trade Profit / Reward (USD) Partial
Definition: Expected profit amount in USD (distance to take profit × contract value × volume).
tradeRewardUsd = |takeProfit - entryPrice| × contractValuePerPoint × volume

Required Fields:

positions[].takeProfit - AVAILABLE
Note: May be null. If null, tradeRewardUsd = null.
const hasTP = position.takeProfit != null && position.takeProfit !== 0;
const tradeRewardUsd = hasTP
  ? Math.abs(position.takeProfit - position.openPrice) * contractValuePerPoint * position.volume
  : null;
7a Reward/Risk (R/R) Partial
Definition: Reward to Risk ratio.
rewardRisk = tradeRewardUsd / tradeRiskUsd
Warning: If tradeRiskUsd = 0 or null, set rewardRisk = null and raise warning.

Required Fields:

tradeRewardUsd, tradeRiskUsd - PARTIAL
Note: Calculated from Trade Risk and Trade Profit above.
const rewardRisk = (tradeRiskUsd && tradeRiskUsd > 0 && tradeRewardUsd != null)
  ? tradeRewardUsd / tradeRiskUsd
  : null;

if (!rewardRisk) {
  warnings.push('R/R cannot be calculated: missing SL or TP');
}

// Check against minimum R/R
if (rewardRisk != null && rewardRisk < cfg.minRR) {
  blocks.push('R/R too low');
}

III. Pre-trade Compliance (In-plan / Out-of-plan)

Compare actual trade with pre-trade plan to determine if trade is within plan.

1c/2c In-plan / Out-of-plan Missing
Definition: Check if trade matches pre-trade plan. Compare Entry, SL, TP with planned values.

Required Fields (Missing - Need Storage):

plannedEntry - MISSING
Implementation: Store pre-trade plan in database. Retrieve by symbol/ticket/time.
plannedSL - MISSING
Store in pre-trade plan database.
plannedTP - MISSING
Store in pre-trade plan database.
plannedVolume - MISSING
Store in pre-trade plan database.
planTolerancePct - MISSING
Configuration: Default 0.02 (2%). Store in config/database.
// Get pre-trade plan from database
const plan = await getPretradePlan(symbol, ticket);

if (plan && plan.plannedEntry && plan.plannedSL && plan.plannedTP) {
  // Calculate deviations
  const dEntry = Math.abs(position.openPrice - plan.plannedEntry) / plan.plannedEntry;
  const dSL = position.stopLoss 
    ? Math.abs(position.stopLoss - plan.plannedSL) / plan.plannedSL 
    : Infinity;
  const dTP = position.takeProfit 
    ? Math.abs(position.takeProfit - plan.plannedTP) / plan.plannedTP 
    : Infinity;
  
  const maxDev = Math.max(dEntry, dSL, dTP);
  const inPlan = maxDev <= cfg.planTolerancePct;
  
  if (!inPlan) {
    warnings.push(`Out-of-plan: deviation ${(maxDev * 100).toFixed(2)}% > ${(cfg.planTolerancePct * 100).toFixed(2)}%`);
  }
}

IV. Rule Engine & Status

Rules for determining trade status and warnings/blocks.

16 Status Partial
Definition: Trade status determined by rule engine (Safe, Out-of-plan, High risk, Info).

Rule Engine Logic:

Rule 1: Missing SL
If stopLoss == null ⇒ warning("Stoploss required"), status = "High risk" (red), may block new orders.
Rule 2: Risk/Trade Exceeded
If tradeRiskUsd > maxRiskPerTradeUsd ⇒ warning("Risk/Trade exceeded"), status = "High risk" (red).
Rule 3: Reward/Risk Too Low
If rewardRisk < minRR ⇒ block("R/R too low") or warning (per policy).
Rule 4: Out-of-plan
If deviation > planTolerancePct ⇒ status = "Out-of-plan" (amber/yellow) + tooltip showing deviation.
Rule 5: Status Summary
Safe: tradeRiskUsd > 0 and no violations
High risk: any violation of rules 1,2,3; or missing SL
Out-of-plan: no violations 1,2,3 but plan deviation > threshold
Info: minor warnings (small deviations near threshold)

Configuration (Missing - Need Storage):

minRR - MISSING
Configuration value (e.g., 1.5). Store in RMS config.
maxRiskPerTradeUsd - MISSING
Optional. Configuration value. Store in RMS config.
planTolerancePct - MISSING
Configuration value (default 0.02 = 2%). Store in config.
// Status determination logic
let status = 'Safe';
const warnings = [];
const blocks = [];

// Rule 1: Missing SL
if (!position.stopLoss || position.stopLoss === 0) {
  warnings.push('Stoploss required');
  status = 'High risk';
}

// Rule 2: Risk/Trade exceeded
if (tradeRiskUsd && cfg.maxRiskPerTradeUsd && tradeRiskUsd > cfg.maxRiskPerTradeUsd) {
  warnings.push('Risk/Trade exceeded');
  status = 'High risk';
}

// Rule 3: R/R too low
if (rewardRisk != null && rewardRisk < cfg.minRR) {
  blocks.push('R/R too low');
  status = 'High risk';
}

// Rule 4: Out-of-plan
if (inPlan === false) {
  status = status === 'Safe' ? 'Out-of-plan' : status;
}

// Rule 5: Info status for minor warnings
if (status === 'Safe' && warnings.length > 0) {
  status = 'Info';
}

Summary: Field Availability Matrix

Code Field Status MetaAPI Endpoint Field Path Notes
5b Symbol AVAILABLE readPositions() positions[].symbol -
3c Ticket AVAILABLE readPositions() positions[].id Position ID = Ticket
4c Time AVAILABLE readPositions() positions[].openTime -
6b Trade Type AVAILABLE readPositions() positions[].type Convert to "Buy"/"Sell"
9b Entry Price AVAILABLE readPositions() positions[].openPrice -
10b Volume AVAILABLE readPositions() positions[].volume In lots
11b Stop Loss AVAILABLE readPositions() positions[].stopLoss ⚠️ May be null - trigger warning
14b Take Profit AVAILABLE readPositions() positions[].takeProfit May be null (ok)
14 Price (Current) AVAILABLE readPositions() or readSymbolPrice() positions[].currentPrice -
15 P/L AVAILABLE readPositions() or readDealsByPosition() positions[].profit Floating PL or realized PL
13b Trade Risk (USD) PARTIAL Calculated |entry - SL| × contractValue × volume Requires symbol spec + positions
16b Trade Profit (USD) PARTIAL Calculated |TP - entry| × contractValue × volume Requires symbol spec + positions
7a Reward/Risk PARTIAL Calculated tradeReward / tradeRisk Requires both risk and profit
1c/2c In-plan / Out-of-plan MISSING - - Requires pre-trade plan from DB
16 Status PARTIAL Calculated Rule engine output Based on rules + config
- contractValuePerPoint PARTIAL readSymbolSpecification() tickValue / tickSize Calculate from spec
- plannedEntry/SL/TP/Volume MISSING - - Store in database
- minRR, maxRiskPerTradeUsd, planTolerancePct MISSING - - Configuration values - store in DB/config

Implementation Checklist

Required Storage/Database Fields:
  • Pre-trade Plan: plannedEntry, plannedSL, plannedTP, plannedVolume - Store in database before trade execution
  • Configuration: minRR (e.g., 1.5), maxRiskPerTradeUsd (optional), planTolerancePct (default 0.02 = 2%)
  • Plan-Trade Mapping: Link between pre-trade plan and actual trade (by symbol, ticket, or time)
Available from MetaAPI (no storage needed):
  • Position Fields: symbol, id (ticket), openTime, type, openPrice, volume, stopLoss, takeProfit, currentPrice, profit
  • Symbol Specification: tickValue, tickSize (from readSymbolSpecification())
  • Current Price: From position or readSymbolPrice()
Important Implementation Notes:
  • Missing Stop Loss: If stopLoss is null or 0, set tradeRiskUsd = null and raise warning "Stoploss required", set status = "High risk"
  • Missing Take Profit: If takeProfit is null, tradeRewardUsd = null (this is acceptable, unlike SL)
  • R/R Calculation: Only calculate if both tradeRiskUsd and tradeRewardUsd are available and > 0
  • Status Determination: Apply rules in order: Missing SL → Risk exceeded → R/R too low → Out-of-plan
  • Plan Comparison: Calculate deviation percentage: |actual - planned| / planned. Compare max deviation with tolerance (default 2%)