223 lines
19 KiB
Plaintext
223 lines
19 KiB
Plaintext
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| PositionMT5.mqh |
|
||
|
|
//| Copyright 2016, Vasiliy Sokolov, St-Petersburg, Russia |
|
||
|
|
//| https://www.mql5.com/en/users/c-4 |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
#property copyright "Copyright 2016, Vasiliy Sokolov."
|
||
|
|
#property link "https://www.mql5.com/en/users/c-4"
|
||
|
|
#include <Object.mqh>
|
||
|
|
#include "Logs.mqh"
|
||
|
|
#include "Trailings\Trailing.mqh"
|
||
|
|
#include <Trade\Trade.mqh>
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Active position class for classical strategies |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
class CPosition : public CObject
|
||
|
|
{
|
||
|
|
private:
|
||
|
|
ulong m_id; // Unique position identifier
|
||
|
|
uint m_magic; // Unique ID of the EA the position belongs to.
|
||
|
|
ENUM_POSITION_TYPE m_direction; // Position direction
|
||
|
|
double m_entry_price; // Position entry price
|
||
|
|
string m_symbol; // The symbol the position is open for
|
||
|
|
datetime m_time_open; // Open time
|
||
|
|
string m_entry_comment; // Incoming comment
|
||
|
|
bool m_is_closed; // True if the position has been closed
|
||
|
|
CLog* Log; // Logging
|
||
|
|
CTrade m_trade; // Trading module
|
||
|
|
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;
|
||
|
|
};
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Initialization of the basic properties of a position |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
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);
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Returns position direction. |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
CPosition::~CPosition(void)
|
||
|
|
{
|
||
|
|
if(CheckPointer(Trailing) == POINTER_DYNAMIC)
|
||
|
|
delete Trailing;
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Returns position direction. |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
ENUM_POSITION_TYPE CPosition::Direction(void)
|
||
|
|
{
|
||
|
|
return m_direction;
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Returns the unique ID of the Expert Advisor |
|
||
|
|
//| the position belongs to. |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
uint CPosition::ExpertMagic(void)
|
||
|
|
{
|
||
|
|
return m_magic;
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Returns the unique position identifier. |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
ulong CPosition::ID(void)
|
||
|
|
{
|
||
|
|
return m_id;
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Returns position entry price. |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
double CPosition::EntryPrice(void)
|
||
|
|
{
|
||
|
|
return m_entry_price;
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Returns current position 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);
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Returns incoming comment of the active position. |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
string CPosition::EntryComment(void)
|
||
|
|
{
|
||
|
|
return m_entry_comment;
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Returns the name of the symbol for which there is currently open |
|
||
|
|
//| position |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
string CPosition::Symbol(void)
|
||
|
|
{
|
||
|
|
return m_symbol;
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Returns position open time. |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
datetime CPosition::TimeOpen(void)
|
||
|
|
{
|
||
|
|
return m_time_open;
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Returns an absolute Stop Loss level for the current position. |
|
||
|
|
//| If the Stop Loss level is not set, returns 0.0 |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
double CPosition::StopLossValue(void)
|
||
|
|
{
|
||
|
|
if(!IsActive())
|
||
|
|
return 0.0;
|
||
|
|
return PositionGetDouble(POSITION_SL);
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Sets an absolute stop loss level |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool CPosition::StopLossValue(double sl)
|
||
|
|
{
|
||
|
|
if(!IsActive())
|
||
|
|
return false;
|
||
|
|
return m_trade.PositionModify(m_id, sl, TakeProfitValue());
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Returns an absolute Stop Loss level for the current position. |
|
||
|
|
//| If the Stop Loss level is not set, returns 0.0 |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
double CPosition::TakeProfitValue(void)
|
||
|
|
{
|
||
|
|
if(!IsActive())
|
||
|
|
return 0.0;
|
||
|
|
return PositionGetDouble(POSITION_TP);
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Sets an absolute stop loss level |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool CPosition::TakeProfitValue(double tp)
|
||
|
|
{
|
||
|
|
if(!IsActive())
|
||
|
|
return false;
|
||
|
|
return m_trade.PositionModify(m_id, StopLossValue(), tp);
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Closes the current position by market and sets a closing |
|
||
|
|
//| comment equal to 'comment' |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool CPosition::CloseAtMarket(string comment="")
|
||
|
|
{
|
||
|
|
if(!IsActive())
|
||
|
|
return false;
|
||
|
|
m_trade.PositionModify(m_id, 0.0, 0.0);
|
||
|
|
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);
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Returns current position volume. |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
double CPosition::Volume(void)
|
||
|
|
{
|
||
|
|
if(!IsActive())
|
||
|
|
return 0.0;
|
||
|
|
return PositionGetDouble(POSITION_VOLUME);
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Returns current profit of position in deposit currency. |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
double CPosition::Profit(void)
|
||
|
|
{
|
||
|
|
if(!IsActive())
|
||
|
|
return 0.0;
|
||
|
|
return PositionGetDouble(POSITION_PROFIT);
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Returns true if the position is active. Returns false |
|
||
|
|
//| if otherwise. |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
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"�
|