初心者の方からの質問 MQL5 MT5 MetaTrader 5 - ページ 618

 
Leo59:
なぜそうなるのか、理由を教えてください。:
Fun_1()とFun_2()は似ています。
関数型や戻り値のない類似品?
 
Leo59:
何が原因なのか、教えていただけませんか?:
Fun_1()とFun_2()は似ています。

学問的に - 関数は純粋ではなく、グローバルな状態を変更します。

簡単に言うと、どちらの関数もグローバル変数や ファイルの読み書きを 行います。

 
Maxim Kuznetsov:

学問的に - 関数は純粋ではなく、グローバルな状態を変更します。

つまり、どちらの関数もグローバル変数や ファイルの読み書きを 行います。

はい、それぞれファイルを書き込んでいます。それで?
 
Leo59:
そう、それぞれがファイルを書き込むのです。それで?

とは連動しません :-)

PS.地下ノックのソースについては、ソースがないとより正確なことは言えませんね。どこかに間違いがある - 修正する

 
省スペースと視認性の向上、この2つを1つの機能で実現。それでもダメなんです。

void Fun_Select_2()                                                   // dSSd Выбор сочетаний из массивов dSe1_Bal_D и dSe1_Bal_W с Proba>67
   {
    // 1. УДАЛЯЕМ старые файлы
    // 2. ПЕРЕБИРАЕМ в поиске соответствия
    // 3. ПЕЧАТАЕМ найденное в файл

    // 1. УДАЛЯЕМ старые файлы
    if(use_Print_Rep_dSS == 1)                                        // =0 -> Условие отключено, =1 -> Печатать в log файл Промежуточные отчёты (dSS)
        {
         LogName="Rep_dSSd "+EN;                                      // (Interum Report) Название ЛОГА + Название ЭТОГО ЭКСПЕРТА, передаваемое в log файл
         // Если файл с таким именем существует, то удаляем его ... 
         ld=log_delete(LogName);                                      // ФЛАГ log файла, удаляемого в директории "logs\\" 
         if(ld==1)
              Alert ("Старый файл dSSd УДАЛЁН");
         LogName="Rep_dSSw "+EN;                                      // (Interum Report) Название ЛОГА + Название ЭТОГО ЭКСПЕРТА, передаваемое в log файл
         // Если файл с таким именем существует, то удаляем его ... 
         ld=log_delete(LogName);                                      // ФЛАГ log файла, удаляемого в директории "logs\\" 
         if(ld==1)
              Alert ("Старый файл dSSw УДАЛЁН");
        }

    // 2. ПЕРЕБИРАЕМ в поиске соответствия
    //    Находим соответствие между [1]-"Num1 А" и [4]-"Num1 B" в массивах dSe1_Bal_D и dSe1_Bal_W
    int t=0;                                                          // Техническая переменная
    int d=0;                                                          // Техническая переменная
    int w=0;                                                          // Техническая переменная
    int D=0;                                                          // Техническая переменная
    int W=0;                                                          // Техническая переменная
    int S=0;                                                          // Техническая переменная

    //    Если есть соответствие тогда записываем её в массив dSSd[][90]
    Count_dSSd=0;                                                     // "Обнуляем" Счётчик записей (строк) в массиве dSSd[][90]
    Range_dSSd_one=0;                                                 // "Обнуляем" Размер первого измерения (число строк)    с индексом_измерения=[0] массива dSSd[][90];
    Range_dSSd_two=0;                                                 // "Обнуляем" Размер второго измерения (число столбцов) с индексом_измерения=[1] массива dSSd[][90];

    for(d=0, t=0; d<Range_dSe1_Bal_D_one; d++)
        {
         for(w=0; w<Range_dSe1_Bal_W_one; w++)
             {
              if( (dSe1_Bal_W[w][1]==dSe1_Bal_D[d][1]) && (dSe1_Bal_W[w][4]==dSe1_Bal_D[d][4]) )
                  {
                   Count_dSSd++;                                      // Счётчик записей (строк) в массиве dSSd[][90]
                   ArrayResize(dSSd, Count_dSSd, 200000);             // Задайм новый размер массива с резервированием памяти на 100000 записей (строк)  
                   for(S=0,  D=0;   D<45;   D++, S++)
                        dSSd[t][S] = dSe1_Bal_D[d][D];                // Значения строки массива dSe1_Bal_D
                   for(S=45, W=0;   W<45;   W++, S++)
                        dSSd[t][S] = dSe1_Bal_W[w][W];                // Значения строки массива dSe1_Bal_W
                   t++;                                               // Увеличили индекс массива dSSd на "1"
                  }
             }
        }
    Range_dSSd_one = ArrayRange(dSSd, 0);                             // Размер первого измерения (число строк)    с индексом_измерения=[0] массива dSSd[][90];
    Range_dSSd_two = ArrayRange(dSSd, 1);                             // Размер второго измерения (число столбцов) с индексом_измерения=[1] массива dSSd[][90];

    //    Если есть соответствие тогда записываем её в массив dSSw[][90]
    Count_dSSw=0;                                                     // "Обнуляем" Счётчик записей (строк) в массиве dSSw[][90]
    Range_dSSw_one=0;                                                 // "Обнуляем" Размер первого измерения (число строк)    с индексом_измерения=[0] массива dSSw[][90];
    Range_dSSw_two=0;                                                 // "Обнуляем" Размер второго измерения (число столбцов) с индексом_измерения=[1] массива dSSw[][90];
    for(d=0, t=0; d<Range_dSe1_Bal_D_one; d++)
        {
         for(w=0; w<Range_dSe1_Bal_W_one; w++)
             {
              if( (dSe1_Bal_W[w][1]==dSe1_Bal_D[d][1]) && (dSe1_Bal_W[w][4]==dSe1_Bal_D[d][4]) )

                  {
                   Count_dSSw++;                                      // Счётчик записей (строк) в массиве dSSw[][90]
                   ArrayResize(dSSw, Count_dSSw, 200000);             // Задайм новый размер массива с резервированием памяти на 100000 записей (строк)  
                   for(S=0,  W=0;   W<45;   W++, S++)
                        dSSw[t][S] = dSe1_Bal_W[w][W];                // Значения строки массива dSe1_Bal_W
                   for(S=45, D=0;   D<45;   D++, S++)
                        dSSw[t][S] = dSe1_Bal_D[d][D];                // Значения строки массива dSe1_Bal_D
                   t++;                                               // Увеличили индекс массива dSSw на "1"
                  }
             }
        }
    Range_dSSw_one = ArrayRange(dSSw, 0);                             // Размер первого измерения (число строк)    с индексом_измерения=[0] массива dSSw[][90];
    Range_dSSw_two = ArrayRange(dSSw, 1);                             // Размер второго измерения (число столбцов) с индексом_измерения=[1] массива dSSw[][90];

    // 3. ПЕЧАТАЕМ найденное в файл
    int LH_Rep=0;                                                     // Хэндл log файла, открытого в директории "logs\\" 
    if(use_Print_Rep_dSS == 1)                                        // =0 -> Условие отключено, =1 -> Печатать в log файл Промежуточные отчёты (dSS)
        {
         if(Count_dSSd>0)
             {
              LogName="Rep_dSSd "+EN;                                 // (Interum Report) Название ЛОГА + Название ЭТОГО ЭКСПЕРТА, передаваемое в log файл
              LH_Rep=log_open(LogName);                               // Хэндл log файла, открытого в директории "logs\\" 
              Fun_Rep_mass90(LH_Rep, dSSd, Count_dSSd);               // Функция F 135 Запись Массива  mass90[][90] в Промежуточный отчёт в *.csv файл
              log_close(LH_Rep);                                      // Закрываем лог-файл этого эксперта
              Alert ("Записан ОТЧЁТ ", LogName);
             }
         if(Count_dSSw>0)
             {
              LogName="Rep_dSSw "+EN;                                 // (Interum Report) Название ЛОГА + Название ЭТОГО ЭКСПЕРТА, передаваемое в log файл
              LH_Rep=log_open(LogName);                               // Хэндл log файла, открытого в директории "logs\\" 
              Fun_Rep_mass90(LH_Rep, dSSw, Count_dSSw);               // Функция F 135 Запись Массива  mass90[][90] в Промежуточный отчёт в *.csv файл
              log_close(LH_Rep);                                      // Закрываем лог-файл этого эксперта
              Alert ("Записан ОТЧЁТ ", LogName);
             }
        }
   }
 
Leo59:
省スペースと視認性の向上、この2つを1つの機能で実現。それでもダメなんです。

今後のために - 関数の結果(少なくとも動作した/しない)が必要な場合、それを無効にしないでください。ざっと見たところ、「トリガー」という基準があるとは判断しがたい。空虚であり、どう投げてもすべてがうまくいく。

をデバッガーの権限で使用することができます。

グローバル変数 Count_XXX, Range_XXXの束を変換し(プラスdSSxx[]配列)、それを使ってログを取るかどうかを決め、参照か値でどこかに渡す...。

を再度呼び出すとCount_dSSが0になるなど、明らかに再計算に問題があるようです。プリントはそれを把握するのに役立つ、またはブレークポイントを設けて見る。

 
Maxim Kuznetsov:

今後のために - 関数の結果が必要な場合(少なくとも動作したかどうか)、それを無効にしないようにしてください。一見すると、何が「トリガー」の基準なのかわからない。空虚である、どう投げてもいい、なんでもいい。

をデバッガーの権限で使用することができます。

グローバル変数 Count_XXX, Range_XXX を変換し(さらに配列 dSSxx[])、それに基づいてログを記録するかどうかを決定し、参照または値でどこかに渡す...というものです。

を再度呼び出すとCount_dSSが0になるなど、明らかに再計算に問題があるようです。プリントはそれを把握するのに役立つ、またはブレークポイントを設けて見る。

どのコールバックのことですか?
簡略化したものです。
double   dSSd[][90];                   // Динамический Массив SelectSort соответствия пары массива dSe1_Bal_W паре массива dSe1_Bal_D
int      Count_dSSd=0;                 // Счётчик записей (строк) в массиве dSSd[][90]
int      Range_dSSd_one=0;             // = ArrayRange(dSS, 0);  Размер первого измерения (число строк)    с индексом_измерения=[0] массива dSSd[][90];
int      Range_dSSd_two=0;             // = ArrayRange(dSS, 1);  Размер второго измерения (число столбцов) с индексом_измерения=[1] массива dSSd[][90];

double   dSSw[][90];                   // Динамический Массив SelectSort соответствия пары массива dSe1_Bal_W паре массива dSe1_Bal_D
int      Count_dSSw=0;                 // Счётчик записей (строк) в массиве dSSw[][90]
int      Range_dSSw_one=0;             // = ArrayRange(dSS, 0);  Размер первого измерения (число строк)    с индексом_измерения=[0] массива dSSw[][90];
int      Range_dSSw_two=0;             // = ArrayRange(dSS, 1);  Размер второго измерения (число столбцов) с индексом_измерения=[1] массива dSSw[][90];

int init()
   {
    ArrayResize(dSSd, 200000, 200000);                                // Задаём новый размер массива с резервированием памяти на 200000 записей (строк)  
    ArrayResize(dSSw, 200000, 200000);                                // Задаём новый размер массива с резервированием памяти на 200000 записей (строк)  
    Fun_Select_2();
    return(0);
   }

void Fun_Select_2()                                                   
   {
    //    Находим соответствие между [1]-"Num1 А" и [4]-"Num1 B" в массивах dSe1_Bal_D и dSe1_Bal_W
    int t=0;                                                          // Техническая переменная
    int d=0;                                                          // Техническая переменная
    int w=0;                                                          // Техническая переменная
    int D=0;                                                          // Техническая переменная
    int W=0;                                                          // Техническая переменная
    int S=0;                                                          // Техническая переменная

    //    Если есть соответствие тогда записываем её в массив dSSd[][90]

    for(d=0, t=0; d<Range_dSe1_Bal_D_one; d++)
        {
         for(w=0; w<Range_dSe1_Bal_W_one; w++)
             {
              if( (dSe1_Bal_W[w][1]==dSe1_Bal_D[d][1]) && (dSe1_Bal_W[w][4]==dSe1_Bal_D[d][4]) )
                  {
                   Count_dSSd++;                                      // Счётчик записей (строк) в массиве dSSd[][90]
                   ArrayResize(dSSd, Count_dSSd, 200000);             // Задаём новый размер массива с резервированием памяти на 100000 записей (строк)  
                   for(S=0,  D=0;   D<45;   D++, S++)
                        dSSd[t][S] = dSe1_Bal_D[d][D];                // Значения строки массива dSe1_Bal_D
                   for(S=45, W=0;   W<45;   W++, S++)
                        dSSd[t][S] = dSe1_Bal_W[w][W];                // Значения строки массива dSe1_Bal_W
                   t++;                                               // Увеличили индекс массива dSSd на "1"
                  }
             }
        }
    Range_dSSd_one = ArrayRange(dSSd, 0);                             // Размер первого измерения (число строк)    с индексом_измерения=[0] массива dSSd[][90];
    Range_dSSd_two = ArrayRange(dSSd, 1);                             // Размер второго измерения (число столбцов) с индексом_измерения=[1] массива dSSd[][90];

    //    Если есть соответствие тогда записываем её в массив dSSw[][90]
   for(d=0, t=0; d<Range_dSe1_Bal_D_one; d++)
        {
         for(w=0; w<Range_dSe1_Bal_W_one; w++)
             {
              if( (dSe1_Bal_W[w][1]==dSe1_Bal_D[d][1]) && (dSe1_Bal_W[w][4]==dSe1_Bal_D[d][4]) )
                  {
                   Count_dSSw++;                                      // Счётчик записей (строк) в массиве dSSw[][90]
                   ArrayResize(dSSw, Count_dSSw, 200000);             // Задаём новый размер массива с резервированием памяти на 100000 записей (строк)  
                   for(S=0,  W=0;   W<45;   W++, S++)
                        dSSw[t][S] = dSe1_Bal_W[w][W];                // Значения строки массива dSe1_Bal_W
                   for(S=45, D=0;   D<45;   D++, S++)
                        dSSw[t][S] = dSe1_Bal_D[d][D];                // Значения строки массива dSe1_Bal_D
                   t++;                                               // Увеличили индекс массива dSSw на "1"
                  }
             }
        }
    Range_dSSw_one = ArrayRange(dSSw, 0);                             // Размер первого измерения (число строк)    с индексом_измерения=[0] массива dSSw[][90];
    Range_dSSw_two = ArrayRange(dSSw, 1);                             // Размер второго измерения (число столбцов) с индексом_измерения=[1] массива dSSw[][90];
   }

// Получаенный результат:

// Count_dSSd     = 280
// Range_dSSd_one = 280
// Range_dSSd_two = 90
// Массив dSSd заполнен правильными значениями

// Count_dSSw     = 280
// Range_dSSw_one = 0
// Range_dSSw_two = 90
// Массив dSSw заполнен "0"
 
// 問題の本質は次のようなものです。
// 2つの動的配列 A[][2]とB[][2]が存在する.
// 1次元目のインデックス "0 "によるマッチングを探している.
// 配列A 配列B
// 31 25 19 66
// 44 15 62 30
// 62 47 54 71
// 31 94
// 取得したい。
// 配列 dSSd[][4] 配列 dSSw[][4].
// 31 25 31 94 31 94 31 25
// 62 47 62 30 62 30 62 47
 
Leo59:
どの コールバックを 想定しているのでしょうか?
簡略化したものです。

に近い機能を指しています(細かいところは違うかもしれませんが)。同じ質問をされましたね。なぜ、これらの機能は別々に機能するのに、(順番に関係なく)次々に機能しないのでしょうか。より正確には、最初の関数だけが動作し、何かを記録する。

つまり、これらの関数の最初の呼び出しが、グローバル変数または配列の内容を変更しました。なぜかというと、ファイルに書き込む ときに変わってしまうからです :-)ホンモノ志向 - 突き抜けろ

Range_dSe1_Bal_W_one

私などは、大変で消極的だと思います。もうデバッガー買ったり、怪しいとこにはプリンターつけたりして。ネーミングのロジックを理解し、どのように機能すべきか(現実とは一致しませんが :-) をある程度理解していることです。)

PS/入力と出力の説明から、2つの配列の代わりにdSSx[][4]で十分で、1つのdSS[][3]で十分だと分かりました :-)。

 
Maxim Kuznetsov:

に近い機能を指しています(細かいところは違うかもしれませんが)。同じ質問をされましたが、なぜこれらの機能は個別に動作し、(順番に関係なく)次々に動作しないのでしょうか?より正確には、最初の関数だけが動作し、何かを記録する。

つまり、グローバルな状態は、これらの関数の最初の呼び出しによって、グローバル変数か配列の内容が変更されたのです。なぜファイルに書き込む ときに変更しなければならないか、その理由はあなたの方がよくご存知かもしれませんね :-)。ホンモノ志向 - 突き抜けろ

私などは、大変で消極的だと思います。もうデバッガー買ったり、怪しいとこにはプリンターつけたりして。ネーミングのロジックを理解し、どのように機能すべきかをある程度考えている(現実とは一致しない:-))。

PS/入力と出力の説明から、2つの配列の代わりにdSSx[][4]で十分で、1つのdSS[][3]で十分だと分かりました :-)。

マキシム 無関心でないことに感謝します。問題は解決しました。メモリ不足の問題であることが判明した。