394 lines
16 KiB
MQL5
394 lines
16 KiB
MQL5
|
//+------------------------------------------------------------------+
|
||
|
//| PositionInfo.mqh |
|
||
|
//| Copyright 2009-2020, MetaQuotes Software Corp. |
|
||
|
//| http://www.mql5.com |
|
||
|
//| Copyright 2022, Yuriy Bykov |
|
||
|
//| https://www.mql5.com/ru/code/38861 |
|
||
|
//| https://www.mql5.com/en/code/39161 |
|
||
|
//+------------------------------------------------------------------+
|
||
|
#property copyright "Copyright 2022, Yuriy Bykov"
|
||
|
#property link "https://www.mql5.com/ru/users/antekov"
|
||
|
#property version "1.00"
|
||
|
#property strict
|
||
|
|
||
|
#ifdef __MQL4__
|
||
|
|
||
|
enum ENUM_POSITION_TYPE {
|
||
|
POSITION_TYPE_BUY,
|
||
|
POSITION_TYPE_SELL,
|
||
|
};
|
||
|
|
||
|
enum ENUM_ACCOUNT_MARGIN_MODE {
|
||
|
ACCOUNT_MARGIN_MODE_RETAIL_NETTING,
|
||
|
ACCOUNT_MARGIN_MODE_EXCHANGE,
|
||
|
ACCOUNT_MARGIN_MODE_RETAIL_HEDGING
|
||
|
};
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| |
|
||
|
//+------------------------------------------------------------------+
|
||
|
int PositionsTotal() {
|
||
|
return OrdersTotal();
|
||
|
}
|
||
|
|
||
|
|
||
|
#include <Object.mqh>
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Class CPositionInfo. |
|
||
|
//| Appointment: Class for access to position info. |
|
||
|
//| Derives from class CObject. |
|
||
|
//+------------------------------------------------------------------+
|
||
|
class CPositionInfo : public CObject {
|
||
|
protected:
|
||
|
ENUM_POSITION_TYPE m_type;
|
||
|
double m_volume;
|
||
|
double m_price;
|
||
|
double m_stop_loss;
|
||
|
double m_take_profit;
|
||
|
|
||
|
public:
|
||
|
CPositionInfo(void);
|
||
|
~CPositionInfo(void);
|
||
|
//--- fast access methods to the integer position propertyes
|
||
|
ulong Ticket(void) const;
|
||
|
datetime Time(void) const;
|
||
|
ulong TimeMsc(void) const;
|
||
|
datetime TimeUpdate(void) const;
|
||
|
ulong TimeUpdateMsc(void) const;
|
||
|
ENUM_POSITION_TYPE PositionType(void) const;
|
||
|
string TypeDescription(void) const;
|
||
|
long Magic(void) const;
|
||
|
long Identifier(void) const;
|
||
|
//--- fast access methods to the double position propertyes
|
||
|
double Volume(void) const;
|
||
|
double PriceOpen(void) const;
|
||
|
double StopLoss(void) const;
|
||
|
double TakeProfit(void) const;
|
||
|
double PriceCurrent(void) const;
|
||
|
double Commission(void) const;
|
||
|
double Swap(void) const;
|
||
|
double Profit(void) const;
|
||
|
//--- fast access methods to the string position propertyes
|
||
|
string Symbol(void) const;
|
||
|
string Comment(void) const;
|
||
|
//--- access methods to the API MQL5 functions
|
||
|
//bool InfoInteger(const ENUM_POSITION_PROPERTY_INTEGER prop_id,long &var) const;
|
||
|
//bool InfoDouble(const ENUM_POSITION_PROPERTY_DOUBLE prop_id,double &var) const;
|
||
|
//bool InfoString(const ENUM_POSITION_PROPERTY_STRING prop_id,string &var) const;
|
||
|
//--- info methods
|
||
|
string FormatType(string &str, const uint type) const;
|
||
|
string FormatPosition(string &str) const;
|
||
|
//--- methods for select position
|
||
|
bool Select(const string symbol);
|
||
|
bool SelectByMagic(const string symbol, const ulong magic);
|
||
|
bool SelectByTicket(const ulong ticket);
|
||
|
bool SelectByIndex(const int index);
|
||
|
//---
|
||
|
void StoreState(void);
|
||
|
bool CheckState(void);
|
||
|
int CountType(ENUM_ORDER_TYPE type,long magic);
|
||
|
};
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Constructor |
|
||
|
//+------------------------------------------------------------------+
|
||
|
CPositionInfo::CPositionInfo(void) : m_type(WRONG_VALUE),
|
||
|
m_volume(0.0),
|
||
|
m_price(0.0),
|
||
|
m_stop_loss(0.0),
|
||
|
m_take_profit(0.0) {
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Destructor |
|
||
|
//+------------------------------------------------------------------+
|
||
|
CPositionInfo::~CPositionInfo(void) {
|
||
|
}
|
||
|
|
||
|
int CPositionInfo::CountType(ENUM_ORDER_TYPE type,long magic){
|
||
|
|
||
|
int result = 0;
|
||
|
int count = OrdersTotal();
|
||
|
|
||
|
for(int i=count-1; i>=0; i--){
|
||
|
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
|
||
|
if(OrderSymbol()==Symbol() && OrderMagicNumber()==magic && (OrderType()==type || type == -1)) result++;
|
||
|
}
|
||
|
|
||
|
return(result);
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get the property value "POSITION_TICKET" |
|
||
|
//+------------------------------------------------------------------+
|
||
|
ulong CPositionInfo::Ticket(void) const {
|
||
|
return((ulong)OrderTicket());
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get the property value "POSITION_TIME" |
|
||
|
//+------------------------------------------------------------------+
|
||
|
datetime CPositionInfo::Time(void) const {
|
||
|
return((datetime)OrderOpenTime());
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get the property value "POSITION_TIME_MSC" |
|
||
|
//+------------------------------------------------------------------+
|
||
|
ulong CPositionInfo::TimeMsc(void) const {
|
||
|
return((ulong)OrderOpenTime());
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get the property value "POSITION_TIME_UPDATE" |
|
||
|
//+------------------------------------------------------------------+
|
||
|
datetime CPositionInfo::TimeUpdate(void) const {
|
||
|
return((datetime)OrderOpenTime());
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get the property value "POSITION_TIME_UPDATE_MSC" |
|
||
|
//+------------------------------------------------------------------+
|
||
|
ulong CPositionInfo::TimeUpdateMsc(void) const {
|
||
|
return((ulong)OrderOpenTime());
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get the property value "POSITION_TYPE" |
|
||
|
//+------------------------------------------------------------------+
|
||
|
ENUM_POSITION_TYPE CPositionInfo::PositionType(void) const {
|
||
|
return((ENUM_POSITION_TYPE)OrderType());
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get the property value "POSITION_TYPE" as string |
|
||
|
//+------------------------------------------------------------------+
|
||
|
string CPositionInfo::TypeDescription(void) const {
|
||
|
string str;
|
||
|
//---
|
||
|
return(FormatType(str, PositionType()));
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get the property value "POSITION_MAGIC" |
|
||
|
//+------------------------------------------------------------------+
|
||
|
long CPositionInfo::Magic(void) const {
|
||
|
return(OrderMagicNumber());
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get the property value "POSITION_IDENTIFIER" |
|
||
|
//+------------------------------------------------------------------+
|
||
|
long CPositionInfo::Identifier(void) const {
|
||
|
return(OrderTicket());
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get the property value "POSITION_VOLUME" |
|
||
|
//+------------------------------------------------------------------+
|
||
|
double CPositionInfo::Volume(void) const {
|
||
|
return(OrderLots());
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get the property value "POSITION_PRICE_OPEN" |
|
||
|
//+------------------------------------------------------------------+
|
||
|
double CPositionInfo::PriceOpen(void) const {
|
||
|
return(OrderOpenPrice());
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get the property value "POSITION_SL" |
|
||
|
//+------------------------------------------------------------------+
|
||
|
double CPositionInfo::StopLoss(void) const {
|
||
|
return(OrderStopLoss());
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get the property value "POSITION_TP" |
|
||
|
//+------------------------------------------------------------------+
|
||
|
double CPositionInfo::TakeProfit(void) const {
|
||
|
return(OrderTakeProfit());
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get the property value "POSITION_PRICE_CURRENT" |
|
||
|
//+------------------------------------------------------------------+
|
||
|
double CPositionInfo::PriceCurrent(void) const {
|
||
|
return -1;
|
||
|
return(OrderType() == ORDER_TYPE_BUY ? Bid : Ask);
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get the property value "POSITION_COMMISSION" |
|
||
|
//+------------------------------------------------------------------+
|
||
|
double CPositionInfo::Commission(void) const {
|
||
|
return(OrderCommission());
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get the property value "POSITION_SWAP" |
|
||
|
//+------------------------------------------------------------------+
|
||
|
double CPositionInfo::Swap(void) const {
|
||
|
return(OrderSwap());
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get the property value "POSITION_PROFIT" |
|
||
|
//+------------------------------------------------------------------+
|
||
|
double CPositionInfo::Profit(void) const {
|
||
|
return(OrderProfit());
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get the property value "POSITION_SYMBOL" |
|
||
|
//+------------------------------------------------------------------+
|
||
|
string CPositionInfo::Symbol(void) const {
|
||
|
return(OrderSymbol());
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get the property value "POSITION_COMMENT" |
|
||
|
//+------------------------------------------------------------------+
|
||
|
string CPositionInfo::Comment(void) const {
|
||
|
return(OrderComment());
|
||
|
}
|
||
|
/*
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Access functions PositionGetInteger(...) |
|
||
|
//+------------------------------------------------------------------+
|
||
|
bool CPositionInfo::InfoInteger(const ENUM_POSITION_PROPERTY_INTEGER prop_id,long &var) const
|
||
|
{
|
||
|
return(PositionGetInteger(prop_id,var));
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Access functions PositionGetDouble(...) |
|
||
|
//+------------------------------------------------------------------+
|
||
|
bool CPositionInfo::InfoDouble(const ENUM_POSITION_PROPERTY_DOUBLE prop_id,double &var) const
|
||
|
{
|
||
|
return(PositionGetDouble(prop_id,var));
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Access functions PositionGetString(...) |
|
||
|
//+------------------------------------------------------------------+
|
||
|
bool CPositionInfo::InfoString(const ENUM_POSITION_PROPERTY_STRING prop_id,string &var) const
|
||
|
{
|
||
|
return(PositionGetString(prop_id,var));
|
||
|
}
|
||
|
|
||
|
*/
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Converts the position type to text |
|
||
|
//+------------------------------------------------------------------+
|
||
|
string CPositionInfo::FormatType(string &str, const uint type) const {
|
||
|
//--- see the type
|
||
|
switch(type) {
|
||
|
case POSITION_TYPE_BUY:
|
||
|
str = "buy";
|
||
|
break;
|
||
|
case POSITION_TYPE_SELL:
|
||
|
str = "sell";
|
||
|
break;
|
||
|
default:
|
||
|
str = "unknown position type " + (string)type;
|
||
|
}
|
||
|
//--- return the result
|
||
|
return(str);
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Converts the position parameters to text |
|
||
|
//+------------------------------------------------------------------+
|
||
|
string CPositionInfo::FormatPosition(string &str) const {
|
||
|
string tmp, type;
|
||
|
long tmp_long;
|
||
|
ENUM_ACCOUNT_MARGIN_MODE margin_mode = ACCOUNT_MARGIN_MODE_RETAIL_HEDGING;
|
||
|
//--- set up
|
||
|
string symbol_name = this.Symbol();
|
||
|
int digits = _Digits;
|
||
|
if(SymbolInfoInteger(symbol_name, SYMBOL_DIGITS, tmp_long))
|
||
|
digits = (int)tmp_long;
|
||
|
//--- form the position description
|
||
|
if(margin_mode == ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)
|
||
|
str = StringFormat("#%I64u %s %s %s %s",
|
||
|
Ticket(),
|
||
|
FormatType(type, PositionType()),
|
||
|
DoubleToString(Volume(), 2),
|
||
|
symbol_name,
|
||
|
DoubleToString(PriceOpen(), digits + 3));
|
||
|
else
|
||
|
str = StringFormat("%s %s %s %s",
|
||
|
FormatType(type, PositionType()),
|
||
|
DoubleToString(Volume(), 2),
|
||
|
symbol_name,
|
||
|
DoubleToString(PriceOpen(), digits + 3));
|
||
|
//--- add stops if there are any
|
||
|
double sl = StopLoss();
|
||
|
double tp = TakeProfit();
|
||
|
if(sl != 0.0) {
|
||
|
tmp = StringFormat(" sl: %s", DoubleToString(sl, digits));
|
||
|
str += tmp;
|
||
|
}
|
||
|
if(tp != 0.0) {
|
||
|
tmp = StringFormat(" tp: %s", DoubleToString(tp, digits));
|
||
|
str += tmp;
|
||
|
}
|
||
|
//--- return the result
|
||
|
return(str);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Access functions PositionSelect(...) |
|
||
|
//+------------------------------------------------------------------+
|
||
|
bool CPositionInfo::Select(const string symbol)
|
||
|
{
|
||
|
return(PositionSelect(symbol));
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Access functions PositionSelect(...) |
|
||
|
//+------------------------------------------------------------------+
|
||
|
bool CPositionInfo::SelectByMagic(const string symbol,const ulong magic)
|
||
|
{
|
||
|
bool res=false;
|
||
|
uint total=PositionsTotal();
|
||
|
//---
|
||
|
for(uint i=0; i<total; i++)
|
||
|
{
|
||
|
string position_symbol=PositionGetSymbol(i);
|
||
|
if(position_symbol==symbol && magic==PositionGetInteger(POSITION_MAGIC))
|
||
|
{
|
||
|
res=true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
//---
|
||
|
return(res);
|
||
|
}
|
||
|
*/
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Access functions PositionSelectByTicket(...) |
|
||
|
//+------------------------------------------------------------------+
|
||
|
bool CPositionInfo::SelectByTicket(const ulong ticket) {
|
||
|
return OrderSelect((int) ticket, SELECT_BY_TICKET, MODE_TRADES);
|
||
|
return(ticket > 0);
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Select a position on the index |
|
||
|
//+------------------------------------------------------------------+
|
||
|
bool CPositionInfo::SelectByIndex(const int index) {
|
||
|
if(OrderSelect(index, SELECT_BY_POS, MODE_TRADES)) {
|
||
|
int type = OrderType();
|
||
|
if(type < 2) {
|
||
|
return(true);
|
||
|
}
|
||
|
}
|
||
|
return(false);
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Stored position's current state |
|
||
|
//+------------------------------------------------------------------+
|
||
|
void CPositionInfo::StoreState(void) {
|
||
|
m_type = PositionType();
|
||
|
m_volume = Volume();
|
||
|
m_price = PriceOpen();
|
||
|
m_stop_loss = StopLoss();
|
||
|
m_take_profit = TakeProfit();
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Check position change |
|
||
|
//+------------------------------------------------------------------+
|
||
|
bool CPositionInfo::CheckState(void) {
|
||
|
if(m_type == PositionType() &&
|
||
|
m_volume == Volume() &&
|
||
|
m_price == PriceOpen() &&
|
||
|
m_stop_loss == StopLoss() &&
|
||
|
m_take_profit == TakeProfit())
|
||
|
return(false);
|
||
|
//---
|
||
|
return(true);
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
|
||
|
#endif
|
||
|
//+------------------------------------------------------------------+
|