unlockernew.mq4
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «unlockernew.mq4» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
Данный продукт представляет собой торговый советник для MetaTrader 4, реализующий механизм локирования и разблокирования торговых позиций. Советник использует индикатор SAR (Stop and Reverse) и EMA с периодом 200 для формирования торговых сигналов и управления ордерами.
Класс CLock обеспечивает работу с частичными локами, накопление прибыли в «копилку» и закрытие позиций при достижении заданного процента профита. Класс CUnlocker управляет основной логикой разблокирования: стабилизацией позиций, выставлением отложек, сопровождением ордеров поддержки, трейлингом и разрезанием убыточных лотов за счёт накопленной прибыли.
Советник работает с торговыми событиями MetaTrader 4, использует торговые операции через OrderSend, OrderClose и OrderModify. Параметры сохраняются глобально через pglobal.LoadParam и pglobal.SaveParam, что позволяет сохранять состояние между перезапусками советника.
Поиск по коду файла
#ifndef __SOVETNIKOV_UNLOCKER_2sdfhgsd
#define __SOVETNIKOV_UNLOCKER_2sdfhgsd
#include <sovetnikovNET\Orders.mqh>
class CLock: public COrders
{
public:
datetime tmKopilka;
ENUM_TIMEFRAMES eSupportTF;
bool bSupport;
double dLockMultiplicator; //Lock lot multiplicator / Множитель лота для лок
double dKopilkaProcent; //Profit % for moneybox / Процент профита в копилку
double dTPinProcent; //All profit % at balance / Закрытие в профит всех ордеров
long iLockMagic; //Lock magic and rezerved: Magic+1 / Идентификатор ордеров лок
CNewBar m_barSupport;
int hsar;
virtual bool OnInitIndicators()
{
m_barSupport.OnInit(m_name,eSupportTF);
#ifdef __MQL5__
hsar=iSAR(m_name,eSupportTF,0.002,0.2);
#endif
return true;
}
virtual bool OnDeinitIndicators()
{
#ifdef __MQL5__
IndicatorRelease(hsar);
#endif
return true;
}
bool CloseByProfitInProcent()
{
double dprofit=ND2(AccountBalance()*dTPinProcent/100);
datetime tmLock=(datetime)pglobal.LoadParam("Kopilka_Time",0);
double dSummProfit=getProfit(ALL);
if(tmLock>0)
dSummProfit+=getProfit(ALL,MODE_HISTORY,tmLock);
if(dSummProfit>0 && dSummProfit>=dprofit)
{
OrderCloseAll(ALL);
return true;
}
return false;
}
void Run()
{
string _sExpertName=WindowExpertName();
double dprofit=ND2(AccountBalance()*dTPinProcent/100);
double dsar[2];
#ifdef __MQL5__
dsar[0]=iCustom(hsar,0,0);
dsar[1]=iCustom(hsar,0,1);
#else
dsar[0]=iSAR(m_name,eSupportTF,0.002,0.2,0);
dsar[1]=iSAR(m_name,eSupportTF,0.002,0.2,1);
#endif
m_barSupport.Refresh();
double dLots[2];
if(CloseByProfitInProcent())
return;
this.OnTick();
int idirect=0;
double dAvg=get_Average(ALL,idirect);
ENUM_ORDER_TYPE iTradeMode=-1;
if(idirect<0)
iTradeMode=OP_SELL;
if(idirect>0)
iTradeMode=OP_BUY;
if(dAvg>0) m_drawvirtual.DrawHLine(0,"bu",0,iTime(m_name,PERIOD_CURRENT,1),dAvg,1,STYLE_SOLID,clrGreen,false,false,"BU");
else m_drawvirtual.Delete(0,"bu");
string sType=TypeToString(iTradeMode);
if(Kopilka(iTradeMode))
return;
double ddeltaLot=Abs(get_lots(dLots));
double dSummLot=0;
double dLastPrice=0,dPrice=0; //цена от которой идет рассчет для установки следующего лока
datetime tmFirst=0,tmLast=0;
if(iTradeMode==OP_BUY)
{
if(dsar[0]>iHigh(m_name,eSupportTF,0) && m_barSupport.isNewBar())
{
ulong t=OrderSend(OP_SELL,NLot(ddeltaLot+dLots[0]*dLockMultiplicator),-1,0,0,NULL);
DEBUG_OrderSend3(t);
if(t>0)
SetAll(OP_SELL,0,0,true);
}
/*else if(dsar[0]<iLow(m_name,eSupportTF,0) && m_barSupport.isNewBar())
{
ulong t=OrderSend(OP_SELL,NLot(ddeltaLot),-1,0,dLockTP,NULL);
DEBUG_OrderSend3(t);
if(t>0)
SetAll(OP_SELL,0,0,true);
}*/
}
if(iTradeMode==OP_SELL)
{
if(dsar[0]<iLow(m_name,eSupportTF,0) && m_barSupport.isNewBar())
{
ulong t=OrderSend(OP_BUY,NLot(ddeltaLot+dLots[1]*dLockMultiplicator),-1,0,0,NULL);
DEBUG_OrderSend3(t);
if(t>0)
SetAll(OP_BUY,0,0,true);
}
/*else
if(dsar[0]>iHigh(m_name,eSupportTF,0) && m_barSupport.isNewBar())
{
ulong t=OrderSend(OP_BUY,NLot(ddeltaLot),-1,0,dLockTP,NULL);
DEBUG_OrderSend3(t);
if(t>0)
SetAll(OP_BUY,0,0,true);
}*/
}
}
virtual bool Check(string symbol,long imagic)
{
if(m_name==NULL || symbol==m_name)
return true;
return false;
}
void Reset(datetime tmNew)
{
if(tmNew==0.0)
{
tmKopilka=0;
pglobal.DeleteParam("Kopilka_Profit"); //сбросим копилку
pglobal.DeleteParam("Kopilka_Time"); //сбросим копилку
m_drawvirtual.Delete(0,"bu");
}
tmKopilka=(datetime)pglobal.LoadParam("Kopilka_Time",0);
if(tmNew>tmKopilka)
{
tmKopilka=tmNew;
pglobal.SaveParam("Kopilka_Time",tmKopilka); //сохраним новое время для копилки
}
}
virtual ulong getLastOrderTicket(double &dSummLot,int itype,_ORDER_MODE imode=ORDER_UP,datetime dtmOpen=0)
{
double array_order_open[][2]; //0- price,1-ticket
ArrayResize(array_order_open,0);
dSummLot=0;
int c=0;
for(int i=PositionsTotal()-1; i>=0; i--)
{
if(!SelectByIndex(i,true))
continue;
ulong uOrderTicket=m_position.Ticket();
int lOrderType=m_position.PositionType();
double dOrderOpenPrice=m_position.PriceOpen();
double dOrderLots=m_position.Volume();
if(m_position.Time()>=dtmOpen)
{
if(lOrderType==POSITION_TYPE_BUY && itype==OP_BUY)
{
ArrayResize(array_order_open,c+1);
array_order_open[c][0]=dOrderOpenPrice;
array_order_open[c][1]=(double)uOrderTicket;
dSummLot+=dOrderLots;
c++;
}
if(lOrderType==POSITION_TYPE_SELL && itype==OP_SELL)
{
ArrayResize(array_order_open,c+1);
array_order_open[c][0]=dOrderOpenPrice;
array_order_open[c][1]=(double)uOrderTicket;
dSummLot+=dOrderLots;
c++;
}
}
}
if(itype==OP_BUY && c>0)
{
ArraySort(array_order_open); //сортируем в сторону увеличения, тогда 0й ордер будет самый нижний, последний сверху (первый).
if(imode==ORDER_DN)
return ((ulong)array_order_open[0][1]);
if(imode==ORDER_UP)
return ((ulong)array_order_open[c-1][1]);
}
if(itype==OP_SELL && c>0)
{
ArraySort(array_order_open); //сортируем в сторону уменьшения, тогда 0й ордер будет самый нижний, последний сверху (первый).
if(imode==ORDER_UP)
return ((ulong)array_order_open[c-1][1]);
if(imode==ORDER_DN)
return ((ulong)array_order_open[0][1]);
}
return 0;
}
bool Kopilka(int _itype)
{
if(_itype==-1)
return false;
datetime tmTime=(datetime)pglobal.LoadParam("Kopilka_Time",0);
/*
нужно загрузить все данные по закрытым ордерам и обновить переменную времени, чтобы их повторо не грузить
*/
if(tmTime==0)
{
ulong tfirst=getFirstOrderTicket(ALL,0);
if(OrderSelect(tfirst,true))
tmTime=OrderOpenTime(true);
pglobal.SaveParam("Kopilka_Time",tmTime);
}
datetime tmp_tmFirst=tmTime;
datetime _tmFirst=tmTime;
datetime tmCurrent=TimeCurrent();
HistorySelect(tmTime,tmCurrent); //загрузем историю закрытых ордеров
double dProfit=0;
for(int i=HistoryDealsTotal()-1; i>=0; i--)
{
if(!m_deal.SelectByIndex(i))
continue;
if(m_deal.Symbol()==m_name && (m_deal.DealType()==DEAL_TYPE_BUY || m_deal.DealType()==DEAL_TYPE_SELL))
{
double dlock_profit=m_deal.Profit()+m_deal.Swap()+m_deal.Commission();
if(dlock_profit>0)
{
dlock_profit=ND2(dlock_profit*dKopilkaProcent/100);
}
dProfit+=dlock_profit;
if(m_deal.Time()>tmp_tmFirst)
tmp_tmFirst=m_deal.Time();
}
}
if(dProfit>0)
{
double dKopilkaAdd=dProfit;
string sType=TypeToString(_itype);
double dKopilka=pglobal.LoadParam("Kopilka_Profit",0);
dKopilka+=dKopilkaAdd;
_tmFirst=tmp_tmFirst+1;
PrintFormat("Kopilka %s add profit: %.2f Kopilka: %.2f Time: %s",sType,dKopilkaAdd,dKopilka,TimeToString(_tmFirst+1,TIME_DATE|TIME_SECONDS));
pglobal.SaveParam("Kopilka_Profit",dKopilka);
}
string sType=TypeToString(_itype);
double dKopilka=pglobal.LoadParam("Kopilka_Profit",0); //текущее значение в копилке
if(dKopilka>0)
{
int iforClose=0,ifor=0;
double dMinusForClose=0;
double dminuslot=0;
double dminlot=0;
ulong itickets=0;
double dpartlot=0;
double dlotstep=SymbolInfoDouble(m_name,SYMBOL_VOLUME_STEP);//шаг лота
double dMinLot=MinLot(m_name);
double dMaxLoss=0;
for(int i=PositionsTotal()-1; i>=0; i--)
{
if(!SelectByIndex(i,true))
continue;
ulong uOrderTicket=m_position.Ticket();
int etype=m_position.PositionType();
double dPositionProfit=m_position.Profit()+2*m_position.Commission()+m_position.Swap();
double dPositionLot=m_position.Volume();
double dminuslotUp=NormalizeDouble(dPositionProfit*dlotstep/dPositionLot,2); //рассчитаем профит на минимальный шаг лота 0.01
if(dPositionProfit<0 && dPositionProfit<dMaxLoss)
{
dMaxLoss=dPositionProfit;
dminuslot=dminuslotUp; //минус на 1 лот
dminlot=dPositionLot;//лот ордера
dpartlot=0;
itickets=uOrderTicket;
iforClose++;
}
}
if(iforClose>0)
{
for(int j=1; !IsStopped(); j++)
{
double dMinus=NormalizeDouble(dminuslot*j,2);
if(dMinus+dKopilka>=0 && dMinus<0)
{
dMinusForClose=dMinus;
dpartlot=NLot(j*dlotstep);
}
else
{
break;
}
}
}
if(dMinusForClose+dKopilka>=0 && dMinusForClose<0 && iforClose>0)
{
PrintFormat("Minis for close: %.2f Kopilka: %.2f count: %d",dMinusForClose,dKopilka,iforClose);
int iOrderClose=0;
if(dpartlot>0)
{
ulong iticket=itickets;
double dlot=NLot(dpartlot);
OrderClose(iticket,dlot);
iOrderClose++;
}
if(iOrderClose>0)
{
dKopilka+=dMinusForClose; //вычтем из копилки
tmCurrent=TimeCurrent();
if(tmCurrent+1>_tmFirst)
_tmFirst=tmCurrent+1;
PrintFormat("Kopilka close orders %s Kopilka: %.2f Time: %s",sType,dKopilka,TimeToString(_tmFirst,TIME_DATE|TIME_SECONDS));
pglobal.SaveParam("Kopilka_Profit",dKopilka);
return true;
}
}
}
return false;
}
};
class CUnlocker: public COrders
{
public:
int iop;
#ifdef __MQL5__
int hma,hsar;
void InitIndicators(ENUM_TIMEFRAMES etf)
{
hma=iMA(m_name,etf,200,0,MODE_EMA,PRICE_OPEN);
hsar=iSAR(m_name,etf,0.002,0.02);
}
#endif
virtual bool Check(string symbol,long imagic)
{
if((m_name==NULL || symbol==m_name) && (m_imagic==-1 || m_imagic==imagic || imagic==-1))
return true;
return false;
}
virtual bool CheckLocksMagic(string symbol,long iMagic)
{
if((m_name==NULL || symbol==m_name) && (iMagic==m_imagic || iMagic==m_imagic+1))
return true;
return false;
}
virtual int CountLocks()
{
__COPYRIGHT__
int ic=0;
for(int i=0; i<PositionsTotal(); i++)
{
if(!SelectByIndex(i,true))
continue; //если не выбирает, пропускаем
if(CheckLocksMagic(m_position.Symbol(),m_position.Magic()) && m_position.PositionType()<2)
{
ic++;
}
}
return ic;
}
virtual double getMaxLotForUnlocker(long iSupportMagic)
{
double dreturn_lot=0;
double dbuy=0,dsell=0;
int icount=PositionsTotal();
for(int i=icount-1; i>=0; i--)
{
if(!SelectByIndex(i,true))
continue;
if(!Check(m_position.Symbol(),m_position.Magic()))
continue;
if(m_position.PositionType()>=2 || m_position.Magic()==iSupportMagic)
continue;
if(m_position.PositionType()==POSITION_TYPE_BUY)
dbuy+=m_position.Volume();
if(m_position.PositionType()==POSITION_TYPE_SELL)
dsell+=m_position.Volume();
}
dreturn_lot=MathMax(dbuy,dsell);
return dreturn_lot;
}
virtual void GetAllHistory(datetime tmLock,datetime &tmEnd,double &dSummProfit,double &dSummMinus)
{
datetime tmStart=tmEnd;
double dSumm=0;
dSummProfit=0;
dSummMinus=0;
HistorySelect(tmLock,TimeCurrent());
for(int i=HistoryDealsTotal()-1; i>=0; i--)
{
if(!m_deal.SelectByIndex(i))
continue;
if(Check(m_deal.Symbol(),m_deal.Magic()) && tmLock>0 && m_deal.Entry()==DEAL_ENTRY_OUT)
{
if(m_deal.Time()<tmLock && tmLock>0)
break;
if(m_deal.Time()>tmStart && m_deal.Time()>=tmLock)
{
dSumm=m_deal.Profit()+m_deal.Commission()+m_deal.Swap(); //посчитаем суммарный профит\убыток закрытых ордеров
if(dSumm>=0)
dSummProfit+=dSumm;
else
dSummMinus+=dSumm;
if(m_deal.Time()>tmEnd)
tmEnd=m_deal.Time();//обновим время обновления для следующего учета
}
}
}
}
virtual bool getMaximumMinus(ulong &tMin,double &dPositionLot,double &dPositionProfit)
{
tMin=0;
dPositionLot=0;
dPositionProfit=0;
double dmin=0;
double dprice=(_Ask+_Bid)/2;
for(int i=0; i<PositionsTotal(); i++)
{
if(!SelectByIndex(i,true))
continue;
if(Check(m_position.Symbol(),m_position.Magic()) && m_position.PositionType()<2)
{
double ddelta=Abs(dprice-m_position.PriceOpen());
double dMacroProfit=m_deal.Profit()+m_deal.Commission()+m_deal.Swap();
if(dMacroProfit<0 && (ddelta>dmin || dmin==0))
{
dmin=ddelta;
tMin=m_position.Ticket();
dPositionLot=m_position.Volume();
dPositionProfit=dMacroProfit;
}
}
}
if(tMin>0)
return true;
return false;
}
virtual void MovePending(int iLockMagic,ENUM_TIMEFRAMES etf,double dMinOffset)
{
double dsarprice=0;
#ifdef __MQL5__
double dma=iCustom(hma,0,0);
#else
double dma=iMA(m_name,etf,200,0,MODE_EMA,PRICE_OPEN,0);
#endif
for(int i=0; i<iBars(m_name,etf); i++)
{
#ifdef __MQL5__
double dsar=iCustom(hsar,0,i);
double dsar1=iCustom(hsar,0,i+1);;
#else
double dsar=iSAR(m_name,etf,0.002,0.02,i);
double dsar1=iSAR(m_name,etf,0.002,0.02,i+1);
#endif
if(dsar>iHigh(m_name,etf,i) && dsar1<iLow(m_name,etf,i+1) && _Ask<dsar+dMinOffset*p)
{
dsarprice=dsar;
break;
}
}
double dOpen=0,dNewOpen=0;
if(dsarprice>0)
{
ulong tbuy=getOrderTicket(OP_BUYSTOP,0,iLockMagic);
if(OrderSelect(tbuy,false))
{
dOpen=OrderOpenPrice();
dNewOpen=dsarprice+dMinOffset*p;
if(dOpen>dNewOpen && _Ask<dNewOpen)
{
OrderModify(tbuy,dNewOpen,0,0);
}
}
}
dsarprice=0;
for(int i=0; i<iBars(m_name,etf); i++)
{
#ifdef __MQL5__
double dsar=iCustom(hsar,0,i);
double dsar1=iCustom(hsar,0,i+1);;
#else
double dsar=iSAR(m_name,etf,0.002,0.02,i);
double dsar1=iSAR(m_name,etf,0.002,0.02,i+1);
#endif
if(dsar<iLow(m_name,etf,i) && dsar1>iHigh(m_name,etf,i+1) && _Bid>dsar-dMinOffset*p)
{
dsarprice=dsar;
break;
}
}
if(dsarprice>0)
{
ulong tsell=getOrderTicket(OP_SELLSTOP,0,iLockMagic);
if(OrderSelect(tsell))
{
dOpen=OrderOpenPrice();
dNewOpen=dsarprice-dMinOffset*p;
if(dOpen<dNewOpen && _Bid>dNewOpen)
{
OrderModify(tsell,dNewOpen,0,0);
}
}
}
}
virtual bool Stabilization(int iLockMagic,
ENUM_TIMEFRAMES etf,
double dPending_MinOffset,
double dMinProfit,
double dSupportMn,
bool bRecountLot,
double dSupportTral,
double dSupportStep)
{
int iSupportMagic=iLockMagic+1; //поддерка будет с меджиком +1 от лока
double array_order_buy[][4];
double array_order_sell[][4];
ArrayResize(array_order_buy,0);
ArrayResize(array_order_sell,0);
int cb=0,cs=0;
double dbuyprofit=0,dsellprofit=0;
for(int i=PositionsTotal()-1; i>=0; i--)
{
if(!SelectByIndex(i,true))
continue;
if(OrderType()==OP_BUY)
{
if(ArrayResize(array_order_buy,cb+1)!=-1Показано первые 50% кода (символов: 23459)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.