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

 
jarikn:
インジケータにアラートをねじ込むのを手伝ってください。

に、その中の指標に

int start()

int init()

int deinit()

ねじ込み式は、自分も他人も大切にしない...。

モダンなインターフェイスへのリデザインに手間をかける

 
Aleksei Stepanenko:

関数内でグローバル変数を 変更すると、その変数が変更されます。しかし、これは危険なプログラミングの方法です。なぜなら、コードが大きくなると、プログラムのさまざまな機能において、明らかでない割り当てが発生するからです。

プログラムの中にmain関数があり、そこでグローバル変数の 代入を行います。そして、他の機能では、このようにします。

あるいはこんな感じ。

膨大なコードでは、不要な変数変更(X)のポイントを見逃しがちなのは同意します。この観点から、Xの何が問題なのかを調べるために、その都度main関数を呼び出すのは正しいことです。しかし、ここで疑問が生じます。メイン関数が複数の異なる値(X,Y,Z)を計算し、出力するもので、しかもかなり大きく、Xはプログラムの中で繰り返し使われるとしたら、この方法は計算能力を過剰に消費しないか?つまり、Xを得るために、例えば1回だけ必要だった Xに加えてYとZも 再計算するブロックを繰り返し実行するのです。したがって、ある関数から別の関数への X の逐次変更・上書きを含むアルゴリズムであれば、プログラマにとっては複雑(注意やエラーチェックが必要)かもしれないが、機械にとっては容易なのである。

 
Maxim Kuznetsov:

に、その中の指標に

int start()

int init()

int deinit()

ねじ込み式は、自分も他人も大切にしない...。

モダンなインターフェイスへのリデザインに手間をかける

では、最新のインターフェースではどのように見えるのか、教えてください。この人はコードを書いたことがないらしい(そうでなければ、私たち抜きでAlertがわかったはずだ)。彼はどこかでコードを見つけ、ここに持ってきて、アラートを求めているだけです。

 
Oleksandr Nozemtsev:

しかし、ここで疑問が生じます。メイン関数が複数の異なる値(X, Y, Z)を計算し出力し、かなり大きく、Xが途中で何度も使われる場合

int X=0;

void OnTick()
   {
   if(УсловиеДляРедкогоРасчёта) X=ТяжёлыйРедкийРасчёт();
   
   ЛекийПостоянныйРасчёт(X);
   }   
   
 
Ilya Prozumentov:

最新のインターフェイスでどのように見えるべきかを示してください。この人はプログラミングをしたことがないようです(そうでなければ、私たちがいなくてもアラートがわかるはずです)。彼はどこかでコードを見つけ、ここに持ってきて、アラートを求めているだけです。

そんな「指標」や「アドバイザー」はどこから出てくるのでしょうか? でも、溶かしたら元も子もないのでは......。

は、長い間、サイトにはありません。

これらの指標のメーカーが成功しなかった場合、市場は新しいMQL5(4)に移行しています。そこで助けてくれたり、説明してくれたりするので、みんなの役に立つと思います。

またはフリーランスへ

 
Maxim Kuznetsov:

が、糖蜜なら

糖蜜という言葉から、ですか?

 
jarikn:
みんな、インジケータにアラートを付けるのを手伝ってくれ。
#property copyright "Subu"
#property link      "http://www.google.com"
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Red
#property indicator_width1 2
#property indicator_width2 2
#property indicator_chart_window

double UpArrow[];
double DownArrow[];
extern int ShiftArrow = -2;
extern bool FilterBullBearCandle = false;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0, DRAW_ARROW, EMPTY,2);
   SetIndexArrow(0, 233);
   SetIndexBuffer(0, UpArrow);
   SetIndexEmptyValue(0,0.0);
   SetIndexShift(0,ShiftArrow);
   SetIndexStyle(1, DRAW_ARROW, EMPTY,2);
   SetIndexArrow(1, 234);
   SetIndexBuffer(1, DownArrow);
   SetIndexEmptyValue(1,0.0);
   SetIndexShift(1,ShiftArrow);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start(){
   int counted_bars=IndicatorCounted();
   int limit, i;
//---- last counted bar will be recounted

   limit=Bars-counted_bars;
//----
   for(i = 1; i < limit; i++){
      DownArrow[i] = 0;
      UpArrow[i] = 0;
      if(High[i+2]>High[i+1] && Low[i+2]>Low[i+1] && High[i+2]>High[i+3] && Low[i+2]>Low[i+3]){
         if( Open[i+1]>Close[i+1] && Close[i+2] > Close[i+1]){
            if(FilterBullBearCandle){
               if( Open[i+2]>Close[i+2]){
                  DownArrow[i] = High[i+2] +0.0003;//Low[i+2] + (High[i+2]-Low[i+2]);
                  if(counted_bars > 0) Alert("Signal down: ", DownArrow[i]);
               }
            }
            else{
                DownArrow[i] = High[i+2] +0.0003;//Low[i+2] + (High[i+2]-Low[i+2]);
                if(counted_bars > 0) Alert("Signal down: ", DownArrow[i]);
            }
         }
      }
      if(High[i+2]<High[i+1] && Low[i+2]<Low[i+1] && High[i+2]<High[i+3] && Low[i+2]<Low[i+3]){
         if(Open[i+1]<Close[i+1] && Close[i+2] < Close[i+1]){
            if(FilterBullBearCandle){
               if( Open[i+2]<Close[i+2]){
                  UpArrow[i] = Low[i+2] - 0.0003;//High[i+2] - (High[i+2]-Low[i+2]);
                  if(counted_bars > 0) Alert("Signal up: ", UpArrow[i]);
               }
            }
            else{
               UpArrow[i] = Low[i+2] - 0.0003;//High[i+2] - (High[i+2]-Low[i+2]);
               if(counted_bars > 0) Alert("Signal up: ", UpArrow[i]);
            }
         }
      }
   }
   return(0);
}
 
私は関数を呼び出すときに パラメータにローソク足の開閉を毎回記述する必要がないように、関数のパラメータを介してではなくOnCalculateから関数に開閉とTDを渡す方法についてmql5をアドバイスしてください。

根源
myfunc(int index, double open[], double close[], double high[], double low[] etc.)

欲しい
myfunc(int index)

そして、すべてのバーデータ(prev, rates, open[]...など)は、この関数の中に書き込まれます。

 
jarikn :
彼ら。アラートをインジケーターに固定するのに役立ちます。

ねじ込み-コードベースと作者からのコードを覚えていません-感謝を言う必要があります! -彼が自分のコードを認識した場合-私は彼に感謝します!

そしてここにあなたの指標があります-私はそれをしました-アラート付きのMT5でのみ。

 //+------------------------------------------------------------------+
//|                                                       jarikn.mq5 |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link        " https://www.mql5.com "
//---- номер версии индикатора
#property version    "1.00"
//---- отрисовка индикатора в главном окне
#property indicator_chart_window
//---- для расчета и отрисовки индикатора использовано два буфера
#property indicator_buffers 2
//---- использовано всего два графических построения
#property indicator_plots    2
//+----------------------------------------------+
//|  Параметры отрисовки бычьго индикатора       |
//+----------------------------------------------+
//---- отрисовка индикатора 1 в виде символа
#property indicator_type1    DRAW_ARROW
//---- в качестве цвета бычей линии индикатора использован розовый цвет
#property indicator_color1   Lime
//---- толщина линии индикатора 1 равна 4
#property indicator_width1    2
//---- отображение метки медвежьей линии индикатора
#property indicator_label1    "jarikn Buy"
//+----------------------------------------------+
//|  Параметры отрисовки медвежьего индикатора   |
//+----------------------------------------------+
//---- отрисовка индикатора 2 в виде символа
#property indicator_type2    DRAW_ARROW
//---- в качестве цвета медвежьей линии индикатора использован зеленый цвет
#property indicator_color2   Magenta
//---- толщина линии индикатора 2 равна 4
#property indicator_width2    2
//---- отображение метки бычьей линии индикатора
#property indicator_label2    "jarikn Sell"
//+----------------------------------------------------+
//| перечисление для вариантов транслируемых сигналов  |
//+----------------------------------------------------+
enum ENUM_SIGNAL_MODE
  {
   MODE_SIGNAL,   //Сигналы пробоя
   MODE_TREND     //Сигналы пробоя и тренда
  };
//+----------------------------------------------+
//| Входные параметры индикатора                 |
//+----------------------------------------------+
input int   ShiftArrow = 0 ;
input group   "---- Входные переменные для алертов ----"
input ENUM_SIGNAL_MODE SignMode=MODE_SIGNAL; //Вариант подачи сигнала
input uint NumberofBar= 0 ;                     //Номер бара для подачи сигнала
input bool SoundON= true ;                     //Разрешение алерта
input uint NumberofAlerts= 1 ;                 //Количество алертов
input bool EMailON= false ;                     //Разрешение почтовой отправки сигнала
input bool PushON= false ;                     //Разрешение отправки сигнала на мобильный
//--- indicator buffers
//---- объявление динамических массивов, которые будут в
//---- дальнейшем использованы в качестве индикаторных буферов
double UpArrow[];
double DownArrow[];

int StartBars;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit ()
  {
//--- indicator buffers mapping
   StartBars= 5 ;
//---- превращение динамического массива в индикаторный буфер
   SetIndexBuffer ( 0 ,UpArrow, INDICATOR_DATA );
//---- осуществление сдвига начала отсчета отрисовки индикатора 1
   PlotIndexSetInteger ( 0 , PLOT_DRAW_BEGIN ,StartBars);
//--- создание метки для отображения в DataWindow
   PlotIndexSetString ( 0 , PLOT_LABEL , "jarikn Buy" );
//---- символ для индикатора
   PlotIndexSetInteger ( 0 , PLOT_ARROW , 108 );
//---- индексация элементов в буфере как в таймсерии
   ArraySetAsSeries (UpArrow, true );
//--- line shifts when drawing
   PlotIndexSetInteger ( 0 , PLOT_SHIFT ,ShiftArrow);
//---- превращение динамического массива в индикаторный буфер
   SetIndexBuffer ( 1 ,DownArrow, INDICATOR_DATA );
//---- осуществление сдвига начала отсчета отрисовки индикатора 2
   PlotIndexSetInteger ( 1 , PLOT_DRAW_BEGIN ,StartBars);
//--- создание метки для отображения в DataWindow
   PlotIndexSetString ( 1 , PLOT_LABEL , "jarikn Sell" );
//---- символ для индикатора
   PlotIndexSetInteger ( 1 , PLOT_ARROW , 108 );
//---- индексация элементов в буфере как в таймсерии
   ArraySetAsSeries (DownArrow, true );
//--- line shifts when drawing
   PlotIndexSetInteger ( 1 , PLOT_SHIFT ,ShiftArrow);
//---- установка формата точности отображения индикатора
   IndicatorSetInteger ( INDICATOR_DIGITS , _Digits );
//---- имя для окон данных и лэйба для субъокон
   string short_name= "jarikn" ;
   IndicatorSetString ( INDICATOR_SHORTNAME ,short_name);
//---
   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<StartBars)
       return ( 0 );
   int limit,i;
//---- расчет стартового номера first для цикла пересчета баров
   if (prev_calculated>rates_total || prev_calculated<= 0 ) // проверка на первый старт расчета индикатора
      limit=rates_total-StartBars;   // стартовый номер для расчета всех баров
   else
      limit=rates_total-prev_calculated; // стартовый номер для расчета новых баров
//---- индексация элементов в массивах как в таймсериях
   ArraySetAsSeries (Open, true );
   ArraySetAsSeries (High, true );
   ArraySetAsSeries (Low, true );
   ArraySetAsSeries (Close, true );
//----
   for (i = 0 ; i <= limit; i++)
     {
      DownArrow[i] = 0 ;
      UpArrow[i] = 0 ;
       if (High[i+ 2 ]>High[i+ 1 ] && Low[i+ 2 ]>Low[i+ 1 ] && High[i+ 2 ]>High[i+ 3 ] && Low[i+ 2 ]>Low[i+ 3 ])
         if (Open[i+ 1 ]>Close[i+ 1 ] && Close[i+ 2 ] > Close[i+ 1 ])
           {
             if (Open[i+ 2 ]>Close[i+ 2 ])
               DownArrow[i] = High[i+ 2 ] + 0.0003 ; //Low[i+2] + (High[i+2]-Low[i+2]);
           }
       if (High[i+ 2 ]<High[i+ 1 ] && Low[i+ 2 ]<Low[i+ 1 ] && High[i+ 2 ]<High[i+ 3 ] && Low[i+ 2 ]<Low[i+ 3 ])
         if (Open[i+ 1 ]<Close[i+ 1 ] && Close[i+ 2 ] < Close[i+ 1 ])
           {
             if (Open[i+ 2 ]<Close[i+ 2 ])
               UpArrow[i] = Low[i+ 2 ] - 0.0003 ; //High[i+2] - (High[i+2]-Low[i+2]);
           }
     }
//--- alert
   BuySignal( "Alert BuySignal" ,UpArrow, 0 ,rates_total,prev_calculated,Close,spread);
   SellSignal( "Alert SellSignal" ,DownArrow, 0 ,rates_total,prev_calculated,Close,spread);
//--- OnCalculate done. Return new prev_calculated.
   return (rates_total);
  }
//+------------------------------------------------------------------+
//| Buy signal function                                              |
//+------------------------------------------------------------------+
void BuySignal( string SignalSirname, // текст имени индикатора для почтовых и пуш-сигналов
               double &ColorArray[], // цветовой индексный буфер
               int ColorIndex, // индекс цвета в цветовом индескном буфере для подачи сигнала
               const int Rates_total,     // текущее количество баров
               const int Prev_calculated, // количество баров на предыдущем тике
               const double &Close[],     // цена закрытия
               const int &Spread[])       // спред
  {
//---
   static uint counter= 0 ;
   if (Rates_total!=Prev_calculated)
      counter= 0 ;
   bool BuySignal= false ;
   bool SeriesTest= ArrayGetAsSeries (ColorArray);
   int index,index1;
   if (SeriesTest)
     {
      index= int (NumberofBar);
      index1=index+ 1 ;
     }
   else
     {
      index=Rates_total- int (NumberofBar)- 1 ;
      index1=index- 1 ;
     }
   if (SignMode==MODE_SIGNAL)
     {
       if (ColorArray[index1]!=ColorIndex && ColorArray[index]==ColorIndex)
         BuySignal= true ;
     }
   else
     {
       if (ColorArray[index]==ColorIndex)
         BuySignal= true ;
     }
   if (BuySignal && counter<=NumberofAlerts)
     {
      counter++;
       MqlDateTime tm;
       TimeToStruct ( TimeCurrent (),tm);
       string text= TimeToString ( TimeCurrent (), TIME_DATE )+ " " + string (tm.hour)+ ":" + string (tm.min);
      SeriesTest= ArrayGetAsSeries (Close);
       if (SeriesTest)
         index= int (NumberofBar);
       else
         index=Rates_total- int (NumberofBar)- 1 ;
       double Ask=Close[index];
       double Bid=Close[index];
      SeriesTest= ArrayGetAsSeries (Spread);
       if (SeriesTest)
         index= int (NumberofBar);
       else
         index=Rates_total- int (NumberofBar)- 1 ;
      Bid+= _Point *Spread[index];
       string sAsk= DoubleToString (Ask, _Digits );
       string sBid= DoubleToString (Bid, _Digits );
       string sPeriod=GetStringTimeframe( ChartPeriod ());
       if (SignMode==MODE_SIGNAL || (SignMode==MODE_TREND && ColorArray[index1]!=ColorIndex))
        {
         if (SoundON)
             Alert ( "BUY signal \n Ask=" ,Ask, "\n Bid=" ,Bid, "\n currtime=" ,text, "\n Symbol=" , Symbol (), " Period=" ,sPeriod);
         if (EMailON)
             SendMail (SignalSirname+ ": BUY signal alert" , "BUY signal at Ask=" +sAsk+ ", Bid=" +sBid+ ", Date=" +text+ " Symbol=" + Symbol ()+ " Period=" +sPeriod);
         if (PushON)
             SendNotification (SignalSirname+ ": BUY signal at Ask=" +sAsk+ ", Bid=" +sBid+ ", Date=" +text+ " Symbol=" + Symbol ()+ " Period=" +sPeriod);
        }
       else
        {
         if (SoundON)
             Alert ( "Up Trend signal \n Ask=" ,Ask, "\n Bid=" ,Bid, "\n currtime=" ,text, "\n Symbol=" , Symbol (), " Period=" ,sPeriod);
         if (EMailON)
             SendMail (SignalSirname+ ": Up Trend signal alert" , "BUY signal at Ask=" +sAsk+ ", Bid=" +sBid+ ", Date=" +text+ " Symbol=" + Symbol ()+ " Period=" +sPeriod);
         if (PushON)
             SendNotification (SignalSirname+ ": Up Trend signal at Ask=" +sAsk+ ", Bid=" +sBid+ ", Date=" +text+ " Symbol=" + Symbol ()+ " Period=" +sPeriod);
        }
     }
//---
  }
//+------------------------------------------------------------------+
//| Sell signal function                                             |
//+------------------------------------------------------------------+
void SellSignal( string SignalSirname, // текст имени индикатора для почтовых и пуш-сигналов
                 double &ColorArray[],       // цветовой индексный буфер
                 int ColorIndex,             // индекс цвета в цветовом индескном буфере для подачи сигнала
                 const int Rates_total,     // текущее количество баров
                 const int Prev_calculated, // количество баров на предыдущем тике
                 const double &Close[],     // цена закрытия
                 const int &Spread[])       // спред
  {
//---
   static uint counter= 0 ;
   if (Rates_total!=Prev_calculated)
      counter= 0 ;
   bool SellSignal= false ;
   bool SeriesTest= ArrayGetAsSeries (ColorArray);
   int index,index1;
   if (SeriesTest)
     {
      index= int (NumberofBar);
      index1=index+ 1 ;
     }
   else
     {
      index=Rates_total- int (NumberofBar)- 1 ;
      index1=index- 1 ;
     }
   if (SignMode==MODE_SIGNAL)
     {
       if (ColorArray[index1]!=ColorIndex && ColorArray[index]==ColorIndex)
         SellSignal= true ;
     }
   else
     {
       if (ColorArray[index]==ColorIndex)
         SellSignal= true ;
     }
   if (SellSignal && counter<=NumberofAlerts)
     {
      counter++;
       MqlDateTime tm;
       TimeToStruct ( TimeCurrent (),tm);
       string text= TimeToString ( TimeCurrent (), TIME_DATE )+ " " + string (tm.hour)+ ":" + string (tm.min);
      SeriesTest= ArrayGetAsSeries (Close);
       if (SeriesTest)
         index= int (NumberofBar);
       else
         index=Rates_total- int (NumberofBar)- 1 ;
       double Ask=Close[index];
       double Bid=Close[index];
      SeriesTest= ArrayGetAsSeries (Spread);
       if (SeriesTest)
         index= int (NumberofBar);
       else
         index=Rates_total- int (NumberofBar)- 1 ;
      Bid+= _Point *Spread[index];
       string sAsk= DoubleToString (Ask, _Digits );
       string sBid= DoubleToString (Bid, _Digits );
       string sPeriod=GetStringTimeframe( ChartPeriod ());
       if (SignMode==MODE_SIGNAL || (SignMode==MODE_TREND && ColorArray[index1]!=ColorIndex))
        {
         if (SoundON)
             Alert ( "SELL signal \n Ask=" ,Ask, "\n Bid=" ,Bid, "\n currtime=" ,text, "\n Symbol=" , Symbol (), " Period=" ,sPeriod);
         if (EMailON)
             SendMail (SignalSirname+ ": SELL signal alert" , "SELL signal at Ask=" +sAsk+ ", Bid=" +sBid+ ", Date=" +text+ " Symbol=" + Symbol ()+ " Period=" +sPeriod);
         if (PushON)
             SendNotification (SignalSirname+ ": SELL signal at Ask=" +sAsk+ ", Bid=" +sBid+ ", Date=" +text+ " Symbol=" + Symbol ()+ " Period=" +sPeriod);
        }
       else
        {
         if (SoundON)
             Alert ( "Down trend signal \n Ask=" ,Ask, "\n Bid=" ,Bid, "\n currtime=" ,text, "\n Symbol=" , Symbol (), " Period=" ,sPeriod);
         if (EMailON)
             SendMail (SignalSirname+ ": Down trend signal alert" , "SELL signal at Ask=" +sAsk+ ", Bid=" +sBid+ ", Date=" +text+ " Symbol=" + Symbol ()+ " Period=" +sPeriod);
         if (PushON)
             SendNotification (SignalSirname+ ": Down trend signal at Ask=" +sAsk+ ", Bid=" +sBid+ ", Date=" +text+ " Symbol=" + Symbol ()+ " Period=" +sPeriod);
        }
     }
//---
  }
//+------------------------------------------------------------------+
//|  Получение таймфрейма в виде строки                              |
//+------------------------------------------------------------------+
string GetStringTimeframe( ENUM_TIMEFRAMES timeframe)
  {
//----
   return ( StringSubstr ( EnumToString (timeframe), 7 ,- 1 ));
//----
  }
//+------------------------------------------------------------------+
 
Алексей КоКоКо:
で、すべてのバーデータ(prev, rates, open[]...and TDs)が関数内で何らかの形で吸い上げられました。

どのように吸い込まれたのでしょうか?こんな感じ?

void MyFunc()
   {
   double high=iHigh(symbol,frame,0);

   }