peg it to an hourly chart.
One thing should normally not happen: an upside fractal should not have a 7-sample MFI read below 54.
This places a pending order 2 pips beyond the fractal and targets the Volatility Breakout level plus 5 pips, with the missing hedge, plus 20% extra.

To test it, I run it for the last fractal without MFI. Here’s the result:
// Morbid MFI Overhedger by Macdulio for Automated Trading
#include <stdlib.mqh>
extern int percentage = 20;
extern int magic_number = 87;
extern int magic_number2 = 88;
extern int magic_number3 = 89;
extern double Ratio = 0.6;
#property copyright "by Macdulio in 2025"
#property link "https://forexfore.blog"
#property description "Morbid MFI Overhedger"
int profits;
double nakedshorts[];
double nakedlongs[];
double open_price;
double stop_loss_price;
double take_profit_price;
double open_price2;
double stop_loss_price2;
double take_profit_price2;
double RSI2[];
double ATRAVG[];
double OrderOpenPrice;
double OrderProfit;
double ExtUpperBuffer[], mfi[];
double ExtLowerBuffer[];
double ExtUpperBuffer_[],ExtLowerBuffer_[];
double ExtUpperBuffer_d[],ExtLowerBuffer_d[];
double ExtMapBuffer[];
double ufractals[],dfractals[];
string symbol = Symbol();
int init() {
return(0);
}
int deinit() {
return(0);
}
int start() {
ArrayResize(ATRAVG, Bars);
ArrayInitialize(ATRAVG, 0);
ArrayResize(RSI2, 600);
ArrayInitialize(RSI2, 0);
ArrayResize(ExtMapBuffer, Bars);
ArrayInitialize(ExtMapBuffer,EMPTY_VALUE);
ArrayResize(ExtUpperBuffer, Bars);
ArrayInitialize(ExtUpperBuffer,EMPTY_VALUE);
ArrayResize(ExtLowerBuffer, Bars);
ArrayInitialize(ExtLowerBuffer, EMPTY_VALUE);
ArrayResize(ExtUpperBuffer_, Bars);
ArrayInitialize(ExtUpperBuffer_,EMPTY_VALUE);
ArrayResize(ExtLowerBuffer_, Bars);
ArrayInitialize(ExtLowerBuffer_, EMPTY_VALUE);
ArrayResize(ExtUpperBuffer_d, Bars);
ArrayInitialize(ExtUpperBuffer_d,EMPTY_VALUE);
ArrayResize(ExtLowerBuffer_d, Bars);
ArrayInitialize(ExtLowerBuffer_d, EMPTY_VALUE);
ArrayResize(ufractals, Bars);
ArrayInitialize(ufractals, EMPTY_VALUE);
ArrayResize(dfractals, Bars);
ArrayInitialize(dfractals, EMPTY_VALUE);
ArrayResize(mfi, 600);
ArrayInitialize(mfi, 0);
int i, counter;
int counted_bars=IndicatorCounted();
int longcount, shortcount;
double nlongs;
double nshorts;
double longsize = 0;
double shortsize = 0;
double longaveragebuffer;
double shortaveragebuffer;
double buylevel=1000;
double sellevel=0;
double weight;
int order_type;
profits = 0;
int hstTotal=OrdersHistoryTotal();
counter = 0;
double ATRA = 0;
for (i=1; i<=3; i++){
ATRA = ATRA+iATR(NULL,1440,14,i);}
for (i=0; i<=160; i++){
ATRAVG[i] = ATRA/3; }
i=0;
while (i<200){
if (ChoppinessIndex(12*4,i)>53 && ChoppinessIndex(12*4,i+1)<53) break;
i++;
}
if (i<200) weight=iClose(symbol,15,i);
// Print("Ratio = ", Ratio);
for(i=100; i>=0; i--){
if (iFractals(symbol,60,MODE_UPPER,i)) ufractals[i]=iHigh(symbol,60,i);
else ufractals[i]=ufractals[i+1];
if (iFractals(symbol,60,MODE_LOWER,i)) dfractals[i]=iLow(symbol,60,i);
else dfractals[i]=dfractals[i+1];
RSI2[i]=iRSI(symbol,60,2,PRICE_MEDIAN,i);
mfi[i]=iMFI(symbol,60,7,i);
ExtUpperBuffer[i]=iLow(symbol,0,iLowest(symbol,0,MODE_LOW,12,i))+460*Point;
ExtLowerBuffer[i]=iHigh(symbol,0,iHighest(symbol,0,MODE_HIGH,12,i))-460*Point;
if (ExtUpperBuffer[i]>ExtLowerBuffer[i]) {ExtUpperBuffer_[i]=ExtUpperBuffer[i]; ExtLowerBuffer_[i]=ExtLowerBuffer[i];
ExtUpperBuffer_d[i]=ExtUpperBuffer_[i]+450*Point; ExtLowerBuffer_d[i]=ExtLowerBuffer_[i]-450*Point;
}
}
for(i=OrdersTotal()-1; i>=0 ; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)
{
Print("Access to orders list failed with error (",GetLastError(),")");
break;
}
// if ( Symbol()=="EURUSD" && OrderStopLoss()==0 ) {
// Print("OderProfit: ", OrderProfit());
//Print("AB:",AccountBalance()*-1*.025);
if (OrderType() == OP_BUY)
{
nlongs = nlongs+OrderLots();
longcount = longcount+1;
longaveragebuffer = longaveragebuffer+(OrderOpenPrice()*OrderLots());
}
if (OrderType() == OP_SELL )
{
nshorts = nshorts+OrderLots();
shortcount = shortcount+1;
shortaveragebuffer = shortaveragebuffer+(OrderOpenPrice()*OrderLots());
}
// }
}
if (nlongs!=nshorts){
double comparison = (AccountEquity()/AccountBalance())*100;
// Print("comparison = ", comparison);
i=1;
while (i<21){
if (iFractals(symbol,60,MODE_UPPER,i) && mfi[i]<54 && High[i]>ufractals[i+1]) break;
// && mfi[i]<54
i++;
}
if (iFractals(symbol,60,MODE_UPPER,i) && mfi[i]<54 && High[i]>ufractals[i+1]) buylevel = High[i]+20*Point;
longsize = (nshorts-nlongs)*(100+percentage)/100;
// Overghedge for shorts
if (nlongs<nshorts && buylevel!=1000 && i<21) {
// if (comparison<Ratio) RemoveStopsandTargets();
open_price2 = NormalizeDouble(buylevel, Digits);
stop_loss_price2 = NormalizeDouble(0,Digits);
take_profit_price2 = NormalizeDouble(weight+1010*Point,Digits);
for (i = OrdersTotal() - 1; i >= 0; i--)
if (OrderSelect(i, SELECT_BY_POS))
if (OrderMagicNumber() == magic_number2) {
order_type = OrderType();
if (order_type == ORDER_TYPE_BUY_STOP) {
if ((NormalizeDouble(OrderOpenPrice(), Digits) != open_price2) || (NormalizeDouble(OrderStopLoss(), Digits) != stop_loss_price2) || (NormalizeDouble(OrderTakeProfit(), Digits) != take_profit_price2)) {
if (!OrderModify(OrderTicket(), open_price2, stop_loss_price2, take_profit_price2, OrderExpiration()))
Print("Error: ", ErrorDescription(_LastError));
}
break;
}
else if (order_type == ORDER_TYPE_BUY)
break;
}
if (i < 0)
if (OrderSend(symbol, OP_BUYSTOP, NormalizeDouble(longsize,2), open_price2, 3, stop_loss_price2, take_profit_price2, magic_number2+" Morbid MFI Overhedger BUY STOP", magic_number2) < 0)
Print("Error: ", ErrorDescription(_LastError));
}
else
for (i = OrdersTotal() - 1; i >= 0; i--)
if (OrderSelect(i, SELECT_BY_POS))
if (OrderMagicNumber() == magic_number2 )
if (OrderType() == ORDER_TYPE_BUY_STOP)
if (!OrderDelete(OrderTicket()))
Print("Error: ", ErrorDescription(_LastError));
i=1;
while (i<21){
if (iFractals(symbol,60,MODE_LOWER,i) && mfi[i]>46 && Low[i]<dfractals[i+1]) break;
i++;
}
if (iFractals(symbol,60,MODE_LOWER,i) && mfi[i]>46 && Low[i]<dfractals[i+1]) sellevel = Low[i]-20*Point;
shortsize = (nlongs-nshorts)*(100+percentage)/100;
// Overhedge For Longs
if (nshorts<nlongs && sellevel!=0 && i<21 ) {
// if (comparison<Ratio) RemoveStopsandTargets();
open_price2 = NormalizeDouble(sellevel, Digits);
stop_loss_price2 = NormalizeDouble(0,Digits);
take_profit_price2 = NormalizeDouble(weight-1010*Point,Digits);
for (i = OrdersTotal() - 1; i >= 0; i--)
if (OrderSelect(i, SELECT_BY_POS))
if (OrderMagicNumber() == magic_number2) {
order_type = OrderType();
if (order_type == ORDER_TYPE_SELL_STOP) {
if ((NormalizeDouble(OrderOpenPrice(), Digits) != open_price2) || (NormalizeDouble(OrderStopLoss(), Digits) != stop_loss_price2) || (NormalizeDouble(OrderTakeProfit(), Digits) != take_profit_price2)) {
if (!OrderModify(OrderTicket(), open_price2, stop_loss_price2, take_profit_price2, OrderExpiration()))
Print("Error: ", ErrorDescription(_LastError));
}
break;
}
else if (order_type == ORDER_TYPE_SELL)
break;
}
if (i < 0)
if (OrderSend(symbol, OP_SELLSTOP, NormalizeDouble(shortsize,2), open_price2, 3, stop_loss_price2, take_profit_price2, magic_number2+" Morbid MFI Overhedger SELL STOP", magic_number2) < 0)
Print("Error: ", ErrorDescription(_LastError));
}
else
for (i = OrdersTotal() - 1; i >= 0; i--)
if (OrderSelect(i, SELECT_BY_POS))
if (OrderMagicNumber() == magic_number2)
if (OrderType() == ORDER_TYPE_SELL_STOP)
if (!OrderDelete(OrderTicket()))
Print("Error: ", ErrorDescription(_LastError));
return(0);
}
}
double RemoveStopsandTargets()
{
int i;
for (i = OrdersTotal() - 1; i >= 0; i--){
if( OrderSelect(i,SELECT_BY_POS, MODE_TRADES))
if( OrderType()==OP_BUYSTOP && MathAbs(OrderOpenPrice()-Ask)<.003)
OrderDelete( OrderTicket() );
else if( OrderType()==OP_SELLSTOP && MathAbs(OrderOpenPrice()-Bid)<.003)
OrderDelete(OrderTicket());}
return(0);
}
double ChoppinessIndex(int period, int bar)
{
double Low0 = 0, High0 = 0, Close1 = 0;
double TrueRangeLow = 0, TrueRangeHigh = 0, TrueRangeSum = 0, Input = 0;
double PeriodTrueRangeLow = 999999999, PeriodTrueRangeHigh = 0, PeriodTrueRange = 0;
for(int k=bar; k<bar+period; k++)
{
Low0 = iLow(NULL,15,k);
High0 = iHigh(NULL,15,k);
Close1 = iClose(NULL,15,k+1);
if (Low0<Close1) TrueRangeLow = Low0; else TrueRangeLow = Close1;
if (High0>Close1) TrueRangeHigh = High0; else TrueRangeHigh = Close1;
if (TrueRangeLow <PeriodTrueRangeLow) PeriodTrueRangeLow = TrueRangeLow; // find true low of period
if (TrueRangeHigh>PeriodTrueRangeHigh) PeriodTrueRangeHigh = TrueRangeHigh; // find true high of period
TrueRangeSum += TrueRangeHigh;
TrueRangeSum -= TrueRangeLow;
}
PeriodTrueRange = PeriodTrueRangeHigh - PeriodTrueRangeLow;
if (PeriodTrueRange==0) PeriodTrueRange = MathPow(10, -12); // avoid possibility of division by zero
Input = TrueRangeSum / PeriodTrueRange;
return ((logN(Input, 10, MathPow(10, -12)) / logN(period, 10, MathPow(10, -12))) * 100);
}
double logN(double x, double base, double epsilon)
{
double integer = 0.0;
if ((x < 1) || (base < 1)) return(0);
while (x < 1)
{
integer -= 1;
x *= base;
}
while (x >= base)
{
integer += 1;
x /= base;
}
double partial = 0.5;
x *= x;
double decimal = 0.0;
while (partial > epsilon)
{
if (x >= base)
{
decimal += partial;
x = x / base;
}
partial *= 0.5;
x *= x;
}
return (integer + decimal);
}
double StdDev(int shift, int samples)
{
double x0=0, x1=0, x2=0;
for (int m=0; m<samples; m++)
{
x0 = ExtMapBuffer[m+shift];
x1 += x0;
x2 += MathPow(x0,2);
}
return(MathSqrt((x2-(x1*x1/samples))/(samples-1))); // minimum samples is 2, enforced in the init section
}
Here’s a gray divergence…
