Article-15026-MQL5-Trade-Hi.../Deal.mqh
2026-03-23 12:53:11 +07:00

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();
}
//+------------------------------------------------------------------+