5190 lines
No EOL
580 KiB
MQL5
5190 lines
No EOL
580 KiB
MQL5
//======================================================================================================
|
|
// 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)<iB4BCloseLim*AccountInfoDouble(ACCOUNT_BALANCE)) {return(true);}//Порог от Equity для инициации закрытия
|
|
while (BePair==true)
|
|
{
|
|
closeLot=0;
|
|
closeProfit=0;
|
|
lossLotBUY=0;
|
|
lossLotSELL=0;
|
|
profitLotBUY=0;
|
|
profitLotSELL=0;
|
|
lossBUY=99999;
|
|
lossSELL=99999;
|
|
profitBUY=-99999;
|
|
profitSELL=-99999;
|
|
nMLossBUY=-1;
|
|
nMLossSELL=-1;
|
|
nMProfitBUY=-1;
|
|
nMProfitSELL=-1;
|
|
{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);
|
|
{if((OrderMagicN<iMagic)||(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)<lossBUY)
|
|
{
|
|
nMLossBUY=Ord_Tick;
|
|
lossBUY=PositionGetDouble(POSITION_PROFIT)
|
|
//+PositionGetDouble(POSITION_COMISSION)
|
|
+PositionGetDouble(POSITION_SWAP)-10*AddComPrice*PositionGetDouble(POSITION_VOLUME);
|
|
lossLotBUY=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)<lossSELL)
|
|
{
|
|
nMLossSELL=Ord_Tick;
|
|
lossSELL=PositionGetDouble(POSITION_PROFIT)
|
|
//+PositionGetDouble(POSITION_COMISSION)
|
|
+PositionGetDouble(POSITION_SWAP)-10*AddComPrice*PositionGetDouble(POSITION_VOLUME);
|
|
lossLotSELL=PositionGetDouble(POSITION_VOLUME);
|
|
}//if(OrderProfit
|
|
}//if ((OP_TYPE)PositionGetInteger(POSITION_TYPE)
|
|
}//if(OrderProfit
|
|
}}//for(int y=PositionsTotal()-1;y>=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)<nnBars+5)
|
|
{
|
|
iBonceStopUp = true; //запрет вверх
|
|
iBonceStopDown = true; //запрет вниз
|
|
return(true);
|
|
}}//if(Bars(TheSymbol,PERIOD_M1)<nnBars+5)
|
|
//----- Параметры ограничения по броскам вынес в параметры
|
|
double BonceMax=0;//
|
|
double BonceMin=Max_Int;//
|
|
double BonceMax2=0;//
|
|
double BonceMin2=Max_Int;//
|
|
double BonceMax3=0;//
|
|
double BonceMin3=Max_Int;//
|
|
int nBonceMax=0;
|
|
int nBonceMin=0;
|
|
int nBonceMax2=0;
|
|
int nBonceMin2=0;
|
|
int nBonceMax3=0;
|
|
int nBonceMin3=0;
|
|
iBonceStopUp=false;//Признак остановки по броску сбрасываем
|
|
iBonceStopDown=false;//Признак остановки по броску сбрасываем
|
|
{for(int nCurBar=0; nCurBar<=nnBars-1; nCurBar++)//Перебираем на глубину просмотра в барах М1 (минутах)
|
|
{
|
|
//Проверка на отсутствие броска
|
|
{if(nCurBar<BonceDeep)//Если глубина просмотра для определения броска не превышена
|
|
//Тут всё переделать именно на односторонний бросок - сейчас блокируются любые колебания превышенные по амплитуде
|
|
{
|
|
//Запоминаем минимаксы
|
|
{if(High[nCurBar]>BonceMax)
|
|
{
|
|
BonceMax=High[nCurBar];
|
|
nBonceMax=nCurBar;
|
|
}}//if(High[nCurBar]>BonceMax)
|
|
{if(Low[nCurBar]<BonceMin)
|
|
{
|
|
BonceMin=Low[nCurBar];
|
|
nBonceMin=nCurBar;
|
|
}}//if(Low[nCurBar]<BonceMin)
|
|
//Оцениваем амплитуду броска
|
|
{if((BonceMax-BonceMin>BonceAmpMax*_Point)&&(nBonceMax>BonceMin))
|
|
{
|
|
iBonceStopDown=true;
|
|
//break;//Амплитуда броска превышена - прекращаем расчет канала
|
|
}}//if(BonceMax-BonceMin>BunceAmpMax)
|
|
{if((BonceMax-BonceMin>BonceAmpMax*_Point)&&(nBonceMax<BonceMin))
|
|
{
|
|
iBonceStopUp=true;
|
|
//break;//Амплитуда броска превышена - прекращаем расчет канала
|
|
}}//if(BonceMax-BonceMin>BunceAmpMax)
|
|
}}//if(nCurBar<BonceDeep)
|
|
{if(nCurBar<BonceDeep2)//Если глубина просмотра для определения броска не превышена
|
|
//Тут всё переделать именно на односторонний бросок - сейчас блокируются любые колебания превышенные по амплитуде
|
|
{
|
|
//Запоминаем минимаксы
|
|
{if(High[nCurBar]>BonceMax2)
|
|
{
|
|
BonceMax2=High[nCurBar];
|
|
nBonceMax2=nCurBar;
|
|
}}//if(High[nCurBar]>BonceMax)
|
|
{if(Low[nCurBar]<BonceMin2)
|
|
{
|
|
BonceMin2=Low[nCurBar];
|
|
nBonceMin2=nCurBar;
|
|
}}//if(Low[nCurBar]<BonceMin)
|
|
//Оцениваем амплитуду броска
|
|
{if((BonceMax2-BonceMin2>BonceAmpMax2*_Point)&&(nBonceMax2>BonceMin2))
|
|
{
|
|
iBonceStopDown=true;
|
|
//break;//Амплитуда броска превышена - прекращаем расчет канала
|
|
}}//if(BonceMax-BonceMin>BunceAmpMax)
|
|
{if((BonceMax2-BonceMin2>BonceAmpMax2*_Point)&&(nBonceMax2<BonceMin2))
|
|
{
|
|
iBonceStopUp=true;
|
|
//break;//Амплитуда броска превышена - прекращаем расчет канала
|
|
}}//if(BonceMax-BonceMin>BunceAmpMax)
|
|
}}//if(nCurBar<BonceDeep2)
|
|
{if(nCurBar<BonceDeep3)//Если глубина просмотра для определения броска не превышена
|
|
//Тут всё переделать именно на односторонний бросок - сейчас блокируются любые колебания превышенные по амплитуде
|
|
{
|
|
//Запоминаем минимаксы
|
|
{if(High[nCurBar]>BonceMax3)
|
|
{
|
|
BonceMax3=High[nCurBar];
|
|
nBonceMax3=nCurBar;
|
|
}}//if(High[nCurBar]>BonceMax)
|
|
if(nCurBar>=ArraySize(Low))Print(" ArraySize=",ArraySize(Low)," nCurBar=",nCurBar);
|
|
{if(Low[nCurBar]<BonceMin3)
|
|
{
|
|
BonceMin3=Low[nCurBar];
|
|
nBonceMin3=nCurBar;
|
|
}}//if(Low[nCurBar]<BonceMin)
|
|
//Оцениваем амплитуду броска
|
|
{if((BonceMax3-BonceMin3>BonceAmpMax3*_Point)&&(nBonceMax3>BonceMin3))
|
|
{
|
|
iBonceStopDown=true;
|
|
//break;//Амплитуда броска превышена - прекращаем расчет канала
|
|
}}//if(BonceMax-BonceMin>BunceAmpMax)
|
|
{if((BonceMax3-BonceMin3>BonceAmpMax*_Point)&&(nBonceMax3<BonceMin3))
|
|
{
|
|
iBonceStopUp=true;
|
|
//break;//Амплитуда броска превышена - прекращаем расчет канала
|
|
}}//if(BonceMax-BonceMin>BunceAmpMax)
|
|
}}//if(nCurBar<BonceDeep3)
|
|
}}//for(int nCurBar=isBars; nCurBar<=nnBars-1; nCurBar++)
|
|
return(iBonceStopUp||iBonceStopDown);
|
|
}//CheckBounceStop()
|
|
//
|
|
//======================================================================================================
|
|
// CalcSRLevels2() - расчет уровней поддержки - сопротивления
|
|
// Вход:
|
|
// inBars - глубина просмотра в барах М1 (минутах)
|
|
// isBars - стартовая глубина просмотра в барах М1 (минутах)
|
|
// inSRLevels - количество анализируемых микроуровней поддержки (сопротивления)
|
|
// inLevelsIn - количество микроуровней поддержки (сопротивления) в интервале
|
|
// inLevelsStep - шаг по анализируемым микроуровням поддержки (сопротивления)
|
|
// inStAnaliseSR - Start Numbers of Analise Levels граница анализа по цене, отступ от цены (в количестве интервалов)
|
|
// Выход:
|
|
// iChan - признак наличия канала
|
|
// iRLevel - граница канала сверху (сопротивление)
|
|
// iSLevel - граница канала снизу (поддержка)
|
|
// Примечание: реализован примитивный способ расчета пучков плотности ордеров. Надо бы переработать.
|
|
// Например строить поперечный разрез с накоплением плотности от центра и определять максимум.
|
|
// Или делать два (три) прохода со смешением границ на полинтервала (третьинтервала).
|
|
// Открытым остается так же вопрос по какой границе (центру) пучка устанавливать границу канала.
|
|
//======================================================================================================
|
|
bool CalcSRLevels2( int inBars, //глубина просмотра в барах М1 (минутах)
|
|
int isBars, //стартовая глубина просмотра в барах М1 (минутах)
|
|
int inSRLevels, //количество анализируемых микроуровней поддержки (сопротивления)
|
|
int inLevelsIn, //количество микроуровней поддержки (сопротивления) в интервале
|
|
int inLevelsStep, //шаг по анализируемым микроуровням поддержки (сопротивления)
|
|
int inStAnaliseSR, //Start Numbers of Analise Levels граница анализа по цене, отступ от цены (в количестве интервалов)
|
|
bool &iChan, //признак наличия канала
|
|
double &iSLevel, //граница канала сверху (сопротивление)
|
|
double &iRLevel){ //граница канала снизу (поддержка)
|
|
double
|
|
HiBid1,
|
|
LoBid1,
|
|
HiAsk1,
|
|
LoAsk1,
|
|
HiBid2,
|
|
LoBid2,
|
|
HiAsk2,
|
|
LoAsk2,
|
|
Mid3Bid1,
|
|
Mid3Bid2,
|
|
Mid3Ask1,
|
|
Mid3Ask2;
|
|
int
|
|
nnBars;//Глубина просмотра в барах М1 (минутах)
|
|
double
|
|
iSLevelOld=iSLevel,
|
|
iRLevelOld=iRLevel;
|
|
bool
|
|
iFoundS=false,
|
|
iFoundR=false;
|
|
//----- Ограничение при недостатке баров
|
|
//Тут надо бы разобраться поподробнее
|
|
{if(Bars(TheSymbol,PERIOD_M1)<50)
|
|
{
|
|
return(false);
|
|
//Print("Bars<50");
|
|
}}//if(Bars<50)
|
|
{if(Bars(TheSymbol,PERIOD_M1)<inBars+50)
|
|
{
|
|
nnBars=Bars(TheSymbol,PERIOD_M1)-50;
|
|
//Print("Bars<inBars+50");
|
|
}else{
|
|
nnBars=inBars;
|
|
}}//if(Bars<nBars+50)
|
|
//Print("nnBars=",nnBars);
|
|
//if(nnBars+2>=ArraySize(Low))Print("CalcSRLevels2.0 >> 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]<LoAsk2]) // и по лоу
|
|
)
|
|
{//Запомним найденный (микро)уровень
|
|
{if(HiAsk1>MaxHi){MaxHi=HiAsk1;}} //Новый максимум дальше в прошлом для поиска следующих (микро)уровней
|
|
r[nHi]=HiAsk1; //Значение (микро)уровня сопротивления
|
|
rt[nHi]=nCurBar+1; //Время возникновения (микро)уровня
|
|
nHi++; //Увеличение счетчика найденных (микро)уровней
|
|
//Тут увеличиваем счетчики всех групп, куда попал уровень
|
|
double nAnaliseSR_Point=nAnaliseSR*_Point;
|
|
{for(nrP=0;nrP<inSRLevels/inLevelsStep;nrP++)//перебираем группы по номерам
|
|
{
|
|
//Проверяем попадание уровня в группу
|
|
LowLim=gAsk+(inLevelsIn+nrP*inLevelsStep)*_Point;//Нижняя граница n-й группы: (Ask + inLevelsIn*point + n * inLevelsStep*point)
|
|
HiLim=LowLim+nAnaliseSR_Point;//Верхняя (дальняя) граница, ширина (nAnaliseSR*point)
|
|
rL[nrP]=HiLim; //Верхний (дальний) уровень группы
|
|
{if((HiAsk1>=LowLim)&&(HiAsk1<HiLim))
|
|
{
|
|
rP[nrP]++; //Наращиваем если в группе
|
|
{if(rP[nrP]>=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<HiLim))
|
|
}}//for(nrP=0;nrP<inSRLevels/inLevelsStep;nrP++)
|
|
}}//if(
|
|
//Support
|
|
{if(//Проверка наличия (микро)уровня
|
|
(LoBid1<gBid) //Учитываем, что лоу определён по биду //???и рассчитываем за спредом внизу
|
|
&&(nLow<=inSRLevels-1) //Количество уровней поддержки не превышено
|
|
&&(LoBid1<=MinLow+dLevel*_Point) //dLevel - глубина заглядывания
|
|
&&(LoBid1<=LoBid2) //Это впадина (локальный минимум) по Лоу далее подъём (или равно)
|
|
//&&(HiBid2>=HiBid1)
|
|
&&(Mid3Bid1<=Mid3Bid2) //Это впадина (локальный минимум) по Среднему далее подъём (или равно)
|
|
//&&(LoBid3>=LoBid2)
|
|
//&&(Hi3Bid>Hi2Bid)
|
|
)
|
|
{
|
|
{if(LoBid1<MinLow){MinLow=LoBid1;}} //Новый минимум дальше в прошлом для поиска следующих (микро)уровней
|
|
s[nLow]=LoBid1; //Значение микроуровня
|
|
st[nLow]=nCurBar-1; //Время микроуровня
|
|
nLow++; //Количество обнаруженных микроуровней
|
|
//Тут увеличить счетчики всех групп, куда попал уровень
|
|
double nAnaliseSR_Point=nAnaliseSR*_Point;
|
|
{for(nsP=0;nsP<inSRLevels/inLevelsStep;nsP++)//перебираем группы по номерам
|
|
{
|
|
HiLim=gBid-(inLevelsIn-nsP*inLevelsStep)*_Point;//Верхняя граница n-й группы: (Бид - Минимальное число уровней - НомерГруппы*ШагГрупп*point)
|
|
LowLim=HiLim-nAnaliseSR_Point;//ширина (nAnaliseSR*point) число пунктов в интервале цены для сборки уровней
|
|
sL[nsP]=LowLim; //Нижний уровень группы
|
|
{if((LoBid1>LowLim)&&(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<LoCurr)&&(LoCurr<=HiLim))
|
|
}}//for(nsP=0;nsP<inSRLevels/inLevelsStep;nsP++)
|
|
}}//if(
|
|
}}//for(int nCurBar=isBars; nCurBar<=nnBars-1; nCurBar++)
|
|
//Print("MaxrP=",MaxrP,"MaxsP=",MaxsP);
|
|
//{if((iRLevel>=0.75*iRmax)||(iSLevel<=1.25*iRmin))//Если или не найден один из уровней (то взять предидущий? или бидаск?)
|
|
//{
|
|
// //iRLevel=iRmax;
|
|
// //iSLevel=iRmin;
|
|
// iChan=false;
|
|
//}}//if((iRLevel==iRmax)||(iSLevel==0.0))
|
|
{if((!iFoundS)&&(!iFoundR))//Если не найдены оба из уровней, то взять предидущие и нет канала
|
|
{
|
|
iSLevel=iSLevelOld;
|
|
iRLevel=iRLevelOld;
|
|
iChan=false;
|
|
}}//if((iRLevel==iRmax)||(iSLevel==0.0))
|
|
{if((!iFoundS)&&(iFoundR))//Если не найден один из уровней, то взять предидущий и есть канал
|
|
{
|
|
iSLevel=iSLevelOld;
|
|
}}//if((iRLevel==iRmax)||(iSLevel==0.0))
|
|
{if((!iFoundR)&&(iFoundS))//Если не найден один из уровней, то взять предидущий и есть канал
|
|
{
|
|
iRLevel=iRLevelOld;
|
|
}}//if((iRLevel==iRmax)||(iSLevel==0.0))
|
|
{if((rt[inLevelsIn+1]==0)||(MaxNRP<inStAnaliseSR))//Если (inLevelsIn+1)-й уровень по R не устанавливался ИЛИ номер группы меньше начальной
|
|
{
|
|
iRLevel=iRLevelOld;
|
|
}}//if(rt[inSRLevels-1]==0)
|
|
{if((st[inLevelsIn+1]==0)||(MaxNSP<inStAnaliseSR))//Если (inLevelsIn+1)-й уровень по S не устанавливался ИЛИ номер группы меньше начальной
|
|
{
|
|
iSLevel=iSLevelOld;
|
|
}}//if(rt[inSRLevels-1]==0)
|
|
{if(((rt[inLevelsIn+1]==0)||(MaxNRP<inStAnaliseSR))//Если (inLevelsIn+1)-й уровень по R не устанавливался ИЛИ номер группы меньше начальной
|
|
&&((st[inLevelsIn+1]==0)||(MaxNSP<inStAnaliseSR)))//Если (inLevelsIn+1)-й уровень по S не устанавливался ИЛИ номер группы меньше начальной
|
|
{
|
|
iSLevel=iSLevelOld;
|
|
iRLevel=iRLevelOld;
|
|
iChan=false;
|
|
}}//if(rt[inSRLevels-1]==0)
|
|
{if((iRLevel-iSLevel<nSpreadToChan*(gAsk-gBid)))//Если ширина канала меньше допустимой по спреду
|
|
{
|
|
iChan=false;
|
|
}}//if(rt[inSRLevels-1]==0)
|
|
{if(gBid>iRLevel+_Point)//Если превышение gBid
|
|
{
|
|
iRLevel=gBid;
|
|
}}//if(rt[inSRLevels-1]==0)
|
|
{if(gAsk<iSLevel-_Point)//Если превышение gAsk
|
|
{
|
|
iSLevel=gAsk;
|
|
}}//if(rt[inSRLevels-1]==0)
|
|
//{if(exMAOn)//Убрано - не работает
|
|
//{
|
|
// ima_o1=iMA(NULL,0,exMAPeriod,0,MODE_LWMA,PRICE_TYPICAL,0);
|
|
// {if((iRLevel<=ima_o1)||(iSLevel>=ima_o1+dSpread))//Если или не найден один из уровней (то взять предидущий? или бидаск?)
|
|
// {
|
|
// //iRLevel=iRmax;
|
|
// //iSLevel=iRmin;
|
|
// iChan=false;
|
|
// }}//if(rt[inSRLevels-1]==0)
|
|
//}}//if(exIMAOn)
|
|
//---- Object Move in Chart
|
|
{if(ViewSRmLevelsOn)
|
|
{
|
|
//Resistense
|
|
{for(int i=0; i<=inSRLevels-1; i++)//Перебор уровней сопротивления
|
|
{
|
|
{if(i<=(nHi-1))
|
|
{//Установить найденые уровни
|
|
//{if(i<=2)
|
|
//{
|
|
// //Print("Bars=",Bars," rt[i]=",rt[i]);
|
|
// ObjectMove("RES-"+IntegerToString(i),0,Time[rt[i]+5],r[i]);
|
|
// ObjectMove("RES-"+IntegerToString(i),1,Time[0]+0*Period(),r[i]-0*_Point);//Метим на удаленную точку, чтоб установить наклон
|
|
//}else{
|
|
// ObjectMove("RES-"+IntegerToString(i),0,Time[rt[i]+3],r[i]);
|
|
// ObjectMove("RES-"+IntegerToString(i),1,Time[0]+0*Period(),r[i]-0*_Point);
|
|
//}}//if(i==0)
|
|
{if(i<=2)
|
|
{
|
|
//Print("Bars=",Bars," rt[i]=",rt[i]);
|
|
ObjectMove(0,"RES-"+IntegerToString(i),0,Time[rt[i]+5],r[i]-gSpread);
|
|
ObjectMove(0,"RES-"+IntegerToString(i),1,Time[0]+0*Period(),r[i]-gSpread-0*_Point);//Метим на удаленную точку, чтоб установить наклон
|
|
}else{
|
|
ObjectMove(0,"RES-"+IntegerToString(i),0,Time[rt[i]+3],r[i]-gSpread);
|
|
ObjectMove(0,"RES-"+IntegerToString(i),1,Time[0]+0*Period(),r[i]-gSpread-0*_Point);
|
|
}}//if(i==0)
|
|
}else{//Не найденые уровни - убрать на край
|
|
ObjectMove(0,"RES-"+IntegerToString(i),0,Time[1],Max_Int);
|
|
ObjectMove(0,"RES-"+IntegerToString(i),1,Time[0],Max_Int);
|
|
}}//if(i<=(nHi-1))
|
|
}}//for(i=0; i<=nnSRLevels-1; i++)
|
|
//Support - всегда рисуем по Биду
|
|
{for(int i=0; i<=inSRLevels-1; i++)//Перебор уровней поддержки
|
|
{
|
|
{if(i<=(nLow-1))
|
|
{//Установить найденые уровни
|
|
{if(i<=2)
|
|
{
|
|
ObjectMove(0,"SUP-"+IntegerToString(i),0,Time[st[i]+5],s[i]);
|
|
ObjectMove(0,"SUP-"+IntegerToString(i),1,Time[0]+0*Period(),s[i]+0*_Point);
|
|
}else{
|
|
ObjectMove(0,"SUP-"+IntegerToString(i),0,Time[st[i]+3],s[i]);
|
|
ObjectMove(0,"SUP-"+IntegerToString(i),1,Time[0]+0*Period(),s[i]+0*_Point);
|
|
}}//if(i==0)
|
|
}else{//Не найденые уровни - убрать на край
|
|
ObjectMove(0,"SUP-"+IntegerToString(i),0,Time[1],0);
|
|
ObjectMove(0,"SUP-"+IntegerToString(i),1,Time[0],0);
|
|
}}//if(i<=(nLow-1))
|
|
}}//for(i=0; i<=nnSRLevels-1; i++)
|
|
}}//if(ViewSRmLevelsOn)
|
|
//iChan=true;//по такому способу расчета канал есть всегда
|
|
return(true);
|
|
}//CalcSRLevels2()
|
|
//
|
|
//======================================================================================================
|
|
// GridCreate()
|
|
// iSizeOfLot - объём ордера, если 0 - авторасчет
|
|
//======================================================================================================
|
|
int GridCreate( string iSymbol,
|
|
bool &iReady,
|
|
OP_TYPE iType,
|
|
long iMagic,
|
|
double iSLevel,
|
|
double iRLevel,
|
|
double &iSizeOfLot,
|
|
double imAlligator,
|
|
bool imAlligator2Buy,
|
|
bool imAlligator2Sel){
|
|
int
|
|
m=(int)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;
|
|
//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<dS
|
|
//{if(nOpenPos1*(iRLevel-gAsk)<(gBid-iSLevel))//k*dR<dS
|
|
{
|
|
//Print("NewGrid>> nOpenPos1=",nOpenPos1," k*dR<dS=",(nOpenPos1*(iRLevel-gAsk)<(gBid-iSLevel)));
|
|
{if(!GridCreate)
|
|
{
|
|
iSizeOfLot=((iSizeOfLot>0.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 - сторона убытка???
|
|
||(gBid<Grid[m].LastLevelSell-dGridOpenProfit*_Point)//Ниже предидущей сетки Sell - сторона прибыли???
|
|
)
|
|
//1. Учесть тиковые МА (пока без передачи параметров)
|
|
&&(//Тиковый МА
|
|
(!TickMA)||//Выключатель фильтра
|
|
((true)
|
|
&&(ima_fast_main[0]<ima_slow_main[0]-p000*_Point)
|
|
&&(ima_fast_main[0]<ima_fast_main[1])
|
|
//&&((ima_slow_main[1]-ima_fast_main[1])<(ima_slow_main[0]-ima_fast_main[0]))
|
|
)
|
|
)
|
|
&&(//Прямые
|
|
((DirectOn)&&
|
|
((true)
|
|
|
|
//Тиковый длинный МА1
|
|
&&(
|
|
(!TickDirectMA)||//Выключатель фильтра
|
|
(
|
|
(ima_fast_dir[0]<ima_slow_dir[0]-p001*_Point)
|
|
&&(ima_fast_dir[0]<ima_fast_dir[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[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(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((iClose2<iClose1)&&(iClose1<iClose0)&&(true))
|
|
//{if((iClose2<iClose1)&&(true))
|
|
{if( (iType==OP_BUY)
|
|
&& (!iStopUp)//Ограничение по броску в противоположную сторону (если бросок вниз, то StopUp - не покупать)
|
|
&& ((imAlligator>0.0)||(!exMAOn))
|
|
&& ((!HedgeFilterOn)||(CalcVolumeHedge(TheSymbol)<=exHedgeLimit))
|
|
)
|
|
{
|
|
Order_Info=0;//Неопределено
|
|
{if(inBounceDn)
|
|
{
|
|
//Print("NewGrid>> nOpenPos1=",nOpenPos1," k*dS<dR=",(nOpenPos1*(gBid-iSLevel)<(iRLevel-gAsk)));
|
|
{if(!GridCreate)
|
|
{
|
|
iSizeOfLot=((iSizeOfLot>0.0)?(iSizeOfLot):(CalcLotSize2(TheSymbol,OP_BUY,exCalcLotMode,OrderNumInGrid,iMagic,1)));
|
|
{if(iSizeOfLot>0.0)
|
|
{
|
|
{if((LongEnable)
|
|
&&( (!exMAOn2) //без аллигатора
|
|
|| ((exMAOn2)&&(!Mode2Create)&&(Mode2Cont)) //с аллигатором, но аллигатор отключен для создания, включен для продолжения
|
|
|| ((exMAOn2)&&(Mode2Create)&&(imAlligator2Buy))//с аллигатором, включено для создания, сработало для покупки
|
|
)
|
|
&&((gAsk<Grid[m].LastLevelBuy+dGridOpenLoss*_Point)//Ниже последнего открытого ордера предидущей сетки Buy - сторона убытка???
|
|
||(gAsk>Grid[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]<ima_slow_reb_a[0]-p102*_Point)
|
|
&&(ima_fast_reb_a[0]<ima_fast_reb_a[1])
|
|
//&&((ima_fast_o21[1]-ima_slow_main[1])<(ima_fast_o21[0]-ima_slow_main[0]))
|
|
))
|
|
)//(ReboundOn)&&
|
|
)//(true)
|
|
||
|
|
(
|
|
(!DirectOn)&&(!ReboundOn)//Режимы пробой - отбой отключены оба
|
|
)
|
|
)//Прямые и отскоки
|
|
//2. Учесть запрет на близкие открытия при убытке (тоже пока примитивно)
|
|
//Если в целом инструмент (или сетка) в убытке, то открываться не ближе mDistOpenOrd в сторону убытка
|
|
&&(
|
|
(CalcPositionProfitSum1(TheSymbol,OP_BUY,MagicNumber,nGrides)>=0.0)
|
|
||
|
|
(
|
|
(CalcPositionProfitSum1(TheSymbol,OP_BUY,MagicNumber,nGrides)<0.0)
|
|
&&(gAsk<CalcSymMidPrice(TheSymbol,OP_BUY,MagicNumber,nGrides,iSum,iVol)-mDistOpenGrid*_Point)//Не влияет!!!
|
|
//&&(gAsk<Grid[m].LastLevelBuy-mDistOpenOrd*_Point)
|
|
)
|
|
)
|
|
)//(LongEnable)&&((imAlligator2>=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*dS<dR
|
|
// {
|
|
// {if(!GridCreate)
|
|
// {
|
|
// iSizeOfLot=CalcLotSize(OP_SELL,exCalcLotMode,OrderNumInGrid,iMagic);
|
|
// {if(iSizeOfLot>0.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((iClose2<iClose1)&&(iClose1<iClose0)&&(true))
|
|
// //{if((iClose2<iClose1)&&(true))
|
|
// {if(((nOpenPos2*(iRLevel-gAsk)<(gBid-iSLevel)))&&(iType==OP_BUY))
|
|
// {
|
|
// {if(!GridCreate)
|
|
// {
|
|
// iSizeOfLot=CalcLotSize(OP_BUY,exCalcLotMode,OrderNumInGrid,iMagic);
|
|
// {if(iSizeOfLot>0.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)&&(iClose2<iClose1))
|
|
// }}//if((nOpenPos1*(rLevel-gAsk)<nOpenPos2*(gBid-sLevel)))
|
|
//}}//if((Mode2_SRL)&&(true))
|
|
{if(GridCreate)
|
|
{
|
|
//Grid[m].StopTime=datetime(TimeCurrent()-OffSetTimeBase+(int)60*(60*PosLifeTimeHours));//Librecoin добавил datatime
|
|
Grid[m].StopTime=datetime(TimeCurrent()+3600*PosLifeTimeHours+60*PosLifeTimeMinutes);//Librecoin добавил datatime
|
|
return(1);//Выход - новая сетка создана
|
|
}}//if(Order_Info>0)
|
|
}}//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_main[0]-p000*_Point)
|
|
&&(ima_fast_main[0]<ima_fast_main[1])
|
|
//&&((ima_slow_main[1]-ima_fast_main[1])<(ima_slow_main[0]-ima_fast_main[0]))
|
|
)
|
|
)
|
|
&&(//Прямые
|
|
((DirectOn)&&
|
|
((true)
|
|
//Тиковый длинный МА1
|
|
&&(
|
|
(!TickDirectMA)||//Выключатель фильтра
|
|
(
|
|
(ima_fast_dir[0]<ima_slow_dir[0]-p001*_Point)
|
|
&&(ima_fast_dir[0]<ima_fast_dir[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[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]<ima_slow_reb_a[0]-p102*_Point)
|
|
&&(ima_fast_reb_a[0]<ima_fast_reb_a[1])
|
|
//&&((ima_fast_o21[1]-ima_slow_main[1])<(ima_fast_o21[0]-ima_slow_main[0]))
|
|
))
|
|
)//(ReboundOn)&&
|
|
)//(true)
|
|
||
|
|
(
|
|
(!DirectOn)&&(!ReboundOn)//Режимы пробой - отбой отключены оба
|
|
)
|
|
)//Прямые и отскоки
|
|
//2. Учесть запрет на близкие открытия при убытке (тоже пока примитивно)
|
|
//Если в целом инструмент (или сетка) в убытке, то открываться не ближе mDistOpenOrd в сторону убытка
|
|
&&(
|
|
(CalcPositionProfitSum1(iSymbol,OP_BUY,iMagic,1)>0.0)
|
|
||
|
|
(
|
|
(CalcPositionProfitSum1(iSymbol,OP_BUY,iMagic,1)<=0.0)
|
|
&&(gAsk<CalcSymMidPrice(iSymbol,OP_BUY,iMagic,1,iSum,iVol)-mDistOpenOrd*_Point)
|
|
&&
|
|
(
|
|
(StLotsMode==0)//0/1 - MidPrice(2.08)/LastPrice(2.15)
|
|
||(gAsk<Grid[m].LastLevelBuy-mDistOpenOrd*_Point)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
{
|
|
//if(iType==OP_BUY){Print("1. iType==OP_BUY>>>"," 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)//Ask ниже цены более чем на MinVSL
|
|
{
|
|
idMin=idMin0+(iPosPrice-gAsk-idMin0-ipStartVSL)*iVSLStart;
|
|
//---iHighest
|
|
//ArraySetAsSeries(High,true);
|
|
CopyHigh(TheSymbol,PERIOD_CURRENT,0,MathMin(Bars(TheSymbol,PERIOD_CURRENT),iSLTuneInterval),High);
|
|
val_index=ArrayMaximum(High,0,MathMin(Bars(TheSymbol,PERIOD_CURRENT),iSLTuneInterval));
|
|
//---
|
|
iVirtualSL=MathMin3(iPosPrice-idMin0,gAsk+ipStartVSL+idMin,((val_index!=-1)?(High[val_index]+idMin0+gSpread):(iPosPrice-idMin0)));//VSL на ipStartVSL под ценой позиции
|
|
}else{//if(gAsk+idMin0+ipStartVSL>=iPosPrice)//WorkVSL не превышен
|
|
idMin=idMin0;//Сбросить idMin хотя он и так =0
|
|
iVirtualSL=0.0;//Сбросить VSL хотя он и так =0
|
|
}}//if(gAsk+idMin0+ipStartVSL<iPosPrice)
|
|
}}//if(iType==OP_BUY)
|
|
}else{//if(iOldVSL>0.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<iPosPrice)//Степ превышен
|
|
{
|
|
idMin=MathMax(idMin0,MathMax(idMin,idMin0+(iPosPrice-gAsk-idMin0-ipWorkVSL)*iVSLWrk));
|
|
//---iHighest
|
|
//ArraySetAsSeries(High,true);
|
|
CopyHigh(TheSymbol,PERIOD_CURRENT,0,MathMin(Bars(TheSymbol,PERIOD_CURRENT),iSLTuneInterval),High);
|
|
val_index=ArrayMaximum(High,0,MathMin(Bars(TheSymbol,PERIOD_CURRENT),iSLTuneInterval));
|
|
//---
|
|
iVirtualSL=MathMin3(iPosPrice-idMin0,MathMin(iVirtualSL,gAsk+ipWorkVSL+idMin),((val_index!=-1)?(High[val_index]+idMin0+gSpread):(iPosPrice-2*idMin0)));//VSL на ipWorkVSL выше бида
|
|
}else{//if(iAsk<=iPositionPrice+iStepVSL+iMinVSL)//Степ не превышен
|
|
idMin=MathMax(idMin0,MathMax(idMin,idMin0+(iPosPrice-gAsk-idMin0-ipStartVSL)*iVSLStart));
|
|
iVirtualSL=MathMin(iPosPrice-idMin0,MathMin(iVirtualSL,gAsk+ipStartVSL+idMin));//VSL на MinVSL под ценой позиции
|
|
}}//if(Bid<iPositionPrice-iStepVSL)
|
|
}}//if(iPositionType==POSITION_TYPE_BUY)
|
|
}}//if(iOldVSL<0.001)1
|
|
//-----
|
|
//Print("TrailingVSL1 OUT>>> 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(gBid<iPosPrice+_Point)
|
|
{
|
|
iVirtualSL=0;
|
|
}}//if(gBid<iPosPrice+_Point)
|
|
}}//if(gBid>iPositionPrice+iTrail_Start*_Point*VSLTrailMult)
|
|
}}//if(PositionIsBuy)
|
|
{if(iType==OP_SELL)
|
|
{
|
|
double iVSLDelta=(iPosPrice-gAsk-iVSLStep)*VSLTrailMult;
|
|
iVSLDelta=((iVSLDelta>0)?(iVSLDelta):(0.0));
|
|
{if(gAsk<iPosPrice-iVSLStart*VSLTrailMult)
|
|
{
|
|
{if(iVirtualSL>0)
|
|
{
|
|
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<iPosPrice-ipWorkVSL)//gAsk ниже цены более чем на WorkVSL
|
|
{
|
|
idMin=MathMax(idMin,((iPosPrice-gAsk)-ipWorkVSL)*VSLTrailMult);
|
|
//Print("TrailingVSL1 INTO>>> 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(gAsk<iPosPrice-ipWorkVSL)
|
|
}}//if(iType==OP_BUY)
|
|
}else{//if(iOldVSL>0.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<iPosPrice-ipWorkVSL)//Степ превышен
|
|
{
|
|
{if(gAsk<iPosPrice-ipWorkVSL-ipMinVSL-idMin)//Степ + min превышен
|
|
{
|
|
iVirtualSL=MathMin(iVirtualSL,gAsk+ipWorkVSL-(iPosPrice-gAsk-ipWorkVSL-ipMinVSL-idMin)*kVSL);//VSL на степ выше бида
|
|
//Print("iVirtualSL=",iVirtualSL," gAsk=",gAsk," iPosPrice=",iPosPrice," d=",((iPosPrice+ipWorkVSL+ipMinVSL+idMin)-gAsk));
|
|
}else{//if(gBid>=iPositionPrice-iStepVSL-iMinVSL)//Степ + min не превышен а степ превышен
|
|
idMin=MathMax(idMin,((iPosPrice-gAsk)-ipWorkVSL)*VSLTrailMult);
|
|
//Print("TrailingVSL1 INTO>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin);
|
|
iVirtualSL=MathMin(iVirtualSL,iPosPrice-ipMinVSL-idMin);//VSL на MinVSL под ценой позиции
|
|
}}//if(iBid<iPositionPrice-iStepVSL-iMinVSL)
|
|
}else{//if(iAsk<=iPositionPrice+iStepVSL+iMinVSL)//Степ не превышен
|
|
idMin=MathMax(idMin,((iPosPrice-gAsk)-ipWorkVSL)*VSLTrailMult);
|
|
//Print("TrailingVSL1 INTO>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin);
|
|
iVirtualSL=MathMin(iVirtualSL,iPosPrice-ipMinVSL-idMin);//VSL на MinVSL под ценой позиции
|
|
}}//if(gBid<iPositionPrice-iStepVSL)
|
|
}}//if(iPositionType==POSITION_TYPE_BUY)
|
|
}}//if(iOldVSL<0.001)
|
|
}else{//if(iPositionPrice<=0)//Нет цены позиции или типа
|
|
iVirtualSL=0.0;//Сбросить VSL
|
|
}}//if(iPosPrice>0)
|
|
//-----
|
|
//{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(gBid<iPosPrice+_Point)
|
|
// {
|
|
// iVirtualSL=0;
|
|
// }}//if(gBid<iPositionPrice+_Point)
|
|
// }}//if(gBid>iPositionPrice+iTrail_Start*_Point*dDig4Mult)
|
|
//}}//if(PositionIsBuy)
|
|
//{if(iType==OP_SELL)
|
|
//{
|
|
// {if(gAsk<iPosPrice-iTrail_Start*_Point*dDig4Mult)
|
|
// {
|
|
// {if(iVirtualSL>0)
|
|
// {
|
|
// 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<iPosPrice-ipWorkVSL)//gAsk ниже цены более чем на WorkVSL
|
|
{
|
|
idMin=MathMax(idMin,((iPosPrice+ipWorkVSL)-gAsk)*VSLTrailMult);
|
|
//Print("TrailingVSL2 INTO>>> 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(gAsk<iPosPrice-ipWorkVSL)
|
|
}}//if(iType==OP_BUY)
|
|
}else{//if(iOldVSL>0.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<iPosPrice-ipWorkVSL)//Степ превышен
|
|
{
|
|
{if(gAsk<iPosPrice-ipWorkVSL-ipMinVSL-idMin)//Степ + min превышен
|
|
{
|
|
iVirtualSL=MathMin(iVirtualSL,gAsk+ipWorkVSL-(((iPosPrice+ipWorkVSL+ipMinVSL+idMin)-gAsk)*kVSL));//VSL на степ выше бида
|
|
//Print("iVirtualSL=",iVirtualSL," gAsk=",gAsk," iPosPrice=",iPosPrice," d=",((iPosPrice+ipWorkVSL+ipMinVSL+idMin)-gAsk));
|
|
}else{//if(gBid>=iPositionPrice-iStepVSL-iMinVSL)//Степ + min не превышен а степ превышен
|
|
idMin=MathMax(idMin,((iPosPrice+ipWorkVSL)-gAsk)*VSLTrailMult);
|
|
//Print("TrailingVSL1 INTO>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin);
|
|
iVirtualSL=MathMin(iVirtualSL,iPosPrice-ipMinVSL-idMin);//VSL на MinVSL под ценой позиции
|
|
}}//if(iBid<iPositionPrice-iStepVSL-iMinVSL)
|
|
}else{//if(iAsk<=iPositionPrice+iStepVSL+iMinVSL)//Степ не превышен
|
|
idMin=MathMax(idMin,((iPosPrice+ipWorkVSL)-gAsk)*VSLTrailMult);
|
|
//Print("TrailingVSL1 INTO>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin);
|
|
iVirtualSL=MathMin(iVirtualSL,iPosPrice-ipMinVSL-idMin);//VSL на MinVSL под ценой позиции
|
|
}}//if(gBid<iPositionPrice-iStepVSL)
|
|
}}//if(iPositionType==POSITION_TYPE_BUY)
|
|
}}//if(iOldVSL<0.001)
|
|
}else{//if(iPositionPrice<=0)//Нет цены позиции или типа
|
|
iVirtualSL=0.0;//Сбросить VSL
|
|
}}//if(iPosPrice>0)
|
|
}}//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<iPosPrice-ipWorkVSL)//gAsk ниже цены более чем на WorkVSL
|
|
{
|
|
idMin=MathMax(idMin,((iPosPrice+ipWorkVSL)-gAsk)*VSLTrailMult);
|
|
//Print("TrailingVSL2 INTO>>> 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(gAsk<iPosPrice-ipWorkVSL)
|
|
}}//if(iType==OP_BUY)
|
|
}else{//if(iOldVSL>0.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<iPosPrice-ipWorkVSL)//Степ превышен
|
|
{
|
|
{if(gAsk<iPosPrice-ipWorkVSL-ipMinVSL-idMin)//Степ + min превышен
|
|
{
|
|
iVirtualSL=MathMin(iVirtualSL,gAsk+ipWorkVSL-(((iPosPrice+ipWorkVSL+ipMinVSL+idMin)-gAsk)*kVSL));//VSL на степ выше бида
|
|
//Print("iVirtualSL=",iVirtualSL," gAsk=",gAsk," iPosPrice=",iPosPrice," d=",((iPosPrice+ipWorkVSL+ipMinVSL+idMin)-gAsk));
|
|
}else{//if(gBid>=iPositionPrice-iStepVSL-iMinVSL)//Степ + min не превышен а степ превышен
|
|
idMin=MathMax(idMin,((iPosPrice+ipWorkVSL)-gAsk)*VSLTrailMult);
|
|
//Print("TrailingVSL1 INTO>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin);
|
|
iVirtualSL=MathMin(iVirtualSL,iPosPrice-ipMinVSL-idMin);//VSL на MinVSL под ценой позиции
|
|
}}//if(iBid<iPositionPrice-iStepVSL-iMinVSL)
|
|
}else{//if(iAsk<=iPositionPrice+iStepVSL+iMinVSL)//Степ не превышен
|
|
idMin=MathMax(idMin,((iPosPrice+ipWorkVSL)-gAsk)*VSLTrailMult);
|
|
//Print("TrailingVSL1 INTO>>> VirtualSL=",iVirtualSL," iType=",TypeToString(iType)," iPosPrice=",iPosPrice," idMin=",idMin);
|
|
iVirtualSL=MathMin(iVirtualSL,iPosPrice-ipMinVSL-idMin);//VSL на MinVSL под ценой позиции
|
|
}}//if(gBid<iPositionPrice-iStepVSL)
|
|
}}//if(iPositionType==POSITION_TYPE_BUY)
|
|
}}//if(iOldVSL<0.001)
|
|
}else{//if(iPositionPrice<=0)//Нет цены позиции или типа
|
|
iVirtualSL=0.0;//Сбросить VSL
|
|
}}//if(iPosPrice>0)
|
|
}}//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(gBid<iPosPrice+_Point)
|
|
// {
|
|
// iVirtualSL=0;
|
|
// }}//if(gBid<iPositionPrice+_Point)
|
|
// }}//if(gBid>iPositionPrice+iTrail_Start*_Point*dDig4Mult)
|
|
//}}//if(PositionIsBuy)
|
|
//{if(iType==OP_SELL)
|
|
//{
|
|
// {if(gAsk<iPosPrice-iTrail_Start*_Point*dDig4Mult)
|
|
// {
|
|
// {if(iVirtualSL>0)
|
|
// {
|
|
// 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<iPosPrice-iTrail_Start*_Point*dDig4Mult)//Если прибыль Меньше старта трала
|
|
// &&(gAsk<iPosPrice-SymbolInfoInteger(TheSymbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point))//И Меньше стоплевела
|
|
// {
|
|
// NewStopLoss=fNormalizeDouble(MathMin(gAsk+iTrail_Step*_Point*dDig4Mult,iPosPrice-_Point));
|
|
// {if(NewStopLoss<gAsk+SymbolInfoInteger(TheSymbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point)
|
|
// {//Меньше стоплевела - нельзя ставить можно только на стоплевел
|
|
// NewStopLoss=fNormalizeDouble(gAsk+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,Red);
|
|
// }}//
|
|
// }}//if ((OldStopLoss==0.0)||((OldStopLoss!=0.0)&&(NewStopLoss<OldStopLoss)))
|
|
// }}//if ((OP_TYPE)PositionGetInteger(POSITION_TYPE)==OP_SELL)
|
|
// Sleep(100);
|
|
// }}//for (int n=PositionsTotal()-1;n>=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<iVirtualSL+iSL2VSLSlip*_Point-SymbolInfoInteger(TheSymbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point)//
|
|
{
|
|
NewStopLoss=fNormalizeDouble(iVirtualSL+iSL2VSLSlip*_Point);
|
|
{if(NewStopLoss<gAsk+SymbolInfoInteger(TheSymbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point)
|
|
{//Меньше стоплевела - нельзя ставить можно только на стоплевел
|
|
NewStopLoss=fNormalizeDouble(gAsk+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 ((OldStopLoss==0.0)||((OldStopLoss!=0.0)&&(NewStopLoss<OldStopLoss)))
|
|
}}//if ((OP_TYPE)PositionGetInteger(POSITION_TYPE)==OP_SELL)
|
|
//Sleep(10);
|
|
}}//for (int n=PositionsTotal()-1;n>=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)||(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)||(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)<lossBUY)
|
|
// {
|
|
// nMLossBUY=Ord_Tick;
|
|
// lossBUY=PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_COMISSION)+PositionGetDouble(POSITION_SWAP)-10*AddCom*PositionGetDouble(POSITION_VOLUME);
|
|
// lossLotBUY=PositionGetDouble(POSITION_VOLUME);
|
|
// }}//if (PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_COMISSION)+PositionGetDouble(POSITION_SWAP)<lossBUY)
|
|
// }}//if ((OP_TYPE)PositionGetInteger(POSITION_TYPE)==OP_BUY)
|
|
// {//Для ордера на продажу
|
|
// if ((OP_TYPE)PositionGetInteger(POSITION_TYPE)==OP_SELL)
|
|
// {
|
|
// {//Если убыток больше (его значение меньше) ранее найденного по SELL
|
|
// if (PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_COMISSION)+PositionGetDouble(POSITION_SWAP)-10*AddCom*PositionGetDouble(POSITION_VOLUME)<lossSELL)
|
|
// {
|
|
// nMLossSELL=Ord_Tick;
|
|
// lossSELL=PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_COMISSION)+PositionGetDouble(POSITION_SWAP)-10*AddCom*PositionGetDouble(POSITION_VOLUME);
|
|
// lossLotSELL=PositionGetDouble(POSITION_VOLUME);
|
|
// }}//if (PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_COMISSION)+PositionGetDouble(POSITION_SWAP)<lossSELL)
|
|
// }}//if ((OP_TYPE)PositionGetInteger(POSITION_TYPE)==OP_SELL)
|
|
// }}//if (PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_COMISSION)+PositionGetDouble(POSITION_SWAP)<-0.0001)
|
|
// }}//for(int y=PositionsTotal()-1;y>=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)||(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)<MathAbs(profitDBUY))
|
|
// {
|
|
// nMProfitBUY=Ord_Tick;
|
|
// profitBUY=PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_COMISSION)+PositionGetDouble(POSITION_SWAP)-10*AddCom*PositionGetDouble(POSITION_VOLUME);
|
|
// profitLotBUY=PositionGetDouble(POSITION_VOLUME);
|
|
// profitDBUY=profitDBUYtmp;
|
|
// }}//if (MathAbs(profitDBUYtmp)<MathAbs(profitDBUY))
|
|
// }else{
|
|
// {//Если было найдено - в прибыль, и теперь в прибыль - то оценим
|
|
// if ((profitDBUY>0)&&(profitDBUYtmp>0))
|
|
// {
|
|
// {//Если значения ближе - запомним
|
|
// if (MathAbs(profitDBUYtmp)<MathAbs(profitDBUY))
|
|
// {
|
|
// nMProfitBUY=Ord_Tick;
|
|
// profitBUY=PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_COMISSION)+PositionGetDouble(POSITION_SWAP)-10*AddCom*PositionGetDouble(POSITION_VOLUME);
|
|
// profitLotBUY=PositionGetDouble(POSITION_VOLUME);
|
|
// profitDBUY=profitDBUYtmp;
|
|
// }}//if (MathAbs(profitDBUYtmp)<MathAbs(profitDBUY))
|
|
// }}//if ((profitDBUY>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)<MathAbs(profitDSELL))
|
|
// {
|
|
// nMProfitSELL=Ord_Tick;
|
|
// profitSELL=PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_COMISSION)+PositionGetDouble(POSITION_SWAP)-10*AddCom*PositionGetDouble(POSITION_VOLUME);
|
|
// profitLotSELL=PositionGetDouble(POSITION_VOLUME);
|
|
// profitDSELL=profitDSELLtmp;
|
|
// }}//if (MathAbs(profitDSELLtmp)<MathAbs(profitDSELL))
|
|
// }else{
|
|
// {//Если было найдено - в прибыль, и теперь в прибыль - то оценим
|
|
// if ((profitDSELL>0)&&(profitDSELLtmp>0))
|
|
// {
|
|
// {//Если значения ближе - запомним
|
|
// if (MathAbs(profitDSELLtmp)<MathAbs(profitDSELL))
|
|
// {
|
|
// nMProfitSELL=Ord_Tick;
|
|
// profitSELL=PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_COMISSION)+PositionGetDouble(POSITION_SWAP)-10*AddCom*PositionGetDouble(POSITION_VOLUME);
|
|
// profitLotSELL=PositionGetDouble(POSITION_VOLUME);
|
|
// profitDSELL=profitDSELLtmp;
|
|
// }}//if (MathAbs(profitDSELLtmp)<MathAbs(profitDSELLtmp))
|
|
// }}//if ((profitDSELL>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;j<nRetry;j++)
|
|
break;//switch (OrdType)
|
|
case OP_SELL:
|
|
{for (j=0;j<=nRetry-1;j++)
|
|
{
|
|
//RefreshRates();
|
|
{if(ShortEnable)
|
|
{
|
|
OrdInfo=(int)PositionOrderSend(TheSymbol,(ENUM_ORDER_TYPE)OP_SELL,Ord_Vol,gBid,OrdSlippage,PriceAddPoints(gAsk,+OrdStopLoss),PriceAddPoints(gBid,-OrdTakeProfit),OrdComment,OrdMagic,OrdExpir,rDeal);
|
|
}}//if(ShortEnable)
|
|
//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;j<nRetry;j++)
|
|
}}//switch (OrdType)
|
|
return(OrdInfo);
|
|
}//fOrderSend
|
|
//
|
|
//======================================================================================================
|
|
// fCloseBuySell() -
|
|
//======================================================================================================
|
|
int fCloseBuySell( string iSymbol,
|
|
bool bCloseBuy,
|
|
bool bCloseSell,
|
|
int iMagic,
|
|
double &iVirtualSL){
|
|
int
|
|
iResult=0;
|
|
ulong
|
|
Pos_Tick;
|
|
//-----
|
|
if(PositionsTotal()>0)
|
|
{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(iVirtualSL<iPosPrice)
|
|
{
|
|
{if(gBid>iPosPrice+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(iVirtualSL<iPosPrice)
|
|
}}//if(iVirtualSL>0.0)
|
|
}}//if(iType==OP_BUY)
|
|
{if(iType==OP_SELL)
|
|
{
|
|
{if(iVirtualSL>0.0)
|
|
{
|
|
{if(iVirtualSL>iPosPrice)
|
|
{
|
|
{if(gAsk<iPosPrice-MathMax(Comis,SymbolInfoInteger(iSymbol,SYMBOL_TRADE_STOPS_LEVEL))*_Point)
|
|
{
|
|
iVirtualSL=iPosPrice-MathMax(Comis,SymbolInfoInteger(iSymbol,SYMBOL_TRADE_STOPS_LEVEL))*_Point;
|
|
}else{
|
|
{if(gAsk>=iPosPrice-_Point)
|
|
{
|
|
//iVirtualSL=iPosPrice+_Point;
|
|
iVirtualSL=0.0;
|
|
}}//if(gAsk>=iPosPrice-_Point)
|
|
}}//if(gAsk<iPosPrice-_Point)
|
|
}}//if(iVirtualSL>iPosPrice)
|
|
}}//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(OrdStopLoss<iPosPrice)
|
|
{
|
|
{if(gBid>iPosPrice+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<iPosPrice-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(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<NextDayBegin)//не UTC
|
|
&&(
|
|
(
|
|
(
|
|
(iCurrencyN==Symbol_1)//Валюта новости есть в инструменте как валюта котирования
|
|
||
|
|
(iCurrencyN==Symbol_2)//Валюта новости есть в инструменте как базовая валюта
|
|
)
|
|
&&
|
|
(iVolatilityN>=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<NextDayBegin))
|
|
}}//while(!FileIsEnding(InFileHandle))
|
|
FileClose(InFileHandle);
|
|
{if(i>=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;j<iNEvents;j++)//
|
|
{
|
|
{if(Events[j].TimeN>TimeOldN)//Наступило новое время
|
|
{
|
|
//----- Обработка завершения предыдущего времени (Не забыть проделать то же на последнем активном элементе 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<iNEvents;j++)//
|
|
//{
|
|
// {if(Events[j].MaxVolBeN)
|
|
// {
|
|
// Events[j].CompositeStringN=TimeToString(Events[j].TimeN)+" "+VolatilityName[Events[j].VolatilityN]+" "+Events[j].CompositeStringN;
|
|
// //Print("CompositeStringN=",Events[j].CompositeStringN);
|
|
// }}//if(Events[j].MaxVolBeN)
|
|
//}}//for(int j=0;j<iNEvents;j++)
|
|
}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++)
|
|
}}//if(Done)
|
|
return(true);
|
|
}//ReadEventsToDay()
|
|
//
|
|
//======================================================================================================
|
|
// ReadEventsWeeks() - читаем из файла массив событий текущей недели, устанавливаем
|
|
// iLastReadDayBegin на начало текущего дня.
|
|
// Вход:
|
|
// iSymbol - фининструмент
|
|
// VolatLimit - минимальный уровень события
|
|
// iInvesting - использовать индексы от Investing.com
|
|
// iTimeCurrent - Текущее серверное время по последнему тику
|
|
// iOffsetTime - смещение времени (для телетрейд -3600 (UTC+2(+3)), остальные скачиваются UTC+3(+4))
|
|
// Выход:
|
|
// iLastReadDayBegin - время начала последней прочитанной недели (устанавливается на начало дня прочтения новостей)
|
|
// iEvents - массив событий недели
|
|
// iNEvents - количество событий недели
|
|
//======================================================================================================
|
|
bool ReadEventsWeeks( string iSymbol,
|
|
string iFileName,
|
|
int iVolatLimit,
|
|
bool iInvesting,
|
|
datetime iTimeCurrent, //Текущее серверное время по последнему тику
|
|
datetime iOffsetTime,
|
|
datetime &iLastReadWeekBegin,
|
|
News &iEvents[],
|
|
int &iNEvents,
|
|
bool iFileCommon)
|
|
{
|
|
string
|
|
StringBuff,
|
|
iCurrencyN,iEventN,iCountryN,
|
|
Symbol_1=StringSubstr(iSymbol,0,3),
|
|
Symbol_2=StringSubstr(iSymbol,3,3);
|
|
//{if(())Тут добавить обработку биржевых инструментов и разных фьючерсов
|
|
//{
|
|
//}}//
|
|
datetime
|
|
iTimeN;
|
|
int
|
|
iVolatilityN;
|
|
bool
|
|
Done=true;
|
|
//----- Рассчет границ недели - учесть оффсет? вроде не надо
|
|
datetime ThisWeekBegin=DateTimeWeekBegin(iTimeCurrent); //начало текущей недели в текущем серверном времени (UTC+2(+3))
|
|
datetime NextWeekBegin=ThisWeekBegin+8*24*60*60; //начало следующей недели в текущем серверном времени (UTC+2(+3))
|
|
//Print("ThisWeekBegin=",ThisWeekBegin," NextWeekBegin=",NextWeekBegin);
|
|
//-----
|
|
ResetLastError();
|
|
int InFileHandle=INVALID_HANDLE;
|
|
//Получение хендла файла новостей с учётом места расположения файла
|
|
{if(iFileCommon)
|
|
{
|
|
InFileHandle=FileOpen(iFileName,FILE_READ|FILE_TXT|FILE_ANSI|FILE_COMMON,';');
|
|
}else{
|
|
InFileHandle=FileOpen(iFileName,FILE_READ|FILE_TXT|FILE_ANSI,';');
|
|
}}//if(iFileCommon)
|
|
//Print("ReadEventsWeeks >>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<EventsListSize))//Пока не конец файла и массив не переполнен
|
|
{
|
|
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("ThisWeekBegin=",ThisWeekBegin," NextWeekBegin=",NextWeekBegin,
|
|
// " iTimeN=",iTimeN," iCurrencyN=",iCurrencyN," iVolatilityN=",iVolatilityN," iEventN=",iEventN);
|
|
//Корректировка по смещению. В файле всегда (UTC+2), что обычно совпадает зимой с серверным временем (на телетрейд-корректировка -3600 сек)
|
|
//летом серверное обычно (UTC+3). Например новость по (UTC+2) выходит в [2017.06.15 12:00] что хранится в файле.
|
|
//на сервере (UTC+3) в это время [2017.06.15 13:00] и если использовать время из файла, то выстрелим раньше на час.
|
|
//Поэтому ко времени новости в файле добавляем смещение (+1) летом северное полушарие.
|
|
iTimeN=iTimeN+iOffsetTime;
|
|
{if(
|
|
((iInvesting)||(StringFind(iEventN,"Investing.com")<0))//Выкусываем индексы от Investing.com к чертям собачьим
|
|
&&(iTimeN>=ThisWeekBegin)&&(iTimeN<NextWeekBegin)//Тут уже по скорректированному (серверному) времени
|
|
&&(
|
|
(
|
|
(
|
|
(iCurrencyN==Symbol_1)//Валюта новости есть в инструменте как валюта котирования
|
|
||
|
|
(iCurrencyN==Symbol_2)//Валюта новости есть в инструменте как базовая валюта
|
|
//тут можно добавить для биржи и всякого прочего
|
|
)
|
|
&&
|
|
(iVolatilityN>=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<NextDayBegin))
|
|
}}//while(!FileIsEnding(InFileHandle))
|
|
FileClose(InFileHandle);
|
|
{if(i>=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;j<iNEvents;j++)//Перебираем всё количество найденных событий
|
|
{
|
|
{if(Events[j].TimeN>TimeOldN)//Наступило новое время
|
|
{
|
|
//----- Обработка завершения предыдущего времени (Не забыть проделать то же на последнем активном элементе 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<EventsListSize;j++)
|
|
//Контрольный вывод
|
|
{for(int j=0;j<iNEvents;j++)//
|
|
{
|
|
{if(Events[j].MaxVolBeN)
|
|
{
|
|
Events[j].CompositeStringN=TimeToString(Events[j].TimeN)+" "+VolatilityName[Events[j].VolatilityN]+" "+Events[j].CompositeStringN;
|
|
//Print("CompositeStringN=",Events[j].CompositeStringN);
|
|
}}//if(Events[j].MaxVolBeN)
|
|
}}//for(int j=0;j<iNEvents;j++)
|
|
}else{
|
|
//Очистка списка событий
|
|
{for(int j=0;j<EventsListSize;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<EventsListSize;j++)
|
|
}}//if(Done)
|
|
return(true);
|
|
}//ReadEventsToDay()
|
|
//
|
|
//======================================================================================================
|
|
// mPositionClose2();//v66.112-v71.163.003 - закрытие ордера
|
|
// OrTic - тикет ордера
|
|
// OrSli - допустимое проскальзывание
|
|
// mRet - допустимое количество попыток закрытия
|
|
// comm - наименование инициатора закрытия для протокола
|
|
//======================================================================================================
|
|
int mPositionClose2( string iSymbol,
|
|
ulong OrTic,
|
|
int OrSli,
|
|
int mRet,
|
|
string comm){
|
|
bool
|
|
mRes=true;
|
|
int
|
|
mErr=-1; //за пределом кодов ошибок
|
|
ResetLastError();
|
|
{if(!PositionSelectByTicket(OrTic)) //Если невозможно выбрать позицию - сваливаем с кодом ошибки
|
|
{
|
|
mErr=GetLastError();
|
|
return(mErr);
|
|
}}//if (!Ord_inf)
|
|
{if(!CloseEnable)
|
|
{
|
|
{if(PrnClose){Print("#",OrTic,">> 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
|
|
<iframe src="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=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&
|
|
countries=25,32,6,37,72,22,17,39,14,10,35,43,56,36,110,11,26,12,4,5&
|
|
Список стран
|
|
(4-GBP|5-USD|6-CAD|7-MXN|9-SEK|10-ITL|11-KRW|12-CHF|14-INR|17-GER|21-NET|22-FRN|23-ILS|24-DKK|25-AUD|26-SPA|27-CLP|29-ARS|32-BRL|33-IRE|34-BEL|35-JPY|36-SGD|37-CNY|38-POR|39-HKD)
|
|
(41-THB|42-MYR|43-NZD|45-PHP|46-TWD|48-IDR|51-GRE|53-PLN|54-AUS|55-CZK|56-RUB|72-EUR|110-ZAR)
|
|
-->
|
|
<!-- Вид календаря (week/day - неделя/день) -->
|
|
<!-- Временная зона лето северное полушарие
|
|
(7 - GMT-5 Central Time USA)(8 - GMT-4 Eastern Time USA)
|
|
(14 - GMT+0 Азорские о-ва)(55 - GMT)(15 - GMT+1 Лондон)(16 - GMT+2 Амстердам)(17 - GMT+3 Иерусалим)(18 - GMT+3 Москва) -->
|
|
<!-- Язык (1-English|7-Russian) -->
|
|
calType=week&
|
|
timeZone=18&
|
|
lang=1"
|
|
width="610"
|
|
height="9999"
|
|
frameborder="0"
|
|
allowtransparency="true"
|
|
marginwidth="0"
|
|
marginheight="0">
|
|
</iframe>
|
|
*/
|
|
//---
|
|
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)
|
|
//// {
|
|
//// //<tr><td colspan="9" class="theDay" id="theDay1458864000">Friday, March 25, 2016</td></tr>
|
|
//// //<tr id="eventRowId_3"><td class="first left">All Day</td><td class="flagCur left"><span title="Australia" class="ceFlags Australia float_lang_base_1" data-img_key="Australia"></span></td><td class="left textNum sentiment"><span class="bold">Holiday</span></td><td colspan="6" class="left event">Australia - Good Friday</td></tr>
|
|
//// //<tr id="eventInfo325877" class="noHover displayNone"><td id="eventInfoTd325877" colspan="8" class="eventInfo"><div class="displayNone" id="eventDivWrapper325877"></div></td></tr>
|
|
//// //<tr id="eventRowId_325877" class="js-event-item" event_attr_id="1623" data-event-datetime="2016/03/24 18:00:00"><td class="first left time js-time" title="Event data was released 548h 57m ago">18:00</td><td class="left flagCur noWrap"><span title="France" class="ceFlags France" data-img_key="France"></span>EUR</td><td class="left textNum sentiment noWrap" title="Moderate Volatility Expected" data-img_key="bull2"><i class="grayFullBullishIcon"></i><i class="grayFullBullishIcon"></i><i class="grayEmptyBullishIcon"></i></td><td class="left event" title="Click to view more info on France Jobseekers Total"><a href="http://www.investing.com/economic-calendar/france-jobseekers-total-1623" target="_blank">France Jobseekers Total (Feb)</a></td><td class="bold act redFont event-325877-actual" title="Worse Than Expected" id="eventActual_325877">3,591.0K</td><td class="fore event-325877-forecast " id="eventForecast_325877">3,555.3K</td><td class="prev blackFont event-325877-previous" id="eventPrevious_325877">3,552.6K</td><td class="diamond" id="eventRevisedFrom_325877"></td></tr>
|
|
////
|
|
////
|
|
//// //<tr id="eventRowId_9"><td class="first left">All Day</td><td class="flagCur left"><span title="United States" class="ceFlags United_States float_lang_base_1" data-img_key="United_States"> </span></td><td class="left textNum sentiment"><span class="bold">Holiday</span></td><td colspan="6" class="left event">United States - New Year's Day</td></tr>
|
|
//// //<tr id="eventRowId_9"><td class="first left">All Day</td><td class="flagCur left"><span title="United Kingdom" class="ceFlags United_Kingdom float_lang_base_1" data-img_key="United_Kingdom"> </span></td> <td class="left textNum sentiment"><span class="bold">Holiday</span></td><td colspan="6" class="left event">United Kingdom - New Year's Day</td></tr>
|
|
//// //<tr id="eventRowId_320509" class="js-event-item" event_attr_id="594" data-event-datetime="2016/01/01 02:00:00"><td class="first left time js-time" title="Event data was released 2556h 43m ago">02:00</td><td class="left flagCur noWrap"><span title="China" class="ceFlags China" data-img_key="China"> </span> CNY</td><td class="left textNum sentiment noWrap" title="High Volatility Expected" data-img_key="bull3"><i class="grayFullBullishIcon"></i><i class="grayFullBullishIcon"></i><i class="grayFullBullishIcon"></i></td><td class="left event" title="Click to view more info on Manufacturing PMI"><a href="http://www.investing.com/economic-calendar/chinese-manufacturing-pmi-594" target="_blank"> Manufacturing PMI (Dec)</a></td><td class="bold act blackFont event-320509-actual" title="In Line with Expectation" id="eventActual_320509">49.7</td><td class="fore event-320509-forecast " id="eventForecast_320509">49.7</td><td class="prev blackFont event-320509-previous" id="eventPrevious_320509">49.6</td><td class="diamond" id="eventRevisedFrom_320509"> </td></tr>
|
|
//// //<tr id="eventRowId_320070" event_attr_id="1292" event_timestamp="2015-12-21 22:00:00"><td class="first left time">01:00</td><td class="left flagCur noWrap"><span title="Colombia" class="ceFlags Colombia" data-img_key="Colombia"> </span> COP</td> <td class="left textNum sentiment noWrap" title="Low Volatility Expected" data-img_key="bull1"><i class="grayFullBullishIcon"></i><i class="grayEmptyBullishIcon"></i><i class="grayEmptyBullishIcon"></i></td> <td class="left event" title="Click to view more info on Imports"><a href="http://www.investing.com/economic-calendar/colombian-imports-1292" target="_blank"> Imports (YoY) (Oct)</a> </td> <td class="bold act blackFont event-320070-actual" title="" id="eventActual_320070"> </td> <td class="fore event-320070-forecast " id="eventForecast_320070"> </td> <td class="prev blackFont event-320070-previous" id="eventPrevious_320070">-22.30%</td> <td class="diamond" id="eventRevisedFrom_320070"> </td> </tr> <tr id="eventInfo320070" class="noHover displayNone"> <td id="eventInfoTd320070" colspan="8" class="eventInfo"> <div class="displayNone" id="eventDivWrapper320070"></div> </td> </tr>
|
|
//// //<tr id="eventRowId_165"> <td class="first left">All Day</td> <td class="flagCur left"><span title="Bahrain" class="ceFlags Bahrain float_lang_base_1" data-img_key="Bahrain"> </span></td> <td class="left textNum sentiment"><span class="bold">Holiday</span></td> <td colspan="6" class="left event">Bahrain - Prophet's Birthday</td> </tr>
|
|
////
|
|
//// //Строка даты нового дня - заносим дату в глобал, для установки дат недатированных событий
|
|
////
|
|
//// //Print("iInpStr=",iInpStr);
|
|
////
|
|
//// string iTheDay="";
|
|
//// int posDay=StringFind(iInpStr,"<td colspan=\"8\" class=\"theDay\" id=\"theDay");
|
|
//// //int posDay=StringFind(iInpStr,"<td colspan=\"9\" class=\"theDay\" id=\"theDay");
|
|
//// {if((posDay>=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,"<tr>","</tr>");
|
|
//// //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,"<tr id=\"eventRowId_","\">");
|
|
//// //<td class="first left time js-time" title="Event data was released 548h 57m ago">18:00</td><td class="left flagCur noWrap"><span title="France" class="ceFlags France" data-img_key="France"></span>EUR</td><td class="left textNum sentiment noWrap" title="Moderate Volatility Expected" data-img_key="bull2"><i class="grayFullBullishIcon"></i><i class="g
|
|
//// iResult=TagDelete(iInpStr,"<td class=","</td>");
|
|
//// //<td class="left flagCur noWrap"><span title="France" class="ceFlags France" data-img_key="France"></span>EUR</td><td class="left textNum sentiment noWrap" title="Moderate Volatility Expected" data-img_key="bull2"><i class="grayFullBullishIcon"></i><i class="g
|
|
//// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,"<td"));
|
|
//// //<td class="left flagCur noWrap"><span title="France" class="ceFlags France" data-img_key="France"></span>EUR</td><td class="left textNum sentiment noWrap" title="Moderate Volatility Expected" data-img_key="bull2"><i class="grayFullBullishIcon"></i><i class="g
|
|
//// //----- Country
|
|
//// iResult=TagContent(iInpStr,"<span title=\"","\" class=\"",iCountry);
|
|
//// //----- Currency
|
|
//// iResult=TagContent(iInpStr,"</span>","</td>",iCouN);
|
|
//// iResult=TagDelete(iInpStr,"<td class=","</td>");
|
|
//// //<td class="left textNum sentiment noWrap" title="Moderate Volatility Expected" data-img_key="bull2"><i class="grayFullBullishIcon"></i><i class="g
|
|
//// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,"<td"));
|
|
//// //----- Impact
|
|
//// iResult=TagContent(iInpStr,"title=\"","\">",iVolatility);
|
|
//// //iResult=TagContent(iInpStr,"noWrap\" title=\"","\" data-img_key",iVolatility);
|
|
//// //----- Impact N
|
|
//// iImpN=StringSubstr(iImpactMN,StringFind(iImpactMN,iVolatility,1)-1,1);
|
|
//// iResult=TagDelete(iInpStr,"<td class=","</td>");
|
|
//// //<td class="left event" title="Click to view more info on France Jobseekers Total"><a href="http://www.investing.com/economic-calendar/france-jobseekers-total-1623" target="_blank">France Jobseekers Total (Feb)</a></td><td class="bold act redFont event-325877-actual" title="Worse Than Expected" id="eventActual_325877">3,591.0K</td><td class="fore event-325877-forecast " id="eventForecast_325877">3,555.3K</td><td class="prev blackFont event-325877-previous" id="eventPrevious_325877">3,552.6K</td><td class="diamond" id="eventRevisedFrom_325877"></td></tr>
|
|
//// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,"<td"));
|
|
//// //----- Тип события
|
|
//// iResult=TagDelete(iInpStr,"<span","</span>"); //Удаляем тип события
|
|
//// //----- Event
|
|
//// iResult=TagContent(iInpStr,"event\">","</td",iEvent);
|
|
//// //iResult=TagContent(iInpStr,"target=\"_blank\">","</a>",iEvent);
|
|
//// iResult=TagDelete(iInpStr,"<td class=","</td>"); //Удаляем событие
|
|
//// //<td class="bold act redFont event-325877-actual" title="Worse Than Expected" id="eventActual_325877">3,591.0K</td><td class="fore event-325877-forecast " id="eventForecast_325877">3,555.3K</td><td class="prev blackFont event-325877-previous" id="eventPrevious_325877">3,552.6K</td><td class="diamond" id="eventRevisedFrom_325877"></td></tr>
|
|
//// n=StringReplace(iEvent,"&","");
|
|
//// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,"<td"));
|
|
//// //----- Actual
|
|
//// iResult=TagContent(iInpStr,"id=\"eventActual_","/td>",iActual);
|
|
//// iResult=TagContent(iActual,"\">","<",iActual);
|
|
//// n=StringReplace(iActual," ","");
|
|
//// iResult=TagDelete(iInpStr,"<td class=","</td>"); //Удаляем тег с актуалом
|
|
//// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,"<td"));
|
|
//// //----- Forecast
|
|
//// iResult=TagContent(iInpStr,"id=\"eventForecast_","/td>",iForecast);
|
|
//// iResult=TagContent(iForecast,"\">","<",iForecast);
|
|
//// n=StringReplace(iForecast," ","");
|
|
//// iResult=TagDelete(iInpStr,"<td class=","</td>"); //Удаляем тег с прогнозом
|
|
//// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,"<td"));
|
|
//// //----- Previous &
|
|
//// iResult=TagContent(iInpStr,"id=\"eventPrevious_","/td>",iPrevious);
|
|
//// iResult=TagContent(iPrevious,"\">","<",iPrevious);
|
|
//// n=StringReplace(iPrevious," ","");
|
|
//// }else{//Если даты нет но возможно "All Day"
|
|
//// {if(TagContent(iInpStr,"<td class=\"first left\">","</td>",iDate)&&(iDate=="All Day")) //если есть дата тэг
|
|
//// {
|
|
//// //----- Date Time
|
|
//// iDateTim=TimeToString(StructToTime(gDateTime),TIME_DATE|TIME_MINUTES);
|
|
//// iResult=TagDelete(iInpStr,"<tr id=\"eventRowId_","</td>");
|
|
//// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,"<td"));
|
|
//// //----- Country
|
|
//// iResult=TagContent(iInpStr,"<span title=\"","\" class=\"",iCountry);
|
|
//// //----- Currency
|
|
//// iCouN=StringSubstr(iCountryS,StringFind(iCountryS,iCountry,3)-3,3);
|
|
//// iResult=TagDelete(iInpStr,"<td class=","</td>");
|
|
//// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,"<td"));
|
|
//// //----- Impact
|
|
//// iResult=TagContent(iInpStr,"<span class=","</td>",iVolatility);
|
|
//// iResult=TagContent(iVolatility,"\">","</span>",iVolatility);
|
|
//// //----- Impact N
|
|
//// iImpN=StringSubstr(iImpactMN,StringFind(iImpactMN,iVolatility,1)-1,1);
|
|
//// iResult=TagDelete(iInpStr,"<td class=","</td>");
|
|
//// iInpStr=StringSubstr(iInpStr,StringFind(iInpStr,"<td"));
|
|
//// //----- Event
|
|
//// iResult=TagContent(iInpStr,"class=\"","td>",iEvent);
|
|
//// iResult=TagContent(iInpStr,"\">","</",iEvent);
|
|
//// //----- Previous
|
|
//// iPrevious="";
|
|
//// //----- Forecast
|
|
//// iForecast="";
|
|
//// //----- Actual
|
|
//// iActual="";
|
|
//// //Print("4. iDate=",iDate," iDateTim=",iDateTim," iStr=",iInpStr);
|
|
//// }else{//Если даты нет и нет "All Day"
|
|
//// iOutStr="";
|
|
//// return(false);
|
|
//// }}//if(TagContent(iInpStr,"<span class=\"date\">","</td>",iMouDay))
|
|
//// }}//if(TagContent(iInpStr,"<span class=\"date\">","</td>",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,"<td class=\"date\">","</td>",iMou)) //если есть дата тэг
|
|
//// {
|
|
//// iResult=TagDelete(iMou,"<span class=\"date\">","<span>"); //Удаляем день недели
|
|
//// iResult=TagDelete(iMou,"</span>","</span>"); //Удаляем </span></span>
|
|
//// 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,"<span class=\"date\">","</td>",iMouDay))
|
|
//// iResult=TagDelete(iInpStr,"<td class=\"date\">","</td>"); //Удаляем дату
|
|
//// //----- Time
|
|
//// {if(TagContent(iInpStr,"<td class=\"time\">","</td>",iTim)) //Если есть время тэг
|
|
//// {
|
|
//// {if((iTim=="Tentative")||(iTim=="All Day"))
|
|
//// {
|
|
//// iTim="00:00";
|
|
//// }else{
|
|
//// {if((StringLen(iTim)>5)&&(StringFind(iTim,":",1)>=1)) //Если есть дополнительный тег и время в нем
|
|
//// {//<span class="upnext">
|
|
//// iResult=TagContent(iTim,"<span class=\"upnext\">","</span>",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,"<span class=\"time\">","</td>",iTim))
|
|
//// iResult=TagDelete(iInpStr,"<td class=\"time\">","</td>"); //Удаляем время
|
|
//// //----- Currency
|
|
//// iResult=TagContent(iInpStr,"<td class=\"currency\">","</td>",iCouN);
|
|
//// {if(!iResult)
|
|
//// {
|
|
//// iOutStr="";
|
|
//// return(false);
|
|
//// }}//if(!iResult)
|
|
//// iResult=TagDelete(iInpStr,"<td class=\"currency\">","</td>");
|
|
//// //----- Impact
|
|
//// iResult=TagContent(iInpStr,"<td class=\"impact\">","</td>",iImpact);
|
|
//// iResult=TagContent(iImpact,"<span title=\"","\" class=\"",iImpact);
|
|
//// {if(!iResult)
|
|
//// {
|
|
//// iOutStr="";
|
|
//// return(false);
|
|
//// }}//if(!iResult)
|
|
//// iResult=TagDelete(iInpStr,"<td class=\"impact\">","</td>");
|
|
//// //----- Impact N
|
|
//// iImpN=StringSubstr(iImpactNN,StringFind(iImpactNN,iImpact,1)-1,1);
|
|
//// //----- Event &
|
|
//// iEvent="";
|
|
//// iResult=TagContent(iInpStr,"<td class=\"event\"><span>","</span></td>",iEvent);
|
|
//// n=StringReplace(iEvent,"&","&");
|
|
//// {if(!iResult)
|
|
//// {
|
|
//// iOutStr="";
|
|
//// return(false);
|
|
//// }}//if(!iResult)
|
|
//// iResult=TagDelete(iInpStr,"<td class=\"event\">","</td>");
|
|
//// iResult=TagDelete(iInpStr,"<td class=\"detail\">","</td>");
|
|
//// 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,"<td class=\"actual\">","</td>",iActual);
|
|
//// {if(StringFind(iActual,"<span class=",0)>=0)
|
|
//// {
|
|
//// string iClass="";
|
|
//// iResult=TagContent(iActual,"<span class=\"","\">",iClass);
|
|
//// iResult=TagContent(iActual,"<span class=\""+iClass+"\">","</span>",iActual);
|
|
//// StringNormal(iActual);
|
|
//// iResult=TagDelete(iInpStr,"<span class=\"","</span>");
|
|
//// }}//
|
|
//// iResult=TagDelete(iInpStr,"<td class=\"actual\">","</td>");
|
|
//// n=StringReplace(iActual,"<","");
|
|
//// n=StringReplace(iActual,"\t","");//Тут всавлен спецсимвол табуляция
|
|
//// n=StringReplace(iActual," ","");
|
|
//// StringNormal(iActual);
|
|
//// //----- Forecast
|
|
//// iResult=TagContent(iInpStr,"<td class=\"forecast\">","</td>",iForecast);
|
|
//// iResult=TagDelete(iInpStr,"<td class=\"forecast\">","</td>");
|
|
//// n=StringReplace(iForecast,"<","");
|
|
//// n=StringReplace(iForecast,"\t","");
|
|
//// n=StringReplace(iForecast," ","");
|
|
//// StringNormal(iForecast);
|
|
//// //----- Previous
|
|
//// iResult=TagContent(iInpStr,"<td class=\"previous\">","</td>",iPrevious);
|
|
//// {if(StringFind(iPrevious,"<span class=",0)>=0)
|
|
//// {
|
|
//// string iClass="";
|
|
//// iResult=TagContent(iPrevious,"<span class=\"","\">",iClass);
|
|
//// iResult=TagContent(iPrevious,"<span class=\""+iClass+"\">","</span>",iPrevious);
|
|
//// iResult=TagDelete(iInpStr,"<span class=\"","</span>");
|
|
//// }}//<
|
|
//// 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</td>
|
|
//////<td style="width: 6%;" class="text-center calendar-td"><div class="flag-20-nzd"></div></td>
|
|
//////<td style="width: 48%;" id="title1_0" class="calendar-td"><div class="visible-xs f16">00:30<br></div>NZD Performance Services Index (NOV)</td>
|
|
//////<td style="width: 12%;" class="calendar-td">
|
|
//////<span id="importance1_0" class="label label-medium text-capitalize hidden-xs">medium</span>
|
|
//////<span id="importance1_0" class="label label-sm label-medium-sm text-capitalize hidden-lg hidden-md hidden-sm">m</span>
|
|
//////</td>
|
|
//////<td style="width: 8%;" class="-color hidden-xs text-center calendar-td">59.8</td>
|
|
//////<td style="width: 10%;" class="hidden-xs text-center calendar-td"></td>
|
|
//////<td style="width: 8%;" class="up-color hidden-xs text-center calendar-td">56.5</td>
|
|
//// //----- 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,"<span class=\"date\">","</td>",iMouDay))
|
|
//// iDate=iYear+"."+iMou+"."+iDay+" "+iTim;
|
|
//// iDateTim=TimeToString(StringToTime(iDate),TIME_DATE|TIME_MINUTES);
|
|
//// TimeToStruct(StringToTime(iDate),gDateTime);
|
|
//// iResult=TagDelete(iInpStr,"id=\"date","</td>"); //Удаляем дату
|
|
//// //----- Currency
|
|
//// iResult=TagContent(iInpStr,"<div class=\"flag-20-","\">",iCouN);
|
|
//// {if(!iResult)
|
|
//// {
|
|
//// iOutStr="";
|
|
//// return(false);
|
|
//// }}//if(!iResult)
|
|
//// StringToUpper(iCouN);
|
|
//// iResult=TagDelete(iInpStr,"<td style=","<br></");
|
|
//// //----- Country
|
|
//// iCountry=StringSubstr(iCountryS,
|
|
//// StringFind(iCountryS,iCouN,0)+3,
|
|
//// StringFind(iCountryS,"#",StringFind(iCountryS,iCouN,0)+3)-StringFind(iCountryS,iCouN,0)-3);
|
|
//// //----- Event
|
|
//// iResult=TagContent(iInpStr,"di","td><td style",iEvent);
|
|
//// {if(!iResult)
|
|
//// {
|
|
//// iOutStr="";
|
|
//// return(false);
|
|
//// }}//if(!iResult)
|
|
//// iResult=TagContent(iEvent,"v>"," ",iCur);
|
|
//// {if(StringFind(iCountryS,iCur)>=0)
|
|
//// {
|
|
//// iResult=TagDelete(iEvent,">"," ");
|
|
//// iResult=TagContent(iEvent,"v","</",iEvent);
|
|
//// }else{
|
|
//// iResult=TagContent(iEvent,"v>","</",iEvent);
|
|
//// }}//if(StringFind(iCountryS,iCur)>=0)
|
|
//// n=StringReplace(iEvent,"'","\'");
|
|
//// iResult=TagDelete(iInpStr,"div>","<span id=\"imp");
|
|
//// //----- Impact
|
|
//// iResult=TagContent(iInpStr,"\">","</span>",iImpact);
|
|
//// {if(!iResult)
|
|
//// {
|
|
//// iOutStr="";
|
|
//// return(false);
|
|
//// }}//if(!iResult)
|
|
//// //----- Impact N
|
|
//// iImpN=StringSubstr(iImpactON,StringFind(iImpactON,iImpact,1)-1,1);
|
|
//// iResult=TagDelete(iInpStr,"ortance","</span></td>");
|
|
//// //----- Actual
|
|
//// iResult=TagContent(iInpStr,"td\">","</td>",iActual);
|
|
//// iResult=TagDelete(iInpStr,"<td style=","</td>");
|
|
//// //n=StringReplace(iActual,"<","");
|
|
//// //n=StringReplace(iActual,"\t","");
|
|
//// //n=StringReplace(iActual," ","");
|
|
//// StringNormal(iActual);
|
|
//// //----- Forecast
|
|
//// iResult=TagContent(iInpStr,"td\">","</td>",iForecast);
|
|
//// iResult=TagDelete(iInpStr,"<td style=","</td>");
|
|
//// //n=StringReplace(iForecast,"<","");
|
|
//// //n=StringReplace(iForecast,"\t","");
|
|
//// //n=StringReplace(iForecast," ","");
|
|
//// StringNormal(iForecast);
|
|
//// //----- Previous
|
|
//// iResult=TagContent(iInpStr,"td\">","</td>",iPrevious);
|
|
//// iResult=TagDelete(iInpStr,"<td style=","</td>");
|
|
//// //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;i<iMAPeriod;i++,pos--)//Перебор на глубину периода МА
|
|
{
|
|
//{if((pos>1000)||(pos<2))
|
|
//{
|
|
// Print("total=",total," i=",i," pos=",pos);
|
|
//}}//if(pos>1000)
|
|
sum+=Array[pos];//Сумма всех элементов массива на периоде МА
|
|
}}//for(i=1;i<iMAPeriod;i++,pos--)
|
|
{while(pos>0)
|
|
{
|
|
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;i<iMAPeriod;i++,k++)
|
|
{
|
|
sum+=Array[k];
|
|
buf[k]=0;
|
|
}}//for(i=0,k=pos;i<iMAPeriod;i++,k++)
|
|
}else{
|
|
sum=buf[pos+1]*(iMAPeriod-1)+Array[pos];
|
|
}}//if(pos==total-iMAPeriod)
|
|
buf[pos]=sum/iMAPeriod;
|
|
pos--;
|
|
}}//while(pos>0)
|
|
{if(pos==0)
|
|
{
|
|
{if(pos==total-iMAPeriod)
|
|
{
|
|
{for(i=0,k=pos;i<iMAPeriod;i++,k++)
|
|
{
|
|
sum+=Array[k];
|
|
buf[k]=0;
|
|
}}//for(i=0,k=pos;i<iMAPeriod;i++,k++)
|
|
}else{
|
|
sum=buf[pos+1]*(iMAPeriod-1)+Array[pos];
|
|
}}//if(pos==total-iMAPeriod)
|
|
buf[pos]=sum/iMAPeriod;
|
|
}}//if(pos==0)
|
|
return(buf[Shift+ma_shift]);
|
|
}//case MODE_SMMA
|
|
case MODE_LWMA :
|
|
{
|
|
double sum=0.0,lsum=0.0;
|
|
double price;
|
|
uint i,weight=0,pos=total-1;
|
|
{for(i=1;i<=iMAPeriod;i++,pos--)
|
|
{
|
|
price=Array[pos];
|
|
sum+=price*i;
|
|
lsum+=price;
|
|
weight+=i;
|
|
}}//for(i=1;i<=iMAPeriod;i++,pos--)
|
|
pos++;
|
|
i=pos+iMAPeriod;
|
|
{while(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;
|
|
}}//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(time<time1) return(1);
|
|
else return(0);
|
|
}else{
|
|
return(-1);
|
|
}}//if(CopyTime(symbol,timeframe,time,time1,Arr)>0)
|
|
}//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)<MinLot)//Нулевой объём - к следующему
|
|
{
|
|
//Print("Return Vol=",PositionGetDouble(POSITION_VOLUME));
|
|
return(false);
|
|
}else{//Ненулевой объём - модификация
|
|
//Print("Request Vol=",PositionGetDouble(POSITION_VOLUME),
|
|
// " Type=",EnumToString((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)),
|
|
// " Price=",PositionGetDouble(POSITION_PRICE_OPEN),
|
|
// " PriceCurr=",PositionGetDouble(POSITION_PRICE_CURRENT),
|
|
// " Bid=",gBid,
|
|
// " Ask=",gAsk);
|
|
//--- Объявление запроса и результата
|
|
MqlTradeRequest Request={0};
|
|
MqlTradeResult Result={0};
|
|
//--- Обнуление значений запроса и результата
|
|
ZeroMemory(Request);
|
|
ZeroMemory(Result);
|
|
//--- установка параметров операции
|
|
Request.symbol=PositionGetString(POSITION_SYMBOL);// Символ (инструмент) позиции
|
|
Request.action=TRADE_ACTION_SLTP; // Тип торговой операции изменение SL TP
|
|
Request.position=iPosTick; // Тикет позиции
|
|
Request.sl=iPosNewSL; // Stop Loss позиции
|
|
Request.tp=iPosNewTP; // Take Profit позиции
|
|
//--- отправка запроса
|
|
return(OrderSendAsync(Request,Result)); //Отправляем асинхронно
|
|
//return(OrderSend(Request,Result));
|
|
}}//if(PositionGetDouble(POSITION_VOLUME)<0.01)
|
|
|
|
}//PositionModifySL()
|
|
//
|
|
//======================================================================================================
|
|
// PositionCloseBy() - Встречное закрытие позиций. Добавить цикличность до победы
|
|
// Вход:
|
|
// iPosTick - тикет позиции
|
|
// iPosTick - тикет встречной позиции
|
|
//======================================================================================================
|
|
bool PositionCloseBy( long iPosTick,
|
|
long iPosTick2){
|
|
bool
|
|
iOrd_inf=false;
|
|
//--- объявление запроса и результата
|
|
MqlTradeRequest Request={0};
|
|
MqlTradeResult Result={0};
|
|
//--- обнуление значений запроса и результата
|
|
ZeroMemory(Request);
|
|
ZeroMemory(Result);
|
|
//--- установка параметров операции
|
|
Request.action=TRADE_ACTION_CLOSE_BY; // тип торговой операции
|
|
Request.position=iPosTick; // тикет позиции
|
|
Request.position_by=iPosTick2; // тикет встречной позиции
|
|
//--- отправка запроса
|
|
iOrd_inf=OrderSendAsync(Request,Result);
|
|
return(iOrd_inf);
|
|
}//PositionCloseBy()
|
|
//
|
|
//======================================================================================================
|
|
// PositionOrderSend() - Отправка запроса на выставление ордера
|
|
// Вход:
|
|
// iSymbol - инструмент позиции
|
|
// iType - тип позиции
|
|
//======================================================================================================
|
|
uint PositionOrderSend( string iSymbol,
|
|
ENUM_ORDER_TYPE iType,
|
|
double iVol,
|
|
double iPrice,
|
|
ulong iSlip,
|
|
double iSL,
|
|
double iTP,
|
|
string iComment,
|
|
ulong iMagic,
|
|
datetime iExpir,
|
|
ulong &iDeal){
|
|
bool
|
|
iOrd_inf=false;
|
|
//--- обнуление значений запроса и результата
|
|
MqlTradeRequest Request={0};
|
|
MqlTradeResult Result={0};
|
|
//ZeroMemory(Request);
|
|
//ZeroMemory(Result);
|
|
//--- подготовим запрос
|
|
Request.action =TRADE_ACTION_DEAL;
|
|
Request.magic =iMagic;
|
|
Request.type =iType;
|
|
Request.symbol =iSymbol;
|
|
Request.volume =iVol;
|
|
Request.price =iPrice;
|
|
Request.sl =iSL;
|
|
Request.tp =iTP;
|
|
Request.deviation =iSlip;
|
|
Request.comment =iComment;
|
|
Request.expiration =iExpir;
|
|
//--- отправка запроса
|
|
//ResetLastError();
|
|
iOrd_inf=OrderSend(Request,Result);
|
|
//Print("ERR 20=",GetLastError());
|
|
iDeal=Result.deal;
|
|
return(Result.retcode);
|
|
}//PositionOrderSend()
|
|
//
|
|
//======================================================================================================
|
|
// PositionOrderSendAsync() - Встречное закрытие позиций. Добавить цикличность до победы
|
|
// Вход:
|
|
// iSymbol - инструмент позиции
|
|
// iType - тип позиции
|
|
//======================================================================================================
|
|
bool PositionOrderSendAsync( string iSymbol,
|
|
ENUM_ORDER_TYPE iType,
|
|
double iVol,
|
|
double iPrice,
|
|
ulong iSlip,
|
|
double iSL,
|
|
double iTP,
|
|
string iComment,
|
|
long iMagic,
|
|
datetime iExpir,
|
|
ulong &iDeal){
|
|
bool
|
|
iOrd_inf=false;
|
|
//--- обнуление значений запроса и результата
|
|
MqlTradeRequest Request={0};
|
|
MqlTradeResult Result={0};
|
|
ZeroMemory(Request);
|
|
ZeroMemory(Result);
|
|
//--- подготовим запрос
|
|
Request.action =TRADE_ACTION_DEAL;
|
|
Request.magic =iMagic;
|
|
Request.type =iType;
|
|
Request.symbol =iSymbol;
|
|
Request.volume =iVol;
|
|
Request.price =iPrice;
|
|
Request.sl =iSL;
|
|
Request.tp =iTP;
|
|
Request.deviation =iSlip;
|
|
Request.comment =iComment;
|
|
Request.expiration =iExpir;
|
|
//--- отправка запроса
|
|
iOrd_inf=OrderSendAsync(Request,Result);
|
|
iDeal=Result.deal;
|
|
return(iOrd_inf);
|
|
}//PositionOrderSendAsync()
|
|
//
|
|
//======================================================================================================
|
|
// PositionCloseOne() - Закрытие позиции. Добавить цикличность до победы
|
|
// Вход:
|
|
// iPosTick - тикет позиции
|
|
//======================================================================================================
|
|
bool PositionCloseOne( ulong iPosTick,
|
|
ulong iSlip ){
|
|
//Print("PositionCloseOne>>");
|
|
//----- Получим дополнительную информацию по позиции
|
|
//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)&&(iTerminalFirstDate<iFirstServerDate))
|
|
{
|
|
Print(__FUNCTION__,"(): Warning: first server date ",iFirstServerDate," for ",iSymbol,
|
|
" does not match to first series date ",iTerminalFirstDate);
|
|
}}//if((iTerminalFirstDate>0)&&(iTerminalFirstDate<first_server_date))
|
|
//--- load data step by step
|
|
int iFailCnt=0;
|
|
{while(!IsStopped())
|
|
{
|
|
//--- 1.дождаться окончания процесса перестройки таймсерии
|
|
{while(
|
|
(!SeriesInfoInteger(iSymbol,iPeriod,SERIES_SYNCHRONIZED))//проверка синхронности данных
|
|
&&
|
|
(!IsStopped())
|
|
)
|
|
{//Если не синхронны и не подготовка к остановке
|
|
Sleep(5);//Маленько подождать...
|
|
}}//while(
|
|
//--- 2.запросим сколько баров мы теперь имеем
|
|
int iBars=Bars(iSymbol,iPeriod);//Общее количество всех баров в истории
|
|
{if(iBars>0)
|
|
{
|
|
//Если есть бары в истории
|
|
//--- баров больше, чем можно отобразить на графике, выходим
|
|
{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(iBars<iTerminalMaxBars)
|
|
{//Количество баров в истории терминала меньше чем максимальное количество баров на графике заданное в настройках
|
|
//Обработка докачки
|
|
//--- 3. узнаем текущую начальную дату в таймсерии (истории терминала???)
|
|
/*L*/ datetime iTerminalFirstDate2=0;
|
|
{if(SeriesInfoInteger(iSymbol,PERIOD_M1,SERIES_TERMINAL_FIRSTDATE,iTerminalFirstDate2))//Получаем в iTerminalFirstDate самую первую дату по символу в терминале
|
|
{
|
|
/*M*/ {if(
|
|
(iTerminalFirstDate2>0)//Дата есть
|
|
&&
|
|
(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*/ }}//(iBars<iTerminalMaxBars)
|
|
/*J*/ }else{
|
|
//Данные для таймсерии с указанными параметрами при вызове функции Bars() еще не сформированы в терминале,
|
|
//или данные таймсерии в момент вызова функции не синхронизированы с торговым сервером
|
|
{if(iFailCntSync>1)
|
|
{//Счетчик попыток получения данных сервера НЕ исчерпан
|
|
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()
|
|
// |