//====================================================================================================== // LibreNetka Function1_5 v4.106 MQL5 // Основные функции алгоритма // Librecoin (c)2014-2017 //====================================================================================================== #property strict //====================================================================================================== // INCLUDE - подключаемые модули //------------------------------------------------------------------------------------------------------ //----- Обратные ссылки на основной файл проекта #include "LIP_Ref_5_v1.001.mqh" //====================================================================================================== // MAIN FUNCTIONS //------------------------------------------------------------------------------------------------------ // //====================================================================================================== // B4BClose();//v66.154 - Закрывает все возможные ордера встречно //====================================================================================================== bool B4BClose( long iMagic, int inGrides){ //Print("****** B4BClose 0 >>"); if (!B4BCloseOn) {return(false);} bool Closed=false, BePair=true; double //AddCom=0.0, closeLot=0, closeProfit=0, lossLotBUY=0, lossLotSELL=0, lossBUY, lossSELL, profitLotBUY=0, profitLotSELL=0, profitBUY, profitSELL; long OrderMagicN=iMagic, Ord_Tick=-1, nMLossBUY=-1, nMLossSELL=-1, nMProfitBUY=-1, nMProfitSELL=-1; // if (AccountFreeMargin()>B4BCloseLim*MathMax(AccountInfoDouble(ACCOUNT_EQUITY),AccountInfoDouble(ACCOUNT_BALANCE))) {return(true);} // if (AccountFreeMargin()>iB4BCloseLim*AccountInfoDouble(ACCOUNT_BALANCE)) {return(true);}//Порог от Equity для инициации закрытия //if (AccountInfoDouble(ACCOUNT_EQUITY)=0;i--) {//перебор всех ордеров ulong Pos_Tick=PositionGetTicket(i);//Выбираем позицию по номеру в списке {if(Pos_Tick<=0){continue;}}//Неудачно - следующий {if(!PositionSelectByTicket(Pos_Tick)){continue;}}//Выбираем позицию по тикету? Неудачно - следующий {if(PositionGetString(POSITION_SYMBOL)!=TheSymbol){continue;}} OrderMagicN=PositionGetInteger(POSITION_MAGIC); {if((OrderMagicN=iMagic+inGrides)){continue;}} //Отбор по магику //Ищем ордер с максимальной прибылью на лот if (PositionGetDouble(POSITION_PROFIT) //+PositionGetDouble(POSITION_COMISSION) +PositionGetDouble(POSITION_SWAP)-10*AddComPrice*PositionGetDouble(POSITION_VOLUME)>0.00001) { if ((OP_TYPE)PositionGetInteger(POSITION_TYPE)==OP_BUY) { if (PositionGetDouble(POSITION_PROFIT) //+PositionGetDouble(POSITION_COMISSION) +PositionGetDouble(POSITION_SWAP)-10*AddComPrice*PositionGetDouble(POSITION_VOLUME)>profitBUY) { nMProfitBUY=Ord_Tick; profitBUY=PositionGetDouble(POSITION_PROFIT) //+PositionGetDouble(POSITION_COMISSION) +PositionGetDouble(POSITION_SWAP)-10*AddComPrice*PositionGetDouble(POSITION_VOLUME); profitLotBUY=PositionGetDouble(POSITION_VOLUME); }//if(OrderProfit }//if ((OP_TYPE)PositionGetInteger(POSITION_TYPE) if ((OP_TYPE)PositionGetInteger(POSITION_TYPE)==OP_SELL) { if (PositionGetDouble(POSITION_PROFIT) //+PositionGetDouble(POSITION_COMISSION) +PositionGetDouble(POSITION_SWAP)-10*AddComPrice*PositionGetDouble(POSITION_VOLUME)>profitSELL) { nMProfitSELL=Ord_Tick; profitSELL=PositionGetDouble(POSITION_PROFIT) //+PositionGetDouble(POSITION_COMISSION) +PositionGetDouble(POSITION_SWAP)-10*AddComPrice*PositionGetDouble(POSITION_VOLUME); profitLotSELL=PositionGetDouble(POSITION_VOLUME); }//if(OrderProfit }//if ((OP_TYPE)PositionGetInteger(POSITION_TYPE) }//if(OrderProfit //Ищем ордер с максимальным убытком на лот //Ord_inf=PositionSelect(Ord_Tick,SELECT_BY_TICKET,MODE_TRADES); //if (!Ord_inf) {break;} if (PositionGetDouble(POSITION_PROFIT) //+PositionGetDouble(POSITION_COMISSION) +PositionGetDouble(POSITION_SWAP)-10*AddComPrice*PositionGetDouble(POSITION_VOLUME)<-0.00001) { if (((OP_TYPE)PositionGetInteger(POSITION_TYPE))==OP_BUY) { if (PositionGetDouble(POSITION_PROFIT) //+PositionGetDouble(POSITION_COMISSION) +PositionGetDouble(POSITION_SWAP)-10*AddComPrice*PositionGetDouble(POSITION_VOLUME)=0;y--) double lim=100; //Print("****** B4BClose 1 >>"); bool pairFoundBuy=false; if ((profitBUY>0.00001)&&(lossSELL<-0.00001))//&&(profitBUY>=-lim*lossSELL))//&&(tTrendBid[iB4BTrend]<-0.0000001))//прибыльный BUY - убыточный SELL { closeLot=MathMin(profitLotBUY,lossLotSELL); closeProfit=closeLot*(profitBUY/profitLotBUY+lossSELL/lossLotSELL); pairFoundBuy=true; if (Prn1) Print(" profitLotBUY=",profitLotBUY," lossLotSELL=",lossLotSELL);//," ltSprad=",ltSprad); } bool pairFoundSell=false; if ((profitSELL>0.00001)&&(lossBUY<-0.00001))//&&(profitSELL>=-lim*lossBUY))//&&(tTrendAsk[iB4BTrend]>0.0000001))//прибыльный SELL - убыточный BUY { closeLot=MathMin(profitLotSELL,lossLotBUY); closeProfit=closeLot*(profitSELL/profitLotSELL+lossBUY/lossLotBUY); pairFoundSell=true; if (Prn1) Print(" profitLotSELL=",profitLotSELL," lossLotBUY=",lossLotBUY);//," ltSprad=",ltSprad); } //Если пары есть - закрываем, пар нет - снимаем флаг продолжения //Print("****** B4BClose 3 >>"); {if (true //&&(false // ||((profitBUY>0.01)&&(lossSELL<-0.01)&&(profitBUY>=-lim*lossSELL)) // ||((profitSELL>0.01)&&(lossBUY<-0.01)&&(profitSELL>=-lim*lossBUY))) //&&(closeProfit>0.01*closeLot*ltSprad/Point) &&((pairFoundBuy)||(pairFoundSell)) ) { //if (Prn1) Print("**************** Close B4B *********************"); //if (Prn1) Print(" profitBUY=",profitBUY," lossSELL=",lossSELL," profitSELL=",profitSELL," lossBUY=",lossBUY); //if (closeProfit>4*closeLot*ltSprad/Point) {//Если пары есть - закрываем //Закрываем прибыльный BUY на убыточный SELL //if ((profitBUY>0.00001)&&(lossSELL<-0.00001)&&(profitBUY>=-lim*lossSELL)&&(tTrendBid[iB4BTrend]<-0.0000001))//прибыльный BUY - убыточный SELL if (pairFoundBuy) { ulong Pos_Tick=PositionSelectByTicket(nMProfitBUY); {if(Pos_Tick<=0){continue;}}//Неудачно - следующий Ord_inf=PositionCloseBy(PositionGetInteger(POSITION_TICKET),nMLossSELL); //if (Ord_inf) {B4BCloseN++;B4BCloseBN++;} if (Ord_inf) {Closed=true;} if (Prn1) Print(" profitBUY="+DoubleToString(profitBUY,2)+" nMProfitBUY="+IntegerToString(nMProfitBUY) +" lossSELL="+DoubleToString(lossSELL,2)+" nMLossSELL="+IntegerToString(nMLossSELL) +" Ord_inf="+((Ord_inf)?("true"):("false")));//," B4BCloseN (A/B/S)=",B4BCloseN,"/",B4BCloseBN,"/",B4BCloseSN); } //Если все быстрые тренды по убытку BUY убыточные - убыток увеличивается //if ((TrendMB[0])&&(TrendMB[0]))//&&(!TrendMB[1])&&(TrendMB[2])&&(TrendMB[3]))//&&(!TrendCB[2])) //Закрываем прибыльный SELL на убыточный BUY //if ((profitSELL>0.00001)&&(lossBUY<-0.00001)&&(profitSELL>=-lim*lossBUY)&&(tTrendAsk[iB4BTrend]>0.0000001))//прибыльный SELL - убыточный BUY if (pairFoundSell) { ulong Pos_Tick=PositionSelectByTicket(nMProfitSELL); {if(Pos_Tick<=0){continue;}}//Неудачно - следующий Ord_inf=PositionCloseBy(PositionGetInteger(POSITION_TICKET),nMLossBUY); //if (Ord_inf) {B4BCloseN++;B4BCloseSN++;} if (Ord_inf) {Closed=true;} if (Prn1) Print(" profitSELL="+DoubleToString(profitSELL,2)+" nMProfitSELL="+IntegerToString(nMProfitSELL) +" lossBUY="+DoubleToString(lossBUY,2)+" nMLossBUY="+IntegerToString(nMLossBUY) +" Ord_inf="+((Ord_inf)?("true"):("false")));//," B4BCloseN (A/B/S)=",B4BCloseN,"/",B4BCloseBN,"/",B4BCloseSN); } //тогда Bepair=true и будет следующий расчет } }else{ //Print("**************** BePair=false *********************"); //Если нет пар - снимаем флаг продолжения BePair=false;//расчет окончен, всё что смогли - закрыли }}//if (true }//end while return(Closed); }//B4BClose() // //====================================================================================================== // CheckBounceStop() - проверка для остановки торговли по броску //====================================================================================================== bool CheckBounceStop(string iSymbol, //int inBars, //глубина просмотра в барах М1 (минутах) bool &iBonceStopUp, //запрет вверх bool &iBonceStopDown){ //запрет вниз int nnBars=MathMax3int(BonceDeep,BonceDeep2,BonceDeep3); bool Result = false; //не стоп iBonceStopUp = false; //нет запрета вверх iBonceStopDown = false; //нет запрета вниз //----- {if(Bars(iSymbol,PERIOD_M1)BonceMax) { BonceMax=High[nCurBar]; nBonceMax=nCurBar; }}//if(High[nCurBar]>BonceMax) {if(Low[nCurBar]BonceAmpMax*_Point)&&(nBonceMax>BonceMin)) { iBonceStopDown=true; //break;//Амплитуда броска превышена - прекращаем расчет канала }}//if(BonceMax-BonceMin>BunceAmpMax) {if((BonceMax-BonceMin>BonceAmpMax*_Point)&&(nBonceMaxBunceAmpMax) }}//if(nCurBarBonceMax2) { BonceMax2=High[nCurBar]; nBonceMax2=nCurBar; }}//if(High[nCurBar]>BonceMax) {if(Low[nCurBar]BonceAmpMax2*_Point)&&(nBonceMax2>BonceMin2)) { iBonceStopDown=true; //break;//Амплитуда броска превышена - прекращаем расчет канала }}//if(BonceMax-BonceMin>BunceAmpMax) {if((BonceMax2-BonceMin2>BonceAmpMax2*_Point)&&(nBonceMax2BunceAmpMax) }}//if(nCurBarBonceMax3) { BonceMax3=High[nCurBar]; nBonceMax3=nCurBar; }}//if(High[nCurBar]>BonceMax) if(nCurBar>=ArraySize(Low))Print(" ArraySize=",ArraySize(Low)," nCurBar=",nCurBar); {if(Low[nCurBar]BonceAmpMax3*_Point)&&(nBonceMax3>BonceMin3)) { iBonceStopDown=true; //break;//Амплитуда броска превышена - прекращаем расчет канала }}//if(BonceMax-BonceMin>BunceAmpMax) {if((BonceMax3-BonceMin3>BonceAmpMax*_Point)&&(nBonceMax3BunceAmpMax) }}//if(nCurBar> nnBars=",nnBars," ArraySize=",ArraySize(Low)); //----- Уровни сопротивления и поддержки //Print("inSRLevels=",inSRLevels); //int MaxnLevels=MathMax(inSRLevels,inLevelsIn)+1; int MaxnLevels=inSRLevels+inLevelsIn+1; //Цены микроуровней ArrayResize(r,MaxnLevels); ArrayFill(r,0,MaxnLevels,Max_Int); ArrayResize(s,MaxnLevels); ArrayFill(s,0,MaxnLevels,0); //Время формирования микроуровней ArrayResize(rt,MaxnLevels); ArrayFill(rt,0,MaxnLevels,0); ArrayResize(st,MaxnLevels); ArrayFill(st,0,MaxnLevels,0); //Массив количества уровней сопротивления попавших в n-й интервал ArrayResize(rP,MaxnLevels); ArrayFill(rP,0,MaxnLevels,0); //Массив значений цены групп уровней сопротивления ArrayResize(rL,MaxnLevels); ArrayFill(rL,0,MaxnLevels,0); //Массив количества уровней поддержки попавших в n-й интервал ArrayResize(sP,MaxnLevels); ArrayFill(sP,0,MaxnLevels,0); //Массив значений цены групп уровней поддержки ArrayResize(sL,MaxnLevels); ArrayFill(sL,0,MaxnLevels,0); // double MinLow=High[isBars]; double MaxHi=Low[isBars]; // double MaxsP=0; double MaxrP=0; int nLow=isBars; int nHi=isBars; int nrP=isBars; int nsP=isBars; double nMaxrP=0; //iRmax=High[1]*2; //Отключил обнуление канала //iSLevel=iRmin; //iRLevel=iRmax;//Максимально широкий канал //Параметры ограничения по броскам (вынес в параметры) //int BonceDeep=120;//Глубина просмотра в барах (минутах) //double BonceAmpMax=100;//Максимально допустимая амплитуда по броску iChan=true;//Признак наличия канала устанавливаем double LowLim; double HiLim; int MaxNRP=isBars; int MaxNSP=isBars; {for(int nCurBar=isBars; nCurBar<=nnBars-1; nCurBar++)//Перебираем на глубину просмотра в барах М1 (минутах) { //Print("nCurBar=",nCurBar); //Print("Bars=",Bars," nnBars=",nnBars," nCurBar=",nCurBar); //SR - Уровни HiBid1=High[nCurBar+1]; //Хай1 определяется по Bid 1бар LoBid1=Low[nCurBar+1]; //Лоу1 определяется по Bid 1бар HiAsk1=High[nCurBar+1]+gSpread; //Хай1 определяется по Ask 1бар LoAsk1=Low[nCurBar+1]+gSpread; //Лоу1 определяется по Ask 1бар HiBid2=High[nCurBar+2]; //Хай2 определяется по Bid 2бар LoBid2=Low[nCurBar+2]; //Лоу2 определяется по Bid 2бар HiAsk2=High[nCurBar+2]+gSpread; //Хай2 определяется по Ask 2бар LoAsk2=Low[nCurBar+2]+gSpread; //Лоу2 определяется по Ask 2бар Mid3Bid1=(High[nCurBar+1]+Low[nCurBar+1]+Close[nCurBar+1])/3.0;//Среднее1 по Bid HLC 1бар Mid3Bid2=(High[nCurBar+2]+Low[nCurBar+2]+Close[nCurBar+2])/3.0;//Среднее2 по Bid HLC 2бар Mid3Ask1=Mid3Bid1+gSpread; //Среднее1 по Ask HLC 1бар Mid3Ask2=Mid3Bid2+gSpread; //Среднее2 по Ask HLC 2бар //Resistense {if(//Проверка наличия (микро)уровня (HiAsk1>gAsk) //По любому (хай по биду) больше Ask (или Bid + Spread)//Учитываем, что хай определён по биду и рассчитываем на спред вверх &&(nHi<=inSRLevels-1) //Количество (микро)уровней сопротивления не превышено &&(HiAsk1>=MaxHi-dLevel*_Point) //Собственно условие определения (микро)уровня - больше чем чуть менее (-dLevel глубина заглядывания) раннего макса &&(HiAsk1>=HiAsk2) // (-2)-й бар ниже (-1)-го по хаям по Ask (или Bid + Spread) //&&(LoAsk2<=LoAsk1) // и по лоу &&(Mid3Ask1>=Mid3Ask2) // и по среднему //&&(HiAsk3<=HiAsk2) // (-3)-й бар ниже (-2)-го по хаям //&&(LoAsk3]MaxHi){MaxHi=HiAsk1;}} //Новый максимум дальше в прошлом для поиска следующих (микро)уровней r[nHi]=HiAsk1; //Значение (микро)уровня сопротивления rt[nHi]=nCurBar+1; //Время возникновения (микро)уровня nHi++; //Увеличение счетчика найденных (микро)уровней //Тут увеличиваем счетчики всех групп, куда попал уровень double nAnaliseSR_Point=nAnaliseSR*_Point; {for(nrP=0;nrP=LowLim)&&(HiAsk1=MaxrP) //Если превышен или равен прежний макс по количеству уровней в группе { {if(MaxrP>inLevelsIn){iRLevel=0.75*HiLim+0.25*LowLim;}}//Если прежний макс больше начального количества уровней, то запомним суперуровень-границу канала по микроуровню //{if(MaxrP>inLevelsIn){iRLevel=(HiLim+LowLim)/2;}}//Если прежний макс больше начального количества уровней, то запомним суперуровень-границу канала по микроуровню iFoundR=true; MaxrP=rP[nrP];//Запомним максимальное количество уровней в группе MaxNRP=nrP; }}//if(rP[nrP]>=MaxrP) }}//if((LowLim<=HiAsk1)&&(HiAsk1=HiBid1) &&(Mid3Bid1<=Mid3Bid2) //Это впадина (локальный минимум) по Среднему далее подъём (или равно) //&&(LoBid3>=LoBid2) //&&(Hi3Bid>Hi2Bid) ) { {if(LoBid1LowLim)&&(LoBid1<=HiLim)) { sP[nsP]++; //Число элементов в группе {if(sP[nsP]>=MaxsP) //Если превышен или равен прежний макс по количеству уровней в группе { {if(MaxsP>inLevelsIn){iSLevel=0.75*LowLim+0.25*HiLim;}} //{if(MaxsP>inLevelsIn){iSLevel=(HiLim+LowLim)/2;}} iFoundS=true; MaxsP=sP[nsP]; MaxNSP=nsP; }}//if(rP[nrP]>=MaxrP) }}//if((LowLim> ArraySize=",ArraySize(Low)); //Шаг сетки превышен и нет открытых ордеров и разрешенное время для торговли {if( (iReady) && (IsTradeTime2()) && (!IsCloseTime(CloseHour,CloseMinutes,CloseInterval)) && (!CheckBounceStop(iSymbol,iStopUp,iStopDown)) ) { iReady=false; //nAnaliseSR OrderNumInGrid=0;//Непонятное присваивание ибо nOrdersOpen<1 то есть ноль //Фактически это единственное условие для выбора направления сделки //Попробовать добавить расчет уровней - к какому ближе, от того и отражаться //if(TheSymbol=="GBPJPY")Print("LevelIs=",LevelIs," rLevel=",rLevel," sLevel=",sLevel); //Print("NewGrid>> iSLevel=",iSLevel," iRLevel=",iRLevel," gAsk=",gAsk," gBid=",gBid); double idMin0=((-CalcAddCommPrice(TheSymbol,AccSrv))/SymbolTradeTickValue)*_Point+gSpread; //Print("GridCreate >> idMin0=",idMin0); int val_index=-1; {if(Mode1_SRL)//Отбой { {if( (iType==OP_SELL) &&(!iStopDown)//Ограничение по броску в противоположную сторону (если бросок вверх, то StopDown - не продавать) &&((imAlligator<0.0)||(!exMAOn)) &&((!HedgeFilterOn)||(CalcVolumeHedge(TheSymbol)>=-exHedgeLimit)) ) { Order_Info=0;//Неопределено {if(inBounceUp)//k*dR> nOpenPos1=",nOpenPos1," k*dR0.0)?(iSizeOfLot):(CalcLotSize2(TheSymbol,OP_SELL,exCalcLotMode,OrderNumInGrid,iMagic,1))); {if(iSizeOfLot>0.0) { {if((ShortEnable) &&( (!exMAOn2) //без аллигатора || ((exMAOn2)&&(!Mode2Create)&&(Mode2Cont)) //с аллигатором, но аллигатор отключен для создания, включен для продолжения || ((exMAOn2)&&(Mode2Create)&&(imAlligator2Sel))//с аллигатором, включено для создания, сработало для продажи ) &&((gBid>Grid[m].LastLevelSell-dGridOpenLoss*_Point)//Выше предидущей сетки Sell - сторона убытка??? ||(gBidima_slow_reb[0]+p102*_Point) &&(ima_fast_reb[0]>ima_fast_reb[1]) //&&((ima_slow_main[1]-ima_fast_o21[1])<(ima_slow_main[0]-ima_fast_o21[0])) )) )//(ReboundOn)&& )//(true) || ( (!DirectOn)&&(!ReboundOn)//Режимы пробой - отбой отключены оба ) ) //2. Учесть запрет на близкие открытия при убытке (тоже пока примитивно) //Если в целом инструмент (или сетка) в убытке, то открываться не ближе mDistOpenOrd в сторону убытка &&( (CalcPositionProfitSum1(TheSymbol,OP_SELL,MagicNumber,nGrides)>=0.0) || ( (CalcPositionProfitSum1(TheSymbol,OP_SELL,MagicNumber,nGrides)<0.0) &&(gBid>CalcSymMidPrice(TheSymbol,OP_SELL,MagicNumber,nGrides,iSum,iVol)+mDistOpenGrid*_Point) //&&(gBid>Grid[m].LastLevelSell+mDistOpenOrd*_Point) ) ) ) { AlligatorCreateSell++; //Print(//"*** Alligator Create Sell=",AlligatorCreateSell, // " Alligator2Sel=",BoolToString(imAlligator2Sel), // " exMAOn2=",BoolToString(exMAOn2), // " (exMAOn2)&&(!Mode2Create)&&(Mode2Cont)=",BoolToString((exMAOn2)&&(!Mode2Create)&&(Mode2Cont)), // " (exMAOn2)&&(Mode2Create)&&(imAlligator2Sel)=",BoolToString((exMAOn2)&&(Mode2Create)&&(imAlligator2Sel)), // " ()||()||()=",BoolToString(((!exMAOn2)||((exMAOn2)&&(!Mode2Create)&&(Mode2Cont))||((exMAOn2)&&(Mode2Create)&&(imAlligator2Sel)))), // "" // ); //&&( (!exMAOn2) //без аллигатора // || ((exMAOn2)&&(!Mode2Create)&&(Mode2Cont)) //с аллигатором, но аллигатор отключен для создания, включен для продолжения // || ((exMAOn2)&&(Mode2Create)&&(imAlligator2Sel))//с аллигатором, включено для создания, сработало для продажи // ) Order_Info= fOrderSend(OP_SELL,iSizeOfLot,Slippage,0,0,TradeComment+" #"+string(OrderNumInGrid)+"-"+string(iMagic),iMagic,0,HotPink,mDeal); {if(Order_Info<=0) { Print("NewGrid >> OP_SELL ERROR=",GetLastError()," RetCode=",Order_Info," SizeOfLot=",iSizeOfLot); return(-2);//Выход - ошибка ордера }}//if(Order_Info<=0) {if(Order_Info>0) { //Пробуем выбрать сделку //ResetLastError(); HistorySelect(0,TimeCurrent()+1000); //Print("ERR 01=",GetLastError()); ulong HistoryOrders=0; //ResetLastError(); HistoryOrders=HistoryOrdersTotal();//Количество ордеров в истории //Print("ERR 02=",GetLastError()); ulong HistoryDeals=0; //ResetLastError(); HistoryDeals=HistoryDealsTotal();//Количество сделок в истории //Print("ERR 03=",GetLastError()); int HistoryPositions=0; //ResetLastError(); HistoryPositions=PositionsTotal();//Количество позиций в истории //Print("ERR 04=",GetLastError()); //ResetLastError(); HistoryDealSelect(mDeal);//Результат не проверяем - вроде всегда срабатывает //Print("ERR 05=",GetLastError()); Grid[m].OpenRLevel=iRLevel; //ResetLastError(); Grid[m].Ticket=HistoryDealGetInteger(mDeal,DEAL_POSITION_ID);//Получаем POSITION_IDENTIFIER //Print("ERR 06=",GetLastError()); //ResetLastError(); Grid[m].LastLevelSell=HistoryDealGetDouble(mDeal,DEAL_PRICE);//Цена последней сделки для текущей позиции (сетки) //Print("ERR 07=",GetLastError()); //Пробуем выбрать позицию ResetLastError(); {if(PositionSelectByTicket(Grid[m].Ticket))//Выбираем позицию по POSITION_IDENTIFIER { GridCreate=true; CreateSell=true; //ArraySetAsSeries(High,true); CopyHigh(TheSymbol,PERIOD_CURRENT,0,MathMin(Bars(TheSymbol,PERIOD_CURRENT),RCTuneInterval),High); val_index=ArrayMaximum(High,0,MathMin(Bars(TheSymbol,PERIOD_CURRENT),RCTuneInterval)); {if(val_index!=-1) { Grid[m].RuptStopLevel=High[val_index]+idMin0+mdChan*_Point+gSpread; Grid[m].RuptStopTime=0; }}//if(val_index!=-1) Print("NewGrid #",m,">> OP_SELL Placed...", " POS(ID/TIC/GR)=",PositionGetInteger(POSITION_IDENTIFIER),"/",PositionGetInteger(POSITION_TICKET),"/",Grid[m].Ticket, " DealTick=",mDeal," LastLevelSell=",Grid[m].LastLevelSell," HistOrders=",HistoryOrders," HistDeals=",HistoryDeals," HistoryPos=",HistoryPositions, " RuptStopLevel=",Grid[m].RuptStopLevel," RetCode=",Order_Info); }else{//не выбралось Print("NewGrid #",iMagic-MagicNumber,">> OP_SELL ERROR=",GetLastError(), " POS(ID/TIC/GR)=",PositionGetInteger(POSITION_IDENTIFIER),"/",PositionGetInteger(POSITION_TICKET),"/",Grid[m].Ticket, " DealTick=",mDeal," LastLevelSell=",Grid[m].LastLevelSell," HistOrders=",HistoryOrders," HistDeals=",HistoryDeals," HistoryPos=",HistoryPositions, " RuptStopLevel=",Grid[m].RuptStopLevel," RetCode=",Order_Info); return(-9);//Ошибка выбора позиции }}//if(PositionSelectByTicket(Grid[m].Ticket)) ////***** TEST ////Для ордеров ////Ордера номеруются от 1 до HistoryDealsTotal()+1, но рекомендовано перебирать через HistoryOrderGetTicket(i) !!!! //ResetLastError(); //HistoryOrderSelect(0);//Результат не проверяем - вроде всегда срабатывает //Print("ERR 000(0)=",GetLastError()); //ResetLastError(); //HistoryOrderSelect(HistoryOrders-1);//Результат не проверяем - вроде всегда срабатывает //Print("ERR 099(HistoryOrders-1)=",GetLastError()); //ResetLastError(); //HistoryOrderSelect(HistoryOrders);//Результат не проверяем - вроде всегда срабатывает //Print("ERR 100(HistoryOrders)=",GetLastError()); //ResetLastError(); //HistoryOrderSelect(HistoryOrders+1);//Результат не проверяем - вроде всегда срабатывает //Print("ERR 101(HistoryOrders+1)=",GetLastError()); ////Для сделок ////Сделки номеруются от 1 до HistoryDealsTotal() //ResetLastError(); //HistoryDealSelect(0);//Результат не проверяем - вроде всегда срабатывает //Print("ERR 000(0)=",GetLastError()); //ResetLastError(); //HistoryDealSelect(HistoryDeals-1);//Результат не проверяем - вроде всегда срабатывает //Print("ERR 099(HistoryDeals-1)=",GetLastError()); //ResetLastError(); //HistoryDealSelect(HistoryDeals);//Результат не проверяем - вроде всегда срабатывает //Print("ERR 100(HistoryDeals)=",GetLastError()); ////Для позиций ////Позиции перебираются от 0 до (HistoryPositions-1) с получением тикетов через PositionGetTicket(i) //int HistoryPositions=0; ////ResetLastError(); //HistoryPositions=PositionsTotal();//Количество позиций в истории //Print("ERR 04=",GetLastError()); //if(HistoryPositions>0)//Есть позиции //{for(int i=0;i<=HistoryPositions;i++)//Перебираем позиции //{ // ResetLastError(); // ulong Pos_Tick=PositionGetTicket(i);//Выбираем позицию по номеру в списке // Print("ERR(200)=",GetLastError()," i=",i," Pos_Tick=",Pos_Tick); // {if(Pos_Tick<=0){continue;}}//Неудачно - следующий // //Выбираем позицию по тикету // ResetLastError(); // {if(!PositionSelectByTicket(Pos_Tick)) // {//Неудачно - следующий // Print("ERR(201)=",GetLastError()," i=",i," Pos_Tick=",Pos_Tick); // continue; // }else{ // Print("ERR(202)=",GetLastError()," i=",i," Pos_Tick=",Pos_Tick); // }}//if(!PositionSelectByTicket(Pos_Tick)) //}}//for(int i=PositionsTotal();i>=0;i--) }}//if(Order_Info>0) }}//if(ShortEnable) }}//if(Size_Of_Lot>0.0) }}//if(GridNotCreate) }else{ //Print(nOpenPos1,"Error: ошибка смещения в канале"); return(-3);//Выход - ошибка смещения в канале }}//if(nOpenPos1*(iRLevel-gAsk)<(gBid-iSLevel)) }else{ //{if((iClose20.0)||(!exMAOn)) && ((!HedgeFilterOn)||(CalcVolumeHedge(TheSymbol)<=exHedgeLimit)) ) { Order_Info=0;//Неопределено {if(inBounceDn) { //Print("NewGrid>> nOpenPos1=",nOpenPos1," k*dS0.0)?(iSizeOfLot):(CalcLotSize2(TheSymbol,OP_BUY,exCalcLotMode,OrderNumInGrid,iMagic,1))); {if(iSizeOfLot>0.0) { {if((LongEnable) &&( (!exMAOn2) //без аллигатора || ((exMAOn2)&&(!Mode2Create)&&(Mode2Cont)) //с аллигатором, но аллигатор отключен для создания, включен для продолжения || ((exMAOn2)&&(Mode2Create)&&(imAlligator2Buy))//с аллигатором, включено для создания, сработало для покупки ) &&((gAskGrid[m].LastLevelBuy+dGridOpenProfit*_Point)//Выше последнего открытого ордера предидущей сетки Buy - сторона прибыли??? ) //1. Учесть тиковые МА (пока без передачи параметров) &&(//Тиковый МА (!TickMA)||//Для режима МА ((true) &&((ima_fast_main_a[0]>ima_slow_main_a[0]+p000*_Point) &&(ima_fast_main_a[0]>ima_fast_main_a[1])) //&&((ima_fast_main[1]-ima_slow_main[1])<(ima_fast_main[0]-ima_slow_main[0])) ) ) &&(//Прямые и отскоки //Прямые ((DirectOn)&& ((true) //Тиковый длинный МА1 &&( (!TickDirectMA)|| ((true) &&(ima_fast_dir_a[0]>ima_slow_dir_a[0]+p001*_Point) &&(ima_fast_dir_a[0]>ima_fast_dir_a[1]) //&&((ima_fast_o21[1]-ima_slow_main[1])<(ima_fast_o21[0]-ima_slow_main[0])) )) )//(DirectOn)&& )//(true) || //Отскоки ((ReboundOn)&& ((true) //Тиковый длинный МА1 &&( (!TickReboundMA)|| ( (ima_fast_reb_a[0]=0.0) || ( (CalcPositionProfitSum1(TheSymbol,OP_BUY,MagicNumber,nGrides)<0.0) &&(gAsk=0)||(!Mode2)) { AlligatorCreateBuy++; //Print("****************** Alligator Create Buy>>",AlligatorCreateBuy); Order_Info= fOrderSend(OP_BUY,iSizeOfLot,Slippage,0,0,TradeComment+" #"+string(OrderNumInGrid)+"-"+string(iMagic),iMagic,0,Lime,mDeal); {if(Order_Info<=0) { Print("NewGrid >> OP_BUY ERROR=",GetLastError()," RetCode=",Order_Info," SizeOfLot=",iSizeOfLot); return(-2);//Выход - ошибка ордера }}//if(Order_Info<=0) {if(Order_Info>0) { //Пробуем выбрать сделку //ResetLastError(); HistorySelect(0,TimeCurrent()+1000); //Print("ERR 01=",GetLastError()); ulong HistoryOrders=0; //ResetLastError(); HistoryOrders=HistoryOrdersTotal();//Количество ордеров в истории //Print("ERR 02=",GetLastError()); ulong HistoryDeals=0; //ResetLastError(); HistoryDeals=HistoryDealsTotal();//Количество сделок в истории //Print("ERR 03=",GetLastError()); int HistoryPositions=0; //ResetLastError(); HistoryPositions=PositionsTotal();//Количество позиций в истории //Print("ERR 04=",GetLastError()); //ResetLastError(); HistoryDealSelect(mDeal);//Результат не проверяем - вроде всегда срабатывает //Print("ERR 05=",GetLastError()); Grid[m].OpenSLevel=iSLevel; //ResetLastError(); Grid[m].Ticket=HistoryDealGetInteger(mDeal,DEAL_POSITION_ID);//Получаем POSITION_IDENTIFIER //Print("ERR 06=",GetLastError()); //ResetLastError(); Grid[m].LastLevelBuy=HistoryDealGetDouble(mDeal,DEAL_PRICE);//Цена последней сделки для текущей позиции (сетки) //Print("ERR 07=",GetLastError()); //Пробуем выбрать позицию ResetLastError(); {if(PositionSelectByTicket(Grid[m].Ticket))//Выбираем позицию по POSITION_IDENTIFIER { GridCreate=true; CreateBuy=true; //ArraySetAsSeries(Low,true); CopyLow(TheSymbol,PERIOD_CURRENT,0,MathMin(Bars(TheSymbol,PERIOD_CURRENT),RCTuneInterval),Low); val_index=ArrayMinimum(Low,0,MathMin(Bars(TheSymbol,PERIOD_CURRENT),RCTuneInterval)); {if(val_index!=-1) { Grid[m].RuptStopLevel=Low[val_index]-idMin0-mdChan*_Point; Grid[m].RuptStopTime=0; }}//if(val_index!=-1) Print("NewGrid #",m,">> OP_BUY Placed...", " POS(ID/TIC/GR)=",PositionGetInteger(POSITION_IDENTIFIER),"/",PositionGetInteger(POSITION_TICKET),"/",Grid[m].Ticket, " DealTick=",mDeal," LastLevelBuy=",Grid[m].LastLevelBuy," HistOrders=",HistoryOrders," HistDeals=",HistoryDeals," HistoryPos=",HistoryPositions, " RuptStopLevel=",Grid[m].RuptStopLevel," RetCode=",Order_Info); }else{//не выбралось Print("NewGrid #",iMagic-MagicNumber,">> OP_BUY ERROR=",GetLastError(), " POS(ID/TIC/GR)=",PositionGetInteger(POSITION_IDENTIFIER),"/",PositionGetInteger(POSITION_TICKET),"/",Grid[m].Ticket, " DealTick=",mDeal," LastLevelBuy=",Grid[m].LastLevelBuy," HistOrders=",HistoryOrders," HistDeals=",HistoryDeals," HistoryPos=",HistoryPositions, " RetCode=",Order_Info); return(-9);//Ошибка выбора позиции }}//if(PositionSelectByTicket(Grid[m].Ticket)) ////***** TEST ////Для ордеров ////Ордера номеруются от 1 до HistoryDealsTotal()+1, но рекомендовано перебирать через HistoryOrderGetTicket(i) !!!! //ResetLastError(); //HistoryOrderSelect(0);//Результат не проверяем - вроде всегда срабатывает //Print("ERR 000(0)=",GetLastError()); //ResetLastError(); //HistoryOrderSelect(HistoryOrders-1);//Результат не проверяем - вроде всегда срабатывает //Print("ERR 099(HistoryOrders-1)=",GetLastError()); //ResetLastError(); //HistoryOrderSelect(HistoryOrders);//Результат не проверяем - вроде всегда срабатывает //Print("ERR 100(HistoryOrders)=",GetLastError()); //ResetLastError(); //HistoryOrderSelect(HistoryOrders+1);//Результат не проверяем - вроде всегда срабатывает //Print("ERR 101(HistoryOrders+1)=",GetLastError()); ////Для сделок ////Сделки номеруются от 1 до HistoryDealsTotal() //ResetLastError(); //HistoryDealSelect(0);//Результат не проверяем - вроде всегда срабатывает //Print("ERR 000(0)=",GetLastError()); //ResetLastError(); //HistoryDealSelect(HistoryDeals-1);//Результат не проверяем - вроде всегда срабатывает //Print("ERR 099(HistoryDeals-1)=",GetLastError()); //ResetLastError(); //HistoryDealSelect(HistoryDeals);//Результат не проверяем - вроде всегда срабатывает //Print("ERR 100(HistoryDeals)=",GetLastError()); ////Для позиций ////Позиции перебираются от 0 до (HistoryPositions-1) с получением тикетов через PositionGetTicket(i) //if(HistoryPositions>0)//Есть позиции //{for(int i=0;i<=HistoryPositions;i++)//Перебираем позиции //{ // ResetLastError(); // ulong Pos_Tick=PositionGetTicket(i);//Выбираем позицию по номеру в списке // Print("ERR(200)=",GetLastError()," i=",i," Pos_Tick=",Pos_Tick); // {if(Pos_Tick<=0){continue;}}//Неудачно - следующий // //Выбираем позицию по тикету // ResetLastError(); // {if(!PositionSelectByTicket(Pos_Tick)) // {//Неудачно - следующий // Print("ERR(201)=",GetLastError()," i=",i," Pos_Tick=",Pos_Tick); // continue; // }else{ // Print("ERR(202)=",GetLastError()," i=",i," Pos_Tick=",Pos_Tick); // }}//if(!PositionSelectByTicket(Pos_Tick)) //}}//for(int i=PositionsTotal();i>=0;i--) }}//if(Order_Info>0) }}//if(LongEnable) }}//if(Size_Of_Lot>0.0) }}//if(GridNotCreate) }else{ //Print(nOpenPos1,"Error: ошибка смещения в канале"); return(-3);//Выход - ошибка смещения в канале }}//if(nOpenPos1*(gBid-iSLevel)<(iRLevel-gAsk)) }}//if(iType==OP_BUY) }}//if(iType==OP_SELL) }}//if((Mode1_SRL)&&(true)) //{if(Mode2_SRL)//Пробой - предусмотреть выход за последний известный канал k*dS>(R-S) //{ // {if(((nOpenPos2*(gBid-iSLevel)<(iRLevel-gAsk)))&&(iType==OP_SELL))//k*dS0.0) // { // {if(ShortEnable) // { // Order_Info= // fOrderSend(OP_SELL,iSizeOfLot,Slippage,0,0,TradeComment+" #"+string(OrderNumInGrid)+"-"+string(iMagic),iMagic,0,HotPink); // }}//if(ShortEnable) // {if(Order_Info<0) // { // Print(iSizeOfLot,"Error: ",GetLastError()); // return(-2);//Выход - ошибка ордера // }}//if(Order_Info<0) // ////dLastOpenPriceBuy=CalcLastOpenPrice(OP_BUY,iMagic); // GridCreate=true; // }}//if(Size_Of_Lot>0.0) // }}//if(GridNotCreate) // }else{ // //{if((iClose20.0) // { // {if(LongEnable) // { // Order_Info= // fOrderSend(OP_BUY,iSizeOfLot,Slippage,0,0,TradeComment+" #"+string(OrderNumInGrid)+"-"+string(iMagic),iMagic,0,Lime); // }}//if(LongEnable) // {if(Order_Info<0) // { // Print(iSizeOfLot,"Error: ",GetLastError()); // return(-2);//Выход - ошибка ордера // }}//if(Order_Info<0) // ////dLastOpenPriceSell=CalcLastOpenPriceA1(OP_BUY,iMagic); // GridCreate=true; // }}//if(Size_Of_Lot>0.0) // }}//if(GridNotCreate) // }}//if((iClose1==iClose0)&&(iClose20) }}//if((iReady)&&(IsTradeTime2())&&(!IsCloseTime(CloseHour,CloseMinutes,CloseInterval))) iReady=false; return(0);//Выход - нет ошибки результат не определен }//GridCreate() // //====================================================================================================== // GridContinue() //====================================================================================================== int GridContinue( string iSymbol, bool iReady, int iType, int iMagic, double iSLevel, double iRLevel, double &iVirtualSL, double &iSizeOfLot, int iOrderNumInGrid, double imAlligator, bool imAlligator2Buy, bool imAlligator2Sel){ int m=iMagic-Grid[0].Magic; bool GridCreate=false; bool iStopUp=false, iStopDown=false; double iSum,iVol; ulong mDeal=0; //----- //Print("GridCreate >> ArraySize=",ArraySize(Low)); {if( (iReady) && (IsTradeTime2()) && (!IsCloseTime(CloseHour,CloseMinutes,CloseInterval)) && (!CheckBounceStop(iSymbol,iStopUp,iStopDown)) ) { iReady=false; double idMin0=((-CalcAddCommPrice(TheSymbol,AccSrv))/SymbolTradeTickValue)*_Point+gSpread; int val_index=-1; {if((iType==OP_SELL)//Найден SELL &&(!iStopDown)//Ограничение по броску в противоположную сторону (если бросок вверх, то StopDown - не продавать) &&((!HedgeFilterOn)||(CalcVolumeHedge(iSymbol)>=-exHedgeLimit)) //1. Учесть тиковые МА (пока без передачи параметров) &&(//Тиковый МА (!TickMA)||//Выключатель фильтра ((true) &&(ima_fast_main[0]ima_slow_reb[0]+p102*_Point) &&(ima_fast_reb[0]>ima_fast_reb[1]) //&&((ima_slow_main[1]-ima_fast_o21[1])<(ima_slow_main[0]-ima_fast_o21[0])) )) )//(ReboundOn)&& )//(true) || ( (!DirectOn)&&(!ReboundOn)//Режимы пробой - отбой отключены оба ) ) //2. Учесть запрет на близкие открытия при убытке (тоже пока примитивно) //Если в целом инструмент (или сетка) в убытке, то открываться не ближе mDistOpenOrd в сторону убытка &&( (CalcPositionProfitSum1(iSymbol,OP_SELL,iMagic,1)>0.0)//Если в прибыли, то разрешить открытие || ( (CalcPositionProfitSum1(iSymbol,OP_SELL,iMagic,1)<=0.0)//Если в убытке &&(gBid>CalcSymMidPrice(iSymbol,OP_SELL,iMagic,1,iSum,iVol)+mDistOpenOrd*_Point)//Бид больше средней цены на отступ!!! && ( (StLotsMode==0) ||(gBid>Grid[m].LastLevelSell+mDistOpenOrd*_Point)//Бид больше последней цены на отступ!!! ) ) ) ) { {if(ShortEnable)//Продажи разрешены { {if(inBounceUp)//Цена у верхней границы канала { {if((imAlligator<0.0)||(!exMAOn))//Цена прекратила рост у верхнего края канала { {if( (!exMAOn2) //без аллигатора || ((exMAOn2)&&(!Mode2Cont)&&(Mode2Create)) //с аллигатором, продолжение выключено, создание включено || ((exMAOn2)&&(Mode2Cont)&&(imAlligator2Sel)) //с аллигатором, продолжение включено, сработало на продажу ) {//Общий тренд - продажи для продолжения AlligatorContBuy++; //Print("****************** Alligator Count Buy>>",AlligatorCountBuy); iOrderNumInGrid=CalcOrdersN(iSymbol,OP_SELL,iMagic,1); {if(OneOrderMode) //Режим одиночного ордера {//Режим одиночных ордеров - расчет размера лота iSizeOfLot=2*CalcPosLastLotSize(iSymbol,OP_SELL,iMagic)+CalcLotSize2(iSymbol,OP_ALL,exCalcLotMode,iOrderNumInGrid,iMagic,1);//Уже нормализовано в процедуре //iSizeOfLot=LotsMult*CalcPosLastLotSize(OP_SELL,iMagic); //и нарастили лот if(CloseEnable) fCloseBuySell(iSymbol,false,true,iMagic,iVirtualSL); //Закрыли продажу }else{//Режим сетки ордеров - расчет размера лота iSizeOfLot=CalcLotSize2(iSymbol,OP_ALL,exCalcLotMode,iOrderNumInGrid,iMagic,1);//Уже нормализовано в процедуре //iSizeOfLot=CalcLotSize(OP_SELL,exCalcLotMode,iOrderNumInGrid,iMagic);//Уже нормализовано в процедуре }}//if(OneOrderMode) {if(iSizeOfLot>0.0) { //Print("CalcSymMidPrice(OP_SELL)==",CalcSymMidPrice(OP_SELL,iMagic,1,iSum,iVol)); iSizeOfLot=NormalizeDouble(MathMin(iSizeOfLot,SymbolInfoDouble(iSymbol,SYMBOL_VOLUME_MAX)),LotStepDigit); Order_Info=0;//Неопределено Order_Info= fOrderSend(OP_SELL,iSizeOfLot,Slippage,0,0,TradeComment+" #"+string(iOrderNumInGrid)+"-"+string(iMagic),iMagic,0,HotPink,mDeal); {if(Order_Info<=0)//Превышено количество (-4) или ошибка ордера (-1) { //{if(Order_Info==-1)//ошибка ордера (-1) //{ // Print("Error: ",GetLastError()); // return(Order_Info); //}else{ return(-1); //}}//if(Order_Info==-1)//ошибка ордера (-1) }else{ {if(Order_Info>0) { //Пробуем выбрать сделку //ResetLastError(); HistorySelect(0,TimeCurrent()); //Print("ERR 01=",GetLastError()); ulong HistoryOrders=0; //ResetLastError(); HistoryOrders=HistoryOrdersTotal();//Количество ордеров в истории //Print("ERR 02=",GetLastError()); ulong HistoryDeals=0; //ResetLastError(); HistoryDeals=HistoryDealsTotal();//Количество сделок в истории //Print("ERR 03=",GetLastError()); int HistoryPositions=0; //ResetLastError(); HistoryPositions=PositionsTotal();//Количество позиций в истории //Print("ERR 04=",GetLastError()); //ResetLastError(); HistoryDealSelect(mDeal);//Результат не проверяем - вроде всегда срабатывает //Grid[m].Ticket=HistoryDealGetInteger(mDeal,DEAL_POSITION_ID);//Уже храним в массиве - не нужно получать заново //ResetLastError(); Grid[m].LastLevelSell=HistoryDealGetDouble(mDeal,DEAL_PRICE);//Цена последней сделки для текущей позиции (сетки) - собственно ради этого и выбирали сделку //Пробуем выбрать позицию ResetLastError(); {if(PositionSelectByTicket(Grid[m].Ticket))//Выбираем позицию по POSITION_IDENTIFIER (он был получен при первом ордере/сделке позиции) { GridCreate=true; CreateSell=true; //ArraySetAsSeries(High,true); CopyHigh(iSymbol,PERIOD_CURRENT,0,MathMin(Bars(iSymbol,PERIOD_CURRENT),RCTuneInterval),High); val_index=ArrayMaximum(High,0,MathMin(Bars(iSymbol,PERIOD_CURRENT),RCTuneInterval)); {if(val_index!=-1) { Grid[m].RuptStopLevel=High[val_index]+idMin0+mdChan*_Point+gSpread; Grid[m].RuptStopTime=0; }}//if(val_index!=-1) Print("GridContinue #",iMagic-MagicNumber,">> OP_SELL Placed...", " POS(ID/TI/GR)=",PositionGetInteger(POSITION_IDENTIFIER),"/",PositionGetInteger(POSITION_TICKET),"/",Grid[m].Ticket, " DealTick=",mDeal," LastLevelSell=",Grid[m].LastLevelSell," HistOrders=",HistoryOrders," HistDeals=",HistoryDeals," HistoryPos=",HistoryPositions, " RuptStopLevel=",Grid[m].RuptStopLevel," RetCode=",Order_Info); }else{//не выбралось Print("GridContinue #",iMagic-MagicNumber,">> OP_SELL ERROR=",GetLastError(), " POS(ID/TI/GR)=",PositionGetInteger(POSITION_IDENTIFIER),"/",PositionGetInteger(POSITION_TICKET),"/",Grid[m].Ticket, " DealTick=",mDeal," LastLevelSell=",Grid[m].LastLevelSell," HistOrders=",HistoryOrders," HistDeals=",HistoryDeals," HistoryPos=",HistoryPositions, " RetCode=",Order_Info); return(-9);//Ошибка выбора позиции }}//if(PositionSelectByTicket(Grid[m].Ticket)) }else{ return(0); }}//if(Order_Info>0) }}//if(Order_Info<0) }else{ return(-4);//Выход - ошибка размера лота }}//if(Size_Of_Lot>0.0) }else{ return(-8);//Выход - ошибка imAlligator2 }}//if((imAlligator2<0)||(!Mode2)) }else{ return(-7);//Выход - ошибка imAlligator }}//if((imAlligator<0.0)||(!exMAOn)) }else{ //Print(nOpenPos1,"Error: ошибка смещения в канале"); return(-3);//Выход - ошибка смещения в канале, цена не в интервале отскока }}//if(inBounceUp) }else{ return(-9);//Выход - ошибка продажи запрещены }}//if(ShortEnable) }}//else{ //if(iType==OP_BUY){Print("0. iType==OP_BUY>>>");} {if((iType==OP_BUY)//Найден BUY &&(!iStopUp)//Ограничение по броску в противоположную сторону (если бросок вниз, то StopUp - не покупать) &&((!HedgeFilterOn)||(CalcVolumeHedge(iSymbol)<=exHedgeLimit)) //1. Учесть тиковые МА (пока без передачи параметров) &&(//Тиковый МА (!TickMA)||//Для режима МА ((true) &&((ima_fast_main_a[0]>ima_slow_main_a[0]+p000*_Point) &&(ima_fast_main_a[0]>ima_fast_main_a[1])) //&&((ima_fast_main[1]-ima_slow_main[1])<(ima_fast_main[0]-ima_slow_main[0])) )) &&(//Прямые и отскоки //Прямые ((DirectOn)&& ((true) //Тиковый длинный МА1 &&( (!TickDirectMA)|| ((true) &&(ima_fast_dir_a[0]>ima_slow_dir_a[0]+p001*_Point) &&(ima_fast_dir_a[0]>ima_fast_dir_a[1]) //&&((ima_fast_o21[1]-ima_slow_main[1])<(ima_fast_o21[0]-ima_slow_main[0])) )) )//(DirectOn)&& )//(true) || //Отскоки ((ReboundOn)&& ((true) //Тиковый длинный МА1 &&( (!TickReboundMA)|| ( (ima_fast_reb_a[0]0.0) || ( (CalcPositionProfitSum1(iSymbol,OP_BUY,iMagic,1)<=0.0) &&(gAsk>>"," gAsk=",gAsk," Grid[m].LastLevelBuy=",Grid[m].LastLevelBuy);} {if(LongEnable)//Покупки разрешены { {if(inBounceDn)//Цена у нижней границы канала { {if((imAlligator>0.0)||(!exMAOn))//Цена прекратила рост у края канала { {if( (!exMAOn2) //без аллигатора || ((exMAOn2)&&(!Mode2Cont)&&(Mode2Create)) //с аллигатором, продолжение отключено, создание включено || ((exMAOn2)&&(Mode2Cont)&&(imAlligator2Buy)) //с аллигатором, продолжение включено, сработало на покупку ) {//Общий тренд - покупать для продолжения AlligatorContSell++; //Print("****************** Alligator Count Sell>>",AlligatorCountSell); iOrderNumInGrid=CalcOrdersN(iSymbol,OP_BUY,iMagic,1); {if(OneOrderMode) { iSizeOfLot=2*CalcPosLastLotSize(iSymbol,OP_BUY,iMagic)+CalcLotSize2(iSymbol,OP_ALL,exCalcLotMode,iOrderNumInGrid,iMagic,1);//Уже нормализовано в процедуре //iSizeOfLot=LotsMult*CalcPosLastLotSize(OP_BUY,iMagic); if(CloseEnable) fCloseBuySell(iSymbol,true,false,iMagic,iVirtualSL); }else{ iSizeOfLot=CalcLotSize2(iSymbol,OP_ALL,exCalcLotMode,iOrderNumInGrid,iMagic,1);//Уже нормализовано в процедуре //iSizeOfLot=CalcLotSize(OP_BUY,exCalcLotMode,iOrderNumInGrid,iMagic);//Уже нормализовано в процедуре }}//if(OneOrderMode) {if(iSizeOfLot>0.0) { //Print("CalcSymMidPrice(OP_BUY)==",CalcSymMidPrice(TheSymbol,OP_BUY,iMagic,1,iSum,iVol)); iSizeOfLot=NormalizeDouble(MathMin(iSizeOfLot,SymbolInfoDouble(iSymbol,SYMBOL_VOLUME_MAX)),LotStepDigit); Order_Info=0;//Неопределено Order_Info= fOrderSend(OP_BUY,iSizeOfLot,Slippage,0,0,TradeComment+" #"+string(iOrderNumInGrid)+"-"+string(iMagic),iMagic,0,Lime,mDeal); {if(Order_Info<=0) { //{if(Order_Info==-1)//ошибка ордера (-1) //{ // Print("Error: ",GetLastError()); // return(Order_Info); //}else{ return(-1); //}}// }else{ {if(Order_Info>0) { //Пробуем выбрать сделку //ResetLastError(); HistorySelect(0,TimeCurrent()); //Print("ERR 01=",GetLastError()); ulong HistoryOrders=0; //ResetLastError(); HistoryOrders=HistoryOrdersTotal();//Количество ордеров в истории //Print("ERR 02=",GetLastError()); ulong HistoryDeals=0; //ResetLastError(); HistoryDeals=HistoryDealsTotal();//Количество сделок в истории //Print("ERR 03=",GetLastError()); int HistoryPositions=0; //ResetLastError(); HistoryPositions=PositionsTotal();//Количество позиций в истории //Print("ERR 04=",GetLastError()); //ResetLastError(); HistoryDealSelect(mDeal);//Результат не проверяем - вроде всегда срабатывает //Grid[m].Ticket=HistoryDealGetInteger(mDeal,DEAL_POSITION_ID);//Уже храним в массиве - не нужно получать заново //ResetLastError(); Grid[m].LastLevelBuy=HistoryDealGetDouble(mDeal,DEAL_PRICE);//Цена последней сделки для текущей позиции (сетки) - собственно ради этого и выбирали сделку //Пробуем выбрать позицию ResetLastError(); {if(PositionSelectByTicket(Grid[m].Ticket))//Выбираем позицию по POSITION_IDENTIFIER (он был получен при первом ордере/сделке позиции) { GridCreate=true; CreateBuy=true; //ArraySetAsSeries(Low,true); CopyLow(iSymbol,PERIOD_CURRENT,0,MathMin(Bars(iSymbol,PERIOD_CURRENT),RCTuneInterval),Low); val_index=ArrayMinimum(Low,0,MathMin(Bars(iSymbol,PERIOD_CURRENT),RCTuneInterval)); {if(val_index!=-1) { Grid[m].RuptStopLevel=Low[val_index]-idMin0-mdChan*_Point; Grid[m].RuptStopTime=0; }}//if(val_index!=-1) Print("GridContinue #",iMagic-MagicNumber,">> OP_BUY Placed...", " POS(ID/TI/GR)=",PositionGetInteger(POSITION_IDENTIFIER),"/",PositionGetInteger(POSITION_TICKET),"/",Grid[m].Ticket, " DealTick=",mDeal," LastLevelBuy=",Grid[m].LastLevelBuy," HistOrders=",HistoryOrders," HistDeals=",HistoryDeals," HistoryPos=",HistoryPositions, " RuptStopLevel=",Grid[m].RuptStopLevel," RetCode=",Order_Info); }else{//не выбралось Print("GridContinue #",iMagic-MagicNumber,">> OP_BUY ERROR=",GetLastError(), " POS(ID/TI/GR)=",PositionGetInteger(POSITION_IDENTIFIER),"/",PositionGetInteger(POSITION_TICKET),"/",Grid[m].Ticket, " DealTick=",mDeal," LastLevelBuy=",Grid[m].LastLevelBuy," HistOrders=",HistoryOrders," HistDeals=",HistoryDeals," HistoryPos=",HistoryPositions, " RetCode=",Order_Info); return(-9);//Ошибка выбора позиции }}//if(PositionSelectByTicket(Grid[m].Ticket)) }else{ return(0); }}// }}//if(Order_Info<0) }else{ return(-4);//Выход - ошибка размера лота }}//if(Size_Of_Lot>0.0) }else{ return(-8);//Выход - ошибка imAlligator2 }}//if((imAlligator2>0)||(!Mode2)) }else{ return(-7);//Выход - ошибка imAlligator }}//if((imAlligator>0.0)||(!exMAOn)) }else{ //Print(nOpenPos1,"Error: ошибка смещения в канале"); return(-3);//Выход - ошибка смещения в канале }}//if(inBounceDn) }else{ return(-6);//Выход - ошибка покупка запрещена }}//if(LongEnable) }}//if(PositionIsBuy) }}//if((iReady)&&(!IsCloseTime(CloseHour,CloseMinutes,CloseInterval))) {if(GridCreate) { Grid[m].StopTime=datetime(TimeCurrent()+3600*PosLifeTimeHours+60*PosLifeTimeMinutes);//Librecoin добавил datatime return(1);//Выход - новая сетка создана }}//if(Order_Info>0) iReady=false; return(0); }//GridContinue() // //====================================================================================================== // TrailingVSL1() - Трейлинг виртуальных ордеров // Вход: // iType - тип позиции // iMagic - магик для идентификации позиции (сетки) // iVirtualSL - старое значение виртуального SL для позиции // iTrail_Start - начальное значение отступа для трейлинга (макс расстояние от цены до SL) // iTrail_Work - рабочее значение отступа для трейлинга (макс расстояние от цены до SL) // iPosPrice - цена позиции // idMin - старый уровень добавки к VSL // iVSLStart - коэфф для VSL промежуточного диапазона // iVSLWrk - коэфф (0..1) увеличения шага при росте отклонения от цены // ------ // TheSymbol - инструмент // AccSrv - имя торг сервера // gSpread - спред в деньгах // Выход: // iVirtualSL - новое значение виртуального SL для позиции // idMin - новый уровень добавки к VSL //------------------------------------------------------------------------------------------------------ // Техническое описание процедуры трейлинга // 1. Первоначальная установка уровня VSL (на примере BUY) // Если Бид превысил цену более чем на рабочее значение дистанции трейлинга, // То // устанавливаем добавку VSL как (Положительная разница между (Бид) и (Цена + Раб знач дистанции трейлинга)) умноженное на коэфф VSLTrailMult // устанавливаем уровень VSL как (Цена + Минимальная дистанция трейлинга + Добавка VSL) // Иначе // сбрасываем уровень VSL (и добавку VSL) // 2. Переустановка уровня VSL (на примере BUY) // //====================================================================================================== void TrailingVSL1( int iType, int iMagic, double &iVirtualSL, int iTrail_Start, int iTrail_Work, double iPosPrice, double &idMin, double iVSLStart, double iVSLWrk, int iSLTuneInterval) { int val_index=0; //----- {if( (iPosPrice<=0.0)//Нет цены позиции || ((iType!=OP_BUY)&&(iType!=OP_SELL))//Не обрабатываемый тип ордера ) { iVirtualSL=0.0; //Print("TrailingVSL1 exit>>> iType==OP_ALL"); return; }}//if((iPosPrice<=0.0)... //----- //Print("TrailingVSL1 done>>> ..."); double ipStartVSL=iTrail_Start*_Point; double ipWorkVSL=iTrail_Work*_Point;//Пересчет из пунктов в валюту //Print("TrailingVSL1 INTO>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin," Bid=",Bid," Ask=",Ask); //<Начальное значение idMin в деньгах> = (<комиссия в (деньгах на лот)> / <цена пункта(денег на поинт)>)*_Point + <спред в деньгах> double idMin0=((-CalcAddCommPrice(TheSymbol,AccSrv))/SymbolTradeTickValue)*_Point+gSpread;//Добавить своп??? {if(iVirtualSL<0.001)//VSL не был установлен { //Print("TrailingVSL1 NOVSL>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); idMin=idMin0;//Сбросить idMin хотя он и так =0 iVirtualSL=0.0; {if(iType==OP_BUY) { {if(gBid-ipStartVSL-idMin0>iPosPrice)//Bid превысил (цену + комспред) более чем на защитный интервал ipStartVSL { idMin=idMin0+(gBid-iPosPrice-idMin0-ipStartVSL)*iVSLStart; //---iLowest //ArraySetAsSeries(Low,true); CopyLow(TheSymbol,PERIOD_CURRENT,0,MathMin(Bars(TheSymbol,PERIOD_CURRENT),iSLTuneInterval),Low); val_index=ArrayMinimum(Low,0,MathMin(Bars(TheSymbol,PERIOD_CURRENT),iSLTuneInterval)); //--- iVirtualSL=MathMax3(iPosPrice+idMin0,gBid-ipStartVSL-idMin,((val_index!=-1)?(Low[val_index]-idMin0):(iPosPrice+idMin0)));//Устанавливаем VSL на ipStartVSL над ценой позиции }else{//(gBid-ipStartVSL-idMin0<=iPosPrice)//WorkVSL не превышен idMin=idMin0;//Сбросить idMin хотя он и так =0 iVirtualSL=0.0;//Сбросить VSL хотя он и так =0 }}//if(gBid-ipStartVSL-idMin0>iPosPrice) }else{//(iType==OP_SELL) {if(gAsk+idMin0+ipStartVSL=iPosPrice)//WorkVSL не превышен idMin=idMin0;//Сбросить idMin хотя он и так =0 iVirtualSL=0.0;//Сбросить VSL хотя он и так =0 }}//if(gAsk+idMin0+ipStartVSL0.0)//VSL был установлен {if(iType==OP_BUY) { {if(gBid-idMin0-ipWorkVSL>iPosPrice)//Bid превысил цену более чем на WorkVSL { idMin=MathMax(idMin0,MathMax(idMin,idMin0+(gBid-iPosPrice-idMin0-ipWorkVSL)*iVSLWrk)); //---iLowest //ArraySetAsSeries(Low,true); CopyLow(TheSymbol,PERIOD_CURRENT,0,MathMin(Bars(TheSymbol,PERIOD_CURRENT),iSLTuneInterval),Low); val_index=ArrayMinimum(Low,0,MathMin(Bars(TheSymbol,PERIOD_CURRENT),iSLTuneInterval)); //--- iVirtualSL=MathMax3(iPosPrice+idMin0,MathMax(iVirtualSL,gBid-ipWorkVSL-idMin),((val_index!=-1)?(Low[val_index]-idMin0):(iPosPrice+2*idMin0)));//VSL на ipWorkVSL ниже аска }else{//if(Bid<=iPosPrice+ipWorkVSL)//WorkVSL не превышен idMin=MathMax(idMin0,MathMax(idMin,idMin0+(gBid-iPosPrice-idMin0-ipStartVSL)*iVSLStart)); iVirtualSL=MathMax(iPosPrice+idMin0,MathMax(iVirtualSL,gBid-ipStartVSL-idMin));//Устанавливаем VSL на MinVSL над ценой позиции }}//if(Ask>iPositionPrice+iStartVSL) }else{//(iPositionType==POSITION_TYPE_SELL) {if(gAsk+idMin0+ipWorkVSL>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); ArrayResize(Low,ArraySize(Time)); ArrayResize(High,ArraySize(Time)); return; }//TrailingVSL1() // /* //====================================================================================================== // TrailingVSL1() - Трейлинг виртуальных ордеров // Вход: // iType - тип позиции // iMagic - магик для идентификации позиции (сетки) // iVirtualSL - старое значение виртуального SL для позиции // iTrail_Start - начальное значение отступа для трейлинга // iTrail_Step - рабочее значение отступа для трейлинга // iPosPrice - цена позиции // idMin - старый уровень добавки к VSL // ---- // kVSL - коэфф (0..1) увеличения шага при росте отклонения от цены // VSLTrailMult - коэфф для VSL промежуточного диапазона // Выход: // iVirtualSL - новое значение виртуального SL для позиции // idMin - новый уровень добавки к VSL //------------------------------------------------------------------------------------------------------ // Техническое описание процедуры трейлинга // 1. Первоначальная установка уровня VSL (на примере BUY) // Если Бид превысил цену более чем на рабочее значение дистанции трейлинга, // То // устанавливаем добавку VSL как (Положительная разница между (Бид) и (Цена + Раб знач дистанции трейлинга)) умноженное на коэфф VSLTrailMult // устанавливаем уровень VSL как (Цена + Минимальная дистанция трейлинга + Добавка VSL) // Иначе // сбрасываем уровень VSL (и добавку VSL) // 2. Переустановка уровня VSL (на примере BUY) // //====================================================================================================== void TrailingVSL1__( int iType, int iMagic, double &iVirtualSL, int iTrail_Start, int iTrail_Step, double iPosPrice, double &idMin) { //------ {if(iType==OP_ALL) { iVirtualSL=0.0; }}//if(iType==OP_ALL) //----- {if((iPosPrice>0)&&((iType==OP_BUY)||(iType==OP_SELL)))//Есть цена позиции и тип позиции OP_BUY или OP_SELL { double iVSLStep=iTrail_Step*_Point;//Пересчет из пунктов в валюту double iVSLStart=iTrail_Start*_Point; {if(iType==OP_BUY) { double iVSLDelta=(gBid-iPosPrice-iVSLStep)*VSLTrailMult; iVSLDelta=((iVSLDelta>0)?(iVSLDelta):(0.0)); {if(gBid>iPosPrice+iVSLStart) { {if(iVirtualSL>0) { iVirtualSL=MathMax3(gBid-iVSLStep-iVSLDelta,iPosPrice+_Point,iVirtualSL); }else{ iVirtualSL=MathMax(gBid-iVSLStart,iPosPrice+_Point); }}//if(iVirtualSL>0) }else{ {if(gBidiPositionPrice+iTrail_Start*_Point*VSLTrailMult) }}//if(PositionIsBuy) {if(iType==OP_SELL) { double iVSLDelta=(iPosPrice-gAsk-iVSLStep)*VSLTrailMult; iVSLDelta=((iVSLDelta>0)?(iVSLDelta):(0.0)); {if(gAsk0) { iVirtualSL=MathMin3(gAsk+iVSLStep+iVSLDelta,iPosPrice-_Point,iVirtualSL); }else{ iVirtualSL=MathMin(gAsk+iVSLStart,iPosPrice-_Point); }} }else{ {if(gAsk>iPosPrice-_Point) { iVirtualSL=0; }}//if(gAsk>iPosPrice-_Point) }}//if(gBid>iPositionPrice+iTrail_Start*_Point*dDig4Mult) }}//if(PositionIsSell) }}//if((iPosPrice>0)&&((iType==OP_BUY)||(iType==OP_SELL))) return; }//TrailingVSL() */ // /* //====================================================================================================== // TrailingVSL1() - Трейлинг виртуальных ордеров // Вход: // iType - тип позиции // iMagic - магик для идентификации позиции (сетки) // iVirtualSL - старое значение виртуального SL для позиции // iTrail_Start - начальное значение отступа для трейлинга // iTrail_Step - рабочее значение отступа для трейлинга // iPosPrice - цена позиции // idMin - старый уровень добавки к VSL // ---- // kVSL - коэфф (0..1) увеличения шага при росте отклонения от цены // VSLTrailMult - коэфф для VSL промежуточного диапазона // Выход: // iVirtualSL - новое значение виртуального SL для позиции // idMin - новый уровень добавки к VSL //------------------------------------------------------------------------------------------------------ // Техническое описание процедуры трейлинга // 1. Первоначальная установка уровня VSL (на примере BUY) // Если Бид превысил цену более чем на рабочее значение дистанции трейлинга, // То // устанавливаем добавку VSL как (Положительная разница между (Бид) и (Цена + Раб знач дистанции трейлинга)) умноженное на коэфф VSLTrailMult // устанавливаем уровень VSL как (Цена + Минимальная дистанция трейлинга + Добавка VSL) // Иначе // сбрасываем уровень VSL (и добавку VSL) // 2. Переустановка уровня VSL (на примере BUY) // //====================================================================================================== void TrailingVSL1___( int iType, int iMagic, double &iVirtualSL, int iTrail_Start, int iTrail_Step, double iPosPrice, double &idMin) { {if(iType==OP_ALL) { iVirtualSL=0.0; //Print("TrailingVSL1 exit>>> iType==OP_ALL"); return; }}//if(iType==OP_ALL) //----- //Print("TrailingVSL1 done>>> ..."); {if((iPosPrice>0)&&((iType==OP_BUY)||(iType==OP_SELL)))//Есть цена позиции и тип позиции OP_BUY или OP_SELL { double ipWorkVSL=iTrail_Step*_Point;//Пересчет из пунктов в валюту double ipMinVSL=iTrail_Start*_Point; //double ipWorkVSL=VSLTrailWrk*_Point;//Пересчет из пунктов в валюту //double ipMinVSL=VSLTrailMin*_Point; //Print("TrailingVSL1 INTO>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); {if(iVirtualSL<0.001)//VSL не был установлен { //Print("TrailingVSL1 NOVSL>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); idMin=0.0;//Сбросить idMin хотя он и так =0 iVirtualSL=0.0; {if(iType==OP_BUY) { {if(gBid>iPosPrice+ipWorkVSL)//gBid превысил цену более чем на WorkVSL { idMin=MathMax(idMin,((gBid-iPosPrice)-ipWorkVSL)*VSLTrailMult); //Print("TrailingVSL1 INTO>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); iVirtualSL=iPosPrice+ipMinVSL+idMin;//Устанавливаем VSL на MinVSL над ценой позиции }else{//(gBid<=iPosPrice+ipWorkVSL)//WorkVSL не превышен idMin=0.0;//Сбросить idMin хотя он и так =0 iVirtualSL=0.0;//Сбросить VSL хотя он и так =0 }}//if(gBid>iPosPrice+ipWorkVSL) }else{//(iType==OP_SELL) {if(gAsk>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); iVirtualSL=iPosPrice-ipMinVSL-idMin;//VSL на MinVSL под ценой позиции }else{//if(gBid>=iPositionPrice-WorkVSL)//WorkVSL не превышен idMin=0.0;//Сбросить idMin хотя он и так =0 iVirtualSL=0.0;//Сбросить VSL хотя он и так =0 }}//if(gAsk0.0)//VSL был устанвлен //Print("TrailingVSL1 VSL IS>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); {if(iType==OP_BUY) { {if(gBid>iPosPrice+ipWorkVSL)//gBid превысил цену более чем на WorkVSL { {if(gBid>iPosPrice+ipWorkVSL+ipMinVSL+idMin)//WorkVSL + MinVSL превышен { iVirtualSL=MathMax(iVirtualSL,gBid-ipWorkVSL+(gBid-iPosPrice-ipWorkVSL-ipMinVSL-idMin)*kVSL);//VSL на StartVSL ниже аска //Print("iVirtualSL=",iVirtualSL," gBid=",gBid," iPosPrice=",iPosPrice," d=",(gBid-(iPosPrice+ipWorkVSL+ipMinVSL+idMin))); }else{//if(gBid<=iPosPrice+ipWorkVSL+ipMinVSL+idMin)//WorkVSL + MinVSL не превышен а WorkVSL превышен idMin=MathMax(idMin,((gBid-iPosPrice)-ipWorkVSL)*VSLTrailMult); //Print("TrailingVSL1 INTO>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); iVirtualSL=MathMax(iVirtualSL,iPosPrice+ipMinVSL+idMin);//Устанавливаем VSL на MinVSL над ценой позиции }}//if(gBid>iPosPrice+ipWorkVSL+ipMinVSL+idMin) }else{//if(gBid<=iPosPrice+ipWorkVSL)//WorkVSL не превышен idMin=MathMax(idMin,((gBid-iPosPrice)-ipWorkVSL)*VSLTrailMult); //Print("TrailingVSL1 INTO>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); iVirtualSL=MathMax(iVirtualSL,iPosPrice+ipMinVSL+idMin);//Устанавливаем VSL на MinVSL над ценой позиции }}//if(gAsk>iPositionPrice+iStartVSL) }else{//(iPositionType==POSITION_TYPE_SELL) {if(gAsk>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); iVirtualSL=MathMin(iVirtualSL,iPosPrice-ipMinVSL-idMin);//VSL на MinVSL под ценой позиции }}//if(iBid>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); iVirtualSL=MathMin(iVirtualSL,iPosPrice-ipMinVSL-idMin);//VSL на MinVSL под ценой позиции }}//if(gBid0) //----- //{if(iType==OP_BUY) //{ // {if(gBid>iPosPrice+iTrail_Start*_Point*dDig4Mult) // { // {if(iVirtualSL>0) // { // iVirtualSL=MathMax3(gBid-iTrail_Step*_Point*dDig4Mult,iPosPrice+_Point,iVirtualSL); // }else{ // iVirtualSL=MathMax(gBid-iTrail_Step*_Point*dDig4Mult,iPosPrice+_Point); // }}//if(iVirtualSL>0) // }else{ // {if(gBidiPositionPrice+iTrail_Start*_Point*dDig4Mult) //}}//if(PositionIsBuy) //{if(iType==OP_SELL) //{ // {if(gAsk0) // { // iVirtualSL=MathMin3(gAsk+iTrail_Step*_Point*dDig4Mult,iPosPrice-_Point,iVirtualSL); // }else{ // iVirtualSL=MathMin(gAsk+iTrail_Step*_Point*dDig4Mult,iPosPrice-_Point); // }} // }else{ // {if(gAsk>iPosPrice-_Point) // { // iVirtualSL=0; // }}// // }}//if(gBid>iPositionPrice+iTrail_Start*_Point*dDig4Mult) //}}//if(PositionIsSell) //Print("TrailingVSL1 OUT>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); return; }//TrailingVSL1() */ // /* //====================================================================================================== // TrailingVSL2() - Трейлинг виртуальных ордеров v2.0 (for LN v2.022) // Вход: // iType - тип позиции // iMagic - магик для идентификации позиции (сетки) // iVirtualSL - старое значение виртуального SL для позиции // iTrail_Start - начальное значение отступа для трейлинга // iTrail_Step - рабочее значение отступа для трейлинга // iPosPrice - цена позиции // idMin - старый уровень добавки к VSL // ---- // kVSL - коэфф (0..1) увеличения шага при росте отклонения от цены // VSLTrailMult - коэфф для VSL промежуточного диапазона // Выход: // iVirtualSL - новое значение виртуального SL для позиции // idMin - новый уровень добавки к VSL //------------------------------------------------------------------------------------------------------ // Техническое описание процедуры трейлинга // 1. Первоначальная установка уровня VSL (на примере BUY) // Если Бид превысил цену более чем на рабочее значение дистанции трейлинга, // То // устанавливаем добавку VSL как (Положительная разница между (Бид) и (Цена + Раб знач дистанции трейлинга)) умноженное на коэфф VSLTrailMult // устанавливаем уровень VSL как (Цена + Минимальная дистанция трейлинга + Добавка VSL) // Иначе // сбрасываем уровень VSL (и добавку VSL) // 2. Переустановка уровня VSL (на примере BUY) // //====================================================================================================== void TrailingVSL2( int iType, int iMagic, double &iVirtualSL, int iTrail_Start, int iTrail_Step, double iPosPrice, double &idMin, int iVSLMode){ {if(iType==OP_ALL) { iVirtualSL=0.0; //Print("TrailingVSL2 exit>>> iType==OP_ALL"); return; }}//if(iType==OP_ALL) //----- //Print("TrailingVSL2 done>>> ..."); {if(iVSLMode==0) { {if((iPosPrice>0)&&((iType==OP_BUY)||(iType==OP_SELL)))//Есть цена позиции и тип позиции OP_BUY или OP_SELL { double ipWorkVSL=iTrail_Step*_Point;//Пересчет из пунктов в валюту double ipMinVSL=iTrail_Start*_Point; //double ipWorkVSL=VSLTrailWrk*_Point;//Пересчет из пунктов в валюту //double ipMinVSL=VSLTrailMin*_Point; //***** //Print("TrailingVSL2 INTO>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); {if(iVirtualSL<0.001)//VSL не был установлен { //Print("TrailingVSL2 NOVSL>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); idMin=0.0;//Сбросить idMin хотя он и так =0 iVirtualSL=0.0; {if(iType==OP_BUY) { {if(gBid>iPosPrice+ipWorkVSL)//gBid превысил цену более чем на WorkVSL { idMin=MathMax(idMin,(gBid-(iPosPrice+ipWorkVSL))*VSLTrailMult); //Print("TrailingVSL2 INTO>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); iVirtualSL=iPosPrice+ipMinVSL+idMin;//Устанавливаем VSL на MinVSL над ценой позиции }else{//(gBid<=iPosPrice+ipWorkVSL)//WorkVSL не превышен idMin=0.0;//Сбросить idMin хотя он и так =0 iVirtualSL=0.0;//Сбросить VSL хотя он и так =0 }}//if(gBid>iPosPrice+ipWorkVSL) }else{//(iType==OP_SELL) {if(gAsk>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); iVirtualSL=iPosPrice-ipMinVSL-idMin;//VSL на MinVSL под ценой позиции }else{//if(gBid>=iPositionPrice-WorkVSL)//WorkVSL не превышен idMin=0.0;//Сбросить idMin хотя он и так =0 iVirtualSL=0.0;//Сбросить VSL хотя он и так =0 }}//if(gAsk0.0)//VSL был устанвлен //Print("TrailingVSL2 VSL IS>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); {if(iType==OP_BUY) { {if(gBid>iPosPrice+ipWorkVSL)//gBid превысил цену более чем на WorkVSL { {if(gBid>iPosPrice+ipWorkVSL+ipMinVSL+idMin)//WorkVSL + MinVSL превышен { iVirtualSL=MathMax(iVirtualSL,gBid-ipWorkVSL+((gBid-(iPosPrice+ipWorkVSL+ipMinVSL+idMin))*kVSL));//VSL на StartVSL ниже аска //Print("iVirtualSL=",iVirtualSL," gBid=",gBid," iPosPrice=",iPosPrice," d=",(gBid-(iPosPrice+ipWorkVSL+ipMinVSL+idMin))); }else{//if(gBid<=iPosPrice+ipWorkVSL+ipMinVSL+idMin)//WorkVSL + MinVSL не превышен а WorkVSL превышен idMin=MathMax(idMin,(gBid-(iPosPrice+ipWorkVSL))*VSLTrailMult); //Print("TrailingVSL1 INTO>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); iVirtualSL=MathMax(iVirtualSL,iPosPrice+ipMinVSL+idMin);//Устанавливаем VSL на MinVSL над ценой позиции }}//if(gBid>iPosPrice+ipWorkVSL+ipMinVSL+idMin) }else{//if(gBid<=iPosPrice+ipWorkVSL)//WorkVSL не превышен idMin=MathMax(idMin,(gBid-(iPosPrice+ipWorkVSL))*VSLTrailMult); //Print("TrailingVSL1 INTO>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); iVirtualSL=MathMax(iVirtualSL,iPosPrice+ipMinVSL+idMin);//Устанавливаем VSL на MinVSL над ценой позиции }}//if(gAsk>iPositionPrice+iStartVSL) }else{//(iPositionType==POSITION_TYPE_SELL) {if(gAsk>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); iVirtualSL=MathMin(iVirtualSL,iPosPrice-ipMinVSL-idMin);//VSL на MinVSL под ценой позиции }}//if(iBid>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); iVirtualSL=MathMin(iVirtualSL,iPosPrice-ipMinVSL-idMin);//VSL на MinVSL под ценой позиции }}//if(gBid0) }}//if(VSLMode==0) //------ double iCommiss=0.0;//Временно {if(iVSLMode==1) { {if((iPosPrice>0)&&((iType==OP_BUY)||(iType==OP_SELL)))//Есть цена позиции и тип позиции OP_BUY или OP_SELL { double ipWorkVSL=iTrail_Step*_Point;//Пересчет из пунктов в валюту double ipMinVSL=iTrail_Start*_Point; //double ipWorkVSL=VSLTrailWrk*_Point;//Пересчет из пунктов в валюту //double ipMinVSL=VSLTrailMin*_Point; //***** //Print("TrailingVSL2 INTO>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); {if(iVirtualSL<0.001)//VSL не был установлен { //Print("TrailingVSL2 NOVSL>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); idMin=0.0;//Сбросить idMin хотя он и так =0 iVirtualSL=0.0; {if(iType==OP_BUY) { {if((gBid-iPosPrice)>(ipMinVSL+iCommiss))//Дельта (gBid-Цена) превысила начальный порог (МинОтступ+Комиссия) { idMin=MathMax(idMin,(gBid-(iPosPrice+ipWorkVSL))*VSLTrailMult); //Print("TrailingVSL2 INTO>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); iVirtualSL=iPosPrice+ipMinVSL+idMin;//Устанавливаем VSL на MinVSL над ценой позиции }else{//(gBid<=iPosPrice+ipWorkVSL)//WorkVSL не превышен idMin=0.0;//Сбросить idMin хотя он и так =0 iVirtualSL=0.0;//Сбросить VSL хотя он и так =0 }}//if(gBid>iPosPrice+ipWorkVSL) }else{//(iType==OP_SELL) {if(gAsk>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); iVirtualSL=iPosPrice-ipMinVSL-idMin;//VSL на MinVSL под ценой позиции }else{//if(gBid>=iPositionPrice-WorkVSL)//WorkVSL не превышен idMin=0.0;//Сбросить idMin хотя он и так =0 iVirtualSL=0.0;//Сбросить VSL хотя он и так =0 }}//if(gAsk0.0)//VSL был устанвлен //Print("TrailingVSL2 VSL IS>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); {if(iType==OP_BUY) { {if(gBid>iPosPrice+ipWorkVSL)//gBid превысил цену более чем на WorkVSL { {if(gBid>iPosPrice+ipWorkVSL+ipMinVSL+idMin)//WorkVSL + MinVSL превышен { iVirtualSL=MathMax(iVirtualSL,gBid-ipWorkVSL+((gBid-(iPosPrice+ipWorkVSL+ipMinVSL+idMin))*kVSL));//VSL на StartVSL ниже аска //Print("iVirtualSL=",iVirtualSL," gBid=",gBid," iPosPrice=",iPosPrice," d=",(gBid-(iPosPrice+ipWorkVSL+ipMinVSL+idMin))); }else{//if(gBid<=iPosPrice+ipWorkVSL+ipMinVSL+idMin)//WorkVSL + MinVSL не превышен а WorkVSL превышен idMin=MathMax(idMin,(gBid-(iPosPrice+ipWorkVSL))*VSLTrailMult); //Print("TrailingVSL1 INTO>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); iVirtualSL=MathMax(iVirtualSL,iPosPrice+ipMinVSL+idMin);//Устанавливаем VSL на MinVSL над ценой позиции }}//if(gBid>iPosPrice+ipWorkVSL+ipMinVSL+idMin) }else{//if(gBid<=iPosPrice+ipWorkVSL)//WorkVSL не превышен idMin=MathMax(idMin,(gBid-(iPosPrice+ipWorkVSL))*VSLTrailMult); //Print("TrailingVSL1 INTO>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); iVirtualSL=MathMax(iVirtualSL,iPosPrice+ipMinVSL+idMin);//Устанавливаем VSL на MinVSL над ценой позиции }}//if(gAsk>iPositionPrice+iStartVSL) }else{//(iPositionType==POSITION_TYPE_SELL) {if(gAsk>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); iVirtualSL=MathMin(iVirtualSL,iPosPrice-ipMinVSL-idMin);//VSL на MinVSL под ценой позиции }}//if(iBid>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); iVirtualSL=MathMin(iVirtualSL,iPosPrice-ipMinVSL-idMin);//VSL на MinVSL под ценой позиции }}//if(gBid0) }}//if(VSLMode==1) //----- //{if(iType==OP_BUY) //{ // {if(gBid>iPosPrice+iTrail_Start*_Point*dDig4Mult) // { // {if(iVirtualSL>0) // { // iVirtualSL=MathMax3(gBid-iTrail_Step*_Point*dDig4Mult,iPosPrice+_Point,iVirtualSL); // }else{ // iVirtualSL=MathMax(gBid-iTrail_Step*_Point*dDig4Mult,iPosPrice+_Point); // }}//if(iVirtualSL>0) // }else{ // {if(gBidiPositionPrice+iTrail_Start*_Point*dDig4Mult) //}}//if(PositionIsBuy) //{if(iType==OP_SELL) //{ // {if(gAsk0) // { // iVirtualSL=MathMin3(gAsk+iTrail_Step*_Point*dDig4Mult,iPosPrice-_Point,iVirtualSL); // }else{ // iVirtualSL=MathMin(gAsk+iTrail_Step*_Point*dDig4Mult,iPosPrice-_Point); // }} // }else{ // {if(gAsk>iPosPrice-_Point) // { // iVirtualSL=0; // }}// // }}//if(gBid>iPositionPrice+iTrail_Start*_Point*dDig4Mult) //}}//if(PositionIsSell) //Print("TrailingVSL2 OUT>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin); return; }//TrailingVSL2() */ // ////====================================================================================================== //// TrailingSL() ////====================================================================================================== //void TrailingSL(int iType, int iMagic, int iTrail_Start, int iTrail_Step, double iPosPrice){ //double OldStopLoss; //double NewStopLoss; ////----- // {if (iTrail_Step!=0) // { // if(PositionsTotal()>0) // {for(int n=PositionsTotal()-1;n>=0;n--) // { // Ord_Inf=PositionSelect(n,SELECT_BY_POS,MODE_TRADES); // {if(!Ord_Inf){continue;}} // {if((PositionGetString(POSITION_SYMBOL)!=TheSymbol)||(PositionGetInteger(POSITION_MAGIC)!=iMagic)){continue;}} // OldStopLoss=PositionGetDouble(POSITION_SL); // {if(((OP_TYPE)PositionGetInteger(POSITION_TYPE)==OP_BUY)&&((iType==OP_ALL)||(iType==OP_BUY))) // { // {if((gBid>iPosPrice+iTrail_Start*_Point*dDig4Mult)//Если прибыль больше старта трала // &&(gBid>iPosPrice+SymbolInfoInteger(TheSymbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point))//И больше стоплевела // { // //Установим если не было (подвинем если был) стоплосс на максимальное из // //1. iPositionPrice+_Point // //2. gBid-iTrail_Step // NewStopLoss=fNormalizeDouble(MathMax(gBid-iTrail_Step*_Point*dDig4Mult,iPosPrice+_Point)); // {if(NewStopLoss>gBid-SymbolInfoInteger(TheSymbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point) // {//Больше стоплевела - нельзя ставить можно только на стоплевел // NewStopLoss=fNormalizeDouble(gBid-SymbolInfoInteger(TheSymbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point); // }}// // {if(((NewStopLoss>OldStopLoss)||(OldStopLoss==0))&&(NewStopLoss>iPosPrice)) // {//Лучше прежнего или первый раз, ну и конечно выше средней цены // Ord_Inf=OrderModify(PositionGetInteger(POSITION_TICKET),PositionGetDouble(POSITION_PRICE_OPEN),NewStopLoss,PositionGetDouble(POSITION_TP),0,Aqua); // }}// // }}//if // }}//if ((OP_TYPE)PositionGetInteger(POSITION_TYPE)==OP_BUY) // {if(((OP_TYPE)PositionGetInteger(POSITION_TYPE)==OP_SELL)&&((iType==OP_ALL)||(iType==OP_SELL))) // { // {if((gAsk=0;n--) // }}//if (iTrailStep!=0) //}//TrailingSL() // //====================================================================================================== // TrailingSL1() v4.105 // Описание: // Устанавливаем стопы чуть позднее виртуальных (на 1-3 пункта SL2VSLSlip) // Вход: // iType // iMagic // iVirtualSL //====================================================================================================== void TrailingSL1( int iType, //Тип позиции int iMagic, //Магик позиции double &iVirtualSL, //Уровень виртуального стоплосса double &iSL, //Уровень стоплосс для позиции после установки int iSL2VSLSlip, //Растояние в пипсах между SL(хуже) и VSL(лучше) double iPosPrice) //Цена позиции { int m=iMagic-Grid[0].Magic; double OldStopLoss; double NewStopLoss; //----- {if (iVirtualSL>=0)//Виртуальный уже установлен { if(PositionsTotal()>0)//Есть сделки {for(int i=PositionsTotal()-1;i>=0;i--)//Перебираем сделки { ulong Pos_Tick=PositionGetTicket(i);//Выбираем позицию по номеру в списке {if(Pos_Tick<=0){continue;}}//Неудачно - следующий {if(!PositionSelectByTicket(Pos_Tick)){continue;}};//Выбираем позицию по тикету? Неудачно - следующий {if(PositionGetString(POSITION_SYMBOL)!=TheSymbol){continue;}}//Не наш символ - к следующему {if((PositionGetInteger(POSITION_MAGIC)!=iMagic)){continue;}}//Не наш магик - к следующему {if(PositionGetDouble(POSITION_VOLUME)<0.01){continue;}}//Нулевой объём - к следующему OldStopLoss=PositionGetDouble(POSITION_SL);//Запомним текущий стоплосс {if((PositionGetInteger(POSITION_TYPE)==OP_BUY)&&((iType==OP_ALL)||(iType==OP_BUY)))//Отбор по типу ордера { {if(gBid>iVirtualSL-iSL2VSLSlip*_Point+SymbolInfoInteger(TheSymbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point)////И больше стоплевела от iVirtualSL-iSL2VSLSlip { //Установим если не было (подвинем если был) стоплосс на iVirtualSL-iSL2VSLSlip NewStopLoss=fNormalizeDouble(iVirtualSL-iSL2VSLSlip*_Point); {if(NewStopLoss>gBid-SymbolInfoInteger(TheSymbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point) {//Больше стоплевела - нельзя ставить можно только на стоплевел NewStopLoss=fNormalizeDouble(gBid-SymbolInfoInteger(TheSymbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point); }}// {if(((NewStopLoss>OldStopLoss)||(OldStopLoss==0))&&(NewStopLoss>iPosPrice)) {//Лучше прежнего или первый раз, ну и конечно выше средней цены Ord_Inf=PositionModifySL(Pos_Tick,NewStopLoss,PositionGetDouble(POSITION_TP)); {if(Ord_Inf) { Grid[m].StopLossLevel=NewStopLoss; iSL=NewStopLoss; }}//if(Ord_Inf) }}// }}//if }}//if(PositionGetInteger(POSITION_TYPE)==OP_BUY) {if((PositionGetInteger(POSITION_TYPE)==OP_SELL)&&((iType==OP_ALL)||(iType==OP_SELL))) { {if(gAsk=0;n--) }}//if (iTrailStep!=0) }//TrailingSL1() // //====================================================================================================== // CloseGrid() - Закрывает несколько позиций (сетку) по инструменту, типу и магику, с возможностью закрытия только убыточных //====================================================================================================== int CloseGrid( string iSymbol, OP_TYPE iType, bool iLossOnly, int iMagic){ int m=iMagic-Grid[0].Magic; int nClosed=0; //----- {if((iLossOnly)&&(CalcPositionProfitSum1(TheSymbol,iType,iMagic,1)>0.0)&&(Grid[m].VirtualSL>0.0)) { return(nClosed); }}//if((iLossOnly)&&(CalcPositionProfitSum()>0.0)) if(PositionsTotal()>0) {for (int i=PositionsTotal()-1;i>=0;i--) { ulong Pos_Tick=PositionGetTicket(i);//Выбираем позицию по номеру в списке {if(Pos_Tick<=0){continue;}}//Неудачно - следующий {if(!PositionSelectByTicket(Pos_Tick)){continue;}}//Выбираем позицию по тикету? Неудачно - следующий {if(PositionGetString(POSITION_SYMBOL)!=iSymbol){continue;}}//Отбор по инструменту {if(PositionGetInteger(POSITION_MAGIC)!=iMagic){continue;}}//Отбор по магику {if(PositionGetDouble(POSITION_VOLUME)==0.0){continue;}}//Отбор непустых ENUM_POSITION_TYPE OrdType=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); //{if((OrdType!=POSITION_TYPE_SELL)&&(OrdType!=POSITION_TYPE_BUY)){continue;}} {if((OrdType==POSITION_TYPE_BUY)&&((iType==OP_BUY)||(iType==OP_ALL))) { //Ord_Inf=mPositionClose2(iSymbol,PositionGetInteger(POSITION_IDENTIFIER),SlipFixOrd,RepFixOrd,"CloseGrid(BUY)"); Ord_Inf=mPositionClose2(iSymbol,Pos_Tick,SlipFixOrd,RepFixOrd,"CloseGrid(BUY)"); nClosed++; continue; }}//if((OrdType==POSITION_TYPE_SELL)&&((iType==OP_SELL)||(iType==OP_ALL))) {if((OrdType==POSITION_TYPE_SELL)&&((iType==OP_SELL)||(iType==OP_ALL))) { //Ord_Inf=mPositionClose2(iSymbol,PositionGetInteger(POSITION_IDENTIFIER),SlipFixOrd,RepFixOrd,"CloseGrid(SELL)"); Ord_Inf=mPositionClose2(iSymbol,Pos_Tick,SlipFixOrd,RepFixOrd,"CloseGrid(SELL)"); nClosed++; }}//if((OrdType==POSITION_TYPE_SELL)&&((iType==OP_SELL)||(iType==OP_ALL))) Sleep(CloseDelay); }}//for (int j=PositionsTotal()-1;j>=0;j--) {if(nClosed>0) { Grid[m].CloseOn=true; Grid[m].Active=false; Grid[m].VirtualSL=0.0; Grid[m].Type=OP_ALL; Grid[m].Ticket=0; }}//if(nClosed>0) return(nClosed); }//CloseGrid // //====================================================================================================== // CloseGridesAll() // Описание: // Закрывает ордера заданного типа и заданного диапазона магиков, возможно только убыточные //====================================================================================================== int CloseGridesAll( string iSymbol, OP_TYPE iType, bool iLossOnly, int iMagic, int inGrides){ int m=0; long OrderMagicN=iMagic; int nClosed=0; //----- {if((iLossOnly)&&(CalcPositionProfitSum1(TheSymbol,iType,iMagic,inGrides)>0.0)) //{if((iLossOnly)&&(CalcPositionProfitSum1(iType,iMagic,inGrides)>0.0)&&(Grid[m].VirtualSL>0.0)) { return(nClosed); }}//if((iLossOnly)&&(CalcPositionProfitSum()>0.0)) if(PositionsTotal()>0) {for (int i=PositionsTotal()-1;i>=0;i--) { ulong Pos_Tick=PositionGetTicket(i);//Выбираем позицию по номеру в списке {if(Pos_Tick<=0){continue;}}//Неудачно - следующий {if(!PositionSelectByTicket(Pos_Tick)){continue;}}//Выбираем позицию по тикету? Неудачно - следующий {if(PositionGetString(POSITION_SYMBOL)!=TheSymbol){continue;}}//Отбор по символу OrderMagicN=PositionGetInteger(POSITION_MAGIC); m=(int)(OrderMagicN-Grid[0].Magic); {if(((OrderMagicN=iMagic+inGrides))&&(iMagic!=MAGIC_ALL)){continue;}}//Отбор по магику {if(PositionGetDouble(POSITION_VOLUME)==0.0){continue;}}//Отбор непустых ENUM_POSITION_TYPE OrdType=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); //{if((OrdType!=POSITION_TYPE_SELL)&&(OrdType!=POSITION_TYPE_BUY)){continue;}} Ord_Int=-1; {if((OrdType==POSITION_TYPE_BUY)&&((iType==OP_BUY)||(iType==OP_ALL))) { //Print("Grid[0].Magic=",Grid[0].Magic," PositionGetInteger(POSITION_MAGIC)=",PositionGetInteger(POSITION_MAGIC)); Ord_Int=mPositionClose2(iSymbol,PositionGetInteger(POSITION_TICKET),SlipFixOrd,RepFixOrd,"CloseGridesAll(BUY)"); //Print("ClosePositionAll in for, VirtualSL Close TRY OP_BUY Ord_Int=",Ord_Int); {if((Ord_Int==ERR_NO_MQLERROR)||(Ord_Int==ERR_SUCCESS)) { Grid[m].VirtualSL=0.0; Grid[m].Type=OP_ALL; Grid[m].Active=false; nClosed++; continue; }}//if(Ord_Inf) }}//if((OrdType==POSITION_TYPE_BUY)&&((iType==OP_BUY)||(iType==OP_ALL))) {if((OrdType==POSITION_TYPE_SELL)&&((iType==OP_SELL)||(iType==OP_ALL))) { Ord_Int=mPositionClose2(iSymbol,PositionGetInteger(POSITION_TICKET),SlipFixOrd,RepFixOrd,"CloseGridesAll(SELL)"); //Print("ClosePositionAll in for, VirtualSL Close TRY OP_SELL Ord_Int=",Ord_Int); {if((Ord_Int==ERR_NO_MQLERROR)||(Ord_Int==ERR_SUCCESS)) { Grid[m].VirtualSL=0.0; Grid[m].Type=OP_ALL; Grid[m].Active=false; nClosed++; //continue; }}//if(Ord_Inf) }}//if((OrdType==POSITION_TYPE_SELL)&&((iType==OP_SELL)||(iType==OP_ALL))) Sleep(CloseDelay); }}//for (int j=PositionsTotal()-1;j>=0;j--) return(nClosed); }//CloseGridesAll // ////====================================================================================================== //// B4BCloseMA();//v69.159 008 - Закрывает все ордера встречно-оптимально ////====================================================================================================== //bool B4BCloseMA(int iMagic,int inGrides){ // if (!B4BCloseMOn) {return(false);} //bool // B4BRes=false, // BePair=true; //double // AddCom=0.0, // closeLot=0, // closeProfit=0, // lossLotBUY=0, // lossLotSELL=0, // lossBUY=0, // lossSELL=0, // profitLotBUY=0, // profitLotSELL=0, // profitBUY=0, // profitSELL=0, // profitDBUY=99999999.0, // profitDSELL=99999999.0; //int // Ord_Tick=-1, // nMLossBUY=-1, // nMLossSELL=-1, // nMProfitBUY=-1, // nMProfitSELL=-1; //// if (AccountFreeMargin()>B4BCloseLim*MathMax(AccountInfoDouble(ACCOUNT_EQUITY),AccountInfoDouble(ACCOUNT_BALANCE))) {return(true);} //// if (AccountFreeMargin()>B4BCloseLim*AccountInfoDouble(ACCOUNT_BALANCE)) {return(true);}//Порог от Equity для инициации закрытия // while (BePair==true)//Надо - ибо не один // { // closeLot=0; // closeProfit=0; // lossLotBUY=0; // lossLotSELL=0; // profitLotBUY=0; // profitLotSELL=0; // lossBUY=0; // lossSELL=0; // profitBUY=0; // profitSELL=0; // profitDBUY=99999999.0; // profitDSELL=99999999.0; // nMLossBUY=-1; // nMLossSELL=-1; // nMProfitBUY=-1; // nMProfitSELL=-1; // //Закрываем максимальный убыток на оптимальную прибыль // //Ищем ордер с максимальным убытком на лот // {//Перебор ордеров от последнего к первому // for(int y=PositionsTotal()-1;y>=0;y--) // { // Ord_inf=PositionSelect(y,SELECT_BY_POS,MODE_TRADES); // if (!Ord_inf) {continue;} // if (PositionGetString(POSITION_SYMBOL)!=_Symbol) {continue;} // {if((PositionGetInteger(POSITION_MAGIC)=iMagic+inGrides)){continue;}} //Отбор по магику // Ord_Tick=PositionGetInteger(POSITION_TICKET); // Ord_inf=PositionSelect(Ord_Tick,SELECT_BY_TICKET,MODE_TRADES); // if (!Ord_inf) {continue;} // {//Если ордер убыточный // if (PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_COMISSION)+PositionGetDouble(POSITION_SWAP)-10*AddCom*PositionGetDouble(POSITION_VOLUME)<-0.0001) // { // {//Для ордера на покупку // if ((OP_TYPE)PositionGetInteger(POSITION_TYPE)==OP_BUY) // { // {//Если убыток больше (его значение меньше) ранее найденного по BUY // if (PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_COMISSION)+PositionGetDouble(POSITION_SWAP)-10*AddCom*PositionGetDouble(POSITION_VOLUME)=0;y--) // {//Если решения по LOSS не найдено // if ((nMLossBUY<0)&&(nMLossSELL<0)) // { // //B4BRes=false; //if (PrnB4BM) Print("************* B4BCloseM 1>>"," LOSSES NOT FOUND!!!"," lossB=",lossBUY," lossS=",lossSELL, // " Fr=",AccountFreeMargin()," Eq=",AccountInfoDouble(ACCOUNT_EQUITY));//," MinEq=",MinEq); // //continue; // return(B4BRes); // }}//if ((nMLossBUY<0)&&(nMLossSELL<0)) //if (PrnB4BM) Print("************* B4BCloseM 2>>"," LOSSES FOUND!!!"," lossB=",lossBUY," lossS=",lossSELL, // " Fr=",AccountFreeMargin()," Eq=",AccountInfoDouble(ACCOUNT_EQUITY));//," MinEq=",MinEq); // //Ищем ордер с оптимальной прибылью на лот // //тут имена переменных унаследованы и особого смысла не имеют // {//Перебор ордеров от конца - к началу // for (int y=PositionsTotal()-1;y>=0;y--) // {//перебор всех ордеров // Ord_inf=PositionSelect(y,SELECT_BY_POS,MODE_TRADES); // if (!Ord_inf) {continue;} // if (PositionGetString(POSITION_SYMBOL)!=_Symbol) {continue;} // {if((PositionGetInteger(POSITION_MAGIC)=iMagic+inGrides)){continue;}} //Отбор по магику // Ord_Tick=PositionGetInteger(POSITION_TICKET); // Ord_inf=PositionSelect(Ord_Tick,SELECT_BY_TICKET,MODE_TRADES); // if (!Ord_inf) {continue;} // {//Если ордер прибыльный // if (PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_COMISSION)+PositionGetDouble(POSITION_SWAP)-10*AddCom*PositionGetDouble(POSITION_VOLUME)>0.0001) // { // {//Для ордера на покупку - если убыток от ордера на продажу обнаружен // if (((OP_TYPE)PositionGetInteger(POSITION_TYPE)==OP_BUY)&&(lossLotSELL>0)&&(PositionGetDouble(POSITION_VOLUME)>0)) // { // //Вычисляем возмоный профит по BUY // double profitDBUYtmp=(PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_COMISSION)+PositionGetDouble(POSITION_SWAP)-10*AddCom*PositionGetDouble(POSITION_VOLUME))/PositionGetDouble(POSITION_VOLUME)+lossSELL/lossLotSELL; // {//Если было найдено - в убыток, а теперь в прибыль - то запомним // if ((profitDBUY<0)&&(profitDBUYtmp>0)) // { // nMProfitBUY=Ord_Tick; // profitBUY=PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_COMISSION)+PositionGetDouble(POSITION_SWAP)-10*AddCom*PositionGetDouble(POSITION_VOLUME); // profitLotBUY=PositionGetDouble(POSITION_VOLUME); // profitDBUY=profitDBUYtmp; // }else{ // {//Если было найдено - в убыток, и теперь в убыток - то оценим // if ((profitDBUY<0)&&(profitDBUYtmp<0)) // { // {//Если значения ближе - запомним // if (MathAbs(profitDBUYtmp)0)&&(profitDBUYtmp>0)) // { // {//Если значения ближе - запомним // if (MathAbs(profitDBUYtmp)0)&&(profitDBUYtmp>0)) // //Если было найдено - в прибыль, а теперь в убыток - то ничего делать не надо // }}//if ((profitDBUY<0)&&(profitDBUYtmp<0)) // }} // }}//if (((OP_TYPE)PositionGetInteger(POSITION_TYPE)==OP_BUY)&&(lossLotSELL>0)&&(PositionGetDouble(POSITION_VOLUME)>0)) // {//Для ордера на продажу - если убыток от ордера на покупку обнаружен // if (((OP_TYPE)PositionGetInteger(POSITION_TYPE)==OP_SELL)&&(lossLotBUY>0)&&(PositionGetDouble(POSITION_VOLUME)>0)) // { // //Вычисляем возмоный профит по SELL // double profitDSELLtmp=(PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_COMISSION)+PositionGetDouble(POSITION_SWAP)-10*AddCom*PositionGetDouble(POSITION_VOLUME))/PositionGetDouble(POSITION_VOLUME)+lossBUY/lossLotBUY; // {//Если было найдено - в убыток, а теперь в прибыль - то запомним // if ((profitDSELL<0)&&(profitDSELLtmp>0)) // { // nMProfitSELL=Ord_Tick; // profitSELL=PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_COMISSION)+PositionGetDouble(POSITION_SWAP)-10*AddCom*PositionGetDouble(POSITION_VOLUME); // profitLotSELL=PositionGetDouble(POSITION_VOLUME); // profitDSELL=profitDSELLtmp; // }else{ // {//Если было найдено - в убыток, и теперь в убыток - то оценим // if ((profitDSELL<0)&&(profitDSELLtmp<0)) // { // {//Если значения ближе - запомним // if (MathAbs(profitDSELLtmp)0)&&(profitDSELLtmp>0)) // { // {//Если значения ближе - запомним // if (MathAbs(profitDSELLtmp)0)&&(profitDSELLtmp>0)) // }}//if ((profitDSELL<0)&&(profitDSELLtmp>0)) // }} // }}//if (((OP_TYPE)PositionGetInteger(POSITION_TYPE)==OP_SELL)&&(lossLotBUY>0)&&(PositionGetDouble(POSITION_VOLUME)>0)) // }}//if (PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_COMISSION)+PositionGetDouble(POSITION_SWAP)>0.0001) // }}//for (int y=PositionsTotal()-1;y>=0;y--) // {//Если решения по Profit не найдено // if ((nMProfitBUY<0)&&(nMProfitSELL<0)) // { // //B4BRes=false; //if (PrnB4BM) Print("************* B4BCloseM 3>>"," PROFIT NOT FOUND!!!"," profitB=",profitBUY," profitS=",profitSELL, // " Fr=",AccountFreeMargin()," Eq=",AccountInfoDouble(ACCOUNT_EQUITY));//," MinEq=",MinEq); // //continue; // return(B4BRes); // }}//if ((nMProfitBUY<0)&&(nMProfitSELL<0)) //if (PrnB4BM) Print("************* B4BCloseM 4>>"," PROFIT FOUND!!!"," profitB=",profitBUY," profitS=",profitSELL, // " Fr=",AccountFreeMargin()," Eq=",AccountInfoDouble(ACCOUNT_EQUITY));//," MinEq=",MinEq); // double lim=100; // bool pairFound=false; // // for (lim=1000;lim>100;lim-=10) // { // if ((profitBUY>0.0001)&&(lossSELL<-0.0001)&&(profitBUY>=-lim*lossSELL))//&&(tsmiTrendBidNorm[9]<0))//прибыльный BUY - убыточный SELL - и прибыль падает // { // closeLot=MathMin(profitLotBUY,lossLotSELL); // closeProfit=closeLot*(profitBUY/profitLotBUY+lossSELL/lossLotSELL); // pairFound=true; // if (Prn1) Print(" profitLotBUY=",profitLotBUY," lossLotSELL=",lossLotSELL);//," ltSprad=",ltSprad); // } // if ((profitSELL>0.0001)&&(lossBUY<-0.0001)&&(profitSELL>=-lim*lossBUY))//&&(tsmiTrendAskNorm[9]>0))//прибыльный SELL - убыточный BUY - и прибыль падает // { // closeLot=MathMin(profitLotSELL,lossLotBUY); // closeProfit=closeLot*(profitSELL/profitLotSELL+lossBUY/lossLotBUY); // pairFound=true; // if (Prn1) Print(" profitLotSELL=",profitLotSELL," lossLotBUY=",lossLotBUY);//," ltSprad=",ltSprad); // } // if (pairFound){break;} // }//end for // // if (!pairFound) // for (lim=100;lim>10;lim-=1) // { // if ((profitBUY>0.0001)&&(lossSELL<-0.0001)&&(profitBUY>=-lim*lossSELL))//&&(tsmiTrendBidNorm[9]<0))//прибыльный BUY - убыточный SELL - и прибыль падает // { // closeLot=MathMin(profitLotBUY,lossLotSELL); // closeProfit=closeLot*(profitBUY/profitLotBUY+lossSELL/lossLotSELL); // pairFound=true; // if (Prn1) Print(" profitLotBUY=",profitLotBUY," lossLotSELL=",lossLotSELL);//," ltSprad=",ltSprad); // } // if ((profitSELL>0.0001)&&(lossBUY<-0.0001)&&(profitSELL>=-lim*lossBUY))//&&(tsmiTrendAskNorm[9]>0))//прибыльный SELL - убыточный BUY - и прибыль падает // { // closeLot=MathMin(profitLotSELL,lossLotBUY); // closeProfit=closeLot*(profitSELL/profitLotSELL+lossBUY/lossLotBUY); // pairFound=true; // if (Prn1) Print(" profitLotSELL=",profitLotSELL," lossLotBUY=",lossLotBUY);//," ltSprad=",ltSprad); // } // if (pairFound){break;} // }//end for // // if (!pairFound) // for (lim=10.0;lim>=B4BMLowLim;lim-=0.001) // { // if ((profitBUY>0.0001)&&(lossSELL<-0.0001)&&(profitBUY>=-lim*lossSELL))//&&(tsmiTrendBidNorm[9]<0))//прибыльный BUY - убыточный SELL - и прибыль падает // { // closeLot=MathMin(profitLotBUY,lossLotSELL); // closeProfit=closeLot*(profitBUY/profitLotBUY+lossSELL/lossLotSELL); // pairFound=true; // if (Prn1) Print(" profitLotBUY=",profitLotBUY," lossLotSELL=",lossLotSELL);//," ltSprad=",ltSprad); // } // if ((profitSELL>0.0001)&&(lossBUY<-0.0001)&&(profitSELL>=-lim*lossBUY))//&&(tsmiTrendAskNorm[9]>0))//прибыльный SELL - убыточный BUY - и прибыль падает // { // closeLot=MathMin(profitLotSELL,lossLotBUY); // closeProfit=closeLot*(profitSELL/profitLotSELL+lossBUY/lossLotBUY); // pairFound=true; // if (Prn1) Print(" profitLotSELL=",profitLotSELL," lossLotBUY=",lossLotBUY);//," ltSprad=",ltSprad); // } // if (pairFound){break;} // }//end for // // if (pairFound) // { //if (PrnB4BM) Print("************* B4BCloseM 5>>"," PAIR FOUND!!!", // " profitLotB=",profitLotBUY," lossLotS=",lossLotSELL," profitLotS=",profitLotSELL," lossLotB=",lossLotBUY, // " Fr=",AccountFreeMargin()," Eq=",AccountInfoDouble(ACCOUNT_EQUITY));//," MinEq=",MinEq); // }else{ // //B4BRes=false; //if (PrnB4BM) Print("************* B4BCloseM 6>>"," PAIR NOT FOUND!!!", // " profitLotB=",profitLotBUY," lossLotS=",lossLotSELL," profitLotS=",profitLotSELL," lossLotB=",lossLotBUY, // " Fr=",AccountFreeMargin()," Eq=",AccountInfoDouble(ACCOUNT_EQUITY));//," MinEq=",MinEq); // //continue; // //return(B4BRes); // } // //Если пары есть - закрываем, пар нет - снимаем флаг продолжения // if (true // //&&(false // // ||((profitBUY>0.01)&&(lossSELL<-0.01)&&(profitBUY>=-lim*lossSELL)) // // ||((profitSELL>0.01)&&(lossBUY<-0.01)&&(profitSELL>=-lim*lossBUY))) // //&&(closeProfit>0.01*closeLot*ltSprad/Point) // &&(pairFound) // ) // { // if (Prn1) Print("**************** Close B4B *********************"); // if (Prn1) Print(" profitBUY=",profitBUY," lossSELL=",lossSELL," profitSELL=",profitSELL," lossBUY=",lossBUY); // //if (closeProfit>4*closeLot*ltSprad/Point) // {//Если пары есть - закрываем // //Закрываем прибыльный BUY на убыточный SELL // if ((profitBUY>0.0001)&&(lossSELL<-0.0001)&&(profitBUY>=-lim*lossSELL))//прибыльный BUY - убыточный SELL //// if ((profitBUY>0.0001)&&(lossSELL<-0.0001)&&(profitBUY>=-lim*lossSELL)&&(tsmiTrendAskNorm[9]>0))//прибыльный BUY - убыточный SELL - и убыток растет //// if ((profitBUY>0.0001)&&(lossSELL<-0.0001)&&(profitBUY>=-lim*lossSELL)&&(tsmiTrendBidNorm[9]<0))//прибыльный BUY - убыточный SELL - и прибыль падает // { // Ord_inf=PositionSelect(nMProfitBUY,SELECT_BY_TICKET,MODE_TRADES); // Ord_inf=OrderCloseBy(PositionGetInteger(POSITION_TICKET),nMLossSELL,clrForestGreen); // if (Ord_inf) // { // B4BCloseOneN++; // B4BRes=true; // //if (Prn1) //if (PrnB4BM) Print("************* B4BCloseM 7>>"," PAIR FOUND AND CLOSED!!!"," B4BRes=",B4BRes, // " profitB=",profitBUY," lossS=",lossSELL," Ord_inf=",Ord_inf," B4BCloMN=",B4BCloseMN, // " Fr=",AccountFreeMargin()," Eq=",AccountInfoDouble(ACCOUNT_EQUITY));//," MinEq=",MinEq); // } // BePair=false;//расчет окончен, всё что смогли - закрыли - 1 пару. // }//if // //Если все быстрые тренды по убытку BUY убыточные - убыток увеличивается // //if ((TrendMB[0])&&(TrendMB[0]))//&&(!TrendMB[1])&&(TrendMB[2])&&(TrendMB[3]))//&&(!TrendCB[2])) // //Закрываем прибыльный SELL на убыточный BUY // if ((profitSELL>0.0001)&&(lossBUY<-0.0001)&&(profitSELL>=-lim*lossBUY))//прибыльный SELL - убыточный BUY //// if ((profitSELL>0.0001)&&(lossBUY<-0.0001)&&(profitSELL>=-lim*lossBUY)&&(tsmiTrendBidNorm[9]<0))//прибыльный SELL - убыточный BUY - и убыток растет //// if ((profitSELL>0.0001)&&(lossBUY<-0.0001)&&(profitSELL>=-lim*lossBUY)&&(tsmiTrendAskNorm[9]>0))//прибыльный SELL - убыточный BUY - и прибыль падает // { // Ord_inf=PositionSelect(nMProfitSELL,SELECT_BY_TICKET,MODE_TRADES); // Ord_inf=OrderCloseBy(PositionGetInteger(POSITION_TICKET),nMLossBUY,clrForestGreen); // if (Ord_inf) // { // B4BCloseOneN++; // B4BRes=true; // //if (Prn1) //if (PrnB4BM) Print("************* B4BCloseM 8>>"," PAIR FOUND AND CLOSED!!!"," B4BRes=",B4BRes, // " profitS=",profitSELL," lossB=",lossBUY," Ord_inf=",Ord_inf," B4BCloMN=",B4BCloseMN, // " Fr=",AccountFreeMargin()," Eq=",AccountInfoDouble(ACCOUNT_EQUITY));//," MinEq=",MinEq); // } // //BePair=false;//расчет окончен, всё что смогли - закрыли - 1 пару. // }//if // //тогда Bepair=true и будет следующий расчет // } // }else{ // //Print("**************** BePair=false *********************"); // //Если нет пар - снимаем флаг продолжения // BePair=false;//расчет окончен, всё что смогли - закрыли // } // }//end while - совсем While //if ((PrnB4BM)&&(B4BRes!=true)) Print("************* B4BCloseM 9>>"," PAIR NOT FOUND!!!"," B4BRes=",B4BRes, // " profitS=",profitSELL," lossB=",lossBUY," profitB=",profitBUY," lossS=",lossSELL," Ord_inf=",Ord_inf," B4BCloMN=",B4BCloseMN, // " Fr=",AccountFreeMargin()," Eq=",AccountInfoDouble(ACCOUNT_EQUITY));//," MinEq=",MinEq); // return(B4BRes); //}//B4BCloseMA() // //====================================================================================================== // fOrderSend() // // Выход: // //====================================================================================================== //fOrderSend() - переписать добавить цикл с увеличением слипа int fOrderSend( OP_TYPE OrdType, double Ord_Vol, int OrdSlippage, int OrdStopLoss, int OrdTakeProfit, string OrdComment, long OrdMagic, int OrdExpir, color Ord_Color, ulong &rDeal){ //Print("fOrderSend>>"); //{if(!IsTradeTime2()){return(0);}}, {if(nOrdersOpen>=MaxOpenOrders){return(-5);}}//Превышено число ордеров int OrdInfo=-1;//Ошибка открытия ордера //int err=0; int j=0; int nRetry=5; //----- rDeal=0; {switch (OrdType) { case OP_BUY: {for (j=0;j<=nRetry-1;j++) { //RefreshRates(); {if(LongEnable) { OrdInfo=(int)PositionOrderSend(TheSymbol,(ENUM_ORDER_TYPE)OP_BUY,Ord_Vol,gAsk,OrdSlippage,PriceAddPoints(gBid,-OrdStopLoss),PriceAddPoints(gAsk,+OrdTakeProfit),OrdComment,OrdMagic,OrdExpir,rDeal); //Print("rDeal>>",rDeal); }}//if(LongEnable) //err=GetLastError(); //{if (err == 0 /* NO_ERROR */ ){break;}}//for //{if (!(( err == 4 /* SERVER_BUSY */ // || err == 137 /* BROKER_BUSY */ // || err == 134 /* NO MONEY */ // || err == 146 /* TRADE_CONTEXT_BUSY */ // || err == 136 /* OFF_QUOTES */ ))){break;}}//for {if ( // (OrdInfo == 10008) /* TRADE_RETCODE_PLACED Ордер размещен */ //|| (OrdInfo == 10009) /* TRADE_RETCODE_DONE Заявка выполнена */ || (OrdInfo == 10010) /* TRADE_RETCODE_DONE_PARTIAL Заявка выполнена частично */ ) { break;//for }else{ OrdInfo=-OrdInfo; }} Sleep(10); }}//for (j=0;j0) {for(int i=PositionsTotal()-1;i>=0;i--) { Pos_Tick=PositionGetTicket(i); {if(Pos_Tick<=0){continue;}}//Неудачно - следующий {if(!PositionSelectByTicket(Pos_Tick)){continue;}}//Выбираем позицию по тикету? Неудачно - следующий {if(PositionGetString(POSITION_SYMBOL)!=iSymbol){continue;}}//Отбор по инструменту {if(PositionGetInteger(POSITION_MAGIC)!=iMagic){continue;}}//Отбор по магику //fCloseBuySell() переписать - добавить цикл с увеличением слипа {if((PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)&&(bCloseBuy)) { Ord_Int=-1; //RefreshRates(); {if(true)//(!IsTradeContextBusy()) { Ord_Int=mPositionClose2(iSymbol,Pos_Tick,SlipFixOrd,RepFixOrd,"fCloseBuySell(OP_BUY)"); {if((Ord_Int!=ERR_SUCCESS)&&(Ord_Int!=ERR_NO_MQLERROR)) // {if((Ord_inf!=ERR_SUCCESS)&&(Ord_inf!=ERR_NO_MQLERROR)) //{if((Ord_inf!=ERR_SUCCESS)) //{if(!OrderClose(PositionGetInteger(POSITION_TICKET),PositionGetDouble(POSITION_VOLUME),fNormalizeDouble(gBid),5,CLR_NONE)) { Print("Error Closing BUY Trade "+string(PositionGetInteger(POSITION_TICKET))); iResult=-1; }}//if(!OrderClose(PositionGetInteger(POSITION_TICKET),PositionGetDouble(POSITION_VOLUME),fNormalizeDouble(gBid),5,CLR_NONE)) }else{ //if(tStopTimeBuy == iTime(NULL, 0, 0)) return (-2); //tStopTimeBuy=iTime(NULL,0,0); Print("Need Closing BUY Trade "+string(PositionGetInteger(POSITION_TICKET))+". Trade Context Busy"); return(-2); }}//if(!IsTradeContextBusy()) }}//if(((OP_TYPE)PositionGetInteger(POSITION_TYPE)==OP_BUY)&&(bCloseBuy)) {if((PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)&&(bCloseSell)) { //RefreshRates(); {if(true)//(!IsTradeContextBusy()) { Ord_Int=mPositionClose2(iSymbol,Pos_Tick,SlipFixOrd,RepFixOrd,"fCloseBuySell(OP_SELL)"); {if((Ord_Int==ERR_SUCCESS)||(Ord_Int==ERR_NO_MQLERROR)){continue;}} //{if(OrderClose(PositionGetInteger(POSITION_TICKET),PositionGetDouble(POSITION_VOLUME),fNormalizeDouble(gAsk),5,CLR_NONE)){continue;}} Print("Error Closing SELL Trade : "+string(PositionGetInteger(POSITION_TICKET))); iResult=-1; continue; }}//if(!IsTradeContextBusy()) //if(tStopTimeSell == iTime(NULL, 0, 0)) return (-2); ////tStopTimeSell=iTime(NULL,0,0); Print("Need to close SELL trade : "+string(PositionGetInteger(POSITION_TICKET))+". Trade Context Busy"); return(-2); }}//if(((OP_TYPE)PositionGetInteger(POSITION_TYPE)==OP_SELL)&&(bCloseSell)) }}//for(int n=PositionsTotal()-1;n>=0;n--) iVirtualSL=0; return(iResult); }//fCloseBuySell // //====================================================================================================== // NormalizeVSL() //====================================================================================================== void NormalizeVSL( string iSymbol, OP_TYPE iType, int iMagic, double &iVirtualSL, double iPosPrice) { //----- double Comis=(PositionGetDouble(POSITION_VOLUME)*CalcAddCommPrice(iSymbol,AccSrv)+CalcGridSwap(iSymbol,iMagic)) /SymbolTradeTickValue; {if(iType==OP_ALL) { iVirtualSL=0.0; }}//if(iType==OP_ALL) {if(iType==OP_BUY) { {if(iVirtualSL>0.0) { {if(iVirtualSLiPosPrice+MathMax(Comis,SymbolInfoInteger(iSymbol,SYMBOL_TRADE_STOPS_LEVEL))*_Point) { iVirtualSL=iPosPrice+MathMax(Comis,SymbolInfoInteger(iSymbol,SYMBOL_TRADE_STOPS_LEVEL))*_Point; }else{ {if(gBid<=iPosPrice+_Point) { //iVirtualSL=iPosPrice+_Point; iVirtualSL=0.0; }}//if(gBid<=iPosPrice+_Point) }}//if(gBid>iPosPrice+_Point) }}//if(iVirtualSL0.0) }}//if(iType==OP_BUY) {if(iType==OP_SELL) { {if(iVirtualSL>0.0) { {if(iVirtualSL>iPosPrice) { {if(gAsk=iPosPrice-_Point) { //iVirtualSL=iPosPrice+_Point; iVirtualSL=0.0; }}//if(gAsk>=iPosPrice-_Point) }}//if(gAskiPosPrice) }}//if(iVirtualSL>0.0) }}//if(iType==OP_SELL) }//NormalizeVSL() // //====================================================================================================== // NormalizeSL() //====================================================================================================== void NormalizeSL( string iSymbol, OP_TYPE iType, int iMagic, double iPosPrice){ double NewStopLoss=0; //Комиссия + своп в пунктах double Comis=(PositionGetDouble(POSITION_VOLUME)*CalcAddCommPrice(iSymbol,AccSrv)+CalcGridSwap(iSymbol,iMagic)) /SymbolTradeTickValue; //----- {if(PositionsTotal()>0) { {for (int i=PositionsTotal()-1;i>=0;i--) { ulong Pos_Tick=PositionGetTicket(i); {if(Pos_Tick<=0){continue;}}//Неудачно - следующий {if(!PositionSelectByTicket(Pos_Tick)){continue;}}//Выбираем позицию по тикету? Неудачно - следующий {if(PositionGetString(POSITION_SYMBOL)!=iSymbol){continue;}}//Отбор по инструменту {if(PositionGetInteger(POSITION_MAGIC)!=iMagic){continue;}}//Отбор по магику double OrdStopLoss=PositionGetDouble(POSITION_SL); {if(OrdStopLoss==0){continue;}} {if((PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)&&((iType==OP_ALL)||(iType==OP_BUY))) { {if(OrdStopLossiPosPrice+MathMax(Comis,SymbolInfoInteger(iSymbol,SYMBOL_TRADE_STOPS_LEVEL))*_Point) { NewStopLoss=NormalizeDouble(iPosPrice+MathMax(Comis,SymbolInfoInteger(iSymbol,SYMBOL_TRADE_STOPS_LEVEL))*_Point,_Digits); }else{ NewStopLoss=0; }}//if(gBid>=PosPrice+SymbolInfoInteger(TheSymbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point) Ord_Inf=PositionModifySL(Pos_Tick,NewStopLoss,0.0); }}//if(OrdStopLoss<=PosPrice) }}//if ((OP_TYPE)PositionGetInteger(POSITION_TYPE)==OP_BUY) {if((PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)&&((iType==OP_ALL)||(iType==OP_SELL))) { {if(OrdStopLoss>iPosPrice) { {if(gAsk=PosPrice+SymbolInfoInteger(TheSymbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point) Ord_Inf=PositionModifySL(Pos_Tick,NewStopLoss,0.0); }}//if(NewStopLoss>=PosPrice) }}//if ((OP_TYPE)PositionGetInteger(POSITION_TYPE)==OP_SELL) Sleep(10); }}//for (int n=PositionsTotal()-1;n>=0;n--) }}//if }//NormalizeSL() // //====================================================================================================== // ReadEventsToDay() - читаем из файла массив событий текущего дня, устанавливаем // iLastReadDayBegin на начало текущего дня. // Вход: // iSymbol - фининструмент // VolatLimit - минимальный уровень события // iInvesting - использовать индексы от Investing.com // iOffsetTime - смещение времени (для телетрейд -3600 (UTC+2), остальные скачиваются UTC+3) // Выход: // iLastReadDayBegin - время начала последнего прочитанного дня (устанавливается на начало дня прочтения новостей) // iEvents - массив событий дня // iNEvents - количество событий дня //====================================================================================================== bool ReadEventsToDay( string iSymbol, string iFileName, int VolatLimit, bool iInvesting, datetime iOffsetTime, datetime &iLastReadDayBegin, News &iEvents[], int &iNEvents, bool iFileCommon) { string StringBuff, iCurrencyN,iEventN,iCountryN, Symbol_1=StringSubstr(iSymbol,0,3), Symbol_2=StringSubstr(iSymbol,3,3); datetime iTimeN; int iVolatilityN; bool Done=true; //----- datetime ThisDayBegin=DateTimeDayBegin(Time_Current);//не UTC datetime NextDayBegin=ThisDayBegin+24*60*60;//не UTC //----- ResetLastError(); int InFileHandle=INVALID_HANDLE; {if(iFileCommon) { InFileHandle=FileOpen(iFileName,FILE_READ|FILE_TXT|FILE_SHARE_READ|FILE_COMMON,';'); }else{ InFileHandle=FileOpen(iFileName,FILE_READ|FILE_TXT|FILE_SHARE_READ,';'); }}//if(iFileCommon) //Print("ReadEventsToDay >>InFileHandle=",InFileHandle); {if((InFileHandle==INVALID_HANDLE)||(FileSize(InFileHandle)==0)) { Print("ReadEventsToDay Error Open File >> "+iFileName); iLastReadDayBegin=0; Done=false; return(false); }else{ //Очистка списка событий {for(int j=0;j<100;j++) { Events[j].TimeN=0; Events[j].CurrencyN=""; Events[j].VolatilityN=0; Events[j].EventN=""; Events[j].CountryN=""; Events[j].MaxVolBeN=false; Events[j].CompositeStringN=""; }}//for(int j=0;j<100;j++) //Цикл чтения строк из файла int i=0; {while(!FileIsEnding(InFileHandle)) { StringBuff=FileReadString(InFileHandle); //Print("StringBuff=",StringBuff); //StringParse(StringBuff,iEvents[i].TimeN,iEvents[i].CurrencyN,iEvents[i].VolatilityN); StringParse(StringBuff,iTimeN,iCurrencyN,iVolatilityN,iEventN,iCountryN); //Print("ThisDayBeginU=",ThisDayBegin," NextDayBegin=",NextDayBegin," iTimeN=",iTimeN," iCurrencyN=",iCurrencyN," iVolatilityN=",iVolatilityN); iTimeN=iTimeN+iOffsetTime; {if( (true) &&((iInvesting)||(StringFind(iEventN,"Investing.com")<0))//Выкусываем индексы от Investing.com к чертям собачьим &&(iTimeN>=ThisDayBegin)&&(iTimeN=VolatLimit) ) || ((iCurrencyN=="USD")&&(iVolatilityN>=2))//... или это доллар с максимальной волатильностью || ((iCurrencyN=="EUR")&&(iVolatilityN>=2))//... или это евро с максимальной волатильностью || ((iCurrencyN=="JPY")&&(iVolatilityN>=2))//... или это йена с максимальной волатильностью || ((iCurrencyN=="GBP")&&(iVolatilityN>=3))//... или это фунт с максимальной волатильностью || ((iCurrencyN=="CHF")&&(iVolatilityN>=3))//... или это франк с максимальной волатильностью || ((iCurrencyN=="AUD")&&(iVolatilityN>=3))//... или это оззи с максимальной волатильностью || ((iCurrencyN=="NSD")&&(iVolatilityN>=3))//... или это киви с максимальной волатильностью || ((iCurrencyN=="CAD")&&(iVolatilityN>=3))//... или это кабель с максимальной волатильностью ) ) { //Print("************ iTimeN=",iTimeN,"ThisDayBegin=",ThisDayBegin," NextDayBegin=",NextDayBegin," iCurrencyN=",iCurrencyN," iVolatilityN=",iVolatilityN); //Print("StringBuff=",StringBuff); iEvents[i].TimeN=iTimeN; iEvents[i].CurrencyN=iCurrencyN; iEvents[i].VolatilityN=iVolatilityN; iEvents[i].EventN=iEventN; iEvents[i].CountryN=iCountryN; i++; }}//if((iTimeN>=ThisDayBegin)&&(iTimeN=1){Print("ReadEventsToDay Close File >> "+iFileName+" read="+IntegerToString(i)," InFileHandle=",InFileHandle);}} //ExpertRemove(); {if(i>=1)//Найдены записи текущего дня { iLastReadDayBegin=ThisDayBegin; iNEvents=i; Done=true; }else{//Записи текущего дня не найдены iLastReadDayBegin=NextDayBegin; iNEvents=0; Done=false; return(false); }}//if(i>=1) }}//if ((InFileHandle!=INVALID_HANDLE)&&(FileSize(InFileHandle)!=0)) //Заполнение признака максимальной волатильности при очередном времени и сводной строки {if(Done) { datetime TimeOldN=0; int MaxVolN=0; string CompositeString=""; int MaxTimeRecord=-1;//Номер записи с максимальной волатильностью внутри времени, и флаг обнаружения максимальной записи (>=0) {for(int j=0;jTimeOldN)//Наступило новое время { //----- Обработка завершения предыдущего времени (Не забыть проделать то же на последнем активном элементе iNEvents-1 массива новостей) {if(MaxTimeRecord>=0)//Если максимальная волатильность была обнаружена { Events[MaxTimeRecord].MaxVolBeN=true;//Помечаем первый элемент с максимальной волатильностью в закрытом времени Events[MaxTimeRecord].CompositeStringN=CompositeString;//Заносим в элемент накопленную строку CompositeString=""; }}//if(MaxTimeRecord>=0) //----- Начальные процедуры нового времени CompositeString=Events[j].EventN;//начальное значение накопительной строки MaxVolN=Events[j].VolatilityN;//новое значение для максимума волатильности MaxTimeRecord=j;//Первую запись считаем максимальной по волатильности //Запомним время для сравнения TimeOldN=Events[j].TimeN; //----- Обработка завершения времени на последнем активном элементе iNEvents-1 массива новостей {if(j==(iNEvents-1))//Последний элемент { Events[MaxTimeRecord].MaxVolBeN=true;//Помечаем первый элемент с максимальной волатильностью в закрытом времени Events[MaxTimeRecord].CompositeStringN=CompositeString;//Заносим в элемент накопленную строку CompositeString=""; }}//if(j==iNEvents) }else{//Время не изменилось //----- Обработка по значению волатильности {if(Events[j].VolatilityN>MaxVolN)//Новый максимум { CompositeString=Events[j].EventN;//начальное значение накопительной строки MaxVolN=Events[j].VolatilityN;//Значение максимума для волатильности MaxTimeRecord=j;//запомним позицию первого элемента с максимумом }else{//Не новый максимум по волатильности {if(Events[j].VolatilityN==MaxVolN)//Событие с волатильностью по максимуму { CompositeString=CompositeString+"* "+Events[j].EventN;//Наращивание накопительной строки }}//if(Events[j].VolatilityN=MaxVolN) }}//if(Events[j].VolatilityN>MaxVolN) //----- Обработка завершения времени на последнем активном элементе iNEvents-1 массива новостей {if(j==(iNEvents-1))//Последний элемент { Events[MaxTimeRecord].MaxVolBeN=true;//Помечаем первый элемент с максимальной волатильностью в закрытом времени Events[MaxTimeRecord].CompositeStringN=CompositeString;//Заносим в элемент накопленную строку }}//if(j==iNEvents) }}//{if(Events[j].TimeN>TimeOldN) }}//for(int j=0;j<100;j++) //{for(int j=0;j>InFileHandle=",InFileHandle); {if((InFileHandle==INVALID_HANDLE)||(FileSize(InFileHandle)==0)) { Print("ReadEventsWeeks Error Open File >> "+iFileName); iLastReadWeekBegin=0; Done=false; return(false); }else{ //Очистка списка событий {for(int j=0;j<100;j++) { Events[j].TimeN=0; Events[j].CurrencyN=""; Events[j].VolatilityN=0; Events[j].EventN=""; Events[j].CountryN=""; Events[j].MaxVolBeN=false; Events[j].CompositeStringN=""; }}//for(int j=0;j<100;j++) //Цикл чтения строк из файла int i=0; {while((!FileIsEnding(InFileHandle))&&(i=ThisWeekBegin)&&(iTimeN=iVolatLimit) ) || //Новости по доллару, евро и йене как очень сильно влияющие используем всегда от важности 2 ((iCurrencyN=="USD")&&(iVolatilityN>=MathMax(2,exVolatLimit)))//... или это доллар с максимальной волатильностью || ((iCurrencyN=="EUR")&&(iVolatilityN>=MathMax(2,exVolatLimit)))//... или это евро с максимальной волатильностью || ((iCurrencyN=="JPY")&&(iVolatilityN>=MathMax(2,exVolatLimit)))//... или это йена с максимальной волатильностью || //Новости по фунту, франку, оззи, киви, каблю как сильно влияющие используем всегда от важности 3 ((iCurrencyN=="GBP")&&(iVolatilityN>=3))//... или это фунт с максимальной волатильностью || ((iCurrencyN=="CHF")&&(iVolatilityN>=3))//... или это франк с максимальной волатильностью || ((iCurrencyN=="AUD")&&(iVolatilityN>=3))//... или это оззи с максимальной волатильностью || ((iCurrencyN=="NSD")&&(iVolatilityN>=3))//... или это киви с максимальной волатильностью || ((iCurrencyN=="CAD")&&(iVolatilityN>=3))//... или это кабель с максимальной волатильностью ) ) { //Print("*** iTimeN=",iTimeN,"ThisWeekBegin=",ThisWeekBegin," NextWeekBegin=",NextWeekBegin, // " iCurrencyN=",iCurrencyN," iVolatilityN=",iVolatilityN," iEventN=",iEventN); //Print("StringBuff=",StringBuff); //Заносим разобранную строку в массив событий iEvents[i].TimeN=iTimeN; iEvents[i].CurrencyN=iCurrencyN; iEvents[i].VolatilityN=iVolatilityN; iEvents[i].EventN=iEventN; iEvents[i].CountryN=iCountryN; i++; }}//if((iTimeN>=ThisDayBegin)&&(iTimeN=EventsListSize){Print("ReadEventsWeeks ERROR >> Размер массива событий ",EventsListSize," недостаточен.");}} //ExpertRemove(); {if(i>=1)//Найдены записи текущей недели { iLastReadWeekBegin=ThisWeekBegin; iNEvents=i;//Количество найденных событий Print("ReadEventsWeeks Close File >> ",iFileName," FileHandle=",InFileHandle," Записи текущей недели =",iNEvents); Done=true; }else{//Записи текущей недели не найдены Print("ReadEventsWeeks ERROR >> Записи текущей недели не найдены."); iLastReadWeekBegin=NextWeekBegin; iNEvents=0;//Обнулим количество найденных событий Done=false; return(false); }}//if(i>=1) }}//if((InFileHandle!=INVALID_HANDLE)&&(FileSize(InFileHandle)!=0)) ZeroMemory(InFileHandle); //Заполнение признака максимальной волатильности при очередном времени и сводной строки {if(Done) { datetime TimeOldN=0; int MaxVolN=0; string CompositeString="";//Сводная строка int MaxTimeRecord=-1;//Номер записи с максимальной волатильностью внутри времени, и флаг обнаружения максимальной записи (>=0) {for(int j=0;jTimeOldN)//Наступило новое время { //----- Обработка завершения предыдущего времени (Не забыть проделать то же на последнем активном элементе iNEvents-1 массива новостей) {if(MaxTimeRecord>=0)//Если максимальная волатильность была обнаружена { Events[MaxTimeRecord].MaxVolBeN=true;//Помечаем первый элемент с максимальной волатильностью в закрытом времени Events[MaxTimeRecord].CompositeStringN=CompositeString;//Заносим в элемент накопленную сводную строку CompositeString="";//Очищаем сводную строку }}//if(MaxTimeRecord>=0) //----- Начальные процедуры нового времени CompositeString=Events[j].EventN;//начальное значение накопительной строки MaxVolN=Events[j].VolatilityN;//новое значение для максимума волатильности MaxTimeRecord=j;//Первую запись считаем максимальной по волатильности //Запомним время для сравнения TimeOldN=Events[j].TimeN; //----- Обработка завершения времени на последнем активном элементе iNEvents-1 массива новостей {if(j==(iNEvents-1))//Последний элемент { Events[MaxTimeRecord].MaxVolBeN=true;//Помечаем первый элемент с максимальной волатильностью в закрытом времени Events[MaxTimeRecord].CompositeStringN=CompositeString;//Заносим в элемент накопленную сводную строку CompositeString="";//Очищаем сводную строку }}//if(j==iNEvents) }else{//Время не изменилось //----- Обработка по значению волатильности {if(Events[j].VolatilityN>MaxVolN)//Новый максимум { CompositeString=Events[j].EventN;//начальное значение накопительной строки MaxVolN=Events[j].VolatilityN;//Значение максимума для волатильности MaxTimeRecord=j;//запомним позицию первого элемента с максимумом }else{//Не новый максимум по волатильности {if(Events[j].VolatilityN==MaxVolN)//Событие с волатильностью по максимуму { CompositeString=CompositeString+"* "+Events[j].EventN;//Наращивание накопительной строки }}//if(Events[j].VolatilityN=MaxVolN) }}//if(Events[j].VolatilityN>MaxVolN) //----- Обработка завершения времени на последнем активном элементе iNEvents-1 массива новостей {if(j==(iNEvents-1))//Последний элемент { Events[MaxTimeRecord].MaxVolBeN=true;//Помечаем первый элемент с максимальной волатильностью в закрытом времени Events[MaxTimeRecord].CompositeStringN=CompositeString;//Заносим в элемент накопленную строку }}//if(j==iNEvents) }}//{if(Events[j].TimeN>TimeOldN) }}//for(int j=0;j> CLOSE DISABLE ERROR IN MORDERCLOSE> "," OrderSymbol()=",PositionGetString(POSITION_SYMBOL)," TheSymbol=",iSymbol);}} return(1995); }else{ {if(PrnClose){Print("#",OrTic,">> CLOSE ENABLE NO ERROR IN MORDERCLOSE> "," OrderSymbol()=",PositionGetString(POSITION_SYMBOL)," TheSymbol=",iSymbol);}} }}//if(!CloseEnable) {if(PositionGetString(POSITION_SYMBOL)!=iSymbol) { if(PrnClose) Print("#",OrTic,">> SYMBOL ERROR IN MORDERCLOSE> "," PositionGetString(POSITION_SYMBOL)=",PositionGetString(POSITION_SYMBOL)," iSymbol=",iSymbol); return(1999); }else{ if(PrnClose) Print("#",OrTic,">> SYMBOL NO ERROR IN MORDERCLOSE> "," PositionGetString(POSITION_SYMBOL)=",PositionGetString(POSITION_SYMBOL)," iSymbol=",iSymbol); }}//if(PositionGetString(POSITION_SYMBOL)!=iSymbol) //========== Неприкасаемые ордера не закрываем!!! //if (((OP_TYPE)PositionGetInteger(POSITION_TYPE)==OP_SELL)&&(MathAbs(PositionGetDouble(POSITION_SL)-_Point)<0.5*_Point)) {return(mErr);} //if (((OP_TYPE)PositionGetInteger(POSITION_TYPE)==OP_BUY)&&(MathAbs(PositionGetDouble(POSITION_SL)-_Point)<0.5*_Point)) {return(mErr);} //================================================= ////if(PrnClose) Print("#",OrTic," 1 >> CLOSE from:",comm, //// " Type=",(((OP_TYPE)PositionGetInteger(POSITION_TYPE)==0)?("BUY"):("SELL")), //// " Lots=",PositionGetDouble(POSITION_VOLUME), //// " Vol=",OrVol, //// " Prc=",OrPrc, //// " Prof=",DoubleToString(CalcOrdersProfit(AllType,PositionGetInteger(POSITION_TICKET),CheckMagicOn),2), //// " Spr=",DoubleToString(ltSprad,_Digits)); ////if(PrnClose) Print("#",OrTic," 2 >> OrdTotal=",PositionsTotal(), //// " OrdOpTim=",OrderOpenTime(),"/",TimeToString(OrderOpenTime()), //// //" OrdExpir=",OrderExpiration()-1600000000,"/",TimeToString(OrderExpiration()), //// " TimCurr=",IntegerToString(TimeCurrent()),"/",TimeCurrent()); {while ( (mErr!=ERR_NO_MQLERROR)&&(mErr!=ERR_SUCCESS) &&(mRet>0) ) { //{if(IsTradeContextBusy()){break;}}//Торговый поток занят - ожидание if(PrnClose) Print("mPositionClose2 in while, from [",comm,"] Close TRY >>"," mErr=",mErr," mRet=",mRet," OrTic=",OrTic," OrSli=",OrSli); ResetLastError(); {if (!PositionSelectByTicket(OrTic)) { mErr=GetLastError(); //Print("mPositionClose2 SELECT ERROR IN WHILE> ","ERR:"+IntegerToString(mErr)); break; }else{ mErr=GetLastError(); //Print("mPositionClose2 SELECT NO ERROR IN WHILE> ","ERR:"+IntegerToString(mErr)); }}//if (!Ord_inf) ResetLastError(); ////{if ((!MQLInfoInteger(MQL_TESTER))&&((-CalcOrdersProfit(AllType,PositionGetInteger(POSITION_TICKET),CheckMagicOn))>=CloseLossQLimit))//Если закрываем большой убыток ////{ //// {if (MessageBox("Close "+DoubleToString(CalcOrdersProfit(AllType,PositionGetInteger(POSITION_TICKET),CheckMagicOn),2)+"$ ?","*** BIG LOSS ORDER CLOSE ***",MB_YESNO+MB_ICONSTOP)==IDYES) //// { //// mRes=OrderClose(OrTic,NormalizeDouble(OrVol,f_N_Sign(SymbolInfoInteger(TheSymbol,SUMBOL_VOLUME_STEP))),NormalizeDouble(OrPrc,_Digits),OrSli,OrCol);//_Digits //// }else{ //// mRes=false; //// }}//if (MessageBox("Close ////}else{//тестирование или небольшой убыток mRes=PositionCloseOne(OrTic,OrSli);// ////}}//if ((!MQLInfoInteger(MQL_TESTER))&&(CalcOrdersProfit mErr=GetLastError(); {if (mRes) { //mErr=ERR_NO_MQLERROR; if(PrnClose) Print("mPositionClose2 CLOSE NO ERROR IN WHILE> ","ERR:"+IntegerToString(mErr)); break; }else{ if(PrnClose) Print("mPositionClose2 CLOSE ERROR IN WHILE> ","ERR:"+IntegerToString(mErr)); }}//if (mRes) OrSli++; mRet--; }}//while ((mErr!=ERR_NO_MQLERROR)&&(mRet>=0))) if (PrnClose) Print("mPositionClose2 CLOSE END> ",((mRes)?("NO_ERROR:"+IntegerToString(mErr)):("ERROR:"+IntegerToString(mErr)))); return(mErr); }//mPositionClose2() // //====================================================================================================== // CalendarRequest() - Download CBOE page source code in a text variable // Вх: // iReqTimeOut - таймаут запроса к сайту // iInFailName - файл для сохранения результата запроса // Вых: - bool результат операции // iOutString - строка с результатом запроса //====================================================================================================== int CalendarRequest( int iReqTimeOut, string iInFailName, string &iOutString){ string cookie=NULL,headers; char post[], result[]; int ErrCode, res; int RetResult=0; //--- to work with the server, you must add the URL "https://www.google.com/finance" //--- the list of allowed URL (Main menu-> Tools-> Settings tab "Advisors"): ////string google_url= //// "http://ec.forexprostools.com/?"columns=exc_currency,exc_importance&importance=1,2,3&calType=week&timeZone=15&lang=1"; iOutString=""; string google_url= "https://sslecal2.forexprostools.com/?"+//"http://ec.forexprostools.com/?"+// "columns=exc_flags,exc_currency,exc_importance,exc_actual,exc_forecast,exc_previous"+ //"&category=_employment,_economicActivity,_inflation,_credit,_centralBanks,_confidenceIndex,_balance,_Bonds"+ "&importance=1,2,3"+ //"&features=timezone"+ //"&features=datepicker,timezone"+ "&countries=4,5,6,9,10,11,12,14,17,22,23,24,25,26,27,29,32,33,34,35,36,37,38,39,41,42,43,45,46,48,54,56,72,110"+ "&calType=week"+//week //"&timeZone=7"+//17 - GMT+3 Иерусалим "&lang=1"; /* !!!ВНИМАНИЕ!!! Скачивается всегда в UTC+0 */ //--- ResetLastError(); //--- download html-pages int timeout=iReqTimeOut; //--- timeout less than 1,000 (1 sec.) is insufficient at a low speed of the Internet Print("WebRequest>>",google_url); res=WebRequest("GET",google_url,cookie,NULL,timeout,post,0,result,headers);//Страница идет в result //--- error checking {if(res==-1)//Ошибка запроса { ErrCode=GetLastError(); Print("WebRequest error [",google_url,"] err.code =",ErrCode); {if(ErrCode==4060)//ERR_FUNCTION_NOT_CONFIRMED Функция не разрешена { //"Необходимо добавить адрес '"+google_url+"' в список разрешенных URL во вкладке 'Советники'","Ошибка", MessageBox("You must add the address ' "+google_url+"' in the list of allowed URL tab 'Advisors' "," Error ",MB_ICONINFORMATION); }}//if(ErrCode==4060) RetResult=10000+ErrCode;//Ошибка запроса к сайту }else{//Запрос выполнен //--- successful download PrintFormat("File successfully downloaded, the file size in bytes =%d.",ArraySize(result)); //--- save the data in the file ResetLastError(); int filehandle=FileOpen(iInFailName,FILE_WRITE|FILE_BIN|FILE_TXT|FILE_ANSI|FILE_COMMON|FILE_SHARE_WRITE); //--- проверка ошибки {if(filehandle==INVALID_HANDLE)//Ошибка { ErrCode=GetLastError(); Print("Error in FileOpen Write [",iInFailName,"] Error code =",ErrCode); RetResult=30000+ErrCode;//Ошибка записи в файл FileClose(filehandle); }else{//Нет ошибки //--- save the contents of the array result [] in file FileWriteArray(filehandle,result,0,ArraySize(result)); //--- close file FileClose(filehandle); //--- load the contents of the result file ResetLastError(); int filehandle2=FileOpen(iInFailName,FILE_READ|FILE_BIN|FILE_TXT|FILE_ANSI|FILE_COMMON|FILE_SHARE_READ); {if(filehandle2==INVALID_HANDLE)//Ошибка { ErrCode=GetLastError(); Print("Error in FileOpen Read [",iInFailName,"] Error code =",ErrCode); RetResult=20000+ErrCode;//Ошибка чтения из файла FileClose(filehandle2); }else{//Нет ошибки iOutString=FileReadString(filehandle2,ArraySize(result)); FileClose(filehandle2); }}//if(filehandle2!=INVALID_HANDLE) }}//if(filehandle!=INVALID_HANDLE) }}//if(res==-1) return(RetResult); }//CalendarRequest() // //////====================================================================================================== ////// StringConverter() - Script program start function //////====================================================================================================== ////bool StringConverter(int iMode,string iInpStr,string &iOutStr,datetime iOffSetTime){ ////int //// n; ////bool //// iResult=true; //// iOutStr=""; //// {if((StringFind(iInpStr,",",0)<0)&&(iMode<=3)) //// { //// iResult=false; //// return(iResult); //// }}//if(StringFind(iInpStr,",",0)<0) //////----- ////string iDateTim=""; ////string iDate=gDat; ////string iYear=gYear; ////string iMou=gMoun; ////string iDay=gDay; ////string iTim=gTim; ////string iEvent=""; ////string iCountry=""; ////string iCouN=""; ////string iCur=""; ////string iVolatility=""; ////string iForecast=""; ////string iImpact=""; ////string iImpN=""; ////string iActual=""; ////string iPrevious=""; ////int nCountry=0; ////int nnCountry=0; //////----- Календарь fxstreet //// {if(iMode==1) //// { //// //Стандартный формат //// //12/11/2015 15:00:00,Reuters/Michigan Consumer Sentiment Index,United States,1,91.800,91.300,92.000 //// //Ограничивающие кавычки в событии //// //12/15/2015 09:30:00,"PPI Core Output (YoY) n.s.a ",United Kingdom,2,,0.300,0.100 //// //Запятая в событии - не обработано //// //01/02/2015 11:30:00,"FX Reserves, USD",India,1,319.710,320.000, //// //01/09/2015 07:45:00,"Exports, EUR",France,1,37.171,36.900, //// //01/27/2015 14:00:00,"Trade Balance s/a, $",Mexico,1,-0.011,-1.060, //// //Нестандартное название страны //// //12/15/2015 08:30:00,Retail Sales (YoY),"Netherlands, The",1,,4.300, //// iMou=StringSubstr(iInpStr,0,2); //// iDay=StringSubstr(iInpStr,3,2); //// iYear=StringSubstr(iInpStr,6,4); //// iInpStr=StringSubstr(iInpStr,11); //// iTim=StringSubstr(iInpStr,0,8); //// iTim=StringSubstr(iTim,0,5);//Удаляем секунды //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,",",0)+1); //// //Нормализуем Ограничивающие кавычки и запятая в событии //// {if(StringFind(iInpStr,"\"",0)==0) //// {//С кавычками //// iEvent=StringSubstr(iInpStr,1,StringFind(iInpStr,"\""+",",1)); //// n=StringReplace(iEvent," "+"\"","");//Убираем "пробел+кавычки" //// n=StringReplace(iEvent,"\"","");//Убираем "кавычки" //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,"\""+",",0)+2); //// }else{//Без кавычек //// iEvent=StringSubstr(iInpStr,0,StringFind(iInpStr,",",0)); //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,",",0)+1); //// }}//if(StringFind(iInpStr,"\"",0)=0) //// //Нормализуем при необходимости Нестандартное название страны //// {if(StringFind(iInpStr,"\"",0)==0) //// { //// //Убираем первые кавычки //// iInpStr=StringSubstr(iInpStr,1); //// //Вырезаем от запятой до вторых кавычек //// n=StringReplace( //// iInpStr, //// StringSubstr(iInpStr,StringFind(iInpStr,",",0),StringFind(iInpStr,"\"",0)-StringFind(iInpStr,",",0)+1), //// ""); //// }}//if(StringFind(iInpStr,"\"",0)=0) //// iCountry=StringSubstr(iInpStr,0,StringFind(iInpStr,",",0)); //// iCouN=StringSubstr(iCountryS,StringFind(iCountryS,iCountry,3)-3,3); //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,",",0)+1); //// iVolatility=StringSubstr(iInpStr,0,StringFind(iInpStr,",",0)); //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,",",0)+1); //// iActual=((StringFind(iInpStr,",",0)>0)?(StringSubstr(iInpStr,0,StringFind(iInpStr,",",0))):("")); //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,",",0)+1); //// iPrevious=((StringFind(iInpStr,",",0)>0)?(StringSubstr(iInpStr,0,StringFind(iInpStr,",",0))):("")); //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,",",0)+1); //// iForecast=iInpStr; //// iOutStr=iYear+"."+iMou+"."+iDay+" "+iTim+";"+iEvent+";"+iCountry+";"+iCouN+";"+iVolatility+";"+iPrevious+";"+iForecast+";"+iActual+";"; //// return(true); //// }}//if(iMode==1) //////----- Календарь myfxbook //// {if(iMode==2) //// { //// //"2015, September 01, 11:30","(United Kingdom) Consumer Credit",Medium,Ј1.23B,Ј1.2B,Ј1.17B,GBP //// iYear=StringSubstr(iInpStr,1,4); //// iInpStr=StringSubstr(iInpStr,7); //// iMou=StringSubstr(iInpStr,0,StringFind(iInpStr," ",3)); //// iMou=StringSubstr(iMounthN,StringFind(iMounthN,iMou,2)-2,2); //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr," ",1)+1); //// iDay=StringSubstr(iInpStr,0,2); //// iInpStr=StringSubstr(iInpStr,4); //// iTim=StringSubstr(iInpStr,0,5); //// iInpStr=StringSubstr(iInpStr,9); //// iDateTim=TimeToString(StringToTime(iYear+"."+iMou+"."+iDay+" "+iTim),TIME_DATE|TIME_MINUTES); //// iCountry=StringSubstr(iInpStr,0,StringFind(iInpStr,")",0)); //// iCouN=StringSubstr(iCountryS,StringFind(iCountryS,iCountry,3)-3,3); //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,") ",0)+2); //// iEvent=StringSubstr(iInpStr,0,StringFind(iInpStr,"\",",0)); //// n=StringReplace(iEvent,";","."); //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,"\",",0)+2); //// iImpact=StringSubstr(iInpStr,0,StringFind(iInpStr,",",0)); //// iImpN=StringSubstr(iImpactLN,StringFind(iImpactLN,iImpact,1)-1,1); //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,",",0)+1); //// iPrevious=((StringFind(iInpStr,",",0)>0)?(StringSubstr(iInpStr,0,StringFind(iInpStr,",",0))):("")); //// StringNormal(iPrevious); //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,",",0)+1); //// iForecast=((StringFind(iInpStr,",",0)>0)?(StringSubstr(iInpStr,0,StringFind(iInpStr,",",0))):("")); //// StringNormal(iForecast); //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,",",0)+1); //// iActual=((StringFind(iInpStr,",",0)>0)?(StringSubstr(iInpStr,0,StringFind(iInpStr,",",0))):("")); //// StringNormal(iActual); //// iOutStr=iDateTim+";"+iEvent+";"+iCountry+";"+iCouN+";"+iImpN+";"+iPrevious+";"+iForecast+";"+iActual+";"; //// return(true); //// }}//if(iMode==2) //////----- Календарь allnews //// {if(iMode==3) //// { //// //"2007/02/06","07:00","EUR","M","German Factory Orders m/m","-0.2%","0.5%","0.8%","1.5%","03558" //// //"2007/01/30","06:18","EUR","L","Italian 10-y Bond Auction","4.29|1.3","","4.17|1.5","","43355" string iDay=StringSubstr(iInpStr,0,2); //// //Date, Time, Currency, News description, Impact, Actual, Forecast, Previous, Revised from, FF event ID //// //Print(iInpStr); //// iYear=StringSubstr(iInpStr,1,4); //// iMou=StringSubstr(iInpStr,6,2); //// iDay=StringSubstr(iInpStr,9,2); //// iInpStr=StringSubstr(iInpStr,14); //// iTim=StringSubstr(iInpStr,0,5); //// iInpStr=StringSubstr(iInpStr,8); //// iCouN=StringSubstr(iInpStr,0,3); //// iInpStr=StringSubstr(iInpStr,6); //// iImpact=StringSubstr(iInpStr,0,1); //// iImpN=StringSubstr(iImpactN,StringFind(iImpactN,iImpact,1)-1,1); //// iInpStr=StringSubstr(iInpStr,4); //// iEvent=StringSubstr(iInpStr,0,StringFind(iInpStr,"\""+",",0)); //// iCountry=StringSubstr(iEvent,0,StringFind(iEvent," ",0)); //// nCountry=StringFind(iCountryT,iCountry,0); //// nnCountry=nCountry+StringLen(iCountry); //// iCountry=((nCountry>=0) //// ?(StringSubstr(iCountryT,nnCountry,StringFind(iCountryT,"#",nnCountry)-nnCountry)) //// :(StringSubstr(iCountryS, //// StringFind(iCountryS,iCouN,0)+3, //// StringFind(iCountryS,"#",StringFind(iCountryS,iCouN,0)+3)-StringFind(iCountryS,iCouN,0)-3))); //// //iEvent=((nCountry>=0)?(StringSubstr(iEvent,StringFind(iEvent," ",0)+1,StringLen(iCountry)-StringFind(iEvent," ",0)-1)):(iEvent)); //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,",",0)+2); //// iActual=((StringFind(iInpStr,"\"",0)>0)?(StringSubstr(iInpStr,0,StringFind(iInpStr,"\"",0))):("")); //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,",",0)+2); //// iPrevious=((StringFind(iInpStr,"\"",0)>0)?(StringSubstr(iInpStr,0,StringFind(iInpStr,"\"",0))):("")); //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,",",0)+2); //// iForecast=((StringFind(iInpStr,"\"",0)>0)?(StringSubstr(iInpStr,0,StringFind(iInpStr,"\"",0))):("")); //// iOutStr=iYear+"."+iMou+"."+iDay+" "+iTim+";"+iEvent+";"+iCountry+";"+iCouN+";"+iImpN+";"+iPrevious+";"+iForecast+";"+iActual+";"; //// return(true); //// }}//if(iMode==3) //////----- Календарь investing html //// {if(iMode==4) //// { //// //Friday, March 25, 2016 //// //All DayHolidayAustralia - Good Friday //// //
//// //18:00EURFrance Jobseekers Total (Feb)3,591.0K3,555.3K3,552.6K //// //// //// //All Day HolidayUnited States - New Year's Day //// //All Day  HolidayUnited Kingdom - New Year's Day //// //02:00  CNY Manufacturing PMI (Dec)49.749.749.6  //// //01:00  COP Imports (YoY) (Oct)     -22.30%  
//// // All Day   Holiday Bahrain - Prophet's Birthday //// //// //Строка даты нового дня - заносим дату в глобал, для установки дат недатированных событий //// //// //Print("iInpStr=",iInpStr); //// //// string iTheDay=""; //// int posDay=StringFind(iInpStr,"=0)&&(TagContent(iInpStr,"id=\"theDay","/td>",iTheDay))) //// { //// iResult=TagContent(iTheDay,", ","<",iTheDay); //// gMoun=StringSubstr(iTheDay,0,StringFind(iTheDay," ")); //// gMoun=StringSubstr(iMounthN,StringFind(iMounthN,gMoun,2)-2,2); //// iResult=TagContent(iTheDay," ",",",gDay); //// gYear=StringSubstr(iTheDay,StringFind(iTheDay,", ")+2); //// iTheDay=gYear+"."+gMoun+"."+gDay+" 00:00:00"; //// TimeToStruct(StringToTime(iTheDay),gDateTime); //// iResult=TagDelete(iInpStr,"",""); //// //Print("iTheDay=",iTheDay); //// return(false); //// }}//if(TagContent(InpStrBuff,"id=\"theDay","/td>",iTheDay)) //// //// int dFormat=0; //// dFormat=(TagContent(iInpStr,"event_timestamp=\"","\">",iDate)) //// ?(1) //// :( //// (TagContent(iInpStr,"data-event-datetime=\"","\">",iDate)) //// ?(2) //// :(0) //// ); //// {if((dFormat==1)||(dFormat==2)) //если один из распознаваемых форматов //// //{if(TagContent(iInpStr,"event_timestamp=\"","\">",iDate)) //если есть дата тэг в формате сгенерированной страницы ноябрь 2016 //// //{if(TagContent(iInpStr,"data-event-datetime=\"","\">",iDate)) //если есть дата тэг в формате апреля 2016 //// //{if(TagContent(iInpStr,"event_timestamp=\"","\">",iDate)) //если есть дата тэг в формате ранее апреля 2016 //// { //// //----- Date Time //// if(dFormat==2)StringReplace(iDate,"/",".");//в формате апреля 2016 //// if(dFormat==1)StringReplace(iDate,"-",".");//в формате ранее апреля 2016 //// iDateTim=TimeToString(StringToTime(iDate)+iOffSetTime,TIME_DATE|TIME_MINUTES); //// TimeToStruct(StringToTime(iDate)+iOffSetTime,gDateTime); //// iResult=TagDelete(iInpStr,""); //// //18:00EUR"); //// //EUREUR","",iCouN); //// iResult=TagDelete(iInpStr,""); //// //",iVolatility); //// //iResult=TagContent(iInpStr,"noWrap\" title=\"","\" data-img_key",iVolatility); //// //----- Impact N //// iImpN=StringSubstr(iImpactMN,StringFind(iImpactMN,iVolatility,1)-1,1); //// iResult=TagDelete(iInpStr,""); //// //France Jobseekers Total (Feb)3,591.0K3,555.3K3,552.6K //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,""); //Удаляем тип события //// //----- Event //// iResult=TagContent(iInpStr,"event\">","","",iEvent); //// iResult=TagDelete(iInpStr,""); //Удаляем событие //// //3,591.0K3,555.3K3,552.6K //// n=StringReplace(iEvent,"&",""); //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,"",iActual); //// iResult=TagContent(iActual,"\">","<",iActual); //// n=StringReplace(iActual," ",""); //// iResult=TagDelete(iInpStr,""); //Удаляем тег с актуалом //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,"",iForecast); //// iResult=TagContent(iForecast,"\">","<",iForecast); //// n=StringReplace(iForecast," ",""); //// iResult=TagDelete(iInpStr,""); //Удаляем тег с прогнозом //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,"",iPrevious); //// iResult=TagContent(iPrevious,"\">","<",iPrevious); //// n=StringReplace(iPrevious," ",""); //// }else{//Если даты нет но возможно "All Day" //// {if(TagContent(iInpStr,"","",iDate)&&(iDate=="All Day")) //если есть дата тэг //// { //// //----- Date Time //// iDateTim=TimeToString(StructToTime(gDateTime),TIME_DATE|TIME_MINUTES); //// iResult=TagDelete(iInpStr,""); //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,""); //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,"",iVolatility); //// iResult=TagContent(iVolatility,"\">","",iVolatility); //// //----- Impact N //// iImpN=StringSubstr(iImpactMN,StringFind(iImpactMN,iVolatility,1)-1,1); //// iResult=TagDelete(iInpStr,""); //// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,"",iEvent); //// iResult=TagContent(iInpStr,"\">","","",iMouDay)) //// }}//if(TagContent(iInpStr,"","",iMouDay)) //// iOutStr=iDateTim+";"+iEvent+";"+iCountry+";"+iCouN+";"+iImpN+";"+iPrevious+";"+iForecast+";"+iActual+";";// //// //Print("iOutStr=",iOutStr); //// //Print("3. iRes=",iResult," iPrevious=",iPrevious," iStr=",iInpStr); //// return(true); //// }}//if(iMode==4) //////----- Календарь forexfactory html //// {if(iMode==5) //// { //// //----- Date //// {if(TagContent(iInpStr,"","",iMou)) //если есть дата тэг //// { //// iResult=TagDelete(iMou,"",""); //Удаляем день недели //// iResult=TagDelete(iMou,"",""); //Удаляем //// iDay=StringSubstr(iMou,4); //Вынимаем "14" или "1" //// iMou=StringSubstr(iMou,0,3); //Вынимаем "Dec" //// iDay=((StringLen(iDay)>=2)?(StringSubstr(iDay,0,2)):("0"+iDay)); //День дополняем нулем //// iMou=StringSubstr(iMounthN,StringFind(iMounthN,iMou,2)-2,2); //Месяц переводим в число //// gDay=iDay; //// gMoun=iMou; //// }else{//Если даты нет //// iDay=gDay; //// iMou=gMoun; //// }}//if(TagContent(iInpStr,"","",iMouDay)) //// iResult=TagDelete(iInpStr,"",""); //Удаляем дату //// //----- Time //// {if(TagContent(iInpStr,"","",iTim)) //Если есть время тэг //// { //// {if((iTim=="Tentative")||(iTim=="All Day")) //// { //// iTim="00:00"; //// }else{ //// {if((StringLen(iTim)>5)&&(StringFind(iTim,":",1)>=1)) //Если есть дополнительный тег и время в нем //// {// //// iResult=TagContent(iTim,"","",iTim); //Вынимаем "0:00" или "00:00" //// }}//if(StringLen(iTim)>5) //// iTim=((StringLen(iTim)>=5)?(StringSubstr(iTim,0,5)):("0"+iTim)); //// gTim=iTim; //// }}// //// }else{//Если даты нет //// iTim=gTim; //// }}//if(TagContent(iInpStr,"","",iTim)) //// iResult=TagDelete(iInpStr,"",""); //Удаляем время //// //----- Currency //// iResult=TagContent(iInpStr,"","",iCouN); //// {if(!iResult) //// { //// iOutStr=""; //// return(false); //// }}//if(!iResult) //// iResult=TagDelete(iInpStr,"",""); //// //----- Impact //// iResult=TagContent(iInpStr,"","",iImpact); //// iResult=TagContent(iImpact,"",""); //// //----- Impact N //// iImpN=StringSubstr(iImpactNN,StringFind(iImpactNN,iImpact,1)-1,1); //// //----- Event & //// iEvent=""; //// iResult=TagContent(iInpStr,"","",iEvent); //// n=StringReplace(iEvent,"&","&"); //// {if(!iResult) //// { //// iOutStr=""; //// return(false); //// }}//if(!iResult) //// iResult=TagDelete(iInpStr,"",""); //// iResult=TagDelete(iInpStr,"",""); //// iCountry=StringSubstr(iEvent,0,StringFind(iEvent," ",0)); //// nCountry=StringFind(iCountryT,iCountry,0); //// nnCountry=nCountry+StringLen(iCountry); //// iCountry=((nCountry>=0) //// ?(StringSubstr(iCountryT,nnCountry,StringFind(iCountryT,"#",nnCountry)-nnCountry)) //// :(StringSubstr(iCountryS, //// StringFind(iCountryS,iCouN,0)+3, //// StringFind(iCountryS,"#",StringFind(iCountryS,iCouN,0)+3)-StringFind(iCountryS,iCouN,0)-3))); //// iEvent=((nCountry>=0)?(StringSubstr(iEvent,StringFind(iEvent," ",0)+1,StringLen(iCountry)-StringFind(iEvent," ",0)-1)):(iEvent)); //// StringTrimRight(iEvent); //// //----- Actual //// iResult=TagContent(iInpStr,"","",iActual); //// {if(StringFind(iActual,"",iClass); //// iResult=TagContent(iActual,"","",iActual); //// StringNormal(iActual); //// iResult=TagDelete(iInpStr,""); //// }}// //// iResult=TagDelete(iInpStr,"",""); //// n=StringReplace(iActual,"<",""); //// n=StringReplace(iActual,"\t","");//Тут всавлен спецсимвол табуляция //// n=StringReplace(iActual," ",""); //// StringNormal(iActual); //// //----- Forecast //// iResult=TagContent(iInpStr,"","",iForecast); //// iResult=TagDelete(iInpStr,"",""); //// n=StringReplace(iForecast,"<",""); //// n=StringReplace(iForecast,"\t",""); //// n=StringReplace(iForecast," ",""); //// StringNormal(iForecast); //// //----- Previous //// iResult=TagContent(iInpStr,"","",iPrevious); //// {if(StringFind(iPrevious,"",iClass); //// iResult=TagContent(iPrevious,"","",iPrevious); //// iResult=TagDelete(iInpStr,""); //// }}//< //// n=StringReplace(iPrevious,"<",""); //// n=StringReplace(iPrevious,"\t",""); //// n=StringReplace(iPrevious," ",""); //// StringNormal(iPrevious); //// iOutStr=iYear+"."+iMou+"."+iDay+" "+iTim+";"+iEvent+";"+iCountry+";"+iCouN+";"+iImpN+";"+iPrevious+";"+iForecast+";"+iActual+";";// //// return(true); //// //Print("iOutStr=",iOutStr); //// //Print("3. iRes=",iResult," iActual=***",iActual,"*** iStr=",iInpStr); //// }}//if(iMode==5) //////----- Календарь DailyFX html //// {if(iMode==6) //// { //////id="date1_0" style="width: 0%;">December 14, 2015 00:30 //////
//////
00:30
NZD Performance Services Index (NOV) ////// ////// ////// ////// //////59.8 ////// //////56.5 //// //----- Date Time //// {if(TagContent(iInpStr,";\"","/td>",iDateTim)) //если есть дата тэг //// { //// iResult=TagContent(iDateTim,">"," ",iMou); //// iMou=StringSubstr(iMounthN,StringFind(iMounthN,iMou,2)-2,2); //Месяц переводим в число //// iResult=TagDelete(iDateTim,">"," "); //Удаляем //// iDay=StringSubstr(iDateTim,0,StringFind(iDateTim,",")); //Вынимаем день //// iDay=((StringLen(iDay)>=2)?(StringSubstr(iDay,0,2)):("0"+iDay)); //День дополняем нулем //// iDateTim=StringSubstr(iDateTim,StringFind(iDateTim,", ")+2); //Вырезаем от года и дальше //// iYear=StringSubstr(iDateTim,0,4); //Вынимаем год //// iResult=TagContent(iDateTim," ","<",iTim); //Вынимаем время //// gYear=iYear; //// gMoun=iMou; //// gDay=iDay; //// gTim=iTim; //// }else{//Если даты нет ??А это возможно?? //// iYear=gYear; //// iDay=gDay; //// iMou=gMoun; //// iTim=gTim; //// }}//if(TagContent(iInpStr,"","",iMouDay)) //// iDate=iYear+"."+iMou+"."+iDay+" "+iTim; //// iDateTim=TimeToString(StringToTime(iDate),TIME_DATE|TIME_MINUTES); //// TimeToStruct(StringToTime(iDate),gDateTime); //// iResult=TagDelete(iInpStr,"id=\"date",""); //Удаляем дату //// //----- Currency //// iResult=TagContent(iInpStr,"
",iCouN); //// {if(!iResult) //// { //// iOutStr=""; //// return(false); //// }}//if(!iResult) //// StringToUpper(iCouN); //// iResult=TagDelete(iInpStr,""," ",iCur); //// {if(StringFind(iCountryS,iCur)>=0) //// { //// iResult=TagDelete(iEvent,">"," "); //// iResult=TagContent(iEvent,"v","","=0) //// n=StringReplace(iEvent,"'","\'"); //// iResult=TagDelete(iInpStr,"div>","","",iImpact); //// {if(!iResult) //// { //// iOutStr=""; //// return(false); //// }}//if(!iResult) //// //----- Impact N //// iImpN=StringSubstr(iImpactON,StringFind(iImpactON,iImpact,1)-1,1); //// iResult=TagDelete(iInpStr,"ortance",""); //// //----- Actual //// iResult=TagContent(iInpStr,"td\">","",iActual); //// iResult=TagDelete(iInpStr,""); //// //n=StringReplace(iActual,"<",""); //// //n=StringReplace(iActual,"\t",""); //// //n=StringReplace(iActual," ",""); //// StringNormal(iActual); //// //----- Forecast //// iResult=TagContent(iInpStr,"td\">","",iForecast); //// iResult=TagDelete(iInpStr,""); //// //n=StringReplace(iForecast,"<",""); //// //n=StringReplace(iForecast,"\t",""); //// //n=StringReplace(iForecast," ",""); //// StringNormal(iForecast); //// //----- Previous //// iResult=TagContent(iInpStr,"td\">","",iPrevious); //// iResult=TagDelete(iInpStr,""); //// //n=StringReplace(iPrevious,"<",""); //// //n=StringReplace(iPrevious,"\t",""); //// //n=StringReplace(iPrevious," ",""); //// StringNormal(iPrevious); //// iOutStr=iYear+"."+iMou+"."+iDay+" "+iTim+";"+iEvent+";"+iCountry+";"+iCouN+";"+iImpN+";"+iPrevious+";"+iForecast+";"+iActual+";";// //// return(true); //// //Print("iOutStr=",iOutStr); //// //Print("3. iRes=",iResult," iActual=***",iActual,"*** iStr=",iInpStr); //// }}//if(iMode==6) //////----- //// return(false); ////}//StringConverter() // //====================================================================================================== // StringNormal() - удаление из строки не цифровых символов //====================================================================================================== void StringNormal(string &iInpStr){ string Cifr="0123456789.-KMBT$|%"; StringTrimLeft(iInpStr); StringTrimRight(iInpStr); StringToUpper(iInpStr); //Print(iInpStr); {for(int i=StringLen(iInpStr)-1;i>=0;i--) { {if(StringFind(Cifr,StringSubstr(iInpStr,i,1),0)<0) { //Print(StringSubstr(iInpStr,i,1)); StringSetCharacter(iInpStr,i,'#'); }}//if(StringFind(Cifr,StringSubstr(iInpStr,i,1),0)<0) }}//for(int i=StringLen(iInpStr)-1;i>=0;i--) //Print(StringReplace(iInpStr,"#","")); StringReplace(iInpStr,"#",""); return; }//StringNormal() // //====================================================================================================== // NormalizeFile() - Удаление из файла повторов и косяков //====================================================================================================== bool NormalizeFile( string iInFileName, string iTmpFileName){ string OutStr=""; uchar LastChar=char(0), InpChar=char(0); int n=0, CharOperation=0;// 0/1/2/3 - без изменений/пропустить/заменить/конец строки //----- ResetLastError(); int InFileHandle = FileOpen(iInFileName,FILE_READ|FILE_BIN|FILE_COMMON,','); {if ((InFileHandle!=INVALID_HANDLE)&&(FileSize(InFileHandle)!=0)) { ResetLastError(); int OutFileHandle=FileOpen(iTmpFileName,FILE_WRITE|FILE_TXT|FILE_ANSI|FILE_COMMON,','); {if(OutFileHandle!=INVALID_HANDLE) { bool NewString=true; {while(!FileIsEnding(InFileHandle)) { CharOperation=0;//Передать на выход по умолчанию ResetLastError(); InpChar=(uchar)FileReadInteger(InFileHandle,1); {if(CharToString(InpChar)==">")//Конец тега - конец строки { CharOperation=3; }}//if(CharToString(InpChar)==">") {if(CharToString(InpChar)==" ")//Пробел... { {if(CharToString(LastChar)==" ")//... после пробела { CharOperation=1;//Пропустить }else{ CharOperation=0;//Передать на выход }}//if(CharToString(LastChar)==" ") }}//if(CharToString(InpChar)==" ") LastChar=InpChar; {switch(CharOperation) { case 1://Пропустить //Просто ничего не делать break; case 2://Заменить //Пока не известно, что можно сразу заменять break; case 3://Конец строки - запись строки в файл ResetLastError(); OutStr=OutStr+CharToString(InpChar); //Подчистка n=StringReplace(OutStr,"\t","");//Удаляем табуляции n=StringReplace(OutStr,"\n","");//удаляем возвраты каретки n=StringReplace(OutStr,"\r","");//удаляем переводы строк n=StringReplace(OutStr,"\0",""); n=StringReplace(OutStr," ","");//  n=StringReplace(OutStr,"&","");//& n=StringReplace(OutStr,"<","");//< n=StringReplace(OutStr,"'","");//' n=StringReplace(OutStr," <","<");//удаляем пробел перед тегом n=StringReplace(OutStr," "," ");//удаляем двойные пробелы OutStr=((StringGetCharacter(OutStr,0)==StringGetCharacter(" ",0))?(StringSubstr(OutStr,1)):(OutStr));//удаляем пробел в начале строки //OutStr=OutStr+"\n\r";//<ВК><ПС> OutStr=OutStr+"\n";//<ВК> //Print("OutStr=",OutStr); if(FileWriteString(OutFileHandle,OutStr)==0)return(false); OutStr=""; break; default://0 - Передать без изменений на выход OutStr=OutStr+CharToString(InpChar); break; }}//switch(CharOperation) }}//while(!FileIsEnding(file_handle)) //Закрытие выходного файла ResetLastError(); FileClose(OutFileHandle); //Закрытие входного файла ResetLastError(); FileClose(InFileHandle); }else{ Print("NormalizeFile>> Операция FileOpen Write неудачна, ошибка ",GetLastError()); return(false); }}//if(OutFileHandle!=INVALID_HANDLE) }else{ Print("NormalizeFile>> Операция FileOpen Read неудачна, ошибка ",GetLastError()); return(false); }}//if ((InFileHandle!=INVALID_HANDLE)&&(FileSize(InFileHandle)!=0)) //----- return(true); }//NormalizeFile() // //====================================================================================================== // iMAOnArrayMql4v2() - Расчет скользящего среднего как для mql4 программ от произвольного массива. // Вход: // Array[] - Массив с данными. // total - Количество элементов для вычисления. 0 означает все элементы массива. // ma_period - Период усреднения для вычисления индикатора. // ma_shift - Сдвиг индикатора относительно ценового графика. // ma_method - Метод усреднения. Может быть любым из значений перечисления ENUM_MA_METHOD. // shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад). // Выход: // Значение технического индикатора Moving Average, рассчитанного на данных, хранящихся в массиве Array[]. //====================================================================================================== double iMAOnArrayMql4v2( double &Array[], uint total, uint iMAPeriod, uint ma_shift, ENUM_MA_METHOD ma_method, uint Shift){ double buf[]; {if((total>0)&&(total<=iMAPeriod)){return(0);}} {if(total==0){total=ArraySize(Array);}}//total равен размеру массива. {if(ArrayResize(buf,total)<0){return(0);}} {switch(ma_method) { case MODE_SMA : { double sum=0; uint i,pos=total-1;//pos равен номеру последнего элемента массива {for(i=1;i1000)||(pos<2)) //{ // Print("total=",total," i=",i," pos=",pos); //}}//if(pos>1000) sum+=Array[pos];//Сумма всех элементов массива на периоде МА }}//for(i=1;i0) { sum+=Array[pos]; buf[pos]=sum/iMAPeriod; sum-=Array[pos+iMAPeriod-1]; pos--; }}//while(pos>0) {if(pos==0) { sum+=Array[pos]; buf[pos]=sum/iMAPeriod; sum-=Array[pos+iMAPeriod-1]; }}//if(pos==0) return(buf[Shift+ma_shift]); }//case MODE_SMA case MODE_EMA : { double pr=2.0/(iMAPeriod+1); uint pos=total-2; {while(pos>0) { if(pos==total-2) buf[pos+1]=Array[pos+1]; buf[pos]=Array[pos]*pr+buf[pos+1]*(1-pr); pos--; }}//while(pos>=0) {if(pos==0) { if(pos==total-2) buf[pos+1]=Array[pos+1]; buf[pos]=Array[pos]*pr+buf[pos+1]*(1-pr); }}//if(pos==0) return(buf[Shift+ma_shift]); }//case MODE_EMA case MODE_SMMA : { double sum=0; uint i,k,pos; pos=total-iMAPeriod; {while(pos>0) { {if(pos==total-iMAPeriod) { {for(i=0,k=pos;i0) {if(pos==0) { {if(pos==total-iMAPeriod) { {for(i=0,k=pos;i0) { buf[pos]=sum/weight; if(pos==0) break; pos--; i--; price=Array[pos]; sum=sum-lsum+price*iMAPeriod; lsum-=Array[i]; lsum+=price; }}//while(pos>0) {if(pos==0) { buf[pos]=sum/weight; if(pos==0) break; pos--; i--; price=Array[pos]; sum=sum-lsum+price*iMAPeriod; lsum-=Array[i]; lsum+=price; }}//if(pos==0) return(buf[Shift+ma_shift]); } default: {return(0);} }}//switch(ma_method) return(0); }//iMAOnArrayMql4v2() // //====================================================================================================== // iBarShiftMql4() - Поиск бара по времени как для mql4. // Функция возвращает индекс бара, в который попадает указанное время. //====================================================================================================== int iBarShiftMql4( string symbol, datetime time, bool exact=false){ {if(time<0){return(-1);}} datetime Arr[],time1; CopyTime(symbol,PERIOD_M1,0,1,Arr); time1=Arr[0]; {if(CopyTime(symbol,PERIOD_M1,time,time1,Arr)>0) { if(ArraySize(Arr)>2) return(ArraySize(Arr)-1); if(time0) }//iBarShiftMql4() // //PositionModify(Pos_Tick,PositionGetDouble(POSITION_PRICE_OPEN),NewStopLoss,PositionGetDouble(POSITION_TP),0,Red) // //====================================================================================================== // PositionModifySL() - Изменение SL TP для позиции // Вход: // iPosTick - тикет позиции // iPosNewSL - Новый SL // iPosNewTP - Новый TP //====================================================================================================== bool PositionModifySL( long iPosTick, double iPosNewSL, double iPosNewTP){ //bool // iOrd_inf=false; //Print("PositionModifySL>>"); //return(true); {if(!PositionSelectByTicket(iPosTick)){return(false);}};//Выбираем позицию по тикету? Неудачно - следующий {if(PositionGetDouble(POSITION_VOLUME)>"); //----- Получим дополнительную информацию по позиции //int q=0; {if(!PositionSelectByTicket(iPosTick)) { Print("Close select error iPosTick=",iPosTick); return(false); }}//if(!PositionSelectByTicket(iPosTick)) //Print(q,". Close select OK iPosTick=",iPosTick);//А эта выводится... или наоборот ENUM_POSITION_TYPE Position_Type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); // тип позиции string Position_Symbol=PositionGetString(POSITION_SYMBOL); // символ //double Position_Volume=PositionGetDouble(POSITION_VOLUME); // объем позиции //double Position_Price=PositionGetDouble(POSITION_PRICE_OPEN); // цена позиции //Print("Position>> Type=",EnumToString(Position_Type), // " Volume=",DoubleToString(Position_Volume,2), // " Price Open=",DoubleToString(Position_Price,5), // " gBid=",gBid, // " gAsk=",gAsk); bool iOrd_inf=false; //--- обнуление значений запроса и результата MqlTradeRequest Request={0}; MqlTradeResult Result={0}; //ZeroMemory(Request); //ZeroMemory(Result); //--- подготовим запрос Request.action =TRADE_ACTION_DEAL; Request.position =iPosTick; // тикет позиции Request.volume =PositionGetDouble(POSITION_VOLUME); // объем позиции Request.deviation =iSlip; Request.symbol =PositionGetString(POSITION_SYMBOL); // символ позиции Request.magic =PositionGetInteger(POSITION_MAGIC); // Request.type =iType; Request.symbol =Position_Symbol; // Request.price =iPrice; // Request.sl =iSL; // Request.tp =iTP; // Request.comment =iComment; // Request.expiration =iExpir; // //--- установка параметров операции // request.volume =volume; // объем позиции // request.deviation=5; // допустимое отклонение от цены // request.magic =EXPERT_MAGIC; // MagicNumber позиции //--- установка цены и типа ордера в зависимости от типа позиции {if(Position_Type==POSITION_TYPE_BUY) { //Request.price = SymbolInfoDouble(Position_Symbol,SYMBOL_ASK); Request.price = SymbolInfoDouble(Position_Symbol,SYMBOL_BID); Request.type = ORDER_TYPE_SELL; //Request.price = Position_Price; }else{ //Request.price = SymbolInfoDouble(Position_Symbol,SYMBOL_BID); Request.price = SymbolInfoDouble(Position_Symbol,SYMBOL_ASK); Request.type = ORDER_TYPE_BUY; //Request.price = Position_Price; }}//if(type==POSITION_TYPE_BUY) //--- последняя проверка и отправка запроса {if(PositionSelectByTicket(iPosTick)) { iOrd_inf=OrderSend(Request,Result); {if(PrnClose){Print("Close select OK iPosTick=",iPosTick);}}//Эта строка в тестере упорно не выводится... }else{ Print("Close select error iPosTick=",iPosTick); return(false); }}//if(!PositionSelectByTicket(iPosTick)) return(iOrd_inf); }//PositionCloseOne() // //====================================================================================================== // Load_History() - загрузка истории // Вход: // iSymbol - инструмент // iPeriod - период // iRequestFirstDate - дата до глубины которой запрашивается подкачка данных // inBars - размер порции подкачки данных // iFailCntMax - число попыток получения данных // Выход: // код завершения операции (отрицательные - ошибки и некорректности) //====================================================================================================== int Load_History_( string iSymbol, ENUM_TIMEFRAMES iPeriod, datetime iRequestFirstDate, int inBars, int iFailCntMax){ datetime iTerminalFirstDate=0; datetime iTimes[]; ArrayResize(iTimes,inBars); //--- check symbol {if((iSymbol==NULL)||(iSymbol=="")) { iSymbol=Symbol(); }}//if((iSymbol==NULL)||(iSymbol=="")) //--- check period {if(iPeriod==PERIOD_CURRENT) { iPeriod=Period(); }}//if(iPeriod==PERIOD_CURRENT) //--- check if symbol is selected in the MarketWatch {if(!SymbolInfoInteger(iSymbol,SYMBOL_SELECT)) { //Неопознанный символ для данного рынка {if(GetLastError()==ERR_MARKET_UNKNOWN_SYMBOL) { return(-1); }}//if(GetLastError()==ERR_MARKET_UNKNOWN_SYMBOL) //Попытка внести символ в окно "Обзор рынка" {if(!SymbolSelect(iSymbol,true)) { Print(__FUNCTION__,"(): Не удалось добавить символ ",iSymbol," в окно MarketWatch!!!"); return(-6); }}//if(!SymbolSelect(iSymbol,true)) }}//(!SymbolInfoInteger(iSymbol,SYMBOL_SELECT)) //--- check if data is present //Теперь необходимо получить начальную дату по уже имеющейся истории для указанной пары символ/период. //Возможно, что значение входного параметра iRequestFirstDate, переданного функции Load_History() //попадает в интервал уже доступной истории, и тогда никакого запроса к торговому серверу не потребуется. //Для получения самой первой даты по символу-периоду на данный момент предназначена функция SeriesInfoInteger() //с модификатором SERIES_FIRSTDATE. SeriesInfoInteger(iSymbol,iPeriod,SERIES_FIRSTDATE,iTerminalFirstDate);//The very first date for the symbol-period for the current moment in terminal {if((iTerminalFirstDate>0)&&(iTerminalFirstDate<=iRequestFirstDate))//Данные есть и перекрывают диапазон запроса { return(1);//Данные есть и перекрывают диапазон запроса, докачка не потребовалась }}//if((iTerminalFirstDate>0)&&(iTerminalFirstDate<=iRequestFirstDate)) //--- don't ask for load of its own data if it is an indicator //Следующая важная проверка — проверка типа программы, из которой вызывается функция. //Напомним, что отправка запроса на обновление таймсерии с тем же периодом, что и у индикатора, //вызывающего обновление, крайне нежелательна. Нежелательность запроса данных по тому же символу-периоду, //что и у индикатора обусловлена тем, что обновление исторических данных производится в том же потоке, //в котором работает индикатор. Поэтому велика вероятность клинча. //Для проверки используем функцию MQL5InfoInteger() с модификатором MQL5_PROGRAM_TYPE. {if( (MQL5InfoInteger(MQL5_PROGRAM_TYPE)==PROGRAM_INDICATOR) && (Period()==iPeriod) && (Symbol()==iSymbol) ) { return(-4); }}//if( //--- second attempt //Если мы успешно прошли все проверки, то сделаем последнюю попытку обойтись без обращения к торговому серверу. //Сначала узнаем начальную дату iTerminalFirstDate, для которой доступны минутные данные в формате HCC. //Запросим это значение функцией SeriesInfoInteger() с модификатором SERIES_TERMINAL_FIRSTDATE //и опять сравним со значением параметра iRequestFirstDate. {if(SeriesInfoInteger(iSymbol,iPeriod,SERIES_TERMINAL_FIRSTDATE,iTerminalFirstDate))//Если значение получено:Самая первая дата в истории независимо от периода (минутные???) в клиентском терминале и она не перекрывает диапазон запроса { //--- there is loaded data to build timeseries {if(iTerminalFirstDate>0)//Данные есть { //--- force timeseries build {if(CopyTime(iSymbol,iPeriod,iTerminalFirstDate+PeriodSeconds(iPeriod),1,iTimes)>0)//Пытаемся скопировать на 1 бар дальше, чем в клиентском терминале { //--- check date {if(SeriesInfoInteger(iSymbol,iPeriod,SERIES_FIRSTDATE,iTerminalFirstDate))//Если значение получено { {if((iTerminalFirstDate>0)&&(iTerminalFirstDate<=iRequestFirstDate))//Данные есть и перекрывают диапазон запроса { return(2);//Данные есть и перекрывают диапазон запроса, потребовалась минимальная докачка в 1 бар }}//if((iTerminalFirstDate>0)&&(iTerminalFirstDate<=iRequestFirstDate)) }}//if(SeriesInfoInteger(iSymbol,iPeriod,SERIES_FIRSTDATE,iTerminalFirstDate)) }}//if(CopyTime(iSymbol,iPeriod,iTerminalFirstDate+PeriodSeconds(iPeriod),1,iTimes)>0) }}//if(iTerminalFirstDate>0) }}//if(SeriesInfoInteger(iSymbol,PERIOD_M1,SERIES_TERMINAL_FIRSTDATE,iTerminalFirstDate)) //--- max bars in chart from terminal options int iMaxBars=TerminalInfoInteger(TERMINAL_MAXBARS);//Максимальное количество баров на графике //--- load symbol history info datetime iFirstServerDate=0; {while( (!SeriesInfoInteger(iSymbol,PERIOD_M1,SERIES_SERVER_FIRSTDATE,iFirstServerDate)) && (!IsStopped()) ) { Sleep(5); }}//while( //--- fix start date for loading {if(iFirstServerDate>iRequestFirstDate) { iRequestFirstDate=iFirstServerDate; }}//if(first_server_date>iRequestFirstDate) {if((iTerminalFirstDate>0)&&(iTerminalFirstDate0)&&(iTerminalFirstDate0) { //Если есть бары в истории //--- баров больше, чем можно отобразить на графике, выходим {if(iBars>=iMaxBars)//Количество баров в истории больше чем максимальное количество баров на графике { return(-2); }}//if(iBars>=iMaxBars) //--- 3. узнаем текущую начальную дату в таймсерии {if(SeriesInfoInteger(iSymbol,iPeriod,SERIES_FIRSTDATE,iTerminalFirstDate))//Получаем в first_date самую первую дату по символу на сервере { //значение было помещено в переменную iTerminalFirstDate {if((iTerminalFirstDate>0)&&(iTerminalFirstDate<=iRequestFirstDate))//Дата есть и меньше требуемой { return(0); }}//if((iTerminalFirstDate>0)&&(iTerminalFirstDate<=iRequestFirstDate)) }else{ //значение НЕ было помещено в переменную iTerminalFirstDate, возвращает false. //Чтобы получить дополнительную информацию об ошибке, необходимо вызвать функцию GetLastError(). Print("Exception 0007"); return(-7); }}//if(SeriesInfoInteger(iSymbol,iPeriod,SERIES_FIRSTDATE,iTerminalFirstDate)) }else{ //данные для таймсерии с указанными параметрами при вызове функции Bars() еще не сформированы в терминале, //или данные таймсерии в момент вызова функции не синхронизированы с торговым сервером Print("Exception 0008"); return(-8); }}//if(iBars>0) //4. Запросим новую порцию истории в inBars баров у торгового сервера от последнего доступного бара под номером iBars int iCopied=CopyTime(iSymbol,iPeriod,iBars,inBars,iTimes);//Запрос подкачки ещё inBars баров истории с бара iBars {if(iCopied>0) { //--- check for data {if(iTimes[0]<=iRequestFirstDate)//самое старое скопированное значение раньше даты начала, готово (массив не as_series!!!) { return(0); }}//if(iTimes[0]<=iRequestFirstDate) {if(iBars+iCopied>=iMaxBars)// баров стало больше, чем можно размещать на график, готово { return(-2); }}//if(iBars+iCopied>=iMaxBars) iFailCnt=0; }else{ //--- no more than iFailCntMax failed attempts iFailCnt++; {if(iFailCnt>=iFailCntMax) { return(-5); }}//if(fail_cnt>=iFailCntMax) Sleep(10); }}//if(iCopied>0) }}//while(!IsStopped()) //----+ stopped return(-3); }//Load_History() // //====================================================================================================== // Load_History2() - загрузка истории в терминал // Вход: // iSymbol - инструмент // iRequestFirstDate - дата до глубины которой запрашивается подкачка данных // inBars - размер порции подкачки данных // iFailCnt... - число попыток получения данных // Выход: // функция: код завершения операции (отрицательные - ошибки и некорректности) // iFirstDate - гарантированное время начала данных //====================================================================================================== int Load_History2( string iSymbol, datetime iRequestFirstDate, datetime &iFirstDate, int &iBarsN, int inBars=100, bool iPrintDebug=false, int iFailCntTerminalFirstDateMax=10,//для запроса данных терминала int iFailCntServerFirstDateMax=10,//для запроса данных сервера int iFailCntCopyRatesMax=10,//для попыток копирования данных int iFailCntSyncMax=10)//для попыток синхронозации { iBarsN=0;//Обнуляем выходной параметр - количество баров на графике iFirstDate=0;//Обнуляем выходной параметр - время начала данных //----- Временный массив для подкачки данных MqlRates iRates[]; ArraySetAsSeries(iRates,false);//Гарантированно не AsSeries ArrayResize(iRates,inBars); //----- Проверка символа на специальные значения {if((iSymbol==NULL)||(iSymbol=="")) { iSymbol=TheSymbol; }}//if((iSymbol==NULL)||(iSymbol=="")) //----- Проверка символа на присутствие в Обзоре Рынка (MarketWatch) {if(!SymbolInfoInteger(iSymbol,SYMBOL_SELECT)) { //Неопознанный символ для данного рынка {if(GetLastError()==ERR_MARKET_UNKNOWN_SYMBOL) { {if(iPrintDebug){Print(__FUNCTION__,"() Error (-1) >> Неопознанный символ ",iSymbol," для данного рынка!");}} return(-1);//Неопознанный символ для данного рынка }}//if(GetLastError()==ERR_MARKET_UNKNOWN_SYMBOL) //----- Попытка внести символ в окно "Обзор рынка" если его там не было {if(!SymbolSelect(iSymbol,true)) { {if(iPrintDebug){Print(__FUNCTION__,"() Error (-6) >> Не удалось добавить символ ",iSymbol," в окно MarketWatch!");}} return(-6);//Не удалось добавить символ в окно MarketWatch }}//if(!SymbolSelect(iSymbol,true)) }}//(!SymbolInfoInteger(iSymbol,SYMBOL_SELECT)) //----- Проверка данных на наличие //Теперь необходимо получить начальную дату по уже имеющейся истории для указанной пары символ/период. //Возможно, что значение входного параметра iRequestFirstDate, переданного функции Load_History() //попадает в интервал уже доступной истории, и тогда никакого запроса к торговому серверу не потребуется. //Для получения самой первой даты по символу-периоду на данный момент предназначена функция SeriesInfoInteger() //с модификатором SERIES_FIRSTDATE. datetime iTerminalFirstDate=0; int iFailCntTerminalFirstDate=iFailCntTerminalFirstDateMax; /*A*/{while(iFailCntTerminalFirstDate>=1)//Продолжаем, пока счетчик попыток не обнулился { {if(IsStopped()){return(-101);}} /*B*/ {if(//Самая первая дата в истории независимо от периода (минутные???) в клиентском терминале (SeriesInfoInteger(iSymbol,PERIOD_M1,SERIES_TERMINAL_FIRSTDATE,iTerminalFirstDate))//Данные получены && (iTerminalFirstDate>0)//Данные реальны ) {//Данные терминала получены iFailCntTerminalFirstDate=iFailCntTerminalFirstDateMax;//Устанавливаем счетчик попыток обращения к данным /*C*/ {if(iTerminalFirstDate<=iRequestFirstDate)//Данные перекрывают диапазон запроса { iBarsN=Bars(iSymbol,PERIOD_M1);//Общее количество всех баров в истории терминала - на выход iFirstDate=iTerminalFirstDate;//Время начала данных терминала - на выход {if(iPrintDebug){Print(__FUNCTION__,"() Normal (1) >> Данные перекрывают диапазон запроса. B=",iBarsN," T=",iFirstDate);}} return(1);//Выход с кодом возврата 1 из цикла /*A*/ /*C*/ }else{//Данные есть, но не перекрывают диапазон запроса - нужна докачка //----- Загрузка информации об истории на сервере datetime iFirstServerDate=0; int iFailCntServerFirstDate=iFailCntServerFirstDateMax;//Число попыток обращения к информации сервера /*D*/ {while(iFailCntServerFirstDate>=1)//Продолжаем, пока счетчик попыток не обнулился { {if(IsStopped()){return(-101);}} //Анализ доступности информации сервера /*E*/ {if(//Самая первая дата в истории независимо от периода (минутки?) на сервере (SeriesInfoInteger(iSymbol,PERIOD_M1,SERIES_SERVER_FIRSTDATE,iFirstServerDate))//Данные получены && (iFirstServerDate>0)//Данные реальны ) {//Данные об истории с сервера получены /*F*/ {if(iFirstServerDate<=iRequestFirstDate)//Истории на сервере достаточно { //Данных на сервере достаточно для обработки запроса //Тут будем пытаться считать запрошенное количество данных //--- load data step by step int iFailCntCopyRates=iFailCntCopyRatesMax;//Устанавливаем счетчик попыток загрузки данных с сервера /*G*/ {while(iFailCntCopyRates>=1)//Продолжаем, пока счетчик попыток не обнулился { {if(IsStopped()){return(-101);}} //--- 1.дождаться окончания процесса перестройки таймсерии int iFailCntSync=iFailCntSyncMax;//Устанавливаем счетчик попыток синхронизации данных /*H*/ {while(iFailCntSync>=1)//Продолжаем попытки синхронизации, пока счетчик попыток не обнулился {//Проверка синхронности данных {if(IsStopped()){return(-101);}} /*I*/ {if((bool)SeriesInfoInteger(iSymbol,PERIOD_M1,SERIES_SYNCHRONIZED))//Проверка синхронности данных {//Если данные синхронны - выполняем загрузку iFailCntSync=iFailCntSyncMax;//Устанавливаем счетчик попыток синхронизации данных //--- 2.запросим сколько баров мы теперь имеем в истории терминала int iBars=Bars(iSymbol,PERIOD_M1);//Общее количество всех баров в истории терминала /*J*/ {if(iBars>0) { //Если есть бары в истории и синхронизировано и сформировано //--- max bars in chart from terminal options int iTerminalMaxBars=TerminalInfoInteger(TERMINAL_MAXBARS);//Максимальное количество баров на графике установленное в настройках /*K*/ {if(iBars0)//Дата есть && (iTerminalFirstDate2<=iRequestFirstDate)//Дата меньше требуемой ) {//Дата начала данных терминала меньше или равна запрошенной iBarsN=iBars;//Общее количество всех баров в истории терминала - на выход iFirstDate=iTerminalFirstDate2;//Время начала данных терминала - на выход {if(iPrintDebug){Print(__FUNCTION__,"() Normal (2) >> Дата начала данных терминала меньше или равна запрошенной. B=",iBarsN," T=",iFirstDate);}} return(2);//Дата начала данных терминала меньше или равна запрошенной /*M*/ }else{//Дата начала данных терминала больше запрошенной //Обработка докачки //4. Запросим новую порцию истории в inBars баров у торгового сервера от последнего доступного бара под номером iBars дальше в прошлое int iCopied=CopyRates(iSymbol,PERIOD_M1,iBars,inBars,iRates);//Запрос подкачки в терминал ещё inBars баров истории начиная с бара iBars и дальше в прошлое /*N*/ {if(iCopied>0) {//Данные скопированы //Проверка условия завершения закачки /*O*/ {if(iRates[0].time<=iRequestFirstDate)//самое старое скопированное значение раньше даты начала, готово (массив iRates не as_series!!!) {//Дата начала данных терминала меньше или равна запрошенной iBarsN=iBars+iCopied;//Общее количество всех баров в истории терминала - на выход iFirstDate=iRates[0].time;//Время начала данных терминала - на выход {if(iPrintDebug){Print(__FUNCTION__,"() Normal (3) >> Дата начала данных терминала меньше или равна запрошенной. B=",iBarsN," T=",iFirstDate);}} return(3);//Дата начала данных терминала меньше или равна запрошенной /*O*/ }else{//Дата терминала больше запрошенной /*P*/ {if(iBars+iCopied>=iTerminalMaxBars)//После докачки баров стало больше, чем можно размещать на график, вернуть достигнутое время {//Продолжение докачки невозможно - превышено максимальное количество баров iBarsN=iBars+iCopied;//Общее количество всех баров в истории терминала - на выход iFirstDate=iRates[0].time;//Время начала данных терминала - на выход {if(iPrintDebug){Print(__FUNCTION__,"() Error (-2) >> После докачки баров стало больше, чем можно размещать на график! B=",iBarsN," T=",iFirstDate);}} return(-2);//После докачки баров стало больше, чем можно размещать на график /*P*/ }else{//Продолжение возможно - максимальное количество баров не превышено //Тут: данные были скопированы, но условие завершения докачки не соблюдено - продолжим докачку iFailCntCopyRates=iFailCntCopyRatesMax;//Устанавливаем счетчик попыток докачки в исходное состояние /*P*/ }}//if(iBars+iCopied>=iTerminalMaxBars) /*O*/ }}//if(iTimes[0]<=iRequestFirstDate) /*N*/ }else{//Данные НЕ скопированы /*Q*/ {if(iFailCntCopyRates>1) {//Количество попыток докачки НЕ исчерпано iFailCntCopyRates--;//Декремент количества попыток докачки Sleep(5);//Небольшая задержка /*Q*/ }else{//Количество попыток докачки исчерпано iBarsN=iBars;//Общее количество всех баров в истории терминала - на выход iFirstDate=iTerminalFirstDate2;//Время начала данных терминала - на выход {if(iPrintDebug){Print(__FUNCTION__,"() Error (-5) >> Количество попыток докачки исчерпано! B=",iBarsN," T=",iFirstDate);}} return(-5);//Количество попыток исчерпано /*Q*/ }}//if(iFailCntCopyRates>1) /*N*/ }}//if(iCopied>0) /*M*/ }}//if((iTerminalFirstDate>0)&&(iTerminalFirstDate<=iRequestFirstDate)) /*L*/ }else{//Значение НЕ было помещено в переменную iTerminalFirstDate /*R*/ {if(iFailCntCopyRates>1) {//Количество попыток докачки НЕ исчерпано iFailCntCopyRates--;//Декремент количества попыток докачки Sleep(5);//Небольшая задержка /*R*/ }else{//Количество попыток докачки исчерпано iBarsN=iBars;//Общее количество всех баров в истории терминала - на выход iFirstDate=iTerminalFirstDate;//Время начала данных терминала - на выход //Чтобы получить дополнительную информацию об ошибке, необходимо вызвать функцию GetLastError(). {if(iPrintDebug){Print(__FUNCTION__,"() Error (-7) >> Значение TerminalFirstDate НЕ получено! Количество попыток докачки исчерпано! B=",iBarsN," T=",iFirstDate);}} return(-7);//Количество попыток исчерпано /*R*/ }}//if(iFailCntCopyRates>1) /*L*/ }}//if(SeriesInfoInteger(iSymbol,iPeriod,SERIES_FIRSTDATE,iTerminalFirstDate2)) /*K*/ }else{//Количество баров в истории больше чем максимально возможное количество баров на графике заданное в настройках //Исправить невозможно - по любому выход iBarsN=iBars;//Общее количество всех баров в истории терминала - на выход iFirstDate=iTerminalFirstDate;//Время начала данных терминала - на выход {if(iPrintDebug){Print(__FUNCTION__,"() Error (-8) >> Количество баров в истории больше, чем можно размещать на график! B=",iBarsN," T=",iFirstDate);}} return(-8); /*K*/ }}//(iBars1) {//Счетчик попыток получения данных сервера НЕ исчерпан iFailCntSync--;//Декремент счетчика попыток синхронизации Sleep(5);//Небольшая задержка... }else{//Счетчик попыток синхронизации исчерпан iBarsN=iBars;//Общее количество всех баров в истории терминала - на выход iFirstDate=iTerminalFirstDate;//Время начала данных терминала - на выход {if(iPrintDebug){Print(__FUNCTION__,"() Error (-9) >> Данные при вызове Bars() не сформированы за ",iFailCntSyncMax," попыток! B=",iBarsN," T=",iFirstDate);}} return(-9);//iFailCntSync error }}//if(iFailCntSync>1) /*J*/ }}//if(iBars>0) /*I*/ }else{//Если данные не синхронны {if(iFailCntSync>1) {//Счетчик попыток получения синхронизации НЕ исчерпан iFailCntSync--;//Декремент счетчика попыток синхронизации Sleep(10);//Небольшая задержка... }else{//Счетчик попыток синхронизации исчерпан iBarsN=Bars(iSymbol,PERIOD_M1);//Общее количество всех баров в истории терминала - на выход iFirstDate=iTerminalFirstDate;//Время начала данных терминала - на выход {if(iPrintDebug){Print(__FUNCTION__,"() Error (-10) >> Данные НЕ синхронизированы за ",iFailCntSyncMax," попыток! B=",iBarsN," T=",iFirstDate);}} return(-10);//iFailCntSync error }}//if(iFailCntSync>1) /*I*/ }}//if((bool)SeriesInfoInteger(iSymbol,PERIOD_M1,SERIES_SYNCHRONIZED)) /*H*/ }}//while( (iFailCntSync>=1)... /*G*/ }}//while( (iFailCntCopyRates>=1)... /*F*/ }else{//Данных на сервере НЕ достаточно //Выходим с признаком ошибки и количеством скачанного iBarsN=Bars(iSymbol,PERIOD_M1);//Общее количество всех баров в истории терминала - на выход iFirstDate=iFirstServerDate;//Время начала данных сервера - на выход {if(iPrintDebug){Print(__FUNCTION__,"() Error (-11) >> Данных на сервере НЕ достаточно!");}} return(-11);//Данных на сервере НЕ достаточно /*F*/ }}//if(iFirstServerDate>iRequestFirstDate) /*E*/ }else{//Данные об истории с сервера НЕ получены {if(iFailCntServerFirstDate>1) {//Счетчик попыток получения данных сервера НЕ исчерпан iFailCntServerFirstDate--;//Декремент счетчика попыток получения данных сервера Sleep(5);//Небольшая задержка... }else{//Счетчик попыток получения данных сервера исчерпан iBarsN=Bars(iSymbol,PERIOD_M1);//Общее количество всех баров в истории терминала - на выход iFirstDate=iTerminalFirstDate;//Время начала данных терминала - на выход {if(iPrintDebug){Print(__FUNCTION__,"() Error (-12) >> Данные об истории сервера НЕ получены за ",iFailCntServerFirstDateMax," попыток! B=",iBarsN," T=",iFirstDate);}} return(-12);//iFailCntServerFirstDate error }}//if(iFailCntFirstServerDate>1) /*E*/ }}//if( (SeriesInfoInteger(iSymbol,PERIOD_M1,SERIES_SERVER_FIRSTDATE,iFirstServerDate)) /*D*/ }}//while( (iFailCntServerFirstDate>=1) && (!IsStopped()) /*C*/ }}//if(iTerminalFirstDate<=iRequestFirstDate)) /*B*/ }else{//Данные терминала НЕ получены {if(iFailCntTerminalFirstDate>1) {//Счетчик попыток получения данных терминала НЕ исчерпан iFailCntTerminalFirstDate--;//Декремент счетчика попыток получения данных терминала Sleep(5);//Небольшая задержка... }else{//Счетчик попыток получения данных терминала исчерпан iBarsN=Bars(iSymbol,PERIOD_M1);//Общее количество всех баров в истории терминала - на выход iFirstDate=iTerminalFirstDate;//Время начала данных терминала - на выход {if(iPrintDebug){Print(__FUNCTION__,"() Error (-13) >> Данные терминала НЕ получены за ",iFailCntTerminalFirstDateMax," попыток !");}} return(-13);//iFailCntTerminalFirstDate error }}//if(iFailCntTerminalFirstDate<=0) /*B*/ }}//if(iTerminalFirstDate>0) /*A*/}}//while( (iFailCntTerminalFirstDate>=1) && (!IsStopped()) //Коды возврата // -101 Завершение по IsStopped() // -100 Завершение по исчерпанию счетчика TerminalFirstDate ??? return(-100); }//Load_History2() //