diff --git a/Indicators/MyIndicators/LinearRegressionChannel.mq5 b/Indicators/MyIndicators/LinearRegressionChannel.mq5 new file mode 100644 index 0000000..cf91f90 --- /dev/null +++ b/Indicators/MyIndicators/LinearRegressionChannel.mq5 @@ -0,0 +1,114 @@ +//+------------------------------------------------------------------+ +//| LinearRegressionChannel.mq5 | +//| Copyright 2025, xxxxxxxx | +//| | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2025, xxxxxxxx" +#property link "" +#property version "3.00" // Final version using OBJ_REGRESSION with smart update +#property description "Draws a clean Linear Regression Channel, updated on new bars." +#property indicator_chart_window +#property indicator_buffers 0 // No buffers needed for plotting +#property indicator_plots 0 // No plots needed + +//--- Input Parameters --- +input int InpRegressionPeriod = 100; +input double InpDeviations = 2.0; +// Note: OBJ_REGRESSION always uses PRICE_CLOSE, so InpAppliedPrice is not needed. + +//--- Global Variables --- +int g_ExtPeriod; +double g_ExtDeviations; +string g_channel_name; +datetime g_last_update_time; // To track the time of the last update + +//+------------------------------------------------------------------+ +//| Custom indicator initialization function. | +//+------------------------------------------------------------------+ +int OnInit() + { + g_ExtPeriod = (InpRegressionPeriod < 2) ? 2 : InpRegressionPeriod; + g_ExtDeviations = (InpDeviations <= 0) ? 2.0 : InpDeviations; + + g_channel_name = "LinRegChannel_" + IntegerToString(ChartID()) + "_" + IntegerToString(GetTickCount()); + g_last_update_time = 0; + + IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("LinReg(%d, %.1f)", g_ExtPeriod, g_ExtDeviations)); + + return(INIT_SUCCEEDED); + } + +//+------------------------------------------------------------------+ +//| Custom indicator deinitialization function. | +//+------------------------------------------------------------------+ +void OnDeinit(const int reason) + { +// Clean up the chart object + ObjectDelete(0, g_channel_name); + ChartRedraw(); + } + +//+------------------------------------------------------------------+ +//| Main calculation 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[]) + { + if(rates_total < g_ExtPeriod) + return(0); + +//--- Check if a new bar has appeared --- + datetime last_bar_time = time[rates_total - 1]; + if(last_bar_time > g_last_update_time) + { + UpdateRegressionChannel(rates_total, time); + g_last_update_time = last_bar_time; + } + + return(rates_total); + } + +//+------------------------------------------------------------------+ +//| Updates the position and properties of the regression channel. | +//+------------------------------------------------------------------+ +void UpdateRegressionChannel(int rates_total, const datetime &time[]) + { +// Define the start and end time for the channel + datetime time1 = time[rates_total - g_ExtPeriod]; + datetime time2 = time[rates_total - 1]; + +// Check if the object exists. If not, create it. + if(ObjectFind(0, g_channel_name) < 0) + { + if(!ObjectCreate(0, g_channel_name, OBJ_REGRESSION, 0, time1, 0, time2, 0)) + { + Print("Error creating regression channel object: ", GetLastError()); + return; + } + + // Set visual properties only once on creation + ObjectSetInteger(0, g_channel_name, OBJPROP_COLOR, clrRed); + ObjectSetInteger(0, g_channel_name, OBJPROP_STYLE, STYLE_SOLID); + ObjectSetDouble(0, g_channel_name, OBJPROP_DEVIATION, g_ExtDeviations); + ObjectSetInteger(0, g_channel_name, OBJPROP_FILL, false); + ObjectSetInteger(0, g_channel_name, OBJPROP_RAY_RIGHT, false); // Do not extend to the right + ObjectSetInteger(0, g_channel_name, OBJPROP_SELECTABLE, false); + } + else // If it exists, just move its time coordinates + { + ObjectSetInteger(0, g_channel_name, OBJPROP_TIME, 0, time1); + ObjectSetInteger(0, g_channel_name, OBJPROP_TIME, 1, time2); + } + + ChartRedraw(); + } +//+------------------------------------------------------------------+ +//+------------------------------------------------------------------+