MQL4、MQL5に関する初心者からの質問、アルゴリズムやコードに関するヘルプ、ディスカッションなど。 - ページ 12

 
Artyom Trishkin:

その理屈はこうだ。

  1. 最後に決済された注文を、その種類と決済時刻で検索します。
  2. この注文が締め切られるまでに、締め切られたバーを見つけると
  3. バーの取得値がゼロより高ければ、新しいポジションを開くことができ、そうでなければ、開くことはできません。
このようなコードの例をどこかで見ることはできますか?
 
Viachaslau Baiko:
失礼しました)このコードの例をどこかで見ることはできますか?

単純なことです。

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 19.02.2008                                                     |
//|  Описание : Возвращает номер бара закрытия последней позиции или -1.       |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   ("" или NULL - текущий символ)          |
//|    tf - таймфрейм                  (    0       - текущий таймфрейм)       |
//|    op - операция                   (   -1       - любая позиция)           |
//|    mn - MagicNumber                (   -1       - любой магик)             |
//+----------------------------------------------------------------------------+
int NumberOfBarCloseLastPos(string sy="0", int tf=0, int op=-1, int mn=-1) {
  datetime t;
  int      i, k=OrdersHistoryTotal();

  if (sy=="" || sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
      if (OrderSymbol()==sy) {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (t<OrderCloseTime()) t=OrderCloseTime();
            }
          }
        }
      }
    }
  }
  return(iBarShift(sy, tf, t, True));
}


すみません、話が違うかもしれません。

 
Dmitry Fedoseev:

この 指標を瞑想してください。静的変数を多く持っています。

   static datetime LastTime=0;
   static int cDir=0;
   static int pDir=0;

バッファの代わりに作られる。

IndicatorCounted()=0の時はLastTimeをゼロにする(他は必要ないが望ましい)。

そして、ループの最初で、値を移動させる。

if(Time[i]>LastTime)
        {
         LastTime=Time[i];
         pDir=cDir;

        }
      else
        {
         cDir=pDir;
        }

c "で始まる変数は現在の値、"p "で始まる変数は以前の値です。

このリンクは開きません - 404エラー。

時間をかけて実験してみましたが、うまくいかず...。最後の小節で計算を止める方法」という方向で考えていたのですが、それが間違いだったようです。これからは、現在のバーを変更する前に、計算の最後のステップに変更を加えない方法を考えたいと思います。

 
Alekseu Fedotov:

単純なことです。

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 19.02.2008                                                     |
//|  Описание : Возвращает номер бара закрытия последней позиции или -1.       |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   ("" или NULL - текущий символ)          |
//|    tf - таймфрейм                  (    0       - текущий таймфрейм)       |
//|    op - операция                   (   -1       - любая позиция)           |
//|    mn - MagicNumber                (   -1       - любой магик)             |
//+----------------------------------------------------------------------------+
int NumberOfBarCloseLastPos(string sy="0", int tf=0, int op=-1, int mn=-1) {
  datetime t;
  int      i, k=OrdersHistoryTotal();

  if (sy=="" || sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
      if (OrderSymbol()==sy) {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (t<OrderCloseTime()) t=OrderCloseTime();
            }
          }
        }
      }
    }
  }
  return(iBarShift(sy, tf, t, True));
}


すみません、話が違うかもしれません。

ありがとうございます!挑戦してみます。
 

こんにちは!アルゴリズムについて教えてください。
Pearsonの相関係数を計算する簡単なスクリプトを書きました。配列は、最初のバーから始まる終値に 基づくものである。

int start()
   {
   int n=25;
   int w=18;
   double sum_x=0;                                                // Сумма цен закрытия для пары 1
   double sum_y=0;                                                // Сумма цен закрытия для пары 2
   double Price_Close_x[];                                        // Массив Price_Close для пары 1
   double Price_Close_y[];                                        // Массив Price_Close для пары 2
   double dx[];                                                   // Отклонение от среднего значения для пары 1 dx
   double dy[];                                                   // Отклонение от среднего значения для пары 2 dy
   double dx2[];                                                  // Квадрат отклонения ср.значения dx2
   double dy2[];                                                  // Квадрат отклонения ср.значения dy2
   double dxdy[];                                                 // Произведение dx и dy



   ArrayResize(Price_Close_x, n);
   ArrayResize(Price_Close_y, n);
   ArrayResize(dx, n);
   ArrayResize(dy, n);  
   ArrayResize(dx2, n);
   ArrayResize(dy2, n);
   ArrayResize(dxdy, n);
   string sym_x="EURUSD";
   string sym_y="GBPUSD";
  
   for(int p=1; p<n; p++)
      {
      Price_Close_x[p]=iClose(sym_x, PERIOD_H1, p);
      Price_Close_y[p]=iClose(sym_y, PERIOD_H1, p);
      sum_x=sum_x+Price_Close_x[p];
      sum_y=sum_y+Price_Close_y[p];
      }
      
   Alert("Sum_x равно ", sum_x);
   Alert("Sum_y равно ", sum_y);
   double Mx=sum_x/(n-1);                                         // Среднее значение цен закрытия пары 1 Mx
   double My=sum_y/(n-1);                                         // Среднее значение цен закрытия пары 2 My
   Alert("Mx равно ", Mx);
   Alert("My равно ", My);  
  
   for(int i=1; i<n; i++)
      {
      dx[i]=Price_Close_x[i]-Mx;
      dy[i]=Price_Close_y[i]-My;
      dx2[i]=DoubleToString(dx[i]*dx[i], w);
      dy2[i]=DoubleToString(dy[i]*dy[i], w);
      dxdy[i]=DoubleToString(dx[i]*dy[i], w);
      Alert("Отклонение dx на баре ", i, " равно ", DoubleToString(dx[i], w));
      Alert("Отклонение dy на баре ", i, " равно ", DoubleToString(dy[i], w));
      Alert("Квадрат dx на баре ", i, " равен ", DoubleToString(dx2[i], w));
      Alert("Квадрат dy на баре ", i, " равен ", DoubleToString(dy2[i], w));
      Alert("dxdy на баре ", i, " равен ", DoubleToString(dxdy[i], w));    
      }
   double Edx2=0;                                                 // Сумма квадратов отклонений Edx2
   double Edy2=0;                                                 // Сумма квадратов отклонений Edy2
   double Edxdy=0;                                                // Сумма произведений отклонений Edxdy
   for(int q=0; q<n; q++)
      {
      Edx2=DoubleToString((Edx2+dx2[q]), w);
      Edy2=DoubleToString((Edy2+dy2[q]), w);
      Edxdy=DoubleToString((Edxdy+dxdy[q]), w);
      }  
   Alert("Сумма Edx2 равна ", DoubleToString(Edx2, w));
   Alert("Сумма Edy2 равна ", DoubleToString(Edy2, w));
   Alert("Сумма Edxdy равна ", DoubleToString(Edxdy, w));
  
   double Koef;                                                    // Коэффициент Пирсона
   Koef=Edxdy/(sqrt(DoubleToString((Edx2*Edy2), w)));
   Alert("Коэффициент корреляции Пирсона между ", sym_x, " и ", sym_y, " равен ", DoubleToString(Koef, w));    
   return;
 }

価格配列は、1本目から24本目までを取得します。
さて、24本のバーの相関を計算したいのですが、2本目(!)のバーから価格の配列を取ります。

アルゴリズムが分からないので、各価格配列を手動で入力しました。

for(int p=1; p<n; p++)

      {

      Price_Close_x[p]=iClose(sym_x, PERIOD_H1, p);

      Price_Close_y[p]=iClose(sym_y, PERIOD_H1, p);

      sum_x=sum_x+Price_Close_x[p];

      sum_y=sum_y+Price_Close_y[p];

         Price_Close_x1[p]=iClose(sym_x, PERIOD_H1, p+1);

         Price_Close_y1[p]=iClose(sym_y, PERIOD_H1, p+1);

         Price_Close_x2[p]=iClose(sym_x, PERIOD_H1, p+2);

         Price_Close_y2[p]=iClose(sym_y, PERIOD_H1, p+2);

         Price_Close_x3[p]=iClose(sym_x, PERIOD_H1, p+3);

         Price_Close_y3[p]=iClose(sym_y, PERIOD_H1, p+3);
         ...
   
         ...
         Price_Close_x24[p]=iClose(sym_x, PERIOD_H1, p+24);

         Price_Close_y24[p]=iClose(sym_y, PERIOD_H1, p+24);
}

24本では足手まといだし、100本の相関を知りたければ、1本1本配列を入力するのは面倒だ。
どうするんだ、みんな)

 
Timur1988:

こんにちは!アルゴリズムについて教えていただけませんか?
ピアソン相関係数を計算するスクリプトを書きました。最初のバーから順に終値で配列しました。

for(int p=1; p<n; p++)
{
Price_Close_x[p]=iClose(sym_x, PERIOD_H1, p);
Price_Close_y[p]=iClose(sym_y, PERIOD_H1, p);
sum_x=sum_x+Price_Close_x[p];
sum_y=sum_y+Price_Close_y[p];
}
_______________________________________

for(int p=1; p<n; p++)

{

Price_Close_x[p]=iClose(sym_x, PERIOD_H1, p);

Price_Close_y[p]=iClose(sym_y, PERIOD_H1, p);

sum_x=sum_x+Price_Close_x[p];

sum_y=sum_y+Price_Close_y[p];

Price_Close_x1[p]=iClose(sym_x, PERIOD_H1, p+1)とする。

Price_Close_y1[p]=iClose(sym_y, PERIOD_H1, p+1)とする。

Price_Close_x2[p]=iClose(sym_x, PERIOD_H1, p+2)とする。

Price_Close_y2[p]=iClose(sym_y, PERIOD_H1, p+2)とする。

Price_Close_x3[p]=iClose(sym_x, PERIOD_H1, p+3)とする。

Price_Close_y3[p]=iClose(sym_y, PERIOD_H1, p+3)とする。
...
Price_Close_x24[p]=iClose(sym_x, PERIOD_H1, p+24)とする。

Price_Close_y24[p]=iClose(sym_y, PERIOD_H1, p+24)とする。
}
____________________________________________________________________________


二次元配列

PriceClose[][2];

double PriceClose[][2];
int n=24;
ArrayResize(PriceClose,n);
for(int p=0; p<n; p++) {
   PriceClose[p][0]=iClose(sym_x, PERIOD_H1, p);
   PriceClose[p][1]=iClose(sym_y, PERIOD_H1, p);
   sum_x+=PriceClose[p][0];
   sum_y+=PriceClose[p][1];
   }
 

どこが悪いのかわからない...。

//+------------------------------------------------------------------+
//|                                                       SVA_03.mq4 |
//|                      Copyright © 2006, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"
#property strict

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Yellow

//---- input parameters
extern int RSIPeriod=14;
extern int Levl=50;
extern int TF=0;
//---- buffers
double MABuffer[];
static datetime TimeN=0;
static datetime TimeX=0;
int StopCalc=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   string short_name;
   IndicatorBuffers(1);
   SetIndexBuffer(0,MABuffer);

//---- indicator line
   SetIndexStyle(0,DRAW_LINE);
//----
//---- name for DataWindow and indicator subwindow label
//   short_name="RSI("+IntegerToString(RSIPeriod)+")";
   short_name="RSI("+RSIPeriod+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,short_name);

   return(0);
  }
//+------------------------------------------------------------------+
//| Relative Strength Index                                          |
//+------------------------------------------------------------------+
int start()
  {
   int    i,counted_bars=IndicatorCounted();
   double rel,negative,positive,sma,x,y,Pos,Neg;
   double sumn=0.0,sump=0.0;
//----
   if(Bars<=RSIPeriod) return(0);
   if(TF!=0)
     {
      string name=WindowExpertName();
      for(i=0; i<Bars-counted_bars+1; i++)
        {
         int barIndex=iBarShift(NULL,TF,Time[i],false);
         MABuffer[i]=iCustom(Symbol(),TF,name,RSIPeriod,Levl,0,0,barIndex);
        }
      return(0);
     }

   i=Bars-RSIPeriod-1;
   if(counted_bars>=RSIPeriod) i=Bars-counted_bars-1;
   datetime TimeC=iTime(NULL,TF,0);
   while(i>=0)
     {
      if(i!=0 && StopCalc==0)
        {
         sumn=0.0;sump=0.0;
         if(i==Bars-RSIPeriod-1)
           {
            int k=Bars-2;
            //---- initial accumulation
            while(k>=i)
              {
               rel=Close[k]-Close[k+1];
               if(rel>0) sump+=rel;
               else      sumn-=rel;
               k--;
              }
            positive=sump/RSIPeriod;
            negative=sumn/RSIPeriod;
           }
         else
           {
            //---- smoothed moving average
            rel=Close[i]-Close[i+1];
            if(rel>0) sump=rel;
            else      sumn=-rel;
            positive=(Pos*(RSIPeriod-1)+sump)/RSIPeriod;
            negative=(Neg*(RSIPeriod-1)+sumn)/RSIPeriod;
           }

         x=Pos;
         y=Neg;
         Pos=positive;
         Neg=negative;
         if(x>0)sma=Close[i+1]+x;
         else sma=Close[i+1]-y;
         MABuffer[i]=sma;
         Print("Этап 01 i=",i);      
        }

      if(i==0)
        {
          if(TimeC!=TimeX)
          {
        
            rel=Close[i+1]-Close[i+2];
            if(rel>0) sump=rel;
            else      sumn=-rel;
            positive=(Pos*(RSIPeriod-1)+sump)/RSIPeriod;
            negative=(Neg*(RSIPeriod-1)+sumn)/RSIPeriod;
            x=Pos;
            y=Neg;
            Pos=positive;
            Neg=negative;
            Print("positive=",positive);
            Print("negative=",negative);


            if(x>0)sma=Close[i+1]+x;
            else sma=Close[i+1]-y;
            MABuffer[i]=sma;
            Print("Этап 2 i=",i);          
            TimeX=iTime(NULL,TF,0);
            StopCalc=1;
          }          
        }
      i--;
     }

//----
   return(0);
  }
//+------------------------------------------------------------------+

の結果がオプション4と異なるのですが、どうしたのでしょうか?

 
-Aleks-:

リンクが開かない - 404エラー

タイミングを合わせて実験してみたが、うまくいかなかった......。最後の小節で計算を止めるにはどうしたらいいか」という方向で考えていたのが、私の間違いだったようです。これからは、現在のバーを変更する前に、計算の最後のステップに変更を加えない方法を考えたいと思います。

なぜそんなに重いのに、ピクリともしないのですか?あなたはすでに解決策を与えられているのですから、あとはじっくりと考えるだけです。もちろん結論は、まあ言葉もないのですが、Timeという言葉を見て、すぐに自分がやったと結論づけたわけですから......。

リンクは必要ありませんし、迷うこともありません。 必要なことはすべてこの記事に書かれていますので、詳しく説明します。

1.静的変数 LastTimeを宣言する。

2. 接頭辞 s と p を持つ一対の静的変数を宣言する。

3.IndicatorCounted()=0のとき、ステップ1、2で作成した変数をすべてNULLにする。

4.サイクルの始めに、値をリセットします。

if(Time[i]>LastTime)
        {
         LastTime=Time[i];
         pDir=cDir;

        }
      else
        {
         cDir=pDir;
        }
 
Dmitry Fedoseev:

なぜ、重箱の隅をつつくようなことをするのか、肝心なところはないのか。すでに決定事項が与えられているのだから、あとはじっくりと考えるだけだ。もちろん結論は、まあ言葉はないのですが、タイムが見て、すぐにあなたがやったと結論づけたということです......。

リンクは必要ありませんし、迷うこともありません。 必要なことはすべてこの記事に書かれていますので、詳しく説明します。

1.静的変数 LastTimeを宣言する。

2. 接頭辞 s と p を持つ一対の静的変数を宣言する。

3.IndicatorCounted()=0のとき、ステップ1、2で作成した変数をすべてNULLにする。

4.ループの最初に、値をリセットします。

if(Time[i]>LastTime)
        {
         LastTime=Time[i];
         pDir=cDir;

        }
      else
        {
         cDir=pDir;
        }

手伝いたいと言ってくれてありがとうございます

私はインジケータを書いた経験があまりないので、上記の私の最後のコードに示されているように、いくつかの困難-私が探している解決策-があります。

あなたの提案した方法は、どの変数をゼロにすればいいのかが分からないので、難しいのです。

私の変形が動作しない理由を説明していただけるなら - 私も計算をバーごとに1ティックに制限し、変数は変化しないはずです。この変形は、あなたが提案した変形とは異なり、すべてのティックでループがアイドル状態にならないので、コストが低いことが期待されます。

 
Artyom Trishkin:

その理屈はこうだ。

  1. 最後に決済された注文を種類と決済時刻で検索します。
  2. この注文が締め切られるまでに、締め切られたバーを見つけると
  3. バーの取得値がゼロより高ければ、新しいポジションを開くことができ、そうでなければ、開くことはできません。

私はここで次のようなニュアンスを持っています:私はこのコードを取りました(Alekseu Fedotovに 感謝します)。

//+----------------------------------------------------------------------------+
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 19.02.2008                                                     |
//|  Описание : Возвращает номер бара закрытия последней позиции или -1.       |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   ("" или NULL - текущий символ)          |
//|    tf - таймфрейм                  (    0       - текущий таймфрейм)       |
//|    op - операция                   (   -1       - любая позиция)           |
//|    mn - MagicNumber                (   -1       - любой магик)             |
//+----------------------------------------------------------------------------+
int NumberOfBarCloseLastPos(string sy="0", int tf=0, int op=-1, int mn=-1) {
  datetime t;
  int      i, k=OrdersHistoryTotal();

  if (sy=="" || sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
      if (OrderSymbol()==sy) {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (t<OrderCloseTime()) t=OrderCloseTime();
            }
          }
        }
      }
    }
  }
  return(iBarShift(sy, tf, t, True));
}

そして今、私はチェックを入れた。

if(УСЛОВИЕ && NumberOfBarCloseLastPos()>0)

そして、ここが問題なのですが、初期状態ではNumberOfBarCloseLastPosは"-1 "に設定されています。そして結果的に、最初の注文が開くことはない。

そんなとき、私たちはどうしたらいいのでしょうか。それとも、私が何か勘違いしているのでしょうか?