Article-15346-MQL5-Trade-Mo.../Account.mqh

212 lines
35 KiB
MQL5
Raw Permalink Normal View History

2026-03-23 13:19:06 +07:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| Account.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 "PositionsControl.mqh"
//+------------------------------------------------------------------+
//| ;0AA 0::0C=B0 |
//+------------------------------------------------------------------+
class CAccount : public CObject
{
private:
protected:
CPositionsControl m_positions; // 1J5:B :>=B@>;O 8AB>@8G5A:8E ?>78F89
//--- F5;>G8A;5==K5 A2>9AB20 0::0C=B0
long m_login; // ><5@ AG5B0
ENUM_ACCOUNT_TRADE_MODE m_trade_mode; // "8? B>@3>2>3> AG5B0
long m_leverage; // 07<5@ ?@54>AB02;5==>3> ?;5G0
int m_limit_orders; // 0:A8<0;L=> 4>?CAB8<>5 :>;8G5AB2> 459AB2CNI8E >B;>65==KE >@45@>2
ENUM_ACCOUNT_STOPOUT_MODE m_margin_so_mode; // 568< 7040=8O <8=8<0;L=> 4>?CAB8<>3> C@>2=O 70;>3>2KE A@54AB2
bool m_trade_allowed; // 07@5H5==>ABL B>@3>2;8 4;O B5:CI53> AG5B0
bool m_trade_expert; // 07@5H5==>ABL B>@3>2;8 4;O M:A?5@B0
ENUM_ACCOUNT_MARGIN_MODE m_margin_mode; // 568< @0AG5B0 <0@68
int m_currency_digits; // >;8G5AB2> 7=0:>2 ?>A;5 70?OB>9 4;O 20;NBK AG5B0, =5>1E>48<KE 4;O B>G=>3> >B>1@065=8O B>@3>2KE @57C;LB0B>2
bool m_fifo_close; // @87=0: B>3>, GB> ?>78F88 <>6=> 70:@K20BL B>;L:> ?> ?@028;C FIFO
bool m_hedge_allowed; // @87=0: B>3>, GB> @07@5H5=K 2AB@5G=K5 ?>78F88 ?> >4=><C A8<2>;C
//--- 25I5AB25==K5 A2>9AB20 0::0C=B0
double m_balance; // 0;0=A AG5B0 2 20;NB5 45?>78B0
double m_credit; // 07<5@ ?@54>AB02;5==>3> :@548B0 2 20;NB5 45?>78B0
double m_profit; // 07<5@ B5:CI59 ?@81K;8 =0 AG5B5 2 20;NB5 45?>78B0
double m_equity; // =0G5=85 A>1AB25==KE A@54AB2 =0 AG5B5 2 20;NB5 45?>78B0
double m_margin; // 07<5@ 70@575@28@>20==KE 70;>3>2KE A@54AB2 =0 AG5B5 2 20;NB5 45?>78B0
double m_margin_free; // 07<5@ A2>1>4=KE A@54AB2 =0 AG5B5 2 20;NB5 45?>78B0, 4>ABC?=KE 4;O >B:@KB8O ?>78F88
double m_margin_level; // #@>25=L 70;>3>2KE A@54AB2 =0 AG5B5 2 ?@>F5=B0E
double m_margin_so_call; // #@>25=L 70;>3>2KE A@54AB2, ?@8 :>B>@>< B@51C5BAO ?>?>;=5=85 AG5B0 (Margin Call)
double m_margin_so_so; // #@>25=L 70;>3>2KE A@54AB2, ?@8 4>AB865=88 :>B>@>3> ?@>8AE>48B ?@8=C48B5;L=>5 70:@KB85 A0<>9 C1KB>G=>9 ?>78F88 (Stop Out)
double m_margin_initial; // 07<5@ A@54AB2, 70@575@28@>20==KE =0 AGQB5, 4;O >15A?5G5=8O 30@0=B89=>9 AC<<K ?> 2A5< >B;>65==K< >@45@0<
double m_margin_maintenance; // 07<5@ A@54AB2, 70@575@28@>20==KE =0 AGQB5, 4;O >15A?5G5=8O <8=8<0;L=>9 AC<<K ?> 2A5< >B:@KBK< ?>78F8O<
double m_assets; // "5:CI89 @07<5@ 0:B82>2 =0 AGQB5
double m_liabilities; // "5:CI89 @07<5@ >1O70B5;LAB2 =0 AGQB5
double m_commission_blocked; // "5:CI0O AC<<0 701;>:8@>20==KE :><8AA89 ?> AGQBC
//--- AB@>:>2K5 A2>9AB20 0::0C=B0
string m_name; // <O :;85=B0
string m_server; // <O B>@3>2>3> A5@25@0
string m_currency; // 0;NB0 45?>78B0
string m_company; // <O :><?0=88, >1A;C6820NI59 AG5B
public:
//--- >72@0I05B (1) >1J5:B :>=B@>;O, (2) A?8A>: 8AB>@8G5A:8E ?>78F89, (3) :>;8G5AB2> ?>78F89
CPositionsControl*GetPositionsCtrlObj(void) { return &this.m_positions; }
CArrayObj *GetPositionsList(void) { return this.m_positions.GetPositionsList();}
int PositionsTotal(void) { return this.m_positions.PositionsTotal(); }
//--- >72@0I05B A?8A>: ?>78F89 ?> D8;LB@C (1) F5;>G8A;5==>3>, (2) 25I5AB25==>3>, (3) AB@>:>2>3> A2>9AB20
CArrayObj *GetPositionsList(ENUM_POSITION_PROPERTY_INT property, long value, ENUM_COMPARER_TYPE mode)
{ return CSelect::ByPositionProperty(this.GetPositionsList(), property, value, mode); }
CArrayObj *GetPositionsList(ENUM_POSITION_PROPERTY_DBL property, double value, ENUM_COMPARER_TYPE mode)
{ return CSelect::ByPositionProperty(this.GetPositionsList(), property, value, mode); }
CArrayObj *GetPositionsList(ENUM_POSITION_PROPERTY_STR property, string value, ENUM_COMPARER_TYPE mode)
{ return CSelect::ByPositionProperty(this.GetPositionsList(), property, value, mode); }
//--- (1) 1=>2;O5B, (2) @0A?5G0BK205B 2 6C@=0; A?8A>: 70:@KBKE ?>78F89
bool PositionsRefresh(void) { return this.m_positions.Refresh();}
void PositionsPrint(void) { this.m_positions.Print(); }
//--- CAB0=02;8205B (1) ;>38=, (2) A5@25@
void SetLogin(const long login) { this.m_login=login; }
void SetServer(const string server) { this.m_server=server; }
//--- 2>72@0B F5;>G8A;5==KE A2>9AB2 0::0C=B0
long Login(void) const { return this.m_login; } // ><5@ AG5B0
ENUM_ACCOUNT_TRADE_MODE TradeMode(void) const { return this.m_trade_mode; } // "8? B>@3>2>3> AG5B0
long Leverage(void) const { return this.m_leverage; } // 07<5@ ?@54>AB02;5==>3> ?;5G0
int LimitOrders(void) const { return this.m_limit_orders; } // 0:A8<0;L=> 4>?CAB8<>5 :>;8G5AB2> 459AB2CNI8E >B;>65==KE >@45@>2
ENUM_ACCOUNT_STOPOUT_MODE MarginSoMode(void) const { return this.m_margin_so_mode; } // 568< 7040=8O <8=8<0;L=> 4>?CAB8<>3> C@>2=O 70;>3>2KE A@54AB2
bool TradeAllowed(void) const { return this.m_trade_allowed; } // 07@5H5==>ABL B>@3>2;8 4;O B5:CI53> AG5B0
bool TradeExpert(void) const { return this.m_trade_expert; } // 07@5H5==>ABL B>@3>2;8 4;O M:A?5@B0
ENUM_ACCOUNT_MARGIN_MODE MarginMode(void) const { return this.m_margin_mode; } // 568< @0AG5B0 <0@68
int CurrencyDigits(void) const { return this.m_currency_digits; } // >;8G5AB2> 7=0:>2 ?>A;5 70?OB>9 4;O 20;NBK AG5B0, =5>1E>48<KE 4;O B>G=>3> >B>1@065=8O B>@3>2KE @57C;LB0B>2
bool FIFOClose(void) const { return this.m_fifo_close; } // @87=0: B>3>, GB> ?>78F88 <>6=> 70:@K20BL B>;L:> ?> ?@028;C FIFO
bool HedgeAllowed(void) const { return this.m_hedge_allowed; } // @87=0: B>3>, GB> @07@5H5=K 2AB@5G=K5 ?>78F88 ?> >4=><C A8<2>;C
//--- 2>72@0B 25I5AB25==KE A2>9AB2 0::0C=B0
double Balance(void) const { return this.m_balance; } // 0;0=A AG5B0 2 20;NB5 45?>78B0
double Credit(void) const { return this.m_credit; } // 07<5@ ?@54>AB02;5==>3> :@548B0 2 20;NB5 45?>78B0
double Profit(void) const { return this.m_profit; } // 07<5@ B5:CI59 ?@81K;8 =0 AG5B5 2 20;NB5 45?>78B0
double Equity(void) const { return this.m_equity; } // =0G5=85 A>1AB25==KE A@54AB2 =0 AG5B5 2 20;NB5 45?>78B0
double Margin(void) const { return this.m_margin; } // 07<5@ 70@575@28@>20==KE 70;>3>2KE A@54AB2 =0 AG5B5 2 20;NB5 45?>78B0
double MarginFree(void) const { return this.m_margin_free; } // 07<5@ A2>1>4=KE A@54AB2 =0 AG5B5 2 20;NB5 45?>78B0, 4>ABC?=KE 4;O >B:@KB8O ?>78F88
double MarginLevel(void) const { return this.m_margin_level; } // #@>25=L 70;>3>2KE A@54AB2 =0 AG5B5 2 ?@>F5=B0E
double MarginSoCall(void) const { return this.m_margin_so_call; } // #@>25=L 70;>3>2KE A@54AB2, ?@8 :>B>@>< B@51C5BAO ?>?>;=5=85 AG5B0 (Margin Call)
double MarginSoSo(void) const { return this.m_margin_so_so; } // #@>25=L 70;>3>2KE A@54AB2, ?@8 4>AB865=88 :>B>@>3> ?@>8AE>48B ?@8=C48B5;L=>5 70:@KB85 A0<>9 C1KB>G=>9 ?>78F88 (Stop Out)
double MarginInitial(void) const { return this.m_margin_initial; } // 07<5@ A@54AB2, 70@575@28@>20==KE =0 AGQB5, 4;O >15A?5G5=8O 30@0=B89=>9 AC<<K ?> 2A5< >B;>65==K< >@45@0<
double MarginMaintenance(void) const { return this.m_margin_maintenance; } // 07<5@ A@54AB2, 70@575@28@>20==KE =0 AGQB5, 4;O >15A?5G5=8O <8=8<0;L=>9 AC<<K ?> 2A5< >B:@KBK< ?>78F8O<
double Assets(void) const { return this.m_assets; } // "5:CI89 @07<5@ 0:B82>2 =0 AGQB5
double Liabilities(void) const { return this.m_liabilities; } // "5:CI89 @07<5@ >1O70B5;LAB2 =0 AGQB5
double CommissionBlocked(void) const { return this.m_commission_blocked; } // "5:CI0O AC<<0 701;>:8@>20==KE :><8AA89 ?> AGQBC
//--- 2>72@0B AB@>:>2KE A2>9AB2 0::0C=B0
string Name(void) const { return this.m_name; } // <O :;85=B0
string Server(void) const { return this.m_server; } // <O B>@3>2>3> A5@25@0
string Currency(void) const { return this.m_currency; } // 0;NB0 45?>78B0
string Company(void) const { return this.m_company; } // <O :><?0=88, >1A;C6820NI59 AG5B
//--- 2>72@0I05B >?8A0=85 (1) 0::0C=B0, (2) B8?0 B>@3>2>3> AGQB0, (3) @568<0 @0AGQB0 <0@68
string Description(void) const;
string TradeModeDescription(void) const;
string MarginModeDescription(void)const;
//--- 28@BC0;L=K9 <5B>4 A@02=5=8O 42CE >1J5:B>2
virtual int Compare(const CObject *node,const int mode=0) const;
//--- K2>48B 2 6C@=0; >?8A0=85 0::0C=B0
void Print(void) { ::Print(this.Description()); }
//--- :>=AB@C:B>@K/45AB@C:B>@
CAccount(void){}
CAccount(const long login, const string server_name);
~CAccount() {}
};
//+------------------------------------------------------------------+
//| >=AB@C:B>@ |
//+------------------------------------------------------------------+
CAccount::CAccount(const long login, const string server_name)
{
this.m_login=login;
this.m_server=server_name;
//--- CAB0=02;8205< F5;>G8A;5==K5 A2>9AB20 0::0C=B0
this.m_trade_mode = (ENUM_ACCOUNT_TRADE_MODE)::AccountInfoInteger(ACCOUNT_TRADE_MODE); // "8? B>@3>2>3> AG5B0
this.m_leverage = ::AccountInfoInteger(ACCOUNT_LEVERAGE); // 07<5@ ?@54>AB02;5==>3> ?;5G0
this.m_limit_orders = (int)::AccountInfoInteger(ACCOUNT_LIMIT_ORDERS); // 0:A8<0;L=> 4>?CAB8<>5 :>;8G5AB2> 459AB2CNI8E >B;>65==KE >@45@>2
this.m_margin_so_mode = (ENUM_ACCOUNT_STOPOUT_MODE)AccountInfoInteger(ACCOUNT_MARGIN_SO_MODE);// 568< 7040=8O <8=8<0;L=> 4>?CAB8<>3> C@>2=O 70;>3>2KE A@54AB2
this.m_trade_allowed = ::AccountInfoInteger(ACCOUNT_TRADE_ALLOWED); // 07@5H5==>ABL B>@3>2;8 4;O B5:CI53> AG5B0
this.m_trade_expert = ::AccountInfoInteger(ACCOUNT_TRADE_EXPERT); // 07@5H5==>ABL B>@3>2;8 4;O M:A?5@B0
this.m_margin_mode = (ENUM_ACCOUNT_MARGIN_MODE)::AccountInfoInteger(ACCOUNT_MARGIN_MODE); // 568< @0AG5B0 <0@68
this.m_currency_digits = (int)::AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS); // >;8G5AB2> 7=0:>2 ?>A;5 70?OB>9 4;O 20;NBK AG5B0, =5>1E>48<KE 4;O B>G=>3> >B>1@065=8O B>@3>2KE @57C;LB0B>2
this.m_fifo_close = ::AccountInfoInteger(ACCOUNT_FIFO_CLOSE); // @87=0: B>3>, GB> ?>78F88 <>6=> 70:@K20BL B>;L:> ?> ?@028;C FIFO
this.m_hedge_allowed = ::AccountInfoInteger(ACCOUNT_HEDGE_ALLOWED); // @87=0: B>3>, GB> @07@5H5=K 2AB@5G=K5 ?>78F88 ?> >4=><C A8<2>;C
//--- CAB0=02;8205< 25I5AB25==K5 A2>9AB20 0::0C=B0
this.m_balance = ::AccountInfoDouble(ACCOUNT_BALANCE); // 0;0=A AG5B0 2 20;NB5 45?>78B0
this.m_credit = ::AccountInfoDouble(ACCOUNT_CREDIT); // 07<5@ ?@54>AB02;5==>3> :@548B0 2 20;NB5 45?>78B0
this.m_profit = ::AccountInfoDouble(ACCOUNT_PROFIT); // 07<5@ B5:CI59 ?@81K;8 =0 AG5B5 2 20;NB5 45?>78B0
this.m_equity = ::AccountInfoDouble(ACCOUNT_EQUITY); // =0G5=85 A>1AB25==KE A@54AB2 =0 AG5B5 2 20;NB5 45?>78B0
this.m_margin = ::AccountInfoDouble(ACCOUNT_MARGIN); // 07<5@ 70@575@28@>20==KE 70;>3>2KE A@54AB2 =0 AG5B5 2 20;NB5 45?>78B0
this.m_margin_free = ::AccountInfoDouble(ACCOUNT_MARGIN_FREE); // 07<5@ A2>1>4=KE A@54AB2 =0 AG5B5 2 20;NB5 45?>78B0, 4>ABC?=KE 4;O >B:@KB8O ?>78F88
this.m_margin_level = ::AccountInfoDouble(ACCOUNT_MARGIN_LEVEL); // #@>25=L 70;>3>2KE A@54AB2 =0 AG5B5 2 ?@>F5=B0E
this.m_margin_so_call = ::AccountInfoDouble(ACCOUNT_MARGIN_SO_CALL); // #@>25=L 70;>3>2KE A@54AB2, ?@8 :>B>@>< B@51C5BAO ?>?>;=5=85 AG5B0 (Margin Call)
this.m_margin_so_so = ::AccountInfoDouble(ACCOUNT_MARGIN_SO_SO); // #@>25=L 70;>3>2KE A@54AB2, ?@8 4>AB865=88 :>B>@>3> ?@>8AE>48B ?@8=C48B5;L=>5 70:@KB85 A0<>9 C1KB>G=>9 ?>78F88 (Stop Out)
this.m_margin_initial = ::AccountInfoDouble(ACCOUNT_MARGIN_INITIAL); // 07<5@ A@54AB2, 70@575@28@>20==KE =0 AGQB5, 4;O >15A?5G5=8O 30@0=B89=>9 AC<<K ?> 2A5< >B;>65==K< >@45@0<
this.m_margin_maintenance = ::AccountInfoDouble(ACCOUNT_MARGIN_MAINTENANCE); // 07<5@ A@54AB2, 70@575@28@>20==KE =0 AGQB5, 4;O >15A?5G5=8O <8=8<0;L=>9 AC<<K ?> 2A5< >B:@KBK< ?>78F8O<
this.m_assets = ::AccountInfoDouble(ACCOUNT_ASSETS); // "5:CI89 @07<5@ 0:B82>2 =0 AGQB5
this.m_liabilities = ::AccountInfoDouble(ACCOUNT_LIABILITIES); // "5:CI89 @07<5@ >1O70B5;LAB2 =0 AGQB5
this.m_commission_blocked = ::AccountInfoDouble(ACCOUNT_COMMISSION_BLOCKED); // "5:CI0O AC<<0 701;>:8@>20==KE :><8AA89 ?> AGQBC
//--- CAB0=02;8205< AB@>:>2K5 A2>9AB20 0::0C=B0
this.m_name = ::AccountInfoString(ACCOUNT_NAME); // <O :;85=B0
this.m_currency = ::AccountInfoString(ACCOUNT_CURRENCY); // 0;NB0 45?>78B0
this.m_company = ::AccountInfoString(ACCOUNT_COMPANY); // <O :><?0=88, >1A;C6820NI59 AG5B
}
//+------------------------------------------------------------------+
//| 5B>4 A@02=5=8O 42CE >1J5:B>2 |
//+------------------------------------------------------------------+
int CAccount::Compare(const CObject *node,const int mode=0) const
{
const CAccount *obj=node;
return(this.Login()>obj.Login() ? 1 : this.Login()<obj.Login() ? -1 :
this.Server()>obj.Server() ? 1 : this.Server()<obj.Server() ? -1 : 0);
}
//+------------------------------------------------------------------+
//| >72@0I05B >?8A0=85 B8?0 B>@3>2>3> AGQB0 |
//+------------------------------------------------------------------+
string CAccount::TradeModeDescription(void) const
{
string mode=::StringSubstr(::EnumToString(this.TradeMode()), 19);
if(mode.Lower())
mode.SetChar(0, ushort(mode.GetChar(0)-32));
return mode;
}
//+------------------------------------------------------------------+
//| >72@0I05B >?8A0=85 @568<0 @0AGQB0 <0@68 |
//+------------------------------------------------------------------+
string CAccount::MarginModeDescription(void) const
{
string mode=::StringSubstr(::EnumToString(this.MarginMode()), 20);
::StringReplace(mode, "RETAIL_", "");
if(mode.Lower())
mode.SetChar(0, ushort(mode.GetChar(0)-32));
return mode;
}
//+------------------------------------------------------------------+
//| >72@0I05B >?8A0=85 0::0C=B0 |
//+------------------------------------------------------------------+
string CAccount::Description(void) const
{
return(::StringFormat("%I64d: %s (%s, %s, %.2f %s, %s)",
this.Login(), this.Name(), this.Company(), this.TradeModeDescription(),
this.Balance(), this.Currency(), this.MarginModeDescription()));
}
//+------------------------------------------------------------------+