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