//+------------------------------------------------------------------+ //| MoneySizeOptimized.mqh | //| Copyright 2000-2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #include #include // wizard description start //+------------------------------------------------------------------+ //| Description of the class | //| Title=Trading with optimized trade volume | //| Type=Money | //| Name=SizeOptimized | //| Class=CMoneySizeOptimized | //| Page= | //| Parameter=DecreaseFactor,double,3.0,Decrease factor | //| Parameter=Percent,double,10.0,Percent | //+------------------------------------------------------------------+ // wizard description end //+------------------------------------------------------------------+ //| Class CMoneySizeOptimized. | //| Purpose: Class of money management with size optimized. | //| Derives from class CExpertMoney. | //+------------------------------------------------------------------+ class CMoneySizeOptimized : public CExpertMoney { protected: double m_decrease_factor; public: CMoneySizeOptimized(void); ~CMoneySizeOptimized(void); //--- void DecreaseFactor(double decrease_factor) { m_decrease_factor=decrease_factor; } virtual bool ValidationSettings(void); //--- virtual double CheckOpenLong(double price,double sl); virtual double CheckOpenShort(double price,double sl); protected: double Optimize(double lots); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ void CMoneySizeOptimized::CMoneySizeOptimized(void) : m_decrease_factor(3.0) { } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ void CMoneySizeOptimized::~CMoneySizeOptimized(void) { } //+------------------------------------------------------------------+ //| Validation settings protected data. | //+------------------------------------------------------------------+ bool CMoneySizeOptimized::ValidationSettings(void) { if(!CExpertMoney::ValidationSettings()) return(false); //--- initial data checks if(m_decrease_factor<=0.0) { printf(__FUNCTION__+": decrease factor must be greater then 0"); return(false); } //--- ok return(true); } //+------------------------------------------------------------------+ //| Getting lot size for open long position. | //+------------------------------------------------------------------+ double CMoneySizeOptimized::CheckOpenLong(double price,double sl) { if(m_symbol==NULL) return(0.0); //--- select lot size double lot; if(price==0.0) lot=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_BUY,m_symbol.Ask(),m_percent); else lot=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_BUY,price,m_percent); //--- return trading volume return(Optimize(lot)); } //+------------------------------------------------------------------+ //| Getting lot size for open short position. | //+------------------------------------------------------------------+ double CMoneySizeOptimized::CheckOpenShort(double price,double sl) { if(m_symbol==NULL) return(0.0); //--- select lot size double lot; if(price==0.0) lot=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_SELL,m_symbol.Bid(),m_percent); else lot=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_SELL,price,m_percent); //--- return trading volume return(Optimize(lot)); } //+------------------------------------------------------------------+ //| Optimizing lot size for open. | //+------------------------------------------------------------------+ double CMoneySizeOptimized::Optimize(double lots) { double lot=lots; //--- calculate number of losses orders without a break if(m_decrease_factor>0) { //--- select history for access HistorySelect(0,TimeCurrent()); //--- int orders=HistoryDealsTotal(); // total history deals int losses=0; // number of consequent losing orders CDealInfo deal; //--- for(int i=orders-1;i>=0;i--) { deal.Ticket(HistoryDealGetTicket(i)); if(deal.Ticket()==0) { Print("CMoneySizeOptimized::Optimize: HistoryDealGetTicket failed, no trade history"); break; } //--- check symbol if(deal.Symbol()!=m_symbol.Name()) continue; //--- check profit double profit=deal.Profit(); if(profit>0.0) break; if(profit<0.0) losses++; } //--- if(losses>1) lot=NormalizeDouble(lot-lot*losses/m_decrease_factor,2); } //--- normalize and check limits double stepvol=m_symbol.LotsStep(); lot=stepvol*NormalizeDouble(lot/stepvol,0); //--- double minvol=m_symbol.LotsMin(); if(lotmaxvol) lot=maxvol; //--- return(lot); } //+------------------------------------------------------------------+