//+------------------------------------------------------------------+ //| Warrior_EA | //| AnimateDread | //| | //+------------------------------------------------------------------+ #include class CExpertMoneyCustom : public CExpertMoney { protected: bool CheckAndCorrectVolumeValue(double &volume, string &description); bool CheckAndAdjustMoneyForTrade(string symb, double &lots, ENUM_ORDER_TYPE type); }; //+------------------------------------------------------------------+ //| Check and correct the order volume to the nearest valid value | //+------------------------------------------------------------------+ bool CExpertMoneyCustom::CheckAndCorrectVolumeValue(double &volume, string &description) { //--- minimal allowed volume for trade operations double min_volume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN); if(volume < min_volume) { volume = min_volume; // Adjust to the minimum valid volume description = StringFormat("Adjusted volume to the minimal allowed SYMBOL_VOLUME_MIN=%.2f", min_volume); } //--- maximal allowed volume of trade operations double max_volume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX); if(volume > max_volume) { volume = max_volume; // Adjust to the maximum valid volume description = StringFormat("Adjusted volume to the maximal allowed SYMBOL_VOLUME_MAX=%.2f", max_volume); } //--- get minimal step of volume changing double volume_step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP); int ratio = (int)MathRound(volume / volume_step); volume = ratio * volume_step; // Correct to the nearest valid step description = "Volume adjusted to a valid value"; return(true); } //+------------------------------------------------------------------+ //| Check and adjust the trade size based on available margin | //+------------------------------------------------------------------+ bool CExpertMoneyCustom::CheckAndAdjustMoneyForTrade(string symb, double &lots, ENUM_ORDER_TYPE type) { MqlTick mqltick; SymbolInfoTick(symb, mqltick); double price = (type == ORDER_TYPE_SELL) ? mqltick.bid : mqltick.ask; double margin, free_margin = AccountInfoDouble(ACCOUNT_MARGIN_FREE); if(!OrderCalcMargin(type, symb, lots, price, margin)) { Print("Error calculating margin: ", GetLastError()); return(false); } while(margin > free_margin && lots > 0) { lots -= 0.01; // Decrease lots by the smallest possible increment if(!OrderCalcMargin(type, symb, lots, price, margin) || lots <= 0) { Print("Unable to adjust lots to fit free margin."); return(false); } } if(lots <= 0) { Print("Adjusted lots size is too small for a trade."); return(false); } // If the code reaches this point, the lots size has been successfully adjusted return(true); } //+------------------------------------------------------------------+