Position modifying and partial close

andrw11
94
andrw11  

i have a take profit of "150" points but , I'd like to partially close a position if it get 50 points profits then modify the remaining position with a take profit (100 points) , here's my code

the problem is that the position closes fully at 50 points , i understand why but can't figure out how to fix it !!


    if(PositionsTotal() > 0 ) {
       
       for (int i = PositionsTotal() - 1; i >=0; i-- ) {
         
         ulong position_ticket =  PositionGetTicket(i);
         if (PositionSelectByTicket(position_ticket) ) {
         
         double position_sl = PositionGetDouble(POSITION_PRICE_OPEN);
         
         if ( (  (PositionGetDouble(POSITION_PROFIT) - PositionGetDouble(POSITION_SWAP) ) / PositionGetDouble(POSITION_VOLUME) )  > 50 ) {
 
               trade.PositionClosePartial(position_ticket,0.10,1);
               trade.PositionModify(position_ticket,position_sl ,Ask + 100 * _Point);
             
         }
         
        } // position select

       }//for loop
    } // total positions
    
    
    
Amir Yacoby
1463
Amir Yacoby  
  1. What is the size of your initial position? The partial close if of volume 0.1 lot.
  2. Does this code runs once, or at each tick? If the latter, then it eventually closes all position. Check also in the journal tab how many closes it has done. If so, you need to add a bool field condition, something like 
        //--- define in expert global part
        bool positions_modified=false;
    
        //--- as usual except the new condition check and set
        if(!positions_modified && PositionsTotal() > 0 ) {
           
           for (int i = PositionsTotal() - 1; i >=0; i-- ) {
             
             ulong position_ticket =  PositionGetTicket(i);
             if (PositionSelectByTicket(position_ticket) ) {
             
             double position_sl = PositionGetDouble(POSITION_PRICE_OPEN);
             
             if ( (  (PositionGetDouble(POSITION_PROFIT) - PositionGetDouble(POSITION_SWAP) ) / PositionGetDouble(POSITION_VOLUME) )  > 50 ) {
     
                   trade.PositionClosePartial(position_ticket,0.10,1);
                   trade.PositionModify(position_ticket,position_sl ,Ask + 100 * _Point);
                    positions_modified=true;
                 
             }
             
            } // position select
    
           }//for loop
        } // 


andrw11
94
andrw11  
Amir Yacoby:
  1. What is the size of your initial position? The partial close if of volume 0.1 lot.
  2. Does this code runs once, or at each tick? If the latter, then it eventually closes all position. Check also in the journal tab how many closes it has done. If so, you need to add a bool field condition, something like 


1. it's 0.2 

2. it's inside onTick , that's why it closes all positions at the partial profit , and i tried adding this bool condition but it doesn't work !!  since after the first modifying the "positions_modified" will remain true 

How should i solve this ?!

Amir Yacoby
1463
Amir Yacoby  
andrw11:

1. it's 0.2 

2. it's inside onTick , that's why it closes all positions at the partial profit , and i tried adding this bool condition but it doesn't work !!  since after the first modifying the "positions_modified" will remain true 

How should i solve this ?!

This condition

if(!positions_modified && PositionsTotal() > 0 ) {

Is false (! means not which is equivalent to positions_modified=false) when positions_modified is true. So, how come it enters again? 

If positions_modified is defined at the global level, and not in OnTick then it remains true and if(!positions_modified) is false. This is how it should work.
So check what's wrong in the code.

andrw11
94
andrw11  
Amir Yacoby:

This condition

Is false (! means not which is equivalent to positions_modified=false) when positions_modified is true. So, how come it enters again? 

If positions_modified is defined at the global level, and not in OnTick then it remains true and if(!positions_modified) is false. This is how it should work.
So check what's wrong in the code.

yes i know , but the problem is that after the first IF, the value of " positions_modified " will remain true as long as the expert works since the value won't reset to false again and won't modify any future positions !

Vladimir Karputov
Moderator
220803
Vladimir Karputov  

There is only one solution: an array is declared in the "header" of the Expert Advisor, in which position identifiers will be stored.

In the loop, you do this: if you made a partial closure, enter the identifier   positions in the array. And before you carry out a partial closure, check whether this identifier is in the array.

Amir Yacoby
1463
Amir Yacoby  
Either what was suggested by Vladimir or select the order by the order ticket (which is supposed to be the same as position ticket) and check ORDER_INITIAL_VOLUME against the current volume of position(it is assumed that the position was opened by one order only, otherwise it wont work) Only modify when they are different. 
In the case you take the array way, dont forget to delete from array when a position is closed.
Vladimir Karputov
Moderator
220803
Vladimir Karputov  
Vladimir Karputov :

There is only one solution: an array is declared in the "header" of the Expert Advisor, in which position identifiers will be stored.

In the loop, you do this: if you made a partial closure, enter the identifier   positions in the array. And before you carry out a partial closure, check whether this identifier is in the array.

Code example: Position Close Partial