EAs cannot backtest when using the functions SymbolInfoInteger() or SymbolInfoString()?

I am using version 5.00 build 6230. I am writing an EA. If I use functions like SymbolInfoInteger() or SymbolInfoString(), it becomes impossible to perform a backtest.
for (int i = 0; i < SymbolsTotal(false); i++)
{
   string Symb = SymbolName(i, false);
   printf(SymbolInfoInteger(Symb, SYMBOL_CUSTOM));
   printf(SymbolInfoString(Symb, SYMBOL_CURRENCY_MARGIN)+ " " + SymbolInfoString(Symb, SYMBOL_CURRENCY_PROFIT));
}

After clicking 'Start' in the Backtest, it immediately displays 'common synchronization completed' without performing any other functions.



When the use of these functions is removed, the backtest process executes normally. How can I perform backtesting when I need to use the SymbolInfoInteger() or SymbolInfoString() functions?

Nguyen Van Luong:
I am using version 5.00 build 6230. I am writing an EA. If I use functions like SymbolInfoInteger() or SymbolInfoString(), it becomes impossible to perform a backtest.

After clicking 'Start' in the Backtest, it immediately displays 'common synchronization completed' without performing any other functions.



When the use of these functions is removed, the backtest process executes normally. How can I perform backtesting when I need to use the SymbolInfoInteger() or SymbolInfoString() functions?

What are you really trying to achieve ? Your code doesn't make sense in the Tester.
Alain Verleyen #:
What are you really trying to achieve ? Your code doesn't make sense in the Tester.

I would like to determine the exact name of a currency pair using the SYMBOL_CURRENCY_MARGIN and SYMBOL_CURRENCY_PROFIT components. For example, I need to retrieve the "EURGBP" currency pair; however, the naming convention for this pair can vary from one broker to another ("EURGBP", "EURGBP.a", "EURGBP.m", ".EURGBP", etc.), I use FindSymbol("EUR", "GBP") to obtain the exact name as provided by the broker.

string FindSymbol(const string sMargin, const string sProfit)
{
   if (sMargin != sProfit)
   {
      string iSymb;
      for (int i = 0; i < SymbolsTotal(false); i++)
      {
         iSymb = SymbolName(i, false);
         if (!SymbolInfoInteger(iSymb, SYMBOL_CUSTOM))
         {
            if (sMargin == SymbolInfoString(iSymb, SYMBOL_CURRENCY_MARGIN) && 
                sProfit == SymbolInfoString(iSymb, SYMBOL_CURRENCY_PROFIT)) return iSymb;
         }
      }
   }
   return "";
}

In my EA, it is always necessary to calculate the value of 1 point for 1 lot of the EURGBP currency pair. I need this value for cases where the EA might be in use on a different currency pair.

   string Symb = TfoMoc_FindSymbol("EUR", "GBP");
   if (Symb != "")
   {
      double profit;
      double Price1 = iClose(Symb, PERIOD_CURRENT, 0);
      double Price2 = Price1 + SymbolInfoDouble(Symb, SYMBOL_POINT);
      if (OrderCalcProfit(ORDER_TYPE_BUY, Symb, 1, Price1, Price2, profit))
      {
         //
      }
   }
Nguyen Van Luong #:

I would like to determine the exact name of a currency pair using the SYMBOL_CURRENCY_MARGIN and SYMBOL_CURRENCY_PROFIT components. For example, I need to retrieve the "EURGBP" currency pair; however, the naming convention for this pair can vary from one broker to another ("EURGBP", "EURGBP.a", "EURGBP.m", ".EURGBP", etc.), I use FindSymbol("EUR", "GBP") to obtain the exact name as provided by the broker.

In my EA, it is always necessary to calculate the value of 1 point for 1 lot of the EURGBP currency pair. I need this value for cases where the EA might be in use on a different currency pair.

You can't do that in the Tester, as to work with a symbol, it needs to be selected in the Market Watch.

During testing, the "Market Watch" is emulated as well, from which one can obtain information on symbols.

By default, at the beginning of testing, there is only one symbol in the "Market Watch" of the Strategy Tester - the symbol that the testing is running on. All of the necessary symbols are connected to the "Market Watch" of the Strategy Tester (not terminal!) automatically when referred to.

Prior to starting testing of a multi-currency Expert Advisor, it is necessary to select symbols required for testing in the "Market Watch" of the terminal and load the required data. During the first call of a "foreign" symbol, its history will be automatically synchronized between the testing agent and the client terminal. A "foreign" symbol is the symbol other than that on which testing is running.


Documentation on MQL5: Testing Trading Strategies / MQL5 programs
Documentation on MQL5: Testing Trading Strategies / MQL5 programs
  • www.mql5.com
The idea of automated trading is appealing by the fact that the trading robot can work non-stop for 24 hours a day, seven days a week. The robot...

In the tester, every foreign symbol you query has to be synchronized, so looping over all SymbolsTotal(false) symbols can stall the run. If the chart symbol is an FX pair, it's simpler to build the name from its prefix and suffix and select only that one:

Use the CODE button (Alt-S) when inserting code.

A moderator corrected the formatting this time. Please format code properly in future; posts with improperly formatted code may be removed.

string FindSymbol(const string sMargin, const string sProfit)
  {
   string base = SymbolInfoString(_Symbol, SYMBOL_CURRENCY_BASE);
   int pos = StringFind(_Symbol, base);
   if(pos < 0)
      return "";
   string name = StringSubstr(_Symbol, 0, pos) + sMargin + sProfit + StringSubstr(_Symbol, pos + 6);
   if(!SymbolSelect(name, true))
      return "";
   return name;
  }

One correction in your FindSymbol function: to identify EURGBP, compare SYMBOL_CURRENCY_BASE with "EUR" and SYMBOL_CURRENCY_PROFIT with "GBP".

SYMBOL_CURRENCY_MARGIN describes the margin currency, not the base currency, so it is not the appropriate property for identifying the pair.

Also, deriving another symbol’s name from the chart symbol’s prefix/suffix assumes the broker uses the same naming pattern across both instruments. Validate the candidate’s currency properties before using it.

Arnab Karmakar #:

In the tester, every foreign symbol you query has to be synchronized, so looping over all SymbolsTotal(false) symbols can stall the run. If the chart symbol is an FX pair, it's simpler to build the name from its prefix and suffix and select only that one:

string FindSymbol(const string sMargin, const string sProfit) { string base = SymbolInfoString(_Symbol, SYMBOL_CURRENCY_BASE); int pos = StringFind(_Symbol, base); if(pos < 0) return ""; string name = StringSubstr(_Symbol, 0, pos) + sMargin + sProfit + StringSubstr(_Symbol, pos + 6); if(!SymbolSelect(name, true)) return ""; return name; }

Thank you. I only perform it once, during OnInit().
Muhammad Andiya Nafhan #:

One correction in your FindSymbol function: to identify EURGBP, compare SYMBOL_CURRENCY_BASE with "EUR" and SYMBOL_CURRENCY_PROFIT with "GBP".

SYMBOL_CURRENCY_MARGIN describes the margin currency, not the base currency, so it is not the appropriate property for identifying the pair.

Also, deriving another symbol’s name from the chart symbol’s prefix/suffix assumes the broker uses the same naming pattern across both instruments. Validate the candidate’s currency properties before using it.

Thank you. SYMBOL_CURRENCY_BASE and SYMBOL_CURRENCY_PROFIT.

the reads fail, not SymbolInfoString: the tester's watch list starts with only the symbol under test, so a symbol outside it returns 4302, not an empty row. for the pair, _Symbol already returns the broker's name, suffix included, so I don't rebuild EURGBP from the currency rows. that covers the pair the program is on. if it trades one it isn't attached to, you're back to the margin and profit rows, where an empty result is a failed call, not a value. one point on one lot is point over tick size, times tick value; a distance in points multiplies that. if the tick size, tick value or point is zero I treat the value as unknown.