Trading-Strategie Heads or Tails Parsen des Handelsroboter-Codes.

Trading-Strategie Heads or Tails Parsen des Handelsroboter-Codes.

21 Januar 2026, 13:03
Vladimir Pastushak
0
6

The trading strategy “Eagle or Tail” belongs to a category of high-risk short-term trading approaches primarily used on stock markets and Forex. Its name derives from the randomness of decision-making, similar to flipping a coin (“heads” means buying an asset, “tails” means selling). This strategy relies solely on intuitive decisions or random signals while ignoring fundamental market analysis factors.


The original code of the trading strategy has been added to the database:

MetaTrader 5: https://www.mql5.com/de/code/11637


#property copyright "Copyright 2025, Trading-Go." // Setting copyright property
#property link      "https://www.mql5.com/en/channels/tradingo-go-en"  // Setting developer resource link
#property version   "26.010" // Program version

This block represents compiler directives for a program written as a MetaTrader Expert Advisor (EA) or indicator using the MQL4/MQL5 language.

Let’s examine each line separately:

1. #property copyright "Copyright 2025, Trading-Go."

This directive sets legal ownership rights over the source code of the EA or indicator. It specifies the owner of intellectual property rights ("Trading-Go") and helps indicate product affiliation within the MetaTrader client terminal's properties window.

2. #property link " "

This allows setting up a web resource link associated with the developer. When traders use this EA or indicator, this link becomes accessible via the tool's properties menu. It's beneficial for developers since they can direct users to support pages, documentation, or community resources related to their products.

3. #property version "26.010"

Here, we set the version of the software product. Typically, developers specify versions in the format XX.XX, where the first digit denotes major version, second minor version, third patch level. The version helps users track updates easily and maintain compatibility between tools.

#include 

 // Including Trade.mqh library
CTrade        trade; // Object of class CTrade to manage trades

#include 

 // Including PositionInfo.mqh library
CPositionInfo posit; // Object of class CPositionInfo to process positions

This section includes libraries and creates objects that allow managing trading operations and processing account positions in the MetaTrader platform.

We will break down each component:

1. #include

This include statement adds the header file (Trade.mqh) containing the definition of the CTrade class. The file resides in the directory /Trade, meaning it's part of the standard trading operations library provided by MetaTrader. The CTrade class simplifies interaction with trading activities such as opening/closing positions, modifying orders, and retrieving information about ongoing trades.

2. CTrade trade;

An object named 'trade' of the CTrade class is created. Using this object, you gain control over various aspects of trading, including opening new positions, adjusting stop losses/take profits, closing existing positions, etc.

3. #include

A second include directive connects another header file (PositionInfo.mqh) located under the same directory (/Trade). This file defines the CPositionInfo class responsible for handling details regarding currently opened positions. Through this class, detailed information like transaction volumes, entry prices, P&L data, etc., can be extracted.

4. CPositionInfo posit;

Another object called 'posit' is instantiated from the CPositionInfo class. With this object, you can retrieve comprehensive details about all active positions on your trading account, facilitating portfolio analysis and informed decision-making based on retrieved data.

General Purpose:

These two libraries form the foundation for automating trading processes by providing a high-level Application Programming Interface (API). They enable developers to focus directly on implementing strategy logic rather than dealing with low-level broker server interactions.

input double  iLots         = 0.10; // Input parameter for lot size (trade volume)
input int     iTakeProfit   = 450;  // Input parameter for profit fixing level (Take Profit)
input int     iStopLoss     = 390;  // Input parameter for loss limitation level (Stop Loss)
input int     iMagicNumber  = 227; // Input parameter for unique deal number (Magic Number)
input int     iSlippage     = 30; // Input parameter for maximum price slippage

string sy = ""; // Variable to store instrument symbol
double pt = 0; // Variable for point calculation step
int    dt = 0; // Variable for decimal places count

Each element of the given code snippet serves specific purposes in configuring an automatic expert advisor (Expert Advisor) within the MetaTrader platform. Let us explore them individually:


Input Parameters:

1. iLots = 0.10;

This input parameter of type double determines the size of the lot (volume per trade). Defaulted at 0.10, it controls how many units of assets are bought or sold in every single trade. For example, if the instrument is EURUSD, then a lot size of 0.1 corresponds to ten thousand base currency units (like euros).

2. iTakeProfit = 450;

An integer-type parameter defining the profit-fixation level (Take Profit). Set to default at 450 pips, this automatically closes out a position when the market reaches the designated profit threshold relative to the entry price.

3. iStopLoss = 390;

Also an integer parameter, it establishes the loss-limitation level (Stop Loss). By default, its value equals 390 pips. Stop Loss ensures automatic closure if the market moves against the position and losses reach the defined limit.

4. iMagicNumber = 227;

An integer parameter serving as a unique identification number (Magic Number) for transactions. Each event—position opening, closing, etc.—receives a unique magic number, allowing filtering deals by this criterion. The default value here is 227.

5. iSlippage = 30;

Another integer parameter limiting the maximum acceptable deviation during order execution. A value of 30 indicates the tolerance range beyond which an order won’t execute due to excessive slippage protection.

Local Variables:

1. sy = "";

A string variable storing the financial instrument symbol (e.g., "EURUSD") utilized for trading. Initially empty.

2. pt = 0;

A double variable intended for calculating the point size increment of the chosen instrument. Used later for computing accurate SL/TP values depending on pip sizes.

3. dt = 0;

An integer variable tracking the number of decimal places after the decimal point in pricing quotes. Varying instruments have different decimal place counts (e.g., USDJPY has 2 decimals, EURUSD has 4). Knowing this ensures proper rounding and computation.

This segment initializes core configurations and prepares the environment for automated Expert Advisors in MetaTrader. The input parameters provide flexibility for customizing EA behavior before initiating trades.

   sy = _Symbol; // Getting current trading instrument
   pt = _Point; // Getting minimum unit change size
   dt = _Digits; // Getting number of decimal digits in price

   trade.SetExpertMagicNumber(iMagicNumber); // Setting unique deal number for trade operations

   trade.SetDeviationInPoints(iSlippage); // Setting maximum price deviation points

   trade.SetTypeFillingBySymbol(sy); // Setting order execution type according to instrument settings

   trade.SetMarginMode(); // Setting margin mode


This block demonstrates initialization steps critical for successful functioning of an Expert Advisor (EA) in MetaTrader. We’ll analyze each command closely:

Environmental Variables Setup:

1. sy = _Symbol;

Assigns the global variable sy the name of the current trading instrument being worked upon. _Symbol is a built-in constant returning the name of the selected asset in the terminal. Thus, we obtain access to the instrument necessary for further calculations and work.

2. pt = _Point;

Sets the variable pt to represent the smallest change in cost for the instrument (_Point). This basic measurement of price movement is essential for correctly interpreting system signals and adjusting trade orders accordingly.

3. dt = _Digits;

Defines the variable dt representing the number of decimal places in the price quote of the current instrument. Different instruments may vary in precision (e.g., USDJPY has two decimal places, whereas EURUSD has four). Hence, this variable plays a crucial role in ensuring correct rounding and computations.


Configuring the Trading Object:

4. trade.SetExpertMagicNumber(iMagicNumber);

Establishes a unique magic number (Magic Number) for all transactions initiated by this EA. Magic numbers help identify transactions executed specifically by the EA, making filtering easier. Uniqueness guarantees clarity among multiple robotized strategies.

5. trade.SetDeviationInPoints(iSlippage);

Limits the maximum permissible deviation during order executions, protecting against large market fluctuations. By setting a fixed value (e.g., 30 pips), only trades with minimal deviations are executed, enhancing accuracy.

6. trade.SetTypeFillingBySymbol(sy);

Adjusts the order filling method according to the characteristics of the particular instrument. Some symbols require instant execution ('Market Execution'), others permit delayed fulfillment ('Instant Execution'). This command auto-selects the appropriate mode based on the instrument's specifications.

7. trade.SetMarginMode();

Configures the margin mode, affecting free capital requirements needed to sustain positions. Correct setup minimizes risks associated with forced position closure due to insufficient capital.

   double stepvol = SymbolInfoDouble(sy, SYMBOL_VOLUME_STEP); // Get the lot size change step for the selected symbol
   if(stepvol > 0.0) // If the lot size step is positive, apply calculation of adjusted lot size
      lt = stepvol * (MathFloor(iLots / stepvol) - 1); // Round down the lot size to the nearest step value and decrease by one step
//---
   double minvol = SymbolInfoDouble(sy, SYMBOL_VOLUME_MIN); // Get minimum allowed lot size for the specified symbol
   if(lt < minvol) // If the adjusted lot size is less than the minimum possible value, reset it to zero
      lt = 0.0;

   ::MathSrand(GetTickCount()); // Generating initial number for random generator

The presented code dynamically regulates the trade volume (lot size) within permitted boundaries set by the exchange for a given instrument (currency pair, stock, contract, etc.). The primary goal is to ensure lot adjustments comply with exchange rules, preventing errors during position openings and maintaining secure trading conditions.

Let's delve into each stage in detail:

Step 1: Determining Lot Size Step:

double stepvol = SymbolInfoDouble(sy, SYMBOL_VOLUME_STEP);

This retrieves the incremental step size for changing the lot amount of the selected symbol (SYMBOL_VOLUME_STEP). This step dictates the smallest interval by which lot sizes can be modified. For instance, some instruments might have a step size of 0.01, implying trades must occur in increments of hundredths of lots.

Step 2: Verifying Positive Step Value:

if(stepvol > 0.0)

Verifies whether the retrieved step size is indeed positive. If non-positive, subsequent calculations become unnecessary.

Step 3: Adjusting Lot Downward by One Step:

lt = stepvol * (MathFloor(iLots / stepvol) - 1);

The algorithm reduces the user-specified lot size (iLots) by exactly one full step increment.

Breakdown of internal operations:

iLots / stepvol: calculates whole steps fitting inside the entered lot.

MathFloor(): rounds fractional result downward to the closest integer.

Subtract one: decreases calculated steps by one.

Multiply back by step: yields corrected lot size.

Step 4: Retrieving Minimum Allowed Lot Size:

double minvol = SymbolInfoDouble(sy, SYMBOL_VOLUME_MIN);

Obtains the minimum allowable lot size for the current symbol (SYMBOL_VOLUME_MIN). Exchanges impose restrictions on minimum lot sizes below which trading isn’t feasible.

Step 5: Ensuring Compliance Below Minimum Limit:

if(lt < minvol)

lt = 0.0;

If the adjusted lot falls below the minimum enforced by the exchange, the lot size resets to zero, avoiding violations.

Step 6: Seeding Random Generator:

::MathSrand(GetTickCount());

Seeds the random number generator with the current tick count obtained via GetTickCount(). This enhances unpredictability for future random sequences.

   int total = ::PositionsTotal(), b = 0, s = 0; // Total open positions and purchase/sale counters

   double Bid = ::SymbolInfoDouble(sy, SYMBOL_BID); // Current bid price (selling price)
   double Ask = ::SymbolInfoDouble(sy, SYMBOL_ASK); // Current ask price (buying price)

   double new_sl = 0, new_tp = 0, old_sl = 0, old_tp = 0; // New and old stop loss and take profit levels

   if(Bid <= 0 || Ask <= 0) // If prices are invalid
      return; // Exit function prematurely

This block performs several preparatory actions prior to executing deeper trade logic within an Expert Advisor (EA) in the MetaTrader platform. Here’s a breakdown of each action:

Initialization Steps:

1. Count Open Positions:

int total = ::PositionsTotal();

Retrieves the total number of active positions across all accounts regardless of direction or instrument. These statistics aid in analyzing and optimizing overall exposure.

2. Initialize Purchase/Sale Counters:

b = 0, s = 0;

Two variables (b and s) initialize purchase and sale counters respectively. Both start at zero but increment during position evaluations.

Current Market Prices Retrieval:

3. Fetch Bid Price:

Bid = ::SymbolInfoDouble(sy, SYMBOL_BID);

Requests the latest known buy price (bid) for the current instrument (sy). The bid reflects the best available sell-offer in the market.

4. Fetch Ask Price:

Ask = ::SymbolInfoDouble(sy, SYMBOL_ASK);

Similarly fetches the last-known sell price (ask) for the same instrument. The ask shows the best buy offer immediately executable.

Preparing Stop Loss/Take Profit Levels:

5. Declare New/Old Stop Loss/Take Profit Values:

new_sl = 0, new_tp = 0, old_sl = 0, old_tp = 0;

Four variables predefine stop-loss and take-profit levels both newly computed and previously established. Initial zeros imply absence until computed.

Safety Precaution:

6. Verify Validity of Retrieved Prices:

if(Bid <= 0 || Ask <= 0)

return;

Checks whether either bid or ask prices are valid. Invalid prices halt further execution, safeguarding against erroneous operations.

 for(int i = 0; i < total; i++) // Iterate through open positions
      if(posit.SelectByIndex(i)) // Select position by index
         if(posit.Symbol() == sy) // Ensure instrument matches
            if(posit.Magic() == iMagicNumber) // Validate unique identifier
              {

               old_sl = ::NormalizeDouble(posit.StopLoss(),   dt); // Convert old stop loss to required decimal precision
               old_tp = ::NormalizeDouble(posit.TakeProfit(), dt); // Convert old take profit to required decimal precision

               if(posit.PositionType() == POSITION_TYPE_BUY) // Process buy (long) positions
                 {
                  new_sl = ::NormalizeDouble(Ask - iStopLoss   * pt, dt); // Calculate new stop loss below current ask price
                  new_tp = ::NormalizeDouble(Ask + iTakeProfit * pt, dt); // Calculate new take profit above current ask price
                  b++;                                                 // Increment purchase counter
                 }

               if(posit.PositionType() == POSITION_TYPE_SELL) // Process sell (short) positions
                 {
                  new_sl = ::NormalizeDouble(Bid + iStopLoss   * pt, dt); // Calculate new stop loss above current bid price
                  new_tp = ::NormalizeDouble(Bid - iTakeProfit * pt, dt); // Calculate new take profit below current bid price
                  s++; // Increment sale counter
                 }

               if(old_sl == 0 || old_tp == 0) // Update SL/TP if new levels differ from previous ones
                  trade.PositionModify(posit.Ticket(), new_sl, new_tp);// Apply updated SL/TP levels
              }

This loop iterates through open positions on the account, updating stop-loss (SL) and take-profit (TP) levels for relevant positions. Let's walk through each operation:

Iteration Over Open Positions:

for(int i = 0; i < total; i++)

Iterates sequentially through all open positions stored internally.

Selecting Specific Position:

if(posit.SelectByIndex(i))

Attempts to select a position by its sequential index within the list. Only successfully retrieved positions proceed forward.

Matching Instrument and Identifier:

if(posit.Symbol() == sy && posit.Magic() == iMagicNumber)

Ensures the retrieved position aligns with the targeted instrument (sy) and carries the expected unique identifier (magic number).

Updating Stop Loss and Take Profit:

For Long Positions:

if(posit.PositionType() == POSITION_TYPE_BUY)

Processes positions classified as buys (long). Updates SL and TP based on current market prices.

For Short Positions:

if(posit.PositionType() == POSITION_TYPE_SELL)

Handles sell (short) positions similarly, adjusting SL and TP according to corresponding market rates.

Applying Changes:

if(old_sl == 0 || old_tp == 0)

trade.PositionModify(posit.Ticket(), new_sl, new_tp);

Updates stop-loss and take-profit levels if new values deviate significantly from old ones.

   if((b + s) == 0) // No active positions exist
      if(::MathRand() % 2 == 0) // Randomly choose trade direction
        {
         if(trade.CheckVolume(sy, lt, Ask, ORDER_TYPE_BUY)) // Verify sufficient funds for desired trade
            if(trade.Buy(lt)) // Execute buy (long) position
               return; // Terminate function execution
        }
      else
         if(trade.CheckVolume(sy, lt, Bid, ORDER_TYPE_SELL)) // Verify sufficient funds for desired trade
            if(trade.Sell(lt)) // Execute sell (short) position
               return; // Terminate function execution

Here we observe the mechanism for randomly deciding whether to initiate a long (BUY) or short (SELL) position when no other active positions exist on the account. Let's review each step carefully:

Check Active Positions:

if((b + s) == 0)

Confirms the absence of any active positions (both buy and sell). Only proceeds if none are found.

Random Direction Selection:

if(MathRand() % 2 == 0)

Generates a random choice between long (BUY) and short (SELL) directions using MathRand() modulo 2.

Executing Long Position:

if(trade.CheckVolume(sy, lt, Ask, ORDER_TYPE_BUY))

Validates availability of adequate funds for executing the desired long trade using the CheckVolume() method.

Execution Logic:

if(trade.Buy(lt))

Initiates a long position (BUY) with the specified lot size (lt). Upon success, terminates further execution.

Alternative Pathway (Short Position):

else

if(trade.CheckVolume(sy, lt, Bid, ORDER_TYPE_SELL))

Follows a parallel path if the random selection favored a short position (SELL). Again verifies funding adequacy.

Final Action:

if(trade.Sell(lt))

Opens a short position (SELL) if funds suffice, halting execution thereafter.

void OnDeinit(const int reason) // Deinitialization function
  {

  }

Leaving the deinitialization function blank is typical unless special cleanup tasks need implementation. Even though left empty, having this placeholder reminds developers of potential clean-up opportunities should they arise later.

Conclusion:

This segment outlines simple yet effective mechanisms for initializing random position openings in scenarios lacking active positions. Focus remains on validating fund availability and securing trade initiation through precise market-pricing methods.