【问题标题】:How to close a trade after a certain time if a position is in loss | MQL4如果头寸亏损,如何在一定时间后关闭交易 | MQL4
【发布时间】:2016-08-14 09:47:55
【问题描述】:

我在 1H4H 周期进行交易,并且我正在尝试实施编码,以在亏损时平仓现在是交易周期的一半(PERIOD_CURRENT)。

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

一个交易周期是4H,所以我希望能够在交易最初开仓2小时后亏损时自动平仓。

根据时间(以 1970 年 1 月 1 日以来的秒数为单位),我将 TimeCurrent()OrderOpenTime() + 进行了比较4H 以秒为单位,但除以 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() );
              }
    }
 }

【问题讨论】:

  • Trade Cycle = 4 Hours = 240 seconds - 显然是几分钟?
  • 是的,抱歉,已更正
  • 60 minutes * 240minutes 再次,它是什么,平方分钟?如果你想使用尺寸,那么它会像60 sec/min * 240 min = 14400 sec
  • MQL ​​平台以秒为单位测量时间,因此如果自 1970 年 1 月 1 日以来订单开仓时间为 14,000,000 秒,那么自 1970 年 1 月 1 日以来平仓时间为 14,014,400 秒。自 1970 年 1 月 1 日以来,中途将是 14,007,200 秒,因此 60 * 240 = 14,400。不过没有提前关闭,所以我认为括号可能是问题

标签: trading algorithmic-trading mql4 metatrader4


【解决方案1】:

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

如上所述,当且仅当满足所有串行嵌套的if()-条件时,代码才执行单个命令earlcloses = OrderClose(...);

紧接着(仅有条件地执行CODEBLOCK-{}),
有一个下一行,相反,在每个for(){...}循环中进行评估,最后一个除外:

if ( earlcloses == true )

这个if()-条件在所有情况下都为True,除了最后一轮for(){...}循环,因为直到最后一轮,for(){...}循环-控制变量声明为

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

这意味着,您的代码到达( earlcloses == true ) 测试时总是带有&gt; False 值,这会产生if(...) 测试的True 输出和以下{...} 代码将被执行(除了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(){...} 逻辑,留下 {none|one}-最后一个循环,通过它的介入赋值 { 0 | 1 } 到循环控制变量。


结语:

一旦您在最后四个问题中的一个中发表了评论,您会因为没有按您希望的方式运行代码而感到厌恶,因为否则,您有一个有利可图的策略,聘请专业人士似乎是合理的两倍为您完成正确且稳健的算法化。与更正单个 code-sn-ps 相比,它会更快地为您生成策略 RTO。

【讨论】:

  • 有趣,感谢您的解释和公平评论:)
  • 是的,很抱歉我还没有投票,我仍在学习如何浏览网站。我是这里的新手 :) 我想询问更多细节,但我不确定询问更多问题和让人们为我编写代码之间的界限在哪里,我知道这不是这个网站的目的。
  • 一个好的做法和一个广为接受的态度是发布代码,具有合理的使用上下文,连同错误日志(日志式 Print() 自诊断消息)和 PrintScreens,以显示您对解决阻塞问题的兴趣(尝试检查 StackOverflow Do's 和 Dont's 上的 MCVE 原则)以及您自己对迄今为止为问题隔离和问题解决所做的尝试的输入。我知道在一些复杂的情况下这并不容易,其中代码库跨越超过 200.000 个 SLOC,但在 MQL4 中,这可能很好地描述意图并显示结果。
【解决方案2】:

建议。请阅读cmets:

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() );
                                }
                           }
}

【讨论】:

    猜你喜欢
    • 2017-09-29
    • 1970-01-01
    • 2022-10-25
    • 2016-10-02
    • 2020-09-11
    • 2012-10-15
    • 1970-01-01
    • 1970-01-01
    • 2014-10-21
    相关资源
    最近更新 更多