Информационный индикатор позиций, сделок и ордеров. - страница 4

 
Vitaly Muzichenko:

Та да)

После стилизатора с 1000 строк получается 5000, и код становится явно не читабельным, и не понятно что к чему принадлежит.


Про стилизатор как раз идёт батл в ветке:

https://www.mql5.com/ru/forum/216476/page4

 

Реализованы изменения в версии v1.002:

1. Отбор по магику.

2. Отбор по тикету.

3. Отборы по исключению значения.

Планируются:

1. Отборы по спискам значений для инструмента, магика и тикета.

2. Отборы по спискам исключения значений для инструмента, магика и тикета.

Планируются на дальнюю перспективу:

1. Использование цветового оформления.

2. Минимальный графический интерфейс управления. Например селекция элементов по клику.

3. Преобразование в советник (или в комплекс индикатор+советник) с добавлением операций закрытия позиций и ордеров.

Замечания и предложения приветствуются.

Файлы:
LIP_v01.002.zip  71 kb
 

Реализованы изменения в версии v1.003:

1. Отборы по спискам значений для инструмента, магика и тикета.

2. Отборы по спискам исключения значений (отсевы) для инструмента, магика и тикета.

lip 01 003

Планируются:

1. Использование цветового оформления.

Планируются на дальнюю перспективу:

2. Минимальный графический интерфейс управления. Например селекция элементов по клику.

3. Преобразование в советник (или в комплекс индикатор+советник) с добавлением операций закрытия позиций и ордеров.

Замечания и предложения приветствуются.


Файлы:
LIP_v01.003.zip  71 kb
 

По поводу преобразования в советник (комплекс индикатор-советник) пока прорабатывается следующее решение:

Индикатор будет заносить тикеты предполагаемых к закрытию (удалению) позиций (ордеров) в глобальные переменные терминала.

Советник будет мониторить глобальные переменные и при обнаружении команд от индикатора будет выполнять соответствующие действия.

Замечания и предложения приветствуются.

 
Yury Kirillov:

По поводу преобразования в советник (комплекс индикатор-советник) пока прорабатывается следующее решение:

Индикатор будет заносить тикеты предполагаемых к закрытию (удалению) позиций (ордеров) в глобальные переменные терминала.

Советник будет мониторить глобальные переменные и при обнаружении команд от индикатора будет выполнять соответствующие действия.

Замечания и предложения приветствуются.

Может Я как-то криво написал, но когда робот стучится к глобальным переменным, то терминал подвисает. С аналогичной логикой доступа с индикатора - проблем нет. Но у меня много глобальный переменных, может поэтому.

 
Vitaly Muzichenko:

Может Я как-то криво написал, но когда робот стучится к глобальным переменным, то терминал подвисает. С аналогичной логикой доступа с индикатора - проблем нет. Но у меня много глобальный переменных, может поэтому.


Спасибо за замечание. Постараюсь внимательно проверить наличие этого отрицательного эффекта.

 

Изменения в версии v1.004:

1. Добавлен расчет суммы по колонкам позиций и сделок (пока без комиссии).

lip 01 004

Файлы:
LIP_v01.004.zip  95 kb
 

В плане развития пункта:

3. Преобразование в советник (или в комплекс индикатор+советник) с добавлением операций закрытия позиций и ордеров.

Публикую предварительное описание протокола обмена командами и результатами их выполнения между индикатором и советником
для версии комплекса: индикатор LibreInfoPDO v1.005 + советник LibreCLOP v1.005

//Протокол обмена между индикатором и советником, для передачи команд на открытие-закрытие позиций из индикатора в советник.
//Глобально (глобальные переменные)
//Переменные:
//Ready_N   -  признак завершения команды (изначально установлен).
//             Используется глобально, чтобы отслеживать завершение команды.
//Command_N -  инициатор выполнения команды (изначально сброшен).
//             Используется глобально, чтобы инициировать выполнение команды.
//На индикаторе (переменные индикатора):
//Переменные:
//BuseInd_N -  канал занят, устанавливается перед отправкой команды, снимается после подтверждения выполнения команды (изначально сброшен).
//             Используется в индикаторе (внутренняя), чтобы не выдавать новую команду до гарантированного завершения обработки предыдущей.
//1. Цикл инициации команд. Перебираем все команды от 1 до N. Для каждой:
//    1.1. Если канал свободен BuseInd_N=0, то выполняем:
//       1.1.1. Если соблюдается условие выполнения команды N: (наличие сигнала на команду N), то выполняем:
//          1.1.1.1. Устанавливается флаг занято BuseInd_N=1 (канал команды N занят, новые действия не инициируются)
//          1.1.1.2. Сбрасывается флаг завершения Ready_N=0 для переменной Ready_N (команда N не выполнена) (изначально все эти флаги установлены)
//          1.1.1.3. Выставляется команда Command_N=N для переменной Command_N (выполнить команду N)
//          //В результате должно быть: Ready_N=0 (сброшено индикатором), Command_N=N (установлено индикатором), BuseInd_N=1 (установлено индикатором)
//2. Цикл проверки выполнения. Перебираем все команды от 1 до N. Для каждой:
//    2.1. Если канал занят Buse_N=1, то выполняем:
//       2.1.1. Проверка выполнения: если выполнено (обнаружен флаг завершения Ready_N=1 для команды N), то выполняем: //таймаут - пока не рассматриваем
//          2.1.1.1. Освобождение канала: Сброс флага занято Buse_N=0 (канал команды N свободен, новые действия допустимы) //таймаут - рассмотреть отдельно
//          //В результате должно быть: Ready_N=1 (установлено советником), Command_N=0 (сброшено советниом), BuseInd_N=0 (сброшено индикатором)
//На советнике (переменные советника):
//Переменные:
//ReadyExp_N - внутренний флаг выполнения команды N (изначально сброшен)
//             Используется в советнике (внутренняя), чтобы отслеживать завершение команды.
//1. Цикл проверки заданий и постановки на выполнение. Перебираем все команды от 1 до N. Для каждой:
//    //1.0. Если канал занят BuseInd_N=1, - не используем ибо используется в индикаторе, чтобы не выдавать новую команду до окончания обработки предыдущей.
//    1.1. Если обнаружена команда N: Command_N=N, то выполняем:
//       1.1.1. Если снят флаг завершения Ready_N=0, то выполняем:
//          1.1.1.1. Сбрасываем команду Command_N=0
//          1.1.1.2. Сбрасываем для советника внутренний флаг завершения команды N: ReadyExp_N=0; (изначально все эти флаги сброшены, но на всякий)
//          1.1.1.3. Запускаем команду на выполнение (после выполнения команды должен быть установлен внутренний флаг выполнения команды N: ReadyExp_N=0;
//          //В результате должно быть: Ready_N=0 (сброшено индикатором), Command_N=0 (сброшено советниом), ReadyExp_N=0??? (сброшено советником)
//          //Ситуация Ready_N=0 + Command_N=0, говорит о том, что команда запущена на выполнение, но ещё не выполнена.
//2. Цикл проверки выполнения. Перебираем все команды от 1 до N. Для каждой:
//    2.1. Если установлен внутренний флаг завершения команды N: ReadyExp_N=1, то выполняем:
//       2.1.1. Устанавливается флаг завершения Ready_N=1 для переменной Ready_N (команда N выполнена)
//       2.1.2. Сбрасываем для советника внутренний флаг завершения команды N: ReadyExp_N=0; 
//       //В результате должно быть: Ready_N=1 (установлено советником), Command_N=0 (сброшено советниом), ReadyExp_N=0 (сброшено советником)

На текущий момент комплекс дорабатывается под следующие минимальные возможности для проведения тестирования системы обмена командами (имитатор):

1. Обмен командами двух видов: "Открыть позицию" и "Закрыть позицию".

2. Фиксированный лот. Лотность в обмене не участвует.

3. Исполнение (имитатор) рыночных ордеров двух типов: Buy и Sell .

4. Сигнал на открытие и закрытие сделок формируется в индикаторе LibreInfoPDO по счетчику тиков последовательно и циклически:

Открытие сделки на покупку --- Закрытие сделки на покупку --- Открытие сделки на продажу --- Закрытие сделки на продажу --- Всё сначала.

5. Непосредственно выполнение команд в советнике LibreCLOP не реализовано, производится только приём команд на исполнение и формирование ответных сигналов об исполнении.

Планируется на ближайшую перспективу:

1. Реализация в индикаторе LibreInfoPDO примитивного формирования сигналов на открытие по МА или одной из свечных моделей.

2. Реализация в индикаторе LibreInfoPDO примитивного формирования сигналов на закрытие по накопленной прибыли или простейшему тралу.

3. Тестирование работы механизма обмена с использованием демо счета при открытии-закрытии позиций.

4. Нагрузочное тестирование механизма обмена, проверка замечания Vitaly Muzichenko 2017.10.01 17:16  по поводу возможного низкого быстродействия механизма обмена.

Планируются на дальнюю перспективу:

1. Дополнительной целью проекта является проверка возможности построения связки (несколько индикаторов - один советник) через механизм обмена данными при помощи глобальных переменных терминала.

Замечания и предложения приветствуются.

В частности интересует мнение сообщества по методике тестирования связки (индикатор - советник) либо  (несколько индикаторов - один советник) в тестере стратегий.

Совершение сделок - Торговые операции - Справка по MetaTrader 5
Совершение сделок - Торговые операции - Справка по MetaTrader 5
  • www.metatrader5.com
Торговая деятельность в платформе связана с формированием и отсылкой рыночных и отложенных ордеров для исполнения брокером, а также с управлением текущими позициями путем их модификации или закрытия. Платформа позволяет удобно просматривать торговую историю на счете, настраивать оповещения о событиях на рынке и многое другое. Открытие позиций...
 

Фрагменты кода обслуживающие механизм обмена.

Индикатор, основной обработчик тиков:

//----- Блок тестирования обмена
//----- Инициатор выполнения
//1. Цикл инициации команд. Перебираем все команды от 1 до N. Для каждой:
//    1.1. Если канал свободен BuseInd_N=0, то выполняем:
//       1.1.1. Если соблюдается условие выполнения команды N: (наличие сигнала на команду N), то выполняем:
//          1.1.1.1. Устанавливается флаг занято BuseInd_N=1 (канал команды N занят, новые действия не инициируются)
//          1.1.1.2. Сбрасывается флаг завершения Ready_N=0 для переменной Ready_N (команда N не выполнена) (изначально все эти флаги установлены)
//          1.1.1.3. Выставляется команда Command_N=N для переменной Command_N (выполнить команду N)
//          //В результате должно быть: Ready_N=0 (сброшено индикатором), Command_N=N (установлено индикатором), BuseInd_N=1 (установлено индикатором)
   {for(int i=1;i<=2;i++)//Перебор типов Команд
   {
      {for(int j=0;j<=1;j++)//Перебор типов Позиций
      {
         //Print("i=",i," j=",j," CommandCode=",(int)CommandCode((enCommandType)i,(ENUM_POSITION_TYPE)j));
         {if(BuseInd[(int)CommandCode((enCommandType)i,(ENUM_POSITION_TYPE)j)]==0)       //Если канал свободен BuseInd_N=0 по данным типам команд и позиций
         {
            {if(CheckCondition(CommandType,PositionType)&&(CommandType==(enCommandType)i)&&(PositionType==(ENUM_POSITION_TYPE)j))  //Проверка условия открытия, получение типа позиции
            {
               BuseInd[(int)CommandCode(CommandType,PositionType)]=1;          //Устанавливается флаг занято BuseInd
               SendCommand(CommandCode(CommandType,PositionType));             //Сбрасывается флаг завершения Ready и Выставляется команда Command с типом по CheckOpenCondition
            }}//if(CheckOpenCondition(PositionType)&&(PositionType==(ENUM_POSITION_TYPE)j))
         }}//if(BuseInd[(int)CommandCode((enCommandType)i,(ENUM_POSITION_TYPE)j)]==0)
      }}//for(int j=0;i<=1;i++)
   }}//for(int i=1;i<=2;i++)
//----- Проверка выполнения
//2. Цикл проверки выполнения. Перебираем все команды от 1 до N. Для каждой:
//    2.1. Если канал занят Buse_N=1, то выполняем:
//       2.1.1. Проверка выполнения: если выполнено (обнаружен флаг завершения Ready_N=1 для команды N), то выполняем: //таймаут - пока не рассматриваем
//          2.1.1.1. Освобождение канала: Сброс флага занято Buse_N=0 (канал команды N свободен, новые действия допустимы) //таймаут - рассмотреть отдельно
//          //В результате должно быть: Ready_N=1 (установлено советником), Command_N=0 (сброшено советниом), BuseInd_N=0 (сброшено индикатором)
   ulong UlongSet=0;
   {for(int i=1;i<=2;i++)
   {
      {for(int j=0;j<=1;j++)//Перебор типов Позиций
      {
         {if(BuseInd[(int)CommandCode((enCommandType)i,(ENUM_POSITION_TYPE)j)]==1)       //Если канал занят Buse_N=1
         {
            //Вынести в CheckCommandResult(CommandCode((enCommandType)i,(ENUM_POSITION_TYPE)j))
            {if((GlobalGetUlong("LIP_"+TheSymbol+"_Ready_"+IntegerToString((int)CommandCode((enCommandType)i,(ENUM_POSITION_TYPE)j)),UlongSet))&&(UlongSet==1))//Если флаг выполнения установлен Ready_N=1
            {
               BuseInd[(int)CommandCode((enCommandType)i,(ENUM_POSITION_TYPE)j)]=0;          //Освобождение канала: Сброс флага занято Buse_N=0
               if(PrintInfo)Print("Инд задача "+IntegerToString(CommandCode((enCommandType)i,(ENUM_POSITION_TYPE)j))+" выполнена! ");
            }}//if(Ready[(int)CommandCode((enCommandType)i,(ENUM_POSITION_TYPE)j)]==1)
         }}//if(BuseInd[(int)CommandCode((enCommandType)i,(ENUM_POSITION_TYPE)j)]==1)
      }}//for(int j=0;i<=1;i++)
   }}//for(int i=1;i<=2;i++)  

Индикатор, функции:

//
//============================================================================================= MQL5 ===
//    CheckCondition - Проверка условия открытия
// Вых:
//    iCommand :  тип команды
//    iPosType :  тип открываемой позиции
//    bool     :  есть условие открытия    
//------------------------------------------------------------------------------------------------------
bool CheckCondition( enCommandType        &iCommand,
                     ENUM_POSITION_TYPE   &iPosType){
//----- Demo
   {if(MathMod(gnTick+0*TestStep,TestBase)<0.5)
   {
      iPosType=POSITION_TYPE_BUY;
      iCommand=Command_Open;
      return(true);
   }}//if(MathMod(gnTick+0*TestStep,TestBase)<0.5)
   {if(MathMod(gnTick+2*TestStep,TestBase)<0.5)
   {
      iPosType=POSITION_TYPE_SELL;
      iCommand=Command_Open;
      return(true);
   }}//if(MathMod(gnTick+2*TestStep,TestBase)<0.5)
   {if(MathMod(gnTick+1*TestStep,TestBase)<0.5)
   {
      iPosType=POSITION_TYPE_BUY;
      iCommand=Command_Close;
      return(true);
   }}//if(MathMod(gnTick+1*TestStep,TestBase)<0.5)
   {if(MathMod(gnTick+3*TestStep,TestBase)<0.5)
   {
      iPosType=POSITION_TYPE_SELL;
      iCommand=Command_Close;
      return(true);
   }}//if(MathMod(gnTick+3*TestStep,TestBase)<0.5)
   return(false);
}//CheckCondition()
//
//============================================================================================= MQL5 ===
//    CommandCode - формирование кода команды для передачи в советник
// Вх:
//    iCommand    :  тип команды (Command_None/Command_Open/Command_Close)
//    iPosType    :  тип позиции (Buy/Sell)
// Вых:
//    ulong       :  код команды (0/1/2/3/4) - (неткоманды/покупка/продажа/закрытиепокупки/закрытиепродажи)
//------------------------------------------------------------------------------------------------------
ulong CommandCode(enCommandType        iCommand,      //тип команды 
                  ENUM_POSITION_TYPE   iPosType){     //тип позиции
//----- Demo
   {if(iCommand==Command_Open)
   {
      {if(iPosType==POSITION_TYPE_BUY)
      {
         return(1);//Покупать
      }}//if(iPosType==POSITION_TYPE_BUY)
      {if(iPosType==POSITION_TYPE_SELL)
      {
         return(2);//Продавать
      }}//if(iPosType==POSITION_TYPE_SELL)
   }}//if(iCommand==Commmand_Open)
   {if(iCommand==Command_Close)
   {
      {if(iPosType==POSITION_TYPE_BUY)
      {
         return(3);//Закрыть Покупать
      }}//if(iPosType==POSITION_TYPE_BUY)
      {if(iPosType==POSITION_TYPE_SELL)
      {
         return(4);//Закрыть Продавать
      }}//if(iPosType==POSITION_TYPE_SELL)
   }}//if(iCommand==Commmand_Close)
   return(0);//нет команды
}//CommandCode()
//
//============================================================================================= MQL5 ===
//    SendCommand - отправка команды в советник
//------------------------------------------------------------------------------------------------------
void SendCommand(ulong iCommandCode){
//-----
   datetime TimeSet=0;
   //1. Сбрасывается флаг выполнения (команда выполнить покупку не выполнена)
   {if(GlobalSetUlong("LIP_"+TheSymbol+"_Ready_"+IntegerToString(iCommandCode),TimeSet,0))
   {
      if(PrintDebug)Print("Инд LIP_"+TheSymbol+"_Ready_"+IntegerToString(iCommandCode)+"=",0);
   }}//if(GlobalSetUlong("LIP_"+TheSymbol+"_Ready_"+EnumToString(iCommandCode),TimeSet,0))
   //2. Выставляется команда (выполнить покупку)
   {if(GlobalSetUlong("LIP_"+TheSymbol+"_Command_"+IntegerToString(iCommandCode),TimeSet,iCommandCode))
   {
      if(PrintDebug)Print("Инд LIP_"+TheSymbol+"_Command_"+IntegerToString(iCommandCode)+"=",iCommandCode);
   }}//if(GlobalSetUlong("LIP_"+TheSymbol+"_Command"+EnumToString(iCommandCode),TimeSet,iCommandCode))
   if(PrintInfo)Print("Инд задача "+IntegerToString(iCommandCode)+" запущена!");
   //DoItCommand=true;
}//SendCommand()

 

Функции (индикатор и советник - общие):

bool GlobalSetDouble(string iName,datetime &iTimeSet,double iDateSet=0.0){
//-----
   iTimeSet=GlobalVariableSet(iName,iDateSet);
   {if(iTimeSet!=0)//Значение удалось установить
   {
      return(true);      
   }else{//Не удалось установить
      return(false);
   }}//if(iTimeSet!=0)
//-----
   return(false);
}//GlobalSetDouble()

bool GlobalGetDouble(string iName,double &iDateGet){
//-----
   iDateGet=0.0;
   {if(GlobalVariableCheck(iName))//Переменная есть
   {
      {if(GlobalVariableGet(iName,iDateGet))//Значение удалось считать
      {
         return(true);      
      }else{//Не удалось считать
         iDateGet=0.0;
         return(false);
      }}//if(GlobalVariableGet(iName,iDateGet))
   }else{//Переменной нет
      iDateGet=0.0;
      return(false);
   }}//if(GlobalVariableCheck(iName))
//-----   
   return(false);
}//GlobalGetDouble()
//
bool GlobalSetString(string iName,datetime &iTimeSet,string iStringSet=""){
//-----
   union ulong_double 
   { 
      double   iDateSet;
      ulong    iLongSet;
      uchar    iCharSet[8];
   };
   ulong_double   ud;
   ud.iLongSet=0;
//-----
   StringToCharArray(iStringSet,ud.iCharSet,0,8);
//-----
   iTimeSet=GlobalVariableSet(iName,ud.iDateSet);
   {if(iTimeSet!=0)//Значение удалось установить
   {
      return(true);      
   }else{//Не удалось установить
      return(false);
   }}//if(iTimeSet!=0)
//-----
   return(false);
}//GlobalSetString()

bool GlobalGetString(string iName,string &iStringGet){
//-----
   iStringGet="";
//-----
   union ulong_double 
   { 
      double   iDateGet;
      ulong    iLongGet;
      uchar    iCharGet[8];
   };
   ulong_double   ud;
   ud.iLongGet=0;
//-----
   {if(GlobalVariableCheck(iName))//Переменная есть
   {
      {if(GlobalVariableGet(iName,ud.iDateGet))//Значение удалось считать
      {
         iStringGet=CharArrayToString(ud.iCharGet,0,8); 
         return(true);      
      }else{//Не удалось считать
         iStringGet="";
         return(false);
      }}//if(GlobalVariableGet(iName,ud.iDateGet))
   }else{//Переменной нет
      iStringGet="";
      return(false);
   }}//if(GlobalVariableCheck(iName))
//-----   
   iStringGet="";
   return(false);
}//GlobalGetString()
//
bool GlobalSetUlong(string iName,datetime &iTimeSet,ulong iUlongSet=0){
//-----
   union ulong_double 
   { 
      double   iDateSet;
      ulong    iLongSet;
   };
   ulong_double   ud;
   ud.iLongSet=iUlongSet;
//-----
   iTimeSet=GlobalVariableSet(iName,ud.iDateSet);
   {if(iTimeSet!=0)//Значение удалось установить
   {
      return(true);      
   }else{//Не удалось установить
      return(false);
   }}//if(GlobalVariableGet(iName,iDate))
//-----
   return(false);
}//GlobalSetDouble()

bool GlobalGetUlong(string iName,ulong &iUlongGet){
//-----
   iUlongGet=0;
//-----
   union ulong_double 
   { 
      double   iDateGet;
      ulong    iLongGet;
   };
   ulong_double   ud;
   ud.iLongGet=0;
//-----
   {if(GlobalVariableCheck(iName))//Переменная есть
   {
      {if(GlobalVariableGet(iName,ud.iDateGet))//Значение удалось считать
      {
         iUlongGet=ud.iLongGet; 
         return(true);      
      }else{//Не удалось считать
         iUlongGet=0;
         return(false);
      }}//if(GlobalVariableGet(iName,iDate))
   }else{//Переменной нет
      iUlongGet=0;
      return(false);
   }}//if(GlobalVariableCheck(iName))
//-----   
   iUlongGet=0;
   return(false);
}//GlobalGetDouble()
Причина обращения: