class CSpeed
Класс для профилирования времени выполнения функций в микросекундах
Сообщите нам, если считаете, что материал размещён без разрешения.
Обращение по товару «sovetnikov_v5.mq4» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
Файл представляет собой библиотеку исходного кода для MetaTrader 4, предоставляющую набор классов и утилит для работы с ордерами, торговлей и управлением состоянием советника. Библиотека включает класс профилирования CSpeed для замера времени выполнения функций, структуру COrderInfo для хранения данных ордеров, основной класс COrders с методами управления открытыми и историческими ордерами, торговыми операциями, виртуализацией стоп-лоссов и тейк-профитов, а также вспомогательные классы для работы с глобальными переменными, рисования на графике, проверки времени торговли и загрузки новостной ленты.
| Настройка | Описание |
|---|---|
| xMaximum | Максимальный шаг — Числовой параметр, используемый как верхний предел шага в макросе PSAR для настройки индикатора Parabolic SAR |
Классов: 4 · методов: 73 · конструкторов: 2 · деструкторов: 1 · отдельных функций: 0
class CSpeed
Класс для профилирования времени выполнения функций в микросекундах
class COrderInfo
Структура для хранения данных ордера
class _global
Простая структура для хранения имени и значения глобальной переменной
class COrders
Основной класс библиотеки для управления ордерами и торговлей
CSpeed()
Конструктор по умолчанию, запускает профилирование с выводом
CSpeed(bool bprint)
Конструктор с параметром управления выводом профилей
~CSpeed()
Деструктор класса профилирования
void Start(bool bprint)
Запускает замер времени
void Stop(string sfunc,string sdop)
Останавливает замер и выводит время выполнения функции
void ReStart(string sfunc,string sdop)
Перезапускает замер времени после вывода результата
double ProfitPoint()
Рассчитывает прибыль ордера в пунктах
double StepPoint()
Рассчитывает шаг между ценами открытия и текущей в пунктах
void operator=(const int nil)
Обнуляет все поля структуры
void operator=(const COrderInfo &a1)
Копирует данные из другой структуры COrderInfo
bool getOrderByTicket(int iticket,int imode)
Загружает данные ордера по тикету из терминала
bool CheckMagic(long iMagic,string sComment)
Проверяет совпадение магического числа и комментария ордера
bool CheckMagic(long iMagic)
Проверяет совпадение магического числа ордера
bool CheckSymbol(string sName)
Проверяет совпадение имени инструмента
void OnInit(string n,int iimagic,int iislippage)
Инициализация класса с параметрами инструмента, магика и проскальзывания
void OnTick()
Обработчик тика, обновляет данные ордеров
void OnTimer()
Обработчик таймера
void OnDeinit(const int reason)
Обработчик деинициализации
bool Save(const int handle)
Сохраняет состояние в файл
bool Load(const int handle)
Загружает состояние из файла
void IniFileSave(void)
Сохраняет данные в INI-файл
void IniFileLoad(void)
Загружает данные из INI-файла
string IniFileExt(void)
Возвращает расширение INI-файла
string IniFileName(void)
Возвращает имя INI-файла
void virtual_OrdersToVirtual()
Переносит стоп-лосс и тейк-профит ордеров в виртуальный режим
bool checkOrderIndex(int iindex)
Проверяет допустимость индекса в массиве открытых ордеров
bool checkHistoryOrderIndex(int iindex)
Проверяет допустимость индекса в массиве исторических ордеров
string OrderSymbol(int iindex)
Возвращает символ ордера по индексу
string OrderComment(int iindex)
Возвращает комментарий ордера по индексу
int OrdersTotal()
Возвращает количество открытых ордеров
int OrderTicket(int iindex)
Возвращает тикет ордера по индексу
int OrderType(int iindex)
Возвращает тип ордера по индексу
int OrderMagicNumber(int iindex)
Возвращает магический номер ордера по индексу
datetime OrderOpenTime(int iindex)
Возвращает время открытия ордера по индексу
datetime OrderCloseTime(int iindex)
Возвращает время закрытия ордера по индексу
datetime OrderExpiration(int iindex)
Возвращает время истечения ордера по индексу
double OrderOpenPrice(int iindex)
Возвращает цену открытия ордера по индексу
double OrderClosePrice(int iindex)
Возвращает цену закрытия ордера по индексу
double OrderLots(int iindex)
Возвращает объём ордера по индексу
double OrderProfit(int iindex)
Возвращает прибыль ордера по индексу
double Profit(int iindex)
Возвращает суммарную прибыль ордера по индексу
double OrderProfitPoint(int iindex)
Возвращает прибыль в пунктах ордера по индексу
double OrderStep(int iindex)
Возвращает шаг ордера по индексу
double OrderSwap(int iindex)
Возвращает своп ордера по индексу
double OrderCommission(int iindex)
Возвращает комиссию ордера по индексу
double OrderStopLoss(int iindex)
Возвращает стоп-лосс ордера по индексу
double OrderTakeProfit(int iindex)
Возвращает тейк-профит ордера по индексу
string HistoryOrderSymbol(int iindex)
Возвращает символ исторического ордера по индексу
string HistoryOrderComment(int iindex)
Возвращает комментарий исторического ордера по индексу
int OrdersHistoryTotal()
Возвращает количество исторических ордеров
int HistoryOrdersTotal()
Возвращает количество исторических ордеров
int HistoryOrderTicket(int iindex)
Возвращает тикет исторического ордера по индексу
int HistoryOrderType(int iindex)
Возвращает тип исторического ордера по индексу
int HistoryOrderMagicNumber(int iindex)
Возвращает магический номер исторического ордера по индексу
datetime HistoryOrderOpenTime(int iindex)
Возвращает время открытия исторического ордера по индексу
datetime HistoryOrderCloseTime(int iindex)
Возвращает время закрытия исторического ордера по индексу
datetime HistoryOrderExpiration(int iindex)
Возвращает время истечения исторического ордера по индексу
double HistoryOrderOpenPrice(int iindex)
Возвращает цену открытия исторического ордера по индексу
double HistoryOrderClosePrice(int iindex)
Возвращает цену закрытия исторического ордера по индексу
double HistoryOrderLots(int iindex)
Возвращает объём исторического ордера по индексу
double HistoryOrderProfit(int iindex)
Возвращает прибыль исторического ордера по индексу
double HistoryProfit(int iindex)
Возвращает суммарную прибыль исторического ордера по индексу
bool HistoryIsTP(int iindex)
Проверяет, был ли ордер закрыт по тейк-профиту
bool HistoryIsSL(int iindex)
Проверяет, был ли ордер закрыт по стоп-лоссу
double HistoryOrderProfitPoint(int iindex)
Возвращает прибыль в пунктах исторического ордера по индексу
double HistoryOrderStep(int iindex)
Возвращает шаг исторического ордера по индексу
double HistoryOrderSwap(int iindex)
Возвращает своп исторического ордера по индексу
double HistoryOrderCommission(int iindex)
Возвращает комиссию исторического ордера по индексу
double HistoryOrderStopLoss(int iindex)
Возвращает стоп-лосс исторического ордера по индексу
double HistoryOrderTakeProfit(int iindex)
Возвращает тейк-профит исторического ордера по индексу
void virtual_VirtualToOrders(string name,int iimagic)
Восстанавливает виртуальные стоп-лосс и тейк-профит для ордеров по имени и магику
void virtual_VirtualToOrders()
Восстанавливает виртуальные стоп-лосс и тейк-профит для ордеров
bool virtual_valid(int iticket)
Проверяет существование и открытость ордера по тикету
void virtual_deinit()
Очищает виртуальные данные ордеров
int GlobalCopy(_global &dest[],_global &src[])
Копирует массив глобальных переменных
int TesterFindIndexGlobal(string name)
Находит индекс глобальной переменной в тестере по имени
/*
данный файл содержит основные рабочие классы для мт4 600+
*/
#property version "3.00"
#property strict
#ifndef __CMAIN__
#define __CMAIN__ sovetnikov_net_23424dsfsdf23433324fdfdgg
#include <../Include/Controls/Button.mqh>
#include <../Include/Controls/Label.mqh>
#define CONTROLS_BUTTON_WIDTH CONTROLS_BUTTON_SIZE*5
#define __COPYRIGHT__ string scopyright="Copyright 2007-, Gavrilin Alexander Victorovich (";
#define __DEBUG__ true
#define LINE IntegerToString(__LINE__)
#define ND2(x) NormalizeDouble(x,2)
#define ND1(x) NormalizeDouble(x,1)
#define SIGNAL_BAR(y) input ENUM_SIGNAL_BAR signal_bar=y
#define I(x) input int x
#define B(x) input bool x
#define TF(x) input ENUM_TIMEFRAMES x
#define D(x) input double x
#define S(x) input string x
#define METHOD(x) input ENUM_MA_METHOD x
#define PRICE(x) input ENUM_APPLIED_PRICE x
#define C(x) input color x
#define SOUND(x) input ENUM_SOUND_WAV x
#define MA(eTF,xPeriod,xShift,eMethod,ePrice) \
input ENUM_TIMEFRAMES eTF;\
input int xPeriod;\
input int xShift;\
input ENUM_MA_METHOD eMethod;\
input ENUM_APPLIED_PRICE ePrice
#define MA2(xPeriod,xShift,eMethod,ePrice) \
input int xPeriod;\
input int xShift;\
input ENUM_MA_METHOD eMethod;\
input ENUM_APPLIED_PRICE ePrice
#define OSMA(eTF,xFastPeriod,xSlowPeriod,xSignalPeriod,ePrice) \
input ENUM_TIMEFRAMES eTF;\
input int xFastPeriod;\
input int xSlowPeriod;\
input int xSignalPeriod;\
input ENUM_APPLIED_PRICE ePrice
#define OSMA2(xFastPeriod,xSlowPeriod,xSignalPeriod,ePrice) \
input int xFastPeriod;\
input int xSlowPeriod;\
input int xSignalPeriod;\
input ENUM_APPLIED_PRICE ePrice
#define CCI(eTF,xPeriod,ePrice) \
input ENUM_TIMEFRAMES eTF;\
input int xPeriod;\
input ENUM_APPLIED_PRICE ePrice
#define CCI2(xPeriod,ePrice) \
input int xPeriod;\
input ENUM_APPLIED_PRICE ePrice
#define STOCH(eTF,xKPeriod,xDPeriod,xSlowing,eMethod,ePrice) \
input ENUM_TIMEFRAMES eTF;\
input int xKPeriod;\
input int xDPeriod;\
input int xSlowing;\
input ENUM_MA_METHOD eMethod;\
input ENUM_STO_PRICE ePrice
#define MACD(eTF,xFast,xSlow,xSignal,ePrice) input ENUM_TIMEFRAMES eTF;\
input int xFast;\
input int xSlow;\
input int xSignal;\
input ENUM_APPLIED_PRICE ePrice
#define PSAR(eTF,xStep,xMaximum) input ENUM_TIMEFRAMES eTF;\
input double xStep;\
input double xMaximum;
#define PSAR2(xStep,xMaximum) input double xStep;\
input double xMaximum;
#define MACRO_STATIC(nsymbol,bBool,etf) static datetime tm_##bBool=0;\
static bool bBool=false;\
datetime tm0_##bBool=iTime(nsymbol,etf,0);\
if(tm_##bBool==0 || tm0_##bBool!=tm_##bBool) bBool=true;\
tm_##bBool=tm0_##bBool
#define MACRO_DOUBLE(dvalue) static double dvalue=0
#define MACRO_DOUBLE2(dvalue) static double dvalue[2]={0}
#define MACRO_START CSpeed s1(true)
#define MACRO_STOP s1.Stop(__FUNCTION__,IntegerToString(__LINE__))
/*tf*/
enum ENUM_TF
{
OFF=-1,
CURRENT=PERIOD_CURRENT,
M1=PERIOD_M1,
M5=PERIOD_M5,
M15=PERIOD_M15,
M30=PERIOD_M30,
H1=PERIOD_H1,
H4=PERIOD_H4,
D1=PERIOD_D1,
W1=PERIOD_W1,
MN1=PERIOD_MN1
};
/*новые константы для типов ордеров*/
enum _TYPES
{
BUY=10,
SELL=21,
BUYLIMIT=32,
SELLLIMIT=64,
BUYSTOP=128,
SELLSTOP=256,
ALL=-1
};
enum ENUM_SIGNAL_BAR
{
SIGNAL_BAR_CURRENT=0,//Every Tick
SIGNAL_BAR_OPEN=1 //Open Bar
};
enum _ORDER_MODE
{
ORDER_UP=1,
ORDER_DN=2
};
enum ENUM_SORT
{
ENUM_MODE_ASCEND=MODE_ASCEND,
ENUM_MODE_DESCEND=MODE_DESCEND
};
enum _trademode
{
LongOnly,//Long Only
ShortOnly,//Short Only
LongAndShort //Long and Short
};
enum ENUM_OKRUGLENIE
{
Floor,
Ceil,
Round
};
int toMyTypes(int def_type)
{
if(def_type>5) return (-1);
int new_type[6]={BUY,SELL,BUYLIMIT,SELLLIMIT,BUYSTOP,SELLSTOP};
return (new_type[def_type]);
}
void Test(){}
int toDefType(int my_type,int def_type)
{
switch(def_type)
{
case 0: return (OP_BUY);
case 1: return (OP_SELL);
case 2: return (OP_BUYLIMIT);
case 3: return (OP_SELLLIMIT);
case 4: return (OP_BUYSTOP);
case 5: return (OP_SELLSTOP);
}
switch(my_type)
{
case BUY: return (OP_BUY);
case SELL: return (OP_SELL);
case BUYLIMIT: return (OP_BUYLIMIT);
case SELLLIMIT: return (OP_SELLLIMIT);
case BUYSTOP: return (OP_BUYSTOP);
case SELLSTOP: return (OP_SELLSTOP);
}
return(-1); //invalid
}
enum ENUM_SOUND_WAV
{
ealert,//alert.wav
ealert2,//alert2.wav
econnect,//connect.wav
edisconnect,//disconnect.wav
eemail,//*********
eexpert,//expert.wav
enews,//news.wav
eok,//ok.wav
estops,//stops.wav
etick,//tick.wav
etimeout,//timeout.wav
ewait,//wait.wav
euser_file//use file
};
string getSoundFile(ENUM_SOUND_WAV ewav,string suser_file)
{
switch(ewav)
{
case ealert: return "alert.wav";
case ealert2: return "alert2.wav";
case econnect: return "connect.wav";
case edisconnect: return "disconnect.wav";
case eemail: return "*********";
case eexpert: return "expert.wav";
case enews: return "news.wav";
case eok: return "ok.wav";
case estops: return "stops.wav";
case etick: return "tick.wav";
case etimeout: return "timeout.wav";
case ewait: return "wait.wav";
case euser_file: return suser_file;
};
return "";
}
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 COrderInfo
{
public:
string OrderSymbol;
string OrderComment;
int OrderTicket;
int OrderType;
int OrderMagicNumber;
datetime OrderOpenTime;
datetime OrderCloseTime;
datetime OrderExpiration;
double OrderOpenPrice;
double OrderClosePrice;
double OrderLots;
double OrderProfit;
double Profit; //суммарный профит
double OrderProfitPoint; //профит убыток в пунктах, если оредер будет закрыт
double OrderStep; //считаем шаг между ордерами, без учета их закрытия (для бай между аск, для селл между бид)
double OrderSwap;
double OrderCommission;
double OrderStopLoss;
double OrderTakeProfit;
double ProfitPoint() //ордер должен быть выбран!
{
double dpp=point(OrderSymbol);
if(dpp==0.0) return 0;
if(OrderCloseTime==0.0 && OrderType<2)
{
if(OrderType==OP_BUY) return ND1((Bid(OrderSymbol)-OrderOpenPrice)/dpp);
if(OrderType==OP_SELL) return ND1((OrderOpenPrice-Ask(OrderSymbol))/dpp);
}
if(OrderCloseTime!=0.0 && OrderType<2)
{
if(OrderType==OP_BUY) return ND1((OrderClosePrice-OrderOpenPrice)/dpp);
if(OrderType==OP_SELL) return ND1((OrderOpenPrice-OrderClosePrice)/dpp);
}
return 0;
}
double StepPoint() //ордер должен быть выбран!
{
double dpp=point(OrderSymbol);
if(dpp==0.0) return 0;
if(OrderCloseTime==0.0 && OrderType<2)
{
if(OrderType==OP_BUY) return (NormalizeDouble((MarketInfo(OrderSymbol,MODE_ASK)-OrderOpenPrice)/dpp,1));
if(OrderType==OP_SELL) return (NormalizeDouble((OrderOpenPrice-MarketInfo(OrderSymbol,MODE_BID))/dpp,1));
}
if(OrderCloseTime!=0.0 && OrderType<2)
{
if(OrderType==OP_BUY) return (NormalizeDouble((OrderClosePrice-OrderOpenPrice)/dpp,1));
if(OrderType==OP_SELL) return (NormalizeDouble((OrderOpenPrice-OrderClosePrice)/dpp,1));
}
return 0;
}
void operator=(const int nil=NULL) //нулевая инициализация переменных
{
OrderSymbol="";
OrderComment="";
OrderTicket=0;
OrderType=-1;
OrderMagicNumber=0;
OrderOpenTime=0;
OrderCloseTime=0;
OrderExpiration=0;
OrderOpenPrice=0;
OrderClosePrice=0;
OrderLots=0;
OrderProfit=0;
Profit=0;
OrderProfitPoint=0;
OrderStep=0;
OrderSwap=0;
OrderCommission=0;
OrderStopLoss=0;
OrderTakeProfit=0;
}
void operator=(const COrderInfo &a1)//простое копирование
{
OrderSymbol=a1.OrderSymbol;
OrderComment=a1.OrderComment;
OrderTicket=a1.OrderTicket;
OrderType=a1.OrderType;
OrderMagicNumber=a1.OrderMagicNumber;
OrderOpenTime=a1.OrderOpenTime;
OrderCloseTime=a1.OrderCloseTime;
OrderExpiration=a1.OrderExpiration;
OrderOpenPrice=a1.OrderOpenPrice;
OrderClosePrice=a1.OrderClosePrice;
OrderLots=a1.OrderLots;
OrderProfit=a1.OrderProfit;
Profit=a1.Profit;
OrderProfitPoint=a1.OrderProfitPoint;
OrderStep=a1.OrderStep;
OrderSwap=a1.OrderSwap;
OrderCommission=a1.OrderCommission;
OrderStopLoss=a1.OrderStopLoss;
OrderTakeProfit=a1.OrderTakeProfit;
}
bool getOrderByTicket(int iticket,int imode=MODE_TRADES)
{
if(OrderTicket()!=iticket)
{
if(!OrderSelect(iticket,SELECT_BY_TICKET,imode)) return false;
}
if(iticket<=0) return false;
OrderSymbol=OrderSymbol();
OrderComment=OrderComment();
OrderTicket=OrderTicket();
OrderType=OrderType();
OrderMagicNumber=OrderMagicNumber();
OrderOpenTime=OrderOpenTime();
OrderCloseTime=OrderCloseTime();
OrderExpiration=OrderExpiration();
OrderOpenPrice=OrderOpenPrice();
OrderClosePrice=OrderClosePrice();
OrderLots=OrderLots();
OrderProfit=OrderProfit();
OrderProfitPoint=ProfitPoint();
OrderStep=StepPoint();
OrderSwap=OrderSwap();
OrderCommission=OrderCommission();
OrderStopLoss=OrderStopLoss();
OrderTakeProfit=OrderTakeProfit();
Profit=OrderProfit+OrderSwap+OrderCommission;
return true;
}
};
void SortOrdersByOrderOpenPrice(COrderInfo &a[],ENUM_SORT idirection=ENUM_MODE_ASCEND)
{
int i=0,j=0;
COrderInfo x;
int size=ArraySize(a);
for(i=0;i<size;i++)
{
for(j=size-1;j>i;j--)
{
if(idirection==MODE_ASCEND && a[j-1].OrderOpenPrice>a[j].OrderOpenPrice)
{
x=a[j-1];
a[j-1]=a[j];
a[j]=x;
}
if(idirection==MODE_DESCEND && a[j-1].OrderOpenPrice<a[j].OrderOpenPrice)
{
x=a[j-1];
a[j-1]=a[j];
a[j]=x;
}
}
}
}
void SortOrdersByOrderOpenTime(COrderInfo &a[],ENUM_SORT idirection=ENUM_MODE_ASCEND)
{
int i=0,j=0;
COrderInfo x;
int size=ArraySize(a);
for(i=0;i<size;i++)
{
for(j=size-1;j>i;j--)
{
if(idirection==MODE_ASCEND && a[j-1].OrderOpenTime>a[j].OrderOpenTime)
{
x=a[j-1];
a[j-1]=a[j];
a[j]=x;
}
if(idirection==MODE_DESCEND && a[j-1].OrderOpenTime<a[j].OrderOpenTime)
{
x=a[j-1];
a[j-1]=a[j];
a[j]=x;
}
}
}
}
struct _global
{
string name;
double data;
};
/*основной класс для торговли и управления ордерами*/
class COrders
{
public:
_global m_global[];
string m_name; //название инстурмента, переменные делаем доступными, чтобы при желании можно было быстро изменить их
long m_imagic; //меджик
int m_islippage; //проскальзывание
double stoplevel; //стоп уровень брокера по инструменту
int m_total; //общее кол-во открытых ордеров в терминале
int m_all; //кол-во открытых ордеров
int m_historyall;
double p; //пункт с учетом разрядности
double dp; //соотношение пунктов, для пересчета 5 знака в 4х. (вспомогательная функция)
int ierrors; //ошибки будут храниться в этой переменной
COrderInfo m_orders[],m_historyorders[];
int orders[10]; //счетчики кол-ва ордеров разного типа
int trades[10]; //счетчики кол-ва открытых на текущем баре
int history[10]; //счетчики кол-ва закрытых на текущем баре
bool IsTester; //тестер или оптимизатор?
int options_iMaxLoadDays;
int options_iRestartCount; //счетчик кол-ва запросов
int options_iTimeout; //пауза при неудачных запросах
bool options_bVirtual; //виртуализация
bool options_bNoModify; //не модифицировать стоп и тейк полностью виртуальные
bool options_bNoCheckPending; //не проверять отложки на нехватку маржи
bool options_bCheckFreeMargin; //проверка маржи перед открытием ордера
bool options_bSupportMaxLot; //поддержка превышения максимального лота
virtual bool CheckMagic(long iMagic,string sComment)
{
return CheckMagic(iMagic);
}
virtual bool CheckMagic(long iMagic)
{
return (iMagic==m_imagic || m_imagic==-1);
}
virtual bool CheckSymbol(string sName)
{
return (sName==m_name || m_name==NULL);
}
virtual void OnInit(string n,int iimagic,int iislippage)
{
// код доступен только после оплаты
}
virtual void OnTick()
{
// код доступен только после оплаты
} //нужно переписать в наследуемом классе
virtual void OnTimer(){ } //нужно переписать в наследуемом классе если испольузем таймеры
virtual void OnDeinit(const int reason=0)
{
virtual_deinit(); //вирутуальные функции контроля
}
virtual bool Save(const int handle){ Print(__FUNCSIG__); return true;}
virtual bool Load(const int handle){ Print(__FUNCSIG__); return true;}
virtual void IniFileSave(void)
{
string filename=IniFileName()+IniFileExt();
int handle=FileOpen(filename,FILE_WRITE|FILE_BIN|FILE_ANSI);
if(handle!=INVALID_HANDLE)
{
Save(handle);
FileClose(handle);
}
}
virtual void IniFileLoad(void)
{
string filename=IniFileName()+IniFileExt();
int handle=FileOpen(filename,FILE_READ|FILE_BIN|FILE_ANSI);
if(handle!=INVALID_HANDLE)
{
Load(handle);
FileClose(handle);
}
}
virtual string IniFileExt(void) const { return(".dat"); }
virtual string IniFileName(void) const
{
string name;
name=WindowExpertName();
name+="_"+Symbol();
name+="_"+IntegerToString(m_imagic);
name+="_Ini";
return(name);
}
void virtual_OrdersToVirtual()
{
for(int i=ArraySize(m_orders)-1;i>=0;i--)
{
if(m_orders[i].OrderCloseTime>0) continue;
if(CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) && CheckSymbol(m_orders[i].OrderSymbol))
{
virtual_set(m_orders[i].OrderTicket,m_orders[i].OrderStopLoss,m_orders[i].OrderTakeProfit);
OrderModify(m_orders[i].OrderTicket,m_orders[i].OrderOpenPrice,0,0,-1,clrNONE);
}
}
}
bool checkOrderIndex(int iindex)
{
if(iindex<0) return false;
int isize=ArraySize(m_orders);
if(iindex>=isize) return false;
return true; //valid
}
bool checkHistoryOrderIndex(int iindex)
{
if(iindex<0) return false;
int isize=ArraySize(m_historyorders);
if(iindex>=isize) return false;
return true; //valid
}
string OrderSymbol(int iindex) { if(!checkOrderIndex(iindex)) return ""; return m_orders[iindex].OrderSymbol; }
string OrderComment(int iindex) { if(!checkOrderIndex(iindex)) return ""; return m_orders[iindex].OrderComment; }
int OrdersTotal()
{
if(ArraySize(m_orders)==0) Update();
return ArraySize(m_orders);
}
int OrderTicket(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderTicket; }
int OrderType(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderType; }
int OrderMagicNumber(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderMagicNumber; }
datetime OrderOpenTime(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderOpenTime; }
datetime OrderCloseTime(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderCloseTime; }
datetime OrderExpiration(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderExpiration; }
double OrderOpenPrice(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderOpenPrice; }
double OrderClosePrice(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderClosePrice; }
double OrderLots(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderLots; }
double OrderProfit(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderProfit; }
double Profit(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].Profit; }
double OrderProfitPoint(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderProfitPoint; }
double OrderStep(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderStep; }
double OrderSwap(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderSwap; }
double OrderCommission(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderCommission; }
double OrderStopLoss(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderStopLoss; }
double OrderTakeProfit(int iindex) { if(!checkOrderIndex(iindex)) return 0; return m_orders[iindex].OrderTakeProfit; }
string HistoryOrderSymbol(int iindex) { if(!checkHistoryOrderIndex(iindex)) return ""; return m_historyorders[iindex].OrderSymbol; }
string HistoryOrderComment(int iindex) { if(!checkHistoryOrderIndex(iindex)) return ""; return m_historyorders[iindex].OrderComment; }
int OrdersHistoryTotal() { if(ArraySize(m_historyorders)==0) UpdateHistory(); return ArraySize(m_historyorders); }
int HistoryOrdersTotal() { if(ArraySize(m_historyorders)==0) UpdateHistory(); return ArraySize(m_historyorders); }
int HistoryOrderTicket(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderTicket; }
int HistoryOrderType(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderType; }
int HistoryOrderMagicNumber(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderMagicNumber; }
datetime HistoryOrderOpenTime(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderOpenTime; }
datetime HistoryOrderCloseTime(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderCloseTime; }
datetime HistoryOrderExpiration(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderExpiration; }
double HistoryOrderOpenPrice(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderOpenPrice; }
double HistoryOrderClosePrice(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderClosePrice; }
double HistoryOrderLots(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderLots; }
double HistoryOrderProfit(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderProfit; }
double HistoryProfit(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].Profit; }
bool HistoryIsTP(int iindex)
{
if(!checkHistoryOrderIndex(iindex)) return false;
if(StringFind(HistoryOrderComment(iindex),"[tp]")>=0 || HistoryOrderClosePrice(iindex)==HistoryOrderTakeProfit(iindex))
{
return true;
}
return false;
}
bool HistoryIsSL(int iindex)
{
if(!checkHistoryOrderIndex(iindex)) return false;
if(StringFind(HistoryOrderComment(iindex),"[sl]")>=0 || HistoryOrderClosePrice(iindex)==HistoryOrderStopLoss(iindex))
{
return true;
}
return false;
}
double HistoryOrderProfitPoint(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderProfitPoint; }
double HistoryOrderStep(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderStep; }
double HistoryOrderSwap(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderSwap; }
double HistoryOrderCommission(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderCommission; }
double HistoryOrderStopLoss(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderStopLoss; }
double HistoryOrderTakeProfit(int iindex) { if(!checkHistoryOrderIndex(iindex)) return 0; return m_historyorders[iindex].OrderTakeProfit; }
void virtual_VirtualToOrders(string name,int iimagic)
{
for(int i=ArraySize(m_orders)-1;i>=0;i--)
{
if(m_orders[i].OrderStopLoss==0.0 && m_orders[i].OrderTakeProfit==0.0 && virtual_check(m_orders[i].OrderTicket))
{
OrderModify(m_orders[i].OrderTicket,-1,virtual_get_sl(m_orders[i].OrderTicket),virtual_get_tp(m_orders[i].OrderTicket),0,clrNONE);
}
}
}
void virtual_VirtualToOrders()
{
for(int i=ArraySize(m_orders)-1;i>=0;i--)
{
if(m_orders[i].OrderCloseTime>0) continue;
if(!CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) || !CheckSymbol(m_orders[i].OrderSymbol)) continue;
if(m_orders[i].OrderStopLoss==0.0 && m_orders[i].OrderTakeProfit==0.0 && virtual_check(m_orders[i].OrderTicket))
{
OrderModify(m_orders[i].OrderTicket,-1,virtual_get_sl(m_orders[i].OrderTicket),virtual_get_tp(m_orders[i].OrderTicket),0,clrNONE);
}
}
}
bool virtual_valid(int iticket)
{
if(!OrderSelect(iticket,SELECT_BY_TICKET)) return (false);
if(OrderCloseTime()==0) return (true);
return (false);
}
void virtual_deinit()
{
if(IsTester)
{
GVariable::Delete("virtual");
ArrayResize(m_global,0); //очистим переменную глобальных перменных)
}
}
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;
}
return isize;
}
return 0;
}
int TesterFindIndexGlobal(string name)
{
if(IsTester)
{
int isize=ArraySize(m_global);
for(int i=isize-1;i>=0;i--)
{
if(StringCompare(m_global[i].name,name,false)==0) return i; //найдем индекс
}
}
return -1;
}
int GlobalVariablesTotal()
{
if(IsTester)
{
return ArraySize(m_global);
}
return ::GlobalVariablesTotal();
}
string GlobalVariableName(int index)
{
if(IsTester)
{
int isize=ArraySize(m_global);
if(index<0 || index>=isize) return "";
return m_global[index].name;
}
return ::GlobalVariableName(index);
}
double GlobalVariableGet(string name)
{
if(IsTester)
{
int index=TesterFindIndexGlobal(name);
if(index==-1)
{
return 0;
}
return m_global[index].data;
}
return ::GlobalVariableGet(name);
}
datetime GlobalVariableSet(string name,double value)
{
if(IsTester)
{
int index=TesterFindIndexGlobal(name);
if(index!=-1)
{
m_global[index].data=value;
}
else
if(index==-1 && value!=0 && name!="")
{
int isize=ArraySize(m_global);
if(ArrayResize(m_global,isize+1)!=-1)
{
m_global[isize].name=name;
m_global[isize].data=value;
}
else
{
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_global);
if(GlobalCopy(newglobal,m_global)>0)
{
isize=0;
ArrayResize(m_global,0); //переформируем структуру
inewsize=ArraySize(newglobal);
for(int i=0;i<inewsize;i++)
{
if(newglobal[i].name!=name)
{
if(ArrayResize(m_global,isize+1)!=-1)
{
m_global[isize].name=newglobal[i].name;
m_global[isize].data=newglobal[i].data;
isize++;
}
}
}
return true;
}
return false;
}
return (bool)::GlobalVariableDel(name);
}
virtual void virtual_init()
{
if(!options_bVirtual) return; //если виртуализация выключена, то не проверяем
string del[],sglobal="",param[],n;
int icount=0,i,itype=-1,isizeParam;
ArrayResize(del,0);
int isize=GlobalVariablesTotal();
for(i=isize-1;i>=0;i--)
{
sglobal=GlobalVariableName(i);
if(sglobal=="" || sglobal==NULL) continue;
if(StringFind(sglobal,"_sl")<0 && StringFind(sglobal,"_tp")<0) continue; //пропустим не наши
if(GlobalVariableGet(sglobal)==0) //все нулевые удалим
{
ArrayResize(del,icount+1);
del[icount]=sglobal;
icount++;
continue;
}
string_explode("_",sglobal,param);
isizeParam=ArraySize(param);
if(isizeParam<2 && isizeParam>3) continue; //пропустим сразу неподходящие под наши правила
if((isizeParam==2 && StringToInteger(param[0])>0) || (isizeParam==3 && param[0]=="virtual" && StringToInteger(param[1])>0))
{
int iticket=(int)StringToInteger(param[0]);//тикет
if(isizeParam==3)
{
iticket=(int)StringToInteger(param[1]);//тикет
}
if(!OrderSelect(iticket))
{
continue;
}
itype=OrderType();
if(itype>=2 || OrderCloseTime()>0) //отложки тоже подчистим и уже закрытых ордеров тоже
{
ArrayResize(del,icount+1);
del[icount]=sglobal;
icount++;
continue; //next order
}
n=OrderSymbol();
if(CheckMagic(OrderMagicNumber(),OrderComment()) && CheckSymbol(n))
{
double pt=0;
double dtp=0;
double dsl=0;
dtp=virtual_get_tp(iticket);
dsl=virtual_get_sl(iticket);
if(dtp!=0 || dsl!=0)
{
RefreshRates();
}
if(dtp==0 && dsl==0) continue;
double _Ask=Ask(n);
double _Bid=Bid(n);
if(dtp!=0 && ((_Bid>=dtp && itype==OP_BUY) || (_Ask<=dtp && itype==OP_SELL)))
{
if(OrderClose(iticket,-1))
{
ArrayResize(del,icount+1);
del[icount]=sglobal;
icount++;
m_total--;
}
}//close by dtp
if(dsl!=0 && ((_Bid<=dsl && itype==OP_BUY) || (_Ask>=dsl && itype==OP_SELL)))
{
if(OrderClose(iticket,-1))
{
ArrayResize(del,icount+1);
del[icount]=sglobal;
icount++;
m_total--;
}
}//close by dstop
}
}
}
if(icount>0)
{
for(i=0;i<icount;i++)
{
if(del[i]!="" && GlobalVariableCheck(del[i]))
GlobalVariableDel(del[i]);
}
}
}
void virtual_set(int iticket,double dsl,double dtp)
{
if(iticket<=0) return;
string n;
if(dtp>=0)
{
if(IsTester) n=StringConcatenate("virtual_",DoubleToStr(iticket,0),"_tp");
else n=StringConcatenate(DoubleToStr(iticket,0),"_tp");
GlobalVariableSet(n,dtp);
}
if(dsl>=0)
{
if(IsTester) n=StringConcatenate("virtual_",DoubleToStr(iticket,0),"_sl");
else n=StringConcatenate(DoubleToStr(iticket,0),"_sl");
GlobalVariableSet(n,dsl);
}
}
bool virtual_check(int iticket)
{
if(iticket<=0) return (false);
string n;
if(IsTester) n=StringConcatenate("virtual_",DoubleToStr(iticket,0),"_tp");
else n=StringConcatenate(DoubleToStr(iticket,0),"_tp");
if(GlobalVariableCheck(n)) return (true);
if(IsTester) n=StringConcatenate("virtual_",DoubleToStr(iticket,0),"_sl");
else n=StringConcatenate(DoubleToStr(iticket,0),"_sl");
if(GlobalVariableCheck(n)) return (true);
return (false);
}
double virtual_get_tp(int iticket)
{
if(iticket<=0) return (0);
string n;
if(IsTester) n=StringConcatenate("virtual_",DoubleToStr(iticket,0),"_tp");
else n=StringConcatenate(DoubleToStr(iticket,0),"_tp");
if(GlobalVariableCheck(n)) return (GlobalVariableGet(n));
return (0);
}
double virtual_get_sl(int iticket)
{
if(iticket<=0) return (0);
string n;
if(IsTester) n=StringConcatenate("virtual_",DoubleToStr(iticket,0),"_sl");
else n=StringConcatenate(DoubleToStr(iticket,0),"_sl");
if(GlobalVariableCheck(n)) return (GlobalVariableGet(n));
return (0);
}
void virtual_set_levels(int iticket,double dsl_pt,double dtp_pt)
{
int index=-1;
if(iticket>0 && OrderSelect(iticket,index))
{
string ssmb=m_orders[index].OrderSymbol;
double dpp=point(ssmb);
double dopen=m_orders[index].OrderOpenPrice;
double dstop=0;
double dtake=0;
int itype=m_orders[index].OrderType;
if(itype==OP_BUY)
{
if(dsl_pt>0) dstop=dopen-dsl_pt*dpp;
if(dtp_pt>0) dtake=dopen+dtp_pt*dpp;
}
if(itype==OP_SELL)
{
if(dsl_pt>0) dstop=dopen+dsl_pt*dpp;
if(dtp_pt>0) dtake=dopen-dtp_pt*dpp;
}
virtual_set(iticket,dstop,dtake);
}
}
int Count(ENUM_ORDER_TYPE itype)
{
__COPYRIGHT__
if((int)itype>=ArraySize(orders) || itype==-1) return -1; //ошибка
return orders[(int)itype];
}
int Count(ENUM_ORDER_TYPE itype,long imagic)
{
__COPYRIGHT__
int ic=0;
for(int i=0;i<OrdersTotal();i++)
{
if(m_orders[i].OrderCloseTime>0) continue; //если не выбирает, пропускаем
if(imagic==m_orders[i].OrderMagicNumber)
{
if(m_orders[i].OrderType==itype) ic++;
}
}
return ic;
}
int HistoryCount(ENUM_ORDER_TYPE itype)
{
__COPYRIGHT__
if((int)itype>=ArraySize(history)) return -1; //ошибка
return history[(int)itype];
}
int HistoryCount(ENUM_ORDER_TYPE itype,long imagic)
{
__COPYRIGHT__
int ic=0;
for(int i=0;i<HistoryOrdersTotal();i++)
{
if(m_historyorders[i].OrderCloseTime>0) continue; //если не выбирает, пропускаем
if(imagic==m_historyorders[i].OrderMagicNumber)
{
if(m_historyorders[i].OrderType==itype) ic++;
}
}
return ic;
}
virtual int Update()
{
__COPYRIGHT__
ArrayResize(m_orders,0);
m_all=0;
ArrayInitialize(orders,0);
int isize=0;
int itotal=::OrdersTotal();
m_total=itotal; //запомним для проверок кол-ва лимита ордеров
for(int i=0;i<itotal;i++)
{
if(!OrderSelect(i,SELECT_BY_POS)) continue; //если не выбирает, пропускаем
if(CheckSymbol(OrderSymbol()))
{
if((!options_bSupportMaxLot && CheckMagic(OrderMagicNumber(),OrderComment())) || options_bSupportMaxLot)
{
isize=ArraySize(m_orders); //кол-во оредров в структуре
if(ArrayResize(m_orders,isize+1)!=-1)
{
if(m_orders[isize].getOrderByTicket(OrderTicket())) //загрузим информацию по ордеру (грузим все ордера)
{
if(CheckMagic(m_orders[isize].OrderMagicNumber,m_orders[isize].OrderComment))
{
orders[m_orders[isize].OrderType]++; //увеличим счетчик
m_all++;
}
}
}
}
}
}
return m_all; //вернем кол-во ордеров в структуре
}
virtual int UpdateHistory(int iNewMaxLoad=EMPTY_VALUE)
{
__COPYRIGHT__
ArrayResize(m_historyorders,0);
ArrayInitialize(history,0);
m_historyall=0;
int isize=0;
datetime tm_end=0;
if(options_iMaxLoadDays>=0) tm_end=iTime(_Symbol,PERIOD_D1,options_iMaxLoadDays);
if(iNewMaxLoad==-1) tm_end=0;
else if(iNewMaxLoad>=0) tm_end=iTime(_Symbol,PERIOD_D1,iNewMaxLoad);
int itotal=::OrdersHistoryTotal();
for(int i=0;i<itotal;i++)
{
if(!OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) continue; //если не выбирает, пропускаем
if(OrderOpenTime()>=tm_end) //учитываем глубину загрузки
{
if(CheckSymbol(OrderSymbol()))
{
if((!options_bSupportMaxLot && CheckMagic(OrderMagicNumber(),OrderComment())) || options_bSupportMaxLot)
{
isize=ArraySize(m_historyorders); //кол-во оредров в структуре
if(ArrayResize(m_historyorders,isize+1)!=-1)
{
if(m_historyorders[isize].getOrderByTicket(OrderTicket(),MODE_HISTORY)) //загрузим информацию по ордеру
{
if(CheckMagic(m_historyorders[isize].OrderMagicNumber,m_historyorders[isize].OrderComment))
{
history[m_historyorders[isize].OrderType]++; //увеличим счетчик
m_historyall++;
}
}
}
}
}
}
}
return m_historyall; //вернем кол-во ордеров в структуре
}
bool CopyOrders(COrderInfo &aOrders[])
{
__COPYRIGHT__
int isize=ArraySize(aOrders);
int isize_current=ArraySize(m_orders);
if(ArrayResize(aOrders,isize+isize_current)!=-1)
{
for(int i=0;i<isize_current;i++)
{
aOrders[isize+i]=m_orders[i];
}
}
return (isize>0);
}
bool CopyHistoryOrders(COrderInfo &aOrders[])
{
__COPYRIGHT__
int isize=ArraySize(aOrders);
int isize_current=ArraySize(m_historyorders);
if(ArrayResize(aOrders,isize+isize_current)!=-1)
{
for(int i=0;i<isize_current;i++)
{
aOrders[isize+i]=m_historyorders[i];
}
}
return (isize>0);
}
int LoadUpdate()
{
CSpeed s1;
__COPYRIGHT__
m_all=0;
ArrayInitialize(orders,0);
int isize=ArraySize(m_orders);
for(int i=isize-1;i>=0;i--)
{
if(m_orders[i].OrderCloseTime>0) continue;
if(CheckSymbol(m_orders[i].OrderSymbol))
{
if((!options_bSupportMaxLot && CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment)) || options_bSupportMaxLot)
{
if(CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment))
{
orders[m_orders[i].OrderType]++; //увеличим счетчик
m_all++;
}
}
}
}
return m_all; //вернем кол-во ордеров в структуре
}
int LoadUpdateHistory()
{
CSpeed s1;
__COPYRIGHT__
m_historyall=0;
ArrayInitialize(history,0);
int isize=ArraySize(m_historyorders);
for(int i=isize-1;i>=0;i--)
{
if(m_historyorders[i].OrderCloseTime>0) continue;
if(CheckSymbol(m_historyorders[i].OrderSymbol))
{
if((!options_bSupportMaxLot && CheckMagic(m_historyorders[i].OrderMagicNumber,m_historyorders[i].OrderComment)) || options_bSupportMaxLot)
{
if(CheckMagic(m_historyorders[i].OrderMagicNumber,m_historyorders[i].OrderComment))
{
orders[m_historyorders[i].OrderType]++; //увеличим счетчик
m_all++;
}
}
}
}
return m_historyall; //вернем кол-во ордеров в структуре
}
bool LoadOrders(COrderInfo &aOrders[])
{
__COPYRIGHT__
int isize=ArraySize(aOrders);
if(ArrayResize(m_orders,isize)!=-1)
{
for(int i=0;i<isize;i++)
{
m_orders[i]=aOrders[i];
}
}
if(isize>0) LoadUpdate();
return (isize>0);
}
bool LoadHistoryOrders(COrderInfo &aOrders[])
{
__COPYRIGHT__
int isize=ArraySize(aOrders);
if(ArrayResize(m_historyorders,isize)!=-1)
{
for(int i=0;i<isize;i++)
{
m_historyorders[i]=aOrders[i];
}
}
if(isize>0) LoadUpdateHistory();
return (isize>0);
}
int OrderInfoCopy(COrderInfo &dest[],COrderInfo &src[])
{
int isize=ArraySize(src);
if(ArrayResize(dest,isize)!=-1)
{
for(int i=0;i<isize;i++)
{
dest[i]=src[i];
}
return isize;
}
return 0;
}
void UpdateOrders() //функцию стоит вызывать после удаления ордеров
{
COrderInfo tmporders[];
if(OrderInfoCopy(tmporders,m_orders)>0)
{
m_all=0;
ArrayInitialize(orders,0);
ArrayResize(m_orders,0);
int isize=ArraySize(tmporders);
int j=0;
for(int i=0;i<isize;i++)
{
if(tmporders[i].OrderCloseTime==0.0) //не закрыт
{
if(ArrayResize(m_orders,j+1)!=-1)
{
m_orders[j]=tmporders[i]; //копируем все элементы кроме удаляемого
j++;
if(CheckSymbol(m_orders[i].OrderSymbol))
{
if((!options_bSupportMaxLot && CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment)) || options_bSupportMaxLot)
{
if(CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment))
{
orders[m_orders[i].OrderType]++; //увеличим счетчик
m_all++;
}
}
}
}
}
}
}
}
void ClearOrder(int iticket,bool bDecOrder=true)
{
__COPYRIGHT__
if(iticket<=0) return;
int close_index=FindOrder(iticket);
if(close_index>=0 && bDecOrder)
{
m_all--;
if(m_all<0) m_all=0;
orders[m_orders[close_index].OrderType]--;
if(orders[m_orders[close_index].OrderType]<0) orders[m_orders[close_index].OrderType]=0;
}
int index=FindHistoryOrder(iticket);
if(index>=0) //если нашли его уже в закрытх, обновим информацию о ордере
{
m_historyorders[index].getOrderByTicket(iticket,MODE_HISTORY); //обновим данные из истории
if(close_index>=0) m_orders[close_index]=m_historyorders[index]; //обновим ордер среди открытых как закрытый
}
else
{
int isize=ArraySize(m_historyorders);
if(ArrayResize(m_historyorders,isize+1)!=-1)
{
if(m_historyorders[isize].getOrderByTicket(iticket,MODE_HISTORY)) //обновим данные из истории и добавим в данные истории
{
m_historyall++;
orders[m_historyorders[isize].OrderType]++;
if(close_index>=0) m_orders[close_index]=m_historyorders[isize]; //сохраним данные, ордер пока не удаляем.
}
}
}
}
virtual double GroupOrderLot(int iticket)
{
__COPYRIGHT__
if(iticket<=0) return 0;
double dlot=0;
for(int i=0;i<ArraySize(m_orders);i++)
{
if(m_orders[i].OrderCloseTime>0) continue;
if(m_orders[i].OrderTicket==iticket || m_orders[i].OrderMagicNumber==MathAbs(iticket))
{
dlot+=m_orders[i].OrderLots;
}
}
return dlot;
}
virtual double GroupHistoryOrderLot(int iticket)
{
__COPYRIGHT__
if(iticket<=0) return 0;
double dlot=0;
for(int i=0;i<ArraySize(m_historyorders);i++)
{
if(m_historyorders[i].OrderCloseTime>0) continue;
if(m_historyorders[i].OrderTicket==iticket || m_historyorders[i].OrderMagicNumber==MathAbs(iticket))
{
dlot+=m_historyorders[i].OrderLots;
}
}
return dlot;
}
virtual double GroupOrderProfit(int iticket)
{
__COPYRIGHT__
if(iticket<=0) return 0;
double dprofit=0;
for(int i=0;i<ArraySize(m_orders);i++)
{
if(m_orders[i].OrderCloseTime>0) continue;
if(m_orders[i].OrderTicket==iticket || m_orders[i].OrderMagicNumber==MathAbs(iticket))
{
dprofit+=m_orders[i].Profit;
}
}
return dprofit;
}
virtual double GroupHistoryOrderProfit(int iticket)
{
__COPYRIGHT__
if(iticket<=0) return 0;
double dprofit=0;
for(int i=0;i<ArraySize(m_historyorders);i++)
{
if(m_historyorders[i].OrderCloseTime==0) continue;
if(m_historyorders[i].OrderTicket==iticket || m_historyorders[i].OrderMagicNumber==MathAbs(iticket))
{
dprofit+=m_historyorders[i].Profit;
}
}
return dprofit;
}
virtual double getLock(int &itype)
{
double dlot=0;
itype=EMPTY;
double dLot[2]={0};
int icount=ArraySize(m_orders);
for(int i=icount-1;i>=0;i--)
{
if(m_orders[i].OrderCloseTime>0) continue;
if(!CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) || !CheckSymbol(m_orders[i].OrderSymbol)) continue;
if(m_orders[i].OrderType>=2) continue;
if(m_orders[i].OrderType==OP_BUY) dLot[0]+=GroupOrderLot(m_orders[i].OrderTicket);
if(m_orders[i].OrderType==OP_SELL) dLot[1]+=GroupOrderLot(m_orders[i].OrderTicket);
}
if(dLot[0]>dLot[1])
{
itype=OP_SELL;
dlot=MathAbs(dLot[0]-dLot[1]);
}
if(dLot[0]<dLot[1])
{
itype=OP_BUY;
dlot=MathAbs(dLot[1]-dLot[0]);
}
return NLot(dlot);
}
virtual double getProfit(int itype=ALL,int imode=MODE_TRADES,datetime dtm=0,bool bUpdate=false)
{
double pr=0;
int flag,icount;
datetime dtm_open;
if(imode==MODE_TRADES)
{
if(ArraySize(m_orders)==0 || bUpdate) Update();
icount=ArraySize(m_orders);
for(int i=icount-1;i>=0;i--)
{
if(m_orders[i].OrderCloseTime>0) continue;
if(!CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) || !CheckSymbol(m_orders[i].OrderSymbol)) continue;
dtm_open=m_orders[i].OrderOpenTime;
flag=toMyTypes(m_orders[i].OrderType)&itype;
if(m_orders[i].OrderType==toDefType(flag,itype) && dtm_open>=dtm)
{
pr+=GroupOrderProfit(m_orders[i].OrderTicket);
}
}
}
else
{
if(ArraySize(m_historyorders)==0 || bUpdate) UpdateHistory();
icount=ArraySize(m_historyorders);
for(int i=icount-1;i>=0;i--)
{
if(m_historyorders[i].OrderCloseTime==0) continue;
if(!CheckMagic(m_historyorders[i].OrderMagicNumber,m_historyorders[i].OrderComment) || !CheckSymbol(m_historyorders[i].OrderSymbol)) continue;
dtm_open=m_historyorders[i].OrderOpenTime;
flag=toMyTypes(m_historyorders[i].OrderType)&itype;
if(m_historyorders[i].OrderType==toDefType(flag,itype) && dtm_open>=dtm)
{
pr+=GroupHistoryOrderProfit(m_historyorders[i].OrderTicket);
}
}
}
return (pr);
}
virtual double get_lots(int itype,bool bUpdate=false) //из старой библиотеки
{
double dlot=0;
if(ArraySize(m_orders)==0 || bUpdate) Update();
for(int i=0;i<ArraySize(m_orders);i++)
{
if(m_orders[i].OrderCloseTime>0) continue;
if(!CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) || !CheckSymbol(m_orders[i].OrderSymbol)) continue;
if(m_orders[i].OrderType==itype)
dlot+=GroupOrderLot(m_orders[i].OrderTicket);
}
return dlot;
}
virtual double get_lots(double &dlots[],bool bUpdate=false) //подсчет лотов
{
double dlot=0;
if(ArrayResize(dlots,2)!=-1){
ArrayInitialize(dlots,0);
if(ArraySize(m_orders)==0 || bUpdate) Update();
for(int i=0;i<ArraySize(m_orders);i++)
{
if(m_orders[i].OrderCloseTime>0) continue;
if(!CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) || !CheckSymbol(m_orders[i].OrderSymbol)) continue;
if(m_orders[i].OrderType<2){
dlots[m_orders[i].OrderType]+=GroupOrderLot(m_orders[i].OrderTicket);
}
}
dlot=dlots[0]+dlots[1];
}
return dlot;
}
int ModifyOrder(int iticket,double dopen,double dstop,double dtake)
{
__COPYRIGHT__
for(int i=0;i<ArraySize(m_orders);i++)
{
if(m_orders[i].OrderCloseTime>0) continue;
if(m_orders[i].OrderTicket==iticket)
{
if(dopen==-1) dopen=m_orders[i].OrderOpenPrice;
if(dstop==-1) dstop=m_orders[i].OrderStopLoss;
if(dtake==-1) dtake=m_orders[i].OrderTakeProfit;
m_orders[i].OrderOpenPrice=dopen;
m_orders[i].OrderStopLoss=dstop;
m_orders[i].OrderTakeProfit=dtake;
return i;
}
}
return -1;
}
int FindOrder(int iticket)
{
__COPYRIGHT__
for(int i=0;i<ArraySize(m_orders);i++)
{
if(m_orders[i].OrderCloseTime>0) continue;
if(m_orders[i].OrderTicket==iticket)
{
return i;
}
}
return EMPTY;
}
int FindHistoryOrder(int iticket)
{
__COPYRIGHT__
for(int i=0;i<ArraySize(m_historyorders);i++)
{
if(m_historyorders[i].OrderCloseTime==0) continue;
if(m_historyorders[i].OrderTicket==iticket)
{
return i;
}
}
return EMPTY;
}
bool OrderSelect(int iticket) //для совместимости
{
if(iticket<=0) return false;
return (::OrderSelect(iticket,SELECT_BY_TICKET));
}
bool OrderSelect(int iticket,int &iindex)
{
iindex=-1;
if(iticket<=0) return false;
iindex=FindOrder(iticket);
return (iindex!=-1);
}
bool HistoryOrderSelect(int iticket,int &iindex)
{
iindex=-1;
if(iticket<=0) return false;
iindex=FindHistoryOrder(iticket);
return (iindex!=-1);
}
bool Modify(const int iticket,double dopen,double dsl=0,double dtp=0,datetime dt=0,const color cl=clrNONE,const bool tpslIsPoint=false,bool bCheck=true)
{
__COPYRIGHT__
if(iticket<=0) return false;
bool is_open=false;
int i=FindOrder(iticket);
if(i==EMPTY) return false; //ордер не найден
double dstop=0,dtake=0,dlot=0;
string sinfo="";
string sname=m_orders[i].OrderSymbol;
double point=point(sname);
if(point==0) return false;
int itype=m_orders[i].OrderType;
double dlaststop=m_orders[i].OrderStopLoss;
double dlasttake=m_orders[i].OrderTakeProfit;
if(dopen==-1) dopen=nd(m_orders[i].OrderOpenPrice);
if(dsl==-1) dsl=dlaststop;
if(dtp==-1) dtp=dlasttake;
stoplevel=GetStopLevel(m_name)*MarketInfo(m_name,MODE_POINT);
if(tpslIsPoint)
{
if(itype==OP_BUY || itype==OP_BUYLIMIT || itype==OP_BUYSTOP)
{
if(dsl>0) dstop=nd(dopen-dsl*p,sname); else dstop=0;
if(dtp>0) dtake=nd(dopen+dtp*p,sname); else dtake=0;
}
if(itype==OP_SELL || itype==OP_SELLLIMIT || itype==OP_SELLSTOP)
{
if(dsl>0) dstop=nd(dopen+dsl*p,sname); else dstop=0;
if(dtp>0) dtake=nd(dopen-dtp*p,sname); else dtake=0;
}
}
else
{
if(dsl>0) dstop=nd(dsl,sname); else dstop=0;
if(dtp>0) dtake=nd(dtp,sname); else dtake=0;
}
dlot=m_orders[i].OrderLots;
/*double dvirtstop=virtual_get_sl(iticket);
double dvirttake=virtual_get_tp(iticket);
if(dsl>0 && dlaststop==0 && dvirtstop>0) dlaststop=dvirtstop;
if(dtp>0 && dlasttake==0 && dvirttake>0) dlasttake=dvirttake;
*/
double _Ask=Ask(sname);
double _Bid=Bid(sname);
/* if((itype==OP_BUYLIMIT || itype==OP_BUYSTOP) && ((dtake<dopen && dtake>0) || (dstop>dopen && dstop>0)))
{
return false;
}
if((itype==OP_SELLLIMIT || itype==OP_SELLSTOP) && ((dtake>dopen && dtake>0) || (dstop<dopen && dstop>0)))
{
return false;
}
*/
if(itype==OP_BUY && ((_Bid>dtake && dtake>0) || (_Bid<dstop && dstop>0)))
{
return false;
}
if(itype==OP_SELL && ((_Ask<dtake && dtake>0) || (_Ask>dstop && dstop>0)))
{
return false;
}
if(dt<=0) dt=m_orders[i].OrderExpiration;
if(!options_bNoModify)
{
int j=0;
while(!is_open && j<options_iRestartCount && !IsStopped())
{
j++;
if(iticket>0 &&
((bCheck && ((MathAbs(dopen-m_orders[i].OrderOpenPrice)/point>=1 && m_orders[i].OrderType>=2) ||
MathAbs(dtake-dlasttake)/point>=1 ||
MathAbs(dstop-dlaststop)/point>=1))
||
(!bCheck && ((MathAbs(dopen-m_orders[i].OrderOpenPrice)/point>=0.1 && m_orders[i].OrderType>=2) ||
MathAbs(dtake-dlasttake)/point>=0.1 ||
MathAbs(dstop-dlaststop)/point>=0.1))))
{
if(OrderSelect(iticket,SELECT_BY_TICKET))
{
if(OrderCloseTime()==0)
{
double ddelta=EMPTY_VALUE;
if(dstop>0){
if(itype==OP_BUY) ddelta=nd(_Ask-dstop);
if(itype==OP_SELL) ddelta=nd(dstop-_Bid);
}
if(ddelta>stoplevel || ddelta==EMPTY_VALUE)
{
if(!::OrderModify(iticket,dopen,dstop,dtake,dt,cl))
{
ierrors=GetLastError();
if(ierrors>0)
{
sinfo=StringConcatenate(__FUNCTION__,"(",iticket,",",string_type(itype),",",dlot,",",dopen,",",dstop,",",dtake,") Ask=",_Ask," Bid=",_Bid);
is_open=ErrorMessage(ierrors,j,sinfo,options_iTimeout);
}
}
else
{
is_open=true;
}
}
else
{
is_open=true;
}
}
}
}
}
}
else
{
is_open=true; //отключена модификация, обновим виртуальные данные
}
if(is_open && iticket>0)
{
int iret=ModifyOrder(iticket,dopen,dstop,dtake); //обновим информацию о тейк и стоп
if(options_bVirtual && itype<2 && (virtual_check(iticket) || iret==-1 || options_bNoModify)) virtual_set(iticket,dstop,dtake); //обновим виртуальные стоп и тейк
}
return is_open;
}
virtual bool OrderModify(const int iticket,double dopen,double dsl=0,double dtp=0,datetime dt=0,const color cl=clrNONE,const bool tpslIsPoint=false,bool bCheck=true)
{
__COPYRIGHT__
int ilast_ticket=OrderTicket();
bool is_modify=Modify(iticket,dopen,dsl,dtp,dt,cl,tpslIsPoint,bCheck);
if(options_bSupportMaxLot)
{
for(int i=ArraySize(m_orders)-1;i>=0;i--)
{
if(m_orders[i].OrderCloseTime>0) continue;
if(m_orders[i].OrderMagicNumber==MathAbs(iticket)) //дополнительные
{
Modify(m_orders[i].OrderTicket,dopen,dsl,dtp,dt,cl,tpslIsPoint,bCheck);
}
}
}
if(ilast_ticket>0) OrderSelect(ilast_ticket);
return (is_modify);
}
int Trade(const int cmd,const double dlot,double dopen,const double dsl=0,const double dtp=0,const string _comment="",const datetime dt=0,const color cl=clrNONE,const bool tpslIsPoint=true,const bool bAddCount=true)
{
__COPYRIGHT__
ierrors=0;
if(cmd<0) return -1;
if(!CheckOrderSend(cmd,dlot))
{
ierrors=134;
return (-134);
}
if(dlot==0.0) return 0; //лот не задан. не открываемся
double ddlot=NLot(dlot,m_name); //округлим лот по правилам
p=point(m_name);
bool is_open=true;
bool bret=false;
string sinfo="";
double dstop=0,dtake=0;
double dnewopen=dopen;
int digit=digits(m_name);
int iticket=-1,j=0;
ierrors=0; //обнулим данные о последней ошибке
bool bOpenEmpty=false;
double _Ask=Ask(m_name);
double _Bid=Bid(m_name);
while(is_open && j<options_iRestartCount && !IsStopped())
{
j++;
if(dopen==-1)
{
RefreshRates();
_Ask=Ask(m_name);
_Bid=Bid(m_name);
bOpenEmpty=true;
if(cmd==OP_BUY) dnewopen=_Ask;
if(cmd==OP_SELL) dnewopen=_Bid;
}
if(cmd==OP_BUYSTOP && _Ask>=dnewopen-stoplevel)
{
return 0;
}
if(cmd==OP_SELLSTOP && _Bid<=dnewopen+stoplevel)
{
return 0;
}
if(iticket==-1)
{
dtake=0;dstop=0;
if(!tpslIsPoint)
{
if(cmd==OP_BUYSTOP || cmd==OP_BUYLIMIT)
{
if(dtp>0) dtake=dtp;
if(dsl>0) dstop=dsl;
}
if(cmd==OP_SELLSTOP || cmd==OP_SELLLIMIT)
{
if(dtp>0) dtake=dtp;
if(dsl>0) dstop=dsl;
}
}else{
if(cmd==OP_BUYSTOP || cmd==OP_BUYLIMIT)
{
if(dtp>0) dtake=dnewopen+dtp*p;
if(dsl>0) dstop=dnewopen-dsl*p;
}
if(cmd==OP_SELLSTOP || cmd==OP_SELLLIMIT)
{
if(dtp>0) dtake=dnewopen-dtp*p;
if(dsl>0) dstop=dnewopen+dsl*p;
}
}
if(cmd>=2)
{
if(!options_bNoModify) iticket=::OrderSend(m_name,cmd,ddlot,NormalizeDouble(dnewopen,digit),m_islippage,dstop,dtake,_comment,(int)m_imagic,dt,cl);
else iticket=::OrderSend(m_name,cmd,ddlot,NormalizeDouble(dnewopen,digit),m_islippage,0,0,_comment,(int)m_imagic,dt,cl);
}
else
{
iticket=::OrderSend(m_name,cmd,ddlot,NormalizeDouble(dnewopen,digit),m_islippage,0,0,_comment,(int)m_imagic,dt,cl);
}
}
if(iticket!=-1 && cmd<2)
{
if(OrderSelect(iticket))
{
dnewopen=OrderOpenPrice();
dtake=0;dstop=0;
if(!tpslIsPoint)
{
if(cmd==OP_BUY)
{
if(dtp>0) dtake=dtp;
if(dsl>0) dstop=dsl;
}
if(cmd==OP_SELL)
{
if(dtp>0) dtake=dtp;
if(dsl>0) dstop=dsl;
}
}
else
{
if(cmd==OP_BUY)
{
if(dtp>0) dtake=dnewopen+dtp*p;
if(dsl>0) dstop=dnewopen-dsl*p;
}
if(cmd==OP_SELL)
{
if(dtp>0) dtake=dnewopen-dtp*p;
if(dsl>0) dstop=dnewopen+dsl*p;
}
}
if((dtake>0.0 || dstop>0.0) && dnewopen>0)
{
if(!options_bNoModify)
{
bret=::OrderModify(iticket,NormalizeDouble(dnewopen,digit),NormalizeDouble(dstop,digit),NormalizeDouble(dtake,digit),dt,cl);
}
if(options_bVirtual && (virtual_check(iticket) || !bret || options_bNoModify)) virtual_set(iticket,NormalizeDouble(dstop,digit),NormalizeDouble(dtake,digit));
}
}
}
ierrors=GetLastError();
if(iticket==-1 || ierrors>0)
{
sinfo=StringConcatenate(__FUNCTION__,"(",m_name,",",string_type(cmd),",",ddlot,",",dnewopen,",",dstop,",",dtake,",",_comment,") Ask=",_Ask," Bid=",_Bid);
is_open=ErrorMessage(ierrors,j,sinfo,options_iTimeout);
}
else
{
is_open=false;
}
if(OrderSelect(iticket))
{
int i=ArraySize(m_orders);
ArrayResize(m_orders,i+1);
if(m_orders[i].getOrderByTicket(iticket))
{
if(bAddCount)
{
m_all++;
orders[m_orders[i].OrderType]++;
}
}
if(iticket>0) m_total++;
return iticket;
}
}
if(iticket>0) m_total++;
return iticket;
}
virtual int OrderSend(const int cmd,const double dlot,double dopen,const double dsl=0,const double dtp=0,const string _comment="",const datetime dt=0,const color cl=clrNONE,const bool tpslIsPoint=true,double dMaxLot=0)
{
__COPYRIGHT__
int iticket=-1;
double dmaxLot=dMaxLot;
CSpeed speed;
if(dmaxLot==0) dmaxLot=MaxLot(m_name);
if(dlot<=dmaxLot)
{
iticket=Trade(cmd,dlot,dopen,dsl,dtp,_comment,dt,cl,tpslIsPoint);
return iticket;
}
if(!options_bSupportMaxLot)
{
return -1;
}
long ilast_magic=m_imagic;
int ic=(int)(MathFloor(dlot/dmaxLot));
double dostatok=0;
dostatok=dlot-dmaxLot*ic; //рассчитаем остаточный лот
iticket=-1;
int ifirst_ticket=-1;
for(int i=0;i<ic;i++)
{
iticket=Trade(cmd,dmaxLot,dopen,dsl,dtp,_comment,dt,cl,tpslIsPoint,false);
if(ifirst_ticket<0)
{
ifirst_ticket=iticket;
m_imagic=MathAbs(iticket); //для всех остальных меджик будет равен тикету по модулю
}
if(ifirst_ticket<0) break; //не открылся ордер
}
if(dostatok>0 && dostatok>=MinLot(m_name) && iticket>0) iticket=Trade(cmd,NLot(dostatok,m_name),dopen,dsl,dtp,_comment,dt,cl,tpslIsPoint,false);
m_imagic=ilast_magic;
return ifirst_ticket;
}
virtual bool OrderCloseAll(const int itype=ALL,const color cl=clrNONE,bool bUpdate=false)
{
__COPYRIGHT__
double currents[][3]; //профит, тикет, i
ArrayResize(currents,0);
int c=0,flag;
if(ArraySize(m_orders)==0 || bUpdate) Update();
bool bRet=false;
for(int i=ArraySize(m_orders)-1;i>=0;i--)
{
if(m_orders[i].OrderCloseTime>0) continue;
flag=toMyTypes(m_orders[i].OrderType)&itype;
if(CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) && CheckSymbol(m_orders[i].OrderSymbol) && m_orders[i].OrderType==toDefType(flag,itype))
{
ArrayResize(currents,c+1);
currents[c][0]=m_orders[i].Profit;
currents[c][1]=m_orders[i].OrderTicket;
currents[c][2]=i;
c++;
}
}
if(c>0)
{
ArraySort(currents,WHOLE_ARRAY,0,MODE_DESCEND); //отсортируем по профиту от минусовых к плюсовым
for(int i=0;i<ArrayRange(currents,0);i++)
{
if(Close((int)currents[i][1],-1,cl))bRet=true;
}
}
if(bRet) UpdateOrders(); //чистим от удаленных
return true;
}
virtual bool Close(const int iticket,double dlot=-1,color cl=clrNONE)
{
__COPYRIGHT__
ierrors=0;
if(iticket<=0) return false;
if(!OrderSelect(iticket))
{
ierrors=GetLastError();
return (false);
}
int aOrder[];
int isize=0;
for(int i=0;i<ArraySize(m_orders);i++)
{
if(m_orders[i].OrderCloseTime>0)
{
continue;
}
if(m_orders[i].OrderTicket==iticket || m_orders[i].OrderMagicNumber==MathAbs(iticket))
{
isize=ArrayRange(aOrder,0);
if(ArrayResize(aOrder,isize+1)!=-1)
{
aOrder[isize]=m_orders[i].OrderTicket;
}
}
}
isize=ArrayRange(aOrder,0);
bool is_open=true;
bool bret=false;
int j=0;
string sinfo="";
double dsummlot=GroupOrderLot(iticket); //весь объем всей группы ордеров
if(dlot==-1) dlot=dsummlot;
double dopen=0;
double dclose=0;
int t=OrderType();
if(isize>1) ArraySort(aOrder,WHOLE_ARRAY,0,MODE_DESCEND); //сортируем по возрастанию
for(int i=isize-1;i>=0;i--)
{
int index_ticket=aOrder[i];
if(iticket==index_ticket)
{
continue; //пропустим основной
}
int index=-1;
if(OrderSelect(index_ticket,index))
{
double dlotClose=m_orders[index].OrderLots;
if(dlot>=dlotClose)
{
if(CloseOrder(index_ticket,t,dlotClose,cl))
dlot-=dlotClose;
}
else
{
if(CloseOrder(index_ticket,t,dlot,cl)) dlot-=dlot;
}
if(dlot<=0) break;
}
}
if(dlot>0)
{
for(int i=isize-1;i>=0;i--)
{
int index_ticket=aOrder[i];
if(iticket!=index_ticket) continue; //пропустим неосновные если остались
int index=-1;
if(OrderSelect(index_ticket,index))
{
double dlotClose=m_orders[index].OrderLots;
if(dlot>=dlotClose)
{
if(CloseOrder(index_ticket,t,dlotClose,cl))
dlot-=dlotClose;
}
else
{
if(CloseOrder(index_ticket,t,dlot,cl)) dlot-=dlot;
}
if(dlot<=0) break;
}
}
}
return (is_open);
}
void Sleep(int millisec)
{
if(IsTester) return; //в тестере отключаем задержки принудительно
::Sleep(millisec);
}
bool CloseOrder(int iticket,int itype,double dlot,color cl)
{
__COPYRIGHT__
int j=0;
double dclose=0;
bool bret=false;
string sinfo="",sname=m_name;
bool is_open=true;
while(is_open && j<options_iRestartCount && !IsStopped())
{
j++;
if(OrderSelect(iticket))
{
bool bPartClose=false;
if(OrderCloseTime()>0)
{
int index_history=FindHistoryOrder(iticket); //найдем наш закрытый ордер и обновим информацию о нем.
int jindex=ArraySize(m_historyorders);
if(index_history==-1)
{
ArrayResize(m_historyorders,jindex+1); //новый ордер в истории, поместим даныне о онем
}
else
{
jindex=index_history; //если найден, то обновим информацию
}
if(m_historyorders[jindex].getOrderByTicket(iticket))
{
if(index_history==-1)
{
m_historyall++;
history[m_historyorders[jindex].OrderType]++;
}
}
continue; //ордер уже закрыт
}
if(iticket>0 && itype<2)
{
sname=OrderSymbol();
if(OrderLots()<dlot) dlot=OrderLots(); //закрыть весь лот
if(OrderLots()>dlot) bPartClose=true;
dclose=OrderClosePrice();
if(dclose==0.0)
{
if(itype==OP_BUY) dclose=Bid(sname);
else if(itype==OP_SELL) dclose=Ask(sname);
}
bret=::OrderClose(iticket,dlot,dclose,m_islippage,cl);
if(bret && bPartClose)
{
string n=OrderSymbol();
int ipos=-1;
if(OrderSelect(iticket,ipos))
{
int itotal=::OrdersTotal();
for(int i=itotal-1;i>=0;i--)
{
if(!OrderSelect(i,SELECT_BY_POS)) continue;
if(OrderSymbol()==n && StringFind(OrderComment(),StringFormat("from #%d",iticket))>=0)
{
if(m_orders[ipos].getOrderByTicket(OrderTicket(),MODE_TRADES))
{
int index_history=FindHistoryOrder(iticket); //найдем нах закрытый ордер и обновим информацию о нем.
int jindex=ArraySize(m_historyorders);
if(index_history==-1)
{
ArrayResize(m_historyorders,jindex+1); //новый ордер в истории, поместим даныне о онем
}
else
{
jindex=index_history; //если найден, то обновим информацию
}
if(m_historyorders[jindex].getOrderByTicket(iticket))
{
if(index_history==-1)
{
m_historyall++;
history[m_historyorders[jindex].OrderType]++;
}
}
}
break;
}
}
}
}
}
if(iticket>0 && itype>=2)
{
bret=OrderDelete(iticket,cl);
bPartClose=false; //отложки не закрыть частями, поэтому информацию о ней нам надо будет удалить потмо
}
ierrors=GetLastError();
if(ierrors>0)
{
sinfo=StringConcatenate(__FUNCTION__,"(",iticket,",",dlot,")");
is_open=ErrorMessage(ierrors,j,NULL,options_iTimeout);
}
else
{
is_open=false;
}
if(bret && !bPartClose)
{
ClearOrder(iticket); //пометим что ордер удален если это было не частичное закрытие! это важно
m_total--;
return true;
}
}
else
{
break;
}
}
return is_open;
}
virtual bool OrderClose(const int iticket,double dlot=-1,color cl=clrNONE)
{
__COPYRIGHT__
int ilast_ticket=OrderTicket();
bool is_modify=Close((int)iticket,dlot,cl); //закрывается основной ордер и дополнительные если требуется
if(ilast_ticket>0) OrderSelect(ilast_ticket);
return (is_modify);
}
bool DefaultOrderClose(const int iticket,double dlot=-1,color cl=clrNONE)
{
__COPYRIGHT__
int ilast_ticket=OrderTicket();
bool is_open=true;
bool bret=false;
int j=0;
int digit=(int)MarketInfo(OrderSymbol(),MODE_DIGITS);
string info="";
if(dlot==-1) dlot=OrderLots();
double dopen=0;
double dclose=0;
int t=OrderType();
while(is_open && j<5)
{
j++;
if(iticket>0 && t<2)
{
if(OrderLots()<dlot) dlot=OrderLots(); //закрыть весь лот
dclose=OrderClosePrice();
if(dclose==0.0)
{
if(t==OP_BUY) dclose=Bid(OrderSymbol());
else if(t==OP_SELL) dclose=Ask(OrderSymbol());
}
bret=::OrderClose(iticket,dlot,dclose,0,cl);
}
if(iticket>0 && t>=2)
{
bret=OrderDelete(iticket,cl);
}
ierrors=GetLastError();
if(ierrors>0)
{
info=StringConcatenate(__FUNCTION__,"(",iticket,",",dlot,")");
is_open=ErrorMessage(ierrors,j,info);
if(ierrors==ERR_OFF_QUOTES)
while(!IsStopped())
{
if(RefreshRates()) break; Sleep(1000);
}
}
else
{
is_open=false;
}
}
if(ilast_ticket>0) OrderSelect(ilast_ticket);
return (is_open);
}
virtual bool PartClose(double dpartclose_profit,double dpartclose_procent,bool bUpdate=false)
{
bool bClose=false;
if(dpartclose_profit==0) return false;
if(ArraySize(m_orders)==0 || bUpdate) Update();
string sname=m_name;
for(int i=ArraySize(m_orders)-1;i>=0;i--)
{
if(m_orders[i].OrderCloseTime>0) continue;
if(m_orders[i].OrderType<2 && CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) && CheckSymbol(m_orders[i].OrderSymbol))
{
if(m_orders[i].OrderType==OP_BUY || m_orders[i].OrderType==OP_SELL)
{
double dstop=m_orders[i].OrderStopLoss;
double pr=m_orders[i].OrderProfitPoint;
double dlot=NLot(m_orders[i].OrderLots*dpartclose_procent/100); //часть лота
if(m_orders[i].OrderLots<=MinLot(m_orders[i].OrderSymbol)) continue; //пропуск если остаток меньше минимального лота или равен ему
double dsummlots=0;
int part=get_part(m_orders[i].OrderTicket,dsummlots);
if(part==0 && pr>=dpartclose_profit)
{
Print("Close part order and safe stoploss: ",DoubleToString(dlot,2));
OrderClose(m_orders[i].OrderTicket,dlot,clrNONE);
bClose=true;
}
}
}
}
return bClose;
}
/*
lot - суммарный лот
*/
virtual int get_part(int ticket,double &dsummlot) //вспомогательная функция ищет кол-во частичных закрытий
{
int part=0;
dsummlot=0;
datetime tOpen=0;
int iimagic;
double open;
string name;
int ipos=FindOrder(ticket);
if(ipos<0) return -1;
open=m_orders[ipos].OrderOpenPrice;
tOpen=m_orders[ipos].OrderOpenTime;
iimagic=m_orders[ipos].OrderMagicNumber;
name=m_orders[ipos].OrderSymbol;
long id=m_orders[ipos].OrderTicket;
dsummlot=m_orders[ipos].OrderLots;
int i=0;
while(i<m_historyall && !IsStopped()) //востановим по истории кол-во закрытий и полный лот
{
if(StringFind(m_historyorders[i].OrderComment,StringFormat("to #%d",id))==0)
{
id=m_historyorders[i].OrderTicket;
dsummlot+=m_historyorders[i].OrderLots;
part++;
i=0;
continue;
}
i++;
}
return part; //вернем сколько раз уже закрывались
}
bool ErrorMessage(const int err,const int j,const string informer="",const int ipause=5000)
{
__COPYRIGHT__
bool is_open=true;
switch(err)
{
case ERR_NO_ERROR:
case ERR_NO_MQLERROR:
case ERR_NO_RESULT:
case ERR_INVALID_TRADE_PARAMETERS:{Print("Invalid trade parameters "+informer);is_open=false;} break;
case ERR_COMMON_ERROR:{is_open=false; break;}
case ERR_BROKER_BUSY: {Print("Broker is busy, try №"+DoubleToStr(j,0)); Sleep(ipause);} break;
case ERR_SERVER_BUSY:
case ERR_TRADE_CONTEXT_BUSY: {Print("Server is busy, try №"+DoubleToStr(j,0)); Sleep(ipause);} break;
case ERR_NO_CONNECTION: {Print("No connection to the server, the attempt №"+DoubleToStr(j,0)); Sleep(ipause); is_open=false;} break;
case ERR_TRADE_TIMEOUT: {Print("Outdated waiting transaction, an attempt №"+DoubleToStr(j,0)); Sleep(ipause); is_open=false;} break;
case ERR_PRICE_CHANGED: {Print("Price changed attempt №"+DoubleToStr(j,0)+" "+informer); Sleep(ipause);} break;
case ERR_REQUOTE: {Print("Requotes attempt №"+DoubleToStr(j,0)+" "+informer); Sleep(ipause); RefreshRates();} break;
case ERR_OFF_QUOTES: {Print("Off quotes attempt №"+DoubleToStr(j,0)+" "+informer); Sleep(ipause); RefreshRates();} break;
case ERR_TOO_FREQUENT_REQUESTS: {Print("Too frequent queries attempt №"+DoubleToStr(j,0)+" "+informer); is_open=false;} break;
case ERR_ORDER_LOCKED: {is_open=false; Print("Order has been locked and processed");} break;
case ERR_INVALID_STOPS: {Print("Invalid stop "+informer);is_open=false;} break;
case ERR_INVALID_PRICE: {Print("Invalid price (slippage), an attempt №"+DoubleToStr(j,0)+" "+informer);} break;
case ERR_INVALID_TRADE_VOLUME: {is_open=false; Print("Invalid volume, "+informer);} break;
case ERR_MARKET_CLOSED: {is_open=false; } break;
case ERR_TRADE_DISABLED: {is_open=false; Print("Trade is not allowed"); } break;//торговля запрещена
case ERR_NOT_ENOUGH_MONEY: {is_open=false; Print("Enough money to make the operation, "+informer);} break;
case ERR_LONG_POSITIONS_ONLY_ALLOWED: {is_open=false; Print("Allowed only buy");} break;
case ERR_TRADE_MODIFY_DENIED: {Print("Order is too close to the market (option disabled), the attempt №"+DoubleToStr(j,0)+" "+informer); Sleep(ipause);} break;
case ERR_TRADE_EXPIRATION_DENIED: {is_open=false; Print("Using the date of expiry of the order is prohibited broker");} break;
case ERR_TRADE_TOO_MANY_ORDERS: {is_open=false; Print("The number of open and pending orders has reached the limit set by the broker");} break;
case ERR_TRADE_HEDGE_PROHIBITED: {is_open=false; Print("Trying to dopen an opposite position to the already existing, if hedging is disabled");} break;
case ERR_TRADE_PROHIBITED_BY_FIFO: {is_open=false; Print("Trying to close the position at the instrument in contradiction with the FIFO rule");} break;
case ERR_ARRAY_INDEX_OUT_OF_RANGE: {is_open=false; break;}
case ERR_INVALID_TICKET: {is_open=false; break; }
case ERR_UNKNOWN_SYMBOL: {is_open=false; Print("Unknown symbol"); break; }
case ERR_TRADE_NOT_ALLOWED: {is_open=false; Print("Trade is not allowed. Enable checkbox \"Allow live trading\" in the expert properties."); break; }
case ERR_LONGS_NOT_ALLOWED: {is_open=false; Print("Longs are not allowed. Check the expert properties."); break; }
case ERR_SHORTS_NOT_ALLOWED: {is_open=false; Print("Shorts are not allowed. Check the expert properties."); break; }
default: {is_open=false; Print("unknown error: "+IntegerToString(err)+" "+informer);} break;
}
return (is_open);
}
bool CheckOrderSend(int itype,double dlot)
{
__COPYRIGHT__
if(dlot<=0.0) return (false);
int limit=(int)AccountInfoInteger(ACCOUNT_LIMIT_ORDERS);
if(limit>0 && m_total>=limit) return false; //обход ошибки 148 превышен лимит ордеров
if(!options_bCheckFreeMargin) return true;
int it=itype;
if(options_bNoCheckPending)
{
if(it==OP_BUYLIMIT || it==OP_BUYSTOP) return true;
if(it==OP_SELLLIMIT || it==OP_SELLSTOP) return true;
}
else
{
if(it==OP_BUYLIMIT || it==OP_BUYSTOP) it=OP_BUY;
if(it==OP_SELLLIMIT || it==OP_SELLSTOP) it=OP_SELL;
}
if(AccountFreeMarginCheck(m_name,it,dlot)<=0 || GetLastError()==134)
{
return (false);
}
return (true);
}
int getOrderTicket(int itype=ALL,const int imode=MODE_TRADES,const datetime dttm=0,bool bHistoryOpenOrderTime=true,bool bUpdate=false)
{
__COPYRIGHT__
datetime dtm=0,dtm_open=0;
int iticket=-1,icount=0;
int flag;
if(imode==MODE_TRADES)
{
if(ArraySize(m_orders)==0 || bUpdate) Update();
icount=ArraySize(m_orders);
for(int i=icount-1;i>=0;i--)
{
if(m_orders[i].OrderCloseTime>0) continue;
if(!CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) || !CheckSymbol(m_orders[i].OrderSymbol)) continue;
dtm_open=m_orders[i].OrderOpenTime;
flag=toMyTypes(m_orders[i].OrderType)&itype;
if(m_orders[i].OrderType==toDefType(flag,itype) && dtm_open>=dttm && dtm_open>=dtm)
{
dtm=dtm_open;
iticket=m_orders[i].OrderTicket;
}
}
}
else
{
if(ArraySize(m_historyorders)==0 || bUpdate) UpdateHistory();
icount=ArraySize(m_historyorders);
for(int i=icount-1;i>=0;i--)
{
if(m_historyorders[i].OrderCloseTime==0) continue;
if(!CheckMagic(m_historyorders[i].OrderMagicNumber,m_historyorders[i].OrderComment) || !CheckSymbol(m_historyorders[i].OrderSymbol)) continue;
if(bHistoryOpenOrderTime) dtm_open=m_historyorders[i].OrderOpenTime; else dtm_open=m_historyorders[i].OrderCloseTime;
flag=toMyTypes(m_historyorders[i].OrderType)&itype;
if(m_historyorders[i].OrderType==toDefType(flag,itype) && dtm_open>=dttm && dtm_open>=dtm)
{
dtm=dtm_open;
iticket=m_historyorders[i].OrderTicket;
}
}
}
return iticket;
}
int getFirstTicket(int itype=ALL,const int imode=MODE_TRADES,const datetime dttm=0,bool bOpenOrderTime=true,bool bUpdate=false)
{
datetime dtm=EMPTY_VALUE,dtm_open=EMPTY_VALUE;
int iticket=-1,icount=0;
int flag;
if(imode==MODE_TRADES)
{
if(ArraySize(m_orders)==0 || bUpdate) Update();
icount=ArraySize(m_orders);
for(int i=icount-1;i>=0;i--)
{
if(m_orders[i].OrderCloseTime>0) continue;
if(!CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) || !CheckSymbol(m_orders[i].OrderSymbol)) continue;
dtm_open=m_orders[i].OrderOpenTime;
flag=toMyTypes(m_orders[i].OrderType)&itype;
if(m_orders[i].OrderType==toDefType(flag,itype) && dtm_open>=dttm && dtm_open<=dtm)
{
dtm=dtm_open;
iticket=m_orders[i].OrderTicket;
}
}
}
else
{
if(ArraySize(m_historyorders)==0 || bUpdate) UpdateHistory();
icount=ArraySize(m_historyorders);
for(int i=icount-1;i>=0;i--)
{
if(m_historyorders[i].OrderCloseTime==0) continue;
if(!CheckMagic(m_historyorders[i].OrderMagicNumber,m_orders[i].OrderComment) || !CheckSymbol(m_historyorders[i].OrderSymbol)) continue;
if(bOpenOrderTime) dtm_open=m_historyorders[i].OrderOpenTime; else dtm_open=m_historyorders[i].OrderCloseTime;
flag=toMyTypes(m_historyorders[i].OrderType)&itype;
if(m_historyorders[i].OrderType==toDefType(flag,itype) && dtm_open>=dttm && dtm_open<=dtm)
{
dtm=dtm_open;
iticket=m_historyorders[i].OrderTicket;
}
}
}
return (iticket);
}
int getLastOrderTicket(int itype=ALL,_ORDER_MODE imode=ORDER_UP,bool bUpdate=false)
{
CSpeed s1;
datetime dtm=0,dtm_open=0;
int iticket=-1,icount=0;
int flag;
double array_order_open[][2];
ArrayResize(array_order_open,0);
int c=0;
if(ArraySize(m_orders)==0 || bUpdate) Update();
for(int i=ArraySize(m_orders)-1;i>=0;i--)
{
if(m_orders[i].OrderCloseTime>0) continue;
if(CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) && CheckSymbol(m_orders[i].OrderSymbol))
{
flag=toMyTypes(m_orders[i].OrderType)&itype;
if(m_orders[i].OrderType==toDefType(flag,itype))
{
ArrayResize(array_order_open,c+1);
array_order_open[c][0]=m_orders[i].OrderOpenPrice;
array_order_open[c][1]=m_orders[i].OrderTicket;
c++;
}
}
}
if(itype==OP_BUY && c>0)
{
ArraySort(array_order_open,WHOLE_ARRAY,0,MODE_ASCEND); //сортируем в сторону увеличения, тогда 0й ордер будет самый нижний, последний сверху (первый).
if(imode==ORDER_DN) return ((int)array_order_open[0][1]);
if(imode==ORDER_UP) return ((int)array_order_open[c-1][1]);
}
if(itype==OP_SELL && c>0)
{
ArraySort(array_order_open,WHOLE_ARRAY,0,MODE_DESCEND); //сортируем в сторону уменьшения, тогда 0й ордер будет самый нижний, последний сверху (первый).
if(imode==ORDER_UP) return ((int)array_order_open[0][1]);
if(imode==ORDER_DN) return ((int)array_order_open[c-1][1]);
}
return 0;
}
int getLastHistoryTicket(int itype=ALL,const datetime dttm=0,bool bUpdate=false)
{
datetime dtm=0,dtm_open=EMPTY_VALUE;
int iticket=-1,icount=0;
int flag;
if(ArraySize(m_historyorders)==0 || bUpdate) UpdateHistory();
icount=ArraySize(m_historyorders);
for(int i=icount-1;i>=0;i--)
{
if(m_historyorders[i].OrderCloseTime==0) continue;
if(CheckSymbol(m_historyorders[i].OrderSymbol) && CheckMagic(m_historyorders[i].OrderMagicNumber,m_historyorders[i].OrderComment))
{
dtm_open=m_historyorders[i].OrderOpenTime;
flag=toMyTypes(m_historyorders[i].OrderType)&itype;
if(m_historyorders[i].OrderType==toDefType(flag,itype) && dtm_open>=dttm && dtm_open>=dtm)
{
dtm=dtm_open;
iticket=m_historyorders[i].OrderTicket;
}
}
}
return (iticket);
}
void trailing_simple(double level,double doffset,double dstep=0,int itype=ALL,bool bUpdate=false)
{
double st,dstop=0,dStep=dstep,dvirtstop=0;
int flag;
if(level==0.0) return;
if(ArraySize(m_orders)==0 || bUpdate) Update();
for(int i=ArraySize(m_orders)-1;i>=0;i--)
{
if(m_orders[i].OrderCloseTime>0) continue;
if(CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) && CheckSymbol(m_orders[i].OrderSymbol))
{
if(m_orders[i].OrderType>=2) continue;
p=point(m_orders[i].OrderSymbol);
string n=m_orders[i].OrderSymbol;
double tick=MarketInfo(n,MODE_TICKSIZE);
if(dStep==0) dStep=tick/p;
dstop=m_orders[i].OrderStopLoss;
dvirtstop=dstop;
if(options_bVirtual) dvirtstop=virtual_get_sl(m_orders[i].OrderTicket);
double pt=0;
flag=toMyTypes(m_orders[i].OrderType)&itype;
if(m_orders[i].OrderType==OP_BUY && m_orders[i].OrderType==toDefType(flag,itype))
{
pt=(Bid(n)-m_orders[i].OrderOpenPrice)/p;
st=NormalizeDouble(MathFloor((Bid(n)-MathAbs(doffset)*p)/tick)*tick,digits(n));
if(pt>=level && level!=0.0)
{
if(dvirtstop>dstop && dvirtstop>0) dstop=dvirtstop;
if(dstop==0 || (dstop<st && (st-dstop)/p>=dStep))
{
OrderModify(m_orders[i].OrderTicket,-1,st,-1,0,clrNONE);
continue;
}
}
}
if(m_orders[i].OrderType==OP_SELL && m_orders[i].OrderType==toDefType(flag,itype))
{
pt=(m_orders[i].OrderOpenPrice-Ask(n))/p;
st=NormalizeDouble(MathFloor((Ask(n)+MathAbs(doffset)*p)/tick)*tick,digits(n));
if(pt>=level && level!=0)
{
if(dvirtstop<dstop && dvirtstop>0) dstop=dvirtstop;
if(dstop==0 || (dstop>st && (dstop-st)/p>=dStep))
{
OrderModify(m_orders[i].OrderTicket,-1,st,-1,0,clrNONE);
continue;
}
}
}
}
}
}
void trailing_udavka(double level,double doffset,double dstep,int itype=ALL,bool bUpdate=false)
{
double st,dstop=0,dStep=dstep,dvirtstop=0;
int flag;
if(level==0.0) return;
if(ArraySize(m_orders)==0 || bUpdate) Update();
for(int i=ArraySize(m_orders)-1;i>=0;i--)
{
if(m_orders[i].OrderCloseTime>0) continue;
if(CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) && CheckSymbol(m_orders[i].OrderSymbol))
{
if(m_orders[i].OrderType>=2) continue;
p=point(m_orders[i].OrderSymbol);
string n=m_orders[i].OrderSymbol;
double tick=MarketInfo(n,MODE_TICKSIZE);
if(dStep==0) dStep=tick/p;
dstop=m_orders[i].OrderStopLoss;
dvirtstop=dstop;
if(options_bVirtual) dvirtstop=virtual_get_sl(m_orders[i].OrderTicket);
double pt=0;
flag=toMyTypes(m_orders[i].OrderType)&itype;
if(m_orders[i].OrderType==OP_BUY && m_orders[i].OrderType==toDefType(flag,itype))
{
pt=(Bid(n)-m_orders[i].OrderOpenPrice)/p;
int steps=(int)MathFloor((pt-level)/dStep);
st=NormalizeDouble(MathFloor((Bid(n)-MathAbs(doffset-steps*dStep)*p)/tick)*tick,digits(n));
if(pt>=level && level!=0.0)
{
if(dvirtstop>dstop && dvirtstop>0) dstop=dvirtstop;
if(dstop==0 || (dstop<st && (st-dstop)/p>=dStep))
{
OrderModify(m_orders[i].OrderTicket,-1,st,-1,0,clrNONE);
continue;
}
}
}
if(m_orders[i].OrderType==OP_SELL && m_orders[i].OrderType==toDefType(flag,itype))
{
pt=(m_orders[i].OrderOpenPrice-Ask(n))/p;
int steps=(int)MathFloor((pt-level)/dStep);
st=NormalizeDouble(MathFloor((Ask(n)+MathAbs(doffset-steps*dStep)*p)/tick)*tick,digits(n));
if(pt>=level && level!=0)
{
if(dvirtstop<dstop && dvirtstop>0) dstop=dvirtstop;
if(dstop==0 || (dstop>st && (dstop-st)/p>=dStep))
{
OrderModify(m_orders[i].OrderTicket,-1,st,-1,0,clrNONE);
continue;
}
}
}
}
}
}
void trailing_by_price(double price=0,int itype=ALL,double dstep=1,bool bUpdate=false)
{
double st,dstop=0,dvirtstop=0;
int flag;
if(price==0.0) return;
if(ArraySize(m_orders)==0 || bUpdate) Update();
for(int i=ArraySize(m_orders)-1;i>=0;i--)
{
if(m_orders[i].OrderCloseTime>0) continue;
if(CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) && CheckSymbol(m_orders[i].OrderSymbol))
{
if(m_orders[i].OrderType>=2) continue;
string n=m_orders[i].OrderSymbol;
double tick=MarketInfo(n,MODE_TICKSIZE);
dstop=m_orders[i].OrderStopLoss;
dvirtstop=dstop;
if(options_bVirtual) dvirtstop=virtual_get_sl(m_orders[i].OrderTicket);
double pt=0;
flag=toMyTypes(m_orders[i].OrderType)&itype;
if(m_orders[i].OrderType==OP_BUY && m_orders[i].OrderType==toDefType(flag,itype))
{
st=NormalizeDouble(MathFloor(price/tick)*tick,digits(n));
if(dvirtstop>dstop && dvirtstop>0) dstop=dvirtstop;
if(dstop==0 || (dstop<st && (st-dstop)/p>=dstep))
{
OrderModify(m_orders[i].OrderTicket,-1,st,-1,0,clrNONE);
continue;
}
}
if(m_orders[i].OrderType==OP_SELL && m_orders[i].OrderType==toDefType(flag,itype))
{
st=NormalizeDouble(MathFloor(price/tick)*tick,digits(n));
if(dvirtstop<dstop && dvirtstop>0) dstop=dvirtstop;
if(dstop==0 || (dstop>st && (dstop-st)/p>=dstep))
{
OrderModify(m_orders[i].OrderTicket,-1,st,-1,0,clrNONE);
continue;
}
}
}
}
}
void bu_simple(double dlevel,double doffset,int itype=ALL,bool bUpdate=false)//перенос в бу при достижении заданной прибыли
{
double st,dstop=0,dvirtstop=0;
int flag;
if(dlevel==0.0) return;
if(ArraySize(m_orders)==0 || bUpdate) Update();
int isize=ArraySize(m_orders);
for(int i=isize-1;i>=0;i--)
{
if(m_orders[i].OrderCloseTime>0) continue;
if(CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) && CheckSymbol(m_orders[i].OrderSymbol))
{
if(m_orders[i].OrderType>=2) continue;
string n=m_orders[i].OrderSymbol;
double tick=MarketInfo(n,MODE_TICKSIZE);
dstop=m_orders[i].OrderStopLoss;
dvirtstop=dstop;
if(options_bVirtual) dvirtstop=virtual_get_sl(m_orders[i].OrderTicket);
double pt=0;
flag=toMyTypes(m_orders[i].OrderType)&itype;
if(m_orders[i].OrderType==OP_BUY && m_orders[i].OrderType==toDefType(flag,itype))
{
pt=(Bid(n)-m_orders[i].OrderOpenPrice)/p;
if(pt>=dlevel && dlevel!=0.0)
{
st=m_orders[i].OrderOpenPrice+doffset*p;
if(dvirtstop>dstop && dvirtstop>0) dstop=dvirtstop;
if(dstop==0 || dstop<st)
{
OrderModify(m_orders[i].OrderTicket,-1,st,-1,0,clrNONE);
continue;
}
}
}
if(m_orders[i].OrderType==OP_SELL && m_orders[i].OrderType==toDefType(flag,itype))
{
pt=(m_orders[i].OrderOpenPrice-Ask(n))/p;
if(pt>=dlevel && dlevel!=0)
{
st=m_orders[i].OrderOpenPrice-doffset*p;
if(dvirtstop<dstop && dvirtstop>0) dstop=dvirtstop;
if(dstop==0 || dstop>st)
{
OrderModify(m_orders[i].OrderTicket,-1,st,-1,0,clrNONE);
continue;
}
}
}
}
}
}
int getCountProfit(int itype=-1,datetime dtm=0,bool bUpdate=false)
{
int icount=0;
if(ArraySize(m_historyorders)==0 || bUpdate) UpdateHistory();
for(int i=ArraySize(m_historyorders)-1;i>=0;i--)
{
if(m_historyorders[i].OrderCloseTime==0) continue;
if(!CheckMagic(m_historyorders[i].OrderMagicNumber,m_historyorders[i].OrderComment) || !CheckSymbol(m_historyorders[i].OrderSymbol)) continue;
if(m_historyorders[i].OrderOpenTime>=dtm && m_historyorders[i].OrderType<2)
{
if((m_historyorders[i].OrderType==itype || itype==-1))
{
if(m_historyorders[i].OrderProfitPoint>=0) icount++;
else break;
}
}
}
return (icount);
}
int getCountMinus(int itype=-1,bool sl_cmt_use=false,datetime dtm=0,bool bUpdate=false)
{
int icount=0;
if(ArraySize(m_historyorders)==0 || bUpdate) UpdateHistory();
for(int i=ArraySize(m_historyorders)-1;i>=0;i--)
{
if(m_historyorders[i].OrderCloseTime==0) continue;
if(!CheckMagic(m_historyorders[i].OrderMagicNumber,m_historyorders[i].OrderComment) || !CheckSymbol(m_historyorders[i].OrderSymbol)) continue;
if(CheckMagic(m_historyorders[i].OrderMagicNumber,m_historyorders[i].OrderComment) && m_historyorders[i].OrderOpenTime>=dtm && m_historyorders[i].OrderType<2)
{
if((m_historyorders[i].OrderType==itype || itype==-1))
{
if(m_historyorders[i].OrderProfitPoint<0 && ((StringFind(m_historyorders[i].OrderComment,"[sl]")>=0 && sl_cmt_use) || !sl_cmt_use)) icount++;
else break;
}
}
}
return (icount);
}
void trailing_bankomat(int itf,int iATR_Period=5,double dSAR_step=0.02,double dSAR_maximum=0.2,int itype=-1,double trailing_bankomat_atr_koef=1,bool bUpdate=false)
{
int t;
double dstop,open,dvirtstop;
double _Ask=Ask(m_name);
double _Bid=Bid(m_name);
double sp=_Ask-_Bid;
if(ArraySize(m_orders)==0 || bUpdate) Update();
for(int i=ArraySize(m_orders)-1;i>=0;i--)
{
if(m_orders[i].OrderCloseTime>0) continue;
if(CheckMagic(m_orders[i].OrderMagicNumber,m_orders[i].OrderComment) && CheckSymbol(m_orders[i].OrderSymbol))
{
t=m_orders[i].OrderTicket;
datetime dtm_start=m_orders[i].OrderOpenTime;
int pos=iBarShift(m_name,itf,dtm_start);
double dhigh[],dlow[];
double datr[],dsar[];
ArrayResize(dhigh,pos+1);
ArrayResize(dlow,pos+1);
ArrayResize(datr,pos+1);
ArrayResize(dsar,pos+1);
ArrayInitialize(dhigh,0);
ArrayInitialize(dlow,0);
ArrayInitialize(datr,0);
ArrayInitialize(dsar,0);
ArraySetAsSeries(dhigh,true);
ArraySetAsSeries(dlow,true);
ArraySetAsSeries(datr,true);
ArraySetAsSeries(dsar,true);
HideTestIndicators(TRUE);
for(int ii=0;ii<pos+1;ii++)
{
datr[ii]=iATR(m_name,itf,iATR_Period,ii+1);
dsar[ii]=iSAR(m_name,itf,dSAR_step,dSAR_maximum,ii+1);
dhigh[ii]=iHigh(m_name,itf,ii+1);
dlow[ii]=iLow(m_name,itf,ii+1);
}
HideTestIndicators(FALSE);
int type=m_orders[i].OrderType;
open=m_orders[i].OrderOpenPrice;
dstop=m_orders[i].OrderStopLoss;
dvirtstop=dstop;
if(options_bVirtual) dvirtstop=virtual_get_sl(m_orders[i].OrderTicket);
double newstop=0;
double tick=MarketInfo(m_name,MODE_TICKSIZE);
for(int ii=0;ii<pos;ii++)
{
if(dsar[ii]>dhigh[ii] && dsar[ii+1]<dlow[ii+1])
{
if(type==OP_BUY)
{
newstop=NormalizeDouble(MathFloor((dlow[ii]-datr[ii]*trailing_bankomat_atr_koef-sp)/tick)*tick,_Digits);
if(dvirtstop>dstop && dvirtstop>0) dstop=dvirtstop;
if((dstop==0 || newstop>dstop) && newstop>m_orders[i].OrderOpenPrice)
{
OrderModify(m_orders[i].OrderTicket,-1,newstop,-1,0,clrNONE);
}
}
break;
}
if(dhigh[ii]>=dsar[ii] &Показано первые 50% кода (символов: 143561)
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.