Libraries: Expert - page 13

 
fxsaber #:

If there is a problem, please give ready mq5 files for playback.

#define  MT4ORDERS_LIBRARY
#include "../../utils/MT4Orders.mqh" 
// #define REPORT_BROWSER // Creating a report with browser startup - requires DLL permission.
#define  TESTER_CUSTOM // Running the Expert Advisor in the User Tester
#include "../../utils/fxsaber/Tester/Tester.mqh" // https://www.mql5.com/en/code/24848

#define  Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
#define  Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

#define  KEY_B 66
#define  KEY_S 83
#define  KEY_C 67

input int In1 = 1;
input group "label1"
input double In2 = 2.0;
// 
void OnChartEvent( const int id, const long &lparam, const double &dparam, const string &sparam ) {
  if (id == CHARTEVENT_KEYDOWN) {
    switch ((int)lparam) {
    case KEY_B: // buy
      OrderSend(_Symbol, OP_BUY, 1, Ask, 100, 0, 0);
      break;
    case KEY_S: // sell
      OrderSend(_Symbol, OP_SELL, 1, Bid, 100, 0, 0);
      break;
    case KEY_C: // close
      for (int i = OrdersTotal() - 1; i >= 0; i--)
        if (OrderSelect(i, SELECT_BY_POS) && (OrderType() <= OP_SELL))
          OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 100);
    }
  }
}


void OnTick() {
  //Print(_Symbol, " ", SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE));
}
void OnTimer() { /* Comment(REPORT::OrdersToString(_Symbol, 0, 5)); */ }
int OnInit() {
  Print(_Symbol, " ", SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE));
  Print(_Symbol, " In2 = ", In2);
  return(INIT_SUCCEEDED);
}
//
void OnDeinit( const int ) {}
//
void OnTradeTransaction(const MqlTradeTransaction& trans, const MqlTradeRequest& request, const MqlTradeResult& result) {

}
//+------------------------------------------------------------------+

The sample code uses the code of your Tester library. After startup, the variable In2 is 0, not 2. That is, all input parameters cannot be retrieved after the group.
 
hini #:

This situation does not seem to be considered. When the parameter is a group, there is no specific value and the value obtained will be null, so no parameters after the group will be obtained.

The following code shows that everything is handled correctly.

input int In1 = 1;
input group "label1"
input double In2 = 2.0;

#include <fxsaber\Expert.mqh> // https://www.mql5.com/en/code/19003

int GetAmountExperts()
{
  int Res = 0;
  
  for (long Chart = ChartFirst(); Chart != -1; Chart = ChartNext(Chart))
    Res += (ChartGetString(Chart, CHART_EXPERT_NAME) != "");
    
  return(Res);
}

void OnInit()
{
  if (GetAmountExperts() < 2)
  {
    MqlParam Params[];
    string Names[];
            
    const int Size = EXPERT::Parameters(0, Params, Names) - 1;
    
    ArrayPrint(Params);
    ArrayPrint(Names);
    
    for (uint i = Size; (bool)i--;)
      EXPERT::AddInputName(Params[i + 1], Names[i]);
            
    Params[Size].string_value = "7";
    EXPERT::Run(ChartOpen(_Symbol, _Period), Params);
  }
}


Result.

    [type] [integer_value] [double_value]      [string_value]
[0]     14               0           0.00 "Scripts\Test6.ex5"
[1]     14               1           1.00 "1"                
[2]     14               0           0.00 null               
[3]     14               2           2.00 "2.0"              
"In1" null  "In2"


Expert Advisor launched through Expert.mqh.

 
input bool InRun = true;
input group "label1"
input double In2 = 2.0;

#include <fxsaber\Expert.mqh> // https://www.mql5.com/en/code/19003


int GetAmountExperts()
{
  int Res = 0;
  
  for (long Chart = ChartFirst(); Chart != -1; Chart = ChartNext(Chart))
    Res += (ChartGetString(Chart, CHART_EXPERT_NAME) != "");
    
  return(Res);
}

void OnInit()
{
  if (InRun)
  {
    MqlParam Params[];
    string Names[];
            
    const int Size = EXPERT::Parameters(0, Params, Names) - 1;
    
    ArrayPrint(Params);
    ArrayPrint(Names);
    int nameSize = ArraySize(Names);
    for (int i = nameSize-1; i >= 0; i--) {
      if (Names[i] == "InRun")
        Params[i+1].string_value = "false";
      EXPERT::AddInputName(Params[i + 1], Names[i]);
    }  
            
    ArrayPrint(Params);
    ArrayPrint(Names);
    //Params[Size].string_value = "7";
    EXPERT::Run(ChartOpen(_Symbol, _Period), Params);
    return;
  }
  Print("In2 = ", In2);
}

The GetAmountExperts function runs for an unknown reason for a very long time with no result. I changed the code a bit - please run it again. You should not assign the value 7 to the In2 parameter (you will see that there is 0, not 2).


 
hini #:

I've changed the code a bit - please run it again.

This is an exemplary bug report: ran the concise code, which immediately showed the bug.

Made the correction, thanks.

 
fxsaber #:

This is an exemplary bug report: ran concise code that immediately showed a bug.

I've made the correction, thank you.

I see, in case of problems I will make reports in the same format.
 

If the script is loaded, it looks like the input parameters cannot be changed.

 //Test1.ex5
#property script_show_inputs
input string str = "test1" ;
//void OnInit() {
void OnStart () {
   Print (str);
}
 // Start the Expert Advisor with specified input parameters
#property script_show_inputs

#include "Expert.mqh"

input bool CurrentChart = false ; // Run EA on current(true)/new(false) chart

string GetMyName( void ) {
   return ( StringSubstr ( MQLInfoString ( MQL_PROGRAM_PATH ), StringLen ( TerminalInfoString ( TERMINAL_DATA_PATH ) + "\\MQL5\\" )));
}

bool RunExpert( const long Chart ) {
   MqlParam Params[ 2 ];
  Params[ 0 ].string_value = "Experts\\Advisors\\Test1.ex5" ;
   // The first input parameter of the Expert Advisor
  Params[ 1 ].type = TYPE_STRING ;
  Params[ 1 ].string_value = "Hello World!" ;
   return (EXPERT::Run(Chart, Params));
}

#define  NAME __FILE__

void OnStart () {
   union UNION {
     double Double;
     long Long;
  } Chart;
   if (CurrentChart) {
    Chart.Long = ChartID ();
     GlobalVariableSet (NAME, Chart.Double);
     MqlParam Params[ 1 ];
     // Path to self (script)
    Params[ 0 ].string_value = GetMyName();
     // On the new chart, we launch ourselves
    EXPERT::Run( ChartOpen ( _Symbol , _Period ), Params);
  } else if ( GlobalVariableCheck (NAME)) {
    Chart.Double = GlobalVariableGet (NAME);
     GlobalVariableDel (NAME);
    RunExpert(Chart.Long);
     ChartClose ();
  } else // The easiest way to run the Expert Advisor (with non-default parameters) is not on the current chart
    RunExpert( ChartOpen ( _Symbol , _Period ));
}
//+------------------------------------------------------------------+
 
hini #:

If the script is loaded, it looks like the input parameters cannot be changed.

Such is the architecture of MT5 that you cannot set input parameter values for scripts and you cannot read them.

The library has an eloquent name.

 
fxsaber #:

Such is the architecture of MT5 that you can't set input parameter values for scripts and you can't read them.

The library has an eloquent name.

ok
 

Forum on trading, automated trading systems and testing trading strategies

Libraries: Expert

fxsaber, 2018.11.16 09:19 AM.

An example of another application of the library
More on the topic of frame mode, when optimisation is launched without setting optimisation intervals.
#include <fxsaber\Expert.mqh> // https://www.mql5.com/en/code/19003

input group "Params"
input int inRange1 = 0;
input double inRange2 = 0;

// Checks if the optimisation intervals are set.
bool OptimizationIsCorrect()
{
  bool Res = false;
  
  if (MQLInfoInteger(MQL_FRAME_MODE))
  {    
    MqlParam Parameters[];
    string Names[];

    EXPERT::Parameters(0, Parameters, Names);
  
    for (uint i = ArraySize(Names); !Res && (bool)i--;)
    {
      long S[4];
      
      ParameterGetRange(Names[i], Res, S[0], S[1], S[2], S[3]);
    }
  }
      
  return(Res);
}

void OnTesterInit()
{
  if (!OptimizationIsCorrect())
  {
    Alert("no optimized parameter selected, please check input(s) to be optimized and set start, step and stop values");
    
    ChartClose();
  }
}

void OnTesterDeinit() {}
Without such a solution, an Expert Advisor in frame mode remains hanging on the chart. It is especially critical when automating the Tester.