0% found this document useful (0 votes)
16 views12 pages

Short Trading EA with Dynamic Risk Management

The document is a trading algorithm implemented in MQL5, focusing on short trades with a 20-period SMA filter and dynamic risk management. It includes parameters for ATR, trailing stops, and conditions for executing trades based on market volatility and trend strength. The algorithm adjusts risk based on trading sessions and consecutive losses, aiming for a risk-reward ratio of 1:2.

Uploaded by

Alpha Omega
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views12 pages

Short Trading EA with Dynamic Risk Management

The document is a trading algorithm implemented in MQL5, focusing on short trades with a 20-period SMA filter and dynamic risk management. It includes parameters for ATR, trailing stops, and conditions for executing trades based on market volatility and trend strength. The algorithm adjusts risk based on trading sessions and consecutive losses, aiming for a risk-reward ratio of 1:2.

Uploaded by

Alpha Omega
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

//+------------------------------------------------------------------+

//| Try.mq5 |

//| Best-Performing Version (v1.2) |

//| [Focus on Shorts + SMA20 Filter + Dynamic RR] |

//+------------------------------------------------------------------+

#include <Trade/[Link]>

#include <Trade/[Link]>

//+------------------------------------------------------------------+

//| Input Parameters |

//+------------------------------------------------------------------+

input ulong MagicNumber = 12345; // EA Magic Number

input int ATR_Period = 14; // ATR period for volatility

input bool UseTrailingStop = true; // Enable trailing stop

input int MaxSpread = 15; // Max allowed spread (points)

//--- Set 6: High RR Compensation ---

input int FastMAPeriod = 3; // Fast MA period

input int SlowMAPeriod = 9; // Slow MA period

input double RiskPercent = 0.5; // Base risk per trade

input int ADX_Period = 10; // ADX period

input int MinADX = 14; // Minimum ADX threshold

input double ATR_Multiplier = 0.9; // Reduced ATR multiplier for tighter stops

input int TrailStart = 25; // Trailing stop activation (pips)

input int TrailStep = 10; // Trailing stop step (pips)

// Global variables

int fastMAHandle, slowMAHandle, adxHandle, atrHandle, smaHandle;

CTrade trade;

CAccountInfo account;

double dynamicRiskPercent; // Dynamic risk adjustment variable


int consecutiveLosses = 0; // Track consecutive losses

//+------------------------------------------------------------------+

//| Expert initialization function |

//+------------------------------------------------------------------+

int OnInit()

// Initialize indicators

fastMAHandle = iMA(_Symbol, PERIOD_CURRENT, FastMAPeriod, 0, MODE_EMA, PRICE_CLOSE);

slowMAHandle = iMA(_Symbol, PERIOD_CURRENT, SlowMAPeriod, 0, MODE_EMA, PRICE_CLOSE);

adxHandle = iADX(_Symbol, PERIOD_CURRENT, ADX_Period);

atrHandle = iATR(_Symbol, PERIOD_CURRENT, ATR_Period);

smaHandle = iMA(_Symbol, PERIOD_CURRENT, 20, 0, MODE_SMA, PRICE_CLOSE); // 20-period


SMA

if(fastMAHandle == INVALID_HANDLE || slowMAHandle == INVALID_HANDLE ||

adxHandle == INVALID_HANDLE || atrHandle == INVALID_HANDLE || smaHandle ==


INVALID_HANDLE)

Print("Indicator initialization failed!");

return(INIT_FAILED);

[Link](MagicNumber);

[Link]();

[Link](ORDER_FILLING_FOK);

dynamicRiskPercent = RiskPercent; // Initialize dynamic risk

return(INIT_SUCCEEDED);

//+------------------------------------------------------------------+
//| Expert tick function |

//+------------------------------------------------------------------+

void OnTick()

static datetime prevBar;

datetime currentBar = iTime(_Symbol, PERIOD_CURRENT, 0);

if(prevBar == currentBar) return;

prevBar = currentBar;

// Skip trades if volatility > 15 pips

double atrValue[1];

if (CopyBuffer(atrHandle, 0, 0, 1, atrValue) == 1 && atrValue[0] > 15 * _Point * 10)

Print("Volatility too high: ", atrValue[0]);

return;

// Skip trades if volatility < 10 pips

if (CopyBuffer(atrHandle, 0, 0, 1, atrValue) == 1 && atrValue[0] < 10 * _Point * 10)

Print("Low volatility: Skipping trade");

return;

// Adjust risk based on session and consecutive losses

AdjustSessionRisk();

if (consecutiveLosses >= 3) dynamicRiskPercent *= 0.7; // Reduce risk after 3 losses

// Check trading conditions

if(!IsTradingTime() || !IsStrongTrend() || !IsSpreadOK() || !IsTickValueValid()) return;


// Get indicator values

double fastMA[2], slowMA[2];

if(CopyBuffer(fastMAHandle, 0, 0, 2, fastMA) != 2 ||

CopyBuffer(slowMAHandle, 0, 0, 2, slowMA) != 2)

Print("Failed to copy MA values");

return;

// Check crossover (only short trades)

bool sellSignal = (fastMA[0] < slowMA[0]) && (fastMA[1] >= slowMA[1]);

if(sellSignal)

CloseAllPositions();

ExecuteTrade(ORDER_TYPE_SELL);

// Manage open positions

if(UseTrailingStop) CheckTrailingStop();

//+------------------------------------------------------------------+

//| Enhanced trading filters |

//+------------------------------------------------------------------+

bool IsTradingTime()

MqlDateTime timeCurrent;

TimeCurrent(timeCurrent);
// Trade during London + NY overlap (07:00-16:00 GMT)

return ([Link] >= 7 && [Link] < 16);

bool IsStrongTrend()

double adxValue[1], sma20[1];

if (CopyBuffer(adxHandle, 0, 0, 1, adxValue) != 1 ||

CopyBuffer(smaHandle, 0, 0, 1, sma20) != 1) return false;

double closePrice = iClose(_Symbol, PERIOD_CURRENT, 0); // Get current close price

return (adxValue[0] >= MinADX && closePrice < sma20[0]); // ADX + SMA filter

bool IsSpreadOK()

long spread = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);

return spread <= MaxSpread;

bool IsTickValueValid()

double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);

return (tickValue > 0);

//+------------------------------------------------------------------+

//| Dynamic Position Sizing |

//+------------------------------------------------------------------+

double CalculateLotSize()

{
double balance = [Link]();

if(balance <= 0) return 0;

// Volatility adjustment (scale down risk when ATR > average)

double atrCurrent[1], atr30[30];

if (CopyBuffer(atrHandle, 0, 0, 1, atrCurrent) != 1 ||

CopyBuffer(atrHandle, 0, 0, 30, atr30) != 30)

Print("Failed to copy ATR values");

return 0;

double atrRatio = atrCurrent[0] / ArrayAverage(atr30);

double adjustedRisk = dynamicRiskPercent;

// Reduce risk by 50% if volatility is 150%+ of average

if(atrRatio >= 1.5) adjustedRisk *= 0.5;

// 1:1 Leverage Constraint

double contractSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_CONTRACT_SIZE);

double price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);

double maxLeverageLots = balance / (contractSize * price);

// Risk-Based Lots

double stopPoints = CalculateStops();

if (stopPoints <= 0) return 0; // Guard against invalid stops

double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);

double riskLots = (balance * adjustedRisk / 100) / (stopPoints * tickValue);

// Final Lot Size (respect both leverage and risk)


double lots = MathMin(maxLeverageLots, riskLots);

// Apply Broker Constraints

double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);

double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);

double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);

// Normalize to Broker's Lot Step

if (lotStep > 0) {

lots = MathRound(lots / lotStep) * lotStep;

lots = NormalizeDouble(lots, (int)-MathLog10(lotStep)); // Dynamic decimal places

// Clamp to Min/Max

lots = MathMax(lots, minLot);

lots = MathMin(lots, maxLot);

// Final Validation

if (lots < minLot || lots > maxLot) {

Print("Invalid lot size: ", lots, " (Min: ", minLot, ", Max: ", maxLot, ")");

return 0;

return lots;

//+------------------------------------------------------------------+

//| Execute Trade with Dynamic RR |

//+------------------------------------------------------------------+

void ExecuteTrade(ENUM_ORDER_TYPE orderType)

{
double lotSize = CalculateLotSize();

if(lotSize <= 0) return;

double price = orderType == ORDER_TYPE_BUY ?

SymbolInfoDouble(_Symbol, SYMBOL_ASK) :

SymbolInfoDouble(_Symbol, SYMBOL_BID);

double stopLoss = CalculateStops();

double takeProfit = stopLoss * 2.0; // RR = 1:2

if(orderType == ORDER_TYPE_BUY)

stopLoss = NormalizeDouble(price - stopLoss, _Digits);

takeProfit = NormalizeDouble(price + takeProfit, _Digits);

else

stopLoss = NormalizeDouble(price + stopLoss, _Digits);

takeProfit = NormalizeDouble(price - takeProfit, _Digits);

// Validate stops

if(stopLoss <= 0 || takeProfit <= 0)

Print("Invalid stop levels: SL=", stopLoss, ", TP=", takeProfit);

return;

// Execute trade

[Link](ORDER_FILLING_IOC);

if(![Link](_Symbol, orderType, lotSize, price, stopLoss, takeProfit))


{

Print("Trade execution failed: ", [Link]());

consecutiveLosses++; // Increment consecutive losses

else

Print("Trade executed: ", EnumToString(orderType), " ", lotSize, " lots at ", price,

" SL=", stopLoss, " TP=", takeProfit);

consecutiveLosses = 0; // Reset consecutive losses

//+------------------------------------------------------------------+

//| Helper Functions |

//+------------------------------------------------------------------+

double ArrayAverage(double &arr[])

double sum = 0;

for(int i=0; i<ArraySize(arr); i++) sum += arr[i];

return sum / ArraySize(arr);

double CalculateStops()

double atrBuffer[1];

if (CopyBuffer(atrHandle, 0, 0, 1, atrBuffer) != 1) return 0;

return MathMax(atrBuffer[0] * ATR_Multiplier, 15 * _Point * 10); // Min 15 pips

void CloseAllPositions()

{
for(int i = PositionsTotal()-1; i >= 0; i--)

ulong ticket = PositionGetTicket(i);

if(ticket > 0 && PositionSelectByTicket(ticket))

if(PositionGetString(POSITION_SYMBOL) == _Symbol &&

PositionGetInteger(POSITION_MAGIC) == MagicNumber)

[Link](ticket);

void CheckTrailingStop()

for(int i = PositionsTotal()-1; i >= 0; i--)

ulong ticket = PositionGetTicket(i);

if(PositionSelectByTicket(ticket))

double currentSl = PositionGetDouble(POSITION_SL);

double priceOpen = PositionGetDouble(POSITION_PRICE_OPEN);

double currentPrice = PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY ?

SymbolInfoDouble(_Symbol, SYMBOL_BID) :

SymbolInfoDouble(_Symbol, SYMBOL_ASK);

double newSl = currentSl;

if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)

if(currentPrice - priceOpen >= TrailStart * _Point)


{

newSl = currentPrice - TrailStep * _Point;

newSl = MathMax(newSl, currentSl);

else

if(priceOpen - currentPrice >= TrailStart * _Point)

newSl = currentPrice + TrailStep * _Point;

newSl = MathMin(newSl, currentSl);

if(newSl != currentSl)

[Link](ticket, newSl, PositionGetDouble(POSITION_TP));

//+------------------------------------------------------------------+

//| Session-Specific Risk Adjustment |

//+------------------------------------------------------------------+

void AdjustSessionRisk()

MqlDateTime timeCurrent;

TimeCurrent(timeCurrent);

// London/NY overlap (07:00-16:00 GMT): Max risk


if([Link] >= 7 && [Link] < 16) {

dynamicRiskPercent = 1.0; // Full risk

// Asian session: Reduced risk

else if([Link] >= 22 || [Link] < 5) {

dynamicRiskPercent = 0.3; // Reduced risk

// Other times: Base risk

else {

dynamicRiskPercent = 0.5; // Base risk

//+------------------------------------------------------------------+

You might also like