//+------------------------------------------------------------------+
//|                                               Pos_Expert_v01.mq4 |
//| нач. 02/04/2024                                                  |
//+------------------------------------------------------------------+
#property copyright "Inkov Evgeni"
#property link      "ew123@mail.ru"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
input bool              On_Trade             = true;      // Включить торговлю
input ENUM_TIMEFRAMES   TF_Trade             = PERIOD_H1; // ТФ торговли
input double            Lot                  = 0.01;      // Лот
input string            s1_______________    = "-----------------------------------";//------------------------------------
input int               TP                   = 50;      // TP (в пунктах)
input int               SL                   = 20;      // SL (в пунктах)
input string            s2_______________    = "------ Переменные индикатора ------";//------------------------------------
input int               barn                 = 2000;
input int               Length               = 180;
input bool              SoundAlertMode       = true;
input bool              targets              = true;
input string            s3_______________    = "-----------------------------------";//------------------------------------
input int               Slippage             = 5;      // Проскальзывание
input int               Magic                = 327;    // Магик
//+------------------------------------------------------------------+
string   pref="rs_";
double   min_l, max_l;
double   lot_step;
double   prof_pips;
double   poi;
string   com_err=""; // сюда выводися строка ошибок при открытии ордеров
//....................
int      kol_ord;
int      mas_ord[6];  
bool     find_ind; 
double   pos_0,pos_1;
//+------------------------------------------------------------------+
int OnInit()
{
   find_ind=false;
   
   prof_pips= MarketInfo(Symbol(),MODE_TICKVALUE);
   //.............................................
   lot_step=MarketInfo(Symbol(),MODE_LOTSTEP);
   //.............................................
   poi=Point;
   if(poi==0)poi=1; 
   //..........................
   min_l=MarketInfo(Symbol(),MODE_MINLOT);
   max_l=MarketInfo(Symbol(),MODE_MAXLOT);
   //..........................
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//---------------------------------------------------
void OnTick()
{
   Orders_Total();
   //...................
   int usl_open=check_usl_Buy_Sell();
      // открыть ордер
   if (On_Trade)
   {
      if (usl_open>0 && mas_ord[OP_BUY]==0)
      {
         if (mas_ord[OP_SELL]>0)Close_ord(OP_SELL); // закрыть противоположные
         Open_Buy(Lot);
      }
      else
         if (usl_open<0 && mas_ord[OP_SELL]==0)
         {
            if (mas_ord[OP_BUY]>0)Close_ord(OP_BUY); // закрыть противоположные
            Open_Sell(Lot);
         }
   }
}
//+------------------------------------------------------------------+
double Pos(int i)
{
   double pos=iCustom(NULL,TF_Trade,"Pos_Ind_v01",barn,Length,SoundAlertMode,targets,1,i);
   return(pos);
}
//+------------------------------------------------------------------+
int check_usl_Buy_Sell()
{
   int out=0;
   pos_1=pos_0;
   pos_0=Pos(0);
//   Comment(pos_1," ",pos_0);
   if (pos_1!=pos_0)
      out=(int)pos_0;
   return(out);
}
//---------------------------
double ND(double n)
{
   return(NormalizeDouble(n,Digits));
}
//---------------------------------------------------------------
bool Open_Buy(double l)
{
   double tp=0;
   double sl=0;
   if (TP>0)tp=Ask+TP*poi;
   if (SL>0)sl=Ask-SL*poi;
   int tik=ust_order(Symbol(), OP_BUY, l, ND(Ask), Slippage, sl, tp, "", Magic, clrBlue);
   return(tik>0);
}
//-------------------------------------------
bool Open_Sell(double l)
{
   double tp=0;
   double sl=0;
   if (TP>0)tp=Bid-TP*poi;
   if (SL>0)sl=Bid+SL*poi;
   int tik=ust_order(Symbol(), OP_SELL, l, ND(Bid), Slippage, sl,tp, "", Magic, clrRed);
   return(tik>0);
}
//-------------------------------------------
int ust_order(string sym,int Tip, double lot1, double pr, int slippage, double sl, double tp, string com2, int mag, color col=clrNONE, int dt=0)
{
   double tek_lot=Ogran_max_lot(lot1);
   tek_lot=Ogran_min_lot(tek_lot);
   
   int tik = OrderSend(sym, Tip, tek_lot, pr, slippage, sl, tp, com2, mag, dt, col);
      
   if (tik<0)IsError(tip_str(Tip)+" lot="+DoubleToStr(lot1,2)+" pr="+DoubleToStr(pr,Digits)+" sl="+DoubleToStr(sl,Digits)+" tp="+DoubleToStr(tp,Digits));

   return(tik);
}
//-----------------------------------------------
string tip_str (int tip)
{
   switch(tip)
   {
      case 0: return("Buy");
      case 1: return("Sell");
      case 2: return("BuyLimit");
      case 3: return("SellLimit");
      case 4: return("BuyStop");
      case 5: return("SellStop");
   }
   return("?");
}
//-----------------------------------------------
int IsError(string Whose)  
{
   int ierr = GetLastError(); 
   
   bool result = (ierr > 1);
   if(result)com_err=Whose+ " error = "+ IntegerToString(ierr)+ "; desc = "+ error(ierr);
      
   return(ierr);
}
//-----------------------------------------------
string error(int eer)
{
   string er;
   switch(eer)
   {
      case 0:   break;
      case 1:   er="Нет ошибки, но результат неизвестен";                         break;
      case 2:   er="Общая ошибка";                                                break;
      case 3:   er="Неправильные параметры";                                      break;
      case 4:   er="Торговый сервер занят";                                       break;
      case 5:   er="Старая версия клиентского терминала";                         break;
      case 6:   er="Нет связи с торговым сервером";                               break;
      case 7:   er="Недостаточно прав";                                           break;
      case 8:   er="Слишком частые запросы";                                      break;
      case 9:   er="Недопустимая операция нарушающая функционирование сервера";   break;
      case 64:  er="Счет заблокирован";                                           break;
      case 65:  er="Неправильный номер счета";                                    break;
      case 128: er="Истек срок ожидания совершения сделки";                       break;
      case 129: er="Неправильная цена";                                           break;
      case 130: er="Неправильные стопы";                                          break;
      case 131: er="Неправильный объем";                                          break;
      case 132: er="Рынок закрыт";                                                break;
      case 133: er="Торговля запрещена";                                          break;
      case 134: er="Недостаточно денег для совершения операции";                  break;
      case 135: er="Цена изменилась";                                             break;
      case 136: er="Нет цен";                                                     break;
      case 137: er="Брокер занят";                                                break;
      case 138: er="Новые цены - Реквот";                                         break;
      case 139: er="Ордер заблокирован и уже обрабатывается";                     break;
      case 140: er="Разрешена только покупка";                                    break;
      case 141: er="Слишком много запросов";                                      break;
      case 145: er="Модификация запрещена, так как ордер слишком близок к рынку"; break;
      case 146: er="Подсистема торговли занята";                                  break;
      case 147: er="Использование даты истечения ордера запрещено брокером";      break;
      case 148: er="Количество открытых и отложенных ордеров достигло предела ";  break;
      //---- 
      case 4000: er="Нет ошибки";                                                 break;
      case 4001: er="Неправильный указатель функции";                             break;
      case 4002: er="Индекс массива - вне диапазона";                             break;
      case 4003: er="Нет памяти для стека функций";                               break;
      case 4004: er="Переполнение стека после рекурсивного вызова";               break;
      case 4005: er="На стеке нет памяти для передачи параметров";                break;
      case 4006: er="Нет памяти для строкового параметра";                        break;
      case 4007: er="Нет памяти для временной строки";                            break;
      case 4008: er="Неинициализированная строка";                                break;
      case 4009: er="Неинициализированная строка в массиве";                      break;
      case 4010: er="Нет памяти для строкового массива";                          break;
      case 4011: er="Слишком длинная строка";                                     break;
      case 4012: er="Остаток от деления на ноль";                                 break;
      case 4013: er="Деление на ноль";                                            break;
      case 4014: er="Неизвестная команда";                                        break;
      case 4015: er="Неправильный переход";                                       break;
      case 4016: er="Неинициализированный массив";                                break;
      case 4017: er="Вызовы DLL не разрешены";                                    break;
      case 4018: er="Невозможно загрузить библиотеку";                            break;
      case 4019: er="Невозможно вызвать функцию";                                 break;
      case 4020: er="eВызовы внешних библиотечных функций не разрешены";          break;
      case 4021: er="Недостаточно памяти для строки, возвращаемой из функции";    break;
      case 4022: er="Система занята";                                             break;
      case 4050: er="Неправильное количество параметров функции";                 break;
      case 4051: er="Недопустимое значение параметра функции";                    break;
      case 4052: er="Внутренняя ошибка строковой функции";                        break;
      case 4053: er="Ошибка массива";                                             break;
      case 4054: er="Неправильное использование массива-таймсерии";               break;
      case 4055: er="Ошибка пользовательского индикатора";                        break;
      case 4056: er="Массивы несовместимы";                                       break;
      case 4057: er="Ошибка обработки глобальныех переменных";                    break;
      case 4058: er="Глобальная переменная не обнаружена";                        break;
      case 4059: er="Функция не разрешена в тестовом режиме";                     break;
      case 4060: er="Функция не подтверждена";                                    break;
      case 4061: er="Ошибка отправки почты";                                      break;
      case 4062: er="Ожидается параметр типа string";                             break;
      case 4063: er="Ожидается параметр типа integer";                            break;
      case 4064: er="Ожидается параметр типа double";                             break;
      case 4065: er="В качестве параметра ожидается массив";                      break;
      case 4066: er="Запрошенные исторические данные в состоянии обновления";     break;
      case 4067: er="Ошибка при выполнении торговой операции";                    break;
      case 4099: er="Конец файла";                                                break;
      case 4100: er="Ошибка при работе с файлом";                                 break;
      case 4101: er="Неправильное имя файла";                                     break;
      case 4102: er="Слишком много открытых файлов";                              break;
      case 4103: er="Невозможно открыть файл";                                    break;
      case 4104: er="Несовместимый режим доступа к файлу";                        break;
      case 4105: er="Ни один ордер не выбран";                                    break;
      case 4106: er="Неизвестный символ";                                         break;
      case 4107: er="Неправильный параметр цены для торговой функции";            break;
      case 4108: er="Неверный номер тикета";                                      break;
      case 4109: er="Торговля не разрешена";                                      break;
      case 4110: er="Длинные позиции не разрешены";                               break;
      case 4111: er="Короткие позиции не разрешены";                              break;
      case 4200: er="Объект уже существует";                                      break;
      case 4201: er="Запрошено неизвестное свойство объекта";                     break;
      case 4202: er="Объект не существует";                                       break;
      case 4203: er="Неизвестный тип объекта";                                    break;
      case 4204: er="Нет имени объекта";                                          break;
      case 4205: er="Ошибка координат объекта";                                   break;
      case 4206: er="Не найдено указанное подокно";                               break;
      case 4207: er="Ошибка при работе с объектом";                               break;
      default:   er="Неизвестная ошибка";
   }
   return(er);
}
//------------------------------------
double Ogran_min_lot(double lot1)
{
   if (lot1 < min_l)lot1 = min_l;
   return(lot1);
}
//---------------------------------------------------------------
double Ogran_max_lot(double lot1)
{
   if (lot1 > max_l)lot1 = max_l;
   return(lot1);
}
//---------------------------------------------------------------
void Close_ord(int tip=-1)
{
   bool C,usl=true,CL=false;
   int n=10;
   while (usl && n>0)
   {
      n--;
      usl=false;
      for(int i=0; i<OrdersTotal(); i++)
      {
         if (!Good_ord(i,MODE_TRADES))continue;
         
         if(OrderType()==OP_BUY && (tip==OP_BUY || tip==-1))
         {
            RefreshRates();
            C=OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,clrBlue);
            CL=true;
            usl=true;
         }
         if (OrderType()==OP_SELL && (tip==OP_SELL || tip==-1))
         {
            RefreshRates();
            C=OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,clrRed);
            CL=true;
            usl=true;
         }
      }
   }
   if(CL)Orders_Total();
}
//-----------------------------------------------
bool Good_ord(int i, int mode)
{
   if (OrderSelect(i,SELECT_BY_POS,mode))
      if (OrderSymbol()==Symbol())
         if (OrderMagicNumber()==Magic)return(true);
            
   return(false);
}
//---------------------------------------------------------------
void Orders_Total()
{
   kol_ord=0;
   ArrayInitialize(mas_ord,0);   

   for (int i=0;i<OrdersTotal();i++)
   {
      if (!Good_ord(i,MODE_TRADES))continue;
      
      mas_ord[OrderType()]++;
      kol_ord++;
   }
}
//---------------------
