533 lines
65 KiB
MQL5
533 lines
65 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| Deal.mqh |
|
|
//| Copyright 2024, MetaQuotes Ltd. |
|
|
//| https://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2024, MetaQuotes Ltd."
|
|
#property link "https://www.mql5.com"
|
|
#property version "1.00"
|
|
|
|
#include <Object.mqh>
|
|
#include <Canvas\Canvas.mqh>
|
|
|
|
enum ENUM_DEAL_SORT_MODE
|
|
{
|
|
SORT_MODE_DEAL_TICKET = 0, // Режим сравнения/сортировки по тикету сделки
|
|
SORT_MODE_DEAL_ORDER, // Режим сравнения/сортировки по ордеру, на основание которого выполнена сделка
|
|
SORT_MODE_DEAL_TIME, // Режим сравнения/сортировки по времени совершения сделки
|
|
SORT_MODE_DEAL_TIME_MSC, // Режим сравнения/сортировки по времени совершения сделки в миллисекундах
|
|
SORT_MODE_DEAL_TYPE, // Режим сравнения/сортировки по типу сделки
|
|
SORT_MODE_DEAL_ENTRY, // Режим сравнения/сортировки по направлению сделки
|
|
SORT_MODE_DEAL_MAGIC, // Режим сравнения/сортировки по Magic number сделки
|
|
SORT_MODE_DEAL_REASON, // Режим сравнения/сортировки по причине или источнику проведения сделки
|
|
SORT_MODE_DEAL_POSITION_ID, // Режим сравнения/сортировки по идентификатору позиции
|
|
SORT_MODE_DEAL_VOLUME, // Режим сравнения/сортировки по объему сделки
|
|
SORT_MODE_DEAL_PRICE, // Режим сравнения/сортировки по цене сделки
|
|
SORT_MODE_DEAL_COMMISSION, // Режим сравнения/сортировки по комиссии
|
|
SORT_MODE_DEAL_SWAP, // Режим сравнения/сортировки по накопленному свопу при закрытии
|
|
SORT_MODE_DEAL_PROFIT, // Режим сравнения/сортировки по финансовому результату сделки
|
|
SORT_MODE_DEAL_FEE, // Режим сравнения/сортировки по оплате за проведение сделки
|
|
SORT_MODE_DEAL_SL, // Режим сравнения/сортировки по уровню Stop Loss
|
|
SORT_MODE_DEAL_TP, // Режим сравнения/сортировки по уровню Take Profit
|
|
SORT_MODE_DEAL_SYMBOL, // Режим сравнения/сортировки по имени символа, по которому произведена сделка
|
|
SORT_MODE_DEAL_COMMENT, // Режим сравнения/сортировки по комментарию к сделке
|
|
SORT_MODE_DEAL_EXTERNAL_ID, // Режим сравнения/сортировки по идентификатору сделки во внешней торговой системе
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| Класс сделки |
|
|
//+------------------------------------------------------------------+
|
|
class CDeal : public CObject
|
|
{
|
|
private:
|
|
MqlTick m_tick; // Структура тика сделки
|
|
//--- Объект CCanvas
|
|
CCanvas m_canvas; // Канвас
|
|
long m_chart_id; // Идентификатор графика
|
|
int m_width; // Ширина канваса
|
|
int m_height; // Высота канваса
|
|
string m_name; // Имя графического объекта
|
|
|
|
//--- Создаёт объект-метку на графике
|
|
bool CreateLabelObj(void);
|
|
|
|
//--- Рисует на холсте (1) маску, (2) стрелку Buy
|
|
void DrawArrowMaskBuy(const int shift_x, const int shift_y);
|
|
void DrawArrowBuy(const int shift_x, const int shift_y);
|
|
|
|
//--- Рисует на холсте (1) маску, (2) стрелку Sell
|
|
void DrawArrowMaskSell(const int shift_x, const int shift_y);
|
|
void DrawArrowSell(const int shift_x, const int shift_y);
|
|
|
|
//--- Рисует внешний вид метки
|
|
void DrawLabelView(void);
|
|
|
|
//--- Получает (1) тик сделки, (2) спред минутного бара сделки
|
|
bool GetDealTick(const int amount=20);
|
|
int GetSpreadM1(void);
|
|
|
|
//--- Возвращает время с миллисекундами
|
|
string TimeMscToString(const long time_msc,int flags=TIME_DATE|TIME_MINUTES|TIME_SECONDS) const;
|
|
|
|
protected:
|
|
//--- Целочисленные свойства
|
|
long m_ticket; // Тикет сделки. Уникальное число, которое присваивается каждой сделке
|
|
long m_order; // Ордер, на основание которого выполнена сделка
|
|
datetime m_time; // Время совершения сделки
|
|
long m_time_msc; // Время совершения сделки в миллисекундах с 01.01.1970
|
|
ENUM_DEAL_TYPE m_type; // Тип сделки
|
|
ENUM_DEAL_ENTRY m_entry; // Направление сделки – вход в рынок, выход из рынка или разворот
|
|
long m_magic; // Magic number для сделки (смотри ORDER_MAGIC)
|
|
ENUM_DEAL_REASON m_reason; // Причина или источник проведения сделки
|
|
long m_position_id; // Идентификатор позиции, в открытии, изменении или закрытии которой участвовала эта сделка
|
|
|
|
//--- Вещественные свойства
|
|
double m_volume; // Объем сделки
|
|
double m_price; // Цена сделки
|
|
double m_commission; // Комиссия по сделке
|
|
double m_swap; // Накопленный своп при закрытии
|
|
double m_profit; // Финансовый результат сделки
|
|
double m_fee; // Оплата за проведение сделки, начисляется сразу после совершения сделки
|
|
double m_sl; // Уровень Stop Loss
|
|
double m_tp; // Уровень Take Profit
|
|
|
|
//--- Строковые свойства
|
|
string m_symbol; // Имя символа, по которому произведена сделка
|
|
string m_comment; // Комментарий к сделке
|
|
string m_external_id; // Идентификатор сделки во внешней торговой системе (на бирже)
|
|
|
|
//--- Дополнительные свойства
|
|
int m_digits; // Digits символа
|
|
double m_point; // Point символа
|
|
double m_bid; // Bid при совершении сделки
|
|
double m_ask; // Ask при совершении сделки
|
|
int m_spread; // Spread при совершении сделки
|
|
color m_color_arrow; // Цвет значка сделки
|
|
|
|
//--- Рисует стрелку, соответствующую типу сделки. Может быть переопределён в наследуемых классах
|
|
virtual void DrawArrow(void);
|
|
|
|
public:
|
|
//--- Установка свойств
|
|
//--- Целочисленные свойства
|
|
void SetTicket(const long ticket) { this.m_ticket=ticket; } // Тикет
|
|
void SetOrder(const long order) { this.m_order=order; } // Ордер
|
|
void SetTime(const datetime time) { this.m_time=time; } // Время
|
|
void SetTimeMsc(const long value) { this.m_time_msc=value; } // Время в миллисекундах
|
|
void SetTypeDeal(const ENUM_DEAL_TYPE type) { this.m_type=type; } // Тип
|
|
void SetEntry(const ENUM_DEAL_ENTRY entry) { this.m_entry=entry; } // Направление
|
|
void SetMagic(const long magic) { this.m_magic=magic; } // Magic number
|
|
void SetReason(const ENUM_DEAL_REASON reason) { this.m_reason=reason; } // Причина или источник проведения сделки
|
|
void SetPositionID(const long id) { this.m_position_id=id; } // Идентификатор позиции
|
|
|
|
//--- Вещественные свойства
|
|
void SetVolume(const double volume) { this.m_volume=volume; } // Объем
|
|
void SetPrice(const double price) { this.m_price=price; } // Цена
|
|
void SetCommission(const double value) { this.m_commission=value; } // Комиссия
|
|
void SetSwap(const double value) { this.m_swap=value; } // Накопленный своп при закрытии
|
|
void SetProfit(const double value) { this.m_profit=value; } // Финансовый результат
|
|
void SetFee(const double value) { this.m_fee=value; } // Оплата за проведение сделки
|
|
void SetSL(const double value) { this.m_sl=value; } // Уровень Stop Loss
|
|
void SetTP(const double value) { this.m_tp=value; } // Уровень Take Profit
|
|
|
|
//--- Строковые свойства
|
|
void SetSymbol(const string symbol) { this.m_symbol=symbol; } // Имя символа
|
|
void SetComment(const string comment) { this.m_comment=comment; } // Комментарий
|
|
void SetExternalID(const string ext_id) { this.m_external_id=ext_id; } // Идентификатор сделки во внешней торговой системе
|
|
|
|
//--- Получение свойств
|
|
//--- Целочисленные свойства
|
|
long Ticket(void) const { return(this.m_ticket); } // Тикет
|
|
long Order(void) const { return(this.m_order); } // Ордер
|
|
datetime Time(void) const { return(this.m_time); } // Время
|
|
long TimeMsc(void) const { return(this.m_time_msc); } // Время в миллисекундах
|
|
ENUM_DEAL_TYPE TypeDeal(void) const { return(this.m_type); } // Тип
|
|
ENUM_DEAL_ENTRY Entry(void) const { return(this.m_entry); } // Направление
|
|
long Magic(void) const { return(this.m_magic); } // Magic number
|
|
ENUM_DEAL_REASON Reason(void) const { return(this.m_reason); } // Причина или источник проведения сделки
|
|
long PositionID(void) const { return(this.m_position_id); } // Идентификатор позиции
|
|
|
|
//--- Вещественные свойства
|
|
double Volume(void) const { return(this.m_volume); } // Объем
|
|
double Price(void) const { return(this.m_price); } // Цена
|
|
double Commission(void) const { return(this.m_commission); } // Комиссия
|
|
double Swap(void) const { return(this.m_swap); } // Накопленный своп при закрытии
|
|
double Profit(void) const { return(this.m_profit); } // Финансовый результат
|
|
double Fee(void) const { return(this.m_fee); } // Оплата за проведение сделки
|
|
double SL(void) const { return(this.m_sl); } // Уровень Stop Loss
|
|
double TP(void) const { return(this.m_tp); } // Уровень Take Profit
|
|
|
|
double Bid(void) const { return(this.m_bid); } // Bid при совершении сделки
|
|
double Ask(void) const { return(this.m_ask); } // Ask при совершении сделки
|
|
int Spread(void) const { return(this.m_spread); } // Spread при совершении сделки
|
|
|
|
//--- Строковые свойства
|
|
string Symbol(void) const { return(this.m_symbol); } // Имя символа
|
|
string Comment(void) const { return(this.m_comment); } // Комментарий
|
|
string ExternalID(void) const { return(this.m_external_id); } // Идентификатор сделки во внешней торговой системе
|
|
|
|
//--- Устанавливает цвет значка сделки
|
|
void SetColorArrow(const color clr);
|
|
|
|
//--- (1) Скрывает, (2) отображает значок сделки на графике
|
|
void HideArrow(const bool chart_redraw=false);
|
|
void ShowArrow(const bool chart_redraw=false);
|
|
|
|
//--- Возвращает описание (1) типа сделки, (2) способа изменения позиции, (3) причины проведения сделки
|
|
string TypeDescription(void) const;
|
|
string EntryDescription(void) const;
|
|
string ReasonDescription(void) const;
|
|
|
|
//--- Возвращает (1) краткое описание, (2) текст всплывающего сообщения сделки
|
|
string Description(void);
|
|
virtual string Tooltip(void);
|
|
|
|
//--- Распечатывает в журнал свойства сделки
|
|
void Print(void);
|
|
|
|
//--- Сравнивает два объекта между собой по указанному в mode свойству
|
|
virtual int Compare(const CObject *node, const int mode=0) const;
|
|
|
|
//--- Конструкторы/деструктор
|
|
CDeal(void) { this.m_ticket=0; }
|
|
CDeal(const ulong ticket);
|
|
~CDeal();
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| Конструктор |
|
|
//+------------------------------------------------------------------+
|
|
CDeal::CDeal(const ulong ticket)
|
|
{
|
|
//--- Сохранение свойств
|
|
//--- Целочисленные свойства
|
|
this.m_ticket = (long)ticket; // Тикет сделки
|
|
this.m_order = ::HistoryDealGetInteger(ticket, DEAL_ORDER); // Ордер
|
|
this.m_time = (datetime)::HistoryDealGetInteger(ticket, DEAL_TIME); // Время совершения сделки
|
|
this.m_time_msc = ::HistoryDealGetInteger(ticket, DEAL_TIME_MSC); // Время совершения сделки в миллисекундах
|
|
this.m_type = (ENUM_DEAL_TYPE)::HistoryDealGetInteger(ticket, DEAL_TYPE); // Тип
|
|
this.m_entry = (ENUM_DEAL_ENTRY)::HistoryDealGetInteger(ticket, DEAL_ENTRY); // Направление
|
|
this.m_magic = ::HistoryDealGetInteger(ticket, DEAL_MAGIC); // Magic number
|
|
this.m_reason = (ENUM_DEAL_REASON)::HistoryDealGetInteger(ticket, DEAL_REASON); // Причина или источник проведения сделки
|
|
this.m_position_id= ::HistoryDealGetInteger(ticket, DEAL_POSITION_ID); // Идентификатор позиции
|
|
|
|
//--- Вещественные свойства
|
|
this.m_volume = ::HistoryDealGetDouble(ticket, DEAL_VOLUME); // Объем
|
|
this.m_price = ::HistoryDealGetDouble(ticket, DEAL_PRICE); // Цена
|
|
this.m_commission = ::HistoryDealGetDouble(ticket, DEAL_COMMISSION); // Комиссия
|
|
this.m_swap = ::HistoryDealGetDouble(ticket, DEAL_SWAP); // Накопленный своп при закрытии
|
|
this.m_profit = ::HistoryDealGetDouble(ticket, DEAL_PROFIT); // Финансовый результат
|
|
this.m_fee = ::HistoryDealGetDouble(ticket, DEAL_FEE); // Оплата за проведение сделки
|
|
this.m_sl = ::HistoryDealGetDouble(ticket, DEAL_SL); // Уровень Stop Loss
|
|
this.m_tp = ::HistoryDealGetDouble(ticket, DEAL_TP); // Уровень Take Profit
|
|
|
|
//--- Строковые свойства
|
|
this.m_symbol = ::HistoryDealGetString(ticket, DEAL_SYMBOL); // Имя символа
|
|
this.m_comment = ::HistoryDealGetString(ticket, DEAL_COMMENT); // Комментарий
|
|
this.m_external_id= ::HistoryDealGetString(ticket, DEAL_EXTERNAL_ID); // Идентификатор сделки во внешней торговой системе
|
|
|
|
//--- Параметры отображения графики
|
|
this.m_chart_id = ::ChartID();
|
|
this.m_digits = (int)::SymbolInfoInteger(this.m_symbol, SYMBOL_DIGITS);
|
|
this.m_point = ::SymbolInfoDouble(this.m_symbol, SYMBOL_POINT);
|
|
this.m_width = 19;
|
|
this.m_height = 19;
|
|
this.m_name = "Deal#"+(string)this.m_ticket;
|
|
this.m_color_arrow= (this.TypeDeal()==DEAL_TYPE_BUY ? C'3,95,172' : this.TypeDeal()==DEAL_TYPE_SELL ? C'225,68,29' : C'180,180,180');
|
|
|
|
//--- Параметры для расчёта спреда
|
|
this.m_spread = 0;
|
|
this.m_bid = 0;
|
|
this.m_ask = 0;
|
|
|
|
//--- Создаём графическую метку
|
|
this.CreateLabelObj();
|
|
|
|
//--- Если исторический тик и значение Point символа удалось получить
|
|
if(this.GetDealTick() && this.m_point!=0)
|
|
{
|
|
//--- запишем значения цен Bid и Ask и рассчитаем и сохраним значение спреда
|
|
this.m_bid=this.m_tick.bid;
|
|
this.m_ask=this.m_tick.ask;
|
|
this.m_spread=int((this.m_ask-this.m_bid)/this.m_point);
|
|
}
|
|
//--- Если исторический тик получить не удалось, возьмём значение спреда минутного бара, на котором была сделка
|
|
else
|
|
this.m_spread=this.GetSpreadM1();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Деструктор |
|
|
//+------------------------------------------------------------------+
|
|
CDeal::~CDeal()
|
|
{
|
|
if(::UninitializeReason()!=REASON_CHARTCHANGE)
|
|
this.m_canvas.Destroy();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Сравнивает два объекта между собой по указанному свойству |
|
|
//+------------------------------------------------------------------+
|
|
int CDeal::Compare(const CObject *node,const int mode=0) const
|
|
{
|
|
const CDeal * obj = node;
|
|
switch(mode)
|
|
{
|
|
case SORT_MODE_DEAL_TICKET : return(this.Ticket() > obj.Ticket() ? 1 : this.Ticket() < obj.Ticket() ? -1 : 0);
|
|
case SORT_MODE_DEAL_ORDER : return(this.Order() > obj.Order() ? 1 : this.Order() < obj.Order() ? -1 : 0);
|
|
case SORT_MODE_DEAL_TIME : return(this.Time() > obj.Time() ? 1 : this.Time() < obj.Time() ? -1 : 0);
|
|
case SORT_MODE_DEAL_TIME_MSC : return(this.TimeMsc() > obj.TimeMsc() ? 1 : this.TimeMsc() < obj.TimeMsc() ? -1 : 0);
|
|
case SORT_MODE_DEAL_TYPE : return(this.TypeDeal() > obj.TypeDeal() ? 1 : this.TypeDeal() < obj.TypeDeal() ? -1 : 0);
|
|
case SORT_MODE_DEAL_ENTRY : return(this.Entry() > obj.Entry() ? 1 : this.Entry() < obj.Entry() ? -1 : 0);
|
|
case SORT_MODE_DEAL_MAGIC : return(this.Magic() > obj.Magic() ? 1 : this.Magic() < obj.Magic() ? -1 : 0);
|
|
case SORT_MODE_DEAL_REASON : return(this.Reason() > obj.Reason() ? 1 : this.Reason() < obj.Reason() ? -1 : 0);
|
|
case SORT_MODE_DEAL_POSITION_ID : return(this.PositionID() > obj.PositionID() ? 1 : this.PositionID() < obj.PositionID() ? -1 : 0);
|
|
case SORT_MODE_DEAL_VOLUME : return(this.Volume() > obj.Volume() ? 1 : this.Volume() < obj.Volume() ? -1 : 0);
|
|
case SORT_MODE_DEAL_PRICE : return(this.Price() > obj.Price() ? 1 : this.Price() < obj.Price() ? -1 : 0);
|
|
case SORT_MODE_DEAL_COMMISSION : return(this.Commission() > obj.Commission() ? 1 : this.Commission() < obj.Commission() ? -1 : 0);
|
|
case SORT_MODE_DEAL_SWAP : return(this.Swap() > obj.Swap() ? 1 : this.Swap() < obj.Swap() ? -1 : 0);
|
|
case SORT_MODE_DEAL_PROFIT : return(this.Profit() > obj.Profit() ? 1 : this.Profit() < obj.Profit() ? -1 : 0);
|
|
case SORT_MODE_DEAL_FEE : return(this.Fee() > obj.Fee() ? 1 : this.Fee() < obj.Fee() ? -1 : 0);
|
|
case SORT_MODE_DEAL_SL : return(this.SL() > obj.SL() ? 1 : this.SL() < obj.SL() ? -1 : 0);
|
|
case SORT_MODE_DEAL_TP : return(this.TP() > obj.TP() ? 1 : this.TP() < obj.TP() ? -1 : 0);
|
|
case SORT_MODE_DEAL_SYMBOL : return(this.Symbol() > obj.Symbol() ? 1 : this.Symbol() < obj.Symbol() ? -1 : 0);
|
|
case SORT_MODE_DEAL_COMMENT : return(this.Comment() > obj.Comment() ? 1 : this.Comment() < obj.Comment() ? -1 : 0);
|
|
case SORT_MODE_DEAL_EXTERNAL_ID : return(this.ExternalID() > obj.ExternalID() ? 1 : this.ExternalID() < obj.ExternalID() ? -1 : 0);
|
|
default : return(-1);
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает описание типа сделки |
|
|
//+------------------------------------------------------------------+
|
|
string CDeal::TypeDescription(void) const
|
|
{
|
|
switch(this.m_type)
|
|
{
|
|
case DEAL_TYPE_BUY : return "Buy";
|
|
case DEAL_TYPE_SELL : return "Sell";
|
|
case DEAL_TYPE_BALANCE : return "Balance";
|
|
case DEAL_TYPE_CREDIT : return "Credit";
|
|
case DEAL_TYPE_CHARGE : return "Additional charge";
|
|
case DEAL_TYPE_CORRECTION : return "Correction";
|
|
case DEAL_TYPE_BONUS : return "Bonus";
|
|
case DEAL_TYPE_COMMISSION : return "Additional commission";
|
|
case DEAL_TYPE_COMMISSION_DAILY : return "Daily commission";
|
|
case DEAL_TYPE_COMMISSION_MONTHLY : return "Monthly commission";
|
|
case DEAL_TYPE_COMMISSION_AGENT_DAILY : return "Daily agent commission";
|
|
case DEAL_TYPE_COMMISSION_AGENT_MONTHLY: return "Monthly agent commission";
|
|
case DEAL_TYPE_INTEREST : return "Interest rate";
|
|
case DEAL_TYPE_BUY_CANCELED : return "Canceled buy deal";
|
|
case DEAL_TYPE_SELL_CANCELED : return "Canceled sell deal";
|
|
case DEAL_DIVIDEND : return "Dividend operations";
|
|
case DEAL_DIVIDEND_FRANKED : return "Franked (non-taxable) dividend operations";
|
|
case DEAL_TAX : return "Tax charges";
|
|
default : return "Unknown: "+(string)this.m_type;
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает описание способа изменения позиции |
|
|
//+------------------------------------------------------------------+
|
|
string CDeal::EntryDescription(void) const
|
|
{
|
|
switch(this.m_entry)
|
|
{
|
|
case DEAL_ENTRY_IN : return "Entry In";
|
|
case DEAL_ENTRY_OUT : return "Entry Out";
|
|
case DEAL_ENTRY_INOUT : return "Reverse";
|
|
case DEAL_ENTRY_OUT_BY : return "Close a position by an opposite one";
|
|
default : return "Unknown: "+(string)this.m_entry;
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает описание причины проведения сделки |
|
|
//+------------------------------------------------------------------+
|
|
string CDeal::ReasonDescription(void) const
|
|
{
|
|
switch(this.m_reason)
|
|
{
|
|
case DEAL_REASON_CLIENT : return "Terminal";
|
|
case DEAL_REASON_MOBILE : return "Mobile";
|
|
case DEAL_REASON_WEB : return "Web";
|
|
case DEAL_REASON_EXPERT : return "EA";
|
|
case DEAL_REASON_SL : return "SL";
|
|
case DEAL_REASON_TP : return "TP";
|
|
case DEAL_REASON_SO : return "SO";
|
|
case DEAL_REASON_ROLLOVER : return "Rollover";
|
|
case DEAL_REASON_VMARGIN : return "Var. Margin";
|
|
case DEAL_REASON_SPLIT : return "Split";
|
|
case DEAL_REASON_CORPORATE_ACTION: return "Corp. Action";
|
|
default : return "Unknown reason "+(string)this.m_reason;
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает описание сделки |
|
|
//+------------------------------------------------------------------+
|
|
string CDeal::Description(void)
|
|
{
|
|
return(::StringFormat("Deal: %-9s %.2f %-4s #%I64d at %s", this.EntryDescription(), this.Volume(), this.TypeDescription(), this.Ticket(), this.TimeMscToString(this.TimeMsc())));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает текст всплывающего сообщения сделки |
|
|
//+------------------------------------------------------------------+
|
|
string CDeal::Tooltip(void)
|
|
{
|
|
return(::StringFormat("Position ID #%I64d %s:\nDeal #%I64d %.2f %s %s\n%s [%.*f]\nProfit: %.2f, SL: %.*f, TP: %.*f",
|
|
this.PositionID(), this.Symbol(), this.Ticket(), this.Volume(), this.TypeDescription(),
|
|
this.EntryDescription(), this.TimeMscToString(this.TimeMsc()), this.m_digits, this.Price(),
|
|
this.Profit(), this.m_digits, this.SL(), this.m_digits, this.TP()));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Распечатывает в журнал свойства сделки |
|
|
//+------------------------------------------------------------------+
|
|
void CDeal::Print(void)
|
|
{
|
|
::PrintFormat(" %s", this.Description());
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает время с миллисекундами |
|
|
//+------------------------------------------------------------------+
|
|
string CDeal::TimeMscToString(const long time_msc, int flags=TIME_DATE|TIME_MINUTES|TIME_SECONDS) const
|
|
{
|
|
return(::TimeToString(time_msc/1000, flags) + "." + ::IntegerToString(time_msc %1000, 3, '0'));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Получает тик сделки |
|
|
//| https://www.mql5.com/ru/forum/42122/page47#comment_37205238 |
|
|
//+------------------------------------------------------------------+
|
|
bool CDeal::GetDealTick(const int amount=20)
|
|
{
|
|
MqlTick ticks[]; // Сюда будем получать тики
|
|
int attempts = amount; // Количество попыток получения тиков
|
|
int offset = 500; // Начальное смещение времени для попытки
|
|
int copied = 0; // Количество скопированных тиков
|
|
|
|
//--- До тех пор, пока не скопирован тик и не закончилось количество попыток копирования
|
|
//--- пытаемся получить тик, на каждой итерации увеличивая вдвое начальное смещение времени (расширяем диапазон времени "from_msc")
|
|
while(!::IsStopped() && (copied<=0) && (attempts--)!=0)
|
|
copied = ::CopyTicksRange(this.m_symbol, ticks, COPY_TICKS_INFO, this.m_time_msc-(offset <<=1), this.m_time_msc);
|
|
|
|
//--- Если тик скопировать удалось (он последний в массиве тиков) - записываем его в переменную m_tick
|
|
if(copied>0)
|
|
this.m_tick=ticks[copied-1];
|
|
|
|
//--- Возвращаем флаг того, что тик скопирован
|
|
return(copied>0);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Получает спред минутного бара сделки |
|
|
//+------------------------------------------------------------------+
|
|
int CDeal::GetSpreadM1(void)
|
|
{
|
|
int array[1]={};
|
|
int bar=::iBarShift(this.m_symbol, PERIOD_M1, this.Time());
|
|
if(bar==WRONG_VALUE)
|
|
return 0;
|
|
return(::CopySpread(this.m_symbol, PERIOD_M1, bar, 1, array)==1 ? array[0] : 0);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Создаёт объект-метку на графике |
|
|
//+------------------------------------------------------------------+
|
|
bool CDeal::CreateLabelObj(void)
|
|
{
|
|
//--- Создаём графический ресурс с привязанным к нему объектом Bitmap
|
|
::ResetLastError();
|
|
if(!this.m_canvas.CreateBitmap(this.m_name, this.m_time, this.m_price, this.m_width, this.m_height, COLOR_FORMAT_ARGB_NORMALIZE))
|
|
{
|
|
::PrintFormat("%s: When creating a graphic object, error %d occurred in the CreateBitmap method of the CCanvas class",__FUNCTION__, ::GetLastError());
|
|
return false;
|
|
}
|
|
//--- При успешном создании графического ресурса устанавливаем для объекта Bitmap, точку привязки, цену, время и текст всплывающей подсказки
|
|
::ObjectSetInteger(this.m_chart_id, this.m_name, OBJPROP_ANCHOR, ANCHOR_CENTER);
|
|
::ObjectSetInteger(this.m_chart_id, this.m_name, OBJPROP_TIME, this.Time());
|
|
::ObjectSetDouble(this.m_chart_id, this.m_name, OBJPROP_PRICE, this.Price());
|
|
::ObjectSetString(this.m_chart_id, this.m_name, OBJPROP_TOOLTIP, this.Tooltip());
|
|
|
|
//--- Скрываем созданный объект с графика и рисуем на нём его внешний вид
|
|
this.HideArrow();
|
|
this.DrawLabelView();
|
|
return true;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Рисует внешний вид объекта-метки |
|
|
//+------------------------------------------------------------------+
|
|
void CDeal::DrawLabelView(void)
|
|
{
|
|
this.m_canvas.Erase(0x00FFFFFF);
|
|
this.DrawArrow();
|
|
this.m_canvas.Update(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Рисует стрелку, соответствующую типу сделки |
|
|
//+------------------------------------------------------------------+
|
|
void CDeal::DrawArrow(void)
|
|
{
|
|
switch(this.TypeDeal())
|
|
{
|
|
case DEAL_TYPE_BUY : this.DrawArrowBuy(5, 10); break;
|
|
case DEAL_TYPE_SELL : this.DrawArrowSell(5, 0); break;
|
|
default : break;
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Рисует на холсте маску стрелки Buy |
|
|
//+------------------------------------------------------------------+
|
|
void CDeal::DrawArrowMaskBuy(const int shift_x, const int shift_y)
|
|
{
|
|
int x[]={4+shift_x, 8+shift_x, 8+shift_x, 6+shift_x, 6+shift_x, 2+shift_x, 2+shift_x, 0+shift_x, 0+shift_x, 4+shift_x};
|
|
int y[]={0+shift_y, 4+shift_y, 5+shift_y, 5+shift_y, 7+shift_y, 7+shift_y, 5+shift_y, 5+shift_y, 4+shift_y, 0+shift_y};
|
|
this.m_canvas.Polygon(x, y, ::ColorToARGB(clrWhite, 220));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Рисует на холсте стрелку Buy |
|
|
//+------------------------------------------------------------------+
|
|
void CDeal::DrawArrowBuy(const int shift_x, const int shift_y)
|
|
{
|
|
this.DrawArrowMaskBuy(shift_x, shift_y);
|
|
int x[]={4+shift_x, 7+shift_x, 5+shift_x, 5+shift_x, 3+shift_x, 3+shift_x, 1+shift_x, 4+shift_x};
|
|
int y[]={1+shift_y, 4+shift_y, 4+shift_y, 6+shift_y, 6+shift_y, 4+shift_y, 4+shift_y, 1+shift_y};
|
|
this.m_canvas.Polygon(x, y, ::ColorToARGB(this.m_color_arrow));
|
|
this.m_canvas.Fill(4+shift_x, 4+shift_y, ::ColorToARGB(this.m_color_arrow));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Рисует на холсте маску стрелки Sell |
|
|
//+------------------------------------------------------------------+
|
|
void CDeal::DrawArrowMaskSell(const int shift_x, const int shift_y)
|
|
{
|
|
int x[]={4+shift_x, 0+shift_x, 0+shift_x, 2+shift_x, 2+shift_x, 6+shift_x, 6+shift_x, 8+shift_x, 8+shift_x, 4+shift_x};
|
|
int y[]={8+shift_y, 4+shift_y, 3+shift_y, 3+shift_y, 1+shift_y, 1+shift_y, 3+shift_y, 3+shift_y, 4+shift_y, 8+shift_y};
|
|
this.m_canvas.Polygon(x, y, ::ColorToARGB(clrWhite, 220));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Рисует на холсте стрелку Sell |
|
|
//+------------------------------------------------------------------+
|
|
void CDeal::DrawArrowSell(const int shift_x, const int shift_y)
|
|
{
|
|
this.DrawArrowMaskSell(shift_x, shift_y);
|
|
int x[]={4+shift_x, 1+shift_x, 3+shift_x, 3+shift_x, 5+shift_x, 5+shift_x, 7+shift_x, 4+shift_x};
|
|
int y[]={7+shift_y, 4+shift_y, 4+shift_y, 2+shift_y, 2+shift_y, 4+shift_y, 4+shift_y, 7+shift_y};
|
|
this.m_canvas.Polygon(x, y, ::ColorToARGB(this.m_color_arrow));
|
|
this.m_canvas.Fill(4+shift_x, 4+shift_y, ::ColorToARGB(this.m_color_arrow));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Скрывает значок сделки на графике |
|
|
//+------------------------------------------------------------------+
|
|
void CDeal::HideArrow(const bool chart_redraw=false)
|
|
{
|
|
::ObjectSetInteger(this.m_chart_id, this.m_name, OBJPROP_TIMEFRAMES, OBJ_NO_PERIODS);
|
|
if(chart_redraw)
|
|
::ChartRedraw(this.m_chart_id);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Отображает значок сделки на графике |
|
|
//+------------------------------------------------------------------+
|
|
void CDeal::ShowArrow(const bool chart_redraw=false)
|
|
{
|
|
::ObjectSetInteger(this.m_chart_id, this.m_name, OBJPROP_TIMEFRAMES, OBJ_ALL_PERIODS);
|
|
if(chart_redraw)
|
|
::ChartRedraw(this.m_chart_id);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Устанавливает цвет значка сделки |
|
|
//+------------------------------------------------------------------+
|
|
void CDeal::SetColorArrow(const color clr)
|
|
{
|
|
this.m_color_arrow=clr;
|
|
this.DrawLabelView();
|
|
}
|
|
//+------------------------------------------------------------------+
|