class _global
Структура для хранения именованных данных (имя, числовое значение, временная метка), используемая внутри библиотеки для управления глобальными переменными.
Сообщите нам, если считаете, что материал размещён без разрешения.
Обращение по товару «orders.mq4» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
orders.mqh — библиотека исходного кода для MetaTrader 4, предоставляющая инструменты управления ордерами и позициями. Библиотека содержит класс COrders для открытия, закрытия, модификации ордеров и позиций, управления виртуальными стоп-лоссами и тейк-профитами, расчёта лотов, а также класс CGlobal для работы с глобальными переменными и профиля тестирования. Класс CSpeed используется для профилирования времени выполнения функций, а структура _global хранит именованные данные с временной меткой.
Классов: 4 · методов: 73 · конструкторов: 2 · деструкторов: 1 · отдельных функций: 0
class _global
Структура для хранения именованных данных (имя, числовое значение, временная метка), используемая внутри библиотеки для управления глобальными переменными.
class CSpeed
Класс для профилирования времени выполнения функций в тестере и во время работы советника.
class CGlobal
Класс для управления глобальными переменными терминала, включая сохранение, загрузку, проверку и удаление параметров с привязкой к имени эксперта и магическому номеру.
class COrders
Основной класс библиотеки для управления ордерами и позициями, включая открытие, закрытие, модификацию, виртуальные уровни и расчёт лотов.
CSpeed()
Создаёт экземпляр класса профилирования и запускает замер времени.
CSpeed(bool bprint)
Создаёт экземпляр класса профилирования с указанием необходимости вывода результатов в журнал.
~CSpeed()
Уничтожает экземпляр класса профилирования.
void Start(bool bprint)
Запускает замер времени выполнения с опциональным выводом результатов.
void Stop(string sfunc,string sdop)
Останавливает замер и выводит затраченное время в микросекундах.
void ReStart(string sfunc,string sdop)
Останавливает текущий замер, выводит результат и запускает новый замер.
void OnInit(string symbol,string sexpert,long imagic)
Инициализирует класс глобальных переменных, устанавливая символ, имя эксперта и магический номер.
void OnDeinit()
Освобождает ресурсы, очищая массив глобальных переменных.
void UpdateTime()
Обновляет временные метки глобальных переменных, сбрасывая устаревшие значения.
bool CheckGlobalParam(string name)
Проверяет наличие глобального параметра по имени с учётом привязки к эксперту и магическому номеру.
double SaveGlobalParam(string name,double data)
Сохраняет числовое значение в глобальную переменную с формированием ключа из имени эксперта, магического номера и параметра.
void DeleteGlobalParam(string name)
Удаляет глобальную переменную по имени с формированием ключа.
double LoadGlobalParam(string name,double ddefault_data)
Загружает числовое значение из глобальной переменной, возвращая значение по умолчанию при отсутствии.
double SaveParam(string name,double data)
Сохраняет числовой параметр в глобальную переменную с расширенным ключом, включающим имя символа.
bool CheckParam(string name)
Проверяет наличие параметра в глобальных переменных по расширенному ключу.
void DeleteParam(string name)
Удаляет параметр из глобальных переменных по расширенному ключу.
double LoadParam(string name,double ddefault_data)
Загружает числовой параметр из глобальных переменных, возвращая значение по умолчанию при отсутствии.
string SaveStringParam(string name,string data)
Сохраняет строковый параметр в глобальную переменную.
string LoadStringParam(string name,string ddefault_data)
Загружает строковый параметр из глобальных переменных, возвращая значение по умолчанию при отсутствии.
bool DeleteStringParam(string name)
Удаляет строковый параметр из глобальных переменных, возвращая флаг успешного удаления.
int GlobalCopy(_global &dest[],_global &src[])
Копирует массив структур _global из исходного массива в целевой.
int TesterFindIndexGlobal(string name)
Ищет индекс глобальной переменной по имени в массиве тестера.
int GlobalVariablesTotal()
Возвращает общее количество глобальных переменных с учётом режима тестера.
string GlobalVariableName(int index)
Возвращает имя глобальной переменной по индексу.
datetime GlobalVariableTime(string sname)
Возвращает временную метку глобальной переменной по имени.
double GlobalVariableGet(string name)
Возвращает числовое значение глобальной переменной по имени.
datetime GlobalVariableSet(string name,double value)
Устанавливает числовое значение глобальной переменной по имени.
bool GlobalVariableCheck(string name)
Проверяет существование глобальной переменной по имени.
bool GlobalVariableDel(string name)
Удаляет глобальную переменную по имени.
bool OnInitIndicators()
Вызывается при инициализации индикаторов советника, возвращает флаг успешности.
bool OnDeinitIndicators()
Вызывается при деинициализации индикаторов советника, возвращает флаг успешности.
int Signal()
Возвращает торговый сигнал (по умолчанию -1, требует переопределения в производном классе).
void SetGlobal(CGlobal *ppglobal,bool bInit)
Привязывает экземпляр класса CGlobal к текущему объекту ордеров с опциональной инициализацией.
void OnDeinit(const int reason)
Выполняет очистку ресурсов при деинициализации советника.
void Magic(long imagic)
Устанавливает магический номер для ордеров и сохраняет его в объекте.
long Magic()
Возвращает текущий магический номер.
void Symbol(string sname)
Устанавливает торговый символ, обновляя данные по нему и настраивая заполнение ордеров.
bool Check(CPositionInfo &position,long imagic)
Проверяет позицию на соответствие символу и магическому номеру.
bool Check(COrderInfo &order,long imagic)
Проверяет ордер на соответствие символу и магическому номеру.
bool Check(CDealInfo &deal,long imagic)
Проверяет сделку на соответствие символу и магическому номеру.
bool Check(string symbol,long imagic)
Проверяет переданный символ и магический номер на соответствие текущим настройкам.
bool CheckMagic(long imagic)
Устаревшая функция проверки магического номера; рекомендует использовать метод Check.
bool OnInit(string sName,long iMagic,int islippage)
Инициализирует объект ордеров, настраивая символ, магический номер, проскальзывание и параметры торговли.
bool IsPosition()
Возвращает флаг того, что текущий выбранный объект является позицией.
bool IsWork(string sSymbol)
Проверяет возможность торговли: открыт ли рынок, есть ли баланс, разрешён ли торговый режим.
bool IsNewDay()
Проверяет, начался ли новый торговый день.
bool SelectByIndex(int i,bool is_position)
Выбирает позицию или ордер по индексу с проверкой по магическому номеру и символу.
bool SelectAllMagic(int i,bool is_position)
Выбирает позицию или ордер по индексу без привязки к магическому номеру.
void OnTick()
Основной обработчик тика: обновляет котировки, пересчитывает позиции и ордера, запускает виртуальный контроль.
void doaction_OnTick()
Вспомогательный обработчик действий на каждом тике (пустая реализация по умолчанию).
int Count(int itype)
Подсчитывает количество позиций и ордеров указанного типа.
int Count(int itype,long imagic)
Подсчитывает количество позиций и ордеров указанного типа и магического номера.
ulong getLastHistoryTicket(int itype,datetime tmhistory,bool bIN)
Ищет последний тикет сделки в истории по типу, времени и направлению входа.
ulong getLastHistoryTicketByMagic(int itype,datetime tmhistory,long iMagic,bool bIN)
Ищет последний тикет сделки в истории по типу, времени, магическому номеру и направлению входа.
ulong getHistoryOrderTicket(int itype,datetime tmhistory,bool bIN)
Возвращает тикет исторического ордера по типу и времени (обёртка над getLastHistoryTicket).
ulong getHistoryOrderTicket(int itype,datetime tmhistory,long _iMagic,bool bIN)
Возвращает тикет исторического ордера по типу, времени и магическому номеру.
int CloseOrdersOnBar(ENUM_TIMEFRAMES etf,int &iorders[])
Подсчитывает и возвращает количество закрытых ордеров на текущем баре указанного таймфрейма.
int OpenOrdersOnBar(ENUM_TIMEFRAMES etf,int &iorders[])
Подсчитывает и возвращает количество открытых ордеров на текущем баре указанного таймфрейма.
void DeleteVariables(string sfind)
Удаляет глобальные переменные, связанные с закрытыми ордерами, по указанному префиксу.
void virtual_init()
Инициализирует виртуальный контроль позиций, проверяя и закрывая позиции по виртуальным уровням.
void virtual_show()
Отображает или удаляет графические линии виртуальных стоп-лоссов и тейк-профитов на графике.
void virtual_set(ulong iticket,double dsl,double dtp)
Устанавливает виртуальные уровни стоп-лосса и тейк-профита для указанного тикета в глобальных переменных.
bool virtual_check(ulong iticket)
Проверяет наличие виртуальных уровней стоп-лосса или тейк-профита для указанного тикета.
double virtual_get_tp(ulong iticket)
Возвращает виртуальный уровень тейк-профита для указанного тикета.
double virtual_get_var(ulong iticket,string svar)
Возвращает произвольное числовое значение виртуальной переменной по тикету и имени.
void virtual_set_var(ulong iticket,string svar,double dvar)
Устанавливает числовое значение виртуальной переменной по тикету и имени.
double virtual_get_sl(ulong iticket)
Возвращает виртуальный уровень стоп-лосса для указанного тикета.
void virtual_set_levels(ulong iticket,double dsl_pt,double dtp_pt)
Устанавливает виртуальные уровни стоп-лосса и тейк-профита в пунктах от цены открытия позиции.
double getLotByProcent(string m_name,ENUM_MM emm,double dprocent,double dstep)
Рассчитывает лот на основе указанного процента от баланса, эквити, свободной маржи или требуемой маржи.
double getLotByProcent(ENUM_MM emm,double dprocent,double dstep)
Рассчитывает лот на основе указанного процента и шага без привязки к имени символа.
double getLotBySL(double drisk,double dsl,double dbalance)
Рассчитывает лот на основе риска в денежном выражении и уровня стоп-лосса.
double getLotBySL_valute(double drisk_valute,double dsl)
Рассчитывает лот на основе риска в валюте счёта и уровня стоп-лосса.
double getLotBySL_valute(double drisk_valute,double dsl,double dcomission)
Рассчитывает лот с учётом комиссии, риска в валюте счёта и уровня стоп-лосса.
double getLotNoLeverage(double dbalance,double dvaluerisk,double dsl,double dopen,double dstoprisk)
Рассчитывает лот без учёта кредитного плеча с ограничением по максимальному риску.
bool CheckMaxSpread(double dMaxSpread)
Проверяет, не превышает ли текущий спред указанный максимальный уровень.
double getMaxLot()
Возвращает максимальный объём текущей позиции по символу и магическому номеру.
#ifndef __SOVETNIKOV_ORDERS_2sdfhgsd
#define __SOVETNIKOV_ORDERS_2sdfhgsd
#ifndef MYMATH
#define MYMATH
#endif
#include <sovetnikovNET\defines.mqh>
#include <sovetnikovNET\Draw.mqh>
/*
новое решение
*/
struct _global {
string name;
double data;
datetime time;
};
class CSpeed
{
protected:
ulong utimer;
bool bPrint;
public:
CSpeed()
{
Start(true);
}
CSpeed(bool bprint)
{
Start(bprint);
}
~CSpeed()
{
}
void Start(bool bprint)
{
bPrint=bprint;
if(bPrint)
utimer=GetMicrosecondCount();
}
void Stop(string sfunc,string sdop="")
{
if(!bPrint)
return; //выключено
ulong msec=GetMicrosecondCount()-utimer;
PrintFormat("CSpeed(%s): %s - %d microsec",sdop,sfunc,msec);
}
void ReStart(string sfunc,string sdop="")
{
if(!bPrint)
return; //выключено
ulong msec=GetMicrosecondCount()-utimer;
PrintFormat("CSpeed(%s): %s - %d microsec",sdop,sfunc,msec);
utimer=GetMicrosecondCount();
}
};
class CGlobal
{
protected:
string m_name;
string m_expert;
long m_imagic;
bool IsTester;
_global m_cglobal[];
public:
virtual void OnInit(string symbol,string sexpert,long imagic)
{
// код доступен только после оплаты
}
virtual void OnDeinit()
{
ArrayFree(m_cglobal); //очистим переменную глобальных перменных)
}
virtual void UpdateTime()
{
if(!IsTester) {
string spattern1=StringFormat("%s",m_expert);
string spattern2="_tp";
string spattern3="_sl";
for(int i=0; i<GlobalVariablesTotal(); i++) {
string svar=GlobalVariableName(i);
if(StringFind(svar,spattern1)==0 || StringFind(svar,spattern2)>0 || StringFind(svar,spattern3)>0) {
datetime tmUpdate=GlobalVariableTime(svar);
if(tmUpdate>0 && (long)(TimeCurrent()-tmUpdate)>=3*604800) {
double dvar=GlobalVariableGet(svar);
GlobalVariableSet(svar,dvar);
}
}
}
}
}
virtual bool CheckGlobalParam(string name)
{
string svar=StringFormat("%s.%d.%s",m_expert,m_imagic,name);
return GlobalVariableCheck(svar);
}
virtual double SaveGlobalParam(string name,double data)
{
GlobalVariableSet(StringFormat("%s.%d.%s",m_expert,m_imagic,name),data);
return data;
}
virtual void DeleteGlobalParam(string name)
{
GlobalVariableDel(StringFormat("%s.%d.%s",m_expert,m_imagic,name));
}
virtual double LoadGlobalParam(string name,double ddefault_data=0)
{
double data=ddefault_data;
data=GlobalVariableGet(StringFormat("%s.%d.%s",m_expert,m_imagic,name));
if(data==0.0)
data=ddefault_data;
return (data);
}
virtual double SaveParam(string name,double data)
{
string svar=StringFormat("%s.%s.%d.%s",m_expert,m_name,m_imagic,name);
GlobalVariableSet(svar,data);
return data;
}
virtual bool CheckParam(string name)
{
string svar=StringFormat("%s.%s.%d.%s",m_expert,m_name,m_imagic,name);
return GlobalVariableCheck(svar);
}
virtual void DeleteParam(string name)
{
GlobalVariableDel(StringFormat("%s.%s.%d.%s",m_expert,m_name,m_imagic,name));
}
virtual double LoadParam(string name,double ddefault_data=0)
{
double data=ddefault_data;
string name_global=StringFormat("%s.%s.%d.%s",m_expert,m_name,m_imagic,name);
if(GlobalVariableCheck(name_global)==false)
data=ddefault_data;
else
data=(double)GlobalVariableGet(name_global);
return data;
}
string SaveStringParam(string name,string data)
{
GlobalVariableSet(StringFormat("%s.%d.%s=%s",m_expert,m_imagic,name,data),1);
return data;
}
string LoadStringParam(string name,string ddefault_data="")
{
string sfull_name=StringFormat("%s.%d.%s",m_expert,m_imagic,name);
string sparam[];
for(int i=0; i<GlobalVariablesTotal(); i++) {
string svar=GlobalVariableName(i);
string_explode("=",svar,sparam);
if(ArraySize(sparam)==2 && StringCompare(sfull_name,sparam[0],false)==0) {
return sparam[1]; //нашли
}
}
return ddefault_data;
}
bool DeleteStringParam(string name)
{
string sfull_name=StringFormat("%s.%d.%s",m_expert,m_imagic,name);
string sparam[];
bool bFind=false;
for(int i=GlobalVariablesTotal()-1; i>=0; i--) {
string svar=GlobalVariableName(i);
string_explode("=",svar,sparam);
if(ArraySize(sparam)==2 && StringCompare(sfull_name,sparam[0],false)==0) {
GlobalVariableDel(svar);
bFind=true;
}
}
return bFind;
}
int GlobalCopy(_global &dest[],_global &src[])
{
int isize=ArraySize(src);
if(ArrayResize(dest,isize)!=-1) {
for(int i=0; i<isize; i++) {
dest[i].data=src[i].data;
dest[i].name=src[i].name;
dest[i].time=src[i].time;
}
return isize;
}
return false;
}
int TesterFindIndexGlobal(string name)
{
int isize=ArraySize(m_cglobal);
for(int i=isize-1; i>=0; i--) {
if(StringCompare(m_cglobal[i].name,name,false)==0)
return i; //найдем индекс
}
return -1;
}
int GlobalVariablesTotal()
{
if(IsTester) {
return ArraySize(m_cglobal);
}
return ::GlobalVariablesTotal();
}
string GlobalVariableName(int index)
{
if(IsTester) {
int isize=ArraySize(m_cglobal);
if(index<0 || index>=isize)
return "";
return m_cglobal[index].name;
}
return ::GlobalVariableName(index);
}
datetime GlobalVariableTime(string sname)
{
if(IsTester) {
int index = TesterFindIndexGlobal(sname);
if(index<0)
return 0;//ошибка
return m_cglobal[index].time;
}
return ::GlobalVariableTime(sname);
}
double GlobalVariableGet(string name)
{
if(IsTester) {
int index=TesterFindIndexGlobal(name);
if(index==-1) {
return false;
}
return m_cglobal[index].data;
}
return ::GlobalVariableGet(name);
}
datetime GlobalVariableSet(string name,double value)
{
if(IsTester) {
int index=TesterFindIndexGlobal(name);
if(index!=-1) {
m_cglobal[index].data=value;
m_cglobal[index].time=TimeCurrent();
} else if(index==-1 && name!="") {
int isize=ArraySize(m_cglobal);
if(ArrayResize(m_cglobal,isize+1)!=-1) {
m_cglobal[isize].name=name;
m_cglobal[isize].data=value;
m_cglobal[isize].time=TimeCurrent();
isize=ArraySize(m_cglobal);
} else {
PrintFormat("(%d) Invalid resize m_cglobal error: %d",__LINE__,GetLastError());
return 0; //ошибка
}
}
return TimeCurrent();
}
return ::GlobalVariableSet(name,value);
}
bool GlobalVariableCheck(string name)
{
if(IsTester) {
int index=TesterFindIndexGlobal(name);
if(index==-1)
return false;
return true;
}
return ::GlobalVariableCheck(name);
}
bool GlobalVariableDel(string name)
{
if(IsTester) {
int index=TesterFindIndexGlobal(name);
if(index==-1) {
return false;
}
_global newglobal[];
int inewsize=0;
int isize=ArraySize(m_cglobal);
if(GlobalCopy(newglobal,m_cglobal)>0) {
isize=0;
ArrayResize(m_cglobal,0); //переформируем структуру
inewsize=ArraySize(newglobal);
for(int i=0; i<inewsize; i++) {
if(newglobal[i].name!=name) {
if(ArrayResize(m_cglobal,isize+1)!=-1) {
m_cglobal[isize].name=newglobal[i].name;
m_cglobal[isize].data=newglobal[i].data;
m_cglobal[isize].time=newglobal[i].time;
isize++;
}
}
}
return true;
}
return false;
}
return (bool)::GlobalVariableDel(name);
}
};
class COrders
{
public:
COrderInfo m_order;
CHistoryOrderInfo m_history;
CPositionInfo m_position; // object of CPositionInfo class
CTrade m_trade; // object of CTrade class
CSymbolInfo m_symbol; // object of CSymbolInfo class
CAccountInfo m_account; // object of CAccountInfo class
CDealInfo m_deal; // object of CDealInfo class
CGlobal *pglobal;
CDraw m_drawvirtual;
double p;
int ierrors;
string serrors;
ulong tmLastTick;
CNewBar m_newday;
bool IsTester;
bool IsDraw;
string m_name;
long m_imagic;
int m_islippage;
int m_all,orders[6];
double _Ask,_Bid;
double dTralProfit;
bool m_bClose;
double dBuProfit;
bool m_bBuClose;
double dProfit;
double dPositionCapital;
bool options_bNewDay; //включает новый день (авто включение если не задано)
int options_bTickPause; //включает паузу >0 при работе по тиках, когда точность тиковая не критична, это ускоряет тест
int options_iPovtor; //кол-во поппыток при открытии ордера
bool options_bNoCheckPending; //отключает проверку лимиток на наличие денег
bool options_bCheckMargin; //проверять маржу при открытии
bool options_bVirtualControl;
bool options_bECN;
bool m_bposition;
string sWindowExpertName;
virtual bool OnInitIndicators()
{
return true;
}
virtual bool OnDeinitIndicators()
{
return true;
}
virtual int Signal()
{
return -1;
}
virtual void SetGlobal(CGlobal *ppglobal,bool bInit=true)
{
if(bInit)
ppglobal.OnInit(m_name,sWindowExpertName,m_imagic);
pglobal=ppglobal;
}
virtual void OnDeinit(const int reason=0)
{
OnDeinitIndicators();
m_drawvirtual.OnDeinit();
}
virtual void Magic(long imagic)
{
m_imagic=imagic;
m_trade.SetExpertMagicNumber(m_imagic);
}
virtual long Magic()
{
return m_imagic;
}
virtual void Symbol(string sname)
{
m_name=sname;
if(sname!=NULL) {
m_symbol.Name(sname);
m_symbol.Refresh(); //обновим данные по символу
m_trade.SetTypeFillingBySymbol(sname);
p=point(sname);
}
}
virtual bool Check(CPositionInfo &position,long imagic)
{
string symbol=position.Symbol();
return Check(symbol,imagic);
}
virtual bool Check(COrderInfo &order,long imagic)
{
string symbol=order.Symbol();
return Check(symbol,imagic);
}
virtual bool Check(CDealInfo &deal,long imagic)
{
string symbol=deal.Symbol();
return Check(symbol,imagic);
}
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;
}
bool CheckMagic(long imagic)
{
Print("Устаревшая функция. Использовать Check(position/order/deal,magic)");
return false;
}
virtual bool OnInit(string sName,long iMagic,int islippage)
{
// код доступен только после оплаты
}
bool IsPosition()
{
return m_bposition;
}
bool IsWork(string sSymbol=NULL)
{
if(options_bTickPause>0) {
if((long)(TimeCurrent()-tmLastTick)<options_bTickPause && tmLastTick>0) {
return false;
}
tmLastTick=TimeCurrent();
}
if(sSymbol==NULL)
sSymbol=m_name;
if(!checkMarketIsOpen(sSymbol)) {
return false; //неторговое время (проверка на клиринг)
}
if(IsTester) {
return true;
}
if(AccountInfoDouble(ACCOUNT_BALANCE)==0.0)
return false;
if(!work_check()) {
return false;
}
if(!checkTradeMode(sSymbol)) {
return false; //торговля по инструменту запрещена
}
return true;
}
bool IsNewDay()
{
if(!options_bNewDay)
options_bNewDay=true;
return m_newday.isNewBar();
}
/*
выбираем позицию или ордер, првоеряем их по меджику и инструменту, если ок то возвращаем true
*/
virtual bool SelectByIndex(int i,bool is_position)
{
if(is_position) {
if(!m_position.SelectByIndex(i)) {
return false;
}
if(Check(m_position,m_position.Magic())) {
return true;
}
} else {
if(!m_order.SelectByIndex(i))
return false;
if(m_order.OrderType()>=6)
return false; //не пропустим ордера с нестандартным типом отложки и рыночные стандартные ордера обрабатываем только
if(Check(m_order,m_order.Magic()))
return true;
}
return false;
}
virtual bool SelectAllMagic(int i,bool is_position)
{
if(is_position) {
if(!m_position.SelectByIndex(i))
return false;
if(Check(m_position,-1))
return true;
} else {
if(!m_order.SelectByIndex(i))
return false;
if(m_order.OrderType()>=6)
return false; //не пропустим ордера с нестандартным типом отложки и рыночные стандартные ордера обрабатываем только
if(Check(m_order,-1))
return true;
}
return false;
}
/*
Основной цикл обработки позиций и ордеров (если требуется подгрузить какие данные и будет за основу взять для закрытия и других функций)
*/
virtual void OnTick()
{
// код доступен только после оплаты
}
virtual void doaction_OnTick()
{
}
int Count(int itype)
{
__COPYRIGHT__
int iall=0;
int flag=toMyTypes(OP_BUY)&itype;
if(toDefType(flag,itype)==OP_BUY)
iall+=orders[OP_BUY];
flag=toMyTypes(OP_SELL)&itype;
if(toDefType(flag,itype)==OP_SELL)
iall+=orders[OP_SELL];
flag=toMyTypes(OP_SELLLIMIT)&itype;
if(toDefType(flag,itype)==OP_SELLLIMIT)
iall+=orders[OP_SELLLIMIT];
flag=toMyTypes(OP_SELLSTOP)&itype;
if(toDefType(flag,itype)==OP_SELLSTOP)
iall+=orders[OP_SELLSTOP];
flag=toMyTypes(OP_BUYLIMIT)&itype;
if(toDefType(flag,itype)==OP_BUYLIMIT)
iall+=orders[OP_BUYLIMIT];
flag=toMyTypes(OP_BUYSTOP)&itype;
if(toDefType(flag,itype)==OP_BUYSTOP)
iall+=orders[OP_BUYSTOP];
return iall;
}
int Count(int itype,long imagic)
{
__COPYRIGHT__
int ic=0;
for(int i=0; i<PositionsTotal(); i++) {
if(!m_position.SelectByIndex(i))
continue; //если не выбирает, пропускаем
if(this.OrderType(true)<2) {
int flag=toMyTypes(this.OrderType(true))&itype;
if((imagic==-1 || imagic==this.OrderMagicNumber(true)) && (m_name==NULL || m_name==this.OrderSymbol(true))) {
if(this.OrderType(true)==toDefType(flag,itype) || itype==ALL) {
ic++;
}
}
}
}
for(int i=0; i<OrdersTotal(); i++) {
if(!m_order.SelectByIndex(i))
continue; //если не выбирает, пропускаем
if(this.OrderType(false)>=2) {
int flag=toMyTypes(this.OrderType(false))&itype;
if((imagic==-1 || imagic==this.OrderMagicNumber(false)) && (m_name==NULL || m_name==this.OrderSymbol(false))) {
if(this.OrderType(false)==toDefType(flag,itype) || itype==ALL)
ic++;
}
}
}
return ic;
}
virtual ulong getLastHistoryTicket(int itype,datetime tmhistory,bool bIN=true)
{
HistorySelect(tmhistory,TimeCurrent()); //загрузем историю последнего месяца
if(!bIN) {
itype=InverseSignal((ENUM_ORDER_TYPE)itype);
}
for(int i=HistoryDealsTotal()-1; i>=0; i--) {
if(!m_deal.SelectByIndex(i))
continue;
if(m_deal.DealType()==DEAL_TYPE_BUY || m_deal.DealType()==DEAL_TYPE_SELL) {
if((m_deal.Magic()==m_imagic || m_imagic==-1) && (m_deal.Symbol()==m_name || m_name==NULL)) {
if(((m_deal.Entry()==DEAL_ENTRY_IN && bIN) || (m_deal.Entry()==DEAL_ENTRY_OUT && !bIN)) && (itype==ALL || itype==m_deal.DealType())) { //было открытие
if(m_deal.Time()>=tmhistory) {
return m_deal.Ticket();
}
}
}
}
}
return 0;
}
virtual ulong getLastHistoryTicketByMagic(int itype,datetime tmhistory,long iMagic,bool bIN=true)
{
HistorySelect(tmhistory,TimeCurrent()); //загрузем историю последнего месяца
if(!bIN) {
itype=InverseSignal((ENUM_ORDER_TYPE)itype);
}
for(int i=HistoryDealsTotal()-1; i>=0; i--) {
if(!m_deal.SelectByIndex(i))
continue;
if(m_deal.DealType()==DEAL_TYPE_BUY || m_deal.DealType()==DEAL_TYPE_SELL) {
if((m_deal.Magic()==iMagic) && (m_deal.Symbol()==m_name || m_name==NULL)) {
if(((m_deal.Entry()==DEAL_ENTRY_IN && bIN) || (m_deal.Entry()==DEAL_ENTRY_OUT && !bIN)) && (itype==ALL || itype==m_deal.DealType())) { //было открытие
if(m_deal.Time()>tmhistory) {
return m_deal.Ticket();
}
}
}
}
}
return 0;
}
virtual ulong getHistoryOrderTicket(int itype,datetime tmhistory,bool bIN=true)
{
return getLastHistoryTicket(itype,tmhistory,bIN);
}
virtual ulong getHistoryOrderTicket(int itype,datetime tmhistory,long _iMagic,bool bIN=true)
{
return getLastHistoryTicketByMagic(itype,tmhistory,_iMagic,bIN);
}
virtual int CloseOrdersOnBar(ENUM_TIMEFRAMES etf,int &iorders[])
{
ArrayResize(iorders,10);
ArrayInitialize(iorders,0);
datetime tStart=iTime(m_name,etf,0);
datetime tEnd=TimeCurrent();
HistorySelect(tStart,tEnd);
int itotal=HistoryDealsTotal();
int icount=0;
int itype=-1;
for(int i=0; i<itotal; i++) {
if(!m_deal.SelectByIndex(i))
continue;
if(Check(m_deal,m_deal.Magic())) {
itype=(int)m_deal.DealType();
datetime tmOpen=0;
if(m_deal.Entry()==DEAL_ENTRY_OUT) {
tmOpen=(datetime)m_deal.Time();
if(tmOpen>0) {
int iBar=iBarShift(m_symbol.Name(),etf,tmOpen);
if(iBar==0) {
if(itype==OP_BUY)
iorders[OP_SELL]++;
if(itype==OP_SELL)
iorders[OP_BUY]++;
icount++;
}
}
}
}
}
return icount;
}
virtual int OpenOrdersOnBar(ENUM_TIMEFRAMES etf,int &iorders[])
{
ArrayResize(iorders,10);
ArrayInitialize(iorders,0);
datetime tStart=iTime(m_name,etf,0);
datetime tEnd=TimeCurrent();
HistorySelect(tStart,tEnd);
int itotal=HistoryDealsTotal();
int icount=0;
int itype=-1;
for(int i=itotal-1; i>=0; i--) {
if(!m_deal.SelectByIndex(i))
continue;
if(Check(m_deal,m_deal.Magic())) {
itype=(int)m_deal.DealType();
datetime tmOpen=0;
if(m_deal.Entry()==DEAL_ENTRY_IN) {
tmOpen=(datetime)m_deal.Time();
if(tmOpen>0) {
int iBar=iBarShift(m_deal.Symbol(),etf,tmOpen);
if(iBar==0) {
iorders[itype]++;
icount++;
}
}
}
}
}
return icount;
}
virtual void DeleteVariables(string sfind)
{
if(CheckPointer(pglobal)==POINTER_INVALID)
return;
int isize=pglobal.GlobalVariablesTotal();
string sglobal="";
for(int i=isize-1; i>=0; i--) {
sglobal=pglobal.GlobalVariableName(i);
if(sglobal=="" || sglobal==NULL)
continue;
if(StringFind(sglobal,StringFormat("_%s",sfind))<0)
continue; //пропустим не наши
string sret[];
int j=string_explode("_",sglobal,sret);
if(j==2) {
ulong iticket=(ulong)StringToInteger(sret[0]);
if(iticket>0) {
if(!PositionSelectByTicket(iticket)) {
pglobal.GlobalVariableDel(sglobal); //удалим переменную закрытого ордера
}
}
}
}
}
virtual void virtual_init()
{
if(CheckPointer(pglobal)==POINTER_INVALID)
return;
string param[],n;
int i,itype=-1,isizeParam=0;
int isize=0;
isize=pglobal.GlobalVariablesTotal();
for(i=isize-1; i>=0; i--) {
string sglobal=pglobal.GlobalVariableName(i);
if(sglobal=="" || sglobal==NULL)
continue;
if(StringFind(sglobal,"_sl")<0 && StringFind(sglobal,"_tp")<0) {
continue; //пропустим не наши
}
string_explode("_",sglobal,param);
isizeParam=ArraySize(param);
if(isizeParam<2 && isizeParam>3)
continue; //пропустим сразу неподходящие под наши правила
if(isizeParam==2 && StringToInteger(param[0])>0) {
ulong iticket=(ulong)StringToInteger(param[0]);//тикет
if(iticket<=0)
continue;
#ifdef __MQL5__
if(!m_position.SelectByTicket(iticket)) {
pglobal.GlobalVariableDel(sglobal);
ObjectDelete(ChartID(),sglobal);
}
#else
if(::OrderSelect((int)iticket,SELECT_BY_TICKET,MODE_HISTORY)) {
if(::OrderCloseTime()>0) {
pglobal.GlobalVariableDel(sglobal);
ObjectDelete(ChartID(),sglobal);
}
}
#endif
if(m_position.SelectByTicket(iticket)) {
itype=m_position.PositionType();
n=m_position.Symbol();
double pt=0;
double dtp=0;
double dsl=0;
dtp=virtual_get_tp(iticket);
dsl=virtual_get_sl(iticket);
if(dtp==0 && dsl==0)
continue;
MqlTick tick;
SymbolInfoTick(n,tick);
if(dtp!=0 && ((tick.bid>=dtp && itype==OP_BUY) || (tick.ask<=dtp && itype==OP_SELL))) {
if(OrderClose(iticket,0)) {
Print("Close by TP: ",iticket," tp=",dtp);
pglobal.GlobalVariableDel(sglobal);
m_drawvirtual.Delete(ChartID(),StringFormat("%lld_tp",iticket));
m_drawvirtual.Delete(ChartID(),StringFormat("%lld_sl",iticket));
}
}//close by dtp
if(dsl!=0 && ((tick.bid<=dsl && itype==OP_BUY) || (tick.ask>=dsl && itype==OP_SELL))) {
if(OrderClose(iticket,0)) {
Print("Close by SL: ",iticket," sl=",dsl);
pglobal.GlobalVariableDel(sglobal);
m_drawvirtual.Delete(ChartID(),StringFormat("%lld_tp",iticket));
m_drawvirtual.Delete(ChartID(),StringFormat("%lld_sl",iticket));
}
}//close by dstop
}
}
}
}
void virtual_show()
{
if(!options_bVirtualControl)
return;
if(CheckPointer(pglobal)==POINTER_INVALID)
return;
string param[];
int i,itype=-1,isizeParam=0;
int isize=0;
isize=pglobal.GlobalVariablesTotal();
for(i=isize-1; i>=0; i--) {
string sglobal=pglobal.GlobalVariableName(i);
if(sglobal=="" || sglobal==NULL)
continue;
if(StringFind(sglobal,"_sl")<0 && StringFind(sglobal,"_tp")<0) {
continue; //пропустим не наши
}
string_explode("_",sglobal,param);
isizeParam=ArraySize(param);
if(isizeParam<2 && isizeParam>3)
continue; //пропустим сразу неподходящие под наши правила
if(isizeParam==2 && StringToInteger(param[0])>0) {
ulong iticket=(ulong)StringToInteger(param[0]);//тикет
if(iticket<=0)
continue;
if(OrderSelect(iticket,true)) {
datetime tmglobal=m_position.Time();
double dstop=m_position.StopLoss();
double dtake=m_position.TakeProfit();
double dtp=0;
double dsl=0;
dtp=virtual_get_tp(iticket);
dsl=virtual_get_sl(iticket);
if(nd(dtp)==nd(dtake))
dtp=0;
if(nd(dsl)==nd(dstop))
dsl=0;
if(dtp>0)
m_drawvirtual.DrawLine(ChartID(),StringFormat("%lld_tp",iticket),0,tmglobal,dtp,TimeCurrent(),dtp,1,STYLE_DASHDOT,clrGreen,false,false,StringFormat("#%lld TP",iticket),true);
else
m_drawvirtual.Delete(ChartID(),StringFormat("%lld_tp",iticket));
if(dsl>0)
m_drawvirtual.DrawLine(ChartID(),StringFormat("%lld_sl",iticket),0,tmglobal,dsl,TimeCurrent(),dsl,1,STYLE_DASHDOT,clrRed,false,false,StringFormat("#%lld SL",iticket),true);
else
m_drawvirtual.Delete(ChartID(),StringFormat("%lld_sl",iticket));
} else {
m_drawvirtual.Delete(ChartID(),StringFormat("%lld_tp",iticket));
m_drawvirtual.Delete(ChartID(),StringFormat("%lld_sl",iticket));
}
}
}
for(i=ObjectsTotal(ChartID(),-1,-1)-1; i>=0; i--) {
string sglobal=ObjectName(ChartID(),i,-1,-1);
if(sglobal=="" || sglobal==NULL)
continue;
if(StringFind(sglobal,"_sl")<0 && StringFind(sglobal,"_tp")<0) {
continue; //пропустим не наши
}
string_explode("_",sglobal,param);
isizeParam=ArraySize(param);
if(isizeParam==3 && StringToInteger(param[1])>0 && param[0]=="virtual") {
ulong iticket=(ulong)StringToInteger(param[1]);//тикет
if(iticket<=0)
continue;
#ifdef __MQL5__
if(!m_position.SelectByTicket(iticket)) {
ObjectDelete(ChartID(),sglobal);
}
#else
if(::OrderSelect((int)iticket,SELECT_BY_TICKET,MODE_HISTORY)) {
if(::OrderCloseTime()>0) {
ObjectDelete(ChartID(),sglobal);
}
}
#endif
}
}
}
void virtual_set(ulong iticket,double dsl,double dtp)
{
if(iticket<=0)
return;
if(CheckPointer(pglobal)==POINTER_INVALID)
return;
string n;
int idgt=digits(_Symbol);
n=StringFormat("%lld_tp",iticket);
if(dtp>=0)
pglobal.GlobalVariableSet(n,dtp);
else
pglobal.GlobalVariableDel(n);
n=StringFormat("%lld_sl",iticket);
if(dsl>=0)
pglobal.GlobalVariableSet(n,dsl);
else
pglobal.GlobalVariableDel(n);
}
bool virtual_check(ulong iticket)
{
if(iticket<=0)
return false;
if(CheckPointer(pglobal)==POINTER_INVALID)
return false;
string n;
n=StringFormat("%lld_tp",iticket);
if(pglobal.GlobalVariableCheck(n))
return true;
n=StringFormat("%lld_sl",iticket);
if(pglobal.GlobalVariableCheck(n))
return true;
return false;
}
double virtual_get_tp(ulong iticket)
{
if(iticket<=0)
return 0;
if(CheckPointer(pglobal)==POINTER_INVALID)
return false;
string n;
n=StringFormat("%lld_tp",iticket);
if(pglobal.GlobalVariableCheck(n))
return pglobal.GlobalVariableGet(n);
return 0;
}
double virtual_get_var(ulong iticket,string svar)
{
if(iticket<=0)
return 0;
if(CheckPointer(pglobal)==POINTER_INVALID)
return 0;
string n;
n=StringFormat("%lld_%s",iticket,svar);
if(pglobal.GlobalVariableCheck(n))
return pglobal.GlobalVariableGet(n);
return 0;
}
void virtual_set_var(ulong iticket,string svar,double dvar)
{
if(iticket<=0)
return;
if(CheckPointer(pglobal)==POINTER_INVALID)
return;
string n;
if(dvar>=0) {
n=StringFormat("%lld_%s",iticket,svar);
pglobal.GlobalVariableSet(n,dvar);
}
}
double virtual_get_sl(ulong iticket)
{
if(iticket<=0)
return 0;
if(CheckPointer(pglobal)==POINTER_INVALID)
return 0;
string n;
n=StringFormat("%lld_sl",iticket);
if(pglobal.GlobalVariableCheck(n))
return pglobal.GlobalVariableGet(n);
return 0;
}
void virtual_set_levels(ulong iticket,double dsl_pt,double dtp_pt)
{
if(iticket>0 && OrderSelect(iticket,true)) {
string ssmb=m_position.Symbol();
double dpp=point(ssmb);
double dopen=m_position.PriceOpen();
double dstop=0;
double dtake=0;
int itype=m_position.PositionType();
if(itype==POSITION_TYPE_BUY) {
if(dsl_pt>0)
dstop=dopen-dsl_pt*dpp;
if(dtp_pt>0)
dtake=dopen+dtp_pt*dpp;
}
if(itype==POSITION_TYPE_SELL) {
if(dsl_pt>0)
dstop=dopen+dsl_pt*dpp;
if(dtp_pt>0)
dtake=dopen-dtp_pt*dpp;
}
virtual_set(iticket,dstop,dtake);
}
}
static double getLotByProcent(string m_name,ENUM_MM emm,double dprocent,double dstep)
{
double dlot=0;
if(dprocent<=0)
return 0;
if(emm==MM_Balance) {
dlot=NLot(0.01*(AccountBalance()*dprocent*0.001));
} else if(emm==MM_Equity) {
dlot=NLot(0.01*(AccountEquity()*dprocent*0.001));
} else if(emm==MM_FreeMargin) {
dlot=NLot(0.01*(AccountFreeMargin()*dprocent*0.001));
} else if(emm==MM_MarginRequired) {
double marginInit=SymbolInfoDouble(m_name,SYMBOL_MARGIN_INITIAL);
if(marginInit>0)
dlot=NLot(0.01*AccountBalance()*dprocent/marginInit);
else
dlot=0;
} else if(emm==MM_BalanceStep && dstep>0) {
dlot=NLot(AccountBalance()*dprocent/dstep);
} else if(emm==MM_EquityStep && dstep>0) {
dlot=NLot(AccountEquity()*dprocent/dstep);
} else if(emm==MM_FreeMarginStep && dstep>0) {
dlot=NLot(AccountFreeMargin()*dprocent/dstep);
} else if(emm==MM_MarginProcent && dprocent>0 && dstep>0) {
double initial_margin_rate=1,maintenance_margin_rate=0;
#ifdef __MQL5__
SymbolInfoMarginRate(
m_name, // символ
ORDER_TYPE_BUY,
initial_margin_rate, // коэффициент взимания начальной маржи
maintenance_margin_rate // коэффициент взимания поддерживающей маржи
);
#endif
if(SymbolInfoInteger(m_name,SYMBOL_TRADE_CALC_MODE) == SYMBOL_CALC_MODE_FOREX) {
double dprice=1;
if(StringFind(m_name,"GOLD")>=0 || StringFind(m_name,"XAU")>=0 || StringFind(m_name,"XAG")>=0)
dprice=dstep;
dlot=NLot(0.01*dprocent*AccountBalance()*AccountInfoInteger(ACCOUNT_LEVERAGE)/(SymbolInfoDouble(m_name,SYMBOL_TRADE_CONTRACT_SIZE)*initial_margin_rate*dprice));
}
#ifdef __MQL5__
if(SymbolInfoInteger(m_name,SYMBOL_TRADE_CALC_MODE) == SYMBOL_CALC_MODE_FOREX_NO_LEVERAGE) {
dlot=NLot(0.01*dprocent*AccountBalance()/(SymbolInfoDouble(m_name,SYMBOL_TRADE_CONTRACT_SIZE)*initial_margin_rate));
}
#endif
if(SymbolInfoInteger(m_name,SYMBOL_TRADE_CALC_MODE)==SYMBOL_CALC_MODE_FUTURES) {
double marginInit=SymbolInfoDouble(m_name,SYMBOL_MARGIN_INITIAL);
dlot=NLot(0.01*dprocent*AccountBalance()/(marginInit*initial_margin_rate));
}
if(SymbolInfoInteger(m_name,SYMBOL_TRADE_CALC_MODE) == SYMBOL_CALC_MODE_CFD) {
dlot=NLot(0.01*dprocent*AccountBalance()/(SymbolInfoDouble(m_name,SYMBOL_TRADE_CONTRACT_SIZE)*initial_margin_rate*dstep));
}
if(SymbolInfoInteger(m_name,SYMBOL_TRADE_CALC_MODE) == SYMBOL_CALC_MODE_CFDLEVERAGE) {
dlot=NLot(0.01*dprocent*AccountBalance()*AccountInfoInteger(ACCOUNT_LEVERAGE)/(SymbolInfoDouble(m_name,SYMBOL_TRADE_CONTRACT_SIZE)*initial_margin_rate*dstep));
}
}
return dlot;
}
virtual double getLotByProcent(ENUM_MM emm,double dprocent,double dstep=0)
{
double dlot=0;
if(dprocent<=0)
return 0;
if(emm==MM_Balance) {
dlot=NLot(0.01*(AccountBalance()*dprocent*0.001));
} else if(emm==MM_Equity) {
dlot=NLot(0.01*(AccountEquity()*dprocent*0.001));
} else if(emm==MM_FreeMargin) {
dlot=NLot(0.01*(AccountFreeMargin()*dprocent*0.001));
} else if(emm==MM_MarginRequired) {
double marginInit=SymbolInfoDouble(m_name,SYMBOL_MARGIN_INITIAL);
if(marginInit>0)
dlot=NLot(0.01*AccountBalance()*dprocent/marginInit);
else
dlot=0;
} else if(emm==MM_BalanceStep && dstep>0) {
dlot=NLot(AccountBalance()*dprocent/dstep);
} else if(emm==MM_EquityStep && dstep>0) {
dlot=NLot(AccountEquity()*dprocent/dstep);
} else if(emm==MM_FreeMarginStep && dstep>0) {
dlot=NLot(AccountFreeMargin()*dprocent/dstep);
} else if(emm==MM_MarginProcent && dprocent>0 && dstep>0) {
double initial_margin_rate=1,maintenance_margin_rate=0;
#ifdef __MQL5__
SymbolInfoMarginRate(
m_name, // символ
ORDER_TYPE_BUY,
initial_margin_rate, // коэффициент взимания начальной маржи
maintenance_margin_rate // коэффициент взимания поддерживающей маржи
);
#endif
if(SymbolInfoInteger(m_name,SYMBOL_TRADE_CALC_MODE) == SYMBOL_CALC_MODE_FOREX) {
double dprice=1;
if(StringFind(m_name,"GOLD")>=0 || StringFind(m_name,"XAU")>=0 || StringFind(m_name,"XAG")>=0)
dprice=dstep;
dlot=NLot(0.01*dprocent*AccountBalance()*AccountInfoInteger(ACCOUNT_LEVERAGE)/(SymbolInfoDouble(m_name,SYMBOL_TRADE_CONTRACT_SIZE)*initial_margin_rate*dprice));
}
#ifdef __MQL5__
if(SymbolInfoInteger(m_name,SYMBOL_TRADE_CALC_MODE) == SYMBOL_CALC_MODE_FOREX_NO_LEVERAGE) {
dlot=NLot(0.01*dprocent*AccountBalance()/(SymbolInfoDouble(m_name,SYMBOL_TRADE_CONTRACT_SIZE)*initial_margin_rate));
}
#endif
if(SymbolInfoInteger(m_name,SYMBOL_TRADE_CALC_MODE)==SYMBOL_CALC_MODE_FUTURES) {
double marginInit=SymbolInfoDouble(m_name,SYMBOL_MARGIN_INITIAL);
dlot=NLot(0.01*dprocent*AccountBalance()/(marginInit*initial_margin_rate));
}
if(SymbolInfoInteger(m_name,SYMBOL_TRADE_CALC_MODE) == SYMBOL_CALC_MODE_CFD) {
dlot=NLot(0.01*dprocent*AccountBalance()/(SymbolInfoDouble(m_name,SYMBOL_TRADE_CONTRACT_SIZE)*initial_margin_rate*dstep));
}
if(SymbolInfoInteger(m_name,SYMBOL_TRADE_CALC_MODE) == SYMBOL_CALC_MODE_CFDLEVERAGE) {
dlot=NLot(0.01*dprocent*AccountBalance()*AccountInfoInteger(ACCOUNT_LEVERAGE)/(SymbolInfoDouble(m_name,SYMBOL_TRADE_CONTRACT_SIZE)*initial_margin_rate*dstep));
}
}
return dlot;
}
virtual double getLotBySL(double drisk,double dsl,double dbalance=0)
{
if(dsl==0.0)
return (0.0);
double dContractSize=SymbolInfoDouble(m_name,SYMBOL_TRADE_CONTRACT_SIZE);
double dTickValue=SymbolInfoDouble(m_name,SYMBOL_TRADE_TICK_VALUE);
double dTickSize=SymbolInfoDouble(m_name,SYMBOL_TRADE_TICK_SIZE);
double dStep=SymbolInfoDouble(m_name,SYMBOL_VOLUME_STEP);
double _dpoint=SymbolInfoDouble(m_name,SYMBOL_POINT);
if(_dpoint==0.0)
return 0.0;
double _sp=GetSpread(m_name);
int d=int(point(m_name)/_dpoint);
double bb=AccountBalance();
if(dbalance>0)
bb=dbalance;
if(dsl*_dpoint*d==0)
return 0;
double m_lots=0;
if(SymbolInfoInteger(m_name,SYMBOL_TRADE_CALC_MODE) == SYMBOL_CALC_MODE_FOREX)
m_lots=MathFloor((bb*drisk*0.01)/(dsl*dTickValue)/dStep)*dStep;
else
m_lots=MathFloor((bb*drisk*0.01)/(dsl*dTickValue*_dpoint/dTickSize)/dStep)*dStep;
return NLot(m_lots,m_name);
}
virtual double getLotBySL_valute(double drisk_valute,double dsl)
{
if(dsl==0.0)
return (0.0);
double dpoint=SymbolInfoDouble(m_name,SYMBOL_TRADE_TICK_VALUE);
double dStep=SymbolInfoDouble(m_name,SYMBOL_VOLUME_STEP);
double _dpoint=SymbolInfoDouble(m_name,SYMBOL_POINT);
if(_dpoint == 0.0)
return 0.0;
int d=int(p/_dpoint);
if(dsl*dpoint*d==0)
return 0;
double m_lots=MathFloor(drisk_valute/(dsl*dpoint*d)/dStep)*dStep;
return NLot(m_lots);
}
virtual double getLotBySL_valute(double drisk_valute,double dsl,double dcomission=0)
{
if(dsl==0.0)
return (0.0);
double dContractSize=SymbolInfoDouble(m_name,SYMBOL_TRADE_CONTRACT_SIZE);
double dTickValue=SymbolInfoDouble(m_name,SYMBOL_TRADE_TICK_VALUE);
double dTickSize=SymbolInfoDouble(m_name,SYMBOL_TRADE_TICK_SIZE);
double dStep=SymbolInfoDouble(m_name,SYMBOL_VOLUME_STEP);
double _dpoint=SymbolInfoDouble(m_name,SYMBOL_POINT);
if(_dpoint==0.0)
return 0.0;
double _sp=GetSpread(m_name);
int d=int(point(m_name)/_dpoint);
if(dsl*_dpoint*d==0)
return 0;
double m_lots=0;
if(SymbolInfoInteger(m_name,SYMBOL_TRADE_CALC_MODE) == SYMBOL_CALC_MODE_FOREX)
m_lots=MathFloor(drisk_valute/(dsl*dTickValue)/dStep)*dStep;
else
m_lots=MathFloor(drisk_valute/(dsl*dTickValue*_dpoint/dTickSize)/dStep)*dStep;
return NLot(m_lots,m_name);
}
virtual double getLotNoLeverage(double dbalance,double dvaluerisk,double dsl,double dopen,double dstoprisk)
{
if(dsl<=0.0 || dstoprisk<=0 || dopen<=0)
return 0.0;
double dpoint=SymbolInfoDouble(m_name,SYMBOL_TRADE_TICK_VALUE);
double dStep=SymbolInfoDouble(m_name,SYMBOL_VOLUME_STEP);
double dLotMin=SymbolInfoDouble(m_name,SYMBOL_VOLUME_MIN);
double dLotMax=SymbolInfoDouble(m_name,SYMBOL_VOLUME_MAX);
double _dpoint=SymbolInfoDouble(m_name,SYMBOL_POINT);
if(_dpoint==0.0)
return 0.0;
int d=int(p/_dpoint);
if(dsl*dpoint*d==0)
return 0;
double tick_value=SymbolInfoDouble(m_name,SYMBOL_TRADE_TICK_VALUE);
double dContractSize=SymbolInfoDouble(m_name,SYMBOL_TRADE_CONTRACT_SIZE);
double m_lots=MathFloor((dbalance/(dopen*dContractSize))/dStep)*dStep;
double dSummPosition=NormalizeDouble(m_lots*dopen*dContractSize,2);
while(dSummPosition>dbalance) {
m_lots-=dStep;
if(m_lots<dLotMin)
return 0;
dSummPosition=NormalizeDouble(m_lots*dopen*dContractSize,2);
}
double dMaxRisk=ND2(dSummPosition*dstoprisk/100); //какую сумму потеряем максимум
while(dMaxRisk>dvaluerisk) {
m_lots-=dStep;
if(m_lots<dLotMin)
return 0;
dSummPosition=NormalizeDouble(m_lots*dopen*dContractSize,2);
dMaxRisk=ND2(dSummPosition*dstoprisk/100); //какую сумму потеряем максимум
}
return NLot(m_lots);
}
virtual bool CheckMaxSpread(double dMaxSpread)
{
if(dMaxSpread==0)
return true;
double sp=GetSpread(m_name);
if(sp>dMaxSpread)
return false;
return true;
}
virtual double getMaxLot()
{
double dreturn_lot=0;
int icount=PositionsTotal();
for(int i=icount-1; i>=0; i--) {
if(!SelectByIndex(i,true))
continue;
if(!Check(m_position,m_position.Magic()))
continue;
if(m_position.Volume()>dreturn_lot)
dreturn_lot=m_position.Volume();
}
return dreturn_lot;
}
virtual double getMaxLot(int itype)
{
double dreturn_lot=0;
int icount=PositionsTotal();
for(int i=icount-1; i>=0; i--) {
if(!SelectByIndex(i,true))
continue;
if(!Check(m_position,m_position.Magic()))
continue;
if(itype==m_position.PositionType()) {
if(m_position.Volume()>dreturn_lot)
dreturn_lot=m_position.Volume();
}
}
return dreturn_lot;
}
virtual double getMaxLot(int itype,double &dopen)
{
dopen=0;
double dreturn_lot=0;
int icount=PositionsTotal();
for(int i=icount-1; i>=0; i--) {
if(!SelectByIndex(i,true))
continue;
if(!Check(m_position,m_position.Magic()))
continue;
if(itype==m_position.PositionType()) {
if(m_position.Volume()>dreturn_lot) {
dreturn_lot=m_position.Volume();
dopen=m_position.PriceOpen();
}
}
}
return dreturn_lot;
}
virtual double getMaxLotForUnlocker()
{
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,m_position.Magic()))
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 double getProfitAccount(int itype=ALL,datetime tmhistory=0)
{
int flag=0;
double dProfit=0;
int itotal=PositionsTotal();
for(int i=itotal-1; i>=0; i--)
{
if(m_position.SelectByIndex(i))
{
if(m_position.PositionType()>=2)
continue; //пропустим отложки
flag=toMyTypes(m_position.PositionType())&itype;
if(itype==ALL || m_position.PositionType()==toDefType(flag,itype))
{
dProfit+=m_position.Profit()+m_position.Swap()+m_position.Commission();
}
}
}
return dProfit;
}
*/
virtual double getProfitAccount(int itype=ALL,datetime tmhistory=0,bool bhistory=false)
{
int flag=0;
double dprofit=0;
if(bhistory) {
HistorySelect(tmhistory,TimeCurrent()); //загрузем историю последнего месяца
ulong iticket=0;
for(int i=0; i<HistoryDealsTotal(); i++) {
if(!m_deal.SelectByIndex(i))
continue;
if(m_deal.DealType()==DEAL_TYPE_BUY || m_deal.DealType()==DEAL_TYPE_SELL) {
double MacroProfit=0;
if(m_deal.Entry()==DEAL_ENTRY_IN) {
MacroProfit=m_deal.Commission(); //при открытии в мт5 списывает комиссию, если так надо учесть в расчетах
}
if(m_deal.Entry()==DEAL_ENTRY_OUT) {
MacroProfit=m_deal.Profit()+m_deal.Swap()+m_deal.Commission(); //при закрытии учесть надо все по сделке все комиссии , свопы и профит
}
datetime tmStart=(datetime)m_deal.Time();
if(tmStart>tmhistory) {
dprofit+=MacroProfit;
}
}
}
}
int itotal=PositionsTotal();
for(int i=itotal-1; i>=0; i--) {
if(m_position.SelectByIndex(i)) {
if(m_position.PositionType()>=2)
continue; //пропустим отложки
flag=toMyTypes(m_position.PositionType())&itype;
if(itype==ALL || m_position.PositionType()==toDefType(flag,itype)) {
dprofit+=m_position.Profit()+m_position.Swap()+m_position.Commission();
}
}
}
return dprofit;
}
virtual double getProfit(int itype=ALL,int imode=0,datetime tmhistory=0,long imagic=-1)
{
int flag=0;
double dprofit=0;
if(imode==0) {
int itotal=PositionsTotal();
for(int i=itotal-1; i>=0; i--) {
if(!m_position.SelectByIndex(i))
continue;
if((imagic==-1 && Check(m_position,m_position.Magic())) ||
(imagic!=-1 && m_position.Symbol()==m_name && m_position.Magic()==imagic)
) {
flag=toMyTypes(m_position.PositionType())&itype;
if(itype==ALL || m_position.PositionType()==toDefType(flag,itype)) {
dprofit+=m_position.Profit()+m_position.Swap()+m_position.Commission();
}
}
}
} else {
HistorySelect(tmhistory,TimeCurrent()); //загрузем историю последнего месяца
ulong iticket=0;
for(int i=0; i<HistoryDealsTotal(); i++) {
if(!m_deal.SelectByIndex(i))
continue;
if(m_deal.DealType()==DEAL_TYPE_BUY || m_deal.DealType()==DEAL_TYPE_SELL) {
if((imagic==-1 && Check(m_deal,m_deal.Magic())) ||
(imagic!=-1 && (m_deal.Symbol()==m_name || m_name==NULL) && m_deal.Magic()==imagic)) {
double MacroProfit=0;
if(m_deal.Entry()==DEAL_ENTRY_IN) {
MacroProfit=m_deal.Commission(); //при открытии в мт5 списывает комиссию, если так надо учесть в расчетах
}
if(m_deal.Entry()==DEAL_ENTRY_OUT) {
MacroProfit=m_deal.Profit()+m_deal.Swap()+m_deal.Commission(); //при закрытии учесть надо все по сделке все комиссии , свопы и профит
}
datetime tmStart=(datetime)m_deal.Time();
if(tmStart>tmhistory) {
dprofit+=MacroProfit;
}
}
}
}
}
return dprofit;
}
virtual void getProfit(double &dprofit_buy,double &dprofit_sell,datetime tmhistory=0,long imagic=-1)
{
dprofit_buy=0;
dprofit_sell=0;
int itotal=PositionsTotal();
for(int i=itotal-1; i>=0; i--) {
if(!m_position.SelectByIndex(i))
continue;
if((imagic==-1 && Check(m_position,m_position.Magic())) ||
(imagic!=-1 && m_position.Symbol()==m_name && m_position.Magic()==imagic)
) {
if(m_position.Time()>=tmhistory) {
if(m_position.PositionType()==POSITION_TYPE_BUY) {
dprofit_buy+=m_position.Profit()+m_position.Swap()+m_position.Commission();
}
if(m_position.PositionType()==POSITION_TYPE_SELL) {
dprofit_sell+=m_position.Profit()+m_position.Swap()+m_position.Commission();
}
}
}
}
}
virtual bool PartClose(double dpartclose_profit,double dpartclose_procent,bool bModeBU=false)
{
if(dpartclose_profit==0)
return false;
ulong iticket=0;
m_symbol.Name(m_name);
m_symbol.Refresh();
m_symbol.RefreshRates();
for(int i=PositionsTotal()-1; i>=0; i--) {
if(!SelectByIndex(i,true))
continue;
ENUM_POSITION_TYPE etype=(ENUM_POSITION_TYPE)m_position.PositionType();
if(etype==POSITION_TYPE_BUY || etype==POSITION_TYPE_SELL) {
double dopen=m_position.PriceOpen();
double dtake=m_position.TakeProfit();
double dstop=m_position.StopLoss();
double pr=0;
if(etype==POSITION_TYPE_BUY)
pr=ND1((m_symbol.Bid()-dopen)/p);
else if(etype==POSITION_TYPE_SELL)
pr=ND1((dopen-m_symbol.Ask())/p);
double dLOT=NormalizeDouble(m_position.Volume(),2);
double dlot=NLot(dLOT*dpartclose_procent/100); //часть лота
if(ND2(dLOT-dlot)<m_symbol.LotsMin())
continue; //пропуск если остаток меньше минимального лота или равен ему
double dsummlots=0;
if(pr>=dpartclose_profit) {
iticket=m_position.Ticket();
int part=get_part(iticket,dsummlots);
if(part==0) {
if(bModeBU) {
m_trade.PositionModify(iticket,dopen,dtake);
}
return OrderClose(iticket,dlot);
}
}
}
}
return false;
}
virtual ulong GetNewTicket(ulong iticket)
{
#ifdef __MQL4__
ulong iticket_loop=0;
for(int i=PositionsTotal()-1; i>=0; i--) {
iticket_loop=PositionGetTicket(i);
if(iticket_loop>0) {
if(StringFormat("from #%lld",iticket)==PositionGetString(POSITION_COMMENT)) {
return iticket_loop;
}
}
}
#endif
return iticket;
}
virtual void Safe(double dplatsl,bool bbu=false,double dbu=0)
{
if(dplatsl==0)
return;
ulong iticket=0;
m_symbol.Name(m_name);
m_symbol.Refresh();
m_symbol.RefreshRates();
for(int i=PositionsTotal()-1; i>=0; i--) {
if(!SelectByIndex(i,true))
continue;
ENUM_POSITION_TYPE etype=(ENUM_POSITION_TYPE)m_position.PositionType();
if(etype==POSITION_TYPE_BUY || etype==POSITION_TYPE_SELL) {
double dopen=m_position.PriceOpen();
double dtake=m_position.TakeProfit();
double dstop=m_position.StopLoss();
if(dstop==0.0)
continue;
double dsl=0;
double pr=0;
if(etype==POSITION_TYPE_BUY) {
pr=ND1((m_symbol.Bid()-dopen)/p);
dsl=ND1((dopen-dstop)/p);
} else if(etype==POSITION_TYPE_SELL) {
pr=ND1((dopen-m_symbol.Ask())/p);
dsl=ND1((dstop-dopen)/p);
}
if(dsl<=0.0)
continue; //стоп уже в бу
double dLOT=NormalizeDouble(m_position.Volume(),2);
double dlot=NLot(dLOT*0.5); //часть лота
if(ND2(dLOT-dlot)<m_symbol.LotsMin())
continue; //пропуск если остаток меньше минимального лота или равен ему
double dsummlots=0;
if(pr/dsl>=dplatsl) {
iticket=m_position.Ticket();
int part=get_part(iticket,dsummlots);
if(part==0) {
if(dbu) {
if(etype==POSITION_TYPE_BUY)
OrderModify(iticket,dopen,dopen+dbu*p,dtake);
else
OrderModify(iticket,dopen,dopen-dbu*p,dtake);
}
OrderClose(iticket,dlot);
}
}
}
}
}
virtual int get_part(ulong iticket,double &dsummlot,double &dprofit) //вспомогательная функция ищет кол-во частичных закрытий
{
dsummlot=0;
dprofit=0;
int part=-1;
HistorySelectByPosition(iticket); //выберем все сделки по позиции
for(int i=HistoryDealsTotal()-1; i>=0; i--) {
if(!m_deal.SelectByIndex(i))
continue;
if(m_deal.Entry()==DEAL_ENTRY_IN) {
dsummlot+=m_deal.Volume();
dprofit+=m_deal.Commission();
}
if(m_deal.Entry()==DEAL_ENTRY_OUT) {
dprofit+=m_deal.Profit()+m_deal.Swap()+m_deal.Commission();
part++;
}
}
if(part==-1)
part=0;
return part; //вернем сколько раз уже закрывались
}
virtual int get_part(ulong iticket,double &dsummlot) //вспомогательная функция ищет кол-во частичных закрытий
{
dsummlot=0;
int part=-1;
#ifdef __MQL5__
part=0;
#endif
HistorySelectByPosition(iticket); //выберем все сделки по позиции
for(int i=HistoryDealsTotal()-1; i>=0; i--) {
if(!m_deal.SelectByIndex(i))
continue;
if(m_deal.Entry()==DEAL_ENTRY_IN) {
dsummlot+=m_deal.Volume();
}
if(m_deal.Entry()==DEAL_ENTRY_OUT) {
part++;
}
}
if(part==-1)
part=0;
return part; //вернем сколько раз уже закрывались
}
virtual double get_lots(double &dlots[]) //подсчет лотов
{
double dlot=0.0;
if(ArrayResize(dlots,2)!=-1) {
ArrayInitialize(dlots,0);
for(int i=0; i<PositionsTotal(); i++) {
if(!SelectByIndex(i,true))
continue;
if(OrderType()<2) {
dlots[(int)OrderType()]+=OrderLots();
}
}
int idgt=LotDigits(m_name);
dlots[0]=NormalizeDouble(dlots[0],idgt);
dlots[1]=NormalizeDouble(dlots[1],idgt);
dlot=dlots[0]-dlots[1];
dlot=NormalizeDouble(dlot,idgt);
}
if(Abs(dlot)<m_symbol.LotsMin())
return 0;
return dlot;
}
virtual double get_lots(int itype) //подсчет лотов по типу (бай или селл)
{
double dlot=0.0;
if(itype<2) {
for(int i=0; i<PositionsTotal(); i++) {
if(!SelectByIndex(i,true))
continue;
if(m_position.PositionType()==itype) {
dlot+=m_position.Volume();
}
}
}
return dlot;
}
virtual double getLock(int &itype)
{
double dreturn_lot=0;
itype=EMPTY;
double dSaveLot[2]= {0};
for(int i=0; i<PositionsTotal(); i++) {
if(!SelectByIndex(i,true))
continue; //если не выбирает, пропускаем
if(OrderType()==OP_BUY)
dSaveLot[0]+=OrderLots();
if(OrderType()==OP_SELL)
dSaveLot[1]+=OrderLots();
}
if(dSaveLot[0]>dSaveLot[1]) {
itype=OP_SELL;//бай больше, надо ставить селл для лока!
dreturn_lot=Abs(dSaveLot[0]-dSaveLot[1]);
}
if(dSaveLot[0]<dSaveLot[1]) {
itype=OP_BUY;
dreturn_lot=Abs(dSaveLot[1]-dSaveLot[0]);
}
if(dreturn_lot<m_symbol.LotsMin())
return 0;
return dreturn_lot;
}
virtual void OnTimer()
{
}
virtual void OnChartEvent(const int id,// идентификатор события
const long& lparam, // параметр события типа long
const double& dparam, // параметр события типа double
const string& sparam // параметр события типа string
)
{
}
virtual void Position()
{
dPositionCapital+=GetCapital();
}
virtual void Order()
{
}
virtual bool OrderSelect(ulong iticket,bool bposition=true)
{
if(iticket<=0)
return false;
if(bposition) {
bool bret=m_position.SelectByTicket(iticket);
if(bret) {
m_bposition=true;
return true;
}
}
bool bret=m_order.Select(iticket);
m_bposition=!bret;
return bret;
}
virtual string OrderSymbol(bool bposition=true)
{
if(bposition)
return m_position.Symbol();
return m_order.Symbol();
}
virtual bool OrderSelectHistory(ulong iticket)
{
if(iticket<=0)
return false;
m_history.Ticket(iticket);
return true;
}
virtual double OrderStep()
{
double dstep=0;
double dopen=m_position.PriceOpen();
long itype=m_position.PositionType();
if(itype==POSITION_TYPE_BUY)
dstep=ND1((m_symbol.Ask()-dopen)/p);
if(itype==POSITION_TYPE_SELL)
dstep=ND1((dopen-m_symbol.Bid())/p);
return dstep;
}
virtual double OrderProfitPoint()
{
double dstep=0;
double dopen=m_position.PriceOpen();
long itype=m_position.PositionType();
if(itype==POSITION_TYPE_BUY)
dstep=nd((m_symbol.Bid()-dopen)/p);
if(itype==POSITION_TYPE_SELL)
dstep=nd((dopen-m_symbol.Ask())/p);
return dstep;
}
virtual double OrderOpenPrice(bool bposition=true)
{
if(bposition)
return m_position.PriceOpen();
return m_order.PriceOpen();
}
virtual double OrderOpenPrice(ulong positionId)
{
double dprice=0;
datetime tmLast=0;
if(positionId==0) {
return 0;
}
HistorySelectByPosition(positionId);
int iprice=0;
for(int i=HistoryDealsTotal()-1; i>=0; i--) {
ulong uticket=(ulong)HistoryDealGetTicket(i);//тикет не уникальный и связан с номером ордера (тикет позиции)
if(uticket<=0)
continue;
if(HistoryDealGetInteger(uticket,DEAL_POSITION_ID)!=positionId)
continue;
if(HistoryDealGetInteger(uticket,DEAL_ENTRY)==DEAL_ENTRY_IN) { //тут надо самый последний
if(HistoryDealGetInteger(uticket,DEAL_TIME)>tmLast || tmLast==0) {
dprice+=HistoryDealGetDouble(uticket,DEAL_PRICE);
iprice++;
tmLast=(datetime)HistoryDealGetInteger(uticket,DEAL_TIME);
}
}
}
if(iprice>0)
dprice/=iprice;
return nd(dprice,m_name);
}
virtual double OrderClosePrice(ulong positionId)
{
double dprice=0;
datetime tmLast=0;
if(positionId==0) {
return 0;
}
HistorySelectByPosition(positionId);
int iprice=0;
for(int i=HistoryDealsTotal()-1; i>=0; i--) {
ulong uticket=(ulong)HistoryDealGetTicket(i);//тикет не уникальный и связан с номером ордера (тикет позиции)
if(uticket<=0)
continue;
if(HistoryDealGetInteger(uticket,DEAL_POSITION_ID)!=positionId)
continue;
if(HistoryDealGetInteger(uticket,DEAL_ENTRY)==DEAL_ENTRY_OUT) { //тут надо самый последний
if(HistoryDealGetInteger(uticket,DEAL_TIME)>tmLast || tmLast==0) {
dprice+=HistoryDealGetDouble(uticket,DEAL_PRICE);
iprice++;
tmLast=(datetime)HistoryDealGetInteger(uticket,DEAL_TIME);
}
}
}
if(iprice>0)
dprice/=iprice;
return nd(dprice,m_name);
}
virtual double OrderOpenPriceRollover()
{
ulong id=m_position.Ticket();
if(id>0) {
if(HistorySelectByPosition(id)) {
int itotals=HistoryDealsTotal();
double dopenPrice=0;
datetime tmDeal=0;
for(int i=itotals-1; i>=0; i--) {
double dopen=HistoryDealGetDouble(id,DEAL_PRICE);
datetime tmdeal=(datetime)HistoryDealGetInteger(id,DEAL_TIME);
if(tmDeal==0 || tmdeal<tmDeal) {
tmDeal=tmdeal;
dopenPrice=dopen;
}
}
return nd(dopenPrice,m_name);
}
}
return 0;
}
virtual datetime OrderOpenTime(bool bposition=true)
{
if(bposition)
return m_position.Time();
return m_order.TimeSetup(); //время установки отложки
}
virtual datetime OrderOpenTimeHistory()
{
HistoryDealSelect(m_history.Ticket());
datetime tmLast=0;
for(int i=0; i<HistoryDealsTotal(); i++) {
ulong tdeal=HistoryDealGetTicket(i);
ENUM_DEAL_ENTRY entry=(ENUM_DEAL_ENTRY)HistoryDealGetInteger(tdeal,DEAL_ENTRY);
if(entry==DEAL_ENTRY_IN || entry==DEAL_ENTRY_INOUT) { //открытие может быть и переворотом
if(HistoryDealGetInteger(tdeal,DEAL_TIME)<tmLast || tmLast==0)
tmLast=(datetime)HistoryDealGetInteger(tdeal,DEAL_TIME); //находим по последнему (более старый)
}
}
return tmLast;
}
virtual datetime OrderCloseTimeHistory()
{
HistoryDealSelect(m_history.Ticket());
datetime tmLast=0;
for(int i=0; i<HistoryDealsTotal(); i++) {
ulong tdeal=HistoryDealGetTicket(i);
ENUM_DEAL_ENTRY entry=(ENUM_DEAL_ENTRY)HistoryDealGetInteger(tdeal,DEAL_ENTRY);
if(entry==DEAL_ENTRY_OUT || entry==DEAL_ENTRY_INOUT || entry==DEAL_ENTRY_OUT_BY) { //отслеживаем перевороты, закрытие
if(HistoryDealGetInteger(tdeal,DEAL_TIME)<tmLast || tmLast==0) //для закрытия самый ранний он первый
tmLast=(datetime)HistoryDealGetInteger(tdeal,DEAL_TIME);
}
}
return tmLast;
}
virtual double OrderTakeProfit(bool bposition=true)
{
double dtake=0;
if(bposition) {
dtake=m_position.TakeProfit();
if(dtake==0.0)
dtake=virtual_get_tp(m_position.Ticket());
} else {
Показано первые 50% кода (символов: 90791)
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.