Zenith-FX/MQL5/Experts/QuantumForexTrader/core/QuantumRiskManager.mqh
copilot-swe-agent[bot] 43b875366c Reorganize Quantum EA into proper MT5 directory structure
Co-authored-by: simonokwundue-ops <243668919+simonokwundue-ops@users.noreply.github.com>
2025-11-14 16:05:58 +00:00

214 Zeilen
8,1 KiB
MQL5

//+------------------------------------------------------------------+
//| QuantumRiskManager.mqh |
//| Quantum Forex Trader Support Library |
//| |
//+------------------------------------------------------------------+
#property copyright "Quantum Forex Trader"
#property link ""
#property version "1.00"
#property strict
#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\AccountInfo.mqh>
//+------------------------------------------------------------------+
//| Quantum Risk Manager Class |
//| Manages position sizing and risk based on quantum signals |
//+------------------------------------------------------------------+
class CQuantumRiskManager
{
private:
CTrade m_trade;
CPositionInfo m_position;
CAccountInfo m_account;
double m_riskPercent;
double m_maxDrawdownPercent;
int m_maxPositions;
double m_minLotSize;
double m_maxLotSize;
public:
CQuantumRiskManager() :
m_riskPercent(1.0),
m_maxDrawdownPercent(20.0),
m_maxPositions(3),
m_minLotSize(0.01),
m_maxLotSize(10.0)
{
}
~CQuantumRiskManager() {}
//+------------------------------------------------------------------+
//| Set risk parameters |
//+------------------------------------------------------------------+
void SetRiskPercent(double percent) { m_riskPercent = percent; }
void SetMaxDrawdown(double percent) { m_maxDrawdownPercent = percent; }
void SetMaxPositions(int max) { m_maxPositions = max; }
//+------------------------------------------------------------------+
//| Calculate position size based on risk |
//+------------------------------------------------------------------+
double CalculatePositionSize(const string symbol, double stopLossPips, double confidence = 1.0)
{
// Get account info
double balance = m_account.Balance();
double equity = m_account.Equity();
// Check drawdown
double currentDrawdown = ((balance - equity) / balance) * 100.0;
if(currentDrawdown >= m_maxDrawdownPercent)
{
Print("Max drawdown reached: ", currentDrawdown, "%");
return 0.0;
}
// Get symbol info
double tickSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE);
double tickValue = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE);
double lotStep = SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
double minLot = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX);
double pointValue = SymbolInfoDouble(symbol, SYMBOL_POINT);
// Calculate pip value
int digits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
double pipSize = (digits == 3 || digits == 5) ? pointValue * 10 : pointValue;
double pipValue = tickValue * (pipSize / tickSize);
// Calculate risk amount
double riskAmount = balance * (m_riskPercent / 100.0);
// Adjust risk based on confidence
riskAmount = riskAmount * confidence;
// Calculate lot size
double lotSize = 0.0;
if(stopLossPips > 0)
{
lotSize = riskAmount / (stopLossPips * pipValue);
}
else
{
// Default to minimum lot if no stop loss
lotSize = minLot;
}
// Normalize lot size
lotSize = MathFloor(lotSize / lotStep) * lotStep;
// Apply limits
if(lotSize < minLot) lotSize = minLot;
if(lotSize > maxLot) lotSize = maxLot;
if(lotSize > m_maxLotSize) lotSize = m_maxLotSize;
return lotSize;
}
//+------------------------------------------------------------------+
//| Check if can open new position |
//+------------------------------------------------------------------+
bool CanOpenPosition(const string symbol)
{
// Check max positions
int totalPositions = PositionsTotal();
if(totalPositions >= m_maxPositions)
{
Print("Max positions reached: ", totalPositions);
return false;
}
// Check if already have position on this symbol
for(int i = 0; i < totalPositions; i++)
{
if(m_position.SelectByIndex(i))
{
if(m_position.Symbol() == symbol)
{
Print("Already have position on ", symbol);
return false;
}
}
}
// Check account equity
if(m_account.Equity() <= 0)
{
Print("Insufficient equity");
return false;
}
// Check drawdown
double balance = m_account.Balance();
double equity = m_account.Equity();
double currentDrawdown = ((balance - equity) / balance) * 100.0;
if(currentDrawdown >= m_maxDrawdownPercent)
{
Print("Max drawdown reached: ", currentDrawdown, "%");
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| Open buy position |
//+------------------------------------------------------------------+
bool OpenBuyPosition(const string symbol, double lotSize, double stopLossPips, double takeProfitPips)
{
if(!CanOpenPosition(symbol))
return false;
double price = SymbolInfoDouble(symbol, SYMBOL_ASK);
int digits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
double point = SymbolInfoDouble(symbol, SYMBOL_POINT);
double pipSize = (digits == 3 || digits == 5) ? point * 10 : point;
double sl = (stopLossPips > 0) ? price - stopLossPips * pipSize : 0;
double tp = (takeProfitPips > 0) ? price + takeProfitPips * pipSize : 0;
bool result = m_trade.Buy(lotSize, symbol, price, sl, tp, "Quantum Buy");
if(result)
Print("Buy position opened: ", symbol, " Lot: ", lotSize, " SL: ", sl, " TP: ", tp);
else
Print("Failed to open buy position: ", m_trade.ResultRetcodeDescription());
return result;
}
//+------------------------------------------------------------------+
//| Open sell position |
//+------------------------------------------------------------------+
bool OpenSellPosition(const string symbol, double lotSize, double stopLossPips, double takeProfitPips)
{
if(!CanOpenPosition(symbol))
return false;
double price = SymbolInfoDouble(symbol, SYMBOL_BID);
int digits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
double point = SymbolInfoDouble(symbol, SYMBOL_POINT);
double pipSize = (digits == 3 || digits == 5) ? point * 10 : point;
double sl = (stopLossPips > 0) ? price + stopLossPips * pipSize : 0;
double tp = (takeProfitPips > 0) ? price - takeProfitPips * pipSize : 0;
bool result = m_trade.Sell(lotSize, symbol, price, sl, tp, "Quantum Sell");
if(result)
Print("Sell position opened: ", symbol, " Lot: ", lotSize, " SL: ", sl, " TP: ", tp);
else
Print("Failed to open sell position: ", m_trade.ResultRetcodeDescription());
return result;
}
//+------------------------------------------------------------------+
//| Get trade object reference |
//+------------------------------------------------------------------+
CTrade* GetTrade() { return GetPointer(m_trade); }
};
//+------------------------------------------------------------------+