From 004479c6b80e3f5a47a7346c18fd9972e072cf33 Mon Sep 17 00:00:00 2001 From: Toh4iem9 Date: Sun, 12 Oct 2025 23:17:16 +0200 Subject: [PATCH] refactor: mean --- Indicators/MyIndicators/Session_Analysis.mq5 | 59 ++++++++++++++------ 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/Indicators/MyIndicators/Session_Analysis.mq5 b/Indicators/MyIndicators/Session_Analysis.mq5 index b8191a0..9ac88d8 100644 --- a/Indicators/MyIndicators/Session_Analysis.mq5 +++ b/Indicators/MyIndicators/Session_Analysis.mq5 @@ -4,8 +4,8 @@ //| | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, xxxxxxxx" -#property version "1.30" // Added VWAP calculation -#property description "Draws boxes and calculates VWAP for user-defined trading sessions." +#property version "1.40" // Added Mean line calculation +#property description "Draws boxes, VWAP, and Mean lines for user-defined trading sessions." #property description "Times are based on broker's server time." #property indicator_chart_window #property indicator_plots 0 @@ -24,12 +24,13 @@ private: bool m_enabled; bool m_fill_box; bool m_show_vwap; + bool m_show_mean; // New member for mean line ENUM_APPLIED_VOLUME m_volume_type; bool IsTimeInSession(const MqlDateTime &dt); public: - void Init(bool enabled, string start_time, string end_time, color box_color, bool fill_box, bool show_vwap, ENUM_APPLIED_VOLUME vol_type, string prefix); + void Init(bool enabled, string start_time, string end_time, color box_color, bool fill_box, bool show_vwap, bool show_mean, ENUM_APPLIED_VOLUME vol_type, string prefix); void Update(const int rates_total, const datetime &time[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[]); void Cleanup(void); }; @@ -37,13 +38,14 @@ public: //+------------------------------------------------------------------+ //| CSessionAnalyzer: Initialization | //+------------------------------------------------------------------+ -void CSessionAnalyzer::Init(bool enabled, string start_time, string end_time, color box_color, bool fill_box, bool show_vwap, ENUM_APPLIED_VOLUME vol_type, string prefix) +void CSessionAnalyzer::Init(bool enabled, string start_time, string end_time, color box_color, bool fill_box, bool show_vwap, bool show_mean, ENUM_APPLIED_VOLUME vol_type, string prefix) { m_enabled = enabled; m_prefix = prefix; m_color = box_color; m_fill_box = fill_box; m_show_vwap = show_vwap; + m_show_mean = show_mean; m_volume_type = vol_type; string parts[]; @@ -104,9 +106,9 @@ void CSessionAnalyzer::Update(const int rates_total, const datetime &time[], con double session_low = 0; long session_id = 0; - double cumulative_tpv = 0; - double cumulative_vol = 0; - double prev_vwap = 0; + double cumulative_tpv = 0, cumulative_vol = 0, prev_vwap = 0; + double cumulative_price = 0; + int bar_count = 0; for(int i = 1; i < rates_total; i++) { @@ -125,6 +127,8 @@ void CSessionAnalyzer::Update(const int rates_total, const datetime &time[], con cumulative_tpv = 0; cumulative_vol = 0; prev_vwap = 0; + cumulative_price = 0; + bar_count = 0; } else if(!is_in_current_session && in_session) @@ -132,12 +136,21 @@ void CSessionAnalyzer::Update(const int rates_total, const datetime &time[], con in_session = false; if(session_start_bar != -1 && i > session_start_bar) { - string obj_name = m_prefix + "Box_" + (string)session_id; - ObjectCreate(0, obj_name, OBJ_RECTANGLE, 0, time[session_start_bar], session_high, time[i-1], session_low); - ObjectSetInteger(0, obj_name, OBJPROP_COLOR, m_color); - ObjectSetInteger(0, obj_name, OBJPROP_STYLE, STYLE_SOLID); - ObjectSetInteger(0, obj_name, OBJPROP_BACK, true); - ObjectSetInteger(0, obj_name, OBJPROP_FILL, m_fill_box); + string box_name = m_prefix + "Box_" + (string)session_id; + ObjectCreate(0, box_name, OBJ_RECTANGLE, 0, time[session_start_bar], session_high, time[i-1], session_low); + ObjectSetInteger(0, box_name, OBJPROP_COLOR, m_color); + ObjectSetInteger(0, box_name, OBJPROP_STYLE, STYLE_SOLID); + ObjectSetInteger(0, box_name, OBJPROP_BACK, true); + ObjectSetInteger(0, box_name, OBJPROP_FILL, m_fill_box); + + if(m_show_mean && bar_count > 0) + { + double mean_price = cumulative_price / bar_count; + string mean_line_name = m_prefix + "Mean_" + (string)session_id; + ObjectCreate(0, mean_line_name, OBJ_TREND, 0, time[session_start_bar], mean_price, time[i-1], mean_price); + ObjectSetInteger(0, mean_line_name, OBJPROP_COLOR, m_color); + ObjectSetInteger(0, mean_line_name, OBJPROP_STYLE, STYLE_DOT); + } } } @@ -161,7 +174,7 @@ void CSessionAnalyzer::Update(const int rates_total, const datetime &time[], con double current_vwap = (cumulative_vol > 0) ? cumulative_tpv / cumulative_vol : 0; - if(prev_vwap > 0) // Don't draw the first point, only from the second + if(prev_vwap > 0) { string vwap_line_name = m_prefix + "VWAP_" + (string)time[i]; ObjectCreate(0, vwap_line_name, OBJ_TREND, 0, time[i-1], prev_vwap, time[i], current_vwap); @@ -171,6 +184,13 @@ void CSessionAnalyzer::Update(const int rates_total, const datetime &time[], con prev_vwap = current_vwap; } + // --- Mean Calculation --- + if(m_show_mean) + { + cumulative_price += close[i]; + bar_count++; + } + // Update the box for the current, active session if(i == rates_total - 1) { @@ -208,6 +228,7 @@ input string InpPreMarket_Start = "08:00"; input string InpPreMarket_End = "09:30"; input color InpPreMarket_Color = C'33,150,243'; input bool InpPreMarket_VWAP = true; +input bool InpPreMarket_Mean = true; //+------------------------------------------------------------------+ //| | @@ -218,6 +239,7 @@ input string InpCore_Start = "09:30"; input string InpCore_End = "16:00"; input color InpCore_Color = C'255,87,34'; input bool InpCore_VWAP = true; +input bool InpCore_Mean = true; //+------------------------------------------------------------------+ //| | @@ -228,6 +250,7 @@ input string InpPostMarket_Start = "16:00"; input string InpPostMarket_End = "20:00"; input color InpPostMarket_Color = C'103,58,183'; input bool InpPostMarket_VWAP = true; +input bool InpPostMarket_Mean = true; //--- Global Variables --- CSessionAnalyzer *g_pre_market_analyzer; @@ -245,17 +268,17 @@ int OnInit() g_pre_market_analyzer = new CSessionAnalyzer(); if(CheckPointer(g_pre_market_analyzer) == POINTER_INVALID) return INIT_FAILED; - g_pre_market_analyzer.Init(InpPreMarket_Enable, InpPreMarket_Start, InpPreMarket_End, InpPreMarket_Color, InpFillBoxes, InpPreMarket_VWAP, InpVolumeType, "PreMarket_"); + g_pre_market_analyzer.Init(InpPreMarket_Enable, InpPreMarket_Start, InpPreMarket_End, InpPreMarket_Color, InpFillBoxes, InpPreMarket_VWAP, InpPreMarket_Mean, InpVolumeType, "PreMarket_"); g_core_market_analyzer = new CSessionAnalyzer(); if(CheckPointer(g_core_market_analyzer) == POINTER_INVALID) return INIT_FAILED; - g_core_market_analyzer.Init(InpCore_Enable, InpCore_Start, InpCore_End, InpCore_Color, InpFillBoxes, InpCore_VWAP, InpVolumeType, "CoreMarket_"); + g_core_market_analyzer.Init(InpCore_Enable, InpCore_Start, InpCore_End, InpCore_Color, InpFillBoxes, InpCore_VWAP, InpCore_Mean, InpVolumeType, "CoreMarket_"); g_post_market_analyzer = new CSessionAnalyzer(); if(CheckPointer(g_post_market_analyzer) == POINTER_INVALID) return INIT_FAILED; - g_post_market_analyzer.Init(InpPostMarket_Enable, InpPostMarket_Start, InpPostMarket_End, InpPostMarket_Color, InpFillBoxes, InpPostMarket_VWAP, InpVolumeType, "PostMarket_"); + g_post_market_analyzer.Init(InpPostMarket_Enable, InpPostMarket_Start, InpPostMarket_End, InpPostMarket_Color, InpFillBoxes, InpPostMarket_VWAP, InpPostMarket_Mean, InpVolumeType, "PostMarket_"); IndicatorSetString(INDICATOR_SHORTNAME, "Session Analysis"); return(INIT_SUCCEEDED); @@ -304,5 +327,5 @@ int OnCalculate(const int rates_total, const int, const datetime& time[], const ChartRedraw(); return(rates_total); } -//+------------------------------------------------------------------+``` +//+------------------------------------------------------------------+ //+------------------------------------------------------------------+