Обёртка для функции OrderModify

Функция качественной модификации ордеров.

Она предназначена для того, чтобы предупреждать ситуации когда советник или скрипт не может изменить уровни StopLoss, TakeProfit или же переместить отложенные(Stop/Limit) ордера из-за ошибок сервера (реквоты, пропадание связи и пр.).

Функцию достаточно добавить в код и исправить Ваш вызов OrderModify:

result = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(ldStopLoss, Digits),OrderTakeProfit(),0,CLR_NONE);

на

result = ModifyOrder(OrderTicket(),OrderOpenPrice(),NormalizeDouble(ldStopLoss, Digits),OrderTakeProfit(),0,CLR_NONE);

Сама функция:

bool ModifyOrder (int aticket, double aprice, double astoploss, 
                  double atakeprofit, datetime expiration, 
                  color arrow_color = CLR_NONE) 
{
    if (IsStopped()) 
    {
        Print("Ошибка, остановлен: IsStopped() == true");
        return(false);
    }
	
    int TryCount = 20;
    int cnt = 0;
	
    while(!IsTradeAllowed() && cnt < TryCount) 
    { 
        Sleep(500); 
        cnt++; 
    } 

    if (!IsTradeAllowed())
    {
       Print("Ошибка: Операция недопустима - IsTradeAllowed()==false"); 
       return(false); 
    }

    if (OrderSelect(aticket, SELECT_BY_TICKET,MODE_TRADES))
    {
        string symbol = OrderSymbol();
        int digits = int(MarketInfo(symbol, MODE_DIGITS));

        if (digits > 0) 
        {
           aprice      = NormalizeDouble(aprice,digits);
           astoploss   = NormalizeDouble(astoploss,digits);
           atakeprofit = NormalizeDouble(atakeprofit,digits); 
        }
    }

    int err = GetLastError(); // so we clear the global variable.  
    err = 0; 
    bool exit_loop = false;
    bool result = false;

	
    while (!exit_loop) 
    {
        if (IsTradeAllowed()) 
        {
            result = OrderModify(aticket, aprice, astoploss, atakeprofit, expiration, arrow_color);
            err = GetLastError();
        } 
        else cnt++;
        if (result == true) 
           exit_loop = true;

        switch (err) 
        {
            case ERR_NO_ERROR:
                 exit_loop = true;
                 break;
				
            case ERR_NO_RESULT:
                 exit_loop = true;
                 break;
				
            case ERR_SERVER_BUSY:
            case ERR_NO_CONNECTION:
            case ERR_INVALID_PRICE:
            case ERR_OFF_QUOTES:
            case ERR_BROKER_BUSY:
            case ERR_TRADE_CONTEXT_BUSY: 
            case ERR_TRADE_TIMEOUT:		
                 cnt++; 	
                 break;
				
            case ERR_PRICE_CHANGED:
            case ERR_REQUOTE:
                 RefreshRates();
                 continue; 	
				
            default:
                 exit_loop = true;
                 break; 
				
        }  // end switch 

        if (cnt > TryCount) 
           exit_loop = true; 
			
        if (!exit_loop) 
        {
           Print("Ошибка, попыток:  (" + IntegerToString(cnt) + "/" + IntegerToString(TryCount)); 
           Sleep(500); 
           RefreshRates(); 
        }
		
        if (exit_loop) 
        {
            if ((err != ERR_NO_ERROR) && (err != ERR_NO_RESULT)) 
               Print("Ошибка: "  + IntegerToString(err)); 
        }
    } // while (!exit_loop) 
	
	
    if ((result == true) || (err == ERR_NO_ERROR)) 
    {
        Print("Успешная модификация");
        if(OrderSelect(aticket, SELECT_BY_TICKET, MODE_TRADES))
        {
           OrderPrint(); 
           return(true); // SUCCESS! 
        } 
        else 
        {   
           return(false);
        }
    } 
	
    if (err == ERR_NO_RESULT) 
    {
        return(true);
    }
	
    Print("Ошибка модификации после " + IntegerToString(cnt) + " попыток");
    Print("Ошибка модификации: "  + IntegerToString(aticket) + " " + Symbol() + 
						"@" + DoubleToString(aprice) + " tp@" + DoubleToString(atakeprofit) + " sl@" + DoubleToString(astoploss)); 
    Print("Ошибка : " + IntegerToString(err)); 
	
    return(false);  
}


 

Written by 

Добавить комментарий