//+------------------------------------------------------------------+ //| 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" //+------------------------------------------------------------------+ //| Тип управления капиталом. | //+------------------------------------------------------------------+ enum ENUM_MM_TYPE { MM_FIX_LOT, // Фиксированный лот MM_PERCENT_DEPO, // Процент от депозита MM_PERCENT_SL // Процент от SL }; //input ENUM_MM_TYPE TypeMM; // Тип управления MM //input double FixLotOrPercent; // Фикс. лот или % //+------------------------------------------------------------------+ //| Модуль управление капиталом. | //+------------------------------------------------------------------+ class CMoneyManagment { private: ENUM_MM_TYPE m_type; // Тип ММ double m_fix_lot; // Значение фиксированного лота. double m_percent; // Процент от депозита или % от SL string m_symbol; // Символ CLog* Log; // Логирование public: CMoneyManagment(void); /* Установка параметров */ void SetMMType(ENUM_MM_TYPE); void SetLotFixed(double fix_lot); void SetPercent(double percent); void SetSymbol(string symbol); bool ParseByXml(CXmlElement *xmlMM); /* Методы расчета лота */ double GetLotFixed(void); double GetLotByPercentDepo(void); double GetLotByStopLoss(double stop_in_pips); }; //+------------------------------------------------------------------+ //| Конструктор по умолчанию | //+------------------------------------------------------------------+ CMoneyManagment::CMoneyManagment(void) { SetMMType(MM_FIX_LOT); SetLotFixed(1.0); SetPercent(2.0); SetSymbol(_Symbol); } //+------------------------------------------------------------------+ //| Устанавливает фиксированный лот возвращаемый методом GetLotFixed | //+------------------------------------------------------------------+ void CMoneyManagment::SetLotFixed(double fix_lot) { m_fix_lot=fix_lot; } //+------------------------------------------------------------------+ //| Устанавливает процент, используемый в расчетах методами | //| GetLotByPercentDepo и GetLotByStopLoss | //+------------------------------------------------------------------+ void CMoneyManagment::SetPercent(double percent) { m_percent=percent; } //+------------------------------------------------------------------+ //| Возвращает фиксированный лот или процент от депозита или % | //| от стоп лосса в зависимости от задаваемого типа ENUM_MM_TYPE | //+------------------------------------------------------------------+ double CMoneyManagment::GetLotFixed(void) { return m_fix_lot; } //+------------------------------------------------------------------+ //| Устанавливае тип управления капиталом | //+------------------------------------------------------------------+ void CMoneyManagment::SetMMType(ENUM_MM_TYPE type) { m_type=type; } //+------------------------------------------------------------------+ //| Устанавливает символ, для которого требуется вернуть количество | //| лотов. | //+------------------------------------------------------------------+ void CMoneyManagment::SetSymbol(string symbol) { m_symbol=symbol; } //+------------------------------------------------------------------+ //| Парсит XML-настройки для текущего модуля ММ | //+------------------------------------------------------------------+ bool CMoneyManagment::ParseByXml(CXmlElement *xmlMM) { CXmlAttribute *attr=xmlMM.GetAttribute("Type"); if(attr==NULL) { string text="Sending node 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 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 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; } //+------------------------------------------------------------------+ //| Возвращает лот стоимостью равный предустановленному проценту | //| от депозита. Например, если через SetPercent установлено значение| //| 20.0 (20%), при депозите 1 000 000 рублей будет куплено 3 | //| контракта Si, стоимостью 66 500 руб. каждый: | //| (1 000 000 * 0.20)/65 500 руб = 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); } //+------------------------------------------------------------------+ //| Возвращает лот рассчитанный таким образом, что если цена пройдет | //| расстояние в пипсах указанное в stop_in_pips, убыток или прибыль | //| будут равны проценту от депозита предварительно установленному в | //| методе 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; } //+------------------------------------------------------------------+