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

 
Vitaly Muzichenko:

次の小節を比較し、シーケンスが壊れていたら、フラグをリセットし、いくつ正解だったかを書き込んで、ループを進みます。

そのバーが強気で、次のバーが弱気であることが分かれば十分で、次のバーは、前のバーと同じであれば、その値を書き込んで、フラッグをリセットするのです。といった具合に、最後まで

しかし、最初の1つは強気になれないかもしれない。

   for(int i=limit-1; i>0; i--)

     {


      if(open[i]<close[i]&&open[i+1]>close[i+1]&&open[i+3]<close[i+3])

        {

         up++;

        }

      else up=0;

    
    
if(max_c<up)max_c=up;

Comment(max_c);
}

//--- return value of prev_calculated for next call

   return(rates_total);

  }

 
PolarSeaman:

が、1枚目は牛じゃないかもしれないけど、仕方ない。

ここでは、全く正しくないが、常に弱気のろうそくからカウントするバリアントは、次のとおりです。

ファイル:
aCandle.mq4  8 kb
 
Vitaly Muzichenko:

ここでは、全く正しくないが、常に弱気のろうそくからカウントするバリアントは、次のとおりです。

ありがとうございます。この数字を二乗して1を足すと、正しい結果になる。

if(i%2==0)でチェックされている?
 
PolarSeaman:

が、1枚目はまさかのブルではないかもしれません。


同じローソク足を見つけて、連鎖の方向を変える例を紹介します。

//+------------------------------------------------------------------+
//|                                              CandlesSequence.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                             https://mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://mql5.com/ru/users/artmedia70"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   1
//--- plot Sequence
#property indicator_label1  "Sequence"
#property indicator_type1   DRAW_COLOR_HISTOGRAM
#property indicator_color1  clrGreen,clrRed,clrGray
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
//--- enums
enum ENUM_CANDLE_TYPE
  {
   CANDLE_TYPE_BULL  =  0,       // Bullish candle
   CANDLE_TYPE_BEAR  =  1,       // Bearish candle
   CANDLE_TYPE_DOJI  = -1        // Doji candle
  };
//--- indicator buffers
double         BufferSeq[];
double         BufferSeqColors[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,BufferSeq,INDICATOR_DATA);
   SetIndexBuffer(1,BufferSeqColors,INDICATOR_COLOR_INDEX);
//--- setting indicator parameters
   IndicatorSetString(INDICATOR_SHORTNAME,"Candles sequence");
   IndicatorSetInteger(INDICATOR_DIGITS,Digits());
//--- setting buffer arrays as timeseries
   ArraySetAsSeries(BufferSeq,true);
   ArraySetAsSeries(BufferSeqColors,true);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//--- Проверка на минимальное колиество баров для расчёта
   if(rates_total<2) return 0;
//--- Установка массивов буферов как таймсерий
   ArraySetAsSeries(open,true);
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);
   ArraySetAsSeries(close,true);
   ENUM_CANDLE_TYPE type_refs=CANDLE_TYPE_DOJI;
   ENUM_CANDLE_TYPE type_curr=CANDLE_TYPE_DOJI;
//--- Проверка и расчёт количества просчитываемых баров   
   int limit=rates_total-prev_calculated;
   if(limit>1)
     {
      limit=rates_total-2;
      ArrayInitialize(BufferSeq,EMPTY_VALUE);
      BufferSeq[rates_total-1]=open[rates_total-1];
     }
//--- Расчёт индикатора
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {
      type_refs=GetTypeCandle(i+1,open,close);
      type_curr=GetTypeCandle(i,open,close);
   //--- смена направления цепочки свечей
      if(!CheckCandle(type_refs,type_curr))
        {
         BufferSeq[i]=(type_curr==CANDLE_TYPE_BULL ? low[i]: type_curr==CANDLE_TYPE_BEAR ? high[i]: open[i]);
        }
   //--- свечи одного типа
      else
        {
         BufferSeq[i]=BufferSeq[i+1];
        }
      BufferSeqColors[i]=(type_curr==CANDLE_TYPE_BULL ? 0 : type_curr==CANDLE_TYPE_BEAR ? 1 : 2);
     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Возвращает тип свечи                                             |
//+------------------------------------------------------------------+
ENUM_CANDLE_TYPE GetTypeCandle(const int shift,const double &open[],const double &close[])
  {
   return(close[shift]>open[shift] ? CANDLE_TYPE_BULL : close[shift]<open[shift] ? CANDLE_TYPE_BEAR : CANDLE_TYPE_DOJI);
  }
//+------------------------------------------------------------------+
//| Сравнивает два типа свечей                                       |
//+------------------------------------------------------------------+
bool CheckCandle(const ENUM_CANDLE_TYPE reference_candle_type,const ENUM_CANDLE_TYPE checked_candle_type)
  {
   return(reference_candle_type==checked_candle_type ? true : false);
  }
//+------------------------------------------------------------------+

これで、連鎖が続くところでは、連鎖しているキャンドルの数を数えてリストに保存し、新しい連鎖に変わるところでは、新たにカウントを開始することができるようになりました。

各チェーンのキャンドルの本数をソートして保存することができます。そして、リストをソートすることで、最大 配列と最小配列を求めることができる。

 
PolarSeaman:

ありがとうございます。得られた数を二乗して1を足せば正解となる。

if(i%2==0)をチェックしていることでしょうか。

iが2の倍数の場合。

iを2で割った余り である

 
Juer:

ここでは、コンパイル時にローカル変数のサイズが大きすぎる(512kb以上)ことが原因です。

どこを見て、何をすればいいのか?関数内に文字列配列CArrayStringがあるので、エラーになるのでは?

Add()メソッドで注入した後、Clear()Shutdown() を再度行っています。そして、Add()メソッドを使って新しいデータで再度埋めています。この場合、配列は再び0項目で埋め尽くされるのでしょうか?

コンパイル段階ですでにメモリを占有しているクラスから、そのようなメンバーを削除しなければならない。このデータは、常に非常に小さいスタック・メモリに割り当てられる。この問題を解決するためには、多くのメモリを占有するクラスメンバに対して動的にメモリを割り当てることが必要です。

例えば、クラスメンバがある場合。

class A
{
   double m_arrfArray[9999999];
};

と置き換える必要があります。

class A
{
   double m_arrfMyArray[];
};

bool A::Init()
{
   if (ArrayResize(m_arrfMyArray, 9999999) != 9999999)
      return false;
   ....
}
 
Ihor Herasko:

コンパイル段階ですでにメモリを占有しているメンバをクラスから削除する必要があります。このデータは、常に非常に小さいスタック・メモリに置かれることになる。この問題を解決するためには、多くのメモリを占有するクラスメンバに対して動的にメモリを割り当てることが必要です。

例えば、クラスメンバがある場合。

であれば、それに置き換える必要があります。

ありがとうございます。どうにかして、各関数のパラメータからクラスを削除することで、この問題を解決しました。一般に、このオブジェクトはすべてのメソッドに対して一度だけ初期化することが可能であった。

CArrayクラス、より具体的にはCArrayObjについて、もう一つ質問があります。Delete()メソッドはあるが、配列内の要素を移動させないのか?つまり、Delete(18)を削除すると、この位置の項目が削除され、後でこのインデックスで項目を照会しようとすると、無効なポインタが表示されるのです。この場合、18番目の要素が削除後に19番目の要素になるように、要素を削除して移動するような方法はありますか?

 
Juer:

ありがとうございます。どうにかして、各関数のパラメータからクラスを削除することで、この問題を解決しました。一般に、このオブジェクトはすべてのメソッドに対して一度だけ初期化することが可能であった。

CArrayクラス、より具体的にはCArrayObjについて、もう一つ質問があります。Delete()メソッドはあるが、配列の要素を移動させないのか?つまり、Delete(18)を削除すると、この位置の項目が削除され、後でこのインデックスで項目を照会しようとすると、無効なポインタが表示されるのです。項目を削除して移動させ、削除後の18番目の項目が19番目の項目になるような方法はないでしょうか?

標準ライブラリを扱ったことはありませんが、ヘルプによると、Delete()メソッドは物理的に要素を削除し、配列のサイズを変更する必要があるようです。例外:メモリ管理機構が無効の場合。デフォルトでは、この機構は有効になっています。FreeModeメソッドは、メモリ管理フラグの状態を確認するために使用されます。

私としては、CArrayクラスに特別な利便性や優位性を見出せないので、MQLでは自分で配列を使い(C++ではベクトルやリストを使うが)、メモリ管理も自分で行うことをお勧めしたい。私はこの方法を使って、自分の配列の項目を割と早く削除しています。

template<typename Array>
bool DeleteArrayElement(Array &array[], int nIndex)
{
   int nArraySize = ArraySize(array);
   if (nIndex < 0 || nIndex >= nArraySize)
      return true;
   
   array[nIndex] = array[nArraySize - 1];
   return (ArrayResize(array, nArraySize - 1, ARRAY_RESERVE_SIZE) == nArraySize - 1);
}

唯一の欠点は、配列の項目の順序を保持しないことです。つまり、順序付き(ソート済み)配列を除くすべての配列に適用できる。

 

こんにちは、MT4で保留中の買い注文と 売り注文を 現在の価格から一定のpips数で一度に出すことができるスクリプトはどこにあるか教えてください、つまり手動で数える必要はなく、多分注文ウィンドウに入ることもないでしょう?注文画面に行きたくない。 ありがとうございました。

PS: スクリプトを使ったことがないので、何か間違ったことを聞いているのかもしれません。

 

"StopLossまたはTakeProfitの値がFreezeLevelパラメータに違反する場合、成行注文を閉じることはできません。" という点について教えてください。

これは文字通り、TakeProfitまたはStopLossがFreezeLevelに満たない場合、成行注文を閉じることができないことを意味しますか?オープンマーケットオーダーがStopLevelまたはFreezeLevelルールに違反するストップを持つことができるのか、よく理解できないのですが?結局、間違ったストップが設定されると、サーバーはエラーを出すだけで、ストップは設定されないのです。

また、ブローカーがFreezeLevelを使用している場合、成行注文を閉じる際に他に知っておくべきことがあれば教えてください。

Требования и ограничения при проведении торговых операций - Приложения - Учебник по MQL4
Требования и ограничения при проведении торговых операций - Приложения - Учебник по MQL4
  • book.mql4.com
В таблицах указаны расчётные значения, ограничивающие проведение торговых операций при открытии, закрытии, установке, удалении и модификации ордеров. Для получения значения минимальной дистанции StopLevel и дистанции заморозки FreezeLevel необходимо вызвать функцию MarketInfo(). Требования. Правильные цены, используемые при осуществлении...