//============================================================================================= MQL5 === // LibreInfoPDO Main_5 v1.005 MQL5 // Модуль обработки событий // LibreCoin (c)2014-2017 //====================================================================================================== #property strict //============================================================================================= MQL5 === // INCLUDE - подключаемые модули //------------------------------------------------------------------------------------------------------ //----- Обратные ссылки на основной файл проекта #include "LIP_Ref_5_v1.005.mqh" //============================================================================================= MQL5 === // EVENT PROCESSING MODULE //------------------------------------------------------------------------------------------------------ // //============================================================================================= MQL5 === // On_Init() - инициализация советника //------------------------------------------------------------------------------------------------------ ENUM_INIT_RETCODE On_Init(){ //----- Счетчики и настройки счетчиков gnTick=0; gInTimer=false; //----- Определяем необходимость использования графики GraphUse=( false //Тут надо проверить какой режим с каким совместим || ((!MQLInfoInteger(MQL_TESTER))&&(!MQLInfoInteger(MQL_OPTIMIZATION))) //Не тестирование и не оптимизация || (MQLInfoInteger(MQL_VISUAL_MODE)) //или визуальный режим ); //GraphUse=true; //----- Определяем имя программы ProgramName=MQLInfoString(MQL_PROGRAM_NAME); ////----- Выбор индикаторов для сигналов открытия и закрытия - работает но дублирует ADXW // int LastError=0; // {if((!GraphUse)&&((OpenMethod==Open_ADXW)||(CloseProfitMethod==CloseProfit_ADXW)||(CloseLossMethod==CloseLoss_ADXW))) // { // ResetLastError(); // adxw_handle=iCustom( TheSymbol, // PERIOD_CURRENT, // "Projects\\Indicatores\\MQ5\\ADX\\adxw_zat_117.ex5", // //----- Input parameters // aInpPeriodADXW, //Period // aInpMethodADXW, //Method (MODE_SMA,MODE_EMA,MODE_SMMA,MODE_LWMA) // aSSCBaseMode, //Корр (0..3)-(off/spread/close/midHLC) // aInpFastPeriodEMA, //Fast EMA period // aInpSlowPeriodEMA, //Slow EMA period // aDICalcMode, //DICalcMode(0..8)-(hi/low/mahl/mihl/suhl/isuhl/imahl/imihl) // //----- Параметры сброса тенденции // adDI, //Для +-DI в долях от (макс-старт) // adActiv, //Для Активности ((+DI)+(-DI)) в долях от максимальной // adDelta, //Для Дельты ((+DI)-(-DI)) в долях от максимальной // //----- Levels // aL0, //L0 ADXOpenLvl // aL1, //L1 ADXOpenLvlMax // aL2, //L2 ADXCloseLvl // aL3, //L3 ADXReversLvl // aL4, //L4 ADXReversLvlMax // //----- Scale // aScaleMax //ScaleMax // ); // LastError=GetLastError(); // {if(LastError!=0) // { // Print("LIP: adxw_handle = ",adxw_handle," error = ",LastError); // }}//if(LastError!=0) // {if((GraphUse)&&(!ChartIndicatorAdd(ChartID(),(int)ChartGetInteger(ChartID(),CHART_WINDOWS_TOTAL),adxw_handle))) // { // Print("LIP: Не добавлен adxw_zat_117!!!"); // }}//if((GraphUse)&&(!ChartIndicatorAdd(0,(int)ChartGetInteger(0,CHART_WINDOWS_TOTAL),adxw_handle))) // }}//if((!GraphUse)&&((OpenMethod==Open_ADXW)||(CloseProfitMethod==CloseProfit_ADXW)||(CloseLossMethod==CloseLoss_ADXW))) ////----- Извлекаем хендл ADXW из глобальной переменной - не проходит! //int LastError=0; //{if((OpenMethod==Open_ADXW)||(CloseProfitMethod==CloseProfit_ADXW)||(CloseLossMethod==CloseLoss_ADXW)) //{ // ulong adxw_handle_tmp=0; // {if(!GlobalGetUlong("LIP_"+TheSymbol+"_ADXW",adxw_handle_tmp)) // { // //{if(LastError!=0) // //{ // // Print("LIP: adxw_handle = ",adxw_handle_tmp," error = ",LastError); // //}}//if(LastError!=0) // return(INIT_FAILED); // }}//if(!GlobalGetUlong("LIP_"+TheSymbol+"_ADXW",adxw_handle_tmp)) // Print("LIP: adxw_handle = ",adxw_handle_tmp," error = ",LastError); // adxw_handle=int(adxw_handle_tmp); // ResetLastError(); // {if(!ChartIndicatorAdd(0,(int)ChartGetInteger(0,CHART_WINDOWS_TOTAL),adxw_handle)) // { // LastError=GetLastError(); // Print("LIP: Не добавлен adxw_zat_117!!!"," error = ",LastError); // return(INIT_FAILED); // }}//if(!ChartIndicatorAdd(0,(int)ChartGetInteger(0,CHART_WINDOWS_TOTAL),adxw_handle)) //}}//if((OpenMethod==Open_ADXW)||(CloseProfitMethod==CloseProfit_ADXW)||(CloseLossMethod==CloseLoss_ADXW)) //----- Извлекаем ChartID из глобальной переменной - не проходит! //----- Ищем уже развернутый ADXW //----- Рассчитываем короткое имя индикатора ChartID_Str=IntegerToString(ChartID()); IndicatorShortName=vers+" "+StringSubstr(ChartID_Str,StringLen(ChartID_Str)-3); IndicatorSetString(INDICATOR_SHORTNAME,IndicatorShortName); //----- Глобальные параметры TheSymbol=Symbol(); //DoItCommand=false; //----- Настройка массивов ArrayResize(inSelectSym,nSymSelectList); ArrayResize(inEliminatSym,nSymEliminatList); ArrayResize(inSelectMag,nMagSelectList); ArrayResize(inEliminatMag,nMagEliminatList); ArrayResize(inSelectTick,nTickSelectList); ArrayResize(inEliminatTick,nTickEliminatList); //----- Настройки для отбора по инструменту {switch(SelSym) { case SelSym_all: { inSelectSym[0]=""; break; } case SelSym_curr: { inSelectSym[0]=TheSymbol; break; } case SelSym_user: { inSelectSym[0]=SelectorSymbol; break; } case SelSym_but: { inEliminatSym[0]=SelectorSymbol; break; } case SelSym_list: { FillSymSelect(inSelectSym); break; } case SelSym_butlist: { FillSymEliminat(inEliminatSym); break; } case SelSym_listbutlist: { FillSymSelect(inSelectSym); FillSymEliminat(inEliminatSym); break; } default: { inSelectSym[0]=""; } }}//switch(SelSym) //----- Настройки для отбора по магику {switch(SelMag) { case SelMag_all: { inSelectMag[0]=0; break; } case SelMag_user: { inSelectMag[0]=SelectorMagic; break; } case SelMag_but: { inEliminatMag[0]=SelectorMagic; break; } case SelMag_list: { FillMagSelect(inSelectMag); break; } case SelMag_butlist: { FillMagEliminat(inEliminatMag); break; } case SelMag_listbutlist: { FillMagSelect(inSelectMag); FillMagEliminat(inEliminatMag); break; } default: { inSelectMag[0]=0; } }}//switch(SelMag) //----- Настройки для отбора по тикету {switch(SelTick) { case SelTick_all: { inSelectTick[0]=0; break; } case SelTick_user: { inSelectTick[0]=SelectorTicket; break; } case SelTick_but: { inEliminatTick[0]=SelectorTicket; break; } case SelTick_list: { FillTickSelect(inSelectTick); break; } case SelTick_butlist: { FillTickEliminat(inEliminatTick); break; } case SelTick_listbutlist: { FillTickSelect(inSelectTick); FillTickEliminat(inEliminatTick); break; } default: { inSelectTick[0]=0; } }}//switch(SelMag) //----- Настройки таймера {if(!MQLInfoInteger(MQL_TESTER)) //Не тестирование { int err=-1; int count=50; {while((err!=0)&&(count>0)) { ResetLastError(); EventSetMillisecondTimer(SetMSTimer); //Установка таймера XXX миллисекунд err=GetLastError(); {if(err!=0) { Sleep(50); Print("LIP: EventSetMillisecondTimer n=",count," err >>",err); }}//if(err!=0) count--; }}//while((err!=0)&&(count>0)) }}//if(!MQLInfoInteger(MQL_TESTER)) //----- Установка и расчет параметров окна индикатора {if(GraphUse) { IndicatorSetInteger(INDICATOR_DIGITS,0); nSubWindow=ChartWindowFind(0,IndicatorShortName); //Что странно, ожидалось что будет работать ProgramName IndHeigh=ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,nSubWindow); IndicatorSetDouble(INDICATOR_MINIMUM,0.0); IndicatorSetDouble(INDICATOR_MAXIMUM,IndHeigh); nFirstBar=(int)ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR); kScale=((ChartGetInteger(0,CHART_WIDTH_IN_PIXELS)>0) //Расчет масштаба графика (баров на пиксел) ?((double)ChartGetInteger(0,CHART_WIDTH_IN_BARS)/ChartGetInteger(0,CHART_WIDTH_IN_PIXELS)) :(1)); }}//if(GraphUse) //----- Запрашиваем историю сделок и ордеров за указанный период серверного времени. {if(!HistorySelect(0,TimeCurrent())) { Print("LIP: HistorySelect Error!"); return(INIT_FAILED); }}//Если неудачно - выходим //----- Определение количества ордеров, сделок, позиций. Создание графических объектов. nColo=0; //Счетчик колонок вывода //----- Открытые позиции {if(PositionsView) { Positions_Total=PositionsTotal(); //Текущие позиции Sel_Positions_Total=CalcPositionsTotal(inSelectSym,inEliminatSym,SelSym, inSelectMag,inEliminatMag,SelMag, inSelectTick,inEliminatTick,SelTick);//Текущие позиции отобранные {if(GraphUse) { CreateColoLabel("LIP",ColoStep*nColo, "Position="+IntegerToString(Sel_Positions_Total)+"/"+IntegerToString(Positions_Total));//Создаём графический объект заголовка колонки CreateColo("LIP",ColoStep*nColo,Positions_Total); //Создаём графический объект для колонки позиций }}//if(GraphUse) Positions_Total_Old=Positions_Total; //Текущие позиции в буфер Sel_Positions_Total_Old=Sel_Positions_Total; //Текущие позиции отобранные в буфер nColo++; }}//if(PositionsView) //----- Открытые отложенные ордера {if(OrdersView) { Orders_Total=OrdersTotal(); //Текущие лимитные ордера Sel_Orders_Total=CalcOrdersTotal(inSelectSym,inEliminatSym,SelSym, inSelectMag,inEliminatMag,SelMag, inSelectTick,inEliminatTick,SelTick); //Текущие лимитные ордера отобранные CreateColoLabel("LIO",ColoStep*nColo, "Order="+IntegerToString(Sel_Orders_Total)+"/"+IntegerToString(Orders_Total));//Создаём графический объект заголовка колонки CreateColo("LIO",ColoStep*nColo,Orders_Total); //Создаём графический объект для колонки ордеров Orders_Total_Old=Orders_Total; //Текущие лимитные ордера в буфер Sel_Orders_Total_Old=Sel_Orders_Total; //Текущие лимитные ордера отобранные в буфер nColo++; }}//if(OrdersView) //----- Выполненные ордера в истории {if(HistoryOrdersView) { History_Orders_Total=HistoryOrdersTotal(); //Закрытые рыночные ордера Sel_History_Orders_Total=CalcHistoryOrdersTotal(inSelectSym,inEliminatSym,SelSym, inSelectMag,inEliminatMag,SelMag, inSelectTick,inEliminatTick,SelTick);//Закрытые рыночные ордера отобранные {if(GraphUse) { CreateColoLabel("LHO",ColoStep*nColo, "History_Order="+IntegerToString(Sel_History_Orders_Total)+"/"+IntegerToString(History_Orders_Total));//Создаём графический объект заголовка колонки CreateColo("LHO",ColoStep*nColo,History_Orders_Total); //Создаём графический объект для колонки ордеров в истории }}//if(GraphUse) History_Orders_Total_Old=History_Orders_Total; //Закрытые рыночные ордера в буфер Sel_History_Orders_Total_Old=Sel_History_Orders_Total; //Закрытые рыночные ордера отобранные в буфер nColo++; }}//if(HistoryOrdersView) //----- Сделки в истории {if(HistoryDealsView) { History_Deals_Total=HistoryDealsTotal(); //Совершенные сделки (выполненные ордера) Sel_History_Deals_Total=CalcHistoryDealsTotal(inSelectSym,inEliminatSym,SelSym, inSelectMag,inEliminatMag,SelMag, inSelectTick,inEliminatTick,SelTick);//Совершенные сделки (выполненные ордера) отобранные {if(GraphUse) { CreateColoLabel("LHD",ColoStep*nColo, "History_Deal="+IntegerToString(Sel_History_Deals_Total)+"/"+IntegerToString(History_Deals_Total));//Создаём графический объект заголовка колонки CreateColo("LHD",ColoStep*nColo,History_Deals_Total); //Создаём графический объект для колонки сделок в истории }}//if(GraphUse) History_Deals_Total_Old=History_Deals_Total; //Совершенные сделки (выполненные ордера) в буфер Sel_History_Deals_Total_Old=Sel_History_Deals_Total; //Совершенные сделки (выполненные ордера) отобранные в буфер nColo++; }}//if(HistoryDealsView) //----- Обнуление глобальных переменных datetime TimeSet=0; {for(int i=1;i<=3;i++)//Перебор типов Команд { {for(int j=0;j<=1;j++)//Перебор типов Позиций { BuseInd[(int)CommandCode((enCommandType)i,(ENUM_POSITION_TYPE)j)]=0; //Освобождаем канал BuseInd_N=0 по данным типам команд и позиций GlobalSetUlong("LIP_"+TheSymbol+"_Command_"+IntegerToString(CommandCode((enCommandType)i,(ENUM_POSITION_TYPE)j)),TimeSet,0);//Сбрасываем команды Command_N=0 GlobalSetUlong("LIP_"+TheSymbol+"_Ready_"+IntegerToString(CommandCode((enCommandType)i,(ENUM_POSITION_TYPE)j)),TimeSet,1); //Устанавливаем флаги завершения Ready_N=1 }}//for(int j=0;i<=1;i++) }}//for(int i=1;i<=2;i++) //----- return(INIT_SUCCEEDED); }//On_Init() // //============================================================================================= MQL5 === // On_Tick() - Основной обработчик тиков //------------------------------------------------------------------------------------------------------ void On_Tick(){ //----- Прерываем загрузку, если индикатор уже есть {if((ChartWindowFind(0,IndicatorShortName)>=0)&&(ChartWindowFind(0,ProgramName)>=0)) { Print("LIP: Abort loading indicator: ",ProgramName); ChartIndicatorDelete(0,ChartWindowFind(0,ProgramName),ProgramName); }}//if((ChartWindowFind(0,IndicatorShortName)>=0)&&(ChartWindowFind(0,ProgramName)>=0)) //----- //{if(!gInTimer) //{ gnTick++; // gInTimer=false; //}}//if(!InTimer) {if(gnTick>4294967000) { gnTick=100; }}//if(gnTick>4294967000) //----- Определяем параметры параллельного индикатора !!! {if((ParallelIndicatorHandle<0)&&(GlobalVariableGet("IndCalc"+Par_03)>0.0)) { Print(ThisID+": OnCalculate(): ParallelInicatorName=",ParallelInicatorName," ChartID()=",ChartID()); //Определяем хендл параллельного индикатора ParallelIndicatorHandle=ChartIndicatorGet(ChartID(),ChartWindowFind(ChartID(),ParallelInicatorName),ParallelInicatorName); {if(ParallelIndicatorHandle>0) { Print(ThisID+": OnCalculate(): SEARCH_OK ParallelIndicatorHandle="+IntegerToString(ParallelIndicatorHandle)); }else{ Print(ThisID+": OnCalculate(): SEARCH_FAILED ParallelIndicatorHandle="+IntegerToString(ParallelIndicatorHandle)); return(rates_total); }}//if(ParallelIndicatorHandle<0) //Имя параллельного индикатора по хендлу ParallelInicatorName=""; IndicatorName_Search_Handle(ParallelIndicatorHandle,ParallelInicatorName); Print(ThisID+": OnCalculate(): Handle Base ParallelInicatorName="+ParallelInicatorName); }}//if(ParallelIndicatorHandle<0) //----- Установка и расчет параметров окна индикатора {if(GraphUse) { ChartID_Str=IntegerToString(ChartID()); IndicatorShortName=vers+" "+StringSubstr(ChartID_Str,StringLen(ChartID_Str)-3); //ProgramName=MQLInfoString(MQL_PROGRAM_NAME); nSubWindow=ChartWindowFind(0,IndicatorShortName); IndHeigh=ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,nSubWindow); IndicatorSetDouble(INDICATOR_MINIMUM,0.0); IndicatorSetDouble(INDICATOR_MAXIMUM,IndHeigh); nFirstBar=(int)ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR); kScale=((ChartGetInteger(0,CHART_WIDTH_IN_PIXELS)>0) //Расчет масштаба графика (баров на пиксел) ?((double)ChartGetInteger(0,CHART_WIDTH_IN_BARS)/ChartGetInteger(0,CHART_WIDTH_IN_PIXELS)) :(1)); }}//if(GraphUse) //----- Запрашиваем историю сделок и ордеров за указанный период серверного времени. {if(!HistorySelect(0,TimeCurrent())) { Print("LIP: HistorySelect Error!"); return; }}//Если неудачно - выходим //----- Определение количества ордеров, сделок, позиций. Вывод графических объектов. nColo=0; //Счетчик колонок вывода //----- Список открытых позиций {if((PositionsView)&&(GraphUse)) { Positions_Total=PositionsTotal(); //Текущие позиции Sel_Positions_Total=CalcPositionsTotal(inSelectSym,inEliminatSym,SelSym, inSelectMag,inEliminatMag,SelMag, inSelectTick,inEliminatTick,SelTick);//Текущие позиции отобранные {if(Sel_Positions_Total!=Sel_Positions_Total_Old) //Пересчет - перерисовка при изменении количества { DeleteColo("LIP",Positions_Total_Old); //Колонка позиций CreateColo("LIP",ColoStep*nColo,Positions_Total); }}//if(Sel_Positions_Total!=Sel_Positions_Total_Old) MoveColoLabel( "LIP", //Заголовок колонки ColoStep*nColo, "Position="+ IntegerToString(Sel_Positions_Total)+"/"+ IntegerToString(Positions_Total)+ ((SummView) ?(" ="+DoubleToString(CalcPositionsSumm(inSelectSym,inEliminatSym,SelSym, inSelectMag,inEliminatMag,SelMag, inSelectTick,inEliminatTick,SelTick),2)+" ") :(""))+ "" ); //----- {if(Positions_Total>=0) { nRow=0; CopyTime(TheSymbol,PERIOD_CURRENT,(nFirstBar-(int)((ColoStep*nColo+ColoShift)*kScale)),1,gTime); {for(int i=Positions_Total-1;i>=0;i--) { sTXW="LIP_"+IntegerToString(i); //Устанавливаем имя для текcтового объекта ObjectSetString(0,sTXW,OBJPROP_TEXT," "); //Обнуление строки вывода ulong Pos_Tick=PositionGetTicket(i); //Выбираем позицию по номеру в списке {if(Pos_Tick<=0){continue;}} //Неудачно - следующий {if(!CheckSym(PositionGetString(POSITION_SYMBOL),inSelectSym,inEliminatSym,SelSym)){continue;}}//Не тот символ - следующий {if(!CheckMag(PositionGetInteger(POSITION_MAGIC),inSelectMag,inEliminatMag,SelMag)){continue;}}//Проверка соответствия магика модели по критерию выбора {if(!CheckTick(PositionGetInteger(POSITION_TICKET),inSelectTick,inEliminatTick,SelTick)){continue;}}//Проверка соответствия тикета модели по критерию выбора ENUM_POSITION_TYPE OrdType=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); TypeStringPos=EnumToString(OrdType); StringReplace(TypeStringPos,"POSITION_TYPE_",""); DataStringPos= " "+ IntegerToString(i)+"."+ PositionGetString(POSITION_SYMBOL)+" "+ TypeStringPos+" ["+ IntegerToString(Pos_Tick)+"-"+ IntegerToString(PositionGetInteger(POSITION_MAGIC))+"-"+ DoubleToString(PositionGetDouble(POSITION_VOLUME),2)+"-"+ DoubleToString(PositionGetDouble(POSITION_PRICE_OPEN), (int)SymbolInfoInteger(PositionGetString(POSITION_SYMBOL),SYMBOL_DIGITS))+"]="+ DoubleToString(PositionGetDouble(POSITION_PROFIT),2)+" "+ ""; ResetLastError(); {if(!ObjectSetInteger( 0, //Идентификатор чарта sTXW, //Имя объекта OBJPROP_TIME, //Изменяем координату времени объекта gTime[0] )) { Print("LIP: ObjectSetInteger0 Error=",GetLastError()); continue; }}//if(!ObjectSetInteger(... ResetLastError(); {if(!ObjectSetDouble( 0, //Идентификатор чарта sTXW, //Имя объекта OBJPROP_PRICE, //Изменяем координату цены объекта IndHeigh-11*(nRow+1) )) { Print("LIP: ObjectSetDouble0 Error=",GetLastError()); continue; }else{ nRow++; }}//if(!ObjectSetDouble(... ObjectSetString(0,sTXW,OBJPROP_TEXT,DataStringPos+""); }}//for(int i=Positions_Total-1;i>=0;i--) }}//if(Positions_Total>=0) //----- Запомним текущие счетчики Positions_Total_Old=Positions_Total; //Текущие позиции Sel_Positions_Total_Old=Sel_Positions_Total; //Текущие позиции отобранные //----- Инкремент счетчика колонок nColo++; }}//if(PositionsView) //----- Список открытых отложенных ордеров {if((OrdersView)&&(GraphUse)) { Orders_Total=OrdersTotal(); //Текущие лимитные ордера Sel_Orders_Total=CalcOrdersTotal(inSelectSym,inEliminatSym,SelSym, inSelectMag,inEliminatMag,SelMag, inSelectTick,inEliminatTick,SelTick); //Текущие лимитные ордера отобранные {if(Sel_Orders_Total!=Sel_Orders_Total_Old) //Пересчет - перерисовка при изменении количества { DeleteColo("LIO",Orders_Total_Old); //Колонка ордеров CreateColo("LIO",ColoStep*nColo,Orders_Total); }}//if(Sel_Orders_Total!=Sel_Orders_Total_Old) MoveColoLabel("LIO",ColoStep*nColo,"Order="+IntegerToString(Sel_Orders_Total)+"/"+IntegerToString(Orders_Total));//Заголовок колонки //----- {if(Orders_Total>=0) { nRow=0; CopyTime(TheSymbol,PERIOD_CURRENT,(nFirstBar-(int)((ColoStep*nColo+ColoShift)*kScale)),1,gTime); {for(int i=Orders_Total-1;i>=0;i--) { sTXW="LIO_"+IntegerToString(i); //Устанавливаем имя для текcтового объекта ObjectSetString(0,sTXW,OBJPROP_TEXT," "); //Обнуление строки вывода ulong Ord_Tick=OrderGetTicket(i); //Выбираем ордер по номеру в списке {if(Ord_Tick<=0){continue;}} //Неудачно - следующий {if(!CheckSym(OrderGetString(ORDER_SYMBOL),inSelectSym,inEliminatSym,SelSym)){continue;}}//Не тот символ - следующий {if(!CheckMag(OrderGetInteger(ORDER_MAGIC),inSelectMag,inEliminatMag,SelMag)){continue;}}//Проверка соответствия магика модели по критерию выбора {if(!CheckTick(OrderGetInteger(ORDER_TICKET),inSelectTick,inEliminatTick,SelTick)){continue;}}//Проверка соответствия тикета модели по критерию выбора ENUM_ORDER_TYPE OrdType=(ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE); TypeStringOrd=EnumToString(OrdType); StringReplace(TypeStringOrd,"ORDER_TYPE_",""); DataStringOrd= " "+ IntegerToString(i)+"."+ OrderGetString(ORDER_SYMBOL)+" "+ TypeStringOrd+" ["+ IntegerToString(Ord_Tick)+"-"+ IntegerToString(OrderGetInteger(ORDER_MAGIC))+"-"+ DoubleToString(OrderGetDouble(ORDER_VOLUME_CURRENT),2)+"-"+ DoubleToString(OrderGetDouble(ORDER_PRICE_OPEN),(int)SymbolInfoInteger(OrderGetString(ORDER_SYMBOL),SYMBOL_DIGITS))+"]"+ ""; ResetLastError(); {if(!ObjectSetInteger( 0, //Идентификатор чарта sTXW, //Имя объекта OBJPROP_TIME, //Изменяем координату времени объекта gTime[0] )) { Print("LIP: ObjectSetInteger1 Error=",GetLastError()); continue; }}//if(!ObjectSetInteger(... ResetLastError(); {if(!ObjectSetDouble( 0, //Идентификатор чарта sTXW, //Имя объекта OBJPROP_PRICE, //Изменяем координату цены объекта IndHeigh-11*(nRow+1) )) { Print("LIP: ObjectSetDouble1 Error=",GetLastError()); continue; }else{ nRow++; }}//if(!ObjectSetDouble(... ObjectSetString(0,sTXW,OBJPROP_TEXT,DataStringOrd+""); }}//for(int i=Orders_Total-1;i>=0;i--) }}//if(Orders_Total>=0) //----- Запомним текущие счетчики Orders_Total_Old=Orders_Total; //Текущие лимитные ордера Sel_Orders_Total_Old=Sel_Orders_Total; //Текущие лимитные ордера отобранные //----- Инкремент счетчика колонок nColo++; }}//if(OrdersView) //----- Список ордеров в истории {if((HistoryOrdersView)&&(GraphUse)) { History_Orders_Total=HistoryOrdersTotal(); //Закрытые рыночные ордера Sel_History_Orders_Total=CalcHistoryOrdersTotal(inSelectSym,inEliminatSym,SelSym, inSelectMag,inEliminatMag,SelMag, inSelectTick,inEliminatTick,SelTick);//Закрытые рыночные ордера отобранные {if(Sel_History_Orders_Total!=Sel_History_Orders_Total_Old)//Пересчет - перерисовка при изменении количества { DeleteColo("LHO",History_Orders_Total_Old); //Колонка истории ордеров CreateColo("LHO",ColoStep*nColo,History_Orders_Total); }}//if(Sel_History_Orders_Total!=Sel_History_Orders_Total_Old) MoveColoLabel("LHO",ColoStep*nColo,"History Order="+IntegerToString(Sel_History_Orders_Total)+"/"+IntegerToString(History_Orders_Total));//Заголовок колонки //----- {if(History_Orders_Total>=0) { nRow=0; CopyTime(TheSymbol,PERIOD_CURRENT,(nFirstBar-(int)((ColoStep*nColo+ColoShift)*kScale)),1,gTime); {for(int i=History_Orders_Total-1;i>=0;i--) { sTXW="LHO_"+IntegerToString(i); //Устанавливаем имя для текcтового объекта ObjectSetString(0,sTXW,OBJPROP_TEXT," "); //Обнуление строки вывода ulong Ord_Tick=HistoryOrderGetTicket(i); //Выбираем ордер по номеру в списке {if(Ord_Tick<=0){continue;}} //Неудачно - следующий {if(!CheckSym(HistoryOrderGetString(Ord_Tick,ORDER_SYMBOL),inSelectSym,inEliminatSym,SelSym)){continue;}}//Не тот символ - следующий {if(!CheckMag(HistoryOrderGetInteger(Ord_Tick,ORDER_MAGIC),inSelectMag,inEliminatMag,SelMag)){continue;}}//Проверка соответствия магика модели по критерию выбора {if(!CheckTick(HistoryOrderGetInteger(Ord_Tick,ORDER_TICKET),inSelectTick,inEliminatTick,SelTick)){continue;}}//Проверка соответствия тикета модели по критерию выбора ENUM_ORDER_TYPE OrdType=(ENUM_ORDER_TYPE)HistoryOrderGetInteger(Ord_Tick,ORDER_TYPE); TypeStringOrd=EnumToString(OrdType); StringReplace(TypeStringOrd,"ORDER_TYPE_",""); DataStringOrd= " "+ IntegerToString(i)+"."+ HistoryOrderGetString(Ord_Tick,ORDER_SYMBOL)+" "+ TypeStringOrd+" ["+ IntegerToString(Ord_Tick)+"-"+ IntegerToString(HistoryOrderGetInteger(Ord_Tick,ORDER_MAGIC))+"-"+ DoubleToString(HistoryOrderGetDouble(Ord_Tick,ORDER_VOLUME_INITIAL),2)+"-"+ DoubleToString(HistoryOrderGetDouble(Ord_Tick,ORDER_PRICE_OPEN), (int)SymbolInfoInteger(HistoryOrderGetString(Ord_Tick,ORDER_SYMBOL),SYMBOL_DIGITS))+"]"+ ""; ResetLastError(); {if(!ObjectSetInteger( 0, //Идентификатор чарта sTXW, //Имя объекта OBJPROP_TIME, //Изменяем координату времени объекта gTime[0] )) { Print("LIP: ObjectSetInteger2 Error=",GetLastError()); continue; }}//if(!ObjectSetInteger(... ResetLastError(); {if(!ObjectSetDouble( 0, //Идентификатор чарта sTXW, //Имя объекта OBJPROP_PRICE, //Изменяем координату цены объекта IndHeigh-11*(nRow+1) )) { Print("LIP: ObjectSetDouble2 Error=",GetLastError()); continue; }else{ nRow++; }}//if(!ObjectSetDouble(... ObjectSetString(0,sTXW,OBJPROP_TEXT,DataStringOrd+""); }}//for(int i=History_Orders_Total-1;i>=0;i--) }}//if(History_Orders_Total>=0) //----- Запомним текущие счетчики History_Orders_Total_Old=History_Orders_Total; //Закрытые рыночные ордера Sel_History_Orders_Total_Old=Sel_History_Orders_Total; //Закрытые рыночные ордера отобранные //----- Инкремент счетчика колонок nColo++; }}//if(HistoryOrdersView) //----- Список сделок в истории {if((HistoryDealsView)&&(GraphUse)) { History_Deals_Total=HistoryDealsTotal(); //Совершенные сделки (выполненные ордера) Sel_History_Deals_Total=CalcHistoryDealsTotal(inSelectSym,inEliminatSym,SelSym, inSelectMag,inEliminatMag,SelMag, inSelectTick,inEliminatTick,SelTick);//Совершенные сделки (выполненные ордера) отобранные {if(Sel_History_Deals_Total!=Sel_History_Deals_Total_Old)//Пересчет - перерисовка при изменении количества { DeleteColo("LHD",History_Deals_Total_Old); //Колонка истории позиций CreateColo("LHD",ColoStep*nColo,History_Deals_Total); }}//if(Sel_History_Deals_Total!=Sel_History_Deals_Total_Old) MoveColoLabel( "LHD", ColoStep*nColo, "History Dial="+ IntegerToString(Sel_History_Deals_Total)+"/"+ IntegerToString(History_Deals_Total)+ ((SummView) ?(" ="+DoubleToString(CalcHistoryDealsSumm( inSelectSym,inEliminatSym,SelSym, inSelectMag,inEliminatMag,SelMag, inSelectTick,inEliminatTick,SelTick),2)+" ") :(""))+ "" );//Заголовок колонки //----- {if(History_Deals_Total>=0) { nRow=0; CopyTime(TheSymbol,PERIOD_CURRENT,(nFirstBar-(int)((ColoStep*nColo+ColoShift)*kScale)),1,gTime); {for(int i=History_Deals_Total-1;i>=0;i--) { sTXW="LHD_"+IntegerToString(i); //Устанавливаем имя для текcтового объекта ObjectSetString(0,sTXW,OBJPROP_TEXT," "); //Обнуление строки вывода ulong Deal_Tick=HistoryDealGetTicket(i); //Выбираем ордер по номеру в списке {if(Deal_Tick<=0){continue;}} //Неудачно - следующий {if(!CheckSym(HistoryDealGetString(Deal_Tick,DEAL_SYMBOL),inSelectSym,inEliminatSym,SelSym)){continue;}}//Не тот символ - следующий {if(!CheckMag(HistoryDealGetInteger(Deal_Tick,DEAL_MAGIC),inSelectMag,inEliminatMag,SelMag)){continue;}}//Проверка соответствия магика модели по критерию выбора {if(!CheckTick(HistoryDealGetInteger(Deal_Tick,DEAL_TICKET),inSelectTick,inEliminatTick,SelTick)){continue;}}//Проверка соответствия тикета модели по критерию выбора ENUM_DEAL_TYPE DealType=(ENUM_DEAL_TYPE)HistoryDealGetInteger(Deal_Tick,DEAL_TYPE); TypeStringDeal=EnumToString(DealType); StringReplace(TypeStringDeal,"DEAL_TYPE_",""); DataStringDeal= " "+ IntegerToString(i)+"."+ HistoryDealGetString(Deal_Tick,DEAL_SYMBOL)+" "+ TypeStringDeal+" ["+ IntegerToString(Deal_Tick)+"-"+ IntegerToString(HistoryDealGetInteger(Deal_Tick,DEAL_MAGIC))+"-"+ DoubleToString(HistoryDealGetDouble(Deal_Tick,DEAL_VOLUME),2)+"-"+ DoubleToString(HistoryDealGetDouble(Deal_Tick,DEAL_PRICE), (int)SymbolInfoInteger(HistoryDealGetString(Deal_Tick,DEAL_SYMBOL),SYMBOL_DIGITS))+"]="+ DoubleToString(HistoryDealGetDouble(Deal_Tick,DEAL_PROFIT),2)+" "+ ""; ResetLastError(); {if(!ObjectSetInteger( 0, //Идентификатор чарта sTXW, //Имя объекта OBJPROP_TIME, //Изменяем координату времени объекта gTime[0] )) { Print("LIP: ObjectSetInteger3 Error=",GetLastError()); continue; }}//if(!ObjectSetInteger(... ResetLastError(); {if(!ObjectSetDouble( 0, //Идентификатор чарта sTXW, //Имя объекта OBJPROP_PRICE, //Изменяем координату цены объекта IndHeigh-11*(nRow+1) )) { Print("LIP: ObjectSetDouble3 Error=",GetLastError()); continue; }else{ nRow++; }}//if(!ObjectSetDouble(... ObjectSetString(0,sTXW,OBJPROP_TEXT,DataStringDeal+""); }}//for(int i=History_Deals_Total-1;i>=0;i--) }}//if(History_Deals_Total>=0) //----- Запомним текущие счетчики History_Deals_Total_Old=History_Deals_Total; //Совершенные сделки (выполненные ордера) Sel_History_Deals_Total_Old=Sel_History_Deals_Total; //Совершенные сделки (выполненные ордера) отобранные //----- Инкремент счетчика колонок nColo++; }}//if(HistoryDealsView) //----- Формируем строку комментария на чарте {if((CommentView)&&(GraphUse)) { CommentLine[0]=""+ "PositionsTotal="+IntegerToString(Positions_Total)+" "+ "OrdersTotal="+IntegerToString(Orders_Total)+" "+ ""; CommentLine[1]=""+ "HistoryOrdersTotal="+IntegerToString(History_Orders_Total)+" "+ "HistoryDealsTotal="+IntegerToString(History_Deals_Total)+" "+ ""; Comment( CommentLine[0]+" "+CommentLine[1]+" "+ (string)(datetime)(TimeCurrent()-ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR,0)*PeriodSeconds(PERIOD_CURRENT))+" "+ _n+"Ticks>>"+IntegerToString(gnTick)+" Tims>>"+IntegerToString(gnTimer)); }}//if(CommentView) //----- Перерисовка чарта {if(GraphUse){ChartRedraw();}} //----- Блок для проверки обмена с советником //Протокол обмена между индикатором и советником, для передачи команд на открытие-закрытие позиций из индикатора в советник. //Глобально (глобальные переменные) //Переменные: //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. Исх: // Флаг обратной связи - сбрасывается передающей стороной при отправке команды, выставляется принимающей стороной при исполнении команды: // Имя переменной "LIP_"+TheSymbol+"_Ready_"+IntegerToString(iCommandCode) // Значение: // 0 - при наличии ненулевой команды инициирует выполнение на принимающей стороне. // 1 - устанавливается принимающей стороной //----- Блок тестирования обмена //----- Инициатор выполнения //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<=3;i++)//Перебор типов Команд { {for(int j=0;j<=1;j++)//Перебор типов Позиций { {if(BuseInd[(int)CommandCode((enCommandType)i,(ENUM_POSITION_TYPE)j)]==0) //Если канал свободен BuseInd_N=0 по данным типам команд и позиций { //Проверка условия открытия, получение типа позиции {if( CheckCondition(OpenMethod,CloseProfitMethod,CloseLossMethod,CommandType,PositionType) && (CommandType==(enCommandType)i) && (PositionType==(ENUM_POSITION_TYPE)j)) { if(PrintDebug)Print("LIP: i=",i," j=",j," CommandCode=",(int)CommandCode((enCommandType)i,(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 ReadyGet=0; {for(int i=1;i<=3;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)),ReadyGet))&&(ReadyGet==1))//Если флаг выполнения установлен Ready_N=1 { BuseInd[(int)CommandCode((enCommandType)i,(ENUM_POSITION_TYPE)j)]=0; //Освобождение канала: Сброс флага занято Buse_N=0 //if(PrintInfo)Print("LIP: задача "+IntegerToString(CommandCode((enCommandType)i,(ENUM_POSITION_TYPE)j))+" выполнена! "); {if(PrintInfo) { {switch((int)CommandCode((enCommandType)i,(ENUM_POSITION_TYPE)j)) { case(1)://Open Buy { Print("LIP: выполнена команда 1>>"+" Open Buy"+" gnTick="+IntegerToString(gnTick)); break; } case(2)://Open Buy { Print("LIP: выполнена команда 2>>"+" Open Sell"+" gnTick="+IntegerToString(gnTick)); break; } case(3)://Open Buy { Print("LIP: выполнена команда 3>>"+" Close Buy PROFIT"+" gnTick="+IntegerToString(gnTick)); break; } case(4)://Open Buy { Print("LIP: выполнена команда 4>>"+" Close Sell PROFIT"+" gnTick="+IntegerToString(gnTick)); break; } case(5)://Open Buy { Print("LIP: выполнена команда 5>>"+" Close Buy LOSS"+" gnTick="+IntegerToString(gnTick)); break; } case(6)://Open Buy { Print("LIP: выполнена команда 6>>"+" Close Sell LOSS"+" gnTick="+IntegerToString(gnTick)); break; } default: { break; } }}//switch((int)CommandCode((enCommandType)i,(ENUM_POSITION_TYPE)j)) }}//if(PrintInfo) }}//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++) //----- //Print("LIP: gnTick=",gnTick); //Comment("LIP: gnTick=",gnTick); //----- return; }//On_Tick() // //============================================================================================= MQL5 === // On_Timer - Обработка событий по таймеру //------------------------------------------------------------------------------------------------------ void On_Timer(){ //----- gnTimer++; {if(gnTimer>4294967000) { gnTimer=100; }}//if(gnTimer>4294967000) gInTimer=true; On_Tick(); }//On_Timer()