← К каталогу
Исходный код · ID 3515

sovetnikov_v5.mq4

Похожие материалы по тегам

ea robofibo source v.11.2.mq4MQL4 / MetaTrader 4 · 2 общих теговpro +.pineTradingView · 2 общих теговofada_gold_trader_v230.mq5MQL5 / MetaTrader 5 · 2 общих теговmulti strategy algo combined by enigma mode.pineTradingView · 2 общих теговmacd-osma-on-chart-mtf-v2.mq5MQL5 / MetaTrader 5 · 2 общих теговmelona ob strategy 6th update (by 3dots).pineTradingView · 2 общих тегов
Вы автор или правообладатель?

Сообщите нам, если считаете, что материал размещён без разрешения.

Краткий обзор

О программе

Файл представляет собой библиотеку исходного кода для MetaTrader 4, предоставляющую набор классов и утилит для работы с ордерами, торговлей и управлением состоянием советника. Библиотека включает класс профилирования CSpeed для замера времени выполнения функций, структуру COrderInfo для хранения данных ордеров, основной класс COrders с методами управления открытыми и историческими ордерами, торговыми операциями, виртуализацией стоп-лоссов и тейк-профитов, а также вспомогательные классы для работы с глобальными переменными, рисования на графике, проверки времени торговли и загрузки новостной ленты.

Настройки программы

НастройкаОписание
xMaximum Максимальный шаг — Числовой параметр, используемый как верхний предел шага в макросе PSAR для настройки индикатора Parabolic SAR

Состав библиотеки

Классов: 4 · методов: 73 · конструкторов: 2 · деструкторов: 1 · отдельных функций: 0

Классы
Класс class CSpeed

Класс для профилирования времени выполнения функций в микросекундах

Класс class COrderInfo

Структура для хранения данных ордера

Класс class _global

Простая структура для хранения имени и значения глобальной переменной

Класс class COrders

Основной класс библиотеки для управления ордерами и торговлей

Методы и конструкторы
Конструктор · CSpeed CSpeed()

Конструктор по умолчанию, запускает профилирование с выводом

Конструктор · CSpeed CSpeed(bool bprint)

Конструктор с параметром управления выводом профилей

Деструктор · CSpeed ~CSpeed()

Деструктор класса профилирования

Метод · CSpeed void Start(bool bprint)

Запускает замер времени

Метод · CSpeed void Stop(string sfunc,string sdop)

Останавливает замер и выводит время выполнения функции

Метод · CSpeed void ReStart(string sfunc,string sdop)

Перезапускает замер времени после вывода результата

Метод · COrderInfo double ProfitPoint()

Рассчитывает прибыль ордера в пунктах

Метод · COrderInfo double StepPoint()

Рассчитывает шаг между ценами открытия и текущей в пунктах

Метод · COrderInfo void operator=(const int nil)

Обнуляет все поля структуры

Метод · COrderInfo void operator=(const COrderInfo &a1)

Копирует данные из другой структуры COrderInfo

Метод · COrderInfo bool getOrderByTicket(int iticket,int imode)

Загружает данные ордера по тикету из терминала

Метод · COrders bool CheckMagic(long iMagic,string sComment)

Проверяет совпадение магического числа и комментария ордера

Метод · COrders bool CheckMagic(long iMagic)

Проверяет совпадение магического числа ордера

Метод · COrders bool CheckSymbol(string sName)

Проверяет совпадение имени инструмента

Метод · COrders void OnInit(string n,int iimagic,int iislippage)

Инициализация класса с параметрами инструмента, магика и проскальзывания

Метод · COrders void OnTick()

Обработчик тика, обновляет данные ордеров

Метод · COrders void OnTimer()

Обработчик таймера

Метод · COrders void OnDeinit(const int reason)

Обработчик деинициализации

Метод · COrders bool Save(const int handle)

Сохраняет состояние в файл

Метод · COrders bool Load(const int handle)

Загружает состояние из файла

Метод · COrders void IniFileSave(void)

Сохраняет данные в INI-файл

Метод · COrders void IniFileLoad(void)

Загружает данные из INI-файла

Метод · COrders string IniFileExt(void)

Возвращает расширение INI-файла

Метод · COrders string IniFileName(void)

Возвращает имя INI-файла

Метод · COrders void virtual_OrdersToVirtual()

Переносит стоп-лосс и тейк-профит ордеров в виртуальный режим

Метод · COrders bool checkOrderIndex(int iindex)

Проверяет допустимость индекса в массиве открытых ордеров

Метод · COrders bool checkHistoryOrderIndex(int iindex)

Проверяет допустимость индекса в массиве исторических ордеров

Метод · COrders string OrderSymbol(int iindex)

Возвращает символ ордера по индексу

Метод · COrders string OrderComment(int iindex)

Возвращает комментарий ордера по индексу

Метод · COrders int OrdersTotal()

Возвращает количество открытых ордеров

Метод · COrders int OrderTicket(int iindex)

Возвращает тикет ордера по индексу

Метод · COrders int OrderType(int iindex)

Возвращает тип ордера по индексу

Метод · COrders int OrderMagicNumber(int iindex)

Возвращает магический номер ордера по индексу

Метод · COrders datetime OrderOpenTime(int iindex)

Возвращает время открытия ордера по индексу

Метод · COrders datetime OrderCloseTime(int iindex)

Возвращает время закрытия ордера по индексу

Метод · COrders datetime OrderExpiration(int iindex)

Возвращает время истечения ордера по индексу

Метод · COrders double OrderOpenPrice(int iindex)

Возвращает цену открытия ордера по индексу

Метод · COrders double OrderClosePrice(int iindex)

Возвращает цену закрытия ордера по индексу

Метод · COrders double OrderLots(int iindex)

Возвращает объём ордера по индексу

Метод · COrders double OrderProfit(int iindex)

Возвращает прибыль ордера по индексу

Метод · COrders double Profit(int iindex)

Возвращает суммарную прибыль ордера по индексу

Метод · COrders double OrderProfitPoint(int iindex)

Возвращает прибыль в пунктах ордера по индексу

Метод · COrders double OrderStep(int iindex)

Возвращает шаг ордера по индексу

Метод · COrders double OrderSwap(int iindex)

Возвращает своп ордера по индексу

Метод · COrders double OrderCommission(int iindex)

Возвращает комиссию ордера по индексу

Метод · COrders double OrderStopLoss(int iindex)

Возвращает стоп-лосс ордера по индексу

Метод · COrders double OrderTakeProfit(int iindex)

Возвращает тейк-профит ордера по индексу

Метод · COrders string HistoryOrderSymbol(int iindex)

Возвращает символ исторического ордера по индексу

Метод · COrders string HistoryOrderComment(int iindex)

Возвращает комментарий исторического ордера по индексу

Метод · COrders int OrdersHistoryTotal()

Возвращает количество исторических ордеров

Метод · COrders int HistoryOrdersTotal()

Возвращает количество исторических ордеров

Метод · COrders int HistoryOrderTicket(int iindex)

Возвращает тикет исторического ордера по индексу

Метод · COrders int HistoryOrderType(int iindex)

Возвращает тип исторического ордера по индексу

Метод · COrders int HistoryOrderMagicNumber(int iindex)

Возвращает магический номер исторического ордера по индексу

Метод · COrders datetime HistoryOrderOpenTime(int iindex)

Возвращает время открытия исторического ордера по индексу

Метод · COrders datetime HistoryOrderCloseTime(int iindex)

Возвращает время закрытия исторического ордера по индексу

Метод · COrders datetime HistoryOrderExpiration(int iindex)

Возвращает время истечения исторического ордера по индексу

Метод · COrders double HistoryOrderOpenPrice(int iindex)

Возвращает цену открытия исторического ордера по индексу

Метод · COrders double HistoryOrderClosePrice(int iindex)

Возвращает цену закрытия исторического ордера по индексу

Метод · COrders double HistoryOrderLots(int iindex)

Возвращает объём исторического ордера по индексу

Метод · COrders double HistoryOrderProfit(int iindex)

Возвращает прибыль исторического ордера по индексу

Метод · COrders double HistoryProfit(int iindex)

Возвращает суммарную прибыль исторического ордера по индексу

Метод · COrders bool HistoryIsTP(int iindex)

Проверяет, был ли ордер закрыт по тейк-профиту

Метод · COrders bool HistoryIsSL(int iindex)

Проверяет, был ли ордер закрыт по стоп-лоссу

Метод · COrders double HistoryOrderProfitPoint(int iindex)

Возвращает прибыль в пунктах исторического ордера по индексу

Метод · COrders double HistoryOrderStep(int iindex)

Возвращает шаг исторического ордера по индексу

Метод · COrders double HistoryOrderSwap(int iindex)

Возвращает своп исторического ордера по индексу

Метод · COrders double HistoryOrderCommission(int iindex)

Возвращает комиссию исторического ордера по индексу

Метод · COrders double HistoryOrderStopLoss(int iindex)

Возвращает стоп-лосс исторического ордера по индексу

Метод · COrders double HistoryOrderTakeProfit(int iindex)

Возвращает тейк-профит исторического ордера по индексу

Метод · COrders void virtual_VirtualToOrders(string name,int iimagic)

Восстанавливает виртуальные стоп-лосс и тейк-профит для ордеров по имени и магику

Метод · COrders void virtual_VirtualToOrders()

Восстанавливает виртуальные стоп-лосс и тейк-профит для ордеров

Метод · COrders bool virtual_valid(int iticket)

Проверяет существование и открытость ордера по тикету

Метод · COrders void virtual_deinit()

Очищает виртуальные данные ордеров

Метод · COrders int GlobalCopy(_global &dest[],_global &src[])

Копирует массив глобальных переменных

Метод · COrders int TesterFindIndexGlobal(string name)

Находит индекс глобальной переменной в тестере по имени

Получить полный код

Поиск по коду файла

/*

данный файл содержит основные рабочие классы для мт4 600+
*/

#property version   "3.00"
#property strict

#ifndef __CMAIN__ 
#define __CMAIN__ sovetnikov_net_23424dsfsdf23433324fdfdgg   

#include <../Include/Controls/Button.mqh>
#include <../Include/Controls/Label.mqh>

#define CONTROLS_BUTTON_WIDTH CONTROLS_BUTTON_SIZE*5
#define __COPYRIGHT__ string scopyright="Copyright 2007-, Gavrilin Alexander Victorovich (";

#define  __DEBUG__ true

#define LINE   IntegerToString(__LINE__)
#define ND2(x) NormalizeDouble(x,2)
#define ND1(x) NormalizeDouble(x,1)

#define SIGNAL_BAR(y) input ENUM_SIGNAL_BAR signal_bar=y

#define I(x) input int x
#define B(x) input bool x
#define TF(x) input ENUM_TIMEFRAMES x
#define D(x) input double x
#define S(x) input string x
#define METHOD(x) input ENUM_MA_METHOD x
#define PRICE(x) input ENUM_APPLIED_PRICE x
#define C(x) input color x
#define SOUND(x) input ENUM_SOUND_WAV x

#define MA(eTF,xPeriod,xShift,eMethod,ePrice) \
input ENUM_TIMEFRAMES eTF;\
input int xPeriod;\
input int xShift;\
input ENUM_MA_METHOD eMethod;\
input ENUM_APPLIED_PRICE ePrice

#define MA2(xPeriod,xShift,eMethod,ePrice) \
input int xPeriod;\
input int xShift;\
input ENUM_MA_METHOD eMethod;\
input ENUM_APPLIED_PRICE ePrice

#define OSMA(eTF,xFastPeriod,xSlowPeriod,xSignalPeriod,ePrice) \
input ENUM_TIMEFRAMES eTF;\
input int xFastPeriod;\
input int xSlowPeriod;\
input int xSignalPeriod;\
input ENUM_APPLIED_PRICE ePrice

#define OSMA2(xFastPeriod,xSlowPeriod,xSignalPeriod,ePrice) \
input int xFastPeriod;\
input int xSlowPeriod;\
input int xSignalPeriod;\
input ENUM_APPLIED_PRICE ePrice

#define CCI(eTF,xPeriod,ePrice) \
input ENUM_TIMEFRAMES eTF;\
input int xPeriod;\
input ENUM_APPLIED_PRICE ePrice

#define CCI2(xPeriod,ePrice) \
input int xPeriod;\
input ENUM_APPLIED_PRICE ePrice

#define STOCH(eTF,xKPeriod,xDPeriod,xSlowing,eMethod,ePrice) \
 input ENUM_TIMEFRAMES eTF;\
input int xKPeriod;\
input int xDPeriod;\
input int xSlowing;\
input ENUM_MA_METHOD eMethod;\
input ENUM_STO_PRICE ePrice

#define MACD(eTF,xFast,xSlow,xSignal,ePrice) input ENUM_TIMEFRAMES eTF;\
input int xFast;\
input int xSlow;\
input int xSignal;\
input ENUM_APPLIED_PRICE ePrice

#define PSAR(eTF,xStep,xMaximum) input ENUM_TIMEFRAMES eTF;\
input double xStep;\
input double xMaximum;

#define PSAR2(xStep,xMaximum) input double xStep;\
input double xMaximum;

#define MACRO_STATIC(nsymbol,bBool,etf) static datetime tm_##bBool=0;\
static bool bBool=false;\
datetime tm0_##bBool=iTime(nsymbol,etf,0);\
if(tm_##bBool==0 || tm0_##bBool!=tm_##bBool) bBool=true;\
tm_##bBool=tm0_##bBool

           #define MACRO_DOUBLE(dvalue) static double dvalue=0
           #define MACRO_DOUBLE2(dvalue) static double dvalue[2]={0}

           #define MACRO_START CSpeed s1(true)
           #define MACRO_STOP s1.Stop(__FUNCTION__,IntegerToString(__LINE__))
           /*tf*/

enum ENUM_TF
  {
   OFF=-1,
   CURRENT=PERIOD_CURRENT,
   M1=PERIOD_M1,
   M5=PERIOD_M5,
   M15=PERIOD_M15,
   M30=PERIOD_M30,
   H1=PERIOD_H1,
   H4=PERIOD_H4,
   D1=PERIOD_D1,
   W1=PERIOD_W1,
   MN1=PERIOD_MN1
  };

/*новые константы для типов ордеров*/
enum _TYPES
  {
   BUY=10,
   SELL=21,
   BUYLIMIT=32,
   SELLLIMIT=64,
   BUYSTOP=128,
   SELLSTOP=256,
   ALL=-1
  };

enum ENUM_SIGNAL_BAR
  {
   SIGNAL_BAR_CURRENT=0,//Every Tick
   SIGNAL_BAR_OPEN=1 //Open Bar
  };

enum _ORDER_MODE
  {
   ORDER_UP=1,
   ORDER_DN=2
  };

enum ENUM_SORT
  {
   ENUM_MODE_ASCEND=MODE_ASCEND,
   ENUM_MODE_DESCEND=MODE_DESCEND
  };

enum _trademode
  {
   LongOnly,//Long Only
   ShortOnly,//Short Only
   LongAndShort //Long and Short
  };

enum ENUM_OKRUGLENIE
  {
   Floor,
   Ceil,
   Round
  };

int toMyTypes(int def_type)
  {
   if(def_type>5) return (-1);
   int new_type[6]={BUY,SELL,BUYLIMIT,SELLLIMIT,BUYSTOP,SELLSTOP};
   return (new_type[def_type]);
  }

void Test(){}

int toDefType(int my_type,int def_type)
  {

   switch(def_type)
     {
      case 0:  return (OP_BUY);
      case 1:  return (OP_SELL);
      case 2:  return (OP_BUYLIMIT);
      case 3:  return (OP_SELLLIMIT);
      case 4:  return (OP_BUYSTOP);
      case 5:  return (OP_SELLSTOP);
     }

   switch(my_type)
     {

      case BUY: return (OP_BUY);
      case SELL: return (OP_SELL);
      case BUYLIMIT: return (OP_BUYLIMIT);
      case SELLLIMIT: return (OP_SELLLIMIT);
      case BUYSTOP: return (OP_BUYSTOP);
      case SELLSTOP: return (OP_SELLSTOP);
     }
   return(-1); //invalid
  }

enum ENUM_SOUND_WAV
  {
   ealert,//alert.wav
   ealert2,//alert2.wav
   econnect,//connect.wav
   edisconnect,//disconnect.wav
   eemail,//*********
   eexpert,//expert.wav
   enews,//news.wav
   eok,//ok.wav
   estops,//stops.wav
   etick,//tick.wav
   etimeout,//timeout.wav
   ewait,//wait.wav
   euser_file//use file
  };

string getSoundFile(ENUM_SOUND_WAV ewav,string suser_file)
  {

   switch(ewav)
     {
      case ealert: return "alert.wav";
      case ealert2: return "alert2.wav";
      case econnect: return "connect.wav";
      case edisconnect: return "disconnect.wav";
      case eemail: return "*********";
      case eexpert: return "expert.wav";
      case enews: return "news.wav";
      case eok: return "ok.wav";
      case estops: return "stops.wav";
      case etick: return "tick.wav";
      case etimeout: return "timeout.wav";
      case ewait: return "wait.wav";
      case euser_file: return suser_file;
     };

   return "";
  }

class CSpeed
  {
protected:
   ulong             utimer;
   bool              bPrint;
public:

                     CSpeed()
     {
      Start(true);
     }

                     CSpeed(bool bprint)
     {
      Start(bprint);
     }

                    ~CSpeed()
     {
     }

   void Start(bool bprint)
     {
      bPrint=bprint;
      if(bPrint)utimer=GetMicrosecondCount();
     }

   void Stop(string sfunc,string sdop="")
     {
      if(!bPrint) return;  //выключено

      ulong msec=GetMicrosecondCount()-utimer;
      PrintFormat("CSpeed(%s): %s - %d microsec",sdop,sfunc,msec);
     }

   void ReStart(string sfunc,string sdop="")
     {
      if(!bPrint) return;  //выключено

      ulong msec=GetMicrosecondCount()-utimer;
      PrintFormat("CSpeed(%s): %s - %d microsec",sdop,sfunc,msec);
      utimer=GetMicrosecondCount();
     }
  };

class COrderInfo
  {
public:
   string            OrderSymbol;
   string            OrderComment;
   int               OrderTicket;
   int               OrderType;
   int               OrderMagicNumber;
   datetime          OrderOpenTime;
   datetime          OrderCloseTime;
   datetime          OrderExpiration;
   double            OrderOpenPrice;
   double            OrderClosePrice;
   double            OrderLots;
   double            OrderProfit;
   double            Profit; //суммарный профит
   double            OrderProfitPoint; //профит убыток в пунктах, если оредер будет закрыт
   double            OrderStep; //считаем шаг между ордерами, без учета их закрытия (для бай между аск, для селл между бид)
   double            OrderSwap;
   double            OrderCommission;
   double            OrderStopLoss;
   double            OrderTakeProfit;

   double ProfitPoint() //ордер должен быть выбран!
     {
      double dpp=point(OrderSymbol);
      if(dpp==0.0) return 0;

      if(OrderCloseTime==0.0 && OrderType<2)
        {

         if(OrderType==OP_BUY) return ND1((Bid(OrderSymbol)-OrderOpenPrice)/dpp);
         if(OrderType==OP_SELL) return ND1((OrderOpenPrice-Ask(OrderSymbol))/dpp);
        }

      if(OrderCloseTime!=0.0 && OrderType<2)
        {
         if(OrderType==OP_BUY) return ND1((OrderClosePrice-OrderOpenPrice)/dpp);
         if(OrderType==OP_SELL) return ND1((OrderOpenPrice-OrderClosePrice)/dpp);
        }

      return 0;
     }

   double StepPoint() //ордер должен быть выбран!
     {
      double dpp=point(OrderSymbol);
      if(dpp==0.0) return 0;

      if(OrderCloseTime==0.0 && OrderType<2)
        {
         if(OrderType==OP_BUY) return (NormalizeDouble((MarketInfo(OrderSymbol,MODE_ASK)-OrderOpenPrice)/dpp,1));
         if(OrderType==OP_SELL) return (NormalizeDouble((OrderOpenPrice-MarketInfo(OrderSymbol,MODE_BID))/dpp,1));
        }

      if(OrderCloseTime!=0.0 && OrderType<2)
        {
         if(OrderType==OP_BUY) return (NormalizeDouble((OrderClosePrice-OrderOpenPrice)/dpp,1));
         if(OrderType==OP_SELL) return (NormalizeDouble((OrderOpenPrice-OrderClosePrice)/dpp,1));
        }

      return 0;
     }

   void operator=(const int nil=NULL) //нулевая инициализация переменных
     {
      OrderSymbol="";
      OrderComment="";
      OrderTicket=0;
      OrderType=-1;
      OrderMagicNumber=0;
      OrderOpenTime=0;
      OrderCloseTime=0;
      OrderExpiration=0;
      OrderOpenPrice=0;
      OrderClosePrice=0;
      OrderLots=0;
      OrderProfit=0;
      Profit=0;
      OrderProfitPoint=0;
      OrderStep=0;
      OrderSwap=0;
      OrderCommission=0;
      OrderStopLoss=0;
      OrderTakeProfit=0;
     }

   void operator=(const COrderInfo &a1)//простое копирование
     {
      OrderSymbol=a1.OrderSymbol;
      OrderComment=a1.OrderComment;
      OrderTicket=a1.OrderTicket;
      OrderType=a1.OrderType;
      OrderMagicNumber=a1.OrderMagicNumber;
      OrderOpenTime=a1.OrderOpenTime;
      OrderCloseTime=a1.OrderCloseTime;
      OrderExpiration=a1.OrderExpiration;
      OrderOpenPrice=a1.OrderOpenPrice;
      OrderClosePrice=a1.OrderClosePrice;
      OrderLots=a1.OrderLots;
      OrderProfit=a1.OrderProfit;
      Profit=a1.Profit;
      OrderProfitPoint=a1.OrderProfitPoint;
      OrderStep=a1.OrderStep;
      OrderSwap=a1.OrderSwap;
      OrderCommission=a1.OrderCommission;
      OrderStopLoss=a1.OrderStopLoss;
      OrderTakeProfit=a1.OrderTakeProfit;
     }

   bool getOrderByTicket(int iticket,int imode=MODE_TRADES)
     {
      if(OrderTicket()!=iticket)
        {
         if(!OrderSelect(iticket,SELECT_BY_TICKET,imode)) return false;
        }

      if(iticket<=0) return false;

      OrderSymbol=OrderSymbol();
      OrderComment=OrderComment();
      OrderTicket=OrderTicket();
      OrderType=OrderType();
      OrderMagicNumber=OrderMagicNumber();
      OrderOpenTime=OrderOpenTime();
      OrderCloseTime=OrderCloseTime();
      OrderExpiration=OrderExpiration();
      OrderOpenPrice=OrderOpenPrice();
      OrderClosePrice=OrderClosePrice();
      OrderLots=OrderLots();
      OrderProfit=OrderProfit();
      OrderProfitPoint=ProfitPoint();

      OrderStep=StepPoint();
      OrderSwap=OrderSwap();
      OrderCommission=OrderCommission();
      OrderStopLoss=OrderStopLoss();
      OrderTakeProfit=OrderTakeProfit();
      Profit=OrderProfit+OrderSwap+OrderCommission;

      return true;
     }

  };

void SortOrdersByOrderOpenPrice(COrderInfo &a[],ENUM_SORT idirection=ENUM_MODE_ASCEND)
  {
   int i=0,j=0;
   COrderInfo x;

   int size=ArraySize(a);

   for(i=0;i<size;i++)
     {
      for(j=size-1;j>i;j--)
        {
         if(idirection==MODE_ASCEND && a[j-1].OrderOpenPrice>a[j].OrderOpenPrice)
           {
            x=a[j-1];
            a[j-1]=a[j];
            a[j]=x;
           }

         if(idirection==MODE_DESCEND && a[j-1].OrderOpenPrice<a[j].OrderOpenPrice)
           {
            x=a[j-1];
            a[j-1]=a[j];
            a[j]=x;
           }
        }
     }
  }

void SortOrdersByOrderOpenTime(COrderInfo &a[],ENUM_SORT idirection=ENUM_MODE_ASCEND)
  {
   int i=0,j=0;
   COrderInfo x;

   int size=ArraySize(a);

   for(i=0;i<size;i++)
     {
      for(j=size-1;j>i;j--)
        {
         if(idirection==MODE_ASCEND && a[j-1].OrderOpenTime>a[j].OrderOpenTime)
           {
            x=a[j-1];
            a[j-1]=a[j];
            a[j]=x;
           }

         if(idirection==MODE_DESCEND && a[j-1].OrderOpenTime<a[j].OrderOpenTime)
           {
            x=a[j-1];
            a[j-1]=a[j];
            a[j]=x;
           }
        }
     }
  }

struct _global
  {
   string            name;
   double            data;
  };

/*основной класс для торговли и управления ордерами*/
class COrders
  {
public:
   _global           m_global[];
   string            m_name; //название инстурмента, переменные делаем доступными, чтобы при желании можно было быстро изменить их
   long              m_imagic; //меджик  
   int               m_islippage; //проскальзывание

   double            stoplevel; //стоп уровень брокера по инструменту
   int               m_total; //общее кол-во открытых ордеров в терминале
   int               m_all; //кол-во открытых ордеров
   int               m_historyall;
   double            p; //пункт с учетом разрядности
   double            dp; //соотношение пунктов, для пересчета 5 знака в 4х. (вспомогательная функция)
   int               ierrors; //ошибки будут храниться в этой переменной

   COrderInfo        m_orders[],m_historyorders[];

   int               orders[10]; //счетчики кол-ва ордеров разного типа
   int               trades[10]; //счетчики кол-ва открытых на текущем баре
   int               history[10]; //счетчики кол-ва закрытых на текущем баре 

   bool              IsTester; //тестер или оптимизатор?
   int               options_iMaxLoadDays;
   int               options_iRestartCount; //счетчик кол-ва запросов
   int               options_iTimeout; //пауза при неудачных запросах
   bool              options_bVirtual; //виртуализация
   bool              options_bNoModify; //не модифицировать стоп и тейк полностью виртуальные
   bool              options_bNoCheckPending; //не проверять отложки на нехватку маржи
   bool              options_bCheckFreeMargin; //проверка маржи перед открытием ордера
   bool              options_bSupportMaxLot; //поддержка превышения максимального лота

   virtual bool CheckMagic(long iMagic,string sComment)
     {
      return CheckMagic(iMagic);
     }

   virtual bool CheckMagic(long iMagic)
     {
      return (iMagic==m_imagic || m_imagic==-1);
     }

   virtual bool CheckSymbol(string sName)
     {
      return (sName==m_name || m_name==NULL);
     }

   virtual void  OnInit(string n,int iimagic,int iislippage)
     {
      // код доступен только после оплаты
   }

   virtual void OnTick()
     {
      // код доступен только после оплаты
   } //нужно переписать в наследуемом классе 

   virtual void OnTimer(){ } //нужно переписать в наследуемом классе если испольузем таймеры

   virtual void  OnDeinit(const int reason=0)
     {
      virtual_deinit(); //вирутуальные функции контроля

     }

   virtual bool Save(const int handle){ Print(__FUNCSIG__); return true;}
   virtual bool Load(const int handle){ Print(__FUNCSIG__); return true;}

   virtual void IniFileSave(void)
     {
      string filename=IniFileName()+IniFileExt();
      int handle=FileOpen(filename,FILE_WRITE|FILE_BIN|FILE_ANSI);

      if(handle!=INVALID_HANDLE)
        {
         Save(handle);
         FileClose(handle);
        }
     }

   virtual void IniFileLoad(void)
     {
      string filename=IniFileName()+IniFileExt();
      int handle=FileOpen(filename,FILE_READ|FILE_BIN|FILE_ANSI);

      if(handle!=INVALID_HANDLE)
        {
         Load(handle);
         FileClose(handle);
        }
     }

   virtual string    IniFileExt(void) const { return(".dat"); }

   virtual string IniFileName(void) const
     {
      string name;

      name=WindowExpertName();
      name+="_"+Symbol();
      name+="_"+IntegerToString(m_imagic);
      name+="_Ini";

      return(name);
     }

   void virtual_OrdersToVirtual()
     {

      for(int i=ArraySize(m_orders)-1;i>=0;i--)
        {
         if(m_orders[i].OrderCloseTime>0) continue;

         if(CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) && CheckSymbol(m_orders[i].OrderSymbol))
           {

            virtual_set(m_orders[i].OrderTicket,m_orders[i].OrderStopLoss,m_orders[i].OrderTakeProfit);

            OrderModify(m_orders[i].OrderTicket,m_orders[i].OrderOpenPrice,0,0,-1,clrNONE);

           }
        }
     }

   bool checkOrderIndex(int iindex)
     {
      if(iindex<0) return false;
      int isize=ArraySize(m_orders);
      if(iindex>=isize) return false;

      return true; //valid
     }

   bool checkHistoryOrderIndex(int iindex)
     {
      if(iindex<0) return false;
      int isize=ArraySize(m_historyorders);
      if(iindex>=isize) return false;

      return true; //valid
     }

   string            OrderSymbol(int iindex) { if(!checkOrderIndex(iindex)) return ""; return m_orders[iindex].OrderSymbol; }
   string            OrderComment(int iindex) { if(!checkOrderIndex(iindex)) return ""; return m_orders[iindex].OrderComment; }
   int               OrdersTotal()
     {
      if(ArraySize(m_orders)==0) Update();
      return ArraySize(m_orders);
     }
   int               OrderTicket(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderTicket; }
   int               OrderType(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderType; }
   int               OrderMagicNumber(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderMagicNumber; }
   datetime          OrderOpenTime(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderOpenTime; }
   datetime          OrderCloseTime(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderCloseTime; }
   datetime          OrderExpiration(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderExpiration; }
   double            OrderOpenPrice(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderOpenPrice; }
   double            OrderClosePrice(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderClosePrice; }
   double            OrderLots(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderLots; }
   double            OrderProfit(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderProfit; }
   double            Profit(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].Profit; }
   double            OrderProfitPoint(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderProfitPoint; }
   double            OrderStep(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderStep; }
   double            OrderSwap(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderSwap; }
   double            OrderCommission(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderCommission; }
   double            OrderStopLoss(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderStopLoss; }
   double            OrderTakeProfit(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderTakeProfit; }

   string            HistoryOrderSymbol(int iindex) { if(!checkHistoryOrderIndex(iindex)) return ""; return m_historyorders[iindex].OrderSymbol; }
   string            HistoryOrderComment(int iindex) { if(!checkHistoryOrderIndex(iindex)) return ""; return m_historyorders[iindex].OrderComment; }
   int               OrdersHistoryTotal() { if(ArraySize(m_historyorders)==0) UpdateHistory(); return ArraySize(m_historyorders); }
   int               HistoryOrdersTotal() { if(ArraySize(m_historyorders)==0) UpdateHistory(); return ArraySize(m_historyorders); }
   int               HistoryOrderTicket(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderTicket; }
   int               HistoryOrderType(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderType; }
   int               HistoryOrderMagicNumber(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderMagicNumber; }
   datetime          HistoryOrderOpenTime(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderOpenTime; }
   datetime          HistoryOrderCloseTime(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderCloseTime; }
   datetime          HistoryOrderExpiration(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderExpiration; }
   double            HistoryOrderOpenPrice(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderOpenPrice; }
   double            HistoryOrderClosePrice(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderClosePrice; }
   double            HistoryOrderLots(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderLots; }
   double            HistoryOrderProfit(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderProfit; }
   double            HistoryProfit(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].Profit; }
   bool              HistoryIsTP(int iindex)
     {
      if(!checkHistoryOrderIndex(iindex)) return false;

      if(StringFind(HistoryOrderComment(iindex),"[tp]")>=0 || HistoryOrderClosePrice(iindex)==HistoryOrderTakeProfit(iindex))
        {

         return true;
        }

      return false;
     }
   bool              HistoryIsSL(int iindex)
     {
      if(!checkHistoryOrderIndex(iindex)) return false;

      if(StringFind(HistoryOrderComment(iindex),"[sl]")>=0 || HistoryOrderClosePrice(iindex)==HistoryOrderStopLoss(iindex))
        {

         return true;
        }

      return false;
     }     
   double            HistoryOrderProfitPoint(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderProfitPoint; }
   double            HistoryOrderStep(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderStep; }
   double            HistoryOrderSwap(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderSwap; }
   double            HistoryOrderCommission(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderCommission; }
   double            HistoryOrderStopLoss(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderStopLoss; }
   double            HistoryOrderTakeProfit(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderTakeProfit; }

   void virtual_VirtualToOrders(string name,int iimagic)
     {
      for(int i=ArraySize(m_orders)-1;i>=0;i--)
        {
         if(m_orders[i].OrderStopLoss==0.0 && m_orders[i].OrderTakeProfit==0.0 && virtual_check(m_orders[i].OrderTicket))
           {
            OrderModify(m_orders[i].OrderTicket,-1,virtual_get_sl(m_orders[i].OrderTicket),virtual_get_tp(m_orders[i].OrderTicket),0,clrNONE);
           }
        }
     }

   void virtual_VirtualToOrders()
     {
      for(int i=ArraySize(m_orders)-1;i>=0;i--)
        {
         if(m_orders[i].OrderCloseTime>0) continue;

         if(!CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) || !CheckSymbol(m_orders[i].OrderSymbol)) continue;

         if(m_orders[i].OrderStopLoss==0.0 && m_orders[i].OrderTakeProfit==0.0 && virtual_check(m_orders[i].OrderTicket))
           {
            OrderModify(m_orders[i].OrderTicket,-1,virtual_get_sl(m_orders[i].OrderTicket),virtual_get_tp(m_orders[i].OrderTicket),0,clrNONE);
           }
        }
     }

   bool virtual_valid(int iticket)
     {
      if(!OrderSelect(iticket,SELECT_BY_TICKET)) return (false);
      if(OrderCloseTime()==0) return (true);
      return (false);
     }

   void virtual_deinit()
     {
      if(IsTester)
        {
         GVariable::Delete("virtual");
         ArrayResize(m_global,0); //очистим переменную глобальных перменных)
        }
     }

   int GlobalCopy(_global &dest[],_global &src[])
     {
      int isize=ArraySize(src);
      if(ArrayResize(dest,isize)!=-1)
        {
         for(int i=0;i<isize;i++)
           {
            dest[i].data=src[i].data;
            dest[i].name=src[i].name;
           }

         return isize;
        }

      return 0;
     }

   int TesterFindIndexGlobal(string name)
     {
      if(IsTester)
        {
         int isize=ArraySize(m_global);

         for(int i=isize-1;i>=0;i--)
           {
            if(StringCompare(m_global[i].name,name,false)==0) return i; //найдем индекс   
           }
        }

      return -1;
     }
   int GlobalVariablesTotal()
     {

      if(IsTester)
        {

         return ArraySize(m_global);

        }

      return ::GlobalVariablesTotal();
     }

   string GlobalVariableName(int index)
     {

      if(IsTester)
        {
         int isize=ArraySize(m_global);
         if(index<0 || index>=isize) return "";

         return m_global[index].name;
        }

      return ::GlobalVariableName(index);
     }

   double GlobalVariableGet(string name)
     {

      if(IsTester)
        {
         int index=TesterFindIndexGlobal(name);

         if(index==-1)
           {

            return 0;
           }

         return m_global[index].data;
        }

      return ::GlobalVariableGet(name);
     }

   datetime GlobalVariableSet(string name,double value)
     {

      if(IsTester)
        {

         int index=TesterFindIndexGlobal(name);

         if(index!=-1)
           {
            m_global[index].data=value;
           }
         else
         if(index==-1 && value!=0 && name!="")
           {
            int isize=ArraySize(m_global);

            if(ArrayResize(m_global,isize+1)!=-1)
              {

               m_global[isize].name=name;
               m_global[isize].data=value;
              }
            else
              {
               return 0; //ошибка
              }
           }

         return TimeCurrent();
        }

      return ::GlobalVariableSet(name,value);
     }

   bool GlobalVariableCheck(string name)
     {

      if(IsTester)
        {
         int index=TesterFindIndexGlobal(name);
         if(index==-1) return false;
         return true;
        }

      return ::GlobalVariableCheck(name);
     }

   bool GlobalVariableDel(string name)
     {

      if(IsTester)
        {
         int index=TesterFindIndexGlobal(name);
         if(index==-1)
           {

            return false;
           }

         _global newglobal[];
         int inewsize=0;
         int isize=ArraySize(m_global);

         if(GlobalCopy(newglobal,m_global)>0)
           {

            isize=0;
            ArrayResize(m_global,0); //переформируем структуру

            inewsize=ArraySize(newglobal);

            for(int i=0;i<inewsize;i++)
              {
               if(newglobal[i].name!=name)
                 {

                  if(ArrayResize(m_global,isize+1)!=-1)
                    {
                     m_global[isize].name=newglobal[i].name;
                     m_global[isize].data=newglobal[i].data;
                     isize++;
                    }
                 }

              }

            return true;
           }

         return false;
        }

      return (bool)::GlobalVariableDel(name);
     }

   virtual void virtual_init()
     {

      if(!options_bVirtual) return; //если виртуализация выключена, то не проверяем 

      string del[],sglobal="",param[],n;
      int icount=0,i,itype=-1,isizeParam;
      ArrayResize(del,0);

      int isize=GlobalVariablesTotal();

      for(i=isize-1;i>=0;i--)
        {
         sglobal=GlobalVariableName(i);

         if(sglobal=="" || sglobal==NULL) continue;
         if(StringFind(sglobal,"_sl")<0 && StringFind(sglobal,"_tp")<0) continue; //пропустим не наши

         if(GlobalVariableGet(sglobal)==0) //все нулевые удалим
           {
            ArrayResize(del,icount+1);
            del[icount]=sglobal;
            icount++;
            continue;
           }

         string_explode("_",sglobal,param);

         isizeParam=ArraySize(param);

         if(isizeParam<2 && isizeParam>3) continue; //пропустим сразу неподходящие под наши правила 

         if((isizeParam==2 && StringToInteger(param[0])>0) || (isizeParam==3 && param[0]=="virtual" && StringToInteger(param[1])>0))
           {
            int iticket=(int)StringToInteger(param[0]);//тикет
            if(isizeParam==3)
              {
               iticket=(int)StringToInteger(param[1]);//тикет
              }

            if(!OrderSelect(iticket))
              {
               continue;
              }

            itype=OrderType();
            if(itype>=2 || OrderCloseTime()>0) //отложки тоже подчистим и уже закрытых ордеров тоже
              {
               ArrayResize(del,icount+1);
               del[icount]=sglobal;
               icount++;

               continue; //next order
              }

            n=OrderSymbol();

            if(CheckMagic(OrderMagicNumber(),OrderComment()) && CheckSymbol(n))
              {
               double pt=0;
               double dtp=0;
               double dsl=0;

               dtp=virtual_get_tp(iticket);
               dsl=virtual_get_sl(iticket);

               if(dtp!=0 || dsl!=0)
                 {
                  RefreshRates();
                 }

               if(dtp==0 && dsl==0) continue;

               double _Ask=Ask(n);
               double _Bid=Bid(n);

               if(dtp!=0 && ((_Bid>=dtp && itype==OP_BUY) || (_Ask<=dtp && itype==OP_SELL)))
                 {
                  if(OrderClose(iticket,-1))
                    {

                     ArrayResize(del,icount+1);
                     del[icount]=sglobal;
                     icount++;
                     m_total--;
                    }
                 }//close by dtp

               if(dsl!=0 && ((_Bid<=dsl && itype==OP_BUY) || (_Ask>=dsl && itype==OP_SELL)))
                 {
                  if(OrderClose(iticket,-1))
                    {

                     ArrayResize(del,icount+1);
                     del[icount]=sglobal;
                     icount++;
                     m_total--;
                    }
                 }//close by dstop
              }

           }

        }

      if(icount>0)
        {
         for(i=0;i<icount;i++)
           {

            if(del[i]!="" && GlobalVariableCheck(del[i]))
               GlobalVariableDel(del[i]);
           }
        }

     }

   void virtual_set(int iticket,double dsl,double dtp)
     {
      if(iticket<=0) return;

      string n;

      if(dtp>=0)
        {
         if(IsTester) n=StringConcatenate("virtual_",DoubleToStr(iticket,0),"_tp");
         else n=StringConcatenate(DoubleToStr(iticket,0),"_tp");

         GlobalVariableSet(n,dtp);

        }

      if(dsl>=0)
        {
         if(IsTester) n=StringConcatenate("virtual_",DoubleToStr(iticket,0),"_sl");
         else n=StringConcatenate(DoubleToStr(iticket,0),"_sl");

         GlobalVariableSet(n,dsl);

        }
     }

   bool virtual_check(int iticket)
     {
      if(iticket<=0) return (false);
      string n;

      if(IsTester) n=StringConcatenate("virtual_",DoubleToStr(iticket,0),"_tp");
      else n=StringConcatenate(DoubleToStr(iticket,0),"_tp");

      if(GlobalVariableCheck(n)) return (true);

      if(IsTester) n=StringConcatenate("virtual_",DoubleToStr(iticket,0),"_sl");
      else n=StringConcatenate(DoubleToStr(iticket,0),"_sl");

      if(GlobalVariableCheck(n)) return (true);

      return (false);
     }

   double virtual_get_tp(int iticket)
     {
      if(iticket<=0) return (0);
      string n;

      if(IsTester) n=StringConcatenate("virtual_",DoubleToStr(iticket,0),"_tp");
      else n=StringConcatenate(DoubleToStr(iticket,0),"_tp");

      if(GlobalVariableCheck(n)) return (GlobalVariableGet(n));
      return (0);
     }

   double virtual_get_sl(int iticket)
     {
      if(iticket<=0) return (0);
      string n;

      if(IsTester) n=StringConcatenate("virtual_",DoubleToStr(iticket,0),"_sl");
      else n=StringConcatenate(DoubleToStr(iticket,0),"_sl");

      if(GlobalVariableCheck(n)) return (GlobalVariableGet(n));
      return (0);
     }

   void virtual_set_levels(int iticket,double dsl_pt,double dtp_pt)
     {
      int index=-1;

      if(iticket>0 && OrderSelect(iticket,index))
        {
         string ssmb=m_orders[index].OrderSymbol;
         double dpp=point(ssmb);

         double dopen=m_orders[index].OrderOpenPrice;
         double dstop=0;
         double dtake=0;
         int itype=m_orders[index].OrderType;

         if(itype==OP_BUY)
           {
            if(dsl_pt>0) dstop=dopen-dsl_pt*dpp;
            if(dtp_pt>0) dtake=dopen+dtp_pt*dpp;
           }

         if(itype==OP_SELL)
           {
            if(dsl_pt>0) dstop=dopen+dsl_pt*dpp;
            if(dtp_pt>0) dtake=dopen-dtp_pt*dpp;
           }

         virtual_set(iticket,dstop,dtake);
        }
     }

   int Count(ENUM_ORDER_TYPE itype)
     {
      __COPYRIGHT__
      if((int)itype>=ArraySize(orders) || itype==-1) return -1; //ошибка

      return orders[(int)itype];
     }

   int Count(ENUM_ORDER_TYPE itype,long imagic)
     {
      __COPYRIGHT__
      int ic=0;

      for(int i=0;i<OrdersTotal();i++)
        {
         if(m_orders[i].OrderCloseTime>0) continue; //если не выбирает, пропускаем

         if(imagic==m_orders[i].OrderMagicNumber)
           {
            if(m_orders[i].OrderType==itype) ic++;
           }
        }

      return ic;
     }

   int HistoryCount(ENUM_ORDER_TYPE itype)
     {
      __COPYRIGHT__
      if((int)itype>=ArraySize(history)) return -1; //ошибка

      return history[(int)itype];
     }

   int HistoryCount(ENUM_ORDER_TYPE itype,long imagic)
     {
      __COPYRIGHT__
      int ic=0;

      for(int i=0;i<HistoryOrdersTotal();i++)
        {
         if(m_historyorders[i].OrderCloseTime>0) continue; //если не выбирает, пропускаем

         if(imagic==m_historyorders[i].OrderMagicNumber)
           {
            if(m_historyorders[i].OrderType==itype) ic++;
           }
        }

      return ic;
     }

   virtual int Update()
     {

      __COPYRIGHT__
      ArrayResize(m_orders,0);
      m_all=0;
      ArrayInitialize(orders,0);

      int isize=0;
      int itotal=::OrdersTotal();

      m_total=itotal; //запомним для проверок кол-ва лимита ордеров

      for(int i=0;i<itotal;i++)
        {
         if(!OrderSelect(i,SELECT_BY_POS)) continue; //если не выбирает, пропускаем

         if(CheckSymbol(OrderSymbol()))
           {

            if((!options_bSupportMaxLot && CheckMagic(OrderMagicNumber(),OrderComment())) || options_bSupportMaxLot)
              {

               isize=ArraySize(m_orders); //кол-во оредров в структуре

               if(ArrayResize(m_orders,isize+1)!=-1)
                 {
                  if(m_orders[isize].getOrderByTicket(OrderTicket())) //загрузим информацию по ордеру (грузим все ордера)
                    {
                     if(CheckMagic(m_orders[isize].OrderMagicNumber,m_orders[isize].OrderComment))
                       {
                        orders[m_orders[isize].OrderType]++; //увеличим счетчик
                        m_all++;
                       }
                    }
                 }
              }

           }
        }

      return m_all; //вернем кол-во ордеров в структуре
     }

   virtual int UpdateHistory(int iNewMaxLoad=EMPTY_VALUE)
     {
      __COPYRIGHT__
      ArrayResize(m_historyorders,0);
      ArrayInitialize(history,0);
      m_historyall=0;

      int isize=0;
      datetime tm_end=0;

      if(options_iMaxLoadDays>=0) tm_end=iTime(_Symbol,PERIOD_D1,options_iMaxLoadDays);
      if(iNewMaxLoad==-1) tm_end=0;
      else if(iNewMaxLoad>=0) tm_end=iTime(_Symbol,PERIOD_D1,iNewMaxLoad);

      int itotal=::OrdersHistoryTotal();

      for(int i=0;i<itotal;i++)
        {
         if(!OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) continue; //если не выбирает, пропускаем

         if(OrderOpenTime()>=tm_end) //учитываем глубину загрузки
           {

            if(CheckSymbol(OrderSymbol()))
              {

               if((!options_bSupportMaxLot && CheckMagic(OrderMagicNumber(),OrderComment())) || options_bSupportMaxLot)
                 {

                  isize=ArraySize(m_historyorders); //кол-во оредров в структуре

                  if(ArrayResize(m_historyorders,isize+1)!=-1)
                    {
                     if(m_historyorders[isize].getOrderByTicket(OrderTicket(),MODE_HISTORY)) //загрузим информацию по ордеру
                       {
                        if(CheckMagic(m_historyorders[isize].OrderMagicNumber,m_historyorders[isize].OrderComment))
                          {
                           history[m_historyorders[isize].OrderType]++; //увеличим счетчик
                           m_historyall++;
                          }
                       }
                    }
                 }
              }
           }
        }

      return m_historyall; //вернем кол-во ордеров в структуре
     }

   bool CopyOrders(COrderInfo &aOrders[])
     {
      __COPYRIGHT__
      int isize=ArraySize(aOrders);
      int isize_current=ArraySize(m_orders);

      if(ArrayResize(aOrders,isize+isize_current)!=-1)
        {
         for(int i=0;i<isize_current;i++)
           {
            aOrders[isize+i]=m_orders[i];
           }
        }

      return (isize>0);
     }

   bool CopyHistoryOrders(COrderInfo &aOrders[])
     {
      __COPYRIGHT__

      int isize=ArraySize(aOrders);
      int isize_current=ArraySize(m_historyorders);
      if(ArrayResize(aOrders,isize+isize_current)!=-1)
        {
         for(int i=0;i<isize_current;i++)
           {
            aOrders[isize+i]=m_historyorders[i];
           }
        }

      return (isize>0);
     }

   int LoadUpdate()
     {

      CSpeed s1;

      __COPYRIGHT__

      m_all=0;
      ArrayInitialize(orders,0);

      int isize=ArraySize(m_orders);

      for(int i=isize-1;i>=0;i--)
        {
         if(m_orders[i].OrderCloseTime>0) continue;

         if(CheckSymbol(m_orders[i].OrderSymbol))
           {

            if((!options_bSupportMaxLot && CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment)) || options_bSupportMaxLot)
              {

               if(CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment))
                 {
                  orders[m_orders[i].OrderType]++; //увеличим счетчик
                  m_all++;
                 }

              }

           }
        }

      return m_all; //вернем кол-во ордеров в структуре
     }

   int LoadUpdateHistory()
     {

      CSpeed s1;

      __COPYRIGHT__
      m_historyall=0;
      ArrayInitialize(history,0);

      int isize=ArraySize(m_historyorders);

      for(int i=isize-1;i>=0;i--)
        {
         if(m_historyorders[i].OrderCloseTime>0) continue;

         if(CheckSymbol(m_historyorders[i].OrderSymbol))
           {

            if((!options_bSupportMaxLot && CheckMagic(m_historyorders[i].OrderMagicNumber,m_historyorders[i].OrderComment)) || options_bSupportMaxLot)
              {

               if(CheckMagic(m_historyorders[i].OrderMagicNumber,m_historyorders[i].OrderComment))
                 {
                  orders[m_historyorders[i].OrderType]++; //увеличим счетчик
                  m_all++;
                 }

              }

           }
        }

      return m_historyall; //вернем кол-во ордеров в структуре
     }

   bool LoadOrders(COrderInfo &aOrders[])
     {
      __COPYRIGHT__

      int isize=ArraySize(aOrders);
      if(ArrayResize(m_orders,isize)!=-1)
        {
         for(int i=0;i<isize;i++)
           {
            m_orders[i]=aOrders[i];
           }
        }
      if(isize>0) LoadUpdate();

      return (isize>0);
     }

   bool LoadHistoryOrders(COrderInfo &aOrders[])
     {
      __COPYRIGHT__

      int isize=ArraySize(aOrders);
      if(ArrayResize(m_historyorders,isize)!=-1)
        {
         for(int i=0;i<isize;i++)
           {
            m_historyorders[i]=aOrders[i];
           }
        }
      if(isize>0) LoadUpdateHistory();

      return (isize>0);
     }

   int OrderInfoCopy(COrderInfo &dest[],COrderInfo &src[])
     {
      int isize=ArraySize(src);
      if(ArrayResize(dest,isize)!=-1)
        {
         for(int i=0;i<isize;i++)
           {
            dest[i]=src[i];
           }

         return isize;
        }

      return 0;
     }

   void UpdateOrders() //функцию стоит вызывать после удаления ордеров
     {
      COrderInfo tmporders[];

      if(OrderInfoCopy(tmporders,m_orders)>0)
        {
         m_all=0;
         ArrayInitialize(orders,0);

         ArrayResize(m_orders,0);

         int isize=ArraySize(tmporders);
         int j=0;
         for(int i=0;i<isize;i++)
           {
            if(tmporders[i].OrderCloseTime==0.0) //не закрыт
              {
               if(ArrayResize(m_orders,j+1)!=-1)
                 {
                  m_orders[j]=tmporders[i]; //копируем все элементы кроме удаляемого
                  j++;

                  if(CheckSymbol(m_orders[i].OrderSymbol))
                    {

                     if((!options_bSupportMaxLot && CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment)) || options_bSupportMaxLot)
                       {

                        if(CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment))
                          {
                           orders[m_orders[i].OrderType]++; //увеличим счетчик
                           m_all++;
                          }

                       }

                    }
                 }
              }
           }
        }

     }

   void   ClearOrder(int iticket,bool bDecOrder=true)
     {
      __COPYRIGHT__
      if(iticket<=0) return;

      int close_index=FindOrder(iticket);

      if(close_index>=0 && bDecOrder)
        {

         m_all--;
         if(m_all<0) m_all=0;
         orders[m_orders[close_index].OrderType]--;
         if(orders[m_orders[close_index].OrderType]<0) orders[m_orders[close_index].OrderType]=0;
        }

      int index=FindHistoryOrder(iticket);
      if(index>=0) //если нашли его уже в закрытх, обновим информацию о ордере
        {
         m_historyorders[index].getOrderByTicket(iticket,MODE_HISTORY); //обновим данные из истории
         if(close_index>=0) m_orders[close_index]=m_historyorders[index]; //обновим ордер среди открытых как закрытый
        }
      else
        {

         int isize=ArraySize(m_historyorders);
         if(ArrayResize(m_historyorders,isize+1)!=-1)
           {
            if(m_historyorders[isize].getOrderByTicket(iticket,MODE_HISTORY)) //обновим данные из истории и добавим в данные истории
              {
               m_historyall++;
               orders[m_historyorders[isize].OrderType]++;

               if(close_index>=0) m_orders[close_index]=m_historyorders[isize]; //сохраним данные, ордер пока не удаляем.
              }
           }
        }

     }

   virtual double   GroupOrderLot(int iticket)
     {
      __COPYRIGHT__
      if(iticket<=0) return 0;
      double dlot=0;

      for(int i=0;i<ArraySize(m_orders);i++)
        {
         if(m_orders[i].OrderCloseTime>0) continue;

         if(m_orders[i].OrderTicket==iticket || m_orders[i].OrderMagicNumber==MathAbs(iticket))
           {
            dlot+=m_orders[i].OrderLots;
           }
        }

      return dlot;
     }

   virtual double   GroupHistoryOrderLot(int iticket)
     {
      __COPYRIGHT__
      if(iticket<=0) return 0;
      double dlot=0;

      for(int i=0;i<ArraySize(m_historyorders);i++)
        {
         if(m_historyorders[i].OrderCloseTime>0) continue;

         if(m_historyorders[i].OrderTicket==iticket || m_historyorders[i].OrderMagicNumber==MathAbs(iticket))
           {
            dlot+=m_historyorders[i].OrderLots;
           }
        }

      return dlot;
     }

   virtual double GroupOrderProfit(int iticket)
     {
      __COPYRIGHT__
      if(iticket<=0) return 0;
      double dprofit=0;

      for(int i=0;i<ArraySize(m_orders);i++)
        {
         if(m_orders[i].OrderCloseTime>0) continue;

         if(m_orders[i].OrderTicket==iticket || m_orders[i].OrderMagicNumber==MathAbs(iticket))
           {
            dprofit+=m_orders[i].Profit;
           }
        }

      return dprofit;

     }

   virtual double GroupHistoryOrderProfit(int iticket)
     {
      __COPYRIGHT__
      if(iticket<=0) return 0;
      double dprofit=0;

      for(int i=0;i<ArraySize(m_historyorders);i++)
        {
         if(m_historyorders[i].OrderCloseTime==0) continue;

         if(m_historyorders[i].OrderTicket==iticket || m_historyorders[i].OrderMagicNumber==MathAbs(iticket))
           {
            dprofit+=m_historyorders[i].Profit;
           }
        }

      return dprofit;

     }

   virtual double getLock(int &itype)
     {

      double dlot=0;
      itype=EMPTY;

      double dLot[2]={0};

      int icount=ArraySize(m_orders);

      for(int i=icount-1;i>=0;i--)
        {
         if(m_orders[i].OrderCloseTime>0) continue;

         if(!CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) || !CheckSymbol(m_orders[i].OrderSymbol)) continue;

         if(m_orders[i].OrderType>=2) continue;

         if(m_orders[i].OrderType==OP_BUY) dLot[0]+=GroupOrderLot(m_orders[i].OrderTicket);
         if(m_orders[i].OrderType==OP_SELL) dLot[1]+=GroupOrderLot(m_orders[i].OrderTicket);
        }

      if(dLot[0]>dLot[1])
        {
         itype=OP_SELL;
         dlot=MathAbs(dLot[0]-dLot[1]);
        }

      if(dLot[0]<dLot[1])
        {
         itype=OP_BUY;
         dlot=MathAbs(dLot[1]-dLot[0]);
        }

      return NLot(dlot);
     }

   virtual double getProfit(int itype=ALL,int imode=MODE_TRADES,datetime dtm=0,bool bUpdate=false)
     {
      double pr=0;
      int flag,icount;
      datetime dtm_open;

      if(imode==MODE_TRADES)
        {
         if(ArraySize(m_orders)==0 || bUpdate) Update();

         icount=ArraySize(m_orders);

         for(int i=icount-1;i>=0;i--)
           {
            if(m_orders[i].OrderCloseTime>0) continue;
            if(!CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) || !CheckSymbol(m_orders[i].OrderSymbol)) continue;

            dtm_open=m_orders[i].OrderOpenTime;
            flag=toMyTypes(m_orders[i].OrderType)&itype;

            if(m_orders[i].OrderType==toDefType(flag,itype) && dtm_open>=dtm)
              {
               pr+=GroupOrderProfit(m_orders[i].OrderTicket);

              }
           }
        }
      else
        {
         if(ArraySize(m_historyorders)==0 || bUpdate) UpdateHistory();
         icount=ArraySize(m_historyorders);

         for(int i=icount-1;i>=0;i--)
           {
            if(m_historyorders[i].OrderCloseTime==0) continue;
            if(!CheckMagic(m_historyorders[i].OrderMagicNumber,m_historyorders[i].OrderComment) || !CheckSymbol(m_historyorders[i].OrderSymbol)) continue;

            dtm_open=m_historyorders[i].OrderOpenTime;
            flag=toMyTypes(m_historyorders[i].OrderType)&itype;

            if(m_historyorders[i].OrderType==toDefType(flag,itype) && dtm_open>=dtm)
              {
               pr+=GroupHistoryOrderProfit(m_historyorders[i].OrderTicket);
              }
           }
        }

      return (pr);
     }

   virtual double get_lots(int itype,bool bUpdate=false) //из старой библиотеки
     {
      double dlot=0;
      if(ArraySize(m_orders)==0 || bUpdate) Update();

      for(int i=0;i<ArraySize(m_orders);i++)
        {
         if(m_orders[i].OrderCloseTime>0) continue;
         if(!CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) || !CheckSymbol(m_orders[i].OrderSymbol)) continue;

         if(m_orders[i].OrderType==itype)
            dlot+=GroupOrderLot(m_orders[i].OrderTicket);

        }

      return dlot;
     }

   virtual double get_lots(double &dlots[],bool bUpdate=false) //подсчет лотов
     {
      double dlot=0;

      if(ArrayResize(dlots,2)!=-1){
      ArrayInitialize(dlots,0);

      if(ArraySize(m_orders)==0 || bUpdate) Update();

      for(int i=0;i<ArraySize(m_orders);i++)
        {
         if(m_orders[i].OrderCloseTime>0) continue;
         if(!CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) || !CheckSymbol(m_orders[i].OrderSymbol)) continue;

         if(m_orders[i].OrderType<2){
            dlots[m_orders[i].OrderType]+=GroupOrderLot(m_orders[i].OrderTicket);
         }

        }

        dlot=dlots[0]+dlots[1];
      }

      return dlot;
     }  

   int   ModifyOrder(int iticket,double dopen,double dstop,double dtake)
     {
      __COPYRIGHT__
      for(int i=0;i<ArraySize(m_orders);i++)
        {
         if(m_orders[i].OrderCloseTime>0) continue;

         if(m_orders[i].OrderTicket==iticket)
           {

            if(dopen==-1) dopen=m_orders[i].OrderOpenPrice;
            if(dstop==-1) dstop=m_orders[i].OrderStopLoss;
            if(dtake==-1) dtake=m_orders[i].OrderTakeProfit;

            m_orders[i].OrderOpenPrice=dopen;
            m_orders[i].OrderStopLoss=dstop;
            m_orders[i].OrderTakeProfit=dtake;

            return i;
           }
        }

      return -1;
     }

   int   FindOrder(int iticket)
     {
      __COPYRIGHT__
      for(int i=0;i<ArraySize(m_orders);i++)
        {
         if(m_orders[i].OrderCloseTime>0) continue;

         if(m_orders[i].OrderTicket==iticket)
           {
            return i;
           }
        }

      return EMPTY;
     }

   int   FindHistoryOrder(int iticket)
     {
      __COPYRIGHT__
      for(int i=0;i<ArraySize(m_historyorders);i++)
        {
         if(m_historyorders[i].OrderCloseTime==0) continue;

         if(m_historyorders[i].OrderTicket==iticket)
           {
            return i;
           }
        }

      return EMPTY;
     }

   bool OrderSelect(int iticket) //для совместимости
     {
      if(iticket<=0) return false;

      return (::OrderSelect(iticket,SELECT_BY_TICKET));
     }

   bool OrderSelect(int iticket,int &iindex)
     {
      iindex=-1;
      if(iticket<=0) return false;
      iindex=FindOrder(iticket);

      return (iindex!=-1);
     }

   bool HistoryOrderSelect(int iticket,int &iindex)
     {
      iindex=-1;
      if(iticket<=0) return false;
      iindex=FindHistoryOrder(iticket);

      return (iindex!=-1);
     }

   bool Modify(const int iticket,double dopen,double dsl=0,double dtp=0,datetime dt=0,const color cl=clrNONE,const bool tpslIsPoint=false,bool bCheck=true)
     {
      __COPYRIGHT__

      if(iticket<=0) return false;

      bool is_open=false;
      int i=FindOrder(iticket);

      if(i==EMPTY) return false; //ордер не найден

      double dstop=0,dtake=0,dlot=0;
      string sinfo="";

      string sname=m_orders[i].OrderSymbol;
      double point=point(sname);
      if(point==0) return false;

      int itype=m_orders[i].OrderType;

      double dlaststop=m_orders[i].OrderStopLoss;
      double dlasttake=m_orders[i].OrderTakeProfit;

      if(dopen==-1) dopen=nd(m_orders[i].OrderOpenPrice);
      if(dsl==-1) dsl=dlaststop;
      if(dtp==-1) dtp=dlasttake;

      stoplevel=GetStopLevel(m_name)*MarketInfo(m_name,MODE_POINT);

      if(tpslIsPoint)
        {
         if(itype==OP_BUY || itype==OP_BUYLIMIT || itype==OP_BUYSTOP)
           {
            if(dsl>0) dstop=nd(dopen-dsl*p,sname); else dstop=0;
            if(dtp>0) dtake=nd(dopen+dtp*p,sname); else dtake=0;
           }

         if(itype==OP_SELL || itype==OP_SELLLIMIT || itype==OP_SELLSTOP)
           {
            if(dsl>0) dstop=nd(dopen+dsl*p,sname); else dstop=0;
            if(dtp>0) dtake=nd(dopen-dtp*p,sname); else dtake=0;
           }
        }
      else
        {
         if(dsl>0) dstop=nd(dsl,sname); else dstop=0;
         if(dtp>0) dtake=nd(dtp,sname); else dtake=0;

        }

      dlot=m_orders[i].OrderLots;

/*double dvirtstop=virtual_get_sl(iticket);
      double dvirttake=virtual_get_tp(iticket);

      if(dsl>0 && dlaststop==0 && dvirtstop>0) dlaststop=dvirtstop;
      if(dtp>0 && dlasttake==0 && dvirttake>0) dlasttake=dvirttake;
*/
      double _Ask=Ask(sname);
      double _Bid=Bid(sname);

/* if((itype==OP_BUYLIMIT || itype==OP_BUYSTOP) && ((dtake<dopen && dtake>0) || (dstop>dopen && dstop>0)))
        {

         return false;
        }

      if((itype==OP_SELLLIMIT || itype==OP_SELLSTOP) && ((dtake>dopen && dtake>0) || (dstop<dopen && dstop>0)))
        {

         return false;
        }
*/
      if(itype==OP_BUY && ((_Bid>dtake && dtake>0) || (_Bid<dstop && dstop>0)))
        {

         return false;
        }

      if(itype==OP_SELL && ((_Ask<dtake && dtake>0) || (_Ask>dstop && dstop>0)))
        {

         return false;
        }

      if(dt<=0) dt=m_orders[i].OrderExpiration;

      if(!options_bNoModify)
        {

         int j=0;
         while(!is_open && j<options_iRestartCount && !IsStopped())
           {
            j++;

            if(iticket>0 && 

               ((bCheck && ((MathAbs(dopen-m_orders[i].OrderOpenPrice)/point>=1 && m_orders[i].OrderType>=2) || 
               MathAbs(dtake-dlasttake)/point>=1 ||
               MathAbs(dstop-dlaststop)/point>=1))
               || 
               (!bCheck && ((MathAbs(dopen-m_orders[i].OrderOpenPrice)/point>=0.1 && m_orders[i].OrderType>=2) || 
               MathAbs(dtake-dlasttake)/point>=0.1 ||
               MathAbs(dstop-dlaststop)/point>=0.1))))
              {

               if(OrderSelect(iticket,SELECT_BY_TICKET))
                 {
                  if(OrderCloseTime()==0)
                    {
                     double ddelta=EMPTY_VALUE;

                     if(dstop>0){
                     if(itype==OP_BUY) ddelta=nd(_Ask-dstop);
                     if(itype==OP_SELL) ddelta=nd(dstop-_Bid);
                     }

                     if(ddelta>stoplevel || ddelta==EMPTY_VALUE)
                       {

                        if(!::OrderModify(iticket,dopen,dstop,dtake,dt,cl))
                          {
                           ierrors=GetLastError();

                           if(ierrors>0)
                             {
                              sinfo=StringConcatenate(__FUNCTION__,"(",iticket,",",string_type(itype),",",dlot,",",dopen,",",dstop,",",dtake,") Ask=",_Ask," Bid=",_Bid);
                              is_open=ErrorMessage(ierrors,j,sinfo,options_iTimeout);
                             }

                          }
                        else
                          {
                           is_open=true;
                          }

                       }
                     else
                       {
                        is_open=true;
                       }

                    }
                 }

              }
           }

        }
      else
        {
         is_open=true; //отключена модификация, обновим виртуальные данные
        }

      if(is_open && iticket>0)
        {
         int iret=ModifyOrder(iticket,dopen,dstop,dtake); //обновим информацию о тейк и стоп
         if(options_bVirtual && itype<2 && (virtual_check(iticket) || iret==-1 || options_bNoModify)) virtual_set(iticket,dstop,dtake); //обновим виртуальные стоп и тейк
        }

      return is_open;
     }

   virtual bool  OrderModify(const int iticket,double dopen,double dsl=0,double dtp=0,datetime dt=0,const color cl=clrNONE,const bool tpslIsPoint=false,bool bCheck=true)
     {
      __COPYRIGHT__

      int ilast_ticket=OrderTicket();

      bool is_modify=Modify(iticket,dopen,dsl,dtp,dt,cl,tpslIsPoint,bCheck);

      if(options_bSupportMaxLot)
        {

         for(int i=ArraySize(m_orders)-1;i>=0;i--)
           {
            if(m_orders[i].OrderCloseTime>0) continue;

            if(m_orders[i].OrderMagicNumber==MathAbs(iticket)) //дополнительные
              {
               Modify(m_orders[i].OrderTicket,dopen,dsl,dtp,dt,cl,tpslIsPoint,bCheck);
              }
           }

        }

      if(ilast_ticket>0) OrderSelect(ilast_ticket);

      return (is_modify);
     }

   int Trade(const int cmd,const double dlot,double dopen,const double dsl=0,const double dtp=0,const string _comment="",const datetime dt=0,const color cl=clrNONE,const bool tpslIsPoint=true,const bool bAddCount=true)
     {
      __COPYRIGHT__

      ierrors=0;
      if(cmd<0) return -1;

      if(!CheckOrderSend(cmd,dlot))
        {

         ierrors=134;

         return (-134);
        }

      if(dlot==0.0) return 0; //лот не задан. не открываемся

      double ddlot=NLot(dlot,m_name); //округлим лот по правилам
      p=point(m_name);

      bool is_open=true;

      bool bret=false;
      string sinfo="";

      double dstop=0,dtake=0;

      double dnewopen=dopen;

      int digit=digits(m_name);
      int iticket=-1,j=0;

      ierrors=0; //обнулим данные о последней ошибке

      bool bOpenEmpty=false;

      double _Ask=Ask(m_name);
      double _Bid=Bid(m_name);

      while(is_open && j<options_iRestartCount && !IsStopped())
        {
         j++;

         if(dopen==-1)
           {
            RefreshRates();

            _Ask=Ask(m_name);
            _Bid=Bid(m_name);

            bOpenEmpty=true;
            if(cmd==OP_BUY) dnewopen=_Ask;
            if(cmd==OP_SELL) dnewopen=_Bid;
           }

         if(cmd==OP_BUYSTOP && _Ask>=dnewopen-stoplevel)
           {
            return 0;
           }

         if(cmd==OP_SELLSTOP && _Bid<=dnewopen+stoplevel)
           {

            return 0;
           }

         if(iticket==-1)
           {

            dtake=0;dstop=0;
            if(!tpslIsPoint)
              {
               if(cmd==OP_BUYSTOP || cmd==OP_BUYLIMIT)
                 {
                  if(dtp>0) dtake=dtp;
                  if(dsl>0) dstop=dsl;
                 }

               if(cmd==OP_SELLSTOP || cmd==OP_SELLLIMIT)
                 {
                  if(dtp>0) dtake=dtp;
                  if(dsl>0) dstop=dsl;
                 }
                 }else{
               if(cmd==OP_BUYSTOP || cmd==OP_BUYLIMIT)
                 {
                  if(dtp>0) dtake=dnewopen+dtp*p;
                  if(dsl>0) dstop=dnewopen-dsl*p;
                 }

               if(cmd==OP_SELLSTOP || cmd==OP_SELLLIMIT)
                 {
                  if(dtp>0) dtake=dnewopen-dtp*p;
                  if(dsl>0) dstop=dnewopen+dsl*p;
                 }
              }

            if(cmd>=2)
              {

               if(!options_bNoModify) iticket=::OrderSend(m_name,cmd,ddlot,NormalizeDouble(dnewopen,digit),m_islippage,dstop,dtake,_comment,(int)m_imagic,dt,cl);
               else iticket=::OrderSend(m_name,cmd,ddlot,NormalizeDouble(dnewopen,digit),m_islippage,0,0,_comment,(int)m_imagic,dt,cl);

              }
            else
              {
               iticket=::OrderSend(m_name,cmd,ddlot,NormalizeDouble(dnewopen,digit),m_islippage,0,0,_comment,(int)m_imagic,dt,cl);
              }

           }

         if(iticket!=-1 && cmd<2)
           {

            if(OrderSelect(iticket))
              {

               dnewopen=OrderOpenPrice();
               dtake=0;dstop=0;

               if(!tpslIsPoint)
                 {
                  if(cmd==OP_BUY)
                    {
                     if(dtp>0) dtake=dtp;
                     if(dsl>0) dstop=dsl;
                    }

                  if(cmd==OP_SELL)
                    {
                     if(dtp>0) dtake=dtp;
                     if(dsl>0) dstop=dsl;
                    }
                 }
               else
                 {
                  if(cmd==OP_BUY)
                    {
                     if(dtp>0) dtake=dnewopen+dtp*p;
                     if(dsl>0) dstop=dnewopen-dsl*p;
                    }

                  if(cmd==OP_SELL)
                    {
                     if(dtp>0) dtake=dnewopen-dtp*p;
                     if(dsl>0) dstop=dnewopen+dsl*p;
                    }
                 }

               if((dtake>0.0 || dstop>0.0) && dnewopen>0)
                 {

                  if(!options_bNoModify)
                    {

                     bret=::OrderModify(iticket,NormalizeDouble(dnewopen,digit),NormalizeDouble(dstop,digit),NormalizeDouble(dtake,digit),dt,cl);
                    }

                  if(options_bVirtual && (virtual_check(iticket) || !bret || options_bNoModify)) virtual_set(iticket,NormalizeDouble(dstop,digit),NormalizeDouble(dtake,digit));
                 }

              }
           }

         ierrors=GetLastError();

         if(iticket==-1 || ierrors>0)
           {
            sinfo=StringConcatenate(__FUNCTION__,"(",m_name,",",string_type(cmd),",",ddlot,",",dnewopen,",",dstop,",",dtake,",",_comment,") Ask=",_Ask," Bid=",_Bid);
            is_open=ErrorMessage(ierrors,j,sinfo,options_iTimeout);
           }
         else
           {
            is_open=false;
           }

         if(OrderSelect(iticket))
           {

            int i=ArraySize(m_orders);
            ArrayResize(m_orders,i+1);
            if(m_orders[i].getOrderByTicket(iticket))
              {

               if(bAddCount)
                 {

                  m_all++;
                  orders[m_orders[i].OrderType]++;
                 }
              }

            if(iticket>0) m_total++;
            return iticket;
           }
        }

      if(iticket>0) m_total++;

      return iticket;
     }

   virtual int OrderSend(const int cmd,const double dlot,double dopen,const double dsl=0,const double dtp=0,const string _comment="",const datetime dt=0,const color cl=clrNONE,const bool tpslIsPoint=true,double dMaxLot=0)
     {
      __COPYRIGHT__
      int iticket=-1;
      double dmaxLot=dMaxLot;
      CSpeed speed;

      if(dmaxLot==0) dmaxLot=MaxLot(m_name);

      if(dlot<=dmaxLot)
        {
         iticket=Trade(cmd,dlot,dopen,dsl,dtp,_comment,dt,cl,tpslIsPoint);

         return iticket;
        }

      if(!options_bSupportMaxLot)
        {

         return -1;
        }

      long ilast_magic=m_imagic;
      int ic=(int)(MathFloor(dlot/dmaxLot));
      double dostatok=0;

      dostatok=dlot-dmaxLot*ic; //рассчитаем остаточный лот 

      iticket=-1;
      int ifirst_ticket=-1;

      for(int i=0;i<ic;i++)
        {

         iticket=Trade(cmd,dmaxLot,dopen,dsl,dtp,_comment,dt,cl,tpslIsPoint,false);

         if(ifirst_ticket<0)
           {
            ifirst_ticket=iticket;
            m_imagic=MathAbs(iticket); //для всех остальных меджик будет равен тикету по модулю
           }

         if(ifirst_ticket<0) break; //не открылся ордер
        }

      if(dostatok>0 && dostatok>=MinLot(m_name) && iticket>0) iticket=Trade(cmd,NLot(dostatok,m_name),dopen,dsl,dtp,_comment,dt,cl,tpslIsPoint,false);

      m_imagic=ilast_magic;
      return ifirst_ticket;
     }

   virtual bool OrderCloseAll(const int itype=ALL,const color cl=clrNONE,bool bUpdate=false)
     {
      __COPYRIGHT__
      double currents[][3]; //профит, тикет, i
      ArrayResize(currents,0);
      int c=0,flag;
      if(ArraySize(m_orders)==0 || bUpdate) Update();

      bool bRet=false;

      for(int i=ArraySize(m_orders)-1;i>=0;i--)
        {
         if(m_orders[i].OrderCloseTime>0) continue;

         flag=toMyTypes(m_orders[i].OrderType)&itype;

         if(CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) && CheckSymbol(m_orders[i].OrderSymbol) && m_orders[i].OrderType==toDefType(flag,itype))
           {
            ArrayResize(currents,c+1);
            currents[c][0]=m_orders[i].Profit;
            currents[c][1]=m_orders[i].OrderTicket;
            currents[c][2]=i;
            c++;
           }
        }

      if(c>0)
        {
         ArraySort(currents,WHOLE_ARRAY,0,MODE_DESCEND); //отсортируем по профиту от минусовых к плюсовым

         for(int i=0;i<ArrayRange(currents,0);i++)
           {

            if(Close((int)currents[i][1],-1,cl))bRet=true;
           }
        }

      if(bRet) UpdateOrders(); //чистим от удаленных

      return true;
     }

   virtual bool Close(const int iticket,double dlot=-1,color cl=clrNONE)
     {
      __COPYRIGHT__
      ierrors=0;

      if(iticket<=0) return false;

      if(!OrderSelect(iticket))
        {

         ierrors=GetLastError();
         return (false);
        }

      int aOrder[];
      int isize=0;

      for(int i=0;i<ArraySize(m_orders);i++)
        {
         if(m_orders[i].OrderCloseTime>0)
           {

            continue;
           }

         if(m_orders[i].OrderTicket==iticket || m_orders[i].OrderMagicNumber==MathAbs(iticket))
           {
            isize=ArrayRange(aOrder,0);
            if(ArrayResize(aOrder,isize+1)!=-1)
              {

               aOrder[isize]=m_orders[i].OrderTicket;
              }
           }
        }

      isize=ArrayRange(aOrder,0);

      bool is_open=true;
      bool bret=false;
      int j=0;

      string sinfo="";
      double dsummlot=GroupOrderLot(iticket); //весь объем всей группы ордеров
      if(dlot==-1) dlot=dsummlot;

      double dopen=0;
      double dclose=0;
      int t=OrderType();

      if(isize>1) ArraySort(aOrder,WHOLE_ARRAY,0,MODE_DESCEND);  //сортируем по возрастанию

      for(int i=isize-1;i>=0;i--)
        {
         int index_ticket=aOrder[i];
         if(iticket==index_ticket)
           {
            continue;  //пропустим основной
           }

         int index=-1;

         if(OrderSelect(index_ticket,index))
           {

            double dlotClose=m_orders[index].OrderLots;

            if(dlot>=dlotClose)
              {

               if(CloseOrder(index_ticket,t,dlotClose,cl))
                  dlot-=dlotClose;
              }
            else
              {

               if(CloseOrder(index_ticket,t,dlot,cl)) dlot-=dlot;

              }

            if(dlot<=0) break;
           }

        }

      if(dlot>0)
        {

         for(int i=isize-1;i>=0;i--)
           {
            int index_ticket=aOrder[i];
            if(iticket!=index_ticket) continue;  //пропустим неосновные если остались

            int index=-1;

            if(OrderSelect(index_ticket,index))
              {

               double dlotClose=m_orders[index].OrderLots;

               if(dlot>=dlotClose)
                 {

                  if(CloseOrder(index_ticket,t,dlotClose,cl))
                     dlot-=dlotClose;
                 }
               else
                 {

                  if(CloseOrder(index_ticket,t,dlot,cl)) dlot-=dlot;

                 }

               if(dlot<=0) break;
              }
           }
        }

      return (is_open);
     }

   void Sleep(int millisec)
     {
      if(IsTester) return; //в тестере отключаем задержки принудительно
      ::Sleep(millisec);
     }

   bool CloseOrder(int iticket,int itype,double dlot,color cl)
     {
      __COPYRIGHT__
      int j=0;
      double dclose=0;
      bool bret=false;
      string sinfo="",sname=m_name;

      bool is_open=true;

      while(is_open && j<options_iRestartCount && !IsStopped())
        {
         j++;

         if(OrderSelect(iticket))
           {
            bool bPartClose=false;

            if(OrderCloseTime()>0)
              {

               int index_history=FindHistoryOrder(iticket);                                                            //найдем наш закрытый ордер и обновим информацию о нем.
               int jindex=ArraySize(m_historyorders);

               if(index_history==-1)
                 {
                  ArrayResize(m_historyorders,jindex+1); //новый ордер в истории, поместим даныне о онем
                 }
               else
                 {
                  jindex=index_history; //если найден, то обновим информацию
                 }

               if(m_historyorders[jindex].getOrderByTicket(iticket))
                 {

                  if(index_history==-1)
                    {
                     m_historyall++;
                     history[m_historyorders[jindex].OrderType]++;
                    }
                 }

               continue; //ордер уже закрыт
              }

            if(iticket>0 && itype<2)
              {
               sname=OrderSymbol();

               if(OrderLots()<dlot) dlot=OrderLots(); //закрыть весь лот

               if(OrderLots()>dlot) bPartClose=true;

               dclose=OrderClosePrice();
               if(dclose==0.0)
                 {
                  if(itype==OP_BUY) dclose=Bid(sname);
                  else if(itype==OP_SELL) dclose=Ask(sname);
                 }

               bret=::OrderClose(iticket,dlot,dclose,m_islippage,cl);

               if(bret && bPartClose)
                 {
                  string n=OrderSymbol();
                  int ipos=-1;

                  if(OrderSelect(iticket,ipos))
                    {

                     int itotal=::OrdersTotal();
                     for(int i=itotal-1;i>=0;i--)
                       {
                        if(!OrderSelect(i,SELECT_BY_POS)) continue;

                        if(OrderSymbol()==n && StringFind(OrderComment(),StringFormat("from #%d",iticket))>=0)
                          {

                           if(m_orders[ipos].getOrderByTicket(OrderTicket(),MODE_TRADES))
                             {

                              int index_history=FindHistoryOrder(iticket);                                                            //найдем нах закрытый ордер и обновим информацию о нем.
                              int jindex=ArraySize(m_historyorders);

                              if(index_history==-1)
                                {
                                 ArrayResize(m_historyorders,jindex+1); //новый ордер в истории, поместим даныне о онем
                                }
                              else
                                {
                                 jindex=index_history; //если найден, то обновим информацию
                                }

                              if(m_historyorders[jindex].getOrderByTicket(iticket))
                                {

                                 if(index_history==-1)
                                   {
                                    m_historyall++;
                                    history[m_historyorders[jindex].OrderType]++;
                                   }
                                }
                             }
                           break;

                          }
                       }

                    }

                 }

              }

            if(iticket>0 && itype>=2)
              {

               bret=OrderDelete(iticket,cl);
               bPartClose=false; //отложки не закрыть частями, поэтому информацию о ней нам надо будет удалить потмо

              }

            ierrors=GetLastError();
            if(ierrors>0)
              {
               sinfo=StringConcatenate(__FUNCTION__,"(",iticket,",",dlot,")");
               is_open=ErrorMessage(ierrors,j,NULL,options_iTimeout);

              }
            else
              {
               is_open=false;
              }

            if(bret && !bPartClose)
              {
               ClearOrder(iticket); //пометим что ордер удален если это было не частичное закрытие! это важно
               m_total--;
               return true;
              }
           }
         else
           {
            break;
           }

        }

      return is_open;

     }

   virtual bool OrderClose(const int iticket,double dlot=-1,color cl=clrNONE)
     {
      __COPYRIGHT__
      int ilast_ticket=OrderTicket();

      bool is_modify=Close((int)iticket,dlot,cl); //закрывается основной ордер и дополнительные если требуется

      if(ilast_ticket>0) OrderSelect(ilast_ticket);

      return (is_modify);
     }

   bool DefaultOrderClose(const int iticket,double dlot=-1,color cl=clrNONE)
     {
      __COPYRIGHT__
      int ilast_ticket=OrderTicket();

      bool is_open=true;
      bool bret=false;
      int j=0;
      int digit=(int)MarketInfo(OrderSymbol(),MODE_DIGITS);
      string info="";
      if(dlot==-1) dlot=OrderLots();
      double dopen=0;
      double dclose=0;
      int t=OrderType();
      while(is_open && j<5)
        {
         j++;

         if(iticket>0 && t<2)
           {
            if(OrderLots()<dlot) dlot=OrderLots(); //закрыть весь лот
            dclose=OrderClosePrice();
            if(dclose==0.0)
              {
               if(t==OP_BUY) dclose=Bid(OrderSymbol());
               else if(t==OP_SELL) dclose=Ask(OrderSymbol());
              }
            bret=::OrderClose(iticket,dlot,dclose,0,cl);

           }

         if(iticket>0 && t>=2)
           {
            bret=OrderDelete(iticket,cl);

           }

         ierrors=GetLastError();
         if(ierrors>0)
           {
            info=StringConcatenate(__FUNCTION__,"(",iticket,",",dlot,")");
            is_open=ErrorMessage(ierrors,j,info);
            if(ierrors==ERR_OFF_QUOTES)
               while(!IsStopped())
                 {
                  if(RefreshRates()) break; Sleep(1000);
                 }
           }
         else
           {
            is_open=false;
           }

        }

      if(ilast_ticket>0) OrderSelect(ilast_ticket);

      return (is_open);
     }

   virtual bool PartClose(double dpartclose_profit,double dpartclose_procent,bool bUpdate=false)
     {
      bool bClose=false;
      if(dpartclose_profit==0) return false;

      if(ArraySize(m_orders)==0 || bUpdate) Update();

      string sname=m_name;

      for(int i=ArraySize(m_orders)-1;i>=0;i--)
        {
         if(m_orders[i].OrderCloseTime>0) continue;

         if(m_orders[i].OrderType<2 && CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) && CheckSymbol(m_orders[i].OrderSymbol))
           {

            if(m_orders[i].OrderType==OP_BUY || m_orders[i].OrderType==OP_SELL)
              {
               double dstop=m_orders[i].OrderStopLoss;
               double pr=m_orders[i].OrderProfitPoint;

               double dlot=NLot(m_orders[i].OrderLots*dpartclose_procent/100); //часть лота

               if(m_orders[i].OrderLots<=MinLot(m_orders[i].OrderSymbol)) continue; //пропуск если остаток меньше минимального лота или равен ему

               double dsummlots=0;
               int part=get_part(m_orders[i].OrderTicket,dsummlots);

               if(part==0 && pr>=dpartclose_profit)
                 {
                  Print("Close part order and safe stoploss: ",DoubleToString(dlot,2));
                  OrderClose(m_orders[i].OrderTicket,dlot,clrNONE);
                  bClose=true;
                 }
              }

           }
        }

      return bClose;
     }

/*
lot - суммарный лот
*/
   virtual int get_part(int ticket,double &dsummlot) //вспомогательная функция ищет кол-во частичных закрытий 
     {

      int part=0;
      dsummlot=0;

      datetime tOpen=0;
      int iimagic;
      double open;
      string name;
      int ipos=FindOrder(ticket);

      if(ipos<0) return -1;

      open=m_orders[ipos].OrderOpenPrice;
      tOpen=m_orders[ipos].OrderOpenTime;
      iimagic=m_orders[ipos].OrderMagicNumber;
      name=m_orders[ipos].OrderSymbol;

      long id=m_orders[ipos].OrderTicket;

      dsummlot=m_orders[ipos].OrderLots;

      int i=0;

      while(i<m_historyall && !IsStopped()) //востановим по истории кол-во закрытий и полный лот
        {

         if(StringFind(m_historyorders[i].OrderComment,StringFormat("to #%d",id))==0)
           {
            id=m_historyorders[i].OrderTicket;
            dsummlot+=m_historyorders[i].OrderLots;
            part++;
            i=0;
            continue;
           }

         i++;
        }

      return part; //вернем сколько раз уже закрывались
     }

   bool ErrorMessage(const int err,const int j,const string informer="",const int ipause=5000)
     {
      __COPYRIGHT__
      bool is_open=true;

      switch(err)
        {
         case ERR_NO_ERROR:
         case ERR_NO_MQLERROR:
         case ERR_NO_RESULT:
         case ERR_INVALID_TRADE_PARAMETERS:{Print("Invalid trade parameters "+informer);is_open=false;} break;
         case ERR_COMMON_ERROR:{is_open=false; break;}
         case ERR_BROKER_BUSY: {Print("Broker is busy, try №"+DoubleToStr(j,0)); Sleep(ipause);} break;
         case ERR_SERVER_BUSY:
         case ERR_TRADE_CONTEXT_BUSY: {Print("Server is busy, try №"+DoubleToStr(j,0)); Sleep(ipause);} break;
         case ERR_NO_CONNECTION: {Print("No connection to the server, the attempt №"+DoubleToStr(j,0)); Sleep(ipause); is_open=false;} break;
         case ERR_TRADE_TIMEOUT: {Print("Outdated waiting transaction, an attempt №"+DoubleToStr(j,0)); Sleep(ipause); is_open=false;} break;
         case ERR_PRICE_CHANGED: {Print("Price changed attempt №"+DoubleToStr(j,0)+" "+informer); Sleep(ipause);} break;
         case ERR_REQUOTE: {Print("Requotes attempt №"+DoubleToStr(j,0)+" "+informer); Sleep(ipause); RefreshRates();} break;
         case ERR_OFF_QUOTES: {Print("Off quotes attempt №"+DoubleToStr(j,0)+" "+informer); Sleep(ipause);  RefreshRates();} break;
         case ERR_TOO_FREQUENT_REQUESTS: {Print("Too frequent queries attempt №"+DoubleToStr(j,0)+" "+informer); is_open=false;} break;
         case ERR_ORDER_LOCKED: {is_open=false; Print("Order has been locked and processed");} break;
         case ERR_INVALID_STOPS: {Print("Invalid stop "+informer);is_open=false;} break;
         case ERR_INVALID_PRICE: {Print("Invalid price (slippage), an attempt №"+DoubleToStr(j,0)+" "+informer);} break;
         case ERR_INVALID_TRADE_VOLUME: {is_open=false; Print("Invalid volume, "+informer);} break;
         case ERR_MARKET_CLOSED: {is_open=false; } break;
         case ERR_TRADE_DISABLED: {is_open=false; Print("Trade is not allowed"); } break;//торговля запрещена
         case ERR_NOT_ENOUGH_MONEY: {is_open=false; Print("Enough money to make the operation, "+informer);} break;
         case ERR_LONG_POSITIONS_ONLY_ALLOWED: {is_open=false; Print("Allowed only buy");} break;
         case ERR_TRADE_MODIFY_DENIED: {Print("Order is too close to the market (option disabled), the attempt №"+DoubleToStr(j,0)+" "+informer); Sleep(ipause);} break;
         case ERR_TRADE_EXPIRATION_DENIED: {is_open=false; Print("Using the date of expiry of the order is prohibited broker");} break;
         case ERR_TRADE_TOO_MANY_ORDERS: {is_open=false; Print("The number of open and pending orders has reached the limit set by the broker");} break;
         case ERR_TRADE_HEDGE_PROHIBITED: {is_open=false; Print("Trying to dopen an opposite position to the already existing, if hedging is disabled");} break;
         case ERR_TRADE_PROHIBITED_BY_FIFO: {is_open=false; Print("Trying to close the position at the instrument in contradiction with the FIFO rule");} break;
         case ERR_ARRAY_INDEX_OUT_OF_RANGE: {is_open=false; break;}
         case ERR_INVALID_TICKET: {is_open=false; break; }
         case ERR_UNKNOWN_SYMBOL: {is_open=false; Print("Unknown symbol"); break; }
         case ERR_TRADE_NOT_ALLOWED: {is_open=false; Print("Trade is not allowed. Enable checkbox \"Allow live trading\" in the expert properties."); break; }
         case ERR_LONGS_NOT_ALLOWED: {is_open=false; Print("Longs are not allowed. Check the expert properties."); break; }
         case ERR_SHORTS_NOT_ALLOWED: {is_open=false; Print("Shorts are not allowed. Check the expert properties."); break; }

         default: {is_open=false; Print("unknown error: "+IntegerToString(err)+" "+informer);} break;
        }

      return (is_open);
     }

   bool CheckOrderSend(int itype,double dlot)
     {
      __COPYRIGHT__

      if(dlot<=0.0) return (false);
      int limit=(int)AccountInfoInteger(ACCOUNT_LIMIT_ORDERS);
      if(limit>0 && m_total>=limit) return false; //обход ошибки 148 превышен лимит ордеров

      if(!options_bCheckFreeMargin) return true;

      int it=itype;

      if(options_bNoCheckPending)
        {
         if(it==OP_BUYLIMIT || it==OP_BUYSTOP) return true;
         if(it==OP_SELLLIMIT || it==OP_SELLSTOP) return true;
        }
      else
        {
         if(it==OP_BUYLIMIT || it==OP_BUYSTOP) it=OP_BUY;
         if(it==OP_SELLLIMIT || it==OP_SELLSTOP) it=OP_SELL;
        }

      if(AccountFreeMarginCheck(m_name,it,dlot)<=0 || GetLastError()==134)
        {

         return (false);
        }

      return (true);
     }

   int getOrderTicket(int itype=ALL,const int imode=MODE_TRADES,const datetime dttm=0,bool bHistoryOpenOrderTime=true,bool bUpdate=false)
     {
      __COPYRIGHT__
      datetime dtm=0,dtm_open=0;
      int iticket=-1,icount=0;
      int flag;

      if(imode==MODE_TRADES)
        {
         if(ArraySize(m_orders)==0 || bUpdate) Update();

         icount=ArraySize(m_orders);

         for(int i=icount-1;i>=0;i--)
           {
            if(m_orders[i].OrderCloseTime>0) continue;
            if(!CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) || !CheckSymbol(m_orders[i].OrderSymbol)) continue;

            dtm_open=m_orders[i].OrderOpenTime;

            flag=toMyTypes(m_orders[i].OrderType)&itype;

            if(m_orders[i].OrderType==toDefType(flag,itype) && dtm_open>=dttm && dtm_open>=dtm)
              {
               dtm=dtm_open;
               iticket=m_orders[i].OrderTicket;
              }

           }
        }
      else
        {
         if(ArraySize(m_historyorders)==0 || bUpdate) UpdateHistory();

         icount=ArraySize(m_historyorders);

         for(int i=icount-1;i>=0;i--)
           {
            if(m_historyorders[i].OrderCloseTime==0) continue;
            if(!CheckMagic(m_historyorders[i].OrderMagicNumber,m_historyorders[i].OrderComment) || !CheckSymbol(m_historyorders[i].OrderSymbol)) continue;

            if(bHistoryOpenOrderTime) dtm_open=m_historyorders[i].OrderOpenTime; else dtm_open=m_historyorders[i].OrderCloseTime;

            flag=toMyTypes(m_historyorders[i].OrderType)&itype;

            if(m_historyorders[i].OrderType==toDefType(flag,itype) && dtm_open>=dttm && dtm_open>=dtm)
              {
               dtm=dtm_open;
               iticket=m_historyorders[i].OrderTicket;
              }

           }

        }

      return iticket;
     }
   int getFirstTicket(int itype=ALL,const int imode=MODE_TRADES,const datetime dttm=0,bool bOpenOrderTime=true,bool bUpdate=false)
     {
      datetime dtm=EMPTY_VALUE,dtm_open=EMPTY_VALUE;
      int iticket=-1,icount=0;
      int flag;

      if(imode==MODE_TRADES)
        {
         if(ArraySize(m_orders)==0 || bUpdate) Update();
         icount=ArraySize(m_orders);

         for(int i=icount-1;i>=0;i--)
           {

            if(m_orders[i].OrderCloseTime>0) continue;
            if(!CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) || !CheckSymbol(m_orders[i].OrderSymbol)) continue;

            dtm_open=m_orders[i].OrderOpenTime;

            flag=toMyTypes(m_orders[i].OrderType)&itype;

            if(m_orders[i].OrderType==toDefType(flag,itype) && dtm_open>=dttm && dtm_open<=dtm)
              {
               dtm=dtm_open;
               iticket=m_orders[i].OrderTicket;
              }
           }

        }
      else
        {

         if(ArraySize(m_historyorders)==0 || bUpdate) UpdateHistory();
         icount=ArraySize(m_historyorders);

         for(int i=icount-1;i>=0;i--)
           {
            if(m_historyorders[i].OrderCloseTime==0) continue;
            if(!CheckMagic(m_historyorders[i].OrderMagicNumber,m_orders[i].OrderComment) || !CheckSymbol(m_historyorders[i].OrderSymbol)) continue;

            if(bOpenOrderTime) dtm_open=m_historyorders[i].OrderOpenTime; else dtm_open=m_historyorders[i].OrderCloseTime;

            flag=toMyTypes(m_historyorders[i].OrderType)&itype;

            if(m_historyorders[i].OrderType==toDefType(flag,itype) && dtm_open>=dttm && dtm_open<=dtm)
              {
               dtm=dtm_open;
               iticket=m_historyorders[i].OrderTicket;
              }

           }
        }
      return (iticket);
     }

   int getLastOrderTicket(int itype=ALL,_ORDER_MODE imode=ORDER_UP,bool bUpdate=false)
     {

      CSpeed s1;

      datetime dtm=0,dtm_open=0;
      int iticket=-1,icount=0;
      int flag;
      double array_order_open[][2];
      ArrayResize(array_order_open,0);
      int c=0;
      if(ArraySize(m_orders)==0 || bUpdate) Update();

      for(int i=ArraySize(m_orders)-1;i>=0;i--)
        {
         if(m_orders[i].OrderCloseTime>0) continue;
         if(CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) && CheckSymbol(m_orders[i].OrderSymbol))
           {

            flag=toMyTypes(m_orders[i].OrderType)&itype;

            if(m_orders[i].OrderType==toDefType(flag,itype))
              {
               ArrayResize(array_order_open,c+1);
               array_order_open[c][0]=m_orders[i].OrderOpenPrice;
               array_order_open[c][1]=m_orders[i].OrderTicket;
               c++;
              }
           }

        }

      if(itype==OP_BUY && c>0)
        {

         ArraySort(array_order_open,WHOLE_ARRAY,0,MODE_ASCEND); //сортируем в сторону увеличения, тогда 0й ордер будет самый нижний, последний сверху (первый).
         if(imode==ORDER_DN) return ((int)array_order_open[0][1]);
         if(imode==ORDER_UP) return ((int)array_order_open[c-1][1]);
        }

      if(itype==OP_SELL && c>0)
        {
         ArraySort(array_order_open,WHOLE_ARRAY,0,MODE_DESCEND); //сортируем в сторону уменьшения, тогда 0й ордер будет самый нижний, последний сверху (первый).
         if(imode==ORDER_UP) return ((int)array_order_open[0][1]);
         if(imode==ORDER_DN) return ((int)array_order_open[c-1][1]);
        }

      return 0;
     }

   int getLastHistoryTicket(int itype=ALL,const datetime dttm=0,bool bUpdate=false)
     {
      datetime dtm=0,dtm_open=EMPTY_VALUE;
      int iticket=-1,icount=0;
      int flag;

      if(ArraySize(m_historyorders)==0 || bUpdate) UpdateHistory();
      icount=ArraySize(m_historyorders);

      for(int i=icount-1;i>=0;i--)
        {

         if(m_historyorders[i].OrderCloseTime==0) continue;

         if(CheckSymbol(m_historyorders[i].OrderSymbol) && CheckMagic(m_historyorders[i].OrderMagicNumber,m_historyorders[i].OrderComment))
           {

            dtm_open=m_historyorders[i].OrderOpenTime;

            flag=toMyTypes(m_historyorders[i].OrderType)&itype;

            if(m_historyorders[i].OrderType==toDefType(flag,itype) && dtm_open>=dttm && dtm_open>=dtm)
              {
               dtm=dtm_open;
               iticket=m_historyorders[i].OrderTicket;
              }
           }

        }

      return (iticket);
     }

   void trailing_simple(double level,double doffset,double dstep=0,int itype=ALL,bool bUpdate=false)
     {
      double st,dstop=0,dStep=dstep,dvirtstop=0;
      int flag;

      if(level==0.0) return;

      if(ArraySize(m_orders)==0 || bUpdate) Update();

      for(int i=ArraySize(m_orders)-1;i>=0;i--)
        {
         if(m_orders[i].OrderCloseTime>0) continue;
         if(CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) && CheckSymbol(m_orders[i].OrderSymbol))
           {

            if(m_orders[i].OrderType>=2) continue;
            p=point(m_orders[i].OrderSymbol);

            string n=m_orders[i].OrderSymbol;
            double tick=MarketInfo(n,MODE_TICKSIZE);
            if(dStep==0) dStep=tick/p;

            dstop=m_orders[i].OrderStopLoss;
            dvirtstop=dstop;
            if(options_bVirtual) dvirtstop=virtual_get_sl(m_orders[i].OrderTicket);

            double pt=0;
            flag=toMyTypes(m_orders[i].OrderType)&itype;

            if(m_orders[i].OrderType==OP_BUY && m_orders[i].OrderType==toDefType(flag,itype))
              {
               pt=(Bid(n)-m_orders[i].OrderOpenPrice)/p;

               st=NormalizeDouble(MathFloor((Bid(n)-MathAbs(doffset)*p)/tick)*tick,digits(n));
               if(pt>=level && level!=0.0)
                 {
                  if(dvirtstop>dstop && dvirtstop>0) dstop=dvirtstop;

                  if(dstop==0 || (dstop<st && (st-dstop)/p>=dStep))
                    {
                     OrderModify(m_orders[i].OrderTicket,-1,st,-1,0,clrNONE);
                     continue;
                    }
                 }

              }

            if(m_orders[i].OrderType==OP_SELL && m_orders[i].OrderType==toDefType(flag,itype))
              {
               pt=(m_orders[i].OrderOpenPrice-Ask(n))/p;

               st=NormalizeDouble(MathFloor((Ask(n)+MathAbs(doffset)*p)/tick)*tick,digits(n));
               if(pt>=level && level!=0)
                 {
                  if(dvirtstop<dstop && dvirtstop>0) dstop=dvirtstop;

                  if(dstop==0 || (dstop>st && (dstop-st)/p>=dStep))
                    {
                     OrderModify(m_orders[i].OrderTicket,-1,st,-1,0,clrNONE);
                     continue;
                    }
                 }

              }
           }
        }

     }

   void trailing_udavka(double level,double doffset,double dstep,int itype=ALL,bool bUpdate=false)
     {
      double st,dstop=0,dStep=dstep,dvirtstop=0;
      int flag;

      if(level==0.0) return;

      if(ArraySize(m_orders)==0 || bUpdate) Update();

      for(int i=ArraySize(m_orders)-1;i>=0;i--)
        {
         if(m_orders[i].OrderCloseTime>0) continue;
         if(CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) && CheckSymbol(m_orders[i].OrderSymbol))
           {

            if(m_orders[i].OrderType>=2) continue;
            p=point(m_orders[i].OrderSymbol);

            string n=m_orders[i].OrderSymbol;
            double tick=MarketInfo(n,MODE_TICKSIZE);
            if(dStep==0) dStep=tick/p;

            dstop=m_orders[i].OrderStopLoss;

            dvirtstop=dstop;
            if(options_bVirtual) dvirtstop=virtual_get_sl(m_orders[i].OrderTicket);

            double pt=0;
            flag=toMyTypes(m_orders[i].OrderType)&itype;

            if(m_orders[i].OrderType==OP_BUY && m_orders[i].OrderType==toDefType(flag,itype))
              {
               pt=(Bid(n)-m_orders[i].OrderOpenPrice)/p;

               int steps=(int)MathFloor((pt-level)/dStep);

               st=NormalizeDouble(MathFloor((Bid(n)-MathAbs(doffset-steps*dStep)*p)/tick)*tick,digits(n));
               if(pt>=level && level!=0.0)
                 {
                  if(dvirtstop>dstop && dvirtstop>0) dstop=dvirtstop;

                  if(dstop==0 || (dstop<st && (st-dstop)/p>=dStep))
                    {
                     OrderModify(m_orders[i].OrderTicket,-1,st,-1,0,clrNONE);
                     continue;
                    }
                 }

              }

            if(m_orders[i].OrderType==OP_SELL && m_orders[i].OrderType==toDefType(flag,itype))
              {
               pt=(m_orders[i].OrderOpenPrice-Ask(n))/p;

               int steps=(int)MathFloor((pt-level)/dStep);

               st=NormalizeDouble(MathFloor((Ask(n)+MathAbs(doffset-steps*dStep)*p)/tick)*tick,digits(n));
               if(pt>=level && level!=0)
                 {
                  if(dvirtstop<dstop && dvirtstop>0) dstop=dvirtstop;

                  if(dstop==0 || (dstop>st && (dstop-st)/p>=dStep))
                    {
                     OrderModify(m_orders[i].OrderTicket,-1,st,-1,0,clrNONE);
                     continue;
                    }
                 }

              }
           }
        }

     }

   void trailing_by_price(double price=0,int itype=ALL,double dstep=1,bool bUpdate=false)
     {
      double st,dstop=0,dvirtstop=0;
      int flag;
      if(price==0.0) return;
      if(ArraySize(m_orders)==0 || bUpdate) Update();

      for(int i=ArraySize(m_orders)-1;i>=0;i--)
        {

         if(m_orders[i].OrderCloseTime>0) continue;
         if(CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) && CheckSymbol(m_orders[i].OrderSymbol))
           {

            if(m_orders[i].OrderType>=2) continue;

            string n=m_orders[i].OrderSymbol;
            double tick=MarketInfo(n,MODE_TICKSIZE);
            dstop=m_orders[i].OrderStopLoss;
            dvirtstop=dstop;
            if(options_bVirtual) dvirtstop=virtual_get_sl(m_orders[i].OrderTicket);

            double pt=0;
            flag=toMyTypes(m_orders[i].OrderType)&itype;

            if(m_orders[i].OrderType==OP_BUY && m_orders[i].OrderType==toDefType(flag,itype))
              {
               st=NormalizeDouble(MathFloor(price/tick)*tick,digits(n));

               if(dvirtstop>dstop && dvirtstop>0) dstop=dvirtstop;

               if(dstop==0 || (dstop<st && (st-dstop)/p>=dstep))
                 {
                  OrderModify(m_orders[i].OrderTicket,-1,st,-1,0,clrNONE);
                  continue;
                 }

              }

            if(m_orders[i].OrderType==OP_SELL && m_orders[i].OrderType==toDefType(flag,itype))
              {

               st=NormalizeDouble(MathFloor(price/tick)*tick,digits(n));

               if(dvirtstop<dstop && dvirtstop>0) dstop=dvirtstop;

               if(dstop==0 || (dstop>st && (dstop-st)/p>=dstep))
                 {
                  OrderModify(m_orders[i].OrderTicket,-1,st,-1,0,clrNONE);
                  continue;
                 }

              }
           }
        }

     }

   void bu_simple(double dlevel,double doffset,int itype=ALL,bool bUpdate=false)//перенос в бу при достижении заданной прибыли
     {
      double st,dstop=0,dvirtstop=0;
      int flag;
      if(dlevel==0.0) return;
      if(ArraySize(m_orders)==0 || bUpdate) Update();
      int isize=ArraySize(m_orders);

      for(int i=isize-1;i>=0;i--)
        {

         if(m_orders[i].OrderCloseTime>0) continue;
         if(CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) && CheckSymbol(m_orders[i].OrderSymbol))
           {

            if(m_orders[i].OrderType>=2) continue;

            string n=m_orders[i].OrderSymbol;
            double tick=MarketInfo(n,MODE_TICKSIZE);
            dstop=m_orders[i].OrderStopLoss;
            dvirtstop=dstop;
            if(options_bVirtual) dvirtstop=virtual_get_sl(m_orders[i].OrderTicket);

            double pt=0;
            flag=toMyTypes(m_orders[i].OrderType)&itype;

            if(m_orders[i].OrderType==OP_BUY && m_orders[i].OrderType==toDefType(flag,itype))
              {
               pt=(Bid(n)-m_orders[i].OrderOpenPrice)/p;

               if(pt>=dlevel && dlevel!=0.0)
                 {

                  st=m_orders[i].OrderOpenPrice+doffset*p;

                  if(dvirtstop>dstop && dvirtstop>0) dstop=dvirtstop;

                  if(dstop==0 || dstop<st)
                    {

                     OrderModify(m_orders[i].OrderTicket,-1,st,-1,0,clrNONE);
                     continue;
                    }
                 }

              }

            if(m_orders[i].OrderType==OP_SELL && m_orders[i].OrderType==toDefType(flag,itype))
              {
               pt=(m_orders[i].OrderOpenPrice-Ask(n))/p;

               if(pt>=dlevel && dlevel!=0)
                 {
                  st=m_orders[i].OrderOpenPrice-doffset*p;
                  if(dvirtstop<dstop && dvirtstop>0) dstop=dvirtstop;
                  if(dstop==0 || dstop>st)
                    {
                     OrderModify(m_orders[i].OrderTicket,-1,st,-1,0,clrNONE);
                     continue;
                    }
                 }

              }
           }
        }

     }

   int getCountProfit(int itype=-1,datetime dtm=0,bool bUpdate=false)
     {
      int icount=0;

      if(ArraySize(m_historyorders)==0 || bUpdate) UpdateHistory();

      for(int i=ArraySize(m_historyorders)-1;i>=0;i--)
        {

         if(m_historyorders[i].OrderCloseTime==0) continue;
         if(!CheckMagic(m_historyorders[i].OrderMagicNumber,m_historyorders[i].OrderComment) || !CheckSymbol(m_historyorders[i].OrderSymbol)) continue;

         if(m_historyorders[i].OrderOpenTime>=dtm && m_historyorders[i].OrderType<2)
           {

            if((m_historyorders[i].OrderType==itype || itype==-1))
              {
               if(m_historyorders[i].OrderProfitPoint>=0) icount++;
               else break;
              }
           }
        }

      return (icount);
     }

   int getCountMinus(int itype=-1,bool sl_cmt_use=false,datetime dtm=0,bool bUpdate=false)
     {
      int icount=0;

      if(ArraySize(m_historyorders)==0 || bUpdate) UpdateHistory();

      for(int i=ArraySize(m_historyorders)-1;i>=0;i--)
        {

         if(m_historyorders[i].OrderCloseTime==0) continue;
         if(!CheckMagic(m_historyorders[i].OrderMagicNumber,m_historyorders[i].OrderComment) || !CheckSymbol(m_historyorders[i].OrderSymbol)) continue;

         if(CheckMagic(m_historyorders[i].OrderMagicNumber,m_historyorders[i].OrderComment) && m_historyorders[i].OrderOpenTime>=dtm && m_historyorders[i].OrderType<2)
           {

            if((m_historyorders[i].OrderType==itype || itype==-1))
              {
               if(m_historyorders[i].OrderProfitPoint<0 && ((StringFind(m_historyorders[i].OrderComment,"[sl]")>=0 && sl_cmt_use) || !sl_cmt_use)) icount++;
               else break;
              }
           }
        }

      return (icount);
     }

   void trailing_bankomat(int itf,int iATR_Period=5,double dSAR_step=0.02,double dSAR_maximum=0.2,int itype=-1,double trailing_bankomat_atr_koef=1,bool bUpdate=false)
     {

      int t;
      double dstop,open,dvirtstop;
      double _Ask=Ask(m_name);
      double _Bid=Bid(m_name);

      double sp=_Ask-_Bid;
      if(ArraySize(m_orders)==0 || bUpdate) Update();

      for(int i=ArraySize(m_orders)-1;i>=0;i--)
        {

         if(m_orders[i].OrderCloseTime>0) continue;

         if(CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) && CheckSymbol(m_orders[i].OrderSymbol))
           {
            t=m_orders[i].OrderTicket;

            datetime dtm_start=m_orders[i].OrderOpenTime;
            int pos=iBarShift(m_name,itf,dtm_start);

            double dhigh[],dlow[];
            double datr[],dsar[];
            ArrayResize(dhigh,pos+1);
            ArrayResize(dlow,pos+1);
            ArrayResize(datr,pos+1);
            ArrayResize(dsar,pos+1);

            ArrayInitialize(dhigh,0);
            ArrayInitialize(dlow,0);
            ArrayInitialize(datr,0);
            ArrayInitialize(dsar,0);

            ArraySetAsSeries(dhigh,true);
            ArraySetAsSeries(dlow,true);
            ArraySetAsSeries(datr,true);
            ArraySetAsSeries(dsar,true);

            HideTestIndicators(TRUE);
            for(int ii=0;ii<pos+1;ii++)
              {
               datr[ii]=iATR(m_name,itf,iATR_Period,ii+1);
               dsar[ii]=iSAR(m_name,itf,dSAR_step,dSAR_maximum,ii+1);
               dhigh[ii]=iHigh(m_name,itf,ii+1);
               dlow[ii]=iLow(m_name,itf,ii+1);
              }
            HideTestIndicators(FALSE);
            int type=m_orders[i].OrderType;

            open=m_orders[i].OrderOpenPrice;
            dstop=m_orders[i].OrderStopLoss;
            dvirtstop=dstop;
            if(options_bVirtual) dvirtstop=virtual_get_sl(m_orders[i].OrderTicket);

            double newstop=0;
            double tick=MarketInfo(m_name,MODE_TICKSIZE);
            for(int ii=0;ii<pos;ii++)
              {

               if(dsar[ii]>dhigh[ii] && dsar[ii+1]<dlow[ii+1])
                 {
                  if(type==OP_BUY)
                    {
                     newstop=NormalizeDouble(MathFloor((dlow[ii]-datr[ii]*trailing_bankomat_atr_koef-sp)/tick)*tick,_Digits);

                     if(dvirtstop>dstop && dvirtstop>0) dstop=dvirtstop;

                     if((dstop==0 || newstop>dstop) && newstop>m_orders[i].OrderOpenPrice)
                       {
                        OrderModify(m_orders[i].OrderTicket,-1,newstop,-1,0,clrNONE);
                       }
                    }
                  break;
                 }

               if(dhigh[ii]>=dsar[ii] &

Показано первые 50% кода (символов: 143561)

Открыть по тарифу

Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.

Разовая покупка файла

На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.

Чтобы оформить заказ, введите email и перейдите к оплате.

Стоимость полного кода
14 356,10₽ ≈ $175.48