【问题标题】:How to open a Buy when a Buy-order hits a T/P, Sell if a Buy-order hits a S/L; a Sell if Sell-order hits a T/P and open Buy if Sell reaches S/L?如何在买单触及 T/P 时建立买入,在买入指令触及 S/L 时卖出; a 如果卖出订单达到 T/P 则卖出,如果卖出达到 S/L 则打开买入?
【发布时间】:2016-05-15 20:05:36
【问题描述】:

我尝试了很多方法,但无法使用下面的代码。

我尝试了以下代码逻辑的变体,但失败了,不知道在哪里实现它:

if (  OrderSelect( OrdersHistoryTotal() - 1, SELECT_BY_POS, MODE_HISTORY ) )
{
      if (  OrderType() == OP_BUY )
      {
            if (  OrderClosePrice() >  OrderStopLoss() )      Print( "Hit TP" );
            else                                              Print( "Hit SL" );
      }
      else if (  OrderType() == OP_SELL )
           {
                 if (  OrderClosePrice() <  OrderStopLoss() ) Print( "Hit TP" );
                 else                                         Print( "Hit SL" );
           }
}  

或

Orderselect...

if (  MathAbs( OrderClosePrice()
             - OrderTakeProfit()
               ) > MathAbs( OrderClosePrice()
                          - OrderStopLoss()
                            )
      ) Print( "StopLoss" );

if (  MathAbs( OrderClosePrice()
             - OrderTakeProfit()
               ) < MathAbs( OrderClosePrice()
                          - OrderStopLoss()
                            )
      ) Print( "TakeProfit" );

OrderSelect() 对我来说一直是个问题,因此我们将不胜感激。

下面是我尝试添加它的 EA,但只要知道如何以及在哪里放置它就会有所帮助。

extern int      MagicNumber     = 10001;
extern double   Lots            =     0.01;
extern double   StopLoss        =     1;
extern double   TakeProfit      =     1;
extern int      TrailingStop    =     0;
extern int      Slippage        =     3;
//+------------------------------------------------------------------+
//    expert start function
//+------------------------------------------------------------------+
int start() // New-MQL4.56789 #strict uses another constructor:         int OnTick(){...}
{
  double MyPoint = Point;
  if (  Digits == 3
     || Digits == 5
     )  MyPoint = Point*10;

  double TheStopLoss    = 0;
  double TheTakeProfit  = 0;

  if ( TotalOrdersCount() == 0 )
  {
     int result = 0;
     if (  ( iMA( NULL, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 1 ) <  iMA( NULL, 0, 200, 0, MODE_SMA, PRICE_CLOSE, 1 ) )
        && ( iMA( NULL, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 0 ) >  iMA( NULL, 0, 200, 0, MODE_SMA, PRICE_CLOSE, 0 ) )
        ) // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Here is your open BUY rule
     {
        result = OrderSend( Symbol(),
                            OP_BUY,
                            Lots,
                            Ask,
                            Slippage,
                            0,
                            0,
                            "Buy",
                            MagicNumber,
                            0,
                            Blue
                            );
        if (  result >  0 )
        {
              TheStopLoss   = 0;
              TheTakeProfit = 0;

              if (  TakeProfit >  0 ) TheTakeProfit = Ask + TakeProfit * MyPoint;
              if (  StopLoss   >  0 ) TheStopLoss   = Ask - StopLoss   * MyPoint;

              OrderSelect( result, SELECT_BY_TICKET );
              OrderModify( OrderTicket(),
                           OrderOpenPrice(),
                           NormalizeDouble( TheStopLoss,   Digits ),
                           NormalizeDouble( TheTakeProfit, Digits ),
                           0,
                           Green
                           );
        }
        return(0);
     }
     if (  ( iMA( NULL, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 1 ) >  iMA( NULL, 0, 200, 0, MODE_SMA, PRICE_CLOSE, 1 ) )
        && ( iMA( NULL, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 0 ) <  iMA( NULL, 0, 200, 0, MODE_SMA, PRICE_CLOSE, 0 ) )
        ) // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Here is your open SELL rule
     {
        result = OrderSend( Symbol(),
                            OP_SELL,
                            Lots,
                            Bid,
                            Slippage,
                            0,
                            0,
                            "Sell",
                            MagicNumber,
                            0,
                            Red
                            );
        if (  result >  0 )
        {     
              TheStopLoss   = 0;
              TheTakeProfit = 0;

              if (  TakeProfit >  0 ) TheTakeProfit = Bid - TakeProfit * MyPoint;
              if (  StopLoss   >  0 ) TheStopLoss   = Bid + StopLoss   * MyPoint;

              OrderSelect( result, SELECT_BY_TICKET );
              OrderModify( OrderTicket(),
                           OrderOpenPrice(),
                           NormalizeDouble( TheStopLoss,   Digits ),
                           NormalizeDouble( TheTakeProfit, Digits ),
                           0,
                           Green
                           );
        }
        return(0);
     }
  }

  for ( int cnt = 0; cnt <  OrdersTotal(); cnt++ )
  {     
        OrderSelect( cnt, SELECT_BY_POS, MODE_TRADES );

        if (  OrderType()        <= OP_SELL
           && OrderSymbol()      == Symbol()
           && OrderMagicNumber() == MagicNumber
           )  
        {     
              if (  OrderType() == OP_BUY )
              {     
                    if (  TrailingStop >  0 )
                    {     
                          if (  Bid - OrderOpenPrice() >  MyPoint * TrailingStop )
                          {     
                                if (  OrderStopLoss()  <  Bid - MyPoint * TrailingStop )
                                {     
                                      OrderModify( OrderTicket(),
                                                   OrderOpenPrice(),
                                                   Bid - TrailingStop * MyPoint,
                                                   OrderTakeProfit(),
                                                   0,
                                                   Green
                                                   );
                                      return(0);
                                }
                          }
                    }
              }
              else 
              {     
                    if (  TrailingStop >  0 )
                    {     
                          if (  ( OrderOpenPrice() - Ask ) >  ( MyPoint * TrailingStop ) )
                          {     
                                if (  ( OrderStopLoss() >  ( Ask + MyPoint * TrailingStop ) )
                                   || ( OrderStopLoss() == 0 )
                                   )
                                {     
                                      OrderModify( OrderTicket(),
                                                   OrderOpenPrice(),
                                                   Ask + MyPoint * TrailingStop,
                                                   OrderTakeProfit(),
                                                   0,
                                                   Red
                                                   );
                                      return(0);
                                }
                          }
                    }
              }
        }
  }
  return(0);
}

int    TotalOrdersCount()
{      
       int result = 0;
       for (  int i = 0; i <  OrdersTotal(); i++ )
       {
           OrderSelect( i, SELECT_BY_POS, MODE_TRADES );

           if (  OrderMagicNumber() == MagicNumber ) result++;

       }
       return( result );
}

【问题讨论】:

    标签: algorithmic-trading mql4 metatrader4 mt4


    【解决方案1】:

    ... open WHEN ... 是目标的关键部分

    OrderSelect() 对您解决 “何时打开” 难题没有多大帮助。它只是爬过 db.POOL 的记录,由 MetaTrader Terminal 4 localhost 内部 DBMS 负责处理,这是处理订单事件的缓慢且非常低效的方式-管理任务,因此尽量避免在生产级系统中对其进行任意扫描。在这里,您甚至不会从如此毁灭性的db.POOL 扫描中获得您的任务所需的任何基本信息,所以让我们首先关注目标。


    ...什么...目标背后的想法是什么?

    EA 是慢 200 / 快 30 简单移动平均线交叉的学术上微不足道的变化。

    我想您想补充一下您的额外想法,即在基础 SMA 交叉发起的交易分别达到{ SL | TP }-termination 的情况下开设额外交易,对吧?

    对于这种情况,具有 MetaTrader Server 4 的经纪商通常允许您下一个所谓的挂单,指示经纪商维护您的意愿记录进入市场,假设价格达到预定义的水平——(猜猜看,这些将是你在标题中要求的{ SL | TP }——并且这样的记录正在等待(带有一些更多可配置的选项),直到这样价格变动发生与否,在此期间此类仓位处于非活动状态等待,称为挂单 ...

    有关条款和条件,请查看您的经纪人的合同和/或询问他们的客户服务代表。可能会有一些特殊限制(最好先了解)。


    ... WHERE ... 放代码?

    无需重新设计提供的代码(那里有一些小错误/效率低下),代码应该放在这里:

        result = OrderSend( Symbol(),
                            OP_SELL,  // PRIMARY SELL <<<AT-MARKET>>>
                            Lots,
                            Bid,
                            Slippage,
                            0,
                            0,
                            "Sell",
                            MagicNumber,
                            0,
                            Red
                            );
        if (  result >  0 )
        {     
              TheStopLoss   = 0;
              TheTakeProfit = 0;
    
              if (  TakeProfit >  0 ) TheTakeProfit = Bid - TakeProfit * MyPoint;
              if (  StopLoss   >  0 ) TheStopLoss   = Bid + StopLoss   * MyPoint;
    
              OrderSelect( result, SELECT_BY_TICKET );
    
              OrderModify( OrderTicket(),
                           OrderOpenPrice(),
                           NormalizeDouble( TheStopLoss,   Digits ),
                           NormalizeDouble( TheTakeProfit, Digits ),
                           0,
                           Green
                           );
           // ---------------------------------------------------- HERE ADD
              OrderSend(   Symbol(),
                           OP_SELLSTOP,    // SELL-STOP PENDING ORDER ON SELL.TP
                           Lots,
                           NormalizeDouble( TheTakeProfit
                                          - MarketInfo( _Symbol, MODE_SPREAD ),
                                            Digits
                                            ),
                           Slippage,
                           0,              // SL: T.B.D.
                           0,              // TP: T.B.D.
                           "Sell on Sell.TP",
                           sTpMagicNumber, // avoid collisions with other logic
                           0,              // never expires
                           Red
                           );
    
              OrderSend(   Symbol(),
                           OP_BUYSTOP,    // BUY-STOP PENDING ORDER ON SELL.SL
                           Lots,
                           NormalizeDouble( TheStopLoss
                                          - MarketInfo( _Symbol, MODE_SPREAD ),
                                            Digits
                                            ),
                           Slippage,
                           0,              // SL: T.B.D.
                           0,              // TP: T.B.D.
                           "Buy on Sell.SL",
                           bSlMagicNumber, // avoid collisions with other logic
                           0,              // never expires
                           Red
                           );
        }
    

    点差调整不是绝对的,因为在不稳定时期,市场会受到虚假点差波动的影响。同样,经纪人的条款和条件在这里适用,所以要小心。

    【讨论】:

    • 很好的答案...但没有完全回答问题“当订单达到 TP/SL”。提供的方法更像是一种解决方法。
    猜你喜欢
    • 2021-09-17
    • 2022-07-28
    • 2022-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    相关资源
    最近更新 更多