エラー、バグ、質問 - ページ 540

 

現在チャンピオンシップに参加している私のExpert Advisorは、CTrade標準ライブラリの不正な動作により、誤った動作を行っています。

ポジションを閉じるにはPositionClose関数を使っています。しかし、この機能はポジションを閉じるだけでなく、それ自体が取引を開始します。

この機能はこのように使用します。

//--- Объект класса СTrade
CTrade mytrade;
//--- Объект класса СPositionInfo
CPositionInfo myposition;

//+------------------------------------------------------------------+
//| Проверяет и если нужно, закрывает открытую позицию               |
//+------------------------------------------------------------------+
bool ClosePosition(string ptype,double clp)
  {
   bool R=false, marker=false; int i;
     
      if(myposition.Select(_Symbol)==true)
        {
         if(myposition.Symbol()==_Symbol)
           {
            //--- Делаем попытки закрыть позицию, если позиция не закрылась с первого раза
              for (i=5; i>=1; i--) 
                {R=mytrade.PositionClose(_Symbol,50,5); if (R == true && myposition.Select(_Symbol)==false) break;}
               if(i >= 1) 
                 {//--- запрос успешно выполнен
                  Alert("Открытая позиция была успешно закрыта!!");
                  marker=true;
                 }
               else
                 {
                  Alert("Запрос на закрытие позиции не выполнен - ошибка: ",mytrade.ResultRetcodeDescription());
                 }
            //  }
           }
        }
      return(marker);
     }

PositionCloseは、不必要な注文を出すことがある。

ここでは、まず買いの取引が決済され、その後、同じサイズの売りの取引が追加で開設されました。さらに、AccountInfoDouble(ACCOUNT_FREEMARGIN)はこの余分な取引に気づいていない。中古MMでは資金が足りなかったが、より大きなロットでのトレードが続いたからだ。

もしかしたら、MQLの関数を最適に使えていないのかもしれないと実感しています。しかし、MQL独自のライブラリにある、取引の決済を 目的とした関数が、勝手に取引を開始して しまうというのは、私の考える関数の許容動作にそぐわないのではと思います。

 
masharov:

MQLの関数を最適に使えていない可能性があることは理解しています。しかし、取引の決済を 目的としたMQL独自のライブラリ関数が、それ自体で取引を開始 するというのは、私の考える許容範囲の関数の動作にそぐわないのです。

記事を読むMetaTrader 5でイベントを取引 する。

トレードイベントや取引履歴の変化については、独立したルートで報告されます。OrderSend()関数でBuyリクエストを送信すると、リクエストが正常にチェックされた場合に作成された注文のチケットをすぐに認識することができます。しかし同時に、注文自体はまだクライアント端末に表示されていない可能性があり、OrderSelect() 関数で選択しようとすると失敗します。

MetaTrader 5のOrders, Positions and Tradesの 記事もご覧ください。
 
Rosh:

記事を読むMetaTrader 5でイベントを取引 する。

MetaTrader 5のOrders, Positions and Tradesの 記事もご覧ください。

OrderSend機能は使ったことがない。標準的なMQLライブラリの関数PositionCloseを 使用しており、これは注文で動作するように設計されています。

この機能のヘルプには、取引開始ができることは記述されていません。

参考文献より引用

ポジションクローズ

指定されたシンボルのポジションをクローズします。

bool PositionClose()
const string symbol, // symbol
ulong deviation=ULONG_MAX // 偏差
)

パラメータ

記号

[ポジションを決済すべき取引商品名。

deviation=ULONG_MAX

[in] 現在の価格からの最大偏差(単位:ポイント)。

戻り値

true - 構造体の基本チェックが成功した場合,それ以外はfalse.

備考

PositionClose(...)メソッドの正常終了は、必ずしも取引操作の正常終了を意味するものではありません。ResultRetcode()メソッドを呼び出して、取引要求の結果(取引サーバーのリターンコード)を確認する必要があります。

 
masharov:

OrderSend機能は使ったことがありません。標準MQLライブラリのPositionClose 関数が使用されており、注文での作業を簡略化するように設計されています。

この機能のヘルプには、取引開始ができることは記述されていません。

参考文献より引用

ポジションクローズ

指定されたシンボルのポジションをクローズします。

bool PositionClose()
const string symbol, // symbol
ulong deviation=ULONG_MAX // 偏差
)

パラメータ

記号

[ポジションを決済すべき取引商品名。

deviation=ULONG_MAX

[in] 現在の価格からの最大偏差(単位:ポイント)。

戻り値

true - 構造体の基本チェックが成功した場合,それ以外はfalse.

備考

PositionClose(...)メソッドの正常終了は、必ずしも取引操作の正常終了を意味するものではありません。取引要求の実行結果(取引サーバのリターンコード)は、ResultRetcode()メソッドを呼び出して確認する必要があります。

ライブラリ関数PositionClose(...)にエラーはありません。しかし、あなたのコードには1つあります。以下、参考までに引用します。

Успешное окончание работы метода PositionClose(...) не всегда означает успешное совершение торговой операции. 
Необходимо проверять результат выполнения торгового запроса (код возврата торгового сервера) вызовом метода ResultRetcode(). 

例えば私は、あなたのコードにこのチェックがないことを確認しています。

 
masharov:

OrderSend機能は使ったことがありません。注文を扱うための標準 MQLライブラリの PositionClose 関数が使用されています。

この機能のヘルプには、取引開始ができることは記述されていません。


そして、PositionClose関数の実装を見ることができます。

bool CTrade::PositionClose(const string symbol,ulong deviation)
  {
   bool   partial_close=false;
   int    retry_count  =10;
   uint   retcode      =TRADE_RETCODE_REJECT;
//--- check stopped
   if(IsStopped(__FUNCTION__)) return(false);
//--- variables
   string action,result;
//--- clean
   ClearStructures();
   do
     {
      //--- checking
      if(PositionSelect(symbol))
        {
         if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
           {
            //--- prepare request for close BUY position
            m_request.type =ORDER_TYPE_SELL;
            m_request.price=SymbolInfoDouble(symbol,SYMBOL_BID);
           }
         else
           {
            //--- prepare request for close SELL position
            m_request.type =ORDER_TYPE_BUY;
            m_request.price=SymbolInfoDouble(symbol,SYMBOL_ASK);
           }
        }
      else
        {
         //--- position not found
         m_result.retcode=retcode;
         return(false);
        }
      //--- setting request
      m_request.action      =TRADE_ACTION_DEAL;
      m_request.symbol      =symbol;
      m_request.deviation   =(deviation==ULONG_MAX) ? m_deviation : deviation;
      m_request.type_filling=m_type_filling;
      m_request.volume      =PositionGetDouble(POSITION_VOLUME);
      //--- check volume
      double max_volume=SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX);
      if(m_request.volume>max_volume)
        {
         m_request.volume=max_volume;
         partial_close=true;
        }
      else
         partial_close=false;
      //--- order check
      if(!OrderCheck(m_request,m_check_result))
        {
         //--- copy return code
         m_result.retcode=m_check_result.retcode;
         if(m_log_level>LOG_LEVEL_NO)
            printf(__FUNCTION__+": %s [%s]",FormatRequest(action,m_request),FormatRequestResult(result,m_request,m_result));
         return(false);
        }
      //--- order send
      if(!OrderSend(m_request,m_result))
        {
         if(--retry_count!=0) continue;
         if(retcode==TRADE_RETCODE_DONE_PARTIAL)
            m_result.retcode=retcode;
         if(m_log_level>LOG_LEVEL_NO)
            printf(__FUNCTION__+": %s [%s]",FormatRequest(action,m_request),FormatRequestResult(result,m_request,m_result));
         return(false);
        }
      retcode=TRADE_RETCODE_DONE_PARTIAL;
      if(partial_close) Sleep(1000);
     }
   while(partial_close);
   if(m_log_level>LOG_LEVEL_ERRORS)
      printf(__FUNCTION__+": %s [%s]",FormatRequest(action,m_request),FormatRequestResult(result,m_request,m_result));
//--- ok
   return(true);
  }
 

標準ライブラリの ソースコードを勉強する必要はないと思ったからです。

ヘルプには、PositionClose 関数で取引を開始できることについては記載されていません。あなたのチームが開発したPositionClose関数で取引を開始することに対するチェックとプロテクションは、それ自体を含んでいるはずです。標準ライブラリは、他の模範となるべき理想的なコードであると思います。したがって、ライブラリのコードを解析してから使用することは必要ないはずです。

引用元

MQL5標準ライブラリは、MQL5言語で書かれており、エンドユーザーがプログラム(インジケーター、スクリプト、エキスパート)を書きやすいように設計されています。このライブラリは、ほとんどのMQL5内部関数に簡単にアクセス することができます。

 
masharov:

標準ライブラリの ソースコードを勉強する必要はないと思ったからです。

ヘルプには、PositionClose 関数で取引を開始できることについては記載されていません。あなたのチームが開発したPositionClose関数で取引を開始することに対するチェックとプロテクションは、それ自体を含んでいるはずです。標準ライブラリは、他の模範となるべき理想的なコードであると思います。したがって、ライブラリを使用する前に、ライブラリのコードを解析することは必要ないはずです。

法律を知らないからといって、責任が免除されるわけではありません。ポジションがクローズしたことを確認するコードはどこにあるのでしょうか?

            //--- Делаем попытки закрыть позицию, если позиция не закрылась с первого раза
              for (i=5; i>=1; i--) 
                {
                 R=mytrade.PositionClose(_Symbol,50,5); 
                 if (R == true && myposition.Select(_Symbol)==false) break;
                }

表現方法

R == true

は、PositionClose() 関数が正常に実行されたことを示すだけで、ポジションがクローズされたことを示すわけではありません。

備考

PositionClose(...)メソッドの正常終了は、必ずしも取引操作の正常終了を意味するものではありません。ResultRetcode() メソッドを呼び出すことで、取引要求の実行結果(取引サーバーのリターンコード)を確認する必要があります。

2番目の式

myposition.Select(_Symbol)==false)

と同じです。

PositionSelect(_Symbol)==false)

であり、非同期取引操作に対する保証もない。取引サーバー上で既にポジションがクローズされ、端末がそのメッセージを受信していない状態。つまり、あなたのコードにバグが発生していることが判明したわけです。

実際の取引では、テスターのようにすべてがスムーズにいくわけではなく、取引依頼を送信してからその実行結果が出るまでに多少の遅れが生じることがあります。この問題は皆さん自分で解決していますが、まずは ヘルプに書いて ある ようにResultRetcode() 関数を使ってリターンコードを確認するのは問題ないでしょう。

 

もう一度。

もしかしたら、MQLの関数を最適に使えていないのかもしれないと実感しています。しかし、取引の決済を 目的としたMQL独自のライブラリの関数が、取引そのものを開いて しまうというのは、私の考える関数の許容動作にそぐわないのです。

あなたの言うことはすべて、取引を終了するときに当てはまります。はい、EAは最適にクローズポジションを チェックしません。しかし、それでは、クローズすることを目的とした機能が、自らトレードを開始することはできません。

ヘルプにはこう書いてある。

ポジションクローズ

指定されたシンボルに従ってポジションをクローズします。

本機能が取引を開始できる条件は記述されていない。リターンコードのチェックの推奨も、取引が終了しているかどうかを追加でチェックするためだけのものです。

 
masharov:

もう一度。

MQLの関数を最適に使えていない可能性があることは理解しています。しかし、取引の決済を 目的としたMQL独自のライブラリの関数が、それだけで取引を開始して しまうというのは、私の考える関数の許容動作にそぐわないのです。
ポジションを閉じる 機能はなく、売買のリクエストを送る機能だけがあります(その結果、ポジションが開くか閉じるかは不明です)。あなたの場合、アルゴリズムのエラーにより、前のリクエストが実行されたかどうかを確認せずに、繰り返しリクエストが送信されています。
 
Rosh:
ポジションクローズ 機能はなく、売買リクエストを送る機能のみです(その結果であるポジションの開始または終了は不明です)。あなたの場合、アルゴリズムのエラーにより、前のリクエストが実行されたかどうかを確認せずに、繰り返しリクエストが送信されています。

ヘルプにはこのような機能があります。

MQL5 リファレンス / 標準ライブラリ / トレーディングクラス / CTrade / PositionClose

指定されたシンボルでポジションを閉じる。

ユーザーは、その機能が低レベルでどのように実装されているかを気にする必要はありません。この機能がある以上、MetaQuotesはヘルプに記載されていない非標準的な動作はしないことを保証しています。

MQL5標準ライブラリは、MQL5で書かれており、エンドユーザーによるプログラム(インジケーター、スクリプト、Expert Advisor)の作成を容易にすることを目的としています。このライブラリは、MQL5の内部関数のほとんどに簡単にアクセス することができます。