ライブラリ: エキスパート - ページ 13

 
fxsaber #:

問題がある場合は、再生用のmq5ファイルをご用意ください。

#define  MT4ORDERS_LIBRARY
#include "../../utils/MT4Orders.mqh" 
// #define REPORT_BROWSER // ブラウザ起動時にレポートを作成 - DLLの許可が必要です。
#define  TESTER_CUSTOM // ユーザーテスターでのエキスパートアドバイザーの実行
#include "../../utils/fxsaber/Tester/Tester.mqh" //https://www.mql5.com/ja/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: // 購入する
      OrderSend(_Symbol, OP_BUY, 1, Ask, 100, 0, 0);
      break;
    case KEY_S: // 販売
      OrderSend(_Symbol, OP_SELL, 1, Bid, 100, 0, 0);
      break;
    case KEY_C: // 閉じる
      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) {

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

サンプルコードはTesterライブラリのコードを使用しています。起動後、変数In2が2ではなく0になっている。つまり、グループ後にすべての入力パラメータを取得できない。
 
hini #:

この状況は考慮されていないようだ。パラメータがグループの場合、特定の値はなく、得られる値はnullとなるため、グループ以降のパラメータは得られない。

次のコードは、すべてが正しく処理されていることを示している。

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

#include <fxsaber\Expert.mqh> //https://www.mql5.com/ja/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);
  }
}


結果

    [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.mqh Expert.mqh を通じて Expert Advisor が起動した。

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

#include <fxsaberExpert.mqh> //https://www.mql5.com/ja/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);
}

GetAmountExperts関数が原因不明のまま長時間実行され、結果が得られません。コードを少し変更しました。In2パラメータに値7を代入すべきではありません(2ではなく0であることがわかります)。


 
hini #:

コードを少し変更しました。

これは模範的なバグ報告です:簡潔なコードを実行したところ、すぐにバグが見つかりました。

修正しました。

 
fxsaber #:

これは模範的なバグ報告だ。簡潔なコードを実行したら、すぐにバグが見つかった。

訂正しました。

なるほど、問題が発生した場合は同じ形式で報告することにします。
 

スクリプトが読み込まれると、入力パラメータを変更できないようだ。

 //Test1.ex5
#property script_show_inputs
input string str = "test1" ;
//void OnInit() { {.
void OnStart () {
   Print (str);
}
 // 指定された入力パラメータでExpert Advisorを起動します。
#property script_show_inputs

#include "Expert.mqh"

input bool CurrentChart = false ; // 現在の(true)/新しい(false)チャートでEAを実行する。

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" ;
   // 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 ];
     // 自己へのパス(スクリプト)
    Params[ 0 ].string_value = GetMyName();
     // 新しいチャートで、自分自身を立ち上げる
    EXPERT::Run( ChartOpen ( _Symbol , _Period ), Params);
  } else if ( GlobalVariableCheck (NAME)) {
    Chart.Double = GlobalVariableGet (NAME);
     GlobalVariableDel (NAME);
    RunExpert(Chart.Long);
     ChartClose ();
  } else // Expert Advisorを(デフォルト以外のパラメータで)実行する最も簡単な方法は、現在のチャート上ではありません。
    RunExpert( ChartOpen ( _Symbol , _Period ));
}
//+------------------------------------------------------------------+
 
hini #:

スクリプトが読み込まれると、入力パラメータを変更できないようだ。

MT5のアーキテクチャでは、スクリプトの入力パラメータ値を設定することはできませんし、読み込むこともできません。

ライブラリには雄弁な名前がついている。

 
fxsaber #:

MT5のアーキテクチャでは、スクリプトの入力パラメータ値を設定することも、それを読み取ることもできません。

このライブラリには雄弁な名前がついている。

OK
 

取引、自動取引システム、取引戦略のテストに関するフォーラム

ライブラリ: Expert

fxsaber, 2018.11.16 09:19 AM.

ライブラリ
の別のアプリケーションの例。
最適化間隔を設定せずに最適化を開始した場合のフレームモードのトピックについて。
#include <fxsaber\Expert.mqh> //https://www.mql5.com/ja/code/19003

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

// 最適化間隔が設定されているかチェックする。
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() {}
このような解決策がないと、フレームモードのExpert Advisorはチャートにぶら下がったままになります。テスターを自動化する場合は特に重要です。