1
votes

I trade on 1H & 4H cycles, & I'm trying to implement coding that closes a position if it is in a loss & by the time it is a half way through the trade cycle ( PERIOD_CURRENT ).

Trade Cycle 4H = 4 [hr] = 240 [min] = 14,400 [s]

A trade cycle is 4H, so I want to be able to automatically close a position if a trade is in loss 2 hours after the trade was initially opened.

Based on the time, being in seconds since 1/1/1970, I've compared the TimeCurrent() with the OrderOpenTime() + the 4H in seconds, but divided this by two to get the time after two hours.

This however isn't working - I've added the code below.

If anyone can shed any light on this, it would be greatly appreciated.

Example

OrderStartTime = 14,000,000

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

Close half way through
if trade is in loss at time
= 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() );
              }
    }
 }
2
Trade Cycle = 4 Hours = 240 seconds - may be minutes obviously?user2807083
Yes, sorry & correcteduser6216142
60 minutes * 240minutes again, what is it, squared minutes? If you want to use dimensions, than it will something like 60 sec/min * 240 min = 14400 secuser2807083
The MQL platform measures time in seconds, so if the order open time is 14,000,000 seconds since 1/1/1970 so closing the position will be at 14,014,400 seconds since 1/1/1970. Half way will be 14,007,200 seconds since 1/1/1970 so 60 * 240 = 14,400. No early closes though so I'm thinking the brackets may be the issue perhapsuser6216142

2 Answers

0
votes

MQL4 Language constructors' syntax should be well understood:

As repaired above, the code is doing a single command earlcloses = OrderClose(...); if and only if all serially nested if()-conditions were met.

Right after that ( only conditionally executed CODEBLOCK-{} ),
there is a next line, which is on the contrary evaluated in each for(){...} loop round, except the last one:

if ( earlcloses == true )

This if()-condition evaluates to True in all cases, except in the last for(){...} loop round, because until that last one, the for(){...} loop--control variable declared as

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

This means, your code arrives at the ( earlcloses == true ) test always with a value > False, which yields the True output from the if(...) test and the following {...} code will be executed ( except the very last loop of the for(), where the earlcloses == 0, thus yielding the if()-test False, as noted above.


OrderClose() shall obey the XTO-rules, ref. other your Questions

Submitting a server-side executed instructions, be sure to have the prices setup correctly. Read about RefreshRates() instead of processing results from MarketInfo() and as has been repeated several times in your previous questions, always NormalizeDouble().


Robust MQL4 code never relies on db.Pool ORDER_BY_POS:

Rather work with OrderTicket() db.Pool-DMA-mode. As listed in your code, implicit position-based assumptions lead to cases, when there is none record in the HISTORY-part of the db.Pool and a blind attempt to OrderSelect( ..., MODE_HISTORY ) will fail.


Time Comparisons should be correct:

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

The worst error
in the concept of the MQL4 code above
is in an intervening assignment,
damaging the logic of a for(){...}-loop-control variable

This if obvious from:

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

The very first OrderClose() call kills the whole for(){...} logic leaving {none|one}-last loop via it's intervening assignment of a value of { 0 | 1 } into the loop-control variable.


Epilogue:

Once you have posted in one of your last four questions a comment, that you feel disgusted by not having the code running as you wish, because otherwise, you have a profitable strategy, it seems double the reasonable to hire a professional to have the algorithmisation done for you correct and robust. It would yield you the strategy RTO much faster, than correcting individual code-snippets.

0
votes

Suggestion. Please read the comments:

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