Math problem when calculating lots for a partial close

 

Hi guys,

this script should close a part of the running trade just to cover a possible loss if the stoploss would be hit.

For example I bought EURUSD at 1.1600 and the stoploss is at 1.1550. Price rises to 1.1700. Now I want to sell exactly the amount of lots that the rest position is safe in case of price falling down to my stoploss at 1.1550.

I hope that makes sense.


Here is my code so far. Everything seems to be correct until the very last part of the code where I try to calculate the lots to close.

void OnStart()
  {
//---
   for (int i=0; i<OrdersTotal(); i++) {
      if (OrderSelect(i, SELECT_BY_POS)) {
         if (_Symbol==OrderSymbol()) {
            double moneyRisk = OrderLots()*MathAbs(OrderOpenPrice()-OrderStopLoss())*MarketInfo(NULL, MODE_TICKVALUE)/MarketInfo(NULL, MODE_TICKSIZE);
            double pipsProfit;
            if (OrderType()==OP_BUY) {
               if (OrderStopLoss()>OrderOpenPrice()) return;
               pipsProfit = Bid-OrderOpenPrice();
            }
            else if (OrderType()==OP_SELL) {
               if (OrderStopLoss()<OrderOpenPrice()) return;
               pipsProfit = OrderOpenPrice()-Ask;
            }
            else return;
            double currentProfit = OrderLots()*pipsProfit*MarketInfo(NULL, MODE_TICKVALUE)/MarketInfo(NULL, MODE_TICKSIZE);
            if (currentProfit<moneyRisk) return;
            double lotsToClose = OrderLots()*moneyRisk/currentProfit;
            lotsToClose = MathFloor(lotsToClose/MarketInfo(NULL, MODE_LOTSTEP))*MarketInfo(NULL, MODE_LOTSTEP)+MarketInfo(NULL, MODE_MINLOT);
            Alert("Lots to close: "+DoubleToString(lotsToClose, 2));
            Alert("Win: "+DoubleToString(lotsToClose*pipsProfit*MarketInfo(NULL, MODE_TICKVALUE)/MarketInfo(NULL, MODE_TICKSIZE), 2)+" "+AccountCurrency());
         }
      } 
   }
  }
 
MarketInfo(NULL, MODE_TICKVALUE)
  • You can use NULL in place of _Symbol only in those calls that the documentation specially says you can. iHigh does, MarketInfo does not. OrderSend does not.
  • Don't use NULL (except for pointers where you explicitly check for it.) Use _Symbol and _Period, that is minimalist as possible and more efficient.
  • Zero is the same as PERIOD_CURRENT which means _Period.
  • No need for a function call with iHigh(NULL,0,s) just use the predefined arrays, i.e. High[].
 
whroeder1:
  • You can use NULL in place of _Symbol only in those calls that the documentation specially says you can. iHigh does, MarketInfo does not. OrderSend does not.
  • Don't use NULL (except for pointers where you explicitly check for it.) Use _Symbol and _Period, that is minimalist as possible and more efficient.
  • Zero is the same as PERIOD_CURRENT which means _Period.
  • No need for a function call with iHigh(NULL,0,s) just use the predefined arrays, i.e. High[].

Thanks, I will take care of it from now on. Just changed my code.

But in this case the result is the same. I receive the same lot size to be closed. There is an error in the maths and I can't figure out the missing part in it.

EDIT: Problem solved!
 

Why don't you open just two orders? The first one (the partial close volume) with a TakeProfit at 1.1700.

If you do a partial close, the broker creates a new position with a new ticket, which you have to search for..

 
Carl Schreiber:

Why don't you open just two orders? The first one (the partial close volume) with a TakeProfit at 1.1700.

If you do a partial close, the broker creates a new position with a new ticket, which you have to search for..


I never thought about that because for me it doesn't matter if a new position with a new ticket is created. Additionally I don't use partial closes all the time. Only when prices comes to an area which might cause troubles.

Reason: