Warrior_EA/Expert/ExpertMoneyCustom.mqh
super.admin 0a527b0cf9 convert
2025-05-30 16:35:54 +02:00

70 lines
3.2 KiB
MQL5

//+------------------------------------------------------------------+
//| Warrior_EA |
//| AnimateDread |
//| |
//+------------------------------------------------------------------+
#include <Expert\ExpertMoney.mqh>
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);
}
//+------------------------------------------------------------------+