23 C
New York
Saturday, June 7, 2025

Constructing a Martingale Grid Buying and selling Technique in MQL5 (Half 1) – Buying and selling Techniques – 6 June 2025


Constructing a Martingale Grid Buying and selling Technique in MQL5

Abstract: This text presents an entire implementation of a Martingale-based grid buying and selling technique in MQL5. We’ll look at the code construction, threat administration options, and potential enhancements for this controversial however highly effective buying and selling strategy.

1. Introduction to Martingale Grid Buying and selling

The Martingale technique is a widely known (and sometimes controversial) buying and selling strategy the place place sizes are elevated after losses, with the expectation that eventual wins will recuperate earlier losses. When utilized as a grid technique, it entails inserting orders at progressively higher costs because the market strikes in opposition to your preliminary place.

How Grid Martingale Works:

  • An preliminary place is opened on the present market worth
  • Extra positions are added at predetermined intervals as worth strikes in opposition to you
  • Every subsequent place is bigger than the earlier (usually 1.5-2x)
  • All positions are closed when the typical break-even worth is reached

Key Dangers to Contemplate:

  • Margin depletion: Exponential place progress can shortly eat accessible margin
  • No assured restoration: Robust tendencies can proceed past your grid ranges
  • Psychological stress: Requires self-discipline to handle rising losses

2. The MQL5 Implementation

Let’s look at the entire code construction with detailed explanations for every part.

2.1. Contains and Preliminary Setup

#embrace <Commerce/Commerce.mqh>
CTrade commerce;

#embrace <TradeAccountInfo.mqh>
static CAccountInfo accountInfo;

Clarification:

  • CTrade class supplies simplified commerce execution strategies (market orders, place administration)
  • CAccountInfo offers entry to account-related capabilities (margin checks, steadiness data)

2.2. Grid Buying and selling Parameters


double initialLotSize = 0.01;
double lotMultiplier = 1.5;
int gridStepPoints = 300;
double gridStep = gridStepPoints * _Point;
int breakEvenTPPoints = 100;
double breakEvenTP = breakEvenTPPoints * _Point;
int digits_number;


double currentBuyGridStep = 0;

Parameter Breakdown:

ParameterDescriptionDefault Worth
initialLotSizeBeginning place dimension0.01 tons
lotMultiplierPlace dimension multiplier for every new grid stage1.5x
gridStepPointsDistance between grid ranges in factors300 factors
breakEvenTPPointsTake-profit distance in factors for break-even exit100 factors

2.3. Initialization Perform

void InitializeVariables() {
    digits_number = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);
    
    if (currentBuyGridStep == 0) {
        currentBuyGridStep = gridStep;
    }
}

Key Features:

  • SymbolInfoInteger(_Symbol, SYMBOL_DIGITS) – Will get the variety of decimal locations for the present image
  • Initializes currentBuyGridStep if not already set

3. Core Buying and selling Logic

3.1. Principal Execution Movement

void OnTick() {
    InitializeVariables();
    RunTradingStrategy();
}

void RunTradingStrategy() {
   int nr_buy_positions = CountBuyPositions();
   double askPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);

   
   if (nr_buy_positions == 0) {
      OpenInitialBuyPosition();
   }

   CheckBuyGridLevels();
   SetBreakEvenTP();
}

Course of Movement:

  1. Initialize mandatory variables on every tick
  2. Rely present purchase positions
  3. Open preliminary place if none exists
  4. Examine if new grid ranges ought to be triggered
  5. Monitor for break-even exit circumstances

3.2. Place Counting Perform

int CountBuyPositions() {
   int depend = 0;
   for (int i = 0; i < PositionsTotal(); i++) {
      ulong ticket = PositionGetTicket(i);
      if (PositionSelectByTicket(ticket) && 
          PositionGetString(POSITION_SYMBOL) == _Symbol &&
          PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) {
         depend++;
      }
   }
   return depend;
}

Key Factors:

  • Iterates by way of all open positions
  • Filters positions for present image and purchase sort
  • Returns depend of matching positions

4. Grid Place Administration

4.1. Opening the Preliminary Place

void OpenInitialBuyPosition() {
   double askPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK); 
   double lotSize = NormalizeLotSize(initialLotSize);
   double requiredMargin = accountInfo.MarginCheck(_Symbol, ORDER_TYPE_BUY, lotSize, askPrice);
   
   if(requiredMargin > accountInfo.FreeMargin()) {
      Print("Not sufficient margin for preliminary purchase! Required: ", requiredMargin, " Free: ", accountInfo.FreeMargin());
      return;
   }

   if (!commerce.Purchase(lotSize, _Symbol, askPrice, 0, 0, "Preliminary Purchase")) {
      Print("Preliminary purchase error: ", GetLastError());
   } else {
      Print("Preliminary purchase place opened at ", askPrice, " with lot dimension ", lotSize);
   }
}

Security Options:

  • Lot dimension normalization to adjust to dealer restrictions
  • Margin examine earlier than opening place
  • Error dealing with and logging

4.2. Grid Stage Monitoring

void CheckBuyGridLevels() {
   double minBuyPrice = DBL_MAX;
   int nr_buy_positions = 0;

   for (int i = 0; i < PositionsTotal(); i++) {
      ulong ticket = PositionGetTicket(i);
      if (PositionSelectByTicket(ticket) && PositionGetString(POSITION_SYMBOL) == _Symbol) {
         if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) {
            double entryPrice = PositionGetDouble(POSITION_PRICE_OPEN);
            if (entryPrice < minBuyPrice) {
               minBuyPrice = entryPrice;
            }
            nr_buy_positions++;
         }
      }
   }

   if (nr_buy_positions > 0) {
      double nextGridBuyPrice = NormalizeDouble(minBuyPrice - currentBuyGridStep, digits_number);
      double currentAsk = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), digits_number);

      if (currentAsk <= nextGridBuyPrice) {
         double newLotSize = NormalizeLotSize(initialLotSize * MathPow(lotMultiplier, nr_buy_positions));
         double requiredMargin = accountInfo.MarginCheck(_Symbol, ORDER_TYPE_BUY, newLotSize, currentAsk);
         
         if(requiredMargin > accountInfo.FreeMargin()) {
            Print("Not sufficient margin for grid purchase!");
            return;
         }

         if (!commerce.Purchase(newLotSize, _Symbol, currentAsk, 0, 0, "Grid Purchase")) {
            Print("Grid purchase error: ", GetLastError());
         }
      }
   }
}

Grid Logic Defined:

  1. Finds the bottom present purchase place worth
  2. Calculates subsequent grid stage worth (present lowest – grid step)
  3. Checks if present ask worth has reached the following grid stage
  4. Calculates new place dimension utilizing exponential progress
  5. Performs margin examine earlier than opening new place

5. Break-Even Exit Technique

void SetBreakEvenTP() {
   double totalBuyVolume = 0;
   double totalBuyCost = 0;

   for (int i = 0; i < PositionsTotal(); i++) {
      ulong ticket = PositionGetTicket(i);
      if (PositionSelectByTicket(ticket) && PositionGetString(POSITION_SYMBOL) == _Symbol) {
         if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) {
            double quantity = PositionGetDouble(POSITION_VOLUME);
            double entryPrice = PositionGetDouble(POSITION_PRICE_OPEN);
            totalBuyVolume += quantity;
            totalBuyCost += entryPrice * quantity;
         }
      }
   }

   if (totalBuyVolume > 0) {
      double breakEvenBuyPrice = NormalizeDouble((totalBuyCost / totalBuyVolume) + breakEvenTP, digits_number);
      double currentBid = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), digits_number);

      if (currentBid >= breakEvenBuyPrice) {
         CloseAllBuyPositions();
      }
   }
}

Exit Logic:

  • Calculates volume-weighted common entry worth
  • Provides the break-even TP distance to find out exit worth
  • Screens present bid worth in opposition to goal exit worth
  • Closes all positions when goal is reached

6. Danger Administration and Enhancements

6.1. Present Security Options

  • Margin checks earlier than every commerce
  • Lot dimension normalization
  • Break-even exit mechanism

6.2. Potential Enhancements

EnhancementDescriptionImplementation Problem
Dynamic Grid SpacingModify step dimension based mostly on ATR or volatilityMedium
Max Drawdown RestrictCease buying and selling after sure loss thresholdSimple
Trailing CeaseDefend income throughout favorable strikesMedium
Time-Primarily based ExitShut positions after sure time intervalSimple

7. Conclusion

This Martingale grid technique implementation supplies a strong basis for automated grid buying and selling in MQL5. Whereas the strategy might be worthwhile in ranging markets, it carries important threat throughout sturdy tendencies. At all times:

  • Completely backtest with historic information
  • Implement strict threat administration guidelines
  • Monitor efficiency in demo accounts earlier than stay buying and selling

In future articles, we’ll discover enhancements like:

  • Promote-side grid implementation
  • Multi-currency help
  • Superior threat controls

Be aware: The entire supply code for this EA is offered within the hooked up .mq5 file. At all times take a look at totally in a demo atmosphere earlier than contemplating stay buying and selling.

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles