last ....
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
#property copyright "Your Name"
|
||||
#property link "https://www.example.com"
|
||||
#property version "1.00"
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 0
|
||||
#property indicator_plots 0
|
||||
|
||||
// Input parameters
|
||||
input int SwingPeriod = 5; // Lookback period for swing detection
|
||||
|
||||
// Global variables
|
||||
double LastSwingHigh = 0, LastSwingLow = 0;
|
||||
bool IsBullish = false;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
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[])
|
||||
{
|
||||
// Start from the latest bar
|
||||
for(int i = rates_total - prev_calculated - 1; i >= 0; i--)
|
||||
{
|
||||
// Detect swing high and low
|
||||
if(IsSwingHigh(high, low, i, SwingPeriod))
|
||||
{
|
||||
LastSwingHigh = high[i];
|
||||
CheckStructure(i, high[i], low[i], time[i]);
|
||||
}
|
||||
if(IsSwingLow(high, low, i, SwingPeriod))
|
||||
{
|
||||
LastSwingLow = low[i];
|
||||
CheckStructure(i, high[i], low[i], time[i]);
|
||||
}
|
||||
}
|
||||
return(rates_total);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
bool IsSwingHigh(const double &high[], const double &low[], int index, int period)
|
||||
{
|
||||
if(index < period || index >= ArraySize(high) - period) return false;
|
||||
for(int i = 1; i <= period; i++)
|
||||
{
|
||||
if(high[index] <= high[index - i] || high[index] <= high[index + i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
bool IsSwingLow(const double &high[], const double &low[], int index, int period)
|
||||
{
|
||||
if(index < period || index >= ArraySize(low) - period) return false;
|
||||
for(int i = 1; i <= period; i++)
|
||||
{
|
||||
if(low[index] >= low[index - i] || low[index] >= low[index + i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
void CheckStructure(int index, double high, double low, datetime time)
|
||||
{
|
||||
// Determine trend direction
|
||||
if(LastSwingHigh > 0 && LastSwingLow > 0)
|
||||
{
|
||||
IsBullish = (LastSwingHigh > LastSwingLow);
|
||||
|
||||
// Check for BOS
|
||||
if(IsBullish && high > LastSwingHigh)
|
||||
{
|
||||
LastSwingHigh = high;
|
||||
ObjectCreate(0, "BOS_" + TimeToString(time), OBJ_TEXT, 0, time, high);
|
||||
ObjectSetString(0, "BOS_" + TimeToString(time), OBJPROP_TEXT, "BOS");
|
||||
ObjectSetInteger(0, "BOS_" + TimeToString(time), OBJPROP_COLOR, clrGreen);
|
||||
Alert("Break of Structure (BOS) detected at " + DoubleToString(high, 5));
|
||||
}
|
||||
else if(!IsBullish && low < LastSwingLow)
|
||||
{
|
||||
LastSwingLow = low;
|
||||
ObjectCreate(0, "BOS_" + TimeToString(time), OBJ_TEXT, 0, time, low);
|
||||
ObjectSetString(0, "BOS_" + TimeToString(time), OBJPROP_TEXT, "BOS");
|
||||
ObjectSetInteger(0, "BOS_" + TimeToString(time), OBJPROP_COLOR, clrRed);
|
||||
Alert("Break of Structure (BOS) detected at " + DoubleToString(low, 5));
|
||||
}
|
||||
|
||||
// Check for CHoCH
|
||||
if(IsBullish && low < LastSwingLow)
|
||||
{
|
||||
LastSwingLow = low;
|
||||
ObjectCreate(0, "CHoCH_" + TimeToString(time), OBJ_TEXT, 0, time, low);
|
||||
ObjectSetString(0, "CHoCH_" + TimeToString(time), OBJPROP_TEXT, "CHoCH");
|
||||
ObjectSetInteger(0, "CHoCH_" + TimeToString(time), OBJPROP_COLOR, clrRed);
|
||||
Alert("Change of Character (CHoCH) detected at " + DoubleToString(low, 5));
|
||||
IsBullish = false; // Trend may reverse
|
||||
}
|
||||
else if(!IsBullish && high > LastSwingHigh)
|
||||
{
|
||||
LastSwingHigh = high;
|
||||
ObjectCreate(0, "CHoCH_" + TimeToString(time), OBJ_TEXT, 0, time, high);
|
||||
ObjectSetString(0, "CHoCH_" + TimeToString(time), OBJPROP_TEXT, "CHoCH");
|
||||
ObjectSetInteger(0, "CHoCH_" + TimeToString(time), OBJPROP_COLOR, clrGreen);
|
||||
Alert("Change of Character (CHoCH) detected at " + DoubleToString(high, 5));
|
||||
IsBullish = true; // Trend may reverse
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
ObjectsDeleteAll(0, "BOS_");
|
||||
ObjectsDeleteAll(0, "CHoCH_");
|
||||
}
|
||||
Reference in New Issue
Block a user