//+------------------------------------------------------------------+ //| BOS_CHOCH.mq5| //| Copyright 2023, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property indicator_chart_window #property indicator_buffers 2 #property indicator_plots 2 #property indicator_color1 clrGreen #property indicator_color2 clrRed #property indicator_width1 2 #property indicator_width2 2 // Indicator Buffers double BOSBuffer[]; double CHOCHBuffer[]; // Input parameters input int lookbackPeriod = 50; // Number of candles to look back for structure analysis //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { // Set up indicator buffers SetIndexBuffer(0, BOSBuffer, INDICATOR_DATA); SetIndexBuffer(1, CHOCHBuffer, INDICATOR_DATA); // Set up indicator labels IndicatorSetString(INDICATOR_SHORTNAME, "BOS & CHOCH Detector"); IndicatorSetInteger(INDICATOR_DIGITS, _Digits); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| 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[]) { // Loop through all candles for (int i = prev_calculated; i < rates_total; i++) { // Detect BOS (Break of Structure) if (IsBOS(i, high, low, lookbackPeriod)) { BOSBuffer[i] = high[i]; // Mark BOS on the chart } else { BOSBuffer[i] = EMPTY_VALUE; } // Detect CHOCH (Change of Character) if (IsCHOCH(i, high, low, lookbackPeriod)) { CHOCHBuffer[i] = low[i]; // Mark CHOCH on the chart } else { CHOCHBuffer[i] = EMPTY_VALUE; } } return(rates_total); } //+------------------------------------------------------------------+ //| Function to detect Break of Structure (BOS) | //+------------------------------------------------------------------+ bool IsBOS(int index, const double &high[], const double &low[], int lookback) { // Check if the current high is higher than the previous highs for (int i = 1; i <= lookback; i++) { if (index - i >= 0 && high[index] <= high[index - i]) { return false; } } return true; } //+------------------------------------------------------------------+ //| Function to detect Change of Character (CHOCH) | //+------------------------------------------------------------------+ bool IsCHOCH(int index, const double &high[], const double &low[], int lookback) { // Check if the current low is lower than the previous lows for (int i = 1; i <= lookback; i++) { if (index - i >= 0 && low[index] >= low[index - i]) { return false; } } return true; }