0% found this document useful (0 votes)
26 views5 pages

DBDRBR

Uploaded by

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

DBDRBR

Uploaded by

kanchanbd
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 5

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

//| DBD_RBR.mq5 |
//| Copyright 2024, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.01"
#property description "DBD/RBR Pattern Trading Strategy"

input int SwingPeriod = 5; // Swing detection period


input double MinSwingPct = 0.1; // Min swing size (% of price)
input int TradeDistance = 50; // Min distance from swing (points)
input double RiskPercent = 1.0; // Risk per trade (%)
input double RewardRatio = 2.0; // Reward/Risk ratio

// Global variables
double swingHighs[], swingLows[];
datetime lastTradeTime = 0;

//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
ArraySetAsSeries(swingHighs, true);
ArraySetAsSeries(swingLows, true);
return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
if(!NewBar()) return;

UpdateSwingPoints();
CheckPatterns();
}
//+------------------------------------------------------------------+
//| Detect new bar formation |
//+------------------------------------------------------------------+
bool NewBar()
{
static datetime prevTime;
if(prevTime != iTime(_Symbol, _Period, 0)) {
prevTime = iTime(_Symbol, _Period, 0);
return true;
}
return false;
}

//+------------------------------------------------------------------+
//| Update swing high/low points |
//+------------------------------------------------------------------+
void UpdateSwingPoints()
{
int bars = Bars(_Symbol, _Period);
if(bars < SwingPeriod*3) return;

ArrayResize(swingHighs, bars);
ArrayResize(swingLows, bars);
ArrayInitialize(swingHighs, 0.0);
ArrayInitialize(swingLows, 0.0);

// Find swing points


for(int i = SwingPeriod; i < bars - SwingPeriod; i++) {
if(IsSwingHigh(i)) {
swingHighs[i] = iHigh(_Symbol, _Period, i);
}
if(IsSwingLow(i)) {
swingLows[i] = iLow(_Symbol, _Period, i);
}
}
}

//+------------------------------------------------------------------+
//| Check if bar is a swing high |
//+------------------------------------------------------------------+
bool IsSwingHigh(int index)
{
for(int i = 1; i <= SwingPeriod; i++) {
if(iHigh(_Symbol, _Period, index) < iHigh(_Symbol, _Period, index-i) ||
iHigh(_Symbol, _Period, index) < iHigh(_Symbol, _Period, index+i))
return false;
}
return true;
}

//+------------------------------------------------------------------+
//| Check if bar is a swing low |
//+------------------------------------------------------------------+
bool IsSwingLow(int index)
{
for(int i = 1; i <= SwingPeriod; i++) {
if(iLow(_Symbol, _Period, index) > iLow(_Symbol, _Period, index-i) ||
iLow(_Symbol, _Period, index) > iLow(_Symbol, _Period, index+i))
return false;
}
return true;
}

//+------------------------------------------------------------------+
//| Check for DBD/RBR patterns |
//+------------------------------------------------------------------+
void CheckPatterns()
{
int bar = 1;
double minSwing = SymbolInfoDouble(_Symbol, SYMBOL_ASK) * MinSwingPct / 100;
double minDistance = TradeDistance * SymbolInfoDouble(_Symbol, SYMBOL_POINT);

// Find recent swing points


int highIdx = -1, lowIdx = -1;
for(int i = bar; i < ArraySize(swingHighs); i++) {
if(swingHighs[i] > 0) highIdx = i;
if(swingLows[i] > 0) lowIdx = i;
if(highIdx > 0 && lowIdx > 0) break;
}

if(highIdx < 0 || lowIdx < 0) return;

// Check Rally Base Rally (RBR) pattern


if(highIdx > lowIdx) {
double baseLow = swingLows[lowIdx];
double rallyHigh = swingHighs[highIdx];
double rallySize = rallyHigh - baseLow;

if(rallySize > minSwing) {


double currentClose = iClose(_Symbol, _Period, bar);

if(currentClose > rallyHigh + minDistance) {


double entry = NormalizeDouble(rallyHigh + minDistance, _Digits);
double sl = NormalizeDouble(baseLow, _Digits);
double tp = NormalizeDouble(entry + (rallySize * RewardRatio),
_Digits);

// Calculate stop level in price terms


double stopLevel = SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL)
* SymbolInfoDouble(_Symbol, SYMBOL_POINT);

if(entry - sl > stopLevel) {


OpenTrade(ORDER_TYPE_BUY, entry, sl, tp);
}
}
}
}

// Check Drop Base Drop (DBD) pattern


else if(lowIdx > highIdx) {
double baseHigh = swingHighs[highIdx];
double dropLow = swingLows[lowIdx];
double dropSize = baseHigh - dropLow;

if(dropSize > minSwing) {


double currentClose = iClose(_Symbol, _Period, bar);

if(currentClose < dropLow - minDistance) {


double entry = NormalizeDouble(dropLow - minDistance, _Digits);
double sl = NormalizeDouble(baseHigh, _Digits);
double tp = NormalizeDouble(entry - (dropSize * RewardRatio), _Digits);

// Calculate stop level in price terms


double stopLevel = SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL)
* SymbolInfoDouble(_Symbol, SYMBOL_POINT);

if(sl - entry > stopLevel) {


OpenTrade(ORDER_TYPE_SELL, entry, sl, tp);
}
}
}
}
}

//+------------------------------------------------------------------+
//| Execute trade with risk management |
//+------------------------------------------------------------------+
void OpenTrade(ENUM_ORDER_TYPE type, double entry, double sl, double tp)
{
if(iTime(_Symbol, _Period, 0) == lastTradeTime) return;

double balance = AccountInfoDouble(ACCOUNT_BALANCE);


double riskAmount = balance * RiskPercent / 100;
double pointValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE) /
SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);

double riskPoints = MathAbs(entry - sl) / SymbolInfoDouble(_Symbol,


SYMBOL_POINT);
double lotSize = NormalizeDouble(riskAmount / (riskPoints * pointValue), 2);

if(lotSize < SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN))


lotSize = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
if(lotSize > SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX))
lotSize = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);

MqlTradeRequest request;
ZeroMemory(request);
MqlTradeResult result;
ZeroMemory(result);

request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = lotSize;
request.type = type;
request.price = entry;
request.sl = sl;
request.tp = tp;
request.deviation = 10;
request.type_filling = ORDER_FILLING_FOK;

OrderSend(request, result);

if(result.retcode == TRADE_RETCODE_DONE) {
lastTradeTime = iTime(_Symbol, _Period, 0);
}
else {
Print("Trade error: ", GetRetcodeID(result.retcode));
}
}

//+------------------------------------------------------------------+
//| Get error message from return code |
//+------------------------------------------------------------------+
string GetRetcodeID(int retCode)
{
switch(retCode)
{
case 10004: return "TRADE_RETCODE_REQUOTE";
case 10006: return "TRADE_RETCODE_REJECT";
case 10007: return "TRADE_RETCODE_CANCEL";
case 10008: return "TRADE_RETCODE_PLACED";
case 10009: return "TRADE_RETCODE_DONE";
case 10010: return "TRADE_RETCODE_DONE_PARTIAL";
case 10011: return "TRADE_RETCODE_ERROR";
case 10012: return "TRADE_RETCODE_TIMEOUT";
case 10013: return "TRADE_RETCODE_INVALID";
case 10014: return "TRADE_RETCODE_INVALID_VOLUME";
case 10015: return "TRADE_RETCODE_INVALID_PRICE";
case 10016: return "TRADE_RETCODE_INVALID_STOPS";
case 10017: return "TRADE_RETCODE_TRADE_DISABLED";
case 10018: return "TRADE_RETCODE_MARKET_CLOSED";
case 10019: return "TRADE_RETCODE_NO_MONEY";
case 10020: return "TRADE_RETCODE_PRICE_CHANGED";
case 10021: return "TRADE_RETCODE_PRICE_OFF";
case 10022: return "TRADE_RETCODE_INVALID_EXPIRATION";
case 10023: return "TRADE_RETCODE_ORDER_CHANGED";
case 10024: return "TRADE_RETCODE_TOO_MANY_REQUESTS";
case 10025: return "TRADE_RETCODE_NO_CHANGES";
case 10026: return "TRADE_RETCODE_SERVER_DISABLES_AT";
case 10027: return "TRADE_RETCODE_CLIENT_DISABLES_AT";
case 10028: return "TRADE_RETCODE_LOCKED";
case 10029: return "TRADE_RETCODE_FROZEN";
case 10030: return "TRADE_RETCODE_INVALID_FILL";
case 10031: return "TRADE_RETCODE_CONNECTION";
case 10032: return "TRADE_RETCODE_ONLY_REAL";
case 10033: return "TRADE_RETCODE_LIMIT_ORDERS";
case 10034: return "TRADE_RETCODE_LIMIT_VOLUME";
default: return "UNKNOWN_ERROR";
}
}
//+------------------------------------------------------------------+

You might also like