🚀 AI One-Click Generation of mql4 Strategy Code

Code a Bulls Power and Bears Power Trading Strategy in Mql4

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

Problem Description

Please create a trading strategy that enters trades based on the values of the Bulls Power and Bears Power indicators.

Solution

Here is a complete, fully functional Expert Advisor (EA) for MetaTrader 4 based on the Elder-Ray Impulse System. This strategy utilizes both Bulls Power and Bears Power indicators in conjunction with an Exponential Moving Average (EMA) to identify trend direction and entry points.

Strategy Logic

  1. Trend Identification: Uses a 13-period EMA.
    • Uptrend: Price Close > EMA.
    • Downtrend: Price Close < EMA.
  2. Buy Signal:
    • Market is in an Uptrend.
    • Bears Power is below zero (indicating a price dip/pullback).
    • Bears Power is rising (current bar > previous bar), indicating sellers are losing strength.
  3. Sell Signal:
    • Market is in a Downtrend.
    • Bulls Power is above zero (indicating a price rally/pullback).
    • Bulls Power is falling (current bar < previous bar), indicating buyers are losing strength.

MQL4 Code

//+------------------------------------------------------------------+
//|                                       BullsBearsPower_Strategy.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   Inp_Settings     = "--- Strategy Settings ---"; // Strategy Settings
input int      Inp_Period       = 13;          // Indicator Period (EMA, Bulls, Bears)
input double   Inp_LotSize      = 0.1;         // Fixed Lot Size
input int      Inp_StopLoss     = 50;          // Stop Loss (in pips)
input int      Inp_TakeProfit   = 100;         // Take Profit (in pips)
input int      Inp_MagicNum     = 123456;      // Magic Number
input int      Inp_Slippage     = 3;           // Max Slippage (pips)
input bool     Inp_UseTrailing  = true;        // Use Trailing Stop
input int      Inp_TrailDist    = 30;          // Trailing Distance (pips)

//--- Global Variables
double m_point;
int    m_digits;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // Adjust point for 3/5 digit brokers
   if(Digits == 3 || Digits == 5)
   {
      m_point = Point * 10;
      m_digits = Digits;
   }
   else
   {
      m_point = Point;
      m_digits = Digits;
   }

   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // Clean up if necessary
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // 1. Basic Checks
   if(Bars < Inp_Period + 2) return; // Not enough history
   if(!IsTradeAllowed()) return;     // Trading not allowed

   // 2. Manage Open Trades (Trailing Stop)
   if(Inp_UseTrailing) ManageTrailingStop();

   // 3. Check for New Entry Signals only if we have no open trades
   // (Simple logic: one trade at a time per symbol/magic number)
   if(CountOpenTrades() == 0)
   {
      // Get Indicator Values for Bar 1 (Closed Bar) and Bar 2 (Previous)
      // We use closed bars to avoid repainting
      
      // EMA for Trend Direction
      double ema1 = iMA(NULL, 0, Inp_Period, 0, MODE_EMA, PRICE_CLOSE, 1);
      
      // Bulls Power
      double bulls1 = iBullsPower(NULL, 0, Inp_Period, PRICE_CLOSE, 1);
      double bulls2 = iBullsPower(NULL, 0, Inp_Period, PRICE_CLOSE, 2);
      
      // Bears Power
      double bears1 = iBearsPower(NULL, 0, Inp_Period, PRICE_CLOSE, 1);
      double bears2 = iBearsPower(NULL, 0, Inp_Period, PRICE_CLOSE, 2);
      
      // Close Prices
      double close1 = iClose(NULL, 0, 1);

      // --- BUY SIGNAL LOGIC ---
      // 1. Trend is UP (Close > EMA)
      // 2. Bears Power is negative (Price dipped below EMA)
      // 3. Bears Power is rising (bears1 > bears2) - Momentum turning up
      if(close1 > ema1 && bears1 < 0 && bears1 > bears2)
      {
         OpenTrade(OP_BUY);
      }

      // --- SELL SIGNAL LOGIC ---
      // 1. Trend is DOWN (Close < EMA)
      // 2. Bulls Power is positive (Price rallied above EMA)
      // 3. Bulls Power is falling (bulls1 < bulls2) - Momentum turning down
      if(close1 < ema1 && bulls1 > 0 && bulls1 < bulls2)
      {
         OpenTrade(OP_SELL);
      }
   }
}

//+------------------------------------------------------------------+
//| Helper: Open Order                                               |
//+------------------------------------------------------------------+
void OpenTrade(int type)
{
   double price, sl, tp;
   color clr;

   if(type == OP_BUY)
   {
      price = Ask;
      sl = (Inp_StopLoss > 0) ? price - Inp_StopLoss * m_point : 0;
      tp = (Inp_TakeProfit > 0) ? price + Inp_TakeProfit * m_point : 0;
      clr = clrBlue;
   }
   else
   {
      price = Bid;
      sl = (Inp_StopLoss > 0) ? price + Inp_StopLoss * m_point : 0;
      tp = (Inp_TakeProfit > 0) ? price - Inp_TakeProfit * m_point : 0;
      clr = clrRed;
   }

   // Normalize prices
   price = NormalizeDouble(price, Digits);
   sl    = NormalizeDouble(sl, Digits);
   tp    = NormalizeDouble(tp, Digits);

   int ticket = OrderSend(Symbol(), type, Inp_LotSize, price, Inp_Slippage, sl, tp, "BullsBears EA", Inp_MagicNum, 0, clr);

   if(ticket < 0)
   {
      Print("OrderSend failed with error #", GetLastError());
   }
}

//+------------------------------------------------------------------+
//| Helper: 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() == Inp_MagicNum)
         {
            count++;
         }
      }
   }
   return(count);
}

//+------------------------------------------------------------------+
//| Helper: Trailing Stop Logic                                      |
//+------------------------------------------------------------------+
void ManageTrailingStop()
{
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == Inp_MagicNum)
         {
            if(OrderType() == OP_BUY)
            {
               if(Bid - OrderOpenPrice() > Inp_TrailDist * m_point)
               {
                  double newSL = NormalizeDouble(Bid - Inp_TrailDist * m_point, Digits);
                  if(newSL > OrderStopLoss())
                  {
                     if(!OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE))
                        Print("Error modifying Buy Trailing Stop: ", GetLastError());
                  }
               }
            }
            else if(OrderType() == OP_SELL)
            {
               if(OrderOpenPrice() - Ask > Inp_TrailDist * m_point)
               {
                  double newSL = NormalizeDouble(Ask + Inp_TrailDist * m_point, Digits);
                  if(newSL < OrderStopLoss() || OrderStopLoss() == 0)
                  {
                     if(!OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE))
                        Print("Error modifying Sell Trailing Stop: ", GetLastError());
                  }
               }
            }
         }
      }
   }
}

Q&A: Strategy Details

Q: Why are both Bulls Power and Bears Power used?
A: This strategy implements the "Elder-Ray" approach. The Bulls Power indicator measures the ability of buyers to push prices above the average consensus (EMA), while Bears Power measures the ability of sellers to push prices below it. Using both allows us to detect when the dominant market force (Trend) is temporarily weakening (Pullback) before resuming.

Q: Why does the code use shift 1 and shift 2 instead of 0?
A: In MQL4, index 0 represents the currently forming bar. The High, Low, and Close of the current bar change with every tick. If we trade based on index 0, the signal might appear and disappear within the same candle (repainting). Using index 1 ensures the candle has closed and the signal is confirmed and permanent.

Q: How does the Trailing Stop work in this code?
A: The trailing stop activates once the price moves in your favor by the Inp_TrailDist amount. It then moves the Stop Loss to maintain that distance behind the current price (Bid for Buys, Ask for Sells), locking in profits as the trend continues.

Q: Can I use this on any timeframe?
A: Yes, the logic is timeframe-independent. However, the Elder-Ray system is traditionally most effective on H1 (1-Hour) and D1 (Daily) charts. You may need to adjust Inp_StopLoss and Inp_TakeProfit depending on the volatility of the timeframe chosen.