4kk4.MQL5/Indicators/SND_RBR_DBD.mq5
clarissya 2394964283 Scripts
2026-04-27 07:14:01 +07:00

176 行
无行尾
7.1 KiB
MQL5

//+------------------------------------------------------------------+
//| SND_RBR_DBD.mq5 |
//| Assistant AI - Gemini |
//+------------------------------------------------------------------+
#property copyright "Assistant AI"
#property link ""
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots 0
//--- Input Parameters
input string Deskripsi_Kriteria = "=== Kriteria Pola ===";
input double InpImbalancePips = 10.0; // Minimal Body Imbalance (Pips)
input double InpBaseMaxBodyRatio = 0.4; // Maksimal Rasio Body/Range pada Base
input string Deskripsi_Warna = "=== Pengaturan Warna ===";
input color InpColorRBRFresh = clrDodgerBlue; // RBR Fresh Zone
input color InpColorRBRTested = clrDarkBlue; // RBR Tested Zone
input color InpColorDBDFresh = clrRed; // DBD Fresh Zone
input color InpColorDBDTested = clrDarkRed; // DBD Tested Zone
// Global variables
double point_size;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Menyesuaikan ukuran pip untuk broker 3/5 digit
if(Digits() == 5 || Digits() == 3) point_size = Point() * 10;
else point_size = Point();
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// Menghapus semua kotak yang digambar oleh indikator ini saat dihapus
ObjectsDeleteAll(0, "SND_ZONE_");
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
if(rates_total < 4) return(0);
// Mengatur array sebagai timeseries (index 0 adalah candle terbaru)
ArraySetAsSeries(time, true);
ArraySetAsSeries(open, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(close, true);
int limit = rates_total - prev_calculated;
if(limit > rates_total - 4) limit = rates_total - 4;
// Loop untuk mencari pola RBR dan DBD
for(int i = limit; i >= 1; i--)
{
// Kita menggunakan pola 3 candle:
// Candle 3 (index i+2): Gerakan awal (Rally/Drop)
// Candle 2 (index i+1): Konsolidasi (Base)
// Candle 1 (index i) : Gerakan Imbalance (Rally/Drop)
double c3_open = open[i+2], c3_close = close[i+2], c3_high = high[i+2], c3_low = low[i+2];
double c2_open = open[i+1], c2_close = close[i+1], c2_high = high[i+1], c2_low = low[i+1];
double c1_open = open[i], c1_close = close[i], c1_high = high[i], c1_low = low[i];
// Kalkulasi ukuran
double c3_body = MathAbs(c3_close - c3_open) / point_size;
double c2_body = MathAbs(c2_close - c2_open);
double c2_range = c2_high - c2_low;
double c1_body = MathAbs(c1_close - c1_open) / point_size;
bool is_c2_base = (c2_range > 0) ? (c2_body / c2_range <= InpBaseMaxBodyRatio) : false;
bool is_c3_imbalance = c3_body >= InpImbalancePips;
bool is_c1_imbalance = c1_body >= InpImbalancePips;
// --- Deteksi RBR (Rally - Base - Rally) ---
if(c3_close > c3_open && is_c3_imbalance && // Rally 1
is_c2_base && // Base
c1_close > c1_open && is_c1_imbalance) // Rally 2 (Imbalance)
{
DrawZone(time[i+1], time[0], c2_high, c2_low, 1, i, high, low, time);
}
// --- Deteksi DBD (Drop - Base - Drop) ---
if(c3_close < c3_open && is_c3_imbalance && // Drop 1
is_c2_base && // Base
c1_close < c1_open && is_c1_imbalance) // Drop 2 (Imbalance)
{
DrawZone(time[i+1], time[0], c2_high, c2_low, -1, i, high, low, time);
}
}
return(rates_total);
}
//+------------------------------------------------------------------+
//| Fungsi untuk Menggambar dan Mengecek Zone |
//+------------------------------------------------------------------+
void DrawZone(datetime time_start, datetime time_end, double base_high, double base_low, int type, int current_index, const double &high[], const double &low[], const datetime &time[])
{
string obj_name = "SND_ZONE_" + TimeToString(time_start);
// Mengecek apakah area ini sudah disentuh oleh harga setelahnya (Tested Zone)
bool is_tested = false;
datetime tested_time = time_end;
// Loop dari candle setelah imbalance sampai candle terbaru untuk mencari sentuhan
for(int j = current_index - 1; j >= 0; j--)
{
if(type == 1) // RBR
{
// Jika harga terendah candle ke-j masuk atau menembus base
if(low[j] <= base_high)
{
is_tested = true;
tested_time = time[j];
break;
}
}
else if(type == -1) // DBD
{
// Jika harga tertinggi candle ke-j masuk atau menembus base
if(high[j] >= base_low)
{
is_tested = true;
tested_time = time[j];
break;
}
}
}
// Menentukan warna berdasarkan tipe dan status (Fresh/Tested)
color zone_color;
if(type == 1) zone_color = is_tested ? InpColorRBRTested : InpColorRBRFresh;
else zone_color = is_tested ? InpColorDBDTested : InpColorDBDFresh;
// Jika zone sudah tested, hentikan gambar di candle tempat terjadinya sentuhan
datetime draw_end_time = is_tested ? tested_time : time[0] + PeriodSeconds() * 10;
// Membuat Rectangle di Chart
if(ObjectFind(0, obj_name) < 0)
{
ObjectCreate(0, obj_name, OBJ_RECTANGLE, 0, time_start, base_high, draw_end_time, base_low);
ObjectSetInteger(0, obj_name, OBJPROP_COLOR, zone_color);
ObjectSetInteger(0, obj_name, OBJPROP_FILL, true);
ObjectSetInteger(0, obj_name, OBJPROP_BACK, true);
// Agar kotak tidak bisa di-klik sembarangan oleh user
ObjectSetInteger(0, obj_name, OBJPROP_SELECTABLE, false);
ObjectSetInteger(0, obj_name, OBJPROP_HIDDEN, true);
}
else
{
// Update Rectangle jika sudah ada (terutama untuk menggeser time_end jika masih fresh)
ObjectSetInteger(0, obj_name, OBJPROP_TIME, 1, draw_end_time);
ObjectSetInteger(0, obj_name, OBJPROP_COLOR, zone_color);
}
}
//+------------------------------------------------------------------+