mql5言語の特徴、微妙なニュアンスとテクニック - ページ 189

 
Nikolai Semko:

CTestTimerクラスのTimer4メソッド(青色で表示)を実行する必要があります。

入り込めなかった。

#property indicator_chart_window
#include <Timer.mqh> // https://www.mql5.com/ru/code/31306

//+------------------------------------------------------------------+
class CTestTimer {
 private:
   //typedef void (CTestTimer::*TFunc2)(); // так работает в C++, но здесь не работает
 public:
   static int x4;
   CTestTimer() {
      //TFunc2 p=CTestTimer::Timer4;
      //TFunc2 p=Timer4;
      //timers.NewTimer(700,p);
      timers.NewTimer(700,Method2Function); // ошибка 'Timer4' - pointer to this function type is not supported yet
   };
   ~CTestTimer(){};
   static void Timer4() {
      x4++;
      if (x4==7) timers.KillTimer(Method2Function); // удаляем этот таймер
   }
};
//+------------------------------------------------------------------+

static int CTestTimer::x4 = 0;

void Method2Function()
{
  CTestTimer::Timer4();
}
 

トレーディング、自動売買システム、トレーディング戦略のテストに関するフォーラム

mql5の特性、ヒントとコツ

fxsaber, 2020.05.14 02:57

また、手に入れました。再ログイン時にまれに発生することがあると推測されます。

解決策は、もし偽の場合は、しばらく間を置いてから再試行することです。

bool IsTradeAllowed( const int Attempts = 0 )
{        
  // https://www.mql5.com/ru/forum/170952/page174#comment_16363677
  bool Res = false;
  int Count = 0;
  
  // https://www.mql5.com/ru/forum/170952/page174#comment_16363677
  while (!(Res = ::MQLInfoInteger(MQL_TRADE_ALLOWED) &&
                 ::AccountInfoInteger(ACCOUNT_TRADE_EXPERT) &&
                 ::AccountInfoInteger(ACCOUNT_TRADE_ALLOWED) &&
                 ::TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) &&
         (Count++ < Attempts) && !::IsStopped())
    ::Sleep(100);
    
  return(Res);
}

これは悪い解決策です。ここで、もっと良い解決策があります。

const bool Init = EventSetMillisecondTimer(1);

bool Allowed()
{
  return(::MQLInfoInteger(MQL_TRADE_ALLOWED) &&
         ::AccountInfoInteger(ACCOUNT_TRADE_EXPERT) &&
         (::AccountInfoInteger(ACCOUNT_TRADE_ALLOWED) || !::TerminalInfoInteger(TERMINAL_CONNECTED)) &&
         ::TerminalInfoInteger(TERMINAL_TRADE_ALLOWED));
}

void OnTimer()
{
  if (!Allowed())
    ExpertRemove();
}

手動で再ログインした場合でも、このEAは動作します。ハイライトされた文字列がない場合は、自己削除されます。

 
fxsaber:

入り込めなかった。

お忙しい中、ありがとうございました。しかし、私は上で、このメソッドは非静的であるべきだと書きました。静的メソッドで可能であることは明らかです。静的メソッドは全くOOPではありません。
明らかに欲張りすぎというか、無理がありました。
C++でこんなことができるのか、と戸惑いましたが、調べてみると、このようなポインタは全く違う構造をしていることが理解できました。

https://habr.com/ru/post/333334/


そして、それは理解できる。


しかし、すべてのオブジェクトは、それ自身のユニークな内部変数の現在の状態を持っています。したがって、非静的メソッドへのポインタは、そのメソッドが現時点で適用されるオブジェクトパラメータ構造で満たされている必要があります。

異なるクラスのオブジェクトを一般的に制御するための他の方法を探す必要があります。

解がないことの証明もまた、解である。

 
Nikolai Semko:

お忙しい中、ありがとうございました。しかし、私は上で、このメソッドは非静的であるべきだと書きました。静止画で可能であることは明らかです。

上記で2つの例を挙げましたが、1つはフル実装のものです。
 
TheXpert:
上記で2つの例を挙げましたが、1つはフル実装のものです。

あなたは私の問題を理解していないようだ。
解決策がないのです。

 
Nikolai Semko:

あなたは私の問題を理解していないようだ。
解決策がないのです。

隣にドアがあるのに、なぜ壁に頭をぶつけるのか? 外部クラスへのハンドラー呼び出しによるマルチタイマー問題が解決されました。

この 仲間は、あなたが考えているような問題に対する解決策を持っています。

 
TheXpert:
隣にドアがあるのに、なぜ壁に頭をぶつけるのか? 外部クラスへのハンドラ呼び出しによるマルチタイマータスクを解決しました。

タイマーがどうのこうのではなく、
白昼夢のようなバカ騒ぎでした。

 
Nikolai Semko:

白昼夢をみて呆然としていたところです。

本格的なtypedefや mqlで同じバインドをするのは大賛成ですが、それくらいが限界です。

 

手動で作成したグラフィックオブジェクトとインジケーターや EAで作成した オブジェクトを区別することは可能ですか?

機能では

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
  {
   if(id == CHARTEVENT_OBJECT_CREATE)
     {

     }
  }
 
Vladimir Pastushak:

手動で作成したグラフィックオブジェクトとインジケーターや EAで作成した オブジェクトを区別することは可能ですか?

機能では

マウスの左ボタン操作でできます。
例えばこんな感じ。

#property indicator_chart_window
#include <Timer.mqh> //https://www.mql5.com/ru/code/31306

uint t_LMB=0;
int OnInit() {
   ChartSetInteger(0,CHART_EVENT_OBJECT_CREATE,0,true);
   ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,const int prev_calculated,const int begin,const double &price[]) {
   return(rates_total);
}
//+------------------------------------------------------------------+
void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam) {
   static string str=sparam;
   if(str!="1" && sparam=="1") t_LMB=GetTickCount(); // нажате левая кнопка мышки
   if(id == CHARTEVENT_OBJECT_CREATE) {
      CheckManual(GetTickCount());
   }
   str=sparam;
}
//+------------------------------------------------------------------+
void CheckManual(uint start=0) {
   static uint s=0;
   if (start>0) {
      s=start;
      timers.NewTimer(20,Timer1); // Создаем таймер на 20 милисекунд и функцией-обработчиком Timer1()
      return;
   }
   int pause = int(t_LMB-s);
   if (pause>=0 && pause<20) Print("Создан графический объект в ручную");
   else Print ("Создан графический объект программно");
   timers.KillTimer(Timer1); // удаляем таймер Timer1
}
//+------------------------------------------------------------------+
void Timer1() {CheckManual();}
理由: