繁体   English   中英

如果头寸处于亏损状态,如何在一定时间后关闭交易| MQL4

[英]How to close a trade after a certain time if a position is in loss | MQL4

我以1H4H周期进行交易,并且我试图实现编码,如果仓位处于亏损状态并且在交易周期的一半时关闭仓位( PERIOD_CURRENT )。

交易周期4H = 4 [hr] = 240 [min] = 14,400 [s]

交易周期为4H ,因此,我希望能够在开仓后2小时内自动平仓。

基于时间,从TimeCurrent()年1月1日开始,以秒为单位,我将TimeCurrent()OrderOpenTime() + 4H以秒为单位TimeCurrent()进行了OrderOpenTime() ,但将其除以2得到两个小时后的时间。

但是,这不起作用-我在下面添加了代码。

如果任何人都能对此有所了解,将不胜感激。

OrderStartTime = 14,000,000

OrderCloseTime = 14,000,000 + 60 minutes * 240 minutes = 14,014,400 <<<<<

通过一半关闭
如果交易在时间上亏损 = 14,000,000 + (60 * 240*0.5) = 140,007,200

for ( int earlcloses = OrdersTotal() - 1; earlcloses >= 0; earlcloses-- )
{
    if (                        OrderSelect( earlcloses, SELECT_BY_POS, MODE_TRADES ) )
         if (                   OrderType()                               == OP_SELL )
               if (             OrderMagicNumber()                        == Period() )
                     if (       OrderOpenTime() + ( 60 * Period() * 0.5 ) <= TimeCurrent() )
                           if ( OrderOpenPrice()                          <  Bid )
                           { // |||||||||||||||||||||||||||||||||||||||||||
                             /* --serially-nested-if()-s CODEBLOCK-{}-START--- */

                                earlcloses = OrderClose( OrderTicket(),
                                                         LotSize,
                                                         MarketInfo( sym, MODE_BID )
                                                       + MarketInfo( sym, MODE_SPREAD )
                                                       * MarketInfo( sym, MODE_POINT ),
                                                         300,
                                                         clrNONE
                                                         );

                             /* ------------------------ CODEBLOCK-{}-FINISH--- */
                           } // ||||||||||||||||||||||||||||||||||||||||||||
    if ( earlcloses == true )
    {    Sleep( 60000 );
         int  earlyclosesel =  OrdersHistoryTotal()-1;
         bool earlySelect   =  OrderSelect( earlyclosesel, SELECT_BY_POS, MODE_HISTORY );
         if ( earlySelect   == true )
         {
              int earlTicket = OrderTicket();
              SendMail( "Notification of early position closure", "Trade #" + IntegerToString( earlTicket, 0 ) + "has been closed at" + DoubleToStr( OrderClosePrice(), 5 ) + "due to timeout" );
         }
         else if ( earlySelect == false )
              {
                   Print( "EarlyClose failed with error #", GetLastError() );
              }
    }
 }

MQL4语言构造函数的语法应被很好地理解:

如上所修复,代码正在执行单个命令earlcloses = OrderClose(...); 当且仅当满足所有串行嵌套的if() conditions时。

之后(仅有条件执行CODEBLOCK-{} ),
下一行相反,在每一轮for(){...}循环中均for(){...}评估,最后一行除外:

if ( earlcloses == true )

除在最后一轮for(){...}循环之外,所有情况下,此if() condition的结果均为True,因为直到最后一轮, for(){...}循环-控制变量声明为

for( int earlcloses =  OrdersTotal() - 1; // .SET  initial value
         earlcloses >= 0;                 // .TEST before a loop-execution starts
         earlcloses--                     // .UPD  after  a loop-execution
         ){...}

这意味着,您的代码始终以> False的值到达( earlcloses == true )测试,这会从if(...)测试产生True输出,并且将执行以下{...}代码(除非earlcloses == 0 ,for()的最后一个循环,其中earlcloses == 0 ,从而产生if() test False


OrderClose()应遵守XTO规则,参考。 其他你的问题

提交服务器端已执行的说明,请确保正确设置价格。 阅读有关RefreshRates()而不是处理MarketInfo()结果,并且在以前的问题中已经多次重复,请始终使用NormalizeDouble()


可靠的MQL4代码从不依赖db.Pool ORDER_BY_POS

而是与OrderTicket() db.Pool- DMA模式一起使用。 如您的代码中列出的那样,基于隐式基于位置的假设会导致以下情况:当db.Pool的HISTORY部分中没有记录时,盲目尝试OrderSelect( ..., MODE_HISTORY )将失败。


时间比较应该是正确的:

( OrderOpenTime() + 0.5 * PeriodSeconds( PERIOD_CURRENT ) <= TimeCurrent() )

最严重的错误
在上面的MQL4代码的概念中
处于介入作业中,
破坏for(){...} -loop-control变量的逻辑

如果从以下方面显而易见:

for ( int earlcloses = OrdersTotal() - 1; earlcloses >= 0; earlcloses-- )
{   if ( ...
          ..
           .
            {                      earlcloses = OrderClose( OrderTicket(), ... );
            }
    ...
}

第一个OrderClose()调用杀死了整个for(){...}逻辑,并通过中间分配的值{ 0 | 1 } for(){...}离开了{none|one} -last循环{ 0 | 1 } { 0 | 1 }进入循环控制变量。


结语:

在最后四个问题之一中发表评论后,您对没有按要求运行代码感到恶心,因为否则,您就有了有利可图的策略,因此聘请专业人员进行算法似乎是合理的两倍。为您做的正确而稳健。 与纠正单个代码段相比,它可以更快地为您提供策略RTO。

建议。 请阅读评论:

for ( int orderIndex = OrdersTotal() - 1; orderIndex >= 0; orderIndex-- ) {
    //Note: You are closing ALL orders regardless of Symbol() of the current chart!!
    if (                        OrderSelect( orderIndex, SELECT_BY_POS, MODE_TRADES ) )
         if (                   OrderType()                               == OP_SELL )
               if (             OrderMagicNumber()                        == Period() )
                     if (       (TimeCurrent()-OrderOpenTime())           >= (60*Period()/2) )
                           if ( (              OrderProfit()     // P&L
                                             + OrderCommission() // needs to factor in Commission
                                             + OrderSwap()       // needs to factor in all Swaps
                                               )                          <  0.0 ) {
                             // --------------------------------------------------
                                RefreshRates();                  // VERY IMPORTANT
                             // --------------------------------------------------                                    
                                int  closedTicket = OrderTicket();
                                if (  OrderClose( closedTicket,
                                                  OrderLots(),
                                                  MarketInfo( Symbol(), MODE_ASK ),   //You are closing a SELL trade, should use ASK price.
                                                  300, clrNONE ) ) {
                                      SendMail( "Notification of early position closure",
                                                "Trade #" + IntegerToString( closedTicket, 0 )
                                              + " has been closed at " + DoubleToStr( MarketInfo( Symbol(), MODE_ASK), 5 ) + " due to timeout."
                                                );
                                }
                                else {
                                      Print( "EarlyClose failed with error #", GetLastError() );
                                }
                           }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM