class CLock
Класс для управления торговыми позициями с механизмом частичного локирования и накопления прибыли
Сообщите нам, если считаете, что материал размещён без разрешения.
Обращение по товару «unlocker.mq4» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
unlocker.mqh — библиотека исходного кода для MetaTrader 4, предоставляющая класс CLock для управления торговыми позициями с механизмом частичного локирования. Библиотека наследуется от класса COrders и использует торговые API для работы с позициями и ордерами. Класс реализует выборочное закрытие позиций по типу, магическому номеру и направлению, а также поддерживает накопление прибыли в копилку для последующего частичного закрытия.
Классов: 1 · методов: 12 · конструкторов: 0 · деструкторов: 0 · отдельных функций: 0
class CLock
Класс для управления торговыми позициями с механизмом частичного локирования и накопления прибыли
bool OrderCloseAll(int itype)
Закрывает все позиции и удаляет все ордера указанного типа
bool OrderCloseAll(long iLockMagic,int itype)
Закрывает позиции и удаляет ордера указанного типа с учётом магического номера
bool OrderCloseProfitAllNoLock(long iLockMagic,int itype)
Закрывает только прибыльные позиции указанного типа, исключая позиции с заданным магическим номером
bool CloseByProfitInProcent(double dTPinProcent)
Закрывает все позиции, если накопленная прибыль достигает заданного процента от баланса
bool SelfDestruct(int itype,long iLockMagic,double dTPinProcent)
Принудительно закрывает часть позиций при достижении заданного процента прибыли
void SetAllforLock(long iLockMagic,int itype,double dstop,double dtake,bool bCheck,bool bForTral,double dTrailingStep)
Устанавливает или модифицирует уровни стоп-лосс и тейк-профита на позициях с поддержкой трейлинга
void Run(int iTradeMode,long iLockMagic,double dTPinProcent,double dLockTP,double dLockBU,double dLockTral, double dLockNext,double dLockMultiplicator,double dKopilkaProcent,double dMinimalLot,bool bSelfDestruct)
Запускает основной цикл управления позицией с возможностью построения сетки, трейлинга и саморазрушения
bool Check(string symbol,long imagic)
Проверяет, соответствует ли символ и магический номер заданным параметрам
double get_Average(long iLockMagic,int itype,int &idirect,double dProfit)
Рассчитывает среднюю цену входа и определяет уровень тейк-профита для достижения заданной прибыли
void Reset(datetime tmNew)
Сбрасывает или обновляет параметры накопления прибыли
ulong getLastOrderTicket(long iLockMagic,double &dSummLot,int itype,_ORDER_MODE imode,datetime dtmOpen)
Возвращает тикет последнего ордера указанного типа и направления с учётом времени открытия
bool Kopilka(long iLockMagic,double dKopilkaProcent,double dMinimalLot,ulong &_tlast,double &_dlot,double &_dSummLot,int _itype,datetime &_tmFirst)
Выполняет частичное закрытие позиций с накоплением прибыли в копилку для последующего использования
#ifndef __SOVETNIKOV_UNLOCKER_2sdfhgsd
#define __SOVETNIKOV_UNLOCKER_2sdfhgsd
#include <sovetnikovNET\Orders.mqh>
class CLock: public COrders
{
public:
datetime tmKopilka;
virtual bool OrderCloseAll(int itype=ALL)
{
__COPYRIGHT__
int c=0,flag;
bool bRet=false;
for(int i=PositionsTotal()-1; i>=0; i--)
{
if(!SelectByIndex(i,true))
continue;
int etype=m_position.PositionType();
flag=toMyTypes(etype)&itype;
if(itype==ALL || etype==toDefType(flag,itype))
{
double dTakeProfit=m_position.TakeProfit();
double dStopLoss=m_position.StopLoss();
double dCurrentPrice=m_position.PriceCurrent();
double dOpenPrice=m_position.PriceOpen();
bool take_profit_level=false;
if(m_position.TakeProfit()>0 && ((etype==OP_BUY && m_position.TakeProfit()-m_position.PriceCurrent()>=m_freeze) || (etype==OP_SELL && m_position.PriceCurrent()-m_position.TakeProfit()>=m_freeze)))
take_profit_level=true;
if(m_position.TakeProfit()==0.0)
take_profit_level=true;
bool stop_loss_level=false;
if(m_position.StopLoss()>0 && ((etype==OP_BUY && MathAbs(m_position.PriceCurrent()-m_position.StopLoss())>=m_freeze) || (etype==OP_SELL && MathAbs(m_position.StopLoss()-m_position.PriceCurrent())>=m_freeze)))
stop_loss_level=true;
if(m_position.StopLoss()==0.0)
stop_loss_level=true;
if(take_profit_level && stop_loss_level)
{
m_trade.SetExpertMagicNumber(m_position.Magic());
if(m_trade.PositionClose(m_position.Ticket())) //закрывает позицию
{
orders[(int)etype]--;
m_all--;
bRet=true;
}
}
}
}
for(int i=OrdersTotal()-1; i>=0; i--)
{
if(!SelectByIndex(i,false))
continue;
flag=toMyTypes(m_order.OrderType())&itype;
if(itype==ALL || m_order.OrderType()==toDefType(flag,itype))
{
m_trade.SetExpertMagicNumber(m_position.Magic());
if(m_trade.OrderDelete(m_order.Ticket())) //закрывает позицию
{
orders[(int)m_order.OrderType()]--;
m_all--;
bRet=true;
}
}
}
return bRet;
}
bool OrderCloseAll(long iLockMagic,int itype)
{
__COPYRIGHT__
int c=0,flag;
bool bRet=false;
for(int i=PositionsTotal()-1; i>=0; i--)
{
if(!SelectByIndex(i,true))
continue;
int etype=m_position.PositionType();
long imagic=m_position.Magic();
if((itype==OP_BUY && ((etype==OP_BUY && imagic!=iLockMagic) || (etype==OP_SELL && imagic==iLockMagic)))
||
(itype==OP_SELL && ((etype==OP_SELL && imagic!=iLockMagic) || (etype==OP_BUY && imagic==iLockMagic))))
{
double dTakeProfit=m_position.TakeProfit();
double dStopLoss=m_position.StopLoss();
double dCurrentPrice=m_position.PriceCurrent();
double dOpenPrice=m_position.PriceOpen();
bool take_profit_level=false;
if(m_position.TakeProfit()>0 && ((etype==OP_BUY && m_position.TakeProfit()-m_position.PriceCurrent()>=m_freeze) || (etype==OP_SELL && m_position.PriceCurrent()-m_position.TakeProfit()>=m_freeze)))
take_profit_level=true;
if(m_position.TakeProfit()==0.0)
take_profit_level=true;
bool stop_loss_level=false;
if(m_position.StopLoss()>0 && ((etype==OP_BUY && MathAbs(m_position.PriceCurrent()-m_position.StopLoss())>=m_freeze) || (etype==OP_SELL && MathAbs(m_position.StopLoss()-m_position.PriceCurrent())>=m_freeze)))
stop_loss_level=true;
if(m_position.StopLoss()==0.0)
stop_loss_level=true;
if(take_profit_level && stop_loss_level)
{
m_trade.SetExpertMagicNumber(m_position.Magic());
if(m_trade.PositionClose(m_position.Ticket())) //закрывает позицию
{
orders[(int)etype]--;
m_all--;
bRet=true;
}
}
}
}
for(int i=OrdersTotal()-1; i>=0; i--)
{
if(!SelectByIndex(i,false))
continue;
flag=toMyTypes(m_order.OrderType())&itype;
if(itype==ALL || m_order.OrderType()==toDefType(flag,itype))
{
m_trade.SetExpertMagicNumber(m_position.Magic());
if(m_trade.OrderDelete(m_order.Ticket())) //закрывает позицию
{
orders[(int)m_order.OrderType()]--;
m_all--;
bRet=true;
}
}
}
return bRet;
}
virtual bool OrderCloseProfitAllNoLock(long iLockMagic,int itype)
{
__COPYRIGHT__
int c=0,flag;
bool bRet=false;
for(int i=PositionsTotal()-1; i>=0; i--)
{
if(!SelectByIndex(i,true))
continue;
int etype=m_position.PositionType();
flag=toMyTypes(etype)&itype;
long imagic=m_position.Magic();
if((itype==OP_BUY && ((etype==OP_BUY && imagic!=iLockMagic) || (etype==OP_SELL && imagic==iLockMagic)))
||
(itype==OP_SELL && ((etype==OP_SELL && imagic!=iLockMagic) || (etype==OP_BUY && imagic==iLockMagic))))
{
double dProfit=m_position.Profit()+m_position.Swap()+m_position.Commission();
if(dProfit>=0)
{
double dTakeProfit=m_position.TakeProfit();
double dStopLoss=m_position.StopLoss();
double dCurrentPrice=m_position.PriceCurrent();
bool take_profit_level=false;
if(m_position.TakeProfit()>0 && ((etype==OP_BUY && m_position.TakeProfit()-m_position.PriceCurrent()>=m_freeze) || (etype==OP_SELL && m_position.PriceCurrent()-m_position.TakeProfit()>=m_freeze)))
take_profit_level=true;
if(m_position.TakeProfit()==0.0)
take_profit_level=true;
bool stop_loss_level=false;
if(m_position.StopLoss()>0 && ((etype==OP_BUY && MathAbs(m_position.PriceCurrent()-m_position.StopLoss())>=m_freeze) || (etype==OP_SELL && MathAbs(m_position.StopLoss()-m_position.PriceCurrent())>=m_freeze)))
stop_loss_level=true;
if(m_position.StopLoss()==0.0)
stop_loss_level=true;
if(take_profit_level && stop_loss_level)
{
m_trade.SetExpertMagicNumber(m_position.Magic());
if(m_trade.PositionClose(m_position.Ticket())) //закрывает позицию
{
orders[(int)etype]--;
m_all--;
bRet=true;
}
}
}
}
}
for(int i=OrdersTotal()-1; i>=0; i--)
{
if(!SelectByIndex(i,false))
continue;
flag=toMyTypes(m_order.OrderType())&itype;
if(itype==ALL || m_order.OrderType()==toDefType(flag,itype))
{
m_trade.SetExpertMagicNumber(m_position.Magic());
if(m_trade.OrderDelete(m_order.Ticket())) //закрывает позицию
{
orders[(int)m_order.OrderType()]--;
m_all--;
bRet=true;
}
}
}
return bRet;
}
bool CloseByProfitInProcent(double dTPinProcent)
{
double dprofit=ND2(AccountBalance()*dTPinProcent/100);
double dSummProfit=getProfit(ALL);
if(dSummProfit>0 && dSummProfit>=dprofit)
{
OrderCloseAll(ALL);
return true;
}
return false;
}
bool SelfDestruct(int itype,long iLockMagic,double dTPinProcent)
{
int c=0;
bool bRet=false;
double dLockMinus=0;
double dSetkaPlus=0;
double dlock_lot=0;
double dprofits[];
ulong utickets[];
ulong ulock=0;
ArrayResize(utickets,0);
ArrayResize(dprofits,0);
double dTickProfit=SymbolInfoDouble(m_name,SYMBOL_TRADE_TICK_VALUE);
bool bLock=false;
for(int i=PositionsTotal()-1; i>=0; i--)
{
if(!SelectByIndex(i,true))
continue;
int etype=m_position.PositionType();
ulong imagic=m_position.Magic();
if((itype==OP_BUY && (etype==OP_BUY && imagic!=iLockMagic))
||
(itype==OP_SELL && (etype==OP_SELL && imagic!=iLockMagic)))
{
double dprofit=Profit();
if(dprofit>0)
{
int isize=ArraySize(utickets);
if(ArrayResize(utickets,isize+1)!=-1 && ArrayResize(dprofits,isize+1)!=-1)
{
utickets[isize]=m_position.Ticket();
dprofits[isize]=dprofit;
dSetkaPlus+=dprofit;
}
}
}
if((itype==OP_BUY && (etype==OP_SELL && imagic==iLockMagic))
||
(itype==OP_SELL && (etype==OP_BUY && imagic==iLockMagic)))
{
double dprofit=Profit();
if(dprofit<=0)
{
int isize=ArraySize(utickets);
if(ArrayResize(utickets,isize+1)!=-1 && ArrayResize(dprofits,isize+1)!=-1)
{
ulock=m_position.Ticket();
dlock_lot=m_position.Volume();
utickets[isize]=m_position.Ticket();
dprofits[isize]=ND2(OrderProfitPoint()*(dlock_lot/2)*dTickProfit);
dLockMinus+=dprofit;
bLock=true;
}
}
}
}
int isize=ArraySize(utickets);
if(bLock && dSetkaPlus>0 && isize>1 && NLot(dlock_lot)>=MinLot()*2)
{
double dprofit=ND2(AccountBalance()*dTPinProcent/100);
if(ND2(dSetkaPlus+dLockMinus)>=ND2(dprofit))
{
for(int i=0; i<isize; i++)
{
if(ulock==utickets[i])
{
m_trade.SetExpertMagicNumber(m_position.Magic());
PrintFormat("Close self-destruct #%lld profit: %.2f",utickets[i], ND2(dprofits[i]));
OrderClose(utickets[i],NLot(dlock_lot/2));//закрываем все перекрытые
}
else
{
m_trade.SetExpertMagicNumber(m_position.Magic());
PrintFormat("Close self-destruct #%lld profit: %.2f",utickets[i], dprofits[i]);
OrderClose(utickets[i]);//закрываем все перекрытые
}
}
return true;
}
}
return false;
}
virtual void SetAllforLock(long iLockMagic,int itype,double dstop,double dtake,bool bCheck=true,bool bForTral=false,double dTrailingStep=0)
{
int flag=0;
int itotal=PositionsTotal();
ulong iticket=0;
for(int i=itotal-1; i>=0; i--)
{
if(!SelectByIndex(i,true))
continue;
if(m_position.Magic()==iLockMagic || m_position.Magic()==iLockMagic+1)
continue;
iticket=m_position.Ticket();
long etype=m_position.PositionType();
flag=toMyTypes(etype)&itype;
if(etype==toDefType(flag,itype))
{
bool bModify=true;
double dOrderStopLoss=m_position.StopLoss();
double dOrderTakeProfit=m_position.TakeProfit();
if(dstop==0 && dtake==0 && dOrderTakeProfit==0 && dOrderStopLoss==0)
continue;
if(bForTral && dstop>0 && dOrderStopLoss>0)
{
if(etype==OP_BUY && nd(dstop-dOrderStopLoss,m_position.Symbol())<dTrailingStep*p)
bModify=false;
if(etype==OP_SELL && nd(dOrderStopLoss-dstop,m_position.Symbol())<dTrailingStep*p)
bModify=false;
}
if(dstop<0)
dstop=dOrderStopLoss;
if(dtake<0)
dtake=dOrderTakeProfit;
if(bModify)
{
if(CheckPositionModify(bCheck,m_position.Symbol(),etype,dOrderStopLoss,dOrderTakeProfit,dstop,dtake))
{
if(m_trade.PositionModify(iticket,dstop,dtake))
{
virtual_set(iticket,dstop,dtake);
}
}
else
{
}
}
}
}
}
void Run(int iTradeMode,long iLockMagic,double dTPinProcent,double dLockTP,double dLockBU,double dLockTral, double dLockNext,double dLockMultiplicator,double dKopilkaProcent,double dMinimalLot,bool bSelfDestruct)
{
string _sExpertName=WindowExpertName();
if(dLockBU>0)
bu_simple_magic(iLockMagic,dLockBU,0);
if(dLockTral>0)
trailing_simple_magic(iLockMagic,dLockTral,dLockTral);
double dprofit=ND2(AccountBalance()*dTPinProcent/100);
if(iTradeMode==OP_SELL)
{
string sType=TypeToString(iTradeMode);
double dKopilka=pglobal.LoadParam("Kopilka",0);
this.OnTick();
if(orders[OP_SELL]>=0)
{
if(bSelfDestruct)
{
if(SelfDestruct(OP_SELL,iLockMagic,dTPinProcent))
return; //для пересчета лока
}
double dSummLot=0;
double dLastPrice=0,dPrice=0; //цена от которой идет рассчет для установки следующего лока
datetime tmFirst=0,tmLast=0;
ulong tlock=getOrderTicket(OP_BUY,0,iLockMagic); //проверим наличие лока
if(OrderSelect(tlock))
{
double dtake=OrderTakeProfit();
if(dtake==0)
{
double dopen=OrderOpenPrice();
if(dLockTP>0 && _Bid>=dopen+dLockTP*p)
{
OrderClose(tlock);
return;
}
}
}
ulong tlast=getLastOrderTicket(iLockMagic,dSummLot,OP_SELL,ORDER_UP); //найдем самый верхний селл
/* if(dSummLot==0.0)
{
if(m_all>0)
{
Print("Close all orders.");
OrderCloseAll(iLockMagic,OP_SELL); //закроем оставшиеся ордера, так как основное направление (исправить закрытие)
}
return;
}*/
if(OrderSelect(tlast,true))
{
tmFirst=OrderOpenTime();
dPrice=OrderOpenPrice();
double dlot=OrderLots();
tmLast=tmFirst;
Kopilka(iLockMagic,dKopilkaProcent,dMinimalLot,tlast,dlot,dSummLot,OP_SELL,tmFirst);
if(OrderSelect(tlast,true))
{
dLastPrice=OrderOpenPrice();
}
}
/*
проверяем не находимся ли мы ниже последнего ордера
*/
if(tlock==0 && dLastPrice>0)
{
ulong thist=getHistoryOrderTicket(OP_BUY,tmLast,true);
#ifdef __MQL5__
if(HistoryDealSelect(thist))
{
long ideal_magic=HistoryDealGetInteger(thist,DEAL_MAGIC);
if(ideal_magic==iLockMagic)
{
ulong id=HistoryDealGetInteger(thist,DEAL_POSITION_ID);
double dCloseTP=OrderClosePrice(id);
double dOpenTP=OrderOpenPrice(id);
if(dCloseTP>0 && dCloseTP>dLastPrice)
dLastPrice=dCloseTP; //обновим цену от которой считать следующий вход локом
if(dPrice>0 && tmFirst>0 && dPrice<dLastPrice && _Ask<dLastPrice)
{
double dprices[];
int j=CopyLow(m_name,PERIOD_M1,tmFirst,TimeCurrent(),dprices);
ArraySetAsSeries(dprices,true);
for(int i=0; i<j; i++)
{
if(dprices[i]<=dPrice)
{
dLastPrice=dPrice;
break;
}
if(dprices[i]<=dOpenTP-dLockNext*p)
{
dLastPrice=dOpenTP;
}
}
}
}
}
#else
if(OrderSelect((int)thist,SELECT_BY_TICKET,MODE_HISTORY))
{
long ideal_magic=::OrderMagicNumber();
if(ideal_magic==iLockMagic)
{
double dCloseTP=::OrderClosePrice();
double dOpenTP=::OrderOpenPrice();
if(dCloseTP>0 && dCloseTP>dLastPrice)
dLastPrice=dCloseTP;Показано первые 50% кода (символов: 21893)
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.