web-dev-qa-db-ja.com

別の取引が開いているときに取引をキャンセルし、所定の期間、取引を維持するにはどうすればよいですか?

以下のコードを書いて、買いと売りのトレード(売り気配値の上下にある一定数のピップ)を特定の時間に開始します。

  1. もう一方を開いたらすぐに閉じる/キャンセルするにはどうすればよいですか?

  2. 利益がXピップスである、または1分後に(最初に到達した条件に応じて)と表示されている場合、どのようにしてオープンしたトレードを閉じることができますか?

私は以下のコードで正しいことをしたかどうか確信が持てません。

double spread = Ask-Bid;
extern datetime time;
extern int pipGap = 7;
extern int lotSize = 0.01;
extern int closeTimeInSeconds = 60;


int start() {
  if (TimeCurrent() >= StrToTime(time)){

    OrderSend(Symbol(),OP_BUYSTOP,lotSize, Ask + Point*pipGap, 0,0,0);
    OrderSend(Symbol(),OP_SELLSTOP,lotSize, Bid - Point*pipGap, 0,0,0);


    }


for(int pos = OrdersTotal()-1; pos >= 0 ; pos--) if (
    OrderSelect(pos, SELECT_BY_POS)           
){              
    int duration = TimeCurrent() - OrderOpenTime();
    if (duration >= closeTimeInSeconds)
         OrderClose( OrderTicket(), OrderLots(), OrderClosePrice(),
                     3*Point);
}

   return(0);
}
15
NotEveryDay
#property strict
//---
input datetime          InpTime1=D'2019.05.01 00:00';       //time to enter the trade, just as an example
input double            InpPipsDist=10;                     //distance in pips to place BS&SS OCO-orders
input int               InpCloseSeconds=60;                 //close time, seconds since main order is sent
input double            InpProfitPips=1.;                   //profit in pips to close all.
input double            InpLotSize=0.1;                     //lot size
input int               InpMagicNumber=123456789;           //magic number
// ---

#include <Arrays\ArrayObj.mqh>
bool firstOrderOpen;
double PIP;
CArrayObj *ordersList;
// ---

class C2Orders : public CObject
  {
private:
   int                  m_ticket1;
   int                  m_ticket2;
   datetime             m_timeStart;//OrderOpenTime of the two tickets might be different,TimeCurrent() is used as time they are open.
   bool                 m_activated;

   void              checkTicket(const int ticket)  //if one order is open, another is deleted.
      {
        if(ticket>0 && OrderSelect(ticket,SELECT_BY_TICKET))
          {
            if(OrderType()<=OP_SELL)
              {
                if(ticket==m_ticket1)
                  {
                   if(OrderDelete(m_ticket2))
                      printf("%i: failed to delete#%d. error=%d",__LINE__,m_ticket2,_LastError);
                    m_ticket2=-1;
                  }
                else
                  {
                    if(!OrderDelete(m_ticket1))
                       printf("%i: failed to delete#%d. error=%d",__LINE__,m_ticket1,_LastError);
                    m_ticket1=-1;
                  }
                m_activated=true;
              }
          }
     }
   double            getPnlPips(const int ticket)const
     {
       if(ticket>0 && OrderSelect(ticket,SELECT_BY_TICKET))
         {
          return (OrderProfit()>0 ? 1 : -1)*fabs(OrderOpenPrice()-OrderClosePrice());
         }
       return 0;
     }
   bool              try2closeByPnl()const
     {
        const double pnl=getPnlPips(m_ticket1)+getPnlPips(m_ticket2);
        if(pnl-InpProfitPips*PIP>0)
          {
            printf("%i : pnl=%.5f vs %.5f target. closing the tickets",__LINE__,pnl,InpProfitPips*PIP);
            close(m_ticket1);
            close(m_ticket2);
            return(true);
          }
        return(false);
     }
   bool              try2closeByTime()const
     {
        if(TimeCurrent()-m_timeStart-InpCloseSeconds>=0)
          {
            if(!OrderDelete(m_ticket1))printf("%i: failed to delete#%d. error=%d",__LINE__,m_ticket1,_LastError);
            if(!OrderDelete(m_ticket2))printf("%i: failed to delete#%d. error=%d",__LINE__,m_ticket2,_LastError);
            return(true);
          }
        return(false);
     }
   void              close(const int ticket)const
     {
        if(ticket>0 && OrderSelect(ticket,SELECT_BY_TICKET))
          {
            RefreshRates();
            if(OrderClose(ticket,OrderLots(),OrderClosePrice(),1))
               printf("%i: failed to close#%d. error=%d",__LINE__,ticket,_LastError);
          }
      }
public:
   C2Orders(const int ticket1,const int ticket2,const datetime time):
    m_ticket1(ticket1),m_ticket2(ticket2),m_activated(false),m_timeStart(time){}
  ~C2Orders(){}

   bool              check()    //returns FALSE if deleting the object
     {
        if(!m_activated)
          {
            checkTicket(m_ticket1);
            checkTicket(m_ticket2);
          }
        if(m_activated)
          {
            if(try2closeByPnl())
                return(false);
          }
        else
          {
            if(try2closeByTime())
                return(false);
          }
        return true;
     }

  };
//+------------------------------------------------------------------+
int OnInit()
    {
        firstOrderOpen=false;
        PIP=_Point*(_Digits%2==1 ? 10 : 1); //does not work for GOLD and indexes, good for FX.
        ordersList=new CArrayObj();

        return(INIT_SUCCEEDED);
    }
void OnDeinit(const int reason)
    {
        delete(ordersList);
    }
void OnTick()
    {
        if(!firstOrderOpen && TimeCurrent()>=InpTime1)
        {
            RefreshRates();
            const int ticketBS=OrderSend(_Symbol,OP_BUYSTOP,InpLotSize,NormalizeDouble(Ask+InpPipsDist*PIP,_Digits),0,0,0,NULL,InpMagicNumber);
            const int ticketSS=OrderSend(_Symbol,OP_SELLSTOP,InpLotSize,NormalizeDouble(Bid-InpPipsDist*PIP,_Digits),0,0,0,NULL,InpMagicNumber);
            C2Orders *oco=new C2Orders(ticketBS,ticketSS,TimeCurrent());
            ordersList.Add(oco);
            firstOrderOpen=true;
        }
        if(firstOrderOpen)
        {
            C2Orders* oco;
            for(int i=ordersList.Total()-1;i>=0;i--)//of course you have only one instance, but in real world you may need to loop over them.
            {
                oco=ordersList.At(i);
                if(!oco.check())
                    ordersList.Delete(i);
            }

            if(ordersList.Total()==0)
                ExpertRemove();//just to finish the test faster.
        }
    }
0
Daniel Kniaz