//+------------------------------------------------------------------+ //| KG Standard Deviation Level V.1.1.mq5 | //| Copyright © 2024, Dibuat oleh Asisten AI Gemini | //| Modifikasi dari konsep umum | //+------------------------------------------------------------------+ #property copyright "Copyright © 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); } //+------------------------------------------------------------------+