エキスパート: Diff_TF_MA_EA - ページ 2

 
fxsaber:

実際には、このコードにはもっと多くの誤りがある。例えば、SBスタイルのためだけにCsymbolInfoを使うのは邪道だということがよくわかる。

以前に収集したチケットのリストを通じてポジションをクローズすることは悪である。これは非常によくあるエラーだ。

これは多くのことを物語っていると思います:

このEAはトレーニング用であることを理解する価値がある。

サーバーのリターンコードの処理について。個人的には、私は常に処理します。しかし、テスターでは(トレーニング用EAはテスター用であり、自分でさらに改良するために作られたものであることを理解してほしい)、おそらく必要なリターンコードをすべて処理する価値はないでしょう。常に自分自身の取引環境を持つことは、実際の取引においても、テスターにおいても、非常に正当なことなのです。

そこに何があるのかを見ることができる:

まず、既存のポジションに関するデータを入力します:

//--- チケットリストの記入
   int positions_total=PositionsTotal();
   if(prev_total!=positions_total)
     {
      FillingListTickets();
      prev_total=positions_total;
     }
   int num_b=NumberBuy();
   int num_s=NumberSell();

次に、シグナルをチェックした後、ポジションを建てる(ここでは買いポジションを建てる):

      if(open_long)
        {
         if(num_s>0) CloseSell();
         if(num_b==0)
           {
            double sl=(InpStopLoss==0   ? 0 : CorrectStopLoss(ORDER_TYPE_BUY,InpStopLoss));
            double tp=(InpTakeProfit==0 ? 0 : CorrectTakeProfit(ORDER_TYPE_BUY,InpTakeProfit));
            double ll=trade.CheckVolume(symb,lot,symbol_info.Ask(),ORDER_TYPE_BUY);
            if(ll>0 && CheckLotForLimitAccount(POSITION_TYPE_BUY,ll))
              {
               if(trade.Buy(ll,symb,0,sl,tp))
                  FillingListTickets();
              }
           }
        }

売りポジションの数がゼロより大きい場合、クローズします。Expert Advisorはスイングします - ポジションは常に1つだけです。そのため、売りポジションがあれば買いポジションはありません。その数をチェックする必要はありませんし、Expert Advisor の内部配列で取引環境を更新する必要もありません。
次に、買いポジションの 数をチェックします。その数がゼロより大きくなるのは、建玉後のみです。しかし、売りポジションを決済した後は、買いポジションの数は必然的にゼロに等しくなります。そして、すでに分かっていることを探してループを実行する必要はありません。

次に、最小限の正しさのチェックと買いポジションのオープンです。trueを返した直後、EAの取引環境の内部配列が更新されます。

すべてが簡潔で過不足がありません。もし私がここで何かを見ていなかったら、訂正してください。

 
fxsaber:

エラーは最小距離ではなく、列挙型の入力と呼び出しにある。しかし、計算も間違っている。


私にはわからない。見せてください。

 
Artyom Trishkin:

これがすべてを物語っていると思う:

このEAはトレーニング用であることを認識する価値がある。

サーバーのリターンコードの処理について。個人的には、私は常に処理しています。しかし、テスターでは(トレーニング用エキスパートアドバイザーはテスター用に作られ、さらに独自に修正されることをご理解いただければと思います)、必要なリターンコードをすべて処理する必要はないでしょう。常に自分自身の取引環境を持つことは、実際の取引においても、またテスターにおいてはなおさらです。

よく読んでいないようだ。私はリターンコードなど望んでいない。チケットのCloseSellはそれ自体が悪です。少なくともデモではコードが正しく動作し、明らかな潜在的エラーもないはずなのに、テスターがそれと何の関係があるのでしょうか?

CloseSellの後にRefreshRatesがあるはずです。それがないので、遅延モードを有効にした場合、テスターでもエラーが発生します。SBスタイルのために標準バイブルを使うのは邪道です。コードはそれをよく示している。


SymbolInfo.mqhを 少し変更しただけで、なんとかコンパイルしてMT4で使えるようになった。しかし、MQL4で何かを書くときに、まともな頭脳の持ち主でこのようなことを思いつく人がいるだろうか!MQL5でコーディングするときに、なぜ多くの人が思いつくのだろうか?エラーの可能性が多く、習得に時間がかかるだけでなく、見た目も不格好だ。

 
fxsaber:

よく読んでいないようだ。私はリターンコードなんて欲しくなかった。チケットのCloseSellはそれ自体が悪です。少なくともデモではコードが正しく動作し、明白な潜在的エラーがないはずなのに、テスターは何をしなければならないのでしょうか?

CloseSellの後にRefreshRatesがあるはずです。それがないので、ディレイ・モードを有効にすれば、テスターでも失敗することになる。SBスタイルのために標準バイブルを使うのは邪道です。そして、コードはそれをよく示している。

CloseSell()の後、価格ゼロの買いが始まっている:

      if(open_long)
        {
         if(num_s>0) CloseSell();
         if(num_b==0)
           {
            double sl=(InpStopLoss==0   ? 0 : CorrectStopLoss(ORDER_TYPE_BUY,InpStopLoss));
            double tp=(InpTakeProfit==0 ? 0 : CorrectTakeProfit(ORDER_TYPE_BUY,InpTakeProfit));
            double ll=trade.CheckVolume(symb,lot,symbol_info.Ask(),ORDER_TYPE_BUY);
            if(ll>0 && CheckLotForLimitAccount(POSITION_TYPE_BUY,ll))
              {
               if(trade.Buy(ll,symb,0,sl,tp))
                  FillingListTickets();
              }
           }
        }

なぜRefreshRates()を2回も?CTradeで SBでオープンするコードを見ましたか?私は見ました:

//+------------------------------------------------------------------+
//| 買いオペレーション|
//+------------------------------------------------------------------+
bool CTrade::Buy(const double volume,const string symbol=NULL,double price=0.0,const double sl=0.0,const double tp=0.0,const string comment="")
  {
   CSymbolInfo sym;
//--- ボリュームをチェックする
   if(volume<=0.0)
     {
      m_result.retcode=TRADE_RETCODE_INVALID_VOLUME;
      return(false);
     }
//--- チェック・シンボル
   sym.Name((symbol==NULL)?Symbol():symbol);
//--- 価格を確認する
   if(price==0.0)        
     {                   
      sym.RefreshRates();
      price=sym.Ask();   
     }                   
//---
   return(PositionOpen(sym.Name(),ORDER_TYPE_BUY,volume,price,sl,tp,comment));
  }
//+------------------------------------------------------------------+
 
Artyom Trishkin:

CloseSell()の後、買いはゼロ価格でオープンされる:

なぜRefreshRates()を2回実行するのですか?

正しい関数が呼び出されているからです。

CTradeのオープンコードを見ましたか?

IncludeTrade*.mqh 私はいつも監視している。

 
fxsaber:

そして、その正しい関数が呼び出される。

敵は見た目でわかるはずだから、いつも見てる。

敵 :))))

正しい関数では、価格はSBのm_tick変数から読み込まれ、それは更新中に記入されるのであって、SymbolInfoDouble() から直接読み込まれるわけではありません。さらに、正しい関数の前にはそれほど多くのコードはなく、価格はティックが到着した直後、つまりOnTick()の一番最初に更新されます:

//--- ゼロ価格をチェックする
   if(!RefreshRates()) return;
 
Artyom Trishkin:

敵 :)))))

正しい関数は、SB の m_tick 変数から価格を読み込んでおり、更新時にその変数が埋められますが、SymbolInfoDouble() からは直接読み込まれません。さらに、正しい関数の前にはそれほど多くのコードはなく、価格はティック到着時に直ちに更新されます:

取引、自動取引システム、取引戦略のテストに関するフォーラム。

エキスパートアドバイザー:Diff_TF_MA_EA

fxsaber, 2018.02.01 22:10

SymbolInfo.mqhに ほとんど変更を加えなかったので、コンパイルしてMT4で使用することが判明しました。しかし、MQL4で何かを書くときに、まともな頭でこれを考えられる人はいない!MQL5でコーディングするときに、なぜ多くの人が思いつくのだろうか?エラーの可能性が多く、習得に時間がかかるだけでなく、見た目も不格好だ。

私はMQL4の庭に一石を投じよう。強制RefreshRatesを使ったBid/Askは邪悪だ。しかし、エラーのない簡潔な結果をもたらす素晴らしいマクロがある。
 
fxsaber:
MQL4の庭に石を投げよう。強制RefreshRatesを使ったBid/Askは邪悪だ。しかし、まぎれもなく簡潔な結果を与える素晴らしいマクロ構造があります。

私はあなたがハンプバックホースに鞍替えするのを待っていました。)

このような正しい関数でSymbolInfoDouble()を使えば、必要な価格を得るには十分です。しかし、それは私が同様の関数でやっていることだ。ここでプログラマーは、シンボル・オブジェクトから受け取ったデータを無駄に頼りにした。

 
Artyom Trishkin:

あなたがせむしの馬に鞍をあげるのを待っていたよ :))))))

これらの関数でSymbolInfoDouble()を使えば、必要な価格を得るのに十分だ。しかし、これは私が同じような関数でやっていることだ。ここでプログラマーは、シンボル・オブジェクトから受け取ったデータを無駄に頼りにしている

ここで論理的な疑問が生じる。誰がOOPで最も単純なデータを取得させたのだろうか?MQL4では、彼はいつも何の問題もなくこのデータを受け取っていた。

傴僂馬

取引、自動取引システム、取引戦略のテストに関するフォーラム。

MT4-テスター VS MT5-テスター

fxsaber, 2017.05.08 10:04 AM

このようなバグが発生するのは、比較する機会があるときに必ず起こることです。

バグを示すExpert Advisor

// MQL4&5コード

#property strict

#ifdef __MQL5__
  #define Bid (SymbolInfoDouble(_Symbol, SYMBOL_BID))
  #define Ask (SymbolInfoDouble(_Symbol, SYMBOL_ASK))
#endif // __MQL5__

#define  PRINT(A) Print(#A + " = " + (string)(A));

void OnTick()
{
  static bool FirstRun = true;
  
  static const double PrevBid = Bid;
  static const double PrevAsk = Ask;
  
  if (FirstRun)
  {
    PRINT((PrevBid != Bid) || (PrevAsk != Ask))
    
    FirstRun = false;
  }
}


MT4

2017.05.08 10:57:33.056 2017.04.10 00:00:08  TDS_Test EURUSD,M1: (PrevBid!=Bid)||(PrevAsk!=Ask) = false


MT5

2017.05.08 11:01:31.266 2017.04.10 00:00:08   (PrevBid!=Bid)||(PrevAsk!=Ask) = true
 
コードが更新されました。標準ライブラリを見て みよう