4kk4.MQL5/Indicators/KG Standard Deviation Level V.1.1.mq5

250 lines
23 KiB
MQL5
Raw Permalink Normal View History

2026-04-27 07:14:01 +07:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| KG Standard Deviation Level V.1.1.mq5 |
//| Copyright <EFBFBD> 2024, Dibuat oleh Asisten AI Gemini |
//| Modifikasi dari konsep umum |
//+------------------------------------------------------------------+
#property copyright "Copyright <00> 2024, Asisten AI Gemini"
#property link ""
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 9 // Pivot + 4x2 Level SD
#property indicator_plots 9
//--- Input Parameter
input ENUM_TIMEFRAMES myPeriod = PERIOD_D1; // Multiplier Deviasi Standar Level 1
input double SD_Mult1 = 0.5; // Deviasi Standar Level 1
input double SD_Mult2 = 1.0; // Deviasi Standar Level 2
input double SD_Mult3 = 1.5; // Deviasi Standar Level 3
input double SD_Mult4 = 2.0; // Deviasi Standar Level 4
//--- Plot Properti untuk Pivot Point
#property indicator_label1 "Pivot Point"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrLime
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//--- Plot Properti untuk Level Deviasi Atas (Upper)
#property indicator_label2 "Pivot +SD1"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrGreen
#property indicator_style2 STYLE_DOT
#property indicator_width2 1
#property indicator_label3 "Pivot -SD1"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrGreen
#property indicator_style3 STYLE_DOT
#property indicator_width3 1
#property indicator_label4 "Pivot +SD2"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrLimeGreen
#property indicator_style4 STYLE_DOT
#property indicator_width4 1
#property indicator_label5 "Pivot -SD2"
#property indicator_type5 DRAW_LINE
#property indicator_color5 clrLimeGreen
#property indicator_style5 STYLE_DOT
#property indicator_width5 1
#property indicator_label6 "Pivot +SD3"
#property indicator_type6 DRAW_LINE
#property indicator_color6 clrSeaGreen
#property indicator_style6 STYLE_DOT
#property indicator_width6 1
#property indicator_label7 "Pivot -SD3"
#property indicator_type7 DRAW_LINE
#property indicator_color7 clrSeaGreen
#property indicator_style7 STYLE_DOT
#property indicator_width7 1
#property indicator_label8 "Pivot +SD4"
#property indicator_type8 DRAW_LINE
#property indicator_color8 clrDarkGreen
#property indicator_style8 STYLE_DOT
#property indicator_width8 1
#property indicator_label9 "Pivot -SD4"
#property indicator_type9 DRAW_LINE
#property indicator_color9 clrDarkGreen
#property indicator_style9 STYLE_DOT
#property indicator_width9 1
//--- Buffers Indikator
double PivotBuffer[];
double UpperSD1Buffer[];
double LowerSD1Buffer[];
double UpperSD2Buffer[];
double LowerSD2Buffer[];
double UpperSD3Buffer[];
double LowerSD3Buffer[];
double UpperSD4Buffer[];
double LowerSD4Buffer[];
//+------------------------------------------------------------------+
//| Fungsi inisialisasi indikator kustom |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0, PivotBuffer, INDICATOR_DATA); PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetString(0, PLOT_LABEL, "Pivot Point");
SetIndexBuffer(1, UpperSD1Buffer, INDICATOR_DATA); PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetString(1, PLOT_LABEL, "Pivot +" + DoubleToString(SD_Mult1,1) + " SD");
SetIndexBuffer(2, LowerSD1Buffer, INDICATOR_DATA); PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetString(2, PLOT_LABEL, "Pivot -" + DoubleToString(SD_Mult1,1) + " SD");
SetIndexBuffer(3, UpperSD2Buffer, INDICATOR_DATA); PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetString(3, PLOT_LABEL, "Pivot +" + DoubleToString(SD_Mult2,1) + " SD");
SetIndexBuffer(4, LowerSD2Buffer, INDICATOR_DATA); PlotIndexSetDouble(4, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetString(4, PLOT_LABEL, "Pivot -" + DoubleToString(SD_Mult2,1) + " SD");
SetIndexBuffer(5, UpperSD3Buffer, INDICATOR_DATA); PlotIndexSetDouble(5, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetString(5, PLOT_LABEL, "Pivot +" + DoubleToString(SD_Mult3,1) + " SD");
SetIndexBuffer(6, LowerSD3Buffer, INDICATOR_DATA); PlotIndexSetDouble(6, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetString(6, PLOT_LABEL, "Pivot -" + DoubleToString(SD_Mult3,1) + " SD");
SetIndexBuffer(7, UpperSD4Buffer, INDICATOR_DATA); PlotIndexSetDouble(7, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetString(7, PLOT_LABEL, "Pivot +" + DoubleToString(SD_Mult4,1) + " SD");
SetIndexBuffer(8, LowerSD4Buffer, INDICATOR_DATA); PlotIndexSetDouble(8, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetString(8, PLOT_LABEL, "Pivot -" + DoubleToString(SD_Mult4,1) + " SD");
IndicatorSetString(INDICATOR_SHORTNAME, "PivotDev(" + DoubleToString(SD_Mult1,1) + "," + DoubleToString(SD_Mult4,1) + ")");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Fungsi deinisialisasi indikator |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Comment(""); // Membersihkan komentar saat indikator dihapus
}
//+------------------------------------------------------------------+
//| Fungsi perhitungan indikator kustom |
//+------------------------------------------------------------------+
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[])
{
int start_idx;
if(prev_calculated == 0) // Perhitungan pertama
{
// Inisialisasi semua buffer dengan EMPTY_VALUE
ArrayInitialize(PivotBuffer, EMPTY_VALUE); ArrayInitialize(UpperSD1Buffer, EMPTY_VALUE);
ArrayInitialize(LowerSD1Buffer, EMPTY_VALUE); ArrayInitialize(UpperSD2Buffer, EMPTY_VALUE);
ArrayInitialize(LowerSD2Buffer, EMPTY_VALUE); ArrayInitialize(UpperSD3Buffer, EMPTY_VALUE);
ArrayInitialize(LowerSD3Buffer, EMPTY_VALUE); ArrayInitialize(UpperSD4Buffer, EMPTY_VALUE);
ArrayInitialize(LowerSD4Buffer, EMPTY_VALUE);
start_idx = 1; // Mulai dari bar kedua karena kita butuh data hari sebelumnya
// Bar paling awal (indeks 0) tidak akan punya data hari sebelumnya
}
else
{
start_idx = prev_calculated - 1;
if(start_idx < 1) start_idx = 1; // Pastikan tidak kurang dari 1
}
// Array untuk menampung data Harian (D1)
double prev_high_D1[1], prev_low_D1[1], prev_close_D1[1];
for(int i = start_idx; i < rates_total; i++)
{
// 1. Dapatkan shift bar D1 yang sesuai untuk bar 'time[i]' saat ini
// Kita ingin data D1 dari HARI SEBELUMNYA relatif terhadap time[i]
// Jadi, kita cari bar D1 yang time[i] jatuh di dalamnya, lalu ambil data dari bar D1 SEBELUMNYA lagi.
datetime current_bar_day_start = time[i] - (time[i] % 86400); // Awal hari dari bar saat ini
datetime prev_day_for_data = current_bar_day_start - 86400; // Awal hari dari hari sebelumnya yang datanya kita inginkan
// Dapatkan shift untuk hari sebelumnya tersebut pada timeframe D1
int shift_D1_prev = iBarShift(_Symbol, myPeriod, prev_day_for_data, false);
bool data_ok = false;
if(shift_D1_prev != -1) // Pastikan iBarShift berhasil
{
// Ambil data HLC dari bar D1 hari sebelumnya
if(CopyHigh(_Symbol, myPeriod, shift_D1_prev, 1, prev_high_D1) == 1 &&
CopyLow(_Symbol, myPeriod, shift_D1_prev, 1, prev_low_D1) == 1 &&
CopyClose(_Symbol, myPeriod, shift_D1_prev, 1, prev_close_D1) == 1)
{
data_ok = true;
}
}
if(data_ok)
{
double H_prev = prev_high_D1[0];
double L_prev = prev_low_D1[0];
double C_prev = prev_close_D1[0];
// Hitung Pivot Point Klasik
double pivot = (H_prev + L_prev + C_prev + C_prev) / 4.0;
/*
//Hitung "Range" sebagai basis untuk deviasi (bisa diganti dengan StdDev aktual jika diinginkan)
// Untuk kesederhanaan, kita gunakan Range (H-L) hari sebelumnya sebagai proxy volatilitas
// StdDev aktual akan melibatkan lebih banyak kalkulasi (rata-rata, lalu sum of squares, etc.)
double daily_range = H_prev - L_prev;
// Jika daily_range terlalu kecil atau tidak valid, hindari pembagian dengan nol atau nilai aneh
if (daily_range <= _Point * 5) // Jika range sangat kecil, mungkin tidak ada volatilitas
{
daily_range = _Point * 5; // Default ke range minimal untuk stabilitas
}
*/
double PA = pivot; //(C_prev + C_prev + L_prev + H_prev) / 4.0;
double S_val = 2 * MathPow(C_prev - PA, 2) + MathPow(L_prev - PA, 2) + MathPow(H_prev - PA, 2);
double StdDev_component = (S_val >= 0) ? MathSqrt(S_val / 3.0) : 0; // Pastikan S_val tidak negatif
double P2_dev = SD_Mult1 * StdDev_component;
double P3_dev = SD_Mult2 * StdDev_component;
double P4_dev = SD_Mult3 * StdDev_component;
double P5_dev = SD_Mult4 * StdDev_component;
// Simpan nilai pivot ke buffer untuk digambar
// Nilai pivot dan SD ini valid untuk SELURUH bar pada time[i] yang jatuh pada hari 'current_bar_day_start'
PivotBuffer[i] = pivot;
UpperSD1Buffer[i] = pivot + P2_dev;
LowerSD1Buffer[i] = pivot - P2_dev;
UpperSD2Buffer[i] = pivot + P3_dev;
LowerSD2Buffer[i] = pivot - P3_dev;
UpperSD3Buffer[i] = pivot + P4_dev;
LowerSD3Buffer[i] = pivot - P4_dev;
UpperSD4Buffer[i] = pivot + P5_dev;
LowerSD4Buffer[i] = pivot - P5_dev;
}
else // Jika data D1 hari sebelumnya tidak tersedia
{
// Jika bar sebelumnya memiliki nilai, teruskan. Jika tidak, biarkan EMPTY_VALUE.
// Ini membantu garis tetap terlihat jika ada lubang data sementara.
PivotBuffer[i] = (i > 0 && PivotBuffer[i-1] != EMPTY_VALUE) ? PivotBuffer[i-1] : EMPTY_VALUE;
UpperSD1Buffer[i] = (i > 0 && UpperSD1Buffer[i-1] != EMPTY_VALUE) ? UpperSD1Buffer[i-1] : EMPTY_VALUE;
LowerSD1Buffer[i] = (i > 0 && LowerSD1Buffer[i-1] != EMPTY_VALUE) ? LowerSD1Buffer[i-1] : EMPTY_VALUE;
UpperSD2Buffer[i] = (i > 0 && UpperSD2Buffer[i-1] != EMPTY_VALUE) ? UpperSD2Buffer[i-1] : EMPTY_VALUE;
LowerSD2Buffer[i] = (i > 0 && LowerSD2Buffer[i-1] != EMPTY_VALUE) ? LowerSD2Buffer[i-1] : EMPTY_VALUE;
UpperSD3Buffer[i] = (i > 0 && UpperSD3Buffer[i-1] != EMPTY_VALUE) ? UpperSD3Buffer[i-1] : EMPTY_VALUE;
LowerSD3Buffer[i] = (i > 0 && LowerSD3Buffer[i-1] != EMPTY_VALUE) ? LowerSD3Buffer[i-1] : EMPTY_VALUE;
UpperSD4Buffer[i] = (i > 0 && UpperSD4Buffer[i-1] != EMPTY_VALUE) ? UpperSD4Buffer[i-1] : EMPTY_VALUE;
LowerSD4Buffer[i] = (i > 0 && LowerSD4Buffer[i-1] != EMPTY_VALUE) ? LowerSD4Buffer[i-1] : EMPTY_VALUE;
if (i == rates_total -1) { // Pesan hanya untuk bar terakhir jika ada masalah
Comment("PivotDev: Data D1 hari sebelumnya tidak tersedia untuk bar " + TimeToString(time[i]));
}
}
}
return(rates_total);
}
//+------------------------------------------------------------------+