BeazCode/Include/MQL4/Trade/PositionInfo.mqh

394 lines
16 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 14:43:23 +02:00
//+------------------------------------------------------------------+
//| 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
//+------------------------------------------------------------------+