MQL Source Checklist

MetaTrader 4
GogoJungle
2023/04/13 19:34
120

MQL source code check items

The following is a description of the MQL source code items checking conducted at GogoJungle.
Please use this as a checklist when you register your EA for sale.

—.

The EA check process is as follows:

  1. source code check (mq4)
  2. back test check via with Strategy Tester
  3. demo account run check

Please note that this check does not guarantee the performance of the EA.


The source code (mq4):

This section describes specific source code checks (mq4).

1. Parameter management

1-1. Magic number input

  • The input can be changed to any value using parameters.
[Example
extern int MagicNumber = 123456;
input int MAGIC = 123456;

1-2. Magic number input change (when upgrading)

  • Check that the magic number is the same as it was prior to the upgrade (search for extern or input to check)

2. Position management

2-1. Number of Positions

  • The number of positions is counted by determining the currency pair and magic number (check by searching for OrdersTotal)
[Example.
      //-------- entering a new position --------
      // Count the number of positions
      for(i=OrdersTotal()-1; i>=0; i--)
      {
         // Select orders (if an error occurs, break out of the loop)
         if (OrderSelect( i, SELECT_BY_POS, MODE_TRADES ) == false)
         {
            Print("OrderSelect returned the error of ", GetLastError() );
            break; }
         }
         
         // Order confirmation (if the currency pair does not match, return to the beginning of the for statement)
         if (OrderSymbol() ! = Symbol()) continue; }
         
         //Confirm magic number (if the magic number does not match, return to the top of the for statement)
         if (OrderMagicNumber() ! = MagicNumber) continue; if (OrderMagicNumber() !
   
         if (OrderType() == OP_BUY)
         {
            CountBuy = CountBuy + 1; }
         }
         
         if (OrderType() == OP_SELL)
         {
            CountSell = CountSell + 1; }
         }
      }     

3. Entry Processing

3-1. Maximum number of positions

  • As a prerequisite, the current number of positions held and the maximum number of positions are compared and determined
    (check by searching with OrderSend).
[Example
if (countbuy<MaxPos) { 
   int ticket = -1;
   ticket=OrderSend(NULL,OP_BUY,lot,Ask,Slippage,0,0,Com,MagicNumber,0,Blue);

3-2. Magic Number input

  • The magic number (specified in 1-1.) must be set when making an entry (in the 9th argument in the OrderSend function).
[Example.
OrderSend(NULL,OP_BUY,lot,Ask,Slippage,0,0,Com,MagicNumber",0,Blue);
[Example.
OrderSend(NULL,OP_BUY,lot,Ask,Slippage,0,0,Com,MagicNumber",0,Blue);

3-3. Currency Pair;

  • When making an entry (in the OrderSend function), the currency pair must be Symbol() or NULL.
    (If fixed, USDJPYm, USDJPY_ or other characters depending on the broker are taken into account)
[Example
OrderSend("Symbol()",OP_BUY,lot,Ask,Slippage,0,0,Com,MagicNumber,0,Blue);

3-4. Stop loss setting (when there is no logic settlement by OrderClose: when only SL and TP are settled)

  • Check that the stop loss is set at the time of entry (search for OrderClose to confirm)
  • Check with 5 arguments (*5th argument can be omitted)
  • Confirmation of order changes for limit and stop positions.

The following is an invalid example because if OrderModify fails, SL and TP will never be set again

[NG Example.
if( EntryPosition == 1 ) //Entry condition for buy.
{
	 res=OrderSend(Symbol(),OP_BUY,Lots ,Ask,SLP,0,0, "TrendLogic",MAGIC,0,Red);
	 if (OrderSelect(res,SELECT_BY_TICKET)==true)
	 {
		 if (Buy_stoploss!=0) SL=OrderOpenPrice()-Buy_stoploss*AdjustPoint(Symbol());
		 if (Buy_takeprofit!=0) TP=OrderOpenPrice()+Buy_takeprofit*AdjustPoint(Symbol());
	 }
	 Modified=OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP,0,Red); }
}
else if(EntryPosition == -1 ) //---- SellEntry
{
	 res=OrderSend(Symbol(),OP_SELL,Lots,Bid,SLP,0,0, "TrendLogic",MAGIC,0,White); }
	 if(OrderSelect(res,SELECT_BY_TICKET)==true)
	 {
		 if(Sell_stoploss!=0) SL=OrderOpenPrice()+Sell_stoploss*AdjustPoint(Symbol());
		 if(Sell_takeprofit!=0) TP=OrderOpenPrice()-Sell_takeprofit*AdjustPoint(Symbol());
	 }
	 Modified=OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP,0,White); }
}
  • When making a proposal to a broker, check the stop loss settings regardless of the logic.

The following is a way to force sl,tp to be set at the time of order

[Before modification
ticket=OrderSend(symbol,OP_BUY,Lots,Ask,Slippage,0,0,NULL,MagicNumber,0,Blue);
if(ticket>=0)
	if(OrderModify(ticket,OrderOpenPrice(),sl,tp,0))
	{
		lastTime=now;
		entry_cnt++;
	}
[After modification
ticket=OrderSend(symbol,OP_BUY,Lots,Ask,Slippage,sl,tp,NULL,MagicNumber,0,Blue);
if(ticket>=0)
	{
		lastTime=now;
		entry_cnt++;
	}

3-5. Verify lot calculation process (if the lot is variable: martingale, compound interest, etc.)

  • When restarting MT4, the variables are initialized (so that they are not reacquired) and the conditional processing that affects the logic does not occur

4. Settlement processing

Magic number.

  • The magic number and currency pair must be determined as preconditions.
[Example.
for( i=OrdersTotal()-1; i>=0; i-- ){
  if( OrderSelect(i, SELECT_BY_POS) == true ){
    if( OrderType() == OP_BUY && OrderMagicNumber() == Magic && OrderSymbol() == Symbol() ){
      if( ! (OrderClose(OrderTicket(),OrderLots(),MarketInfo(Symbol(),MODE_BID),Slippage,Green)){

4-2. Confirmation of tickets for settlement

  • After the magic number and currency pair are determinatined, the ticket subject to settlement should not change (OrderSelect should not be executed).

The following is invalid because of the pattern of ticket change at the time of settlement

for( i=OrdersTotal()-1; i>=0; i-- ){
  if( OrderSelect(i, SELECT_BY_POS) == true ){
    if( OrderType() == OP_BUY && OrderMagicNumber() == Magic && OrderSymbol() == Symbol() ){
      OrderTicketChange();.
      if( ! (OrderClose(OrderTicket(),OrderLots(),MarketInfo(Symbol(),MODE_BID),Slippage,Green)){
void OrderTicketChange()
  {
   OrderSelect(3, SELECT_BY_POS); }   
  }

4-3. Retry processing

  • Even if settlement fails once, settlement judgment and processing must be performed again for each tick (settlement failure must be taken into account).

If infinite loop processing is used, it is NG.

[Example.
bool closePosition(int magic, int type = -1) //function to process settlement.
{
   int result_count = 0; //number of attempts
   int close_signal = 0; //0 means success, non-zero means failure

   if(IsTradeAllowed() == true) {
      for(int i = OrdersTotal() - 1; i >= 0; i--) {
         if(OrderSelect(i, SELECT_BY_POS) == false) continue;
         if(OrderSymbol() ! = Symbol() || OrderMagicNumber() ! = magic) continue; if(type >= 0 &&
         if(type >= 0 && OrderType() ! = type) continue; if(OrderType() !
         RefreshRates(); if(OrderClose(OrderType() !

if(OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage, ArrowColor[OrderType()]) == true) {
            continue; //first close process (usually succeeds here)
         }else{ //processing in case of settlement failure from here
            result_count = 0; for(int j = 0; j = 0; j = 0; j = 0; j = 0
            for(int j = 0; j < RETRY_COUNT; j++) { //repeat processing until retry count is reached
               Sleep(200);

               if(OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage, ArrowColor[OrderType()]) == true) { 
                  break; //exit from the loop if successful
               }else{ //in case of failure
                  int err = GetLastError();
                  if(err > 0){
                     result_count++; //increase the counter for the number of failures
                     Print("[OrderClose Error] : ", err, " ", ErrorDescription(err)); }
                  }
               }
               if(result_count == RETRY_COUNT) { //when the counter reaches the specified number of attempts
                  close_signal++; //signal settlement failure
               }
            }
         }
   }
      if(close_signal == 0) return(true); //exit the function because of success
      Alert("[OrderClose Error] : Close timeout. Check the experts log."); //Timeout error on failure  
   }
   return(false); //Alert and exit the function.
}

4-4. Settlement Conditions:

  • When restarting MT4, the variables are initialized (because they are not reacquired) and the conditional processing that affects the logic does not occur

It is invalid if variables used for settlement conditions are initialized upon restart.

5. Exception handling

5-1. Confirmation of error handling

  • Loop processing while must not result in an infinite loop (error handling patterns must be covered).
[Good example: Timeout handling is described.
while(true)
{
int hoge; //variable that becomes 1 when processing is successful

   //**** where processing such as settlement***//

if(hoge) return(true);

   // timeout processing
   if (GetTickCount() - StartTime > 10 * 1000)
   {
      Alert("OrderSend timeout. Check the experts log."); { return(-1); }
      
      return(-1); }
   }
[Bad example: timeout processing is not described.
while(true)
{
int hoge; //variable that becomes 1 if processing is successful

   //**** where processing such as settlement***//

if(hoge) return(true); }
   }
[Other examples of loop escaping
// If the error is not resolved by retrying, escape the loop
if(err == ERR_INVALID_PRICE) break; }
if(err == ERR_INVALID_STOPS) break;
if(err == ERR_LONGS_NOT_ALLOWED) break; break
if(err == ERR_SHORTS_NOT_ALLOWED) break; if(err == ERR_SHORTS_NOT_ALLOWED) break;
if(err == ERR_NOT_ENOUGH_MONEY) break; break
if(err == ERR_TRADE_TOO_MANY_ORDERS) break; if(err == ERR_TRADE_TOO_MANY_ORDERS)

Transaction Limitations

6-1. Trading Restrictions Verification

  • Operate with multiple brokers (no restrictions on broker, course, account number, or filename).
[invalid Example: Specifying a brokerage firm (Gaitame)
int OnInit()
{
   if(IsTradeAllowed() == false) {
      Alert("Enable the setting 'Allow live trading' in the Expert Properties!"); }
   }
   if(StringFind(TerminalInfoString(TERMINAL_COMPANY), "Gaitame") == -1) return(INIT_FAILED); //If the brokerage is not "Gaitame", initialization will fail


   magic_array[0] = Magic1;
   bars1 = getBars(Magic1);

   return(INIT_SUCCEEDED); }
}

7. External Processing

7-1. External communication

  • Check that there is no external communication or communication by file (search for http to check)
  • Check that there are no external links (it is invalid if there are any other links than ours)

7-2. External files

  • Confirm that they are not used for the purpose of optimizing backtest results (check by searching for hst,dll)

7-3. lobal variables

  • Global variables (GlobalVariableSet, GlobalVariableGet) are not used.
    (If they are used, they must be implemented without any problems based on an understanding of the characteristics of global variables.)

8. Comment for real trade

OrderSend argument comment confirmation

  • Check that the comment for real trade is applied to the 8th comment of the OrderSend argument in the entry process (search for OrderSend to confirm).
    The comment must be less than 31 single-byte alphanumeric characters in length.
Example: In the case of product ID 12345, product name GogoJungleEA
int ticket = OrderSend( ①, ②, ③, ④, ⑤, ⑥, ⑦, "12345:GogoJungle_EA", ⑨, ⑩, ⑪);

9. Copyright

9-1. Check decompilation

  • Not decompiled code.
[Example
double Gda_280[30];
int G_digits_192=0;
double G_point_196=0.0;
int Gi_204;
double Gd_208;
double Gd_216; double
double Gd_224; double Gd_224;.
  • Check for copyright issues, even for encrypted code, since it is difficult to decrypt.
[Example
int 2516972921474835825095 ;
int 919926175214748358129332 ;
int OnInit()
{
    158651616521474836452710 = 945331452214748360523750 (); int
    1821361779214748361111350 ( 158651616521474836452710 );
  • No license-related statements.
[Example.
//#include <MT4params.mqh>
//#include <MT4License_1.mqh>
//int group_no = 11,group,a1=1; //group number 0:not used
//bool PC_Check = true; // true: do PC binding false: don't do it
//datetime PrevTime;
//string ServerURL0 = "http://reapseven.xsrv.jp/license";
//string ServerURL = "http://fxea.xsrv.jp/license"; //server URL
//string ServerURL2 = "http://fxea.xsrv.jp/license"; //string
//int stp=-1;
//#import "shell32.dll"
//int ShellExecuteW(int hWnd, int lpVerb, string lpFile, string lpParameters, string lpDirectory, int nCmdShow);
//#import
//string DataPath = TerminalInfoString(TERMINAL_DATA_PATH)+"\\MQL4\Libraries";

9-2. Check for Terms of Service violations

  • Do not upload similar sources with multiple accounts (selling with multiple accounts is a violation of the terms of service)

10.Items to be checked in MT5

10-1. Brokerage firm support

  • It is necessary to acquire the value corresponding to 1 or 2 that the securities company has (search by type_filling and confirm)

If 1: ORDER_FILLING_FOK * Default
If 2: ORDER_FILLING_IOC

[Example
int FillingMode=(int)SymbolInfoInteger(_Symbol,SYMBOL_FILLING_MODE);
if(FillingMode == 2){
      request.type_filling = ORDER_FILLING_IOC;
}

10-2. Calculating the number of positions held

  • Determine the currency pair and magic number, and that the number of positions is counted (check by searching for PositionsTotal).
[Example
   int pos = 0;.
   int posTotal=PositionsTotal();
   for( int posIndex=0; posIndex<posTotal; posIndex++ )
     {
      const ulong ticket=PositionGetTicket(posIndex);
      if(PositionSelectByTicket(ticket) &&
         PositionGetString(POSITION_SYMBOL)==_Symbol &&
         PositionGetInteger(POSITION_MAGIC)==Magic_Number)
        {
            pos++; }
        }
     }
  }

10-3. Entry

  • Entry is ordered with a magic number of the user’s choice at the time of entry.
  • The order is placed with the broker’s consideration value for the currency pair at the time of entry.
  • SL/TP is set if there is no settlement order logic.
[Example
input int Magic_Number;
MqlTradeRequest request;
MqlTradeResult result;

request.action = TRADE_ACTION_DEAL;
request.magic = Magic_Number;
request.symbol = _Symbol;
request.volume = 0.1;
request.sl = stoploss;
request.tp = takeprofit;
request.position = 0;

OrderSend(request,result);

10-4. Settlement

  • Correct positions are closed (i.e., positions acquired by other EAs are not closed by mistake).
    Settlement orders are placed with a ticket number.
  • Failure of a settlement order must be taken into account.
  • Initialization of global variables must be taken into account.
[Example
   int posTotal=PositionsTotal();
   for( int posIndex=0; posIndex<posTotal; posIndex++ )
     {
      const ulong ticket=PositionGetTicket(posIndex);
      if(PositionSelectByTicket(ticket) &&
         PositionGetString(POSITION_SYMBOL)==_Symbol &&
         PositionGetInteger(POSITION_MAGIC)==Magic_Number)
        {
           MqlTradeRequest request request; MqlTradeResult result
           MqlTradeResult result;

           request.action = TRADE_ACTION_DEAL;
           request.magic = Magic_Number;
           request.symbol = _Symbol;
           request.volume = 0.1;
           request.sl = 0;
           request.tp = 0;
           request.position = ticket;

           OrderSend(request,result);
        }
     }
  }

Conclusion

GogoJungle performs the above source checks on all EAs.
Please report any operational problems or new information to us.

We will update the checked items as needed based on your reports.

We look forward to receiving your EAs.

コメント

関連トピックス

検索結果がありません。

ノーコードで誰でも簡単EA開発!MQL言語学習にも使える! | GogoJungle

注目トピックス

検索結果がありません。