//+------------------------------------------------------------------+ //| PositionMT5.mqh | //| Copyright 2016, Vasiliy Sokolov, St-Petersburg, Russia | //| https://www.mql5.com/ru/users/c-4 | //+------------------------------------------------------------------+ #property copyright "Copyright 2016, Vasiliy Sokolov." #property link "https://www.mql5.com/ru/users/c-4" #include #include "Logs.mqh" #include "Trailings\Trailing.mqh" #include //+------------------------------------------------------------------+ //| Класс активной позиции, для классических стратегий | //+------------------------------------------------------------------+ class CPosition : public CObject { private: ulong m_id; // Уникальный идентификатор позиции uint m_magic; // Уникальный идентификатор эксперта, к которому принадлежит данная позиция. ENUM_POSITION_TYPE m_direction; // Направление позиции double m_entry_price; // Цена входа в позицию string m_symbol; // Инструмент, по которому открыта позиция datetime m_time_open; // Время открытия string m_entry_comment; // Входящий комментарий bool m_is_closed; // Истина, если позиция была закрыта CLog* Log; // Логирование CTrade m_trade; // Торговый модуль public: CPosition(void); ~CPosition(void); uint ExpertMagic(void); ulong ID(void); ENUM_POSITION_TYPE Direction(void); double EntryPrice(void); double CurrentPrice(void); string EntryComment(void); double Profit(void); double Volume(void); string Symbol(void); datetime TimeOpen(void); bool CloseAtMarket(string comment=""); double StopLossValue(void); bool StopLossValue(double sl); double TakeProfitValue(void); bool TakeProfitValue(double tp); bool IsActive(void); CTrailing* Trailing; CObject* ExpertData; }; //+------------------------------------------------------------------+ //| Инициализация основных свойств позиции | //+------------------------------------------------------------------+ void CPosition::CPosition(void) : m_id(0), m_entry_price(0.0), m_symbol(""), m_time_open(0) { m_id=PositionGetInteger(POSITION_IDENTIFIER); m_magic=(uint)PositionGetInteger(POSITION_MAGIC); m_direction=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); m_entry_price=PositionGetDouble(POSITION_PRICE_OPEN); m_symbol=PositionGetString(POSITION_SYMBOL); m_time_open=(datetime)PositionGetInteger(POSITION_TIME); m_entry_comment=PositionGetString(POSITION_COMMENT); m_trade.SetExpertMagicNumber(m_magic); } //+------------------------------------------------------------------+ //| Возвращает направление позиции. | //+------------------------------------------------------------------+ CPosition::~CPosition(void) { if(CheckPointer(Trailing) == POINTER_DYNAMIC) delete Trailing; } //+------------------------------------------------------------------+ //| Возвращает направление позиции. | //+------------------------------------------------------------------+ ENUM_POSITION_TYPE CPosition::Direction(void) { return m_direction; } //+------------------------------------------------------------------+ //| Возвращает уникальный идентификатор эксперта, которому | //| принадлежит текущая позиция. | //+------------------------------------------------------------------+ uint CPosition::ExpertMagic(void) { return m_magic; } //+------------------------------------------------------------------+ //| Возвращает уникальный идентификатор позиции. | //+------------------------------------------------------------------+ ulong CPosition::ID(void) { return m_id; } //+------------------------------------------------------------------+ //| Возвращает цену входа в позицию. | //+------------------------------------------------------------------+ double CPosition::EntryPrice(void) { return m_entry_price; } //+------------------------------------------------------------------+ //| Возвращает текущую цену позиции. | //+------------------------------------------------------------------+ double CPosition::CurrentPrice(void) { double price = 0.0; int digits = (int)SymbolInfoInteger(m_symbol, SYMBOL_DIGITS); if(Direction() == POSITION_TYPE_BUY) price = SymbolInfoDouble(m_symbol, SYMBOL_BID); else price = SymbolInfoDouble(m_symbol, SYMBOL_ASK); return NormalizeDouble(price, digits); } //+------------------------------------------------------------------+ //| Возвращает входящий комментарий активной позиции. | //+------------------------------------------------------------------+ string CPosition::EntryComment(void) { return m_entry_comment; } //+------------------------------------------------------------------+ //| Возвращает название инструмента, по которому открыта текущая | //| позиция. | //+------------------------------------------------------------------+ string CPosition::Symbol(void) { return m_symbol; } //+------------------------------------------------------------------+ //| Возвращает время открытия позиции. | //+------------------------------------------------------------------+ datetime CPosition::TimeOpen(void) { return m_time_open; } //+------------------------------------------------------------------+ //| Возвращает абсолютный уровень стоп-лосса для текущей позиции. | //| Если уровень стоп-лосса не установлен, возвращает 0.0 | //+------------------------------------------------------------------+ double CPosition::StopLossValue(void) { if(!IsActive()) return 0.0; return PositionGetDouble(POSITION_SL); } //+------------------------------------------------------------------+ //| Устанавливает абсолютный уровень стоп-лосса | //+------------------------------------------------------------------+ bool CPosition::StopLossValue(double sl) { if(!IsActive()) return false; return m_trade.PositionModify(m_id, sl, TakeProfitValue()); } //+------------------------------------------------------------------+ //| Возвращает абсолютный уровень стоп-лосса для текущей позиции. | //| Если уровень стоп-лосса не установлен, возвращает 0.0 | //+------------------------------------------------------------------+ double CPosition::TakeProfitValue(void) { if(!IsActive()) return 0.0; return PositionGetDouble(POSITION_TP); } //+------------------------------------------------------------------+ //| Устанавливает абсолютный уровень стоп-лосса | //+------------------------------------------------------------------+ bool CPosition::TakeProfitValue(double tp) { if(!IsActive()) return false; return m_trade.PositionModify(m_id, StopLossValue(), tp); } //+------------------------------------------------------------------+ //| Закрывает текущую позицию по рынку, устанавливая закрывающий | //| комментарий равный comment | //+------------------------------------------------------------------+ bool CPosition::CloseAtMarket(string comment="") { if(!IsActive()) return false; ENUM_ACCOUNT_MARGIN_MODE mode=(ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE); if(mode != ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) return m_trade.PositionClose(m_symbol); return m_trade.PositionClose(m_id); } //+------------------------------------------------------------------+ //| Возвращает текущий объем позиции. | //+------------------------------------------------------------------+ double CPosition::Volume(void) { if(!IsActive()) return 0.0; return PositionGetDouble(POSITION_VOLUME); } //+------------------------------------------------------------------+ //| Возвращает текущую прибыль позиции в валюте депозита. | //+------------------------------------------------------------------+ double CPosition::Profit(void) { if(!IsActive()) return 0.0; return PositionGetDouble(POSITION_PROFIT); } //+------------------------------------------------------------------+ //| Возвращает истину, если позиция активна. Возвращает ложь | //| в противном случае. | //+------------------------------------------------------------------+ bool CPosition::IsActive(void) { ENUM_ACCOUNT_MARGIN_MODE mode=(ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE); if(mode!=ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) return PositionSelect(m_symbol); else return PositionSelectByTicket(m_id); } //+------------------------------------------------------------------+ //#include "Trailing.mqh"