70 lines
3.2 KiB
MQL5
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);
|
|
}
|
|
//+------------------------------------------------------------------+
|