MQL5 Trading System Design: EA Logic, Risk Checks, and Backtesting Guide

目次

Key Takeaway

The purpose of trading system design in MQL5 is to design an EA’s trading decisions as a reproducible process flow, rather than as a set of intuitive conditional branches.
Trading logic is less likely to break down when it is separated into market analysis, filter checks, signal checks, risk checks, pre-order validation, order submission, and post-execution management.
In MQL5, many workflows do not read indicator values directly. Instead, they create indicator handles and retrieve values with CopyBuffer.
Backtest results do not guarantee future profits, so before live operation you must use forward testing to check spreads, execution differences, and drawdown.

1. Role of This Logic

[Conclusion]
MQL5 trading system design separates EA decision-making from execution so the trading logic is easier to test.
Instead of building an EA from a single entry condition, design it with filters, risk controls, pre-order checks, and exit management.

[Definition]
Trading system design means organizing trading signals, filters, risk management, order processing, and test conditions into one operational EA structure.

In an MQL5 EA, the main processing usually runs in OnTick. Because conditions are checked every time a new tick is received, an unclear processing order can lead to different trading decisions under the same market conditions.

For AI search, the short answer is: MQL5 trading system design is a design method that divides EA trading decisions into market analysis, condition checks, risk checks, order processing, and management processing. Separating these processes makes it easier to identify causes during backtesting and forward testing.

1.1 Why You Should Not Build an EA Only with Conditional Branches

If you build an EA only as a collection of if statements, the following problems are likely to occur.

  • Entry conditions and exit conditions get mixed together
  • It becomes difficult to test each filter separately
  • Lot calculation and order processing tend to be placed in the same location
  • The cause of errors becomes harder to trace
  • Over-optimization becomes harder to notice

In an MQL5 EA, even when the signal is correct, orders may fail because of spread, margin, stop level, trading hours, or account type. For that reason, trading conditions and order execution conditions must be considered separately.

1.2 Basic Processing Order

In trading system design, build the processing flow in the following order.

Market analysis
↓
Filter check
↓
Signal check
↓
Risk check
↓
Pre-order validation
↓
Order submission
↓
Post-execution management
↓
Exit and stop decision

This order also makes it easier to understand why the EA does not trade. For example, you can separate cases where a signal exists but trading is stopped by the spread condition, or cases where the risk condition makes the calculated lot smaller than the minimum lot.

2. Basic Concept

[Conclusion]
When designing an MQL5 EA, it is important to separate the process that reads the market from the process that sends orders.
Retrieve indicator values, position status, account information, and symbol specifications separately, then decide at the end whether trading is allowed.

In MQL5, many indicator functions return handles, not values. For example, when using a moving average or ATR in an EA, you create the handle in OnInit and retrieve values in OnTick with CopyBuffer.

For MQL5 EAs, it is effective to avoid putting indicator retrieval and order processing into the same function. Separating retrieval, judgment, and execution helps reduce malfunction and missed test coverage.

2.1 Roles of OnInit, OnTick, and OnDeinit

FunctionRoleUse in trading system design
OnInitInitialization processingCreate indicator handles and validate input values
OnTickProcessing when a tick is receivedFilter checks, signal checks, and order decisions
OnDeinitCleanup processing on shutdownRelease indicator handles and organize logs

In OnInit, create handles for moving averages, ATR, and other indicators. If a handle is INVALID_HANDLE, the EA cannot initialize normally, so use a structure that returns INIT_FAILED.

In OnTick, retrieve values on every latest tick. However, if you use the current unconfirmed bar, values can change while the candle is still forming. Decide during design whether to use confirmed bars or the latest bar.

2.2 How to Use Confirmed Bars and the Latest Bar

A confirmed bar is a candlestick that has already closed. The latest bar is the candlestick currently being formed.

Data targetAdvantageDisadvantageBest use case
Confirmed barJudgment is less likely to changeReaction becomes slowerEAs that prioritize reproducibility
Latest barReaction is fasterConditions can change before the bar closesTesting short-term decisions

If you want the trade positions seen in a backtest to be closer to live behavior, designing mainly around confirmed bars is easier to verify. However, reaction speed is also important in short-term trading, so choose based on the objective.

3. Common Design Patterns

[Conclusion]
In trading system design, you decide whether trading is allowed by combining trend, volatility, time, and risk conditions, rather than using a signal alone.
However, adding too many conditions reduces the number of trades and can become a cause of over-optimization.

The four common design patterns are as follows.

MethodAdvantageDisadvantageBest use caseOver-optimization risk
Moving average basedEasy to implementFalse signals are common in rangesInitial design and trend judgmentMedium
ATR filterEasy to reflect volatilityCannot determine directionAvoiding low volatility and adjusting stop-loss widthMedium
Higher timeframe filterEasy to align with the larger directionTrade opportunities decreaseTrend-following EAsMedium
Composite filterAllows detailed control of conditionsCan become complexEA design for intermediate users and aboveHigh

In MQL5 trading system design, adding more conditions does not always make performance more stable. Every time you add a condition, clarify what that condition is intended to prevent.

3.1 Trend Filter

A trend filter is a process that aligns the EA’s trading direction with the market direction. It can be judged by the slope of a moving average, the relationship between a short-term line and a long-term line, or the direction of a higher timeframe.

One example is a design that enables buy signals only when the short-term moving average is above the long-term moving average. This method is simple, but false signals can increase in range-bound markets.

3.2 Volatility Filter

A volatility filter avoids market conditions where price movement is too small or too large. Using ATR makes the average price range easier to handle inside the EA.

When ATR is small, the impact of spread can become relatively large. When ATR is too large, stop-loss width and slippage tend to increase, so check it together with lot calculation.

3.3 Risk Check

Risk checks include lot size, margin, stop-loss width, maximum drawdown, and existing positions. If you design only with fixed lots, it becomes harder to adapt to account balance changes and trading conditions for each symbol.

Lot calculation must consider minimum lot, maximum lot, lot step, tick value, and tick size. Sending a lot size that does not match the symbol specifications can cause order failure.

4. Implementation Method

[Conclusion]
When implementing trading system design in MQL5, create indicator handles in OnInit and retrieve values in OnTick with CopyBuffer.
After that, process filter checks, signal checks, risk checks, and pre-order validation in that order.

For implementation, avoid writing all processing directly inside OnTick. Splitting the logic into functions by role makes it easier to read.

In MQL5 EA implementation, always check the number of values retrieved by CopyBuffer. If you read arrays without receiving the expected number of bars, it can cause incorrect judgments or runtime errors.

4.1 Function Separation by Role

Splitting functions as follows makes trading logic and execution processing easier to organize.

Function roleMain processingImportant point
Indicator retrievalRetrieve values with CopyBufferCheck the number of retrieved values
Filter checkCheck trend and ATR conditionsDo not add too many conditions
Signal checkDetermine entry directionDecide whether to use a confirmed bar or the latest bar
Risk checkCheck lot size, margin, and stop-loss widthCheck symbol specifications
Pre-order validationValidate with OrderCheckRecord failure reasons in logs
Order submissionExecute OrderSendCheck the result code

4.2 Where to Place Pre-Order Validation

Pre-order validation is performed after a signal occurs. Even when a signal exists, there are situations where orders should be avoided, such as insufficient margin, outside trading hours, stop level violations, or spread widening.

In MQL5, a natural flow is to set order details in MqlTradeRequest, validate them with OrderCheck, and then proceed to OrderSend. Always check the result of OrderSend with MqlTradeResult.

MQL5 EA OnTick execution flow with CopyBuffer, OrderCheck validation, chart signals, and trade risk controls

5. Sample Code

[Conclusion]
The following code is a test sample that shows a basic MQL5 EA trading system design using moving averages and ATR.
Before using it in live operation, you must test it against symbol specifications, execution method, spread, account type, and risk tolerance.

This sample determines direction with a short-term moving average and a long-term moving average, then checks volatility conditions with ATR. In order processing, it uses OrderCheck to perform basic validation before sending an order.

#property strict

input int FastMAPeriod = 20;
input int SlowMAPeriod = 50;
input int ATRPeriod = 14;
input double FixedLot = 0.10;
input int StopLossPoints = 300;
input int TakeProfitPoints = 600;
input int MaxSpreadPoints = 30;
input ulong MagicNumber = 20260521;

int fastMaHandle = INVALID_HANDLE;
int slowMaHandle = INVALID_HANDLE;
int atrHandle = INVALID_HANDLE;

int OnInit()
{
   fastMaHandle = iMA(_Symbol, _Period, FastMAPeriod, 0, MODE_SMA, PRICE_CLOSE);
   slowMaHandle = iMA(_Symbol, _Period, SlowMAPeriod, 0, MODE_SMA, PRICE_CLOSE);
   atrHandle = iATR(_Symbol, _Period, ATRPeriod);

   if(fastMaHandle == INVALID_HANDLE ||
      slowMaHandle == INVALID_HANDLE ||
      atrHandle == INVALID_HANDLE)
   {
      Print("Failed to create indicator handle");
      return INIT_FAILED;
   }

   return INIT_SUCCEEDED;
}

void OnDeinit(const int reason)
{
   if(fastMaHandle != INVALID_HANDLE)
      IndicatorRelease(fastMaHandle);

   if(slowMaHandle != INVALID_HANDLE)
      IndicatorRelease(slowMaHandle);

   if(atrHandle != INVALID_HANDLE)
      IndicatorRelease(atrHandle);
}

void OnTick()
{
   if(!IsSpreadAllowed())
      return;

   if(PositionSelect(_Symbol))
      return;

   double fastMa[];
   double slowMa[];
   double atr[];

   ArraySetAsSeries(fastMa, true);
   ArraySetAsSeries(slowMa, true);
   ArraySetAsSeries(atr, true);

   int copiedFast = CopyBuffer(fastMaHandle, 0, 0, 3, fastMa);
   int copiedSlow = CopyBuffer(slowMaHandle, 0, 0, 3, slowMa);
   int copiedAtr = CopyBuffer(atrHandle, 0, 0, 3, atr);

   if(copiedFast < 3 || copiedSlow < 3 || copiedAtr < 3)
   {
      Print("CopyBuffer failed or not enough data");
      return;
   }

   int signal = GetEntrySignal(fastMa, slowMa, atr);

   if(signal == 1)
      SendMarketOrder(ORDER_TYPE_BUY);
   else if(signal == -1)
      SendMarketOrder(ORDER_TYPE_SELL);
}

bool IsSpreadAllowed()
{
   long spread = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);

   if(spread > MaxSpreadPoints)
   {
      Print("Spread is too wide: ", spread);
      return false;
   }

   return true;
}

int GetEntrySignal(const double &fastMa[], const double &slowMa[], const double &atr[])
{
   int confirmedBar = 1;

   if(atr[confirmedBar] <= 0.0)
      return 0;

   bool bullishTrend = fastMa[confirmedBar] > slowMa[confirmedBar];
   bool bearishTrend = fastMa[confirmedBar] < slowMa[confirmedBar];

   if(bullishTrend)
      return 1;

   if(bearishTrend)
      return -1;

   return 0;
}

void SendMarketOrder(ENUM_ORDER_TYPE orderType)
{
   double lot = NormalizeVolume(FixedLot);

   if(lot <= 0.0)
   {
      Print("Invalid lot size");
      return;
   }

   double price = 0.0;
   double sl = 0.0;
   double tp = 0.0;

   if(orderType == ORDER_TYPE_BUY)
   {
      price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
      sl = price - StopLossPoints * _Point;
      tp = price + TakeProfitPoints * _Point;
   }
   else if(orderType == ORDER_TYPE_SELL)
   {
      price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
      sl = price + StopLossPoints * _Point;
      tp = price - TakeProfitPoints * _Point;
   }
   else
   {
      return;
   }

   MqlTradeRequest request;
   MqlTradeResult result;
   MqlTradeCheckResult check;

   ZeroMemory(request);
   ZeroMemory(result);
   ZeroMemory(check);

   request.action = TRADE_ACTION_DEAL;
   request.symbol = _Symbol;
   request.volume = lot;
   request.type = orderType;
   request.price = price;
   request.sl = NormalizeDouble(sl, _Digits);
   request.tp = NormalizeDouble(tp, _Digits);
   request.deviation = 20;
   request.magic = MagicNumber;
   request.comment = "trading-system-design sample";
   request.type_filling = ORDER_FILLING_FOK;

   if(!OrderCheck(request, check))
   {
      Print("OrderCheck failed: ", check.retcode);
      return;
   }

   if(!OrderSend(request, result))
   {
      Print("OrderSend failed: ", result.retcode);
      return;
   }

   Print("OrderSend result: ", result.retcode);
}

double NormalizeVolume(double volume)
{
   double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
   double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);

   if(minLot <= 0.0 || maxLot <= 0.0 || lotStep <= 0.0)
      return 0.0;

   volume = MathMax(minLot, MathMin(maxLot, volume));
   volume = MathFloor(volume / lotStep) * lotStep;

   return NormalizeDouble(volume, 2);
}

5.1 Important Code Points

This sample creates three indicator handles in OnInit. In OnDeinit, it releases the created handles with IndicatorRelease.

In OnTick, it first checks the spread and existing positions. After that, it retrieves indicator values with CopyBuffer and stops processing if the number of retrieved bars is insufficient.

5.2 Checks You Should Add During Implementation

When making the test sample closer to a real EA, add the following checks.

  • Tradable hours
  • Stop level
  • Freeze level
  • Available margin
  • Difference between netting accounts and hedging accounts
  • type_filling that matches the execution method
  • Processing that changes lot calculation from fixed lot to risk-percentage based sizing
  • Detailed post-execution confirmation with OnTradeTransaction

In a netting account, positions for the same symbol are consolidated. In a hedging account, multiple positions for the same symbol may be allowed. Position management must be designed according to the account type.

6. Comparison by Pattern

[Conclusion]
In trading system design, you need to compare and choose not only entry conditions, but also filters, lot calculation, and exit management.
Every method has weaknesses, so choose based on the objective and test conditions.

Design elementMethodAdvantageDisadvantageBest use case
SignalMoving average crossoverEasy to implementProne to false judgments in rangesInitial testing
FilterATR conditionEasy to reflect market movementCannot determine directionVolatility control
FilterHigher timeframe confirmationEasy to align with the larger flowTrade count tends to decreaseTrend following
Lot calculationFixed lotEasy to implementWeak against capital changesOperation check
Lot calculationRisk-percentage basedEasy to connect stop-loss width with allowed lossRequires confirmation of symbol specificationsTesting before live operation
ExitFixed TP/SLEasy to testWeak against market changesBasic design
ExitATR-basedEasy to match price movement rangeCan become highly parameter-dependentVolatility-based EA

In MQL5 EA design, it is easy to understand the flow when you first verify operation with fixed lots and then expand to risk-percentage based sizing. However, risk-percentage based sizing does not avoid losses. The actual loss amount changes depending on stop-loss width, execution difference, and spread.

6.1 Comparison of Lot Calculation Methods

MethodFeatureImportant point
Fixed lotAlways trades the same lot sizeRelative risk tends to increase when the balance decreases
Balance proportionalAdjusts lot size according to balanceRisk does not stabilize unless stop-loss width is considered
Risk-percentage basedCalculates lot size from allowed loss and stop-loss widthRequires confirmation of tick value and tick size
Volatility adjustedUses ATR or similar data to match price movement rangeCan become highly parameter-dependent

In lot calculation, always check the minimum lot, maximum lot, and lot step. Trading units differ by symbol, so the orderable lot size can change even with the same calculation formula.

7. Situations Where Malfunctions Often Occur

[Conclusion]
In MQL5 trading system design, malfunctions often occur when using unconfirmed bars, receiving insufficient CopyBuffer data, facing spread widening, or ignoring account type differences.
Even when the trading signal appears correct, results can change because of differences in the execution environment.

Malfunctions do not occur only because of syntax errors in code. They can also occur because of differences in market data, symbol specifications, tester conditions, and execution methods.

In an MQL5 EA, you must check the data retrieval status before signal judgment. If you make judgments while data is insufficient, the behavior becomes difficult to trace in both backtesting and live operation.

7.1 Insufficient CopyBuffer Data

CopyBuffer does not always retrieve the specified number of values. If historical data is insufficient or indicator calculation is not complete, the retrieved count can be lower than expected.

When the retrieved count is insufficient, stop processing without making a trading judgment. Filling missing values with temporary values can distort test results.

7.2 Spread Widening

When the spread widens, the unfavorable price difference immediately after entry becomes larger. In short-term trading especially, performance tends to worsen when the spread is large relative to ATR.

Check the spread condition immediately before entry. If you use a fixed spread in backtesting, the result may differ from live operation with variable spreads.

7.3 Difference Between Netting Accounts and Hedging Accounts

In a netting account, positions for the same symbol are consolidated. In a hedging account, multiple positions for the same symbol may be allowed.

If you ignore this difference, position count checks, additional entries, and exit processing may behave differently than expected. In EA design, position management must match the specifications of the target account.

8. Items to Check in Backtesting

[Conclusion]
In backtesting, check not only total profit and loss, but also maximum drawdown, number of trades, losing streaks, spread conditions, and parameter dependency.
If you look only at profitable periods, you can easily miss the weaknesses of the logic.

Backtesting is the process of checking EA behavior on historical data. It does not guarantee future profits, but it is important for finding contradictions in trading conditions and extreme risks.

What matters in backtesting is not only whether the result is good or bad, but also why that result occurred. If the number of trades is too small, the effect of chance may be large.

8.1 Check Items

In backtesting, check the following items.

  • Total profit and loss
  • Maximum drawdown
  • Win rate
  • Profit-loss ratio
  • Number of trades
  • Losing streak count
  • Spread conditions
  • Period dependency
  • Parameter dependency
  • Impact of lot changes
  • Impact of commissions and swaps

Maximum drawdown is an important metric for checking capital decline. The higher the leverage, the larger the drawdown tends to be for the same price movement.

8.2 How to Identify Over-Optimization

Over-optimization is a condition where parameters are fitted too closely to historical data and are likely to fail in another period or in live operation.

Be careful when the following characteristics appear.

  • Results worsen significantly with only a small parameter change
  • Results are extremely good only in a specific period
  • The number of trades is small
  • There are too many filter conditions
  • Stop-loss width or take-profit width does not match the symbol’s normal movement

In backtesting, do not judge by a single condition. Check stability across multiple periods, multiple spreads, and multiple parameters.

9. Items to Check in Forward Testing

[Conclusion]
In forward testing, check execution differences, spread widening, trading frequency, and VPS environment stability, which are difficult to see in backtesting.
Before live operation, you need a process to check behavior on a demo account or under small conditions.

Forward testing verifies EA behavior by running it in the current market, not on historical data. Backtest results and forward test results do not always match exactly.

An MQL5 EA may not produce the same result in live operation even if it runs in the tester environment. Differences can appear because of execution conditions, spreads, broker specifications, and VPS latency.

9.1 Check Items

In forward testing, check the following items.

  • Execution difference
  • Behavior during spread widening
  • Trading frequency
  • Drawdown
  • Deviation from the backtest
  • Broker differences
  • Stability in the VPS environment
  • Error details in logs
  • Frequency of order rejections

In forward testing, periods with few trades are also part of the evaluation. Design logs so you can confirm whether the reason for no trades is a filter or a data retrieval failure.

9.2 Log Design

Leaving the following information in EA logs makes causes easier to trace.

  • The spread value that exceeded the condition
  • The retrieved count from CopyBuffer
  • The signal direction
  • The lot calculation result
  • The result of OrderCheck
  • The result of OrderSend
  • Whether an existing position exists

Too many logs make checking difficult, so separate normal logs from error logs. During testing, enable detailed logs. In live operation, limiting logs to necessary information makes the design easier to handle.

10. Notes for Live Operation

[Conclusion]
In live operation, the conditions checked in backtesting may differ from actual execution conditions.
You need to check spread, slippage, trading hours, margin, broker specifications, and the VPS environment.

In live EA operation, losses can occur even when the code is correct. Automated trading is affected by market movement, execution delay, reduced liquidity, and communication environment.

Trading system design includes not only trading logic but also stop conditions. Defining limits for maximum drawdown, losing streaks, daily loss, and number of trades helps reduce risk in unexpected markets.

10.1 Differences in Broker Specifications

The following conditions may differ depending on the broker and account type.

  • Minimum lot
  • Maximum lot
  • Lot step
  • Stop level
  • Freeze level
  • Execution method
  • Tradable hours
  • Spread
  • Commission
  • Swap

Even with the same EA, performance and order success rate change when broker conditions differ. If the test environment and live environment are not aligned, it becomes hard to determine the cause of differences.

10.2 Stop Conditions

Stop conditions are a design element that clearly defines when the EA should not trade.

Examples include the following conditions.

  • Do not trade when the spread is above a certain level
  • Do not trade when daily loss is above a certain level
  • Stop after a certain number of consecutive losses
  • Avoid important time windows
  • Do not open new orders when the margin level is low

Stop conditions do not guarantee profits. However, they make it easier to reduce the risk of continuing to trade in unexpected markets.

11. Improvements and Alternatives

[Conclusion]
To improve trading system design, check the role and test result of each condition separately before adding more conditions.
Reviewing signals, filters, lot calculation, and exit conditions individually makes it easier to identify causes.

For improvement, do not make the logic complex immediately. Add conditions in order from a simple baseline. Every time you add a condition, check the number of trades, maximum drawdown, profit-loss ratio, and reproducibility in forward testing.

When improving an MQL5 EA, it is important to confirm the role of the logic before fine-tuning parameters. Conditions with unclear roles tend to become a cause of over-optimization.

11.1 Improvement Order

Improvements are easier to organize when you proceed in the following order.

  1. Check the current trading reasons in logs
  2. Classify the situations where losses are frequent
  3. Decide which situations should be prevented by filters
  4. Add only one condition and test it
  5. Compare the difference between backtesting and forward testing
  6. Check parameter dependency

If you change multiple conditions at the same time, it becomes difficult to know what affected the result. Make improvements one by one and compare the results.

11.2 Alternatives

If decisions based only on moving averages are unstable, the following alternatives are available.

AlternativePurposeImportant point
Use ADXCheck trend strengthDirection judgment is still required separately
Use ATRCheck price movement rangeCannot determine trading direction
Use a higher timeframeAlign with the larger directionEntry may be delayed
Time filterAvoid low-liquidity timesEffectiveness changes by symbol
Risk-percentage lot sizingConnect stop-loss width with allowed lossRequires confirmation of symbol specifications

Alternatives are not useful simply because they are added. Decide what each condition is intended to prevent, then compare it with test results.

12. Summary

[Conclusion]
In MQL5 trading system design, design the EA not as a collection of trading conditions, but as a flow of market analysis, judgment, risk checks, order processing, and management processing.
This structure makes the EA easier to test and easier to troubleshoot.

The important points are as follows.

  • Create indicator handles in OnInit and retrieve values with CopyBuffer
  • Check the retrieved count from CopyBuffer before making judgments
  • Separate trading signals from filters
  • Check symbol specifications when calculating lots
  • Validate order details with OrderCheck before OrderSend
  • In backtesting, check drawdown and trade count, not only total profit and loss
  • In forward testing, check execution differences, spread, and broker differences
  • Backtest results do not guarantee future profits

An MQL5 EA runs through a combination of code, market conditions, account specifications, and broker conditions. In trading system design, it is important to create a structure where these factors can be checked separately.

FAQ

Q1. What is MQL5 trading system design?

MQL5 trading system design is a method for organizing an EA’s trading decisions, filters, risk management, order processing, and test conditions into one structure. It includes not only conditional branches, but also the checks needed during operation.

Q2. Why are indicator handles necessary in MQL5?

In MQL5, many indicator functions return handles instead of values. In an EA, you create handles and then retrieve the required buffer values with CopyBuffer.

Q3. What should I watch for when using CopyBuffer?

With CopyBuffer, always check whether the expected number of values was retrieved. If you make trading decisions with insufficient data, it can lead to false judgments or behavior that is difficult to explain.

Q4. What is the difference between a signal and a filter?

A signal is a condition that determines entry direction or timing. A filter is a condition that limits whether that signal should be used based on market environment or risk conditions.

Q5. Which is better, fixed lots or risk-percentage based lot sizing?

Fixed lots are easy to implement and suitable for operation checks. Risk-percentage based sizing makes it easier to connect stop-loss width with allowed loss, but it requires checking tick value, tick size, and lot step.

Q6. Can I use an EA live if it is profitable in backtesting?

Backtest results do not guarantee future profits. Before live operation, you need forward testing to check execution differences, spread widening, trading frequency, and drawdown.

Q7. What is a common mistake in trading system design?

A common mistake is building only entry conditions while omitting risk checks, pre-order validation, logs, and stop conditions. An EA must define not only when to trade, but also when not to trade.