🚀 AI One-Click Generation of mql4 Strategy Code

How to Code a Force Index Trading Strategy in an Mql4 EA

mql4 | Published on: 2025/12/4
The following content is generated by EasyQuant .

Problem Description

Please code a trading algorithm based on the Force Index indicator.

Solution

Here is a complete, fully functional Expert Advisor (EA) for MetaTrader 4 based on the Force Index indicator.

Strategy Logic

This algorithm uses a classic trend-following approach combined with the Force Index for entry timing.

  1. Trend Filter: It uses a 200-period Exponential Moving Average (EMA).
    • Bullish: Price is above the 200 EMA.
    • Bearish: Price is below the 200 EMA.
  2. Entry Signal (Force Index):
    • Buy: Trend is Bullish AND Force Index crosses above the Zero line.
    • Sell: Trend is Bearish AND Force Index crosses below the Zero line.
  3. Risk Management: Includes Stop Loss, Take Profit, and a Trailing Stop to lock in profits.

MQL4 Code

//+------------------------------------------------------------------+
//|                                           ForceIndexStrategy.mq4 |
//|                        Copyright 2023, Quantitative Trading AI   |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, Quantitative Trading AI"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

//--- Input Parameters
input string   StrategySettings = "--- Strategy Settings ---";
input int      MagicNumber      = 123456;      // Unique ID for this EA
input double   LotSize          = 0.1;         // Fixed Lot Size
input int      Slippage         = 3;           // Max Slippage in pips

input string   IndicatorSettings = "--- Indicator Settings ---";
input int      ForcePeriod      = 13;          // Force Index Period
input ENUM_MA_METHOD ForceMethod = MODE_EMA;   // Force Index Smoothing Method
input ENUM_APPLIED_PRICE ForcePrice = PRICE_CLOSE; // Force Index Applied Price
input int      TrendMAPeriod    = 200;         // Trend Filter MA Period

input string   RiskSettings     = "--- Risk Management ---";
input int      StopLoss         = 50;          // Stop Loss in pips (0 = none)
input int      TakeProfit       = 100;         // Take Profit in pips (0 = none)
input bool     UseTrailing      = true;        // Enable Trailing Stop
input int      TrailingStop     = 30;          // Trailing Stop distance in pips
input int      TrailingStep     = 5;           // Trailing Step in pips

//--- Global Variables
double pipValue;
int    pipMultiplier;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // Adjust pips for 3/5 digit brokers
   if(Digits == 3 || Digits == 5)
   {
      pipMultiplier = 10;
      pipValue = Point * 10;
   }
   else
   {
      pipMultiplier = 1;
      pipValue = Point;
   }

   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // 1. Check if we have open orders for this symbol/magic number
   if(CountOpenTrades() == 0)
   {
      // 2. Calculate Indicator Values
      // We look at closed bars (index 1 and 2) to avoid repainting
      double fi1 = iForce(NULL, 0, ForcePeriod, ForceMethod, ForcePrice, 1); // Previous bar
      double fi2 = iForce(NULL, 0, ForcePeriod, ForceMethod, ForcePrice, 2); // Bar before previous
      
      double maTrend = iMA(NULL, 0, TrendMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 1);
      double closePrice = iClose(NULL, 0, 1);

      // 3. Check Buy Conditions
      // Trend is UP (Price > MA) AND Force Index crosses 0 from below
      if(closePrice > maTrend && fi2 <= 0 && fi1 > 0)
      {
         OpenTrade(OP_BUY);
      }

      // 4. Check Sell Conditions
      // Trend is DOWN (Price < MA) AND Force Index crosses 0 from above
      else if(closePrice < maTrend && fi2 >= 0 && fi1 < 0)
      {
         OpenTrade(OP_SELL);
      }
   }
   else
   {
      // 5. Manage Open Trades (Trailing Stop)
      if(UseTrailing) ManageTrailingStop();
   }
}

//+------------------------------------------------------------------+
//| Function to Open Trades                                          |
//+------------------------------------------------------------------+
void OpenTrade(int type)
{
   double sl = 0, tp = 0;
   double price = 0;
   color cmdColor = clrNONE;

   if(type == OP_BUY)
   {
      price = Ask;
      if(StopLoss > 0) sl = price - (StopLoss * pipValue);
      if(TakeProfit > 0) tp = price + (TakeProfit * pipValue);
      cmdColor = clrBlue;
   }
   else if(type == OP_SELL)
   {
      price = Bid;
      if(StopLoss > 0) sl = price + (StopLoss * pipValue);
      if(TakeProfit > 0) tp = price - (TakeProfit * pipValue);
      cmdColor = clrRed;
   }

   int ticket = OrderSend(Symbol(), type, LotSize, price, Slippage * pipMultiplier, sl, tp, "ForceIndex EA", MagicNumber, 0, cmdColor);
   
   if(ticket < 0)
   {
      Print("OrderSend failed with error #", GetLastError());
   }
}

//+------------------------------------------------------------------+
//| Function to Count Open Trades for this EA                        |
//+------------------------------------------------------------------+
int CountOpenTrades()
{
   int count = 0;
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
         {
            if(OrderType() == OP_BUY || OrderType() == OP_SELL)
               count++;
         }
      }
   }
   return count;
}

//+------------------------------------------------------------------+
//| Function to Manage Trailing Stop                                 |
//+------------------------------------------------------------------+
void ManageTrailingStop()
{
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
         {
            // Buy Order Trailing
            if(OrderType() == OP_BUY)
            {
               if(Bid - OrderOpenPrice() > TrailingStop * pipValue)
               {
                  if(OrderStopLoss() < Bid - (TrailingStop * pipValue))
                  {
                     // Only modify if the change is larger than the step
                     if(Bid - (TrailingStop * pipValue) - OrderStopLoss() >= TrailingStep * pipValue || OrderStopLoss() == 0)
                     {
                        if(!OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(Bid - (TrailingStop * pipValue), Digits), OrderTakeProfit(), 0, clrGreen))
                           Print("Error modifying Buy Trailing Stop: ", GetLastError());
                     }
                  }
               }
            }
            // Sell Order Trailing
            else if(OrderType() == OP_SELL)
            {
               if(OrderOpenPrice() - Ask > TrailingStop * pipValue)
               {
                  if(OrderStopLoss() > Ask + (TrailingStop * pipValue) || OrderStopLoss() == 0)
                  {
                     // Only modify if the change is larger than the step
                     if(OrderStopLoss() - (Ask + (TrailingStop * pipValue)) >= TrailingStep * pipValue || OrderStopLoss() == 0)
                     {
                        if(!OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(Ask + (TrailingStop * pipValue), Digits), OrderTakeProfit(), 0, clrGreen))
                           Print("Error modifying Sell Trailing Stop: ", GetLastError());
                     }
                  }
               }
            }
         }
      }
   }
}
//+------------------------------------------------------------------+

How to Install and Run

  1. Open MetaTrader 4.
  2. Press F4 to open the MetaEditor.
  3. Click New -> Expert Advisor (template) -> Name it "ForceIndexStrategy".
  4. Delete everything in the new file and paste the code provided above.
  5. Press F7 to Compile. Ensure there are no errors in the "Errors" tab at the bottom.
  6. Go back to the main MT4 window.
  7. Find "ForceIndexStrategy" in the Navigator panel under Expert Advisors.
  8. Drag it onto a chart (e.g., EURUSD H1).
  9. Ensure the "Allow live trading" checkbox is ticked in the Common tab.

Q&A: Force Index Strategy

Q: Why is a Moving Average (MA) included in this code?
A: The Force Index is a very sensitive oscillator. Using it alone often generates false signals during choppy markets. The 200-period EMA acts as a "regime filter," ensuring you only take Buy signals when the long-term trend is up, and Sell signals when the trend is down.

Q: Does this EA work on 5-digit brokers?
A: Yes. The OnInit function automatically detects if the broker uses 3 or 5 decimal places (points) and adjusts the pipValue variable accordingly. This ensures that a 50 pip Stop Loss is calculated correctly as 500 points on a 5-digit broker.

Q: Why does the code use iForce(..., 1) and iForce(..., 2) instead of 0?
A: Index 0 represents the current, forming bar. The data on this bar changes with every tick (repainting). To ensure the signal is valid and permanent, the EA checks indices 1 (the last closed bar) and 2 (the bar before that) to confirm a crossover has actually completed.

Q: Can I optimize the parameters?
A: Yes. You can use the MT4 Strategy Tester (Ctrl+R) to optimize inputs like ForcePeriod, StopLoss, and TakeProfit. A common variation is changing the ForcePeriod to 2 for short-term scalping or keeping it at 13 for standard swing trading.