Source 2
Source 2
// Input Parameters
input group "Risk Management"
input double BaseRiskPercent = 2.0; // Base Risk Percentage
input double MaxRiskPerTrade = 3.0; // Maximum Risk Per Trade (%)
input double MaxDrawdown = 10.0; // Maximum Account Drawdown (%)
public:
CAdaptiveLearning() {
ArrayInitialize(m_entryScores, 0.5);
ArrayInitialize(m_winRates, 0.5);
ArrayInitialize(m_tradeHistory, 0);
m_historyIndex = 0;
}
CAdaptiveLearning g_mlLearning;
//+------------------------------------------------------------------+
//| Normalize Lot Size |
//+------------------------------------------------------------------+
double NormalizeLotSize(double lotSize) {
double minLot = MarketInfo(Symbol(), MODE_MINLOT);
double maxLot = MarketInfo(Symbol(), MODE_MAXLOT);
double stepLot = MarketInfo(Symbol(), MODE_LOTSTEP);
return MathMax(minLot, MathMin(maxLot, MathFloor(lotSize / stepLot) * stepLot));
}
//+------------------------------------------------------------------+
//| Validate Trade Setup |
//+------------------------------------------------------------------+
bool IsValidTradeSetup(bool isLong) {
static double cachedFastMA = 0;
static double cachedSlowMA = 0;
static double cachedADX = 0;
static double cachedRSI = 0;
static datetime lastCalculationTime = 0;
if (lastCalculationTime != Time[0]) {
cachedFastMA = iMA(NULL, 0, FastMA_Period, 0, MODE_EMA, PRICE_CLOSE, 0);
cachedSlowMA = iMA(NULL, 0, SlowMA_Period, 0, MODE_EMA, PRICE_CLOSE, 0);
cachedADX = iADX(NULL, 0, ADX_Period, PRICE_CLOSE, MODE_MAIN, 0);
cachedRSI = iRSI(NULL, 0, RSI_Period, PRICE_CLOSE, 0);
lastCalculationTime = Time[0];
}
if (isLong) {
return (
cachedFastMA > cachedSlowMA &&
cachedADX > 25 &&
cachedRSI > 50
);
} else {
return (
cachedFastMA < cachedSlowMA &&
cachedADX > 25 &&
cachedRSI < 50
);
}
}
//+------------------------------------------------------------------+
//| Adaptive Lot Size Calculation |
//+------------------------------------------------------------------+
double CalculateAdaptiveLotSize(double stopLossPips, bool isLong) {
double accountBalance = AccountBalance();
double riskAmount = accountBalance * (BaseRiskPercent / 100);
double atr = iATR(NULL, 0, ATR_Period, 0);
double volatilityFactor = atr / Point;
double mlProbability = g_mlLearning.GetEntryProbability(isLong);
double baseTickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
double lotSize = riskAmount / (stopLossPips * baseTickValue);
double adaptiveLotSize = lotSize * mlProbability * (1 + (volatilityFactor / 100));
//+------------------------------------------------------------------+
//| Smart Stop Loss Calculation |
//+------------------------------------------------------------------+
double CalculateSmartStopLoss(bool isLong) {
double atr = iATR(NULL, 0, ATR_Period, 0);
if (isLong) {
double swingLow = Low[iLowest(Symbol(), 0, MODE_LOW, 14, 1)];
double technicalStop = Close[0] - (atr * 1.5);
return MathMin(swingLow, technicalStop);
} else {
double swingHigh = High[iHighest(Symbol(), 0, MODE_HIGH, 14, 1)];
double technicalStop = Close[0] + (atr * 1.5);
return MathMax(swingHigh, technicalStop);
}
}
//+------------------------------------------------------------------+
//| Advanced Breakeven Management |
//+------------------------------------------------------------------+
void ManageAdvancedBreakeven() {
for (int i = 0; i < OrdersTotal(); i++) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if (OrderSymbol() != Symbol()) continue;
if (OrderType() == OP_BUY) {
if (Bid >= OrderOpenPrice() + breakEvenBuffer) {
if (OrderStopLoss() < OrderOpenPrice()) {
if (!OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() +
breakEvenBuffer, OrderTakeProfit(), 0, clrGreen)) {
Print("Error modifying BUY order: ", GetLastError());
}
}
}
} else if (OrderType() == OP_SELL) {
if (Ask <= OrderOpenPrice() - breakEvenBuffer) {
if (OrderStopLoss() > OrderOpenPrice()) {
if (!OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() -
breakEvenBuffer, OrderTakeProfit(), 0, clrRed)) {
Print("Error modifying SELL order: ", GetLastError());
}
}
}
}
}
}
}
//+------------------------------------------------------------------+
//| Advanced Error Handling |
//+------------------------------------------------------------------+
void HandleOrderError(int errorCode) {
switch (errorCode) {
case 134: // ERR_NO_MONEY
Print("Error: Not enough money to execute the trade.");
break;
case ERR_INVALID_STOPS:
Print("Error: Invalid stop loss or take profit values.");
break;
case ERR_TRADE_TIMEOUT:
Print("Error: Trade timeout.");
break;
case ERR_TRADE_DISABLED:
Print("Error: Trading is disabled for the symbol.");
break;
default:
Print("Error: Unhandled error code - ", errorCode);
}
}
//+------------------------------------------------------------------+
//| Final Trade Setup and Execution Function |
//+------------------------------------------------------------------+
bool ExecuteTrade(bool isLong, double lotSize, double stopLoss, double takeProfit) {
int ticket;
double price = isLong ? Ask : Bid;
int orderType = isLong ? OP_BUY : OP_SELL;
if (ticket < 0) {
HandleOrderError(GetLastError());
return false;
}
//+------------------------------------------------------------------+
//| Main Execution and Strategy Evaluation Logic |
//+------------------------------------------------------------------+
void OnTick() {
// Check for trading conditions and manage risk
if (AccountEquity() / AccountBalance() < (1 - (MaxDrawdown / 100))) {
Print("Max Drawdown threshold reached. Trading halted.");
return;
}
if (longSetup || shortSetup) {
bool isLong = longSetup;
double stopLoss = CalculateSmartStopLoss(isLong);
double takeProfit = isLong ? Ask + (MathAbs(Ask - stopLoss) * 2) : Bid - (MathAbs(Bid -
stopLoss) * 2);
double lotSize = NormalizeLotSize(CalculateAdaptiveLotSize(MathAbs(Close[0] - stopLoss) /
Point, isLong));