OnTradeTransaction処理

 

こんばんは。

みんな、助けてくれ。この問題はおそらく新しいものではないでしょうが、(実際にもフォーラムにも)解決策は一つも見つかっていません。

ターミナルで2種類のロボットを2種類の計測器で動かしています。魔法はどこでも違うんです。ロボットは保留中の制限を置き、OnTradeTransaction 手続きで取引を検出し、この取引を使用して保留中のストップオーダーを置くことができます。

以下は、貿易取引に関するコードです。

case TRADE_TRANSACTION_DEAL_ADD:
        {
         drop_info2("TRADE_TRANSACTION_DEAL_ADD\r\n"+TransactionDescription(trans));
         if((trans.deal_type==DEAL_TYPE_BUY || trans.deal_type==DEAL_TYPE_SELL) && trans.order!=0)
           {
            if(getIsDealOfExpert(trans.deal)) //функция проверки принадлежности сделки к роботу
              {
               drop_info2("Сделка наша");
               analyzeFilledOrder(trans.order,trans.volume); //процедура по выставлению отложенных стоп ордеров
              }
           }
        }
      break;

これは、取引がロボットに属するかどうかをチェックする関数のコードです。

bool getIsDealOfExpert(ulong dealTicket)
     {
      if(HistoryDealSelect(dealTicket) && HistoryDealGetInteger(dealTicket,DEAL_MAGIC)==magic_number && HistoryDealGetString(dealTicket,DEAL_SYMBOL)==symbol)
         return true;
      else
         return false;
     }

これは、ストップオーダーを保留する手順のコードです。

void analyzeFilledOrder(ulong orderTicket,double volume)
  {
   bool isFindOrder=false;
   string fullComment;
   ENUM_ORDER_TYPE orderType;
   if(getIsOrderOfExpert(orderTicket,true)) //Если ордер из сделки уже в истории
     {
      fullComment=HistoryOrderGetString(orderTicket,ORDER_COMMENT);
      orderType=ENUM_ORDER_TYPE(HistoryOrderGetInteger(orderTicket,ORDER_TYPE));
      isFindOrder=true; //локальная переменная, если нашли в истории
     }
   if(!isFindOrder && getIsOrderOfExpert(orderTicket,false)) //Если не нашли ордер в истории и ордер есть не в истории
     {
      fullComment=OrderGetString(ORDER_COMMENT); 
      orderType=ENUM_ORDER_TYPE(OrderGetInteger(ORDER_TYPE));
      isFindOrder=true; //локальная переменная, если нашли не в истории
     }
   if(isFindOrder) //если хоть где-то нашли, то выставляем отложенные стоп ордера
     {
     //выставляем стоп ордера

以下は、履歴の中の注文と履歴の外の注文を検索する関数のコードです。

bool getIsOrderOfExpert(ulong OrderTicket,bool isHistory)
     {
      bool is_expert=false;
      //если ордер находится в истории
      if(isHistory)
        {
         if(HistoryOrderSelect(OrderTicket) && HistoryOrderGetInteger(OrderTicket,ORDER_MAGIC)==magic_number && HistoryOrderGetString(OrderTicket,ORDER_SYMBOL)==symbol)
            is_expert=true;
        }
      else
        {
         if(OrderSelect(OrderTicket) && OrderGetInteger(ORDER_MAGIC)==magic_number && OrderGetString(ORDER_SYMBOL)==symbol)
            is_expert=true;
        }
      return is_expert;
     }

端末に受信したトランザクションの情報を順番にログファイルに出力していくんだ。さて、デモ口座での取引で直面した問題があります。

トランザクションは、TRADE_TRANSACTION_ORDER_DELETE、TRADE_TRANSACTION_DEAL_ADD、TRADE_TRANSACTION_HISTORY_ADDの順で行われることがあるようです。この場合、ストップ注文は取引が成立した後に発注されないことが多い。これは、注文がすでに削除されているにもかかわらず、まだ履歴に追加されていないために起こるのでしょう。履歴にも端末にも、その取引からの注文が見つからないということです。疑わしいが,ロボットが全次元で注文を検索しても見つからなかった(isFindOrder=false)ため,逆指値注文が出されていないのが実情である。取引の順番は正しいが、注文がどこにもない場合がある。 いずれの場合も、ロボットは取引を正しく検出するが、注文を出すまでには至らない。ただし、正しく動作し、注文が出る場合もある

いろいろな方法を試したが、うまくいかない。今、考えているのは、注文を保留する手順の最初に1秒のインターバルを設けることです。他にどこを掘ればいいのかわからない。

あなたの経験やアイデアをお聞かせください。

 
Илья Ребенок:

こんばんは。

みんな、助けてくれ。この問題はおそらく新しいものではないでしょうが、(実際にもフォーラムにも)解決策は一つも見つかっていません。

ターミナルで2種類のロボットを2種類の計測器で動かしています。魔法はどこでも違うんです。ロボットは保留中の制限を置き、OnTradeTransaction 手続きで取引を検出し、この取引を使用して保留中のストップオーダーを置くことができます。

以下は、貿易取引に関するコードです。

これは、取引がロボットに属するかどうかをチェックする関数のコードです。

これは、ストップオーダーを保留する手順のコードです。

以下は、履歴の中の注文と履歴の外の注文を検索する関数のコードです。

端末に受信したトランザクションの情報を順番にログに出力するんだ。さて、デモ口座での取引で直面した問題があります。

トランザクションは、TRADE_TRANSACTION_ORDER_DELETE、TRADE_TRANSACTION_DEAL_ADD、TRADE_TRANSACTION_HISTORY_ADDの順で行われることがあるようです。この場合、ストップ注文は取引が成立した後に発注されないことが多い。これは、注文がすでに削除されているにもかかわらず、まだ履歴に追加されていないために起こるのでしょう。履歴にも端末にも、その取引からの注文が見つからないということです。疑わしいが,ロボットが全次元で注文を検索しても見つからなかった(isFindOrder=false)ため,逆指値注文が出されていないのが実情である。取引順は正しくても、注文はどこにもない。

様々なアプローチを試みたが、何も解決しなかった。今考えているのは、保留中の注文を出す手順の最初に1秒間のスリープを入れることですが、もしかしたら時間が足りないかもしれません。他にどこを掘ればいいのかもわからない。

あなたの経験やアイデアをお聞かせください。

すべてのコードに目を通すことは始めていません。このやり方は全く正しくないと思います。

TRADE_TRANSACTION_DEAL_ADDの時点で、trans.positionを選択し、そのマジックをチェックする必要があります。

if(PositionSelectByTicket(trans.position) && PositionGetInteger(POSITION_MAGIC) == mag)

また、trans.symbol == _Symbolをチェックし、その結果に基づいて判断することも可能です。

 
Alexey Viktorov:

すべてのコードを調べたわけではありません。私見では、このやり方はまったく正しくない。

TRADE_TRANSACTION_DEAL_ADD 取引の種類を選択した時点で trans.position を選択し、そのマジックを確認する必要があります。

また、trans.symbol == _Symbolをチェックし、その結果に基づいて判断することも可能です。

モードがネットであることを付け加えるのを忘れていました。位置はどのロボットも同じです。つまり、あるロボットがポジションを買い、2番目のロボットがそれを買い、TRADE_TRANSACTION_DEAL_ADDイベントが逆順にやってきて、最初のロボットは結果的にそれを見なかったということです。

そして、論理的にはトレードから注文コメントを取得する必要があり、ポジションはあまり役に立ちません。
 
Илья Ребенок:

あなたの経験やアイデアをお聞かせください。

ある状況

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

バグ、バグ、質問

fxsaber さん 2018.06.20 23:18

システムに注文があるにもかかわらず、ターミナルに注文がない場合、このような幻の注文がどのくらい続くのかを確認することにしました。

// Советник отслеживает длительность ситуаций, когда ордер отсутствует среди текущих и исторических

#define  TOSTRING(A)  #A + " = " + (string)(A) + "\n"
#define  TOSTRING2(A) #A + " = " + EnumToString(A) + " (" + (string)(A) + ")\n"

bool OrderIsExist( const ulong &OrderTicket )
{
  return(OrderTicket ? OrderSelect(OrderTicket) || HistoryOrderSelect(OrderTicket) : true);
}

void OnTradeTransaction ( const MqlTradeTransaction &Trans, const MqlTradeRequest&, const MqlTradeResult& )
{
  static bool PrevIsExist = true;
  static ulong StartTime = 0;
  static ulong MaxInterval = 0;
  
  const ulong NowTime = GetMicrosecondCount();
  const bool IsExist = OrderIsExist(Trans.order);
    
  if (!IsExist)
  {
    Print(TOSTRING2(Trans.type) + TOSTRING(Trans.order) +
          TOSTRING(OrderSelect(Trans.order)) + TOSTRING(HistoryOrderSelect(Trans.order)));       
  
    if (PrevIsExist) 
      StartTime = NowTime;
  }
  else if (!PrevIsExist)
  {
    const ulong Interval = NowTime - StartTime;
    
    Print(TOSTRING(Interval) + TOSTRING2(Trans.type) + TOSTRING(Trans.order) +
          TOSTRING(OrderSelect(Trans.order)) + TOSTRING(HistoryOrderSelect(Trans.order)));       
    
    if (Interval > MaxInterval)
    {
      MaxInterval = Interval;
      
      Comment(TOSTRING(MaxInterval) + TOSTRING(Trans.order)); // mcs.
    }
  }
          
  PrevIsExist = IsExist;
}


結果

2018.06.21 00:10:31.047 Trans.type = TRADE_TRANSACTION_ORDER_DELETE (2)
2018.06.21 00:10:31.047 Trans.order = 2210967406
2018.06.21 00:10:31.047 OrderSelect(Trans.order) = false
2018.06.21 00:10:31.047 HistoryOrderSelect(Trans.order) = false
2018.06.21 00:10:31.047 
2018.06.21 00:10:31.080 Interval = 32643
2018.06.21 00:10:31.080 Trans.type = TRADE_TRANSACTION_HISTORY_ADD (3)
2018.06.21 00:10:31.080 Trans.order = 2210967406
2018.06.21 00:10:31.080 OrderSelect(Trans.order) = false
2018.06.21 00:10:31.080 HistoryOrderSelect(Trans.order) = true


32ミリ秒、注文はあるがターミナルにない!もし、この間に売買ロジックが実行されたらどうなるか、想像してみてください.


興味深いことに、ファントム注文はTRADE_TRANSACTION_ORDER_DELETEと TRADE_TRANSACTION_DEAL_ADD(かなり稀)の取引タイプにのみ 存在することが多い。


非常に悪いプラットフォームのニュアンス。


ZZY 5の貿易取引のスピードに疑問がある、残念。


第2回

ポジションを開始 し、OrdersTotalが1つ増加しました。

  • 実行され、OrdersTotalは1つ減少したが、PositionsTotalは1つ増加 しなかった。つまり、位置はあるのだが、端末がそれを知らないのである。
  • 例えば、ポジションや注文がない場合、PositionsTotal = 0、OrdersTotal = 0となります。

    成行注文を設定します。PositionTotal = 0, OrdersTotal = 1.

    成行注文が執行される - OrdersTotal = 0.しかし、PositionsTotal = 0!

     
    Илья Ребенок:

    モードがネットであることを付け加えるのを忘れていました。位置はどのロボットも同じです。

    どうでもいいことです。ポジションは常にチケットを持っていますが、シンボルで選択することも可能です。取引量の チェックなどを追加する必要があるかもしれません。例えば、あるポジションのオーダーやディールを選択し、それらを振って探す。しかし、取引は取引だ...。また、トランザクションの整合性は誰も保証してくれません。少し前までは、取引ができなくなる可能性があるという警告があったくらいです。


    あなたの投稿の追記を考えると、すべて間違っています。その場合は、もっと慎重に調べる必要があります。

     
    Илья Ребенок:

    いろいろな方法を試してみたが、うまくいかない。

    実行すべき簡単なアクションを書く。

     
    fxsaber:

    ある状況


    第2回

    ありがとうございます!読んでみますが、一見すると私の思い込みを裏付けていますね。

    アレクセイ・ヴィクトロフ

    そんなことはどうでもいいんです。ポジションには必ずチケットがありますが、記号で選択することもできます。トランザクション量の チェックなどを追加する必要があるかもしれません。例えば、あるポジションのオーダーやディールを選択し、それらを振って探す。しかし、取引は取引だ...。また、トランザクションの整合性は誰も保証してくれません。少し前に、トランザクションが失われる可能性があるという警告がありました。


    投稿の追記を考えると、全部は収まりませんね。その場合は、もっと慎重に調べる必要があります。

    トランザクションロスの投稿を見たが、そこのモデレーターが過去の遺物だと言って、ドキュメントから削除し忘れていた。

    fxsaber

    実行する簡単なアクションを書きます。

    簡単なアクションを書くことがよくわからないのですが)説明してください。

     
    Илья Ребенок:


    トランザクションを失うという書き込みを見たが、そこのモデレーターは過去の遺物だと言って、ドキュメントから削除するのを忘れていた。

    そうなんですが、そんなに昔の話じゃないんです。

     
    Илья Ребенок:

    簡単なアクションの書き方がよくわからないのですが)説明してください。

    貿易の目的は何ですか?

     
    fxsaber:

    トレードの目的は何ですか?

    指値注文を出し、それが発動したときにストップオーダーと テイクプロフィットオーダーを出すのです。ストップオーダーがトリガーされると、テイクプロフィットを削除し、その逆も同様です。ストップオーダーとテイクプロフィットのコメントには、それを元に設定した初回リミットチケットが書かれています。そのため、注文コメントを取得しておくと、ストップ注文が発動したときに、同じコメントのテイクプロフィットを見つけて削除することができるのです。

    このロボットはポジションをリフィルすることができるので、ストップオーダーとテイクプロフィットも発注し、リフィルチケットのエントリーをコメントに残しておく必要があります。

    1秒睡眠は可能か?全取引の時間を確保するためTRADE_TRANSACTION_ORDER_DELETEとTRADE_TRANSACTION_HISTORY_ADD

    Общие принципы - Торговые операции - MetaTrader 5
    Общие принципы - Торговые операции - MetaTrader 5
    • www.metatrader5.com
    Перед тем как приступить к изучению торговых функций платформы, необходимо создать четкое представление об основных терминах: ордер, сделка и позиция. — это распоряжение брокерской компании купить или продать финансовый инструмент. Различают два основных типа ордеров: рыночный и отложенный. Помимо них существуют специальные ордера Тейк Профит...
     

    Илья Ребенок:

    このロボットでは、スキャルインが可能なので、買い増しするときは、ストップオーダーとテイクプロフィットも入れて、スキャルインをチケットに記録しておきます。

    テイクとストップの注文を同時に2つまで出すことはできますか?

    理由: