last ...
This commit is contained in:
@@ -2231,7 +2231,7 @@ class XCBarAnalyser : public XCBase
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool IsSwimpleSwing(
|
||||
bool IsSimpleSwing(
|
||||
XOHCL &bar,
|
||||
ENUM_X_DIRECTION &dir //
|
||||
)
|
||||
@@ -2286,6 +2286,13 @@ class XCBarAnalyser : public XCBase
|
||||
//
|
||||
result = isPBarSwingLow ||
|
||||
isPBarSwingHigh;
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
dir = isPBarSwingLow
|
||||
? X_DIRECTION_BULLISH
|
||||
: X_DIRECTION_BEARISH;
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup Resourses ...
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
#property copyright "Your Name"
|
||||
#property link "https://www.yourwebsite.com"
|
||||
#property version "1.02"
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 2
|
||||
#property indicator_plots 2
|
||||
|
||||
//--- Input parameters
|
||||
input int atr_period = 14; // ATR Period
|
||||
input double atr_threshold = 0.0005; // ATR Threshold for Consolidation (e.g., 0.0005 for EURUSD, 5.0 for XAUUSD)
|
||||
input int range_period = 20; // Period to check price range
|
||||
input double range_multiplier = 2.0; // Price range multiplier (relative to ATR)
|
||||
input bool enable_alerts = true; // Enable breakout alerts
|
||||
input bool draw_rectangles = true; // Draw rectangles for consolidation zones
|
||||
|
||||
//--- Indicator buffers
|
||||
double UpperBuffer[];
|
||||
double LowerBuffer[];
|
||||
|
||||
//--- Global variables
|
||||
int atr_handle = INVALID_HANDLE;
|
||||
int zone_count = 0; // For unique rectangle names
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- Set indicator buffers
|
||||
SetIndexBuffer(0, UpperBuffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(1, LowerBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetString(0, PLOT_LABEL, "Upper Consolidation");
|
||||
PlotIndexSetString(1, PLOT_LABEL, "Lower Consolidation");
|
||||
PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_LINE);
|
||||
PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_LINE);
|
||||
PlotIndexSetInteger(0, PLOT_LINE_STYLE, STYLE_SOLID);
|
||||
PlotIndexSetInteger(1, PLOT_LINE_STYLE, STYLE_SOLID);
|
||||
PlotIndexSetInteger(0, PLOT_LINE_COLOR, clrRed);
|
||||
PlotIndexSetInteger(1, PLOT_LINE_COLOR, clrBlue);
|
||||
|
||||
//--- Create ATR handle
|
||||
atr_handle = iATR(_Symbol, _Period, atr_period);
|
||||
if(atr_handle == INVALID_HANDLE)
|
||||
{
|
||||
Print("Failed to create ATR handle, error: ", GetLastError());
|
||||
return(INIT_FAILED);
|
||||
}
|
||||
|
||||
//--- Check available bars
|
||||
int available_bars = Bars(_Symbol, _Period);
|
||||
if(available_bars < range_period + atr_period)
|
||||
{
|
||||
Print("Insufficient bars: ", available_bars, ", required: ", range_period + atr_period);
|
||||
return(INIT_FAILED);
|
||||
}
|
||||
|
||||
//--- Log initialization
|
||||
Print("Indicator initialized. Symbol: ", _Symbol, ", Timeframe: ", Period(),
|
||||
", ATR Period: ", atr_period, ", Range Period: ", range_period);
|
||||
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
if(atr_handle != INVALID_HANDLE)
|
||||
IndicatorRelease(atr_handle);
|
||||
ObjectsDeleteAll(0, "Consolidation_"); // Remove all rectangles
|
||||
Print("Indicator deinitialized, reason: ", reason);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| 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[])
|
||||
{
|
||||
//--- Ensure enough bars
|
||||
if(rates_total < range_period + atr_period)
|
||||
{
|
||||
Print("Not enough bars: ", rates_total, ", required: ", range_period + atr_period);
|
||||
return(0);
|
||||
}
|
||||
|
||||
//--- Set arrays as series
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(UpperBuffer, true);
|
||||
ArraySetAsSeries(LowerBuffer, true);
|
||||
|
||||
//--- Calculate ATR
|
||||
double atr[];
|
||||
ArraySetAsSeries(atr, true);
|
||||
ArrayResize(atr, rates_total);
|
||||
if(CopyBuffer(atr_handle, 0, 0, rates_total, atr) <= 0)
|
||||
{
|
||||
Print("Failed to copy ATR buffer, error: ", GetLastError());
|
||||
return(0);
|
||||
}
|
||||
|
||||
//--- Initialize buffers for first calculation
|
||||
if(prev_calculated == 0)
|
||||
{
|
||||
ArrayInitialize(UpperBuffer, EMPTY_VALUE);
|
||||
ArrayInitialize(LowerBuffer, EMPTY_VALUE);
|
||||
}
|
||||
|
||||
//--- Loop through bars
|
||||
int start = prev_calculated == 0 ? range_period : MathMax(range_period, prev_calculated - 1);
|
||||
for(int i = start; i < rates_total && !IsStopped(); i++)
|
||||
{
|
||||
//--- Calculate range over range_period
|
||||
int max_idx = ArrayMaximum(high, i - range_period + 1, range_period);
|
||||
int min_idx = ArrayMinimum(low, i - range_period + 1, range_period);
|
||||
if(max_idx == -1 || min_idx == -1)
|
||||
{
|
||||
Print("Error: Invalid array index at bar ", i);
|
||||
continue;
|
||||
}
|
||||
double max_high = high[max_idx];
|
||||
double min_low = low[min_idx];
|
||||
double price_range = max_high - min_low;
|
||||
|
||||
//--- Log values for debugging
|
||||
if(i == rates_total - 1) // Log only for the latest bar
|
||||
{
|
||||
Print("Bar ", i, ": ATR = ", DoubleToString(atr[i], _Digits),
|
||||
", Price Range = ", DoubleToString(price_range, _Digits),
|
||||
", Threshold = ", DoubleToString(atr_threshold, _Digits),
|
||||
", Range Limit = ", DoubleToString(atr[i] * range_multiplier, _Digits));
|
||||
}
|
||||
|
||||
//--- Check for consolidation
|
||||
if(atr[i] < atr_threshold && price_range < atr[i] * range_multiplier)
|
||||
{
|
||||
UpperBuffer[i] = max_high;
|
||||
LowerBuffer[i] = min_low;
|
||||
|
||||
//--- Draw rectangle for the consolidation zone
|
||||
if(draw_rectangles && i >= range_period)
|
||||
{
|
||||
string obj_name = "Consolidation_" + IntegerToString(zone_count++) + "_" + TimeToString(time[i]);
|
||||
ObjectCreate(0, obj_name, OBJ_RECTANGLE, 0, time[i], max_high, time[i - range_period + 1], min_low);
|
||||
ObjectSetInteger(0, obj_name, OBJPROP_COLOR, clrRed);
|
||||
ObjectSetInteger(0, obj_name, OBJPROP_STYLE, STYLE_SOLID);
|
||||
ObjectSetInteger(0, obj_name, OBJPROP_WIDTH, 1);
|
||||
ObjectSetInteger(0, obj_name, OBJPROP_FILL, false);
|
||||
ObjectSetInteger(0, obj_name, OBJPROP_BACK, false);
|
||||
}
|
||||
|
||||
//--- Check for breakout (on latest bar only)
|
||||
if(enable_alerts && i == rates_total - 1)
|
||||
{
|
||||
if(close[i] > UpperBuffer[i] && (i == 0 || close[i-1] <= UpperBuffer[i-1]))
|
||||
Alert("Breakout Up at ", TimeToString(time[i]), ": Price = ", DoubleToString(close[i], _Digits));
|
||||
if(close[i] < LowerBuffer[i] && (i == 0 || close[i-1] >= LowerBuffer[i-1]))
|
||||
Alert("Breakout Down at ", TimeToString(time[i]), ": Price = ", DoubleToString(close[i], _Digits));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UpperBuffer[i] = EMPTY_VALUE;
|
||||
LowerBuffer[i] = EMPTY_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
return(rates_total);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user