90 lines
4.4 KiB
MQL5
90 lines
4.4 KiB
MQL5
|
//+------------------------------------------------------------------+
|
||
|
//| MoneyFixedRisk.mqh |
|
||
|
//| Copyright 2000-2023, MetaQuotes Ltd. |
|
||
|
//| https://www.mql5.com |
|
||
|
//+------------------------------------------------------------------+
|
||
|
#include "..\Expert\ExpertMoneyCustom.mqh"
|
||
|
// wizard description start
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Description of the class |
|
||
|
//| Title=Trading with fixed risk |
|
||
|
//| Type=Money |
|
||
|
//| Name=FixRisk |
|
||
|
//| Class=CMoneyFixedRisk |
|
||
|
//| Page= |
|
||
|
//| Parameter=Percent,double,10.0,Risk percentage |
|
||
|
//+------------------------------------------------------------------+
|
||
|
// wizard description end
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Class CMoneyFixedRisk. |
|
||
|
//| Purpose: Class of money management with fixed percent risk. |
|
||
|
//| Derives from class CExpertMoney. |
|
||
|
//+------------------------------------------------------------------+
|
||
|
class CMoneyFixedRisk : public CExpertMoneyCustom
|
||
|
{
|
||
|
public:
|
||
|
virtual double CheckOpenLong(double price, double sl);
|
||
|
virtual double CheckOpenShort(double price, double sl);
|
||
|
virtual double CheckClose(CPositionInfo *position) { return(0.0); }
|
||
|
|
||
|
private:
|
||
|
double CalculatePotentialLoss(ENUM_ORDER_TYPE orderType, double price, double sl);
|
||
|
double CalculateLotSize(double loss);
|
||
|
};
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Getting lot size for open long position. |
|
||
|
//+------------------------------------------------------------------+
|
||
|
double CMoneyFixedRisk::CheckOpenLong(double price, double sl)
|
||
|
{
|
||
|
if(m_symbol == NULL)
|
||
|
return 0.0;
|
||
|
double loss = CalculatePotentialLoss(ORDER_TYPE_BUY, price, sl);
|
||
|
if(loss <= 0.0)
|
||
|
return m_symbol.LotsMin();
|
||
|
double lot = CalculateLotSize(loss);
|
||
|
string description;
|
||
|
// Adjust the lot size within allowed bounds and ensure sufficient margin
|
||
|
if(CheckAndCorrectVolumeValue(lot, description) && CheckAndAdjustMoneyForTrade(m_symbol.Name(), lot, ORDER_TYPE_BUY))
|
||
|
return lot;
|
||
|
else
|
||
|
return 0.0; // Handle as needed or inform the user
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Getting lot size for open short position. |
|
||
|
//+------------------------------------------------------------------+
|
||
|
double CMoneyFixedRisk::CheckOpenShort(double price, double sl)
|
||
|
{
|
||
|
if(m_symbol == NULL)
|
||
|
return 0.0;
|
||
|
double loss = CalculatePotentialLoss(ORDER_TYPE_SELL, price, sl);
|
||
|
if(loss <= 0.0)
|
||
|
return m_symbol.LotsMin();
|
||
|
double lot = CalculateLotSize(loss);
|
||
|
string description;
|
||
|
// Adjust the lot size within allowed bounds and ensure sufficient margin
|
||
|
if(CheckAndCorrectVolumeValue(lot, description) && CheckAndAdjustMoneyForTrade(m_symbol.Name(), lot, ORDER_TYPE_SELL))
|
||
|
return lot;
|
||
|
else
|
||
|
return 0.0; // Handle as needed or inform the user
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Calculate potential loss |
|
||
|
//+------------------------------------------------------------------+
|
||
|
double CMoneyFixedRisk::CalculatePotentialLoss(ENUM_ORDER_TYPE orderType, double price, double sl)
|
||
|
{
|
||
|
if(price == 0.0)
|
||
|
price = (orderType == ORDER_TYPE_BUY) ? m_symbol.Ask() : m_symbol.Bid();
|
||
|
return -m_account.OrderProfitCheck(m_symbol.Name(), orderType, 1.0, price, sl);
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Calculate the lot size based on potential loss and account balance|
|
||
|
//+------------------------------------------------------------------+
|
||
|
double CMoneyFixedRisk::CalculateLotSize(double loss)
|
||
|
{
|
||
|
double riskAmount = m_account.Balance() * m_percent / 100.0;
|
||
|
double stepvol = m_symbol.LotsStep();
|
||
|
return MathFloor(riskAmount / loss / stepvol) * stepvol;
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|