Доработать код от ошибки 131

 
NedeljВ этом коде все работает хорошо в терминале, а валидацию пройти не может. Что можно добавить, чтобы хватало средств и не было ошибки 131
input double _LosPercent = 3;

// Stop Loss (в пунктах)
input int _SL = 30;

// Take Profit (в пунктах)
input int _TP = 60;

// Magic Number (метка "своих" сделок для робота)
input int _MagicNumber = 4734;

// Комментарий для сделок
input string _Comment = "RussiaBot";

// Допустимое проскальзывание
input int _Slippage = 5;

// Одновременно не более одной сделки
input bool _OnlyOneOpenedPos = true;

// Автоучёт числа знаков цены
input bool _AutoDigits = true;

// ---

double OP_LOTS = 0.0;
// ---
// MQL4 | класс автоопределния числа знаков после запятой у текущего инструмента | ENSED Team, http://ensed.org
class CKDig
{
   public:
      CKDig(const bool useAutoDigits)
      {
         Set(useAutoDigits);
      }
      
      ~CKDig(void)
      {
      }
      
      uint Get(void)
      {
         return m_value;
      }
      
   private:      
      uint m_value;      
      
      void Set(const bool useAutoDigits)
      {
         m_value = 1;
         if (!useAutoDigits)
         {
            return;
         }
         
         if (Digits() == 3 || Digits() == 5)
         {
            m_value = 10;
         }
      }
};

CKDig *KDig;
#define K_DIG (KDig.Get())

datetime LAST_BUY_BARTIME = 0;
datetime LAST_SELL_BARTIME = 0;

// ---
void OnInit()
{
        // ---
        // ---
        KDig  = new CKDig(_AutoDigits);
}

// ---
void OnDeinit(const int reason)
{
        // ---
        // ---
        if(CheckPointer(KDig))
        {
           delete KDig;
        }
}

// ---
void OnTick()
{
        // ---
        // закрытие сделки
        if(find_orders(_MagicNumber))
        {
                if(cl_buy_sig())
                {
                        cbm(_MagicNumber, _Slippage, OP_BUY);
                }
                if(cl_sell_sig())
                {
                        cbm(_MagicNumber, _Slippage, OP_SELL);
                }
        }
        
        // открытие сделки
        // ---
        get_lots_by_percent(Ask, Ask-_SL*K_DIG*Point);
        // ---
        if(!find_orders(_MagicNumber, (_OnlyOneOpenedPos ? -1 : OP_BUY)))
        {
                if(op_buy_sig() && LAST_BUY_BARTIME != iTime(Symbol(), Period(), 0))
                {
                        LAST_BUY_BARTIME = iTime(Symbol(), Period(), 0);
                        open_positions(OP_BUY, OP_LOTS);        
                }
        }
        // ---
        if(!find_orders(_MagicNumber, (_OnlyOneOpenedPos ? -1 : OP_SELL)))
        {
                if(op_sell_sig() && LAST_SELL_BARTIME != iTime(Symbol(), Period(), 0))
                {
                        LAST_SELL_BARTIME = iTime(Symbol(), Period(), 0);
                        open_positions(OP_SELL, OP_LOTS);       
                }
        }
}

// ---

// ---
void get_lots_by_percent(double op_price, double sl_price)
{
        // MQL4 | объём сделки рассчитывается по значению SL и допустимому проценту потерь| ENSED Team
        RefreshRates();
        if(_SL == 0)
        {
                OP_LOTS = MarketInfo(Symbol(), MODE_MINLOT);
                return;
        }
        // ---
        int pp;
        if (op_price < sl_price)
                pp = int((sl_price - op_price) / Point);
        else
                pp = int((op_price - sl_price) / Point);
        OP_LOTS = (((AccountFreeMargin() * _LosPercent) / 100) / MarketInfo(Symbol(), MODE_TICKVALUE)) / (pp);
        OP_LOTS = MathRound(OP_LOTS / MarketInfo(Symbol(), MODE_LOTSTEP)) * MarketInfo(Symbol(), MODE_LOTSTEP);
        OP_LOTS = MathMax(OP_LOTS, MarketInfo(Symbol(), MODE_MINLOT));
        OP_LOTS = MathMin(OP_LOTS, MarketInfo(Symbol(), MODE_MAXLOT));
}

// ---
// ---
bool find_orders(int magic = -1, int type = -1, int time = -1, string symb = "NULL", double price = -1, double lot = -1)
{
        // MQL4 | функция поиска открытых ордеров | ENSED Team, http://ensed.org
        // возвращает истину, если найден хотя бы один ордер с подходящими параметрами
        for (int i = OrdersTotal() - 1; i >= 0; i--)
        {
                if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
                        break;
                if (((OrderType() == type) || (type == -1))
                        && ((OrderMagicNumber() == magic) || (magic == -1))
                        && ((OrderSymbol() == symb) || (symb == "NULL" && OrderSymbol() == Symbol()))
                        && ((OrderOpenTime() >= time) || (time == -1))
                        && ((OrderLots() == lot) || (lot == -1))
                        && ((NormalizeDouble(OrderOpenPrice(), Digits) == NormalizeDouble(price, Digits)) || (price == -1)))
                {
                        return (true);
                        break;
                }
        }
        return (false);
}
// ---
void open_positions(int signal, double lot, double price = 0.0, string symb = "NONE", int mode = 0)
{
        // MQL4 | функция открытия ордеров | ENSED Team, http://ensed.org
        RefreshRates();
        // ---
        int symbDigits = 0;
        string _symb = symb;
        // ---
        if (_symb == "NONE")
        {
                symbDigits = Digits;
                _symb = Symbol();
        }
        else
                symbDigits = int(MarketInfo(_symb, MODE_DIGITS));
        // ---
        if (signal == OP_BUY)
                price = NormalizeDouble(MarketInfo(_symb, MODE_ASK), symbDigits); // цена открытия для покупок
        if (signal == OP_SELL)
                price = NormalizeDouble(MarketInfo(_symb, MODE_BID), symbDigits); // цена открытия для продаж
        // ---
        int err = 0;
        for (int i = 0; i <= 5; i++)
        {
           RefreshRates();
           // ---
                int ticket = OrderSend(_symb, // символ
                        signal, // тип ордера
                        lot, // объем
                        NormalizeDouble(price, symbDigits), // цена открытия
                        _Slippage * KDig.Get(), // уровень допустимого реквота
                        0, // Stop Loss
                        0, // Take Profit
                        _Comment, // комментарий ордера
                        _MagicNumber, // магическое число
                        0, // срок истечения (используется в отложенных ордерах)
                        CLR_NONE); // цвет отображаемой стрелки на графике (CLR_NONE - стрелка не рисуется)
                // ---
                if (ticket != -1)
                {
                        err = 0;
                        // ---
                        if (!IsTesting())
                                Sleep(1000);
                        // ---
                        RefreshRates();
                        // ---
                        if(_SL != 0 || _TP != 0)
                        {
                                for (int tryModify = 0; tryModify <= 5; tryModify++)
                                {
                                        RefreshRates();
                                        // ---
                                        if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES))
                                        {
                                                double sl = NormalizeDouble(get_sl(_SL * KDig.Get(), signal, price, _symb), symbDigits);
                                                double tp = NormalizeDouble(get_tp(_TP * KDig.Get(), signal, price, _symb), symbDigits);
                                                // ---
                                                if (sl != 0 || tp != 0)
                                                if (OrderModify(OrderTicket(), OrderOpenPrice(), sl, tp, OrderExpiration()))
                                                        break;
                                                // ---
                                                err = GetLastError(); // получаем код ошибки модификации
                                        }
                                        // ---
                                        if (!IsTesting())
                                                Sleep(tryModify*1000);
                                }
                                // ---
                                if (err != 0)
                                        Alert("Ошибка выставления SL/TP: " + Market_Err_To_Str(err));
                        }
                        // ---
                        break;
                }
                else
                {
                        err = GetLastError(); // получаем код ошибки открытия
                        // ---
                        if (err == 0)
                                break;
                        // ---
                        i++;
                        // ---
                        if (!IsTesting())
                                Sleep(i*500); // в случае ошибки делаем паузу перед новой попыткой
                }
        }
        // ---
        if (err != 0)
        {
                if(signal == OP_BUY)
                        LAST_BUY_BARTIME = 0;
                if(signal == OP_SELL)
                        LAST_SELL_BARTIME = 0;
                Alert("Ошибка открытия: "  + Market_Err_To_Str(err)); // если есть ошибка - выводим сообщение
        }
}

// ---
double get_tp(int tp_value, int type, double price = 0.0, string symb = "NONE")
{
        // MQL4 | функция расчета величины Take Profit для ордеров | ENSED Team, http://ensed.org
        double _price = price;
        string _symb = symb;
        // ---
        if (_symb == "NONE")
                _symb = Symbol();
        int symbDigits = int(MarketInfo(_symb, MODE_DIGITS));
        // ---
        if (_price == 0)
        {
                if (type == OP_BUY)
                        _price = NormalizeDouble(MarketInfo(_symb, MODE_ASK), symbDigits);
                // ---
                if (type == OP_SELL)
                        _price = NormalizeDouble(MarketInfo(_symb, MODE_BID), symbDigits);
        }
        // ---
        if (tp_value > 0)
        {
                if (type == OP_BUY || type == OP_BUYLIMIT || type == OP_BUYSTOP)
                        return NormalizeDouble(_price + tp_value * MarketInfo(_symb, MODE_POINT), symbDigits);
                // ---
                if (type == OP_SELL || type == OP_SELLLIMIT || type == OP_SELLSTOP)
                        return NormalizeDouble(_price - tp_value *  MarketInfo(_symb, MODE_POINT), symbDigits);
        }
        // ---
        return 0.0;
}

// ---
double get_sl(int sl_value, int type, double price = 0.0, string _symb = "NONE")
{
        // MQL4 | функция расчета величины Stop Loss для ордеров по фиксированному значению SL | ENSED Team, http://ensed.org
        if (_symb == "NONE")
                _symb = Symbol();
        int symbDigits = int(MarketInfo(_symb, MODE_DIGITS));
        double symbPoint = MarketInfo(_symb, MODE_POINT);
        // ---
        if (price == 0.0)
        {
                if (type == OP_BUY)
                        price = NormalizeDouble(MarketInfo(_symb, MODE_ASK), symbDigits);
                if (type == OP_SELL)
                        price = NormalizeDouble(MarketInfo(_symb, MODE_BID), symbDigits);
        }
        // ---
        if (sl_value > 0)
        {
                if (type == OP_BUY || type == OP_BUYLIMIT || type == OP_BUYSTOP)
                        return NormalizeDouble(price - sl_value * symbPoint, symbDigits);
                if (type == OP_SELL || type == OP_SELLLIMIT || type == OP_SELLSTOP)
                        return NormalizeDouble(price + sl_value * symbPoint, symbDigits);
        }
        // ---
        return 0.0;
}

// ---
bool close_by_ticket(const int ticket, const int slippage)
{
        /*
         MQL4 | функция закрытия сделки по её номеру (тикету) | ENSED Team
         При закрытии рыночного ордера учитывается уровень максимально допустимого проскальзывания (slipage)
         */
        if (!OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES)) // выбираем ордер по тикету
        {
           return false;
        }
        
        int err = 0;
        
        for (int i = 0; i < 5; i++)
        {
           ResetLastError();
           
                RefreshRates();
                
                double price = 0.0;
                
                if (OrderType() == OP_BUY)
                {
                        price = NormalizeDouble(SymbolInfoDouble(OrderSymbol(), SYMBOL_BID), (int)SymbolInfoInteger(OrderSymbol(), SYMBOL_DIGITS));
                }
                if (OrderType() == OP_SELL)
                {
                        price = NormalizeDouble(SymbolInfoDouble(OrderSymbol(), SYMBOL_ASK), (int)SymbolInfoInteger(OrderSymbol(), SYMBOL_DIGITS));
                }
                                   
           // если рыночный ордер - закрываем его, если отложенный - удаляем
           bool result = false;
           
                if (OrderType() <= OP_SELL) 
                {
                        result = OrderClose(OrderTicket(), OrderLots(), price, slippage * KDig.Get(), clrNONE);
           }
                else
                {
                        result = OrderDelete(OrderTicket());
                }
                
                if (result) // если закрытие или удаление прошло успешно - возвращаем true и выходим из цикла
                {
                        return (true);
                }
                
                err = GetLastError();
                
                if (err != 0)
                {
                        Print("Error of close_by_ticket() #" + (string)err + ": " + Market_Err_To_Str(err)); // если есть ошибка - даём расшифровку её кода в журнал
                }
                
                Sleep(300 * i);
        }
        return (false);
}

// ---
bool cbm(int magic, int slippage, int type)
{
        /*
         close by magic (закрытие всех ордеров данного типа с данным MagicNumber)
         Учитывается максимально допустимое проскальзывание (slipage)
         Используется функция close_by_ticket.
         */
        int n = 0;
        RefreshRates();
        for (int i = OrdersTotal() - 1; i >= 0; i--)
        {
                if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
                        break;
                if ((OrderType() == type) && (OrderMagicNumber() == magic) && (Symbol() == OrderSymbol()))
                {
                        close_by_ticket(OrderTicket(), slippage); // закрываем сделку
                        n++; // наращиваем счётчик закрытых сделок (на самом деле - попыток закрытия)
                }
        }
        if (n > 0) // если попыток закрытия было больше 0, то функция возвращает true
                        return (true);
        return (false);
}

double e_Low()
{
        return Low[0];
}
double e_High()
{
        return High[0];
}
double e_Close()
{
        return Close[0];
}
double e_Open()
{
        return Open[0];
}
 
Сигналы из кода скрыли специально? "чтоб никто не догадался?"

я его слепила из того , что было? 

А почитать? - Как обычно говорят........

 
Vladislav Andruschenko:

А почитать? - Как обычно говорят........

Чего там читать-то??? Почитай это

double e_Low()
{
        return Low[0];
}
double e_High()
{
        return High[0];
}
double e_Close()
{
        return Close[0];
}
double e_Open()
{
        return Open[0];
}
Вспомни ё-мобиль, проведи аналогию к бане... и всё встанет на свои места.
 
Alexey Viktorov:

Чего там читать-то??? Почитай это

Вспомни ё-мобиль, проведи аналогию к бане... и всё встанет на свои места.

А это)

2 строки кода, заменено классом 

// MQL4 | класс автоопределния числа знаков после запятой у текущего инструмента | ENSED Team, http://ensed.org
class CKDig
{
   public:
      CKDig(const bool useAutoDigits)
      {
         Set(useAutoDigits);
      }
      
      ~CKDig(void)
      {
      }
      
      uint Get(void)
      {
         return m_value;
      }
      
   private:      
      uint m_value;      
      
      void Set(const bool useAutoDigits)
      {
         m_value = 1;
         if (!useAutoDigits)
         {
            return;
         }
         
         if (Digits() == 3 || Digits() == 5)
         {
            m_value = 10;
         }
      }
};

CKDig *KDig;
#define K_DIG (KDig.Get())
 
Vitaly Muzichenko:

А это)

2 строки кода, заменено классом 

Спасибо ща попробую. А насчет кода, так тут не помещается. Итак основу оставил где проблемы были. А в сигнале все хорошо

 
Sprut112:

Спасибо ща попробую. А насчет кода, так тут не помещается. Итак основу оставил где проблемы были. А в сигнале все хорошо

Че таа ни .... ваще

Причина обращения: