[ARCHIVE!] フォーラムを散らかさないように、どんなルーキーの質問でも。プロフェッショナルは、通り過ぎないでください。あなたなしではどこにも行けない - 4. - ページ 99

 
Lisi4ka330:


こんにちは!ArrayMo関数(密度曲線の最大値を返す)について教えてください。

double ArrayMo(double& x[], int d=4) {
  double e, s=0;
  double m[][2];             // временный массив:
                             //  столбец 1 - количество значений
                             //  столбец 2 - значения
  int    i, k=ArraySize(x);
  int    n;                  // номер строки временного массива m
  int    r;                  // количество строк во временном массиве m

  if (k>0) {
    for (i=0; i<k; i++) {
      e=NormalizeDouble(x[i], d);
      n=ArraySearchDouble(m, e);
      if (n<0) {
        r=ArrayRange(m, 0);
        ArrayResize(m, r+1);
        m[r][0]++;
        m[r][1]=e;
      } else m[n][0]++;
    }
    ArraySort(m, WHOLE_ARRAY, 0, MODE_DESCEND);
    s=m[0][1];
  } else Print("ArrayMo(): Массив пуст!");

  return(s);
}

以下のような疑問が出てきました。

1.テンポラリーアレイを作成する目的は何ですか?

m[][2]

2.一時配列の値が何から取得されるかが不明であり、したがって、この配列をどのように検索すればよいかが不明である。

n=ArraySearchDouble(m, e)

3.そして、一般的に私にとっての真実は深く隠されている)))))値がないことを確認したら、「不明確な値」の配列の大きさを決定する作業に入る。

この物語に一筋の光明を見出すことができたら、とてもありがたいです)))


結局、この機能はかなり正しく書かれていないような気がします。主な理由は、発表後です。

double m[][2];

ひつようふかけつ

ArrayResize(m,0);

でないと

intArrayResize() void array[], int new_size).
配列の 1 次元に新しいサイズを設定します. 成功した場合は,サイズ変更後の配列に含まれる全要素の数を返します.そうでない場合は,-1 を返し,配列はサイズ変更されません.
注意: 関数の中でローカルに宣言された配列は、サイズが変更されても、関数が実行された後は変更されません。 関数が再び呼び出されると、その配列は宣言されたものとは異なるサイズに なります!!!!

そのため、複数回呼び出すと、関数が「過去に落ちる」ことになる)

アルゴリズムの仕組みについて配列m[][2]自体は、変数x[i]の異なる値によるヒット数の経験的分布を直接表現したものである。つまり、配列の各要素は、ある値(第1フィールド)のヒット数と、その値自体の2つの数値から構成されている。このループでは、各x[i]に対して配列mから同じ値を探し、見つかれば数値フィールドを追加し、そうでなければArrayResize()で新しい要素を作り、そこに我々のx[i]を書き込んでいます。

次に、配列に入力されたら、最大ヒット数の要素、つまり、定義上、分布のモジュラスxを見つければよいのです。

これは、文字列

    ArraySort(m, WHOLE_ARRAY, 0, MODE_DESCEND);
    s=m[0][1];

と思われますが(多次元配列は不明)、単に

    s=m[ArrayMaximum(m)][1];

全体として言えることは(コードの作者に敬意を表して)、すべての不具合を修正しても、このアルゴリズムは非常に効率が悪く、しばしば間違った結果を出す可能性があるということです。これは、double型を扱っているため、x[i]の値が近くても区別がつく確率がかなり高いからです。これは、x[i]が定義される区間の総数よりもサンプルサイズがはるかに大きい(数百倍以上)場合、それほど顕著ではないかもしれません。しかし、この制約を満たさない場合、間違った計算が多くなる。

経験分布関数(度数分布と混同しないように)を作り、それを区分線形から平滑補間し、最後に最大微分の点を探すというのが、より正しい最頻値の計算方法である。このようなアルゴリズムは、上記のような欠点がなく、サンプルサイズが小さくても非常に効果的に機能する。少なくとも、50~100個の要素からなるサンプルに対して、同等の区間数でモードを求めるというタスクだけはMQLを使って解決しなければなりませんでしたが、すべてOKでした。唯一の欠点は、質的に平滑化したい場合はもちろんのこと、通常、補間によって計算速度が大幅に低下することである。

 
こんにちは、尊敬するフォーラムのメンバー、私はEAを書く ことについて話をすることができます。自分たちの方向ではない動きに対して倍返しすることを前提とした指標のないEA。
 
Glazunov:
こんにちは、尊敬するフォーラムのメンバー、私はEAを書くことについて話をすることができます。自分たちの方向ではない動きに対して倍返しすることを前提とした指標のないEA。
こちら:https://www.mql5.com/ru/job
 
ilunga:
こちら:https://www.mql5.com/ru/job

ありがとうございます。もしかしたら、もっと選択肢があるのかもしれません。
 
Glazunov:

ありがとうございます。もしかしたら、もっと選択肢があるのかもしれません。
ウェブサイト検索で「マーチンゲール」と入力してみてください - 驚きますよ。
 
YOUNGA:
サイト内検索で「マーチンゲール」と入力してみると

もう見た!でも、欲しいものがない(
 
Glazunov:
こんにちは、尊敬するフォーラムのメンバー、私はEAを書くことについて話をすることができます。自分たちの方向ではない動きに対して倍返しすることを前提とした指標のないEA。


こちらからご覧ください。

https://www.mql5.com/ru/forum/136747

 

こんにちは。MQL4で始めたばかりです。

OrderModify 関数についてアドバイスください。マニュアルや事例を見ると、この機能はトローリング、つまりストップロスの変更に使われていることがわかります。ストップロスは注文が開始された時点では設定されておらず、変更中も0を 維持する必要があります。

注文の計算や選択はどのようにすればよいのでしょうか?

最終的なターゲットは次のようなものになります。

if (OrderType()==OP_BUY && OrderOpenPrice()-Bid>kof*Point) // 買いがあるが、kofだけ下がった
{
OrderModify(OrderTicket(),OrderOpenPrice(),0,OrderOpenPrice()+tpnew*Point,0,CLR_NONE);// 先に置いたものより低いところに TP を移動させる。

セルも同様です。

回答ありがとうございました。

 

また、こんにちは :)

やはり、問題が発生しました。以下はそのコードです。ポイントは、テスター上の注文はTPによってクローズされ、Trailing Stop中に注文が変更されると機能上TPが削除されることです。

double my_ord[31][2];                                           //ордера советника
                                                                //[][0] Ticket
                                                                //[][1] Вид операции 
//---------------------------------------------------------------------------------

void FindMyOrders()                                             //ищем свои ордера(от советника)
   {
    for (int a = 0;a<32;a++)                                    //во избежание ошибок заполняем все нулями
      {
       my_ord[a][0]=0;
       my_ord[a][1]=0;
      }
    int pos = 0;
    for(int i=0; i<32; i++)
      {
       if (Mas_Ord_New[i][8]==1)                                //есть ли комментарий
         {
          int num = Mas_Ord_New[i][4];
          OrderSelect(SELECT_BY_TICKET, num);
          string str = OrderComment();
          if (str == "AO Day Profiter Trade")                   //наш ли это комментарий
            {
             my_ord[pos][0] = num;
             my_ord[pos][1] = Mas_Ord_New[i][6];                //если наш, записываем Ticket и вид операции
             pos++;
            }
          else { }
         }
       else { }
      }
   }
//---------------------------------------------------------------
void TrailStop(int ticket, int TStop)                           //ф-ция трейлинг стопа, TStop-расстояние в пп
   {
    int minDist = MarketInfo(symb, MODE_STOPLEVEL);
    if (TStop<minDist)
      {
       TStop = minDist;
      }
    else { }
    if (TStop>0)
      {
       OrderSelect(ticket, SELECT_BY_TICKET);
       if(OrderType()==OP_BUY)
         {
          if(Bid - OrderOpenPrice()>Point*TStop)
            {
             if(OrderStopLoss()<Bid-Point*TStop)
               {
                OrderModify(OrderTicket(), OrderOpenPrice(), 
                Bid-Point*TStop, 0, 0, Blue);
                return;
               }
             else { }
            }
            else{ }
         }
       else if (OrderType()==OP_SELL)
         {
          if(OrderOpenPrice() - Ask>Point*TStop)
            {
             if(OrderStopLoss()>Ask + TStop*Point)
               {
                OrderModify(OrderTicket(), OrderOpenPrice(), 
                Ask+Point*TStop, 0, 0, Blue);                           //ordertakeprofit!!
                return;
               }
             else { }
            }
          else { }
         }
       else { }
      }
    else { }
    }
//-----------------------------------а это кусочек Start(), отвечающий за трейлинг стоп
   for (int i = 0; i<32; i++)                                   //трейлинг стоп для наших ордеров
      {
       if (my_ord[i][0]>0)
         {
          TrailStop(my_ord[i][0], TralingStop);
         }
       else {break;}
      }
つまりトレーリングストップは実行されず、テスターのログには間違ったTPとSLのエラーはありませんでした。では、何が問題なのか?
 

プロフェッショナルの皆様、この質問についてアドバイスをお願いします。

以前書いた1次元の文字列配列がテキストファイルにあります。

EURUSD 1654.31

GBPUSD -1654.61

USDCAD 110.98

USDJPY 1180.17

USDCADの合計利益が変更され、3行目を「USDCAD 115.64」に置き換える必要があるとします。

このデータを一次元の文字列配列として読み込むのですが、テキストファイルのこの要素だけを置き換えることができません(どなたか関数を書いていただけませんか)。

それとも、面倒くさがらずに配列全体を上書きした方が良いのでしょうか?

私はただ、異なるペアに立っているEAから入ってくるデータを持っています - 各ペアは異なる文字列を持っています - それはもちろん、おそらく1つの要素だけを変更する方が良いでしょう。