UTE/Strategy/MoneyManagment.mqh

200 lines
17 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 16:34:43 +02:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| MoneyManagment.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 "XML\XMLbase.mqh"
#include "Message.mqh"
#include "Logs.mqh"
//+------------------------------------------------------------------+
//| "8? C?@02;5=8O :0?8B0;><. |
//+------------------------------------------------------------------+
enum ENUM_MM_TYPE
{
MM_FIX_LOT, // $8:A8@>20==K9 ;>B
MM_PERCENT_DEPO, // @>F5=B >B 45?>78B0
MM_PERCENT_SL // @>F5=B >B SL
};
//input ENUM_MM_TYPE TypeMM; // "8? C?@02;5=8O MM
//input double FixLotOrPercent; // $8:A. ;>B 8;8 %
//+------------------------------------------------------------------+
//| >4C;L C?@02;5=85 :0?8B0;><. |
//+------------------------------------------------------------------+
class CMoneyManagment
{
private:
ENUM_MM_TYPE m_type; // "8? 
double m_fix_lot; // =0G5=85 D8:A8@>20==>3> ;>B0.
double m_percent; // @>F5=B >B 45?>78B0 8;8 % >B SL
string m_symbol; // !8<2>;
CLog* Log; // >38@>20=85
public:
CMoneyManagment(void);
/* #AB0=>2:0 ?0@0<5B@>2 */
void SetMMType(ENUM_MM_TYPE);
void SetLotFixed(double fix_lot);
void SetPercent(double percent);
void SetSymbol(string symbol);
bool ParseByXml(CXmlElement *xmlMM);
/* 5B>4K @0AG5B0 ;>B0 */
double GetLotFixed(void);
double GetLotByPercentDepo(void);
double GetLotByStopLoss(double stop_in_pips);
};
//+------------------------------------------------------------------+
//| >=AB@C:B>@ ?> C<>;G0=8N |
//+------------------------------------------------------------------+
CMoneyManagment::CMoneyManagment(void)
{
SetMMType(MM_FIX_LOT);
SetLotFixed(1.0);
SetPercent(2.0);
SetSymbol(_Symbol);
}
//+------------------------------------------------------------------+
//| #AB0=02;8205B D8:A8@>20==K9 ;>B 2>72@0I05<K9 <5B>4>< GetLotFixed |
//+------------------------------------------------------------------+
void CMoneyManagment::SetLotFixed(double fix_lot)
{
m_fix_lot=fix_lot;
}
//+------------------------------------------------------------------+
//| #AB0=02;8205B ?@>F5=B, 8A?>;L7C5<K9 2 @0AG5B0E <5B>40<8 |
//| GetLotByPercentDepo 8 GetLotByStopLoss |
//+------------------------------------------------------------------+
void CMoneyManagment::SetPercent(double percent)
{
m_percent=percent;
}
//+------------------------------------------------------------------+
//| >72@0I05B D8:A8@>20==K9 ;>B 8;8 ?@>F5=B >B 45?>78B0 8;8 % |
//| >B AB>? ;>AA0 2 7028A8<>AB8 >B 7040205<>3> B8?0 ENUM_MM_TYPE |
//+------------------------------------------------------------------+
double CMoneyManagment::GetLotFixed(void)
{
return m_fix_lot;
}
//+------------------------------------------------------------------+
//| #AB0=02;8205 B8? C?@02;5=8O :0?8B0;>< |
//+------------------------------------------------------------------+
void CMoneyManagment::SetMMType(ENUM_MM_TYPE type)
{
m_type=type;
}
//+------------------------------------------------------------------+
//| #AB0=02;8205B A8<2>;, 4;O :>B>@>3> B@51C5BAO 25@=CBL :>;8G5AB2> |
//| ;>B>2. |
//+------------------------------------------------------------------+
void CMoneyManagment::SetSymbol(string symbol)
{
m_symbol=symbol;
}
//+------------------------------------------------------------------+
//| 0@A8B XML-=0AB@>9:8 4;O B5:CI53> <>4C;O  |
//+------------------------------------------------------------------+
bool CMoneyManagment::ParseByXml(CXmlElement *xmlMM)
{
CXmlAttribute *attr=xmlMM.GetAttribute("Type");
if(attr==NULL)
{
string text="Sending node <MoneyManagment> does not contain a mandatory attribute 'Type'";
CMessage *msg=new CMessage(MESSAGE_WARNING,__FUNCTION__,text);
Log.AddMessage(msg);
return false;
}
string sType=attr.GetValue();
if(sType!="FixedLot" && sType!="PercentDepo" && sType!="PercentSL")
{
string text="Attribute 'Type' contain a wrong value: "+sType+". Value must be equal 'FixedLot', 'PercentDepo' ot 'PercentSL'";
CMessage *msg=new CMessage(MESSAGE_WARNING,__FUNCTION__,text);
Log.AddMessage(msg);
return false;
}
if(sType=="FixedLot")
{
CXmlAttribute *lot=xmlMM.GetAttribute("Lot");
if(lot==NULL)
{
string text="Sending node <MoneyManagment> does not contain a mandatory attribute 'Lot'";
CMessage *msg=new CMessage(MESSAGE_WARNING,__FUNCTION__,text);
Log.AddMessage(msg);
return false;
}
double d_lot=StringToDouble(lot.GetValue());
if(d_lot<=0.0)
{
string text="Attribute 'Lot' contain a non-double value: "+lot.GetValue()+". The value must be greater than zero";
CMessage *msg=new CMessage(MESSAGE_WARNING,__FUNCTION__,text);
Log.AddMessage(msg);
return false;
}
else
{
m_type=MM_FIX_LOT;
m_fix_lot=d_lot;
}
}
else
{
CXmlAttribute *per=xmlMM.GetAttribute("Percent");
if(per==NULL)
{
string text="Sending node <MoneyManagment> does not contain a mandatory attribute 'Percent'";
CMessage *msg=new CMessage(MESSAGE_WARNING,__FUNCTION__,text);
Log.AddMessage(msg);
return false;
}
double d_per=StringToDouble(per.GetValue());
if(d_per<=0.0)
{
string text="Attribute 'Percent' contain a non-double value: "+per.GetValue()+". The value must be greater than zero";
CMessage *msg=new CMessage(MESSAGE_WARNING,__FUNCTION__,text);
Log.AddMessage(msg);
return false;
}
else
{
m_type=sType=="PercentDepo" ? MM_PERCENT_DEPO : MM_PERCENT_SL;
m_percent=d_per;
}
}
return true;
}
//+------------------------------------------------------------------+
//| >72@0I05B ;>B AB>8<>ABLN @02=K9 ?@54CAB0=>2;5==><C ?@>F5=BC |
//| >B 45?>78B0. 0?@8<5@, 5A;8 G5@57 SetPercent CAB0=>2;5=> 7=0G5=85|
//| 20.0 (20%), ?@8 45?>78B5 1 000 000 @C1;59 1C45B :C?;5=> 3 |
//| :>=B@0:B0 Si, AB>8<>ABLN 66 500 @C1. :064K9: |
//| (1 000 000 * 0.20)/65 500 @C1 = 3.0534 |
//+------------------------------------------------------------------+
double CMoneyManagment::GetLotByPercentDepo(void)
{
double point_cost=SymbolInfoDouble(m_symbol,SYMBOL_TRADE_TICK_VALUE);
double last = SymbolInfoDouble(m_symbol, SYMBOL_LAST);
double cost = point_cost*last;
double limit= AccountInfoDouble(ACCOUNT_BALANCE)*m_percent;
double lot=limit/cost;
return MathRound(lot);
}
//+------------------------------------------------------------------+
//| >72@0I05B ;>B @0AAG8B0==K9 B0:8< >1@07><, GB> 5A;8 F5=0 ?@>945B |
//| @0AAB>O=85 2 ?8?A0E C:070==>5 2 stop_in_pips, C1KB>: 8;8 ?@81K;L |
//| 1C4CB @02=K ?@>F5=BC >B 45?>78B0 ?@5420@8B5;L=> CAB0=>2;5==><C 2 |
//| <5B>45 SetPercent. |
//+------------------------------------------------------------------+
double CMoneyManagment::GetLotByStopLoss(double stop_in_pips)
{
double point_cost=SymbolInfoDouble(m_symbol,SYMBOL_TRADE_TICK_VALUE);
double cost=point_cost*stop_in_pips;
double limit=AccountInfoDouble(ACCOUNT_BALANCE)*m_percent;
double vol=MathAbs(limit/cost);
return vol;
}
//+------------------------------------------------------------------+