初心者の方からの質問 MQL5 MT5 MetaTrader 5 - ページ 64

 
Leser: No.2ウィンドウに属するMAをEAで指定する方法と場所を教えてください。例えば、MFIにMAを追加し、このMAをEAに登録したいのですが。どこでどうすればいいのかわからない。
詳細を知りたいですか?お使いのExpert AdvisorはすでにMFI指標を使用しており、2番目の指標であるMA指標を使用するようにしたいのですか?または、エキスパートアドバイザーは全く指標を使用しておらず、MA指標を使用する必要があるのですか?
 
Yedelkin:

1.私が言いたいのは、他人のコードを使うときは細心の注意を払ってほしいということです。他人のコードということは、他人のミスもあるということですから。

2.ここ(https://www.mql5.com/ru/forum/6343/page64#comment_357008) では、変数を使う前に正しくゼロにすることを心がけるよう提案しました。しかし、あなたのコードはまだこの提案を実装していません。さらに、あなたのコードには次のようなタイプのコンストラクトが含まれています。

この構成では、リクエスト変数と結果変数が使用される前ではなく、使用された後に ゼロになることはお分かりでしょう。また、これらの局所変数がゼロになると、関数は動作を停止してしまうので、ゼロにすること自体に意味がない。つまり、このような構成は、MqlTradeRequestと MqlTradeResultの 変数がゼロにならない ようにするための良い例です。というわけで、熱心な方は、ぜひ、正しく変数をクリアしてみてください。うまくいかないときは、何が「うまくいかない」のか、具体的に教えてください。

3.標準ライブラリには、「MQL5 Reference / Standard Library / Trade Classes / CTrade」というトレードクラスがあります。実際にどのように適用するかを考えてみてください。語学に没頭する最初の段階では、このクラスで十分かもしれません。例えば、このクラスは次のメソッドを持っています:「MQL5 Reference / Standard Library / Trade Classes / 2CTrade/ PositionModify」。以下のように実装されています。

その中の'ClearStructures();の行で、変数m_requestを使用する前に クリアしています。

イェデルキン

どうもありがとうございました :)

調べてみると、自分の間違いがわかりました。

このように書くことができます。

//+------------------------------------------------------------------+
//| Clear structures request,result and check_result                 |
//+------------------------------------------------------------------+
void ClearStructures()
  {
   MqlTradeRequest request;
   MqlTradeResult result;
   MqlTradeCheckResult check_result;
   ZeroMemory(request);
   ZeroMemory(result);
   ZeroMemory(check_result);
  } 

でも、あなたの提案がよかった。

   MqlTradeRequest request={0};
   MqlTradeResult result={0};
すべて同じ結果です。

今はポジションが見つかっていないので、この仕事を無理してでもやっていこうと思っています。

ありがとうございます。

 

イェデルキン

十分な回答が得られているからこそ、書き込んでいるのです。

MT4とMT5の2台を持っています。

なぜMT5で動かないのか、同じものなのに。

ファイル:
MTB_1E.mq4  4 kb
MTB_E.mq5  9 kb
 
mario065: MT4とMT5がありますが、なぜMT5で動作しないのですか?

残念ながら、私はMT4を全く理解していません。見てみて、何か分かったらお知らせします。

追記一般的には、マーケットオープンを待って、具体的にうまくいくはずだったことがうまくいかなかったことを報告することになります。

 
Yedelkin:

残念ながら、私はMT4を全く理解していません。見てみて、何か分かったらお知らせします。

追記一般的には、マーケットが開くのを待って、うまくいくはずなのにうまくいかなかったことを説明します。

だから、自分のため、必要なら誰のためにもやるんです。

以下はそのコメントです。

2つのヤジカ(MT4とMT5)の修正用pipsボルシェゴの表示がゼロの場合。

if(TradeTrailing>0)

if(MStop > 0)

これらのピップス(ビッド-ピップス)bolsheオープンposishon場合。

if((NormalizeDouble(Bid, Digits)-TradeTrailing)>=OrderOpenPrice())

if(NormalizeDouble(Bid - MStop,4) >= Open)
ストップ=0またはBid - pipsi dal trailing >= Open Posishonから+ pips definitionの場合。
if(OrderStopLoss()==0 || (NormalizeDouble(Bid, Digits)-TradeTrailing)>=(OrderStopLoss()+0.0005))

if(SL == 0 || NormalizeDouble(Bid - MStop,4) >= NormalizeDouble(SL + MStop,4))

を変更することができます。

ОrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(Bid, Digits)-TradeTrailing,OrderTakeProfit(),0,Blue);

ModifyPosition(Symbol(),NormalizeDouble(Bid - MStop,4),TP);

それだけです。

修正用の関数を別に作りたいのですが。

 
Yedelkin:
もう少し具体的に教えてください。お使いのExpert AdvisorはすでにMFI指標を使用しており、2つ目の指標であるMA指標を使用する必要があるのでは?または、エキスパートアドバイザーは全く指標を使用しませんが、MA指標を使用する必要があるのでしょうか?
私のExpert AdvisorはMFIを使用していますが、MAインジケータの書き方がわかりません!主な条件は、MAの設置場所です。MAはチャート上(ウィンドウ1)ではなく、MFIインジケーターのあるウィンドウ(ウィンドウ2)に表示されます。
 
Leser: 私のExpert AdvisorはMFIを使用していますが、MAインジケータの書き方が分かりません!?主な条件は、MAの設置場所です。MAはチャート上(ウィンドウ#1)ではなく、MFIインジケータのあるウィンドウ(ウィンドウ#2)に表示されます。

Expert AdvisorがMFIを使用している場合、そのコードにはこのインジケータの ハンドルを取得する行が含まれている必要があります。そのため、移動平均の扱い方については、「MQL5リファレンス ガイド/テクニカル指標 iMA」にて解説しています。

また、「MQL5でインジケータを 使いこなす」の記事も読んでみてください。

 
mario065: コメント:Bid-STOPS_LEVELが0以上の場合修正:このBid-STOPSがOpen Positionより多い場合:Stop = 0またはBid-STOPSがOpen Positionから≧末尾の場合+Pipsの定義:修正:以上です。改造のための機能を別に作りたい。

1.残念ながら、何が「うまくいかない」のかが明記されていませんね。プログラムのロジック(どう動くか)は述べているが、どこがどう壊れているかは述べていない。問題の詳細な説明がなければ、コードについてのコメントしかできません。

2.bool ModifyPosition(const string symbol,double StopLoss,double Takeprofit) 関数は、このような行を含みます。

   if(!OrderSend(request,result) || result.deal==0)
     {
      Print("Modify error =", GetLastError());
      return(false);
     }

MqlTradeResultの構造体の説明を見ると、取引フィールドは以下のように記述されています。

引合

ディールチケット、ディールが実行された場合。取引操作の際に報告されるTRADE_ACTION_DEAL

ModifyPosition()関数は全く別の処理を行うので、result.dealの値は常に0であるべきです。その結果、演算子
if(!OrderSend(request,result) || result.deal==0)

は、たとえ変更が成功した場合でも常にトリガーされ、同時にエラーメッセージを表示します。

2.前のポイント2からの線を見てください。そこでGetLastError()という関数を使っていますが、これは最後に発生したエラーのコードを返すためのものです。しかし、エラーコードの入った変数をクリアしてから使うことは全くしていないので、たとえ修正が成功しても、位置の修正要求が送信されるずっと前に発生したかもしれないエラーを出力してしまうのです。こんな感じでいいんじゃないでしょうか。

ResetLastError();   
if(!OrderSend(request,result))
   { 
    ... 
    Print("Modify error =", GetLastError());
    ...
   }

3.このセリフを見てください。

          if(SL == 0 || NormalizeDouble(Bid - MStop,4) >= SL) 
           {
            ModifyPosition(Symbol(),NormalizeDouble(Bid - MStop,4),TP);
           }

次のティックでNormalizeDouble(Bid - MStop,4) == SLという条件が発動されたとします。仮にSL==1.11110とする。しかし、その後、ModifyPosition(Symbol(),1.11110,TP)も。すなわち、この修正により、以前に設定されたレベルが指定される。

また、等式NormalizeDouble(Bid - MStop,4) == SLが次のティックで再び動作する場合、何が起こるのでしょうか?)特に、(a)5桁の相場があるかもしれないのに4桁で正規化を行っている、(b)サーバー上で取引要求が多少遅れて実行されることがある、といったことを考慮すれば、なおさらである。

4.また、SYMBOL_TRADE_STOPS_LEVELという文字プロパティも存在する。しかし、あなたのコードでは、このレベルはチェックされていません。つまり、買いポジションの新しいストップロスの候補をSL_newと指定した場合、if(Bid-STOPS_LEVEL>SL_new)という条件を確認すると便利でしょう。

 

実際、リファレンスマニュアルで実数の比較を探してみてください。私の記憶では、次のように2つの実数を比較することを強く勧めています: if(double_1 == double_2).

 

イェデルキン

Reshetovもエラーの場所を教えてくれて、ありがとうございました。

以下、機能そのものを紹介します。

//+------------------------------------------------------------------+
//| Modify position.                                                 |
//+------------------------------------------------------------------+
bool ModifyPosition(const string symbol,double StopLoss,double Takeprofit){
//---- обявяване на структурата и резултата на търговското искане
   MqlTradeRequest request={0};
   MqlTradeResult result={0};
//---- структурна инициализация на  търговското искане MqlTradeRequest за модифициране на  позиция
   request.action       = TRADE_ACTION_SLTP;
   request.symbol       = symbol;
   request.sl           = StopLoss;
   request.tp           = Takeprofit;
   string word          = "";
   StringConcatenate(word,
                     "<<< ============ Modifyposition():   Модифицираме позицията  ",
                     symbol," ============ >>>");
   Print(word);
//---- модифицираме позицията и  проверяваме резултата от търговското искане
   if(!OrderSend(request,result))
     {
      Print("Modify error =", GetLastError());
      return(false);
     }
   return(true);
  }

そして、関数そのものをどうすればよかったかというと、こんな感じです。

  double buy_trail = 0;
  double sel_trail = 0;
  double SL,TP,Open;
  if(PositionSelect(Symbol())){
    if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
      {
      Open = PositionGetDouble(POSITION_PRICE_OPEN);
      SL   = PositionGetDouble(POSITION_SL);
      TP   = PositionGetDouble(POSITION_TP);
      Bid  = SymbolInfoDouble(Symbol(),SYMBOL_BID);
      buy_trail = NormalizeDouble(Bid - Open,Digits());
      if(buy_trail > MStop)
       {
        if(NormalizeDouble((Bid - MStop),Digits()) >= Open && Open > SL)
          {
           ModifyPosition(Symbol(),Open,TP);
          }
          if(NormalizeDouble((Bid - MStop),Digits()) > SL && Open <= SL)
           {
            ModifyPosition(Symbol(),NormalizeDouble((SL + 0.001),Digits()),TP);
           }
        }
      }
    if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
      {
      Open = PositionGetDouble(POSITION_PRICE_OPEN);
      SL   = PositionGetDouble(POSITION_SL);
      TP   = PositionGetDouble(POSITION_TP);
      Ask  = SymbolInfoDouble(Symbol(),SYMBOL_ASK);
      sel_trail = NormalizeDouble(Open - Ask,Digits());
      if(sel_trail > MStop)
       { 
        if(NormalizeDouble((Ask + MStop),Digits()) <= Open && Open < SL)
          {
           ModifyPosition(Symbol(),Open,TP);
          }
          if(NormalizeDouble((Ask + MStop),Digits()) < SL && Open >= SL)
           {
            ModifyPosition(Symbol(),NormalizeDouble((SL - 0.001),Digits()),TP);
           }
        }
      }
     }

現在はすべて正常に動作しています。

ありがとうございます。

理由: