//@version=6
strategy(title="2025.09.05 Theseus", scale=scale.right, overlay=true, calc_on_every_tick=false, initial_capital=1000, max_lines_count=500, max_labels_count = 500, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.5, slippage=3, fill_orders_on_standard_ohlc=true)

//{ Collapse all down to long condition section
import TradingView/ta/10
import NiceOrbit/LibraryUtility/9 as utils
import NiceOrbit/LibraryRSIDivergence/1 as rsiDiv
import NiceOrbit/LibraryGaussianChannel/1 as gcl
import NiceOrbit/LibraryMACD/9 as macdLib
import NiceOrbit/LibraryMoneySupply/7 as libMoneySupply
import NiceOrbit/LibraryStochasticDivergence/3 as libStochDiv
import NiceOrbit/LibraryVWAPDivergence/3 as libVwapDiv
import NiceOrbit/LibraryRealizedPrice/4 as libRealizedPrice
import NiceOrbit/LibraryTradeLogger/8 as tradeLogger
import NiceOrbit/LibraryLongExit/5 as libLongExit
import NiceOrbit/LibraryLongEntry/24 as libLongEntry


//{ Date, Condition switches & Settings  ======================
group_date_range                        = "Back Testing Date Range"
startDate                               = input.time(timestamp("1 January 2018"), "Start", group=group_date_range, inline="date", display=display.none)
endDate                                 = input.time(timestamp("1 July 2024 23:59 +0000"), "End ", group=group_date_range, inline="date", display=display.none)
timeCondition                           = time >= startDate and time <= endDate

group_general_settings                = "General Setings"
i_display_condition_names_on_chart      = input.bool(true, title="Display condition names on chart", group=group_general_settings, display=display.none)
i_log_variables_to_list_of_trades       = input.bool(false, title="Log Variables on each trade in List of Trades", group=group_general_settings,display=display.none)
i_enable_plot_all_enabled_conditions    = input.bool(true, title="Plot Enabled entries and exits, in lighter color", group=group_general_settings, display=display.none)
i_enable_plot_disabled_entry_conditions = input.bool(false, title="Plot Disabled Entries and ", group=group_general_settings, display=display.none, inline="disabledEntriesExits")
i_enable_plot_disabled_exit_conditions  = input.bool(false, title="Disabled Exits, in darker color ", group=group_general_settings, display=display.none, inline="disabledEntriesExits")
i_enable_timeframe_adjustment           = input.bool(true, title="Enable Time Frame Adjustment", group=group_general_settings,display=display.none, tooltip = "For timeframes shorter than 1 Day, adjusted to use more bars to keep same range of data as 1 day would")
i_enableShort                           = input.bool(false, title="Enable Shorting", group=group_general_settings,display=display.none)
group_LongEntry_Enabled                 = "Long Entry Types Enabled"
group_LongExit_Enabled                  = "Long Exit Types Enabled"

timeframe_divisor = utils.f_resInDays()

string longExitDetailedStats = ""

// Entry Condition Switches
i_enableLong                                                    = input.bool(true, title="All-Long Entries, ", group=group_LongEntry_Enabled,display=display.none, inline="original")
longEntryAggressiveness                                         = input.string(defval="priceAboveHband",title="Aggressiveness", options=["priceAboveHband", "priceAboveMband", "priceAboveLband","ignore bands"], group=group_LongEntry_Enabled, inline="original", display=display.none)
i_enablelongCondition_original                                  = input.bool(false, title="  F2-43-original", group=group_LongEntry_Enabled,display=display.none)
i_enablelongCondition_new                                       = input.bool(false, title="  F3-new", group=group_LongEntry_Enabled,display=display.none)
i_enablelongCondition_base                                      = input.bool(false, title="  -base", group=group_LongEntry_Enabled,display=display.none)
i_enablelongCondition_rocLongEntry                              = input.bool(true,  title="  DH-rocLongEntry", group=group_LongEntry_Enabled,display=display.none)
i_enableLongGaussianGreenAndHMA                                 = input.bool(false, title="  F5-gaussianGreen and HMA", group=group_LongEntry_Enabled,display=display.none)
i_enable_longCondition_macd_crossOver                           = input.bool(false, title="  F8-macd_crossOver", group=group_LongEntry_Enabled, display=display.none)
i_enable_longCondition_rsiSlowingBullishDivergence              = input.bool(false, title="  F8-rsiSlowingBullishDivergence", group=group_LongEntry_Enabled,display=display.none)
i_enable_longCondition_rsiDelayedDipDivergence                  = input.bool(true,  title="  D43-rsiDelayedDipDivergence", group=group_LongEntry_Enabled,display=display.none)
i_enable_longCondition_rsiRegularBullishDivergence              = input.bool(true,  title="  D3-rsiRegularBullishDivergence",group=group_LongEntry_Enabled,display=display.none)
i_enable_longCondition_rsiHiddenBullishDivergence               = input.bool(false, title="  F3-rsiHiddenBullishDivergence",group=group_LongEntry_Enabled,display=display.none)
i_enable_longCondition_rsiConfirmedBullishDivergence            = input.bool(false, title="  -rsiConfirmedBullishDivergence",group=group_LongEntry_Enabled,display=display.none)
i_enable_longCondition_rsiRealTimeBullishDivergence             = input.bool(false, title="  3-rsiRealTimeBullishDivergence",group=group_LongEntry_Enabled,display=display.none)
i_enable_longCondition_realTime_slowing_confirmed               = input.bool(false, title="  ?-realTime_slowing_confirmed", group=group_LongEntry_Enabled, display=display.none )
i_enable_longCondition_stochastic_divergence                    = input.bool(false, title="  -stochastic_divergence", group=group_LongEntry_Enabled, display=display.none)
i_enable_longCondition_stochbullish_rocM3bullish_not_macd_flipped_bearish = input.bool(true, title="  DH-stochbullish_rocM3bullish_not_macd_flipped_bearish", group=group_LongEntry_Enabled, inline="notmacdflipped", display=display.none)
i_enable_longCondition_stochbullish_rocM3bullish_not_macd_flipped_bearish_n_bars_out = input.int(3, title="  n bars out >", group=group_LongEntry_Enabled, inline="notmacdflipped", display=display.none)
i_stochbullish_rocM3bullish_not_macd_flipped_bearish_macd_value= input.float(-250.0, "MACD below",group=group_LongEntry_Enabled, inline="notmacdflipped", display=display.none)
i_enable_longCondition_stochbullish_macd_flipped_bullish_rocM3_flipped_bullish = input.bool(true, title="  DH-stochbullish_macd_flipped_bullish_rocM3_flipped_bullish", group=group_LongEntry_Enabled, display=display.none)
i_enable_longCondition_base_not_macd_is_decreasing              = input.bool(false, title="  F3-base_not_macd_is_decreasing", group=group_LongEntry_Enabled, display=display.none )
i_enable_longCondition_base_isMacdHistRising                    = input.bool(false, title="  F4-base_isMacdHistRising", group=group_LongEntry_Enabled, display=display.none )
i_enable_longCondition_base_isM2SmoothedShortOffsetRising       = input.bool(false, title="  F1-base_isM2SmoothedShortOffsetRising", group=group_LongEntry_Enabled, display=display.none )
i_enable_longCondition_base_macd_slope_above_threshold          = input.bool(false, title="  F3-base_macd_slope_above_threshold", group=group_LongEntry_Enabled, display=display.none )
i_enable_longCondition_base_not_isM2SmoothedLongOffsetFalling= input.bool(true,  title="  D-base_not_isM2SmoothedLongOffsetFalling", group=group_LongEntry_Enabled, display=display.none )
i_enable_longCondition_base_not_rsi_high_range_cond             = input.bool(true,  title="  D-base_not_rsi_high_range_cond", group=group_LongEntry_Enabled, display=display.none )
i_enable_longCondition_base_rsid_osc_above_50                   = input.bool(false, title="  -base_rsid_osc_above_50", group=group_LongEntry_Enabled, display=display.none, inline="rsid_osc_above")
i_longCondition_base_rsid_rsid_osc_threshold                    = input.int(50,     title=">", group=group_LongEntry_Enabled, display=display.none, inline="rsid_osc_above" )
i_longCondition_base_rsid_m2_threshold                          = input.int(80,     title="M2 threshold(1D-80, 12H-95)", group=group_LongEntry_Enabled, display=display.none, inline="rsid_osc_above" )
i_enable_longCondition_base_stoch_high_range_cond               = input.bool(false, title="  -base_stoch_high_range_cond", group=group_LongEntry_Enabled, display=display.none )
i_enable_longCondition_base_stoch_low_range_cond                = input.bool(false, title="  H-base_stoch_low_range_cond", group=group_LongEntry_Enabled, display=display.none )
i_enable_longCondition_isM2MacdLongCrossBullish                 = input.bool(false, title="  -isM2MacdLongCrossBullish", group=group_LongEntry_Enabled, display=display.none )
i_enable_longCondition_isM2MacdShortCrossBullish                = input.bool(true,  title="  DH-isM2MacdShortCrossBullish", group=group_LongEntry_Enabled, display=display.none )
i_enable_longCondition_low_rsid                                 = input.bool(true,  title="  DH-low_rsid", group=group_LongEntry_Enabled, display=display.none, inline="lowRSID")
i_longCondition_low_rsid_threshold                              = input.int(17,     title="threshold(17,20)", tooltip="filter to include values only below this number", group=group_LongEntry_Enabled, display=display.none, inline="lowRSID" )
i_longCondition_low_rsid_delta                                  = input.int(12,     title="delta(12,9)", tooltip="filter to require this amount of increase from previous to current rsid_osc", group=group_LongEntry_Enabled, display=display.none, inline="lowRSID" )
i_enable_longCondition_macd_crossUnderPrediction                = input.bool(true,  title="  DH-macd_crossUnderPrediction", group=group_LongEntry_Enabled, display=display.none)
i_enable_longCondition_vwap_bullish_diff_short                  = input.bool(true,  title="  DH-vwap_bullish_diff_short", group=group_LongEntry_Enabled, display=display.none)
i_enable_longCondition_realized_price_bull_div                  = input.bool(true,  title="  DH-realized_price_bull_div", group=group_LongEntry_Enabled, display=display.none)

//Entry conditions under test
i_enable_longCondition_realized_price_bull_cond                 = input.bool(false, title="  realized_price_bull_cond", group=group_LongEntry_Enabled, display=display.none)
i_enable_longCondition_filtered_realized_price_bull_cond        = input.bool(false, title="  filtered_realized_price_bull_cond", group=group_LongEntry_Enabled, display=display.none)
i_enable_longCondition_realized_price_crossOverUpper            = input.bool(false,  title="  realized_price_crossOverUpper", group=group_LongEntry_Enabled, display=display.none)
i_enable_longCondition_vwap_bullish_all_rising                  = input.bool(false, title="  test_vwap_bullish_all_rising", group=group_LongEntry_Enabled, display=display.none)
i_enable_longCondition_rsiHiddenBearishCondition                = input.bool(false, title="  test_rsiHiddenBearishCondition", group=group_LongEntry_Enabled, display=display.none)
i_enable_longCondition_realized_price_bull_div_not_isRisingTinyShort= input.bool(false, title="  realized_price_bull_div_not_isRisingTinyShort", group=group_LongEntry_Enabled, display=display.none)
i_enable_longCondition_isRising_smoothedM3_no_offset            = input.bool(false, title="  isRising_smoothedM3_no_offset", group=group_LongEntry_Enabled, display=display.none)
i_enable_longCondition_test                                     = input.bool(false, title="  -test", group=group_LongEntry_Enabled, display=display.none)
i_enable_longCondition_base_not_isM3GlobalSmoothedFalling       = input.bool(false,  title="  -base_not_isM3GlobalSmoothedFalling", group=group_LongEntry_Enabled, display=display.none)

// Exit Condition Switches
i_enableLongExit                                                = input.bool(true,  title="All-Long Exit Types in General", group=group_LongExit_Enabled,display=display.none)
i_enable_longExitCondition_rsiSlowingBearishDivergence          = input.bool(false, title="  F-Slowing Bearish Confirmation", group=group_LongExit_Enabled,display=display.none)
i_enable_longExitCondition_rsiDelayedPeakDivergence             = input.bool(true,  title="  ?D-Delayed Peak Divergence", group=group_LongExit_Enabled,display=display.none)
i_enable_longExitCondition_rsiRegularBearishDivergence          = input.bool(true,  title="  D-Regular Bearish Divergence",group=group_LongExit_Enabled,display=display.none)
i_enable_longExitCondition_rsiHiddenBearishDivergence           = input.bool(true,  title="  ?D-Hidden Bearish Divergence",group=group_LongExit_Enabled,display=display.none)
i_enable_longExitCondition_rsiConfirmedBearishDivergence        = input.bool(true,  title="  ?D-Confirmed Bearish Divergence",group=group_LongExit_Enabled,display=display.none)
i_enable_longExitCondition_rsiRealTimeBearishDivergence         = input.bool(false, title="  F1-RealTimeBearishDivergence",group=group_LongExit_Enabled,display=display.none)
i_enable_longExitCondition_rsiRealTimeBearishVWAPDivergenceA    = input.bool(true,  title="  D-RealTimeBearishVWAPDivergenceA",group=group_LongExit_Enabled,display=display.none)
i_enable_longExitCondition_rsiRealTimeBearishVWAPDivergenceB    = input.bool(false, title="  Test-RealTimeBearishVWAPDivergenceB",group=group_LongExit_Enabled,display=display.none)
i_enable_longExitCondition_stochbearish_negative_diffs          = input.bool(false, title="  Test-stochbearish_negative_diffs",group=group_LongExit_Enabled,display=display.none)
i_enable_longExitCondition_crossUnderCloseHband                 = input.bool(true,  title="  D-crossUnderCloseHband", group=group_LongExit_Enabled,display=display.none)
i_enable_longExitCondition_rocHMALongExitUnderThreshold         = input.bool(false, title="  F-rocHMALongExitUnderThreshold", group=group_LongExit_Enabled,display=display.none )
i_enable_longExitCondition_rocLongExitCondition                 = input.bool(true,  title="  ?-rocLongExitCondition", group=group_LongExit_Enabled,display=display.none )
i_enable_longExitCondition_volatilityCondition                  = input.bool(false, title="  F-volatilityCondition", group=group_LongExit_Enabled,display=display.none )
i_enable_longExitCondition_macd_crossUnderPrediction            = input.bool(false, title="  F-MACD cross-under prediction", group=group_LongExit_Enabled, display=display.none )
i_enable_longExitCondition_shortEntryCondition                  = input.bool(true,  title="  D-Short Entry as Long Exit", group=group_LongExit_Enabled, display=display.none )
i_enable_longExitCondition_macd_crossUnder                      = input.bool(false, title="  F-macd_crossUnder", group=group_LongExit_Enabled)
i_enable_longExitCondition_stochastic_divergence                = input.bool(false, title="  F2-stochastic_divergence", group=group_LongExit_Enabled)
i_enable_longExitCondition_stochbearish_vwap_bearish_macd_hist_rising     = input.bool(true, title="  D-stochbearish_vwap_bearish_macd_hist_rising", group=group_LongExit_Enabled, display=display.none)
i_enable_longExitCondition_stochbearish_vwap_bearish_macd_flipped_bearish = input.bool(true, title="  D-stochbearish_vwap_bearish_macd_flipped_bearish", group=group_LongExit_Enabled, display=display.none)
i_enable_longExitCondition_isM2MacdLongCrossBearish             = input.bool(false, title="  F6-isM2MacdLongCrossBearish", group=group_LongExit_Enabled, display=display.none )
i_enable_longExitCondition_isM2MacdShortCrossBearish            = input.bool(false, title="  F3-isM2MacdShortCrossBearish", group=group_LongExit_Enabled, display=display.none )
i_enable_longExitCondition_m2_diff_less_than                    = input.bool(false, title="  F4-m2_diff_less_than", group=group_LongExit_Enabled, display=display.none, inline="m2diff")
i_enable_longExitCondition_m2_diff_less_than_diff_less_than     = input.float(-4.0, title="  less_than", group=group_LongExit_Enabled, display=display.none, inline="m2diff")
i_enable_longExitCondition_m2Macd_shortOffsetDifference_under_0     = input.bool(true, title="  D-m2Macd_shortOffsetDifference_under_0", group=group_LongExit_Enabled, display=display.none )
i_enable_longExitCondition_up_spike_when_isM2SmoothedTinyOffsetFlat = input.bool(true, title="  D-up_spike_when_isM2SmoothedTinyOffsetFlat", group=group_LongExit_Enabled, display=display.none )
i_enable_longExitCondition_stochbearish_stoch_over_N            = input.bool(false, title="  F4-stochbearish_stoch_over_N", group=group_LongExit_Enabled, display=display.none, inline="stoch_over_N")
i_longExitCondition_stoch_over_N_threshold                      = input.int(80,     title="stoch threshold(80)", tooltip="stochastic value over this number will be included in filter", group=group_LongExit_Enabled, display=display.none, inline="stoch_over_N")
i_longExitCondition_rsi_over_N_threshold                        = input.int(70,     title="    rsi threshold(70)", tooltip="rsi value over this number will be included in filter", group=group_LongExit_Enabled, display=display.none, inline="stoch_over_N")
i_longExitCondition_macd_slope_current_under_N_threshold        = input.int(-20,    title="    macd slope threshold(-20)", tooltip="macd_slope_current under over this number will be included in filter", group=group_LongExit_Enabled, display=display.none, inline="stoch_over_N")
i_enable_longExitCondition_stochastic_divergence_isFalling      = input.bool(false, title="  F2-stochastic_divergence_isFalling", group=group_LongExit_Enabled, inline="stochastic_divergence_isFalling_rsid_threshold", display=display.none)
i_enable_stochastic_divergence_isFalling_rsid_threshold         = input.int(85,     title="    RSID_OSC threshold", group=group_LongExit_Enabled, inline="stochastic_divergence_isFalling_rsid_threshold", display=display.none)
i_enable_longExitCondition_isFalling_short_high_rsi_high_stoch  = input.bool(true,  title="  D-isFalling_short_high_rsi_high_stoch", group=group_LongExit_Enabled, display=display.none)
i_enable_longExitCondition_realized_price_bear_cond             = input.bool(false, title="  realized_price_bear_cond", group=group_LongExit_Enabled, display=display.none)

// Exit conditions under test
groupTestExits = "Exit conditions under test"
i_enable_longExitCondition_filtered_realized_price_bear_cond    = input.bool(false, title="  filtered_realized_price_bear_cond", group=groupTestExits, display=display.none)
i_enable_longExitCondition_realized_price_bear_div              = input.bool(false, title="  realized_price_bear_div", group=groupTestExits, display=display.none)
i_enable_longExitCondition_realized_price_bear_div_tiny         = input.bool(false, title="  realized_price_bear_div_tiny", group=groupTestExits, display=display.none)
i_enable_longExitCondition_realized_price_crossUnderUpper       = input.bool(false, title="  realized_price_crossUnderUpper", group=groupTestExits, display=display.none)
i_enable_longExitCondition_isFalling_smoothedM3_no_offset       = input.bool(false, title="  isFalling_smoothedM3_no_offset", group=groupTestExits, display=display.none)
i_enable_longExitCondition_testCondition                        = input.bool(false, title="  Test Condition", group=groupTestExits, display=display.none)

//}

//{ M3 Indicator Code }
groupM3          = "M3 Settings"
m3_growth_rate_period        = input.int(92, "92D-Daily percent gain period", group=groupM3,display=display.none)

// New smoothing inputs (add these)
m3_globalSmoothingMethod          = input.string(title="Money Supply Smoothing Method", options=["None", "Simple Moving Average", "Exponential Moving Average", "Hull Moving Average"],  defval="None", group=groupM3, display=display.none)
m3_globalSmoothingPeriod          = input.int(title="Money Supply Smoothing Period",  defval=14, minval=1, group=groupM3, display=display.none)
smoothM3SmoothingMethod           = input.string(title="Smooth M3 Moving Average", options=["None", "Simple Moving Average", "Exponential Moving Average", "Hull Moving Average"], defval="Exponential Moving Average", group=groupM3, display=display.none)
smoothM3SmoothingPeriod           = input.int(title="Smooth M3 Smoothing Period", defval=5, minval=1, group=groupM3, display=display.none)
m3LongEntryMode                   = input.string(title="Apply M3 to Long Entry", defval="Enabled", options=["Enabled", "Disabled", "Boost/Dampen Based on Trend"], group=groupM3,display=display.none)
m3LongEntryMinAllowed             = input.float(-1.15, "Minimum M3 required for Long Entry", step=0.10, group=groupM3,display=display.none)
m3LongExitMode                    = input.string(title="Apply M3 to Long Exit", defval="Boost Exit Conditions", options=["None", "Boost Exit Conditions", "Override and Immediately Exit"], group=groupM3,display=display.none)
m3LongExitMinAllowed              = input.float(-1.2, "Minimum M3 allowed before Immediate Long Exit", step=0.10, group=groupM3,display=display.none)
m3ShortEntryMode                  = input.string(title="Apply M3 to Short Entry", defval="Boost/Dampen Based on Trend", options=["Disabled", "Boost/Dampen Based on Trend"], group=groupM3,display=display.none)
m3ShortExitMode                   = input.string(title="Apply M3 to Short Exit", defval="Boost Exit Conditions", options=["None", "Boost Exit Conditions", "Override and Immediately Exit"], group=groupM3,display=display.none)
m3ShortEntryThreshold             = input.float(1.85, "M3 Short Entry Threshold, must be over this for entry", step=0.05, group=groupM3, display=display.none)
m3_growthRateTrendShortEntryThreshold        = input.float(-0.5, "M3 Trend Short Entry Threshold, must be under this for entry", step=0.10, group=groupM3, display=display.none)
m3_growthRateTrend2ShortEntryThreshold       = input.float(-0.5, "M3 Trend 2 Short Entry Threshold, must be under this for entry", step=0.10, group=groupM3, display=display.none)
m3_growthRateTrendsShortEntrySummedThreshold = input.float(-1.3, "M3 Trends Summed Short Entry Threshold, must be under this for entry", step=0.10, group=groupM3, display=display.none)

// Create and populate MoneySupplyInputs
moneySupplyInputs = libMoneySupply.MoneySupplySettings.new()
moneySupplyInputs.m3_growth_rate_period := m3_growth_rate_period
moneySupplyInputs.m3_globalSmoothingMethod := m3_globalSmoothingMethod
moneySupplyInputs.m3_globalSmoothingPeriod := m3_globalSmoothingPeriod
moneySupplyInputs.smoothM3SmoothingMethod := smoothM3SmoothingMethod
moneySupplyInputs.smoothM3SmoothingPeriod := smoothM3SmoothingPeriod
moneySupplyInputs.i_enable_timeframe_adjustment := i_enable_timeframe_adjustment
moneySupplyInputs.timeframe_divisor := timeframe_divisor

// Calculate money supply data
moneySupplyData = libMoneySupply.calculate_money_supply(moneySupplyInputs)
m2_US_EU_CN = moneySupplyData.m2_US_EU_CN
m3_global = moneySupplyData.m3_global
m3_global_smoothed = moneySupplyData.m3_global_smoothed
m3_growth_rate = moneySupplyData.m3_growth_rate
m3_growth_rate_smoothed = moneySupplyData.m3_growth_rate_smoothed    
//}

//{ Hullman Moving Average Indicators, fast moving average on m3_growth_rate }
hma_length                  = input(30, "HMA Length",group=groupM3, display=display.none)
hmaTrend_slope_period       = input.int(2, "hmaTrend_slope_period",group=groupM3, display=display.none)
hmaTrendThreshold           = input.float(-0.2, "hmaTrendThreshhold",step=0.10,group=groupM3, display=display.none)
hma_period_LongExit         = input(63, "HMA Period LongExit",group=groupM3, display=display.none)
hma_smooth_period_LongExit  = input(2, "HMA Smoothing Period LongExit",group=groupM3, display=display.none)
hma_period_LongEntry        = input(74, "HMA Period LongEntry(72 or 74?)",group=groupM3, display=display.none)
hma_smooth_period_LongEntry = input(2, "HMA Smoothing Period LongEntry",group=groupM3, display=display.none)
rocHMALongEntryThreshold    = input.float(-4.5,"rocHMALongEntryThreshold", step=0.1,group=groupM3, display=display.none)
rocHMALongExitThreshold     = input.float(-6.5,"rocHMALongExitThreshold", step=0.1,group=groupM3, display=display.none)

// Adjust periods
if i_enable_timeframe_adjustment
    hma_length                  := int(hma_length / timeframe_divisor) > 5000 ? 5000 : int(hma_length / timeframe_divisor) 
    hmaTrend_slope_period       := int(hmaTrend_slope_period / timeframe_divisor) > 5000 ? 5000 : int(hmaTrend_slope_period / timeframe_divisor) 
    hma_period_LongExit         := int(hma_period_LongExit / timeframe_divisor) > 5000 ? 5000 : int(hma_period_LongExit/ timeframe_divisor) 
    hma_smooth_period_LongExit  := int(hma_smooth_period_LongExit / timeframe_divisor) > 5000 ? 5000 : int(hma_smooth_period_LongExit / timeframe_divisor) 
    hma_period_LongEntry        := int(hma_period_LongEntry / timeframe_divisor) > 5000 ? 5000 : int(hma_period_LongEntry/ timeframe_divisor) 
    hma_smooth_period_LongEntry := int(hma_smooth_period_LongEntry / timeframe_divisor) > 5000 ? 5000 : int(hma_smooth_period_LongEntry / timeframe_divisor) 

// Calculations
hma = ta.hma(m3_growth_rate_smoothed, hma_length)
hmaTrend                 = hma - hma[hmaTrend_slope_period]
hmaTrend2                = hma - hma[hmaTrend_slope_period * 2]
rocHMALongExit           = (hma - hma[hma_period_LongExit]) / hma[hma_period_LongExit]
hma_smooth_roc_LongExit  = ta.sma(rocHMALongExit, hma_smooth_period_LongExit)
denominator = hma[hma_period_LongEntry]
// rocHMALongEntry_raw = if math.abs(denominator) > 0.1
//     (hma - denominator) / denominator
// else
//     0.0
// rocHMALongEntry_smoothed = ta.sma(rocHMALongEntry_raw, hma_smooth_period_LongEntry)
rocHMALongEntry_raw = (hma - denominator) / denominator
//}

//{ MACD Setup }
// Create settings object
macd_settings = macdLib.MACDSettings.new()
fast_length_1D                      = input.int(12,"Fast Length (1D)", group="MACD", display=display.none)
fast_length_12H                     = input.int(15,"Fast Length (12H)", group="MACD", display=display.none) // Tuned from 12
macd_settings.fast_length           := utils.f_getParamForTimeframe_int(fast_length_1D, fast_length_12H, fast_length_1D)
slow_length_1D                      = input.int(26,"Slow Length (1D)", group="MACD", display=display.none)
slow_length_12H                     = input.int(35,"Slow Length (12H)", group="MACD", display=display.none) // Tuned from 26
macd_settings.slow_length           := utils.f_getParamForTimeframe_int(slow_length_1D, slow_length_12H, slow_length_1D)
signal_length_1D                    = input.int(9,"Signal Smoothing (1D)",minval=1,maxval=50,group="MACD", display=display.none)
signal_length_12H                   = input.int(9,"Signal Smoothing (12H)",minval=1,maxval=50,group="MACD", display=display.none)
macd_settings.signal_length         := utils.f_getParamForTimeframe_int(signal_length_1D, signal_length_12H, signal_length_1D)
macd_settings.sma_source            := input.string("EMA","Oscillator MA Type",options=["SMA","EMA"],group="MACD", display=display.none)
macd_settings.sma_signal            := input.string("EMA","Signal Line MA Type",options=["SMA","EMA"],group="MACD", display=display.none)
macd_settings.bullishFlipSignalBars := input.int(1, "Stability in bars before bullish flip(1D=1)",group="MACD", display=display.none)
macd_settings.bearishFlipSignalBars := input.int(2, "Stability in bars before bearish flip",group="MACD", display=display.none)
macd_settings.i_macd_slope_threshold_percent := input(-9.0, "MACD Slope Threshold (%)", group="MACD", display=display.none)
macd_settings.nBarsOut              := input.int(5,"N bars in the future to predict crossover(1D=5)",group="MACD", display=display.none)

// Call the library function
macd_source  = input(title="Source",defval=close, group="MACD", display=display.none)
macd_results = macdLib.calculate_macd(macd_source, macd_settings)

// Unpack results
macd = macd_results.macd
signal = macd_results.signal
hist = macd_results.hist
isMacdHistRising = macd_results.isMacdHistRising
isMacdHistFalling = macd_results.isMacdHistFalling
macd_slope_above_threshold = macd_results.macd_slope_above_threshold
macd_is_increasing = macd_results.macd_is_increasing
macd_is_decreasing = macd_results.macd_is_decreasing
macd_prediction = macd_results.macd_prediction
macd_flipped_bullish = macd_results.macd_flipped_bullish
macd_flipped_bearish = macd_results.macd_flipped_bearish
macdLongEntryCondition = macd_results.macdLongEntryCondition
macdLongExitCondition = macd_results.macdLongExitCondition
macd_slope_current = macd_results.macd_slope_current
isMacdMinusMacdOneRising = macd_results.isMacdMinusMacdOneRising
macd_signal_difference_percentage = macd_results.macd_signal_difference_percentage
isMacdRising_len2 = macd_results.isMacdRising_len2 
//}

//{ Gaussian Channel Inputs }
groupGAUSSIAN = "Gaussian Settings"
poles           = input.int(defval=1, title="Poles", minval=1, maxval=9, group=groupGAUSSIAN, display=display.none)
per             = input.int(defval=146, title="Sampling Period", minval=2, group=groupGAUSSIAN, display=display.none)
mult            = input.float(defval=1.15, title="Filtered True Range Multiplier", minval=0, group=groupGAUSSIAN, display=display.none)
modeLag         = input.bool(defval=false, title="Reduced Lag Mode", group=groupGAUSSIAN, display=display.none)
modeFast        = input.bool(defval=false, title="Fast Response Mode", group=groupGAUSSIAN, display=display.none)
gaussian_src    = input(low, title="Gaussian Source(low)", group=groupGAUSSIAN, display=display.none)

// Adaptive MA Inputs
groupAMA        = "Adaptive MA Settings"
use_ama         = input.bool(true, "Use Adaptive MA", group=groupAMA, display=display.none)
ama_length      = input.int(3, "AMA Length(3)", minval=1, group=groupAMA, display=display.none)
ama_fast        = input.int(3, "AMA Fast Period(3)", minval=1, group=groupAMA, display=display.none)
ama_slow        = input.int(30, "AMA Slow Period(30)", minval=1, group=groupAMA, display=display.none)

// Timeframe Adjustment
if i_enable_timeframe_adjustment
    ama_length  := int(ama_length / timeframe_divisor) > 5000 ? 5000 : int(ama_length / timeframe_divisor)
    ama_fast    := int(ama_fast / timeframe_divisor) > 5000 ? 5000 : int(ama_fast / timeframe_divisor) 
    ama_slow    := int(ama_slow / timeframe_divisor) > 5000 ? 5000 : int(ama_slow / timeframe_divisor) 

// Create settings object
settings = gcl.GaussianSettings.new(
     poles = poles, 
     per = per, 
     mult = mult, 
     modeLag = modeLag, 
     modeFast = modeFast, 
     useAma = use_ama, 
     amaLength = ama_length, 
     amaFast = ama_fast, 
     amaSlow = ama_slow, 
     useSimpleCalc = false
 )

// Call the library function
[hband, lband, ma, gaussianGreen] = gcl.calc( gaussian_src, settings)
//} ========================

//{ Stochastic RSI Calculation }

groupStochRSI       = "Stochastic RSI Settings"
stochMasterSwitch   = input.string("Enabled", title="Stochastic RSI Master Switch", options=["Enabled","Disabled"], group= groupStochRSI, display=display.none)
smoothK_1D          = input.int(4,  "K (1D)", minval=1, group= groupStochRSI, display=display.none)
smoothK_12H         = input.int(2,  "K (12H)", minval=1, group= groupStochRSI, display=display.none)
smoothK             = utils.f_getParamForTimeframe_int(smoothK_1D, smoothK_12H, smoothK_1D)
smoothD             = input.int(3,  "D", minval=1, group= groupStochRSI, display=display.none)
lengthRSI           = input.int(10, "RSI Length", minval=1, group= groupStochRSI, display=display.none)
lengthStoch_1D      = input.int(17, "Stochastic Length (1D)", minval=1, group= groupStochRSI, display=display.none)
lengthStoch_12H     = input.int(12, "Stochastic Length (12H)", minval=1, group= groupStochRSI, display=display.none)
lengthStoch         = utils.f_getParamForTimeframe_int(lengthStoch_1D, lengthStoch_12H, lengthStoch_1D)
src_stoch           = input(close,  title="RSI Source", group= groupStochRSI, display=display.none)
stoch_tf            = input.timeframe("", "Stoch RSI Timeframe", group= groupStochRSI, display=display.none)
stoch_high_limit    = input.int(87, title="Stochastic High Limit", group= groupStochRSI, display=display.none)
stoch_low_limit     = input.int(20, title="Stochastic Low Limit", group= groupStochRSI, display=display.none)
calcStoch()         => ta.sma(ta.stoch(ta.rsi(src_stoch, lengthRSI), ta.rsi(src_stoch, lengthRSI), ta.rsi(src_stoch, lengthRSI), lengthStoch), smoothK)
stoch_value         = stoch_tf == "" ? calcStoch() : request.security(syminfo.tickerid, stoch_tf, calcStoch(), gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_off)
bool stochCondition = stochMasterSwitch == "Enabled" ? (stoch_value > stoch_high_limit or stoch_value < stoch_low_limit) : true
osc_high_limit      = input.int(67, title="Maximum RSI allowed on regular long entry condition(67)", group= groupStochRSI, display=display.none)
osc_src             = input(low, "OSC source(low)", group= groupStochRSI, display=display.none)

if i_enable_timeframe_adjustment
    lengthRSI      := int(lengthRSI / timeframe_divisor) > 5000 ? 5000 : int(lengthRSI / timeframe_divisor)
    lengthStoch    := int(lengthStoch / timeframe_divisor) > 5000 ? 5000 : int(lengthStoch / timeframe_divisor)
//} ========================

//{ Stochastic Divergence}
groupStochDiv = "Stochastic Divergence"
stochDivSettings = libStochDiv.StochasticDivergenceSettings.new()
stochDivSettings.stochLength := input.int(14, title="Stochastic Length", minval=1, group=groupStochDiv, display=display.none)
stochDivSettings.smoothK := input.int(3, title="K Smoothing", minval=1, group=groupStochDiv, display=display.none)
stochDivSettings.smoothD := input.int(3, title="D Smoothing", minval=1, group=groupStochDiv, display=display.none)
stochDivSettings.maTypeK := input.string("Simple Moving Average", "MA Type K", options=["Simple Moving Average", "Exponential Moving Average", "Weighted Moving Average", "Hull Moving Average", "Volume Weighted Moving Average", "Volume Weighted Average Price", "None"], group=groupStochDiv, display=display.none)
stochDivSettings.maTypeD := input.string("Exponential Moving Average", "MA Type D", options=["Simple Moving Average", "Exponential Moving Average", "Weighted Moving Average", "Hull Moving Average", "Volume Weighted Moving Average", "Volume Weighted Average Price", "None"], group=groupStochDiv, display=display.none)
stochDivSettings.pivotLookback := input.int(5, title="Pivot Lookback Bars", minval=1, group=groupStochDiv, display=display.none)
stochDivSettings.divergenceStrength := input.int(2, title="Divergence Strength (bars away)", minval=1, group=groupStochDiv, display=display.none)

if i_enable_timeframe_adjustment
    stochDivSettings.stochLength   := int(stochDivSettings.stochLength / timeframe_divisor) > 5000 ? 5000 : int(stochDivSettings.stochLength / timeframe_divisor)
    stochDivSettings.pivotLookback := int(stochDivSettings.pivotLookback / timeframe_divisor) > 5000 ? 5000 : int(stochDivSettings.pivotLookback / timeframe_divisor)

[stoch_bullishDivergence, stoch_bearishDivergence] = libStochDiv.f_calc(stochDivSettings)
//} ========================

//{ VWAP Divergence }
groupVwapDiv = "VWAP Divergence"
vwapDivSettings = libVwapDiv.VWAPDivergenceSettings.new()
vwapDivSettings.pivotLookbackLeft := input.int(1, title="Pivot Lookback Bars Left", minval=1, group=groupVwapDiv, display=display.none)
vwapDivSettings.pivotLookbackRight := input.int(1, title="Pivot Lookback Bars Right", minval=1, group=groupVwapDiv, display=display.none)
vwapDivSettings.divergenceStrength := input.int(2, title="Divergence Strength (bars away)", minval=1, group=groupVwapDiv, display=display.none)

[vwap_bullishDivergence, vwap_bearishDivergence] = libVwapDiv.f_calc(vwapDivSettings)
//} ========================

//{ M3 Indicator }

m3_growthRateTrend        = m3_growth_rate_smoothed - nz(m3_growth_rate_smoothed[1], m3_growth_rate_smoothed)
m3_growthRateTrend2       = m3_growth_rate_smoothed - nz(m3_growth_rate_smoothed[2], m3_growth_rate_smoothed)
m3Clamped      = utils.f_clamp(m3_growth_rate_smoothed, -5.0, 15.0)
m3ClampedScale = (m3Clamped + 5.0) / 20.0
var bool m3LongEntryCondition = true
if m3LongEntryMode == "Disabled"
    m3LongEntryCondition := false
if m3LongEntryMode == "Enabled"
    m3LongEntryCondition := true
if m3LongEntryMode == "Boost/Dampen Based on Trend"
    if m3_growthRateTrend > 0
        m3LongEntryCondition := (m3ClampedScale > 0.10)
    else
        m3LongEntryCondition := (m3ClampedScale > 0.50)
bool m3ExitCondition = false
if m3LongExitMode == "Boost Exit Conditions"
    m3ExitCondition := (m3_growth_rate_smoothed < 0) and (m3_growthRateTrend <= 0)
if m3LongExitMode == "Override and Immediately Exit"
    if (m3_growth_rate_smoothed < m3LongExitMinAllowed) and (m3_growthRateTrend <= 0)
        m3ExitCondition := true

groupM3ROC                      = "M3 Growth Rate Rate of Change"
m3ROCEnabledEntry               = input.string("Enabled", "Include Rate of Change of M3 on Long Entry", options=["Disabled","Enabled"], group=groupM3ROC, display=display.none)
m3_growth_rate_smoothed_rocLongEntryThreshold  = input.float(40, "m3_growth_rate_smoothed_rocLongEntryThreshold(40)", step=1.0, group=groupM3ROC, display=display.none)
m3ROCEnabledExit                = input.string("Disabled", "Include Rate of Change of M3 on Long Exit",  options=["Disabled","Enabled"], group=groupM3ROC, display=display.none)
m3_growth_rate_smoothed_rocLongExitThreshold   = input.float(-15, "m3_growth_rate_smoothed_rocLongExitThreshold(-15)", step=1.0, group=groupM3ROC, display=display.none)
roc_period                      = input.int(2, "ROC Period", group=groupM3ROC, display=display.none)
smooth_period                   = input.int(5, "Smoothing Period", group=groupM3ROC, display=display.none)
rocLongEntrySource              = input.string("smoothed_roc", "ROC Source for Long Entry", options=["m3_growthRateRocPercentage","smoothed_roc"], group=groupM3ROC, display=display.none)
rocLongExitSource               = input.string("smoothed_roc", "ROC Source for Long Exit",  options=["m3_growthRateRocPercentage","smoothed_roc"], group=groupM3ROC, display=display.none)

if i_enable_timeframe_adjustment
    roc_period      := int(roc_period / timeframe_divisor) > 5000 ? 5000 : int(roc_period / timeframe_divisor) 
    smooth_period   := int(smooth_period / timeframe_divisor) > 5000 ? 5000 : int(smooth_period / timeframe_divisor) 

//m3_growth_rate_roc = ((m3_growth_rate_smoothed - nz(m3_growth_rate_smoothed[roc_period])) / nz(m3_growth_rate_smoothed[roc_period])) * 100  // TODO DEBUG   was / 5 or * 100 New definition just below
m3_growth_rate_roc  = ((m3_growth_rate_smoothed - nz(m3_growth_rate_smoothed[roc_period])) / nz(m3_growth_rate_smoothed[roc_period])) // NEW with smoothing first, also took off the divide by 5  to get similar peak heights as previous implementation

m3_growthRateRocPercentage             = ((m3_growth_rate_smoothed - nz(m3_growth_rate_smoothed[roc_period])) / nz(m3_growth_rate_smoothed[roc_period])) * 100  // TODO DEBUG   was / 5 or * 100
//m3_growthRateRocPercentage = m3_growth_rate_roc * 100

float entryROcM3    = rocLongEntrySource == "m3_growthRateRocPercentage" ? m3_growthRateRocPercentage : m3_growth_rate_roc
float exitROcM3     = rocLongExitSource  == "m3_growthRateRocPercentage" ? m3_growthRateRocPercentage : m3_growth_rate_roc
bool rocLongEntryCondition = (m3ROCEnabledEntry == "Enabled") and (entryROcM3 >= m3_growth_rate_smoothed_rocLongEntryThreshold)
bool rocLongExitCondition  = (m3ROCEnabledExit == "Enabled") and (exitROcM3 <= m3_growth_rate_smoothed_rocLongExitThreshold)

m3_growthRateRocPercentage_flipped_bullish          = macdLib.getSequenceReversal_M3(-m3_growthRateRocPercentage, 3, 2, i_enable_timeframe_adjustment, timeframe_divisor)
m3_growthRateRocPercentage_flipped_bearish          = macdLib.getSequenceReversal_M3(m3_growthRateRocPercentage, 3, 2, i_enable_timeframe_adjustment, timeframe_divisor)
isM3GrowthRateRocRawFlippedBullish   = macdLib.getSequenceReversal_M3(-m3_growth_rate_roc, 3, 2, i_enable_timeframe_adjustment, timeframe_divisor)
//m3_growth_rate_roc_flipped_bearish = getSequenceReversal(m3_growth_rate_roc, 3, 2)

//plotchar(m3_growthRateRocPercentage_flipped_bullish ? 1.0 : 0.0, title="U - m3_growthRateRocPercentage_flipped_bullish", color=color.gray, char="U")
plotchar(m3_growthRateRocPercentage_flipped_bearish ? 1.0 : 0.0, title="R - m3_growthRateRocPercentage_flipped_bearish", color=color.green, char="R", display=display.data_window)
plotchar(stoch_bullishDivergence ? 1.0 : 0.0, title="S - stoch_bullishDivergence", color=color.blue, char="S", display=display.data_window)
plotchar(macd_flipped_bullish ? 1.0 : 0.0, title="M - macd_flipped_bullish", color=color.orange, char="M", display=display.data_window)
//}

//{ Price Peak and Trough Detection } 
groupPricePeaksAndTroughs   = "Price Peaks and Troughs"

// --- Inputs ---
// group_m2LeadingIndicator_calculations = "M2LI Calculations" // This group name should be defined earlier in your script.
i_lookbackDaysPeak          = input.int(defval=32, title="Peak  Lookback (Days)", minval=1, group=groupPricePeaksAndTroughs, display=display.none)
i_lookbackDaysTrough        = input.int(defval=32, title="Trough  Lookback (Days)", minval=1, group=groupPricePeaksAndTroughs, display=display.none)

if i_enable_timeframe_adjustment  // TODO may want to add another switch and or multiplier to improve perf on shorter timeframes
    i_lookbackDaysPeak      := int(i_lookbackDaysPeak / timeframe_divisor) > 5000 ? 5000 : int(i_lookbackDaysPeak / timeframe_divisor) 
    i_lookbackDaysTrough    := int(i_lookbackDaysTrough / timeframe_divisor) > 5000 ? 5000 : int(i_lookbackDaysTrough / timeframe_divisor) 

pricePeak                   = ta.highest(nz(high), nz(i_lookbackDaysPeak))
priceTrough                 = ta.lowest(nz(low), nz(i_lookbackDaysTrough))

//}

//{ M2LeadingIndicator Indicator }
group_m2LeadingIndicator_visuals       = "M2 Leading Indicator Visuals"
i_m2LeadingIndicator_showPlots         = input.bool(true, "Show Plots", tooltip="Display plots or not, does not affect strategy calculations", group=group_m2LeadingIndicator_visuals, display=display.none, inline="m2VisualSwitches")
i_m2LeadingIndicator_tempMultiplier    = input.int(1000, "Multiplier", tooltip="Multiplier value just to try to get it to show up on chart near price without blowing out the scale, adjust as needed", group=group_m2LeadingIndicator_visuals, display=display.none)
i_m2LeadingIndicator_tempAdjustUp      =  input(60000.0, "Adjust M2 plot up by this value", tooltip="Just for charting purposes, no effect on strategy", group=group_m2LeadingIndicator_visuals, display=display.none) //  / 2.0 //40000  // TODO Likely needs to be subsequently multiplied by 0.95 later
i_m2LeadingIndicator_tempAdjustUp     := i_m2LeadingIndicator_tempAdjustUp * 0.9 // to scale it down slightly to no blow out chart
group_m2LeadingIndicator_calculations  = "M2 Leading Indicator Calculations"
//i_m2li_applyScaling    = input.bool(true,"Apply scaling 0 to 100", tooltip="This adjust along the way so the farther right you go may change values on the left as new highs occur", group=group_m2LeadingIndicator_calculations, display=display.none)
m2LeadingIndicator_scalingLookback     = input.int(150, title="Scaling Lookback Period(150)", minval=2, group=group_m2LeadingIndicator_calculations, tooltip="Number of bars used to find the min/max values for scaling the M2 plots.", display=display.none)
i_m2LeadingIndicator_smoothingMethod   = input.string("Hull Moving Average", title="M2 Smoothing Method", options=["None", "Simple Moving Average", "Exponential Moving Average", "Hull Moving Average"], group=group_m2LeadingIndicator_calculations, display=display.none)
i_m2LeadingIndicator_barsToRightOfShortLength = input.int(10,"Bars from short length for diff/slope calculations(10)", group=group_general_settings, display=display.none, tooltip = "Value used in multiple entry and exit calculations, huge effect on performance")
i_m2LeadingIndicator_microOffset       = input.int(3, title= "Micro offset, orange line(3)", group=group_m2LeadingIndicator_calculations, display=display.none)
i_m2LeadingIndicator_miniOffset        = input.int(10, title="Mini offset, orange line(10)", group=group_m2LeadingIndicator_calculations, display=display.none)
i_m2LeadingIndicator_tinyOffset        = input.int(48, "Tiny offset, orange line(48)", group=group_m2LeadingIndicator_calculations, display=display.none)
i_m2LeadingIndicator_shortOffset       = input.int(64, "Short offset, orange line(64)", group=group_m2LeadingIndicator_calculations, display=display.none)
i_m2LeadingIndicator_shortOffset_smoothingLength = input.int(13, "Short Offset Smoothing Length(13)", group=group_m2LeadingIndicator_calculations, display=display.none)
i_m2LeadingIndicator_mediumOffset      = input.int(78, "Medium offset, red line", group=group_m2LeadingIndicator_calculations, display=display.none)
i_m2LeadingIndicator_mediumOffset_smoothingLength = input.int(16, "Medium Offset Smoothing Length", group=group_m2LeadingIndicator_calculations, display=display.none)
i_m2LeadingIndicator_longOffset        = input.int(92, "Long offset, yellow line(92)", group=group_m2LeadingIndicator_calculations, display=display.none)
i_m2LeadingIndicator_longOffset_smoothingLength = input.int(20, "Long Offset Smoothing Length", group=group_m2LeadingIndicator_calculations, display=display.none)
i_m2LeadingIndicator_riseFallLength    = input.int(3, "Length to use for calculating Rise/Fall", group=group_m2LeadingIndicator_calculations, display=display.none) // TODO may later want to have different lengths for different offsets?
i_m2LeadingIndicator_oneDayOffset      = input.int(1, "Adjustment factor for one day, unclear if scaling it is needed", group=group_m2LeadingIndicator_calculations, display=display.none)  

if i_enable_timeframe_adjustment
    m2LeadingIndicator_scalingLookback                := int(m2LeadingIndicator_scalingLookback / timeframe_divisor) > 5000 ? 5000 : int(m2LeadingIndicator_scalingLookback/ timeframe_divisor)
    i_m2LeadingIndicator_barsToRightOfShortLength     := int(i_m2LeadingIndicator_barsToRightOfShortLength / timeframe_divisor) > 5000 ? 5000 : int(i_m2LeadingIndicator_barsToRightOfShortLength/ timeframe_divisor)
    i_m2LeadingIndicator_tinyOffset                   := int(i_m2LeadingIndicator_tinyOffset / timeframe_divisor) > 5000 ? 5000 : int(i_m2LeadingIndicator_tinyOffset/ timeframe_divisor)
    i_m2LeadingIndicator_shortOffset                  := int(i_m2LeadingIndicator_shortOffset / timeframe_divisor) > 5000 ? 5000 : int(i_m2LeadingIndicator_shortOffset / timeframe_divisor)
    i_m2LeadingIndicator_shortOffset_smoothingLength  := int(i_m2LeadingIndicator_shortOffset_smoothingLength / timeframe_divisor) > 5000 ? 5000 : int(i_m2LeadingIndicator_shortOffset_smoothingLength/ timeframe_divisor)
    i_m2LeadingIndicator_mediumOffset                 := int(i_m2LeadingIndicator_mediumOffset / timeframe_divisor) > 5000 ? 5000 : int(i_m2LeadingIndicator_mediumOffset / timeframe_divisor)
    i_m2LeadingIndicator_mediumOffset_smoothingLength := int(i_m2LeadingIndicator_mediumOffset_smoothingLength / timeframe_divisor) > 5000 ? 5000 : int(i_m2LeadingIndicator_mediumOffset_smoothingLength/ timeframe_divisor)
    i_m2LeadingIndicator_longOffset                   := int(i_m2LeadingIndicator_longOffset / timeframe_divisor) > 5000 ? 5000 : int(i_m2LeadingIndicator_longOffset / timeframe_divisor)
    i_m2LeadingIndicator_longOffset_smoothingLength   := int(i_m2LeadingIndicator_longOffset_smoothingLength / timeframe_divisor) > 5000 ? 5000 : int(i_m2LeadingIndicator_longOffset_smoothingLength/ timeframe_divisor)
    i_m2LeadingIndicator_riseFallLength               := int(i_m2LeadingIndicator_riseFallLength  / timeframe_divisor) > 5000 ? 5000 : int(i_m2LeadingIndicator_riseFallLength / timeframe_divisor)
    i_m2LeadingIndicator_oneDayOffset                 := int(i_m2LeadingIndicator_oneDayOffset  / timeframe_divisor) > 5000 ? 5000 : int(i_m2LeadingIndicator_oneDayOffset / timeframe_divisor)

plot(m2_US_EU_CN, title="Debug: m2_US_EU_CN tiny_offset", color=color.white, offset=i_m2LeadingIndicator_tinyOffset, display=display.all-display.status_line) // tiny is 48
plot(m3_global / 1.51,          title="Debug: m3_global tiny_offset / 1.51", color=color.rgb(93, 238, 108), offset=i_m2LeadingIndicator_tinyOffset, display=display.all-display.status_line) // testing to see if adjusted to scale to they still show differences

m2_smoothed_microOffset     = utils.f_ma(m2_US_EU_CN, i_m2LeadingIndicator_smoothingMethod, i_m2LeadingIndicator_shortOffset_smoothingLength) // TODO maybe later add tiny_offset_smoothingLength
m2_smoothed_miniOffset      = utils.f_ma(m2_US_EU_CN, i_m2LeadingIndicator_smoothingMethod, i_m2LeadingIndicator_shortOffset_smoothingLength) // TODO maybe later add tiny_offset_smoothingLength
m2_smoothed_tinyOffset      = utils.f_ma(m2_US_EU_CN, i_m2LeadingIndicator_smoothingMethod, i_m2LeadingIndicator_shortOffset_smoothingLength) // TODO maybe later add tiny_offset_smoothingLength
m2_smoothed_shortOffset     = utils.f_ma(m2_US_EU_CN, i_m2LeadingIndicator_smoothingMethod, i_m2LeadingIndicator_shortOffset_smoothingLength)
m2_smoothed_mediumOffset    = utils.f_ma(m2_US_EU_CN, i_m2LeadingIndicator_smoothingMethod, i_m2LeadingIndicator_mediumOffset_smoothingLength)
m2_smoothed_longOffset      = utils.f_ma(m2_US_EU_CN, i_m2LeadingIndicator_smoothingMethod, i_m2LeadingIndicator_longOffset_smoothingLength)

m2_smoothedTinyOffsetSlope     = m2_smoothed_shortOffset[i_m2LeadingIndicator_tinyOffset] - m2_smoothed_shortOffset[(i_m2LeadingIndicator_tinyOffset + i_m2LeadingIndicator_oneDayOffset) > 5000 ? 5000 : (i_m2LeadingIndicator_tinyOffset + i_m2LeadingIndicator_oneDayOffset)]
m2_smoothedShortOffsetSlope    = m2_smoothed_shortOffset[i_m2LeadingIndicator_shortOffset] - m2_smoothed_shortOffset[(i_m2LeadingIndicator_shortOffset + i_m2LeadingIndicator_oneDayOffset) > 5000 ? 5000 : (i_m2LeadingIndicator_shortOffset + i_m2LeadingIndicator_oneDayOffset)]
m2_smoothedMediumOffsetSlope   = m2_smoothed_mediumOffset[i_m2LeadingIndicator_mediumOffset] - m2_smoothed_mediumOffset[(i_m2LeadingIndicator_mediumOffset + i_m2LeadingIndicator_oneDayOffset) > 5000 ? 5000 : (i_m2LeadingIndicator_mediumOffset + i_m2LeadingIndicator_oneDayOffset) ]
m2_smoothedLongOffsetSlope     = m2_smoothed_longOffset[i_m2LeadingIndicator_longOffset] - m2_smoothed_longOffset[(i_m2LeadingIndicator_longOffset + i_m2LeadingIndicator_oneDayOffset) > 5000 ? 5000 : (i_m2LeadingIndicator_longOffset + i_m2LeadingIndicator_oneDayOffset)]

isM2SmoothedMicroOffsetRising    = false // should not be necessary, but seeing some headscratchers with conditions firing that shouldn't
isM2SmoothedMiniOffsetRising     = false
isM2SmoothedTinyOffsetRising     = false
isM2SmoothedShortOffsetRising    = false
isM2SmoothedMediumOffsetRising   = false
isM2SmoothedLongOffsetRising     = false

isRising_smoothedM3_no_offset = ta.rising (m3_global_smoothed, i_m2LeadingIndicator_riseFallLength)
isFalling_smoothedM3_no_offset= ta.falling(m3_global_smoothed, i_m2LeadingIndicator_riseFallLength)

isM2SmoothedMicroOffsetRising    := ta.rising(m2_smoothed_microOffset, i_m2LeadingIndicator_riseFallLength)  // TODO maybe later add tiny_offset_smoothingLength
isM2SmoothedMiniOffsetRising     := ta.rising(m2_smoothed_miniOffset, i_m2LeadingIndicator_riseFallLength)
isM2SmoothedTinyOffsetRising     := ta.rising(m2_smoothed_shortOffset, i_m2LeadingIndicator_riseFallLength)  // TODO maybe later add tiny_offset_smoothingLength
isM2SmoothedShortOffsetRising    := ta.rising(m2_smoothed_shortOffset, i_m2LeadingIndicator_riseFallLength)
isM2SmoothedMediumOffsetRising   := ta.rising(m2_smoothed_mediumOffset, i_m2LeadingIndicator_riseFallLength)
isM2SmoothedLongOffsetRising     := ta.rising(m2_smoothed_longOffset, i_m2LeadingIndicator_riseFallLength)

isRising_smoothedM3_short_offset     = ta.rising(m3_growth_rate_smoothed[i_m2LeadingIndicator_shortOffset], i_m2LeadingIndicator_shortOffset_smoothingLength)
isFalling_smoothedM3_short_offset    = ta.falling(m3_growth_rate_smoothed[i_m2LeadingIndicator_shortOffset], i_m2LeadingIndicator_shortOffset_smoothingLength)

isM2SmoothedMicroOffsetFalling   = ta.falling(m2_smoothed_microOffset, i_m2LeadingIndicator_riseFallLength)
isM2SmoothedMiniOffsetFalling    = ta.falling(m2_smoothed_miniOffset, i_m2LeadingIndicator_riseFallLength)
isM2SmoothedTinyOffsetFalling    = ta.falling(m2_smoothed_shortOffset, i_m2LeadingIndicator_riseFallLength)  // TODO maybe later add tiny_offset_smoothingLength
isM2SmoothedShortOffsetFalling   = ta.falling(m2_smoothed_shortOffset, i_m2LeadingIndicator_riseFallLength)
isM2SmoothedMediumOffsetFalling  = ta.falling(m2_smoothed_mediumOffset, i_m2LeadingIndicator_riseFallLength)
isM2SmoothedLongOffsetFalling    = ta.falling(m2_smoothed_longOffset, i_m2LeadingIndicator_riseFallLength)

isM2SmoothedTinyOffsetFlat       = not isM2SmoothedTinyOffsetRising   and not isM2SmoothedTinyOffsetFalling
isM2SmoothedShortOffsetFlat      = not isM2SmoothedShortOffsetRising  and not isM2SmoothedShortOffsetFalling
isM2SmoothedMediumOffsetFlat     = not isM2SmoothedMediumOffsetRising and not isM2SmoothedMediumOffsetFalling
isM2SmoothedLongOffsetFlat       = not isM2SmoothedLongOffsetRising   and not isM2SmoothedLongOffsetFalling

i_outputSmoothing   = input.int(3, title="Output Smoothing Length", group="M2LI Calculations", display=display.none)
i_m2LeadingIndicator_scaledOffset = input.int(74, title="Scaled Offset", group="M2LI Calculations", display=display.none )

if i_enable_timeframe_adjustment
    i_outputSmoothing   := int(i_outputSmoothing / timeframe_divisor) > 5000 ? 5000 : int(i_outputSmoothing/ timeframe_divisor)
    i_m2LeadingIndicator_scaledOffset := int(i_m2LeadingIndicator_scaledOffset / timeframe_divisor) > 5000 ? 5000 : int(i_m2LeadingIndicator_scaledOffset / timeframe_divisor)

//m2_defaultScaleRange = 100.0
m2_smoothed_tinyOffset   := utils.f_scale_ToRange(m2_smoothed_tinyOffset,  m2LeadingIndicator_scalingLookback, m2LeadingIndicator_scalingLookback)
m2_smoothed_shortOffset  := utils.f_scale_ToRange(m2_smoothed_shortOffset,  m2LeadingIndicator_scalingLookback, m2LeadingIndicator_scalingLookback)
m2_smoothed_mediumOffset := utils.f_scale_ToRange(m2_smoothed_mediumOffset, m2LeadingIndicator_scalingLookback, m2LeadingIndicator_scalingLookback)
m2_smoothed_longOffset   := utils.f_scale_ToRange(m2_smoothed_longOffset,   m2LeadingIndicator_scalingLookback, m2LeadingIndicator_scalingLookback)

msInDay = 1000 * 60 * 60 * 24
offsetTime = time - (i_m2LeadingIndicator_scaledOffset * msInDay)  // TODO figure out how to apply:  "if i_enable_timeframe_adjustment" 
sourceOffsetBars = ta.barssince(time <= offsetTime)
int finalOffset = na(sourceOffsetBars) ? 0 : sourceOffsetBars

// 3. Get the historical source value using the bar offset.
float historical_source_val = m2_smoothed_mediumOffset[finalOffset]

// 4. Call the scaling function with the HISTORICAL source and CURRENT price range.
// We are re-enabling clamping to prevent overshoots.
float scaled_historical_value = utils.f_scale_ToRange(historical_source_val, i_lookbackDaysPeak, i_lookbackDaysTrough, pricePeak, priceTrough, true)

// 5. Apply a small amount of smoothing for a cleaner visual.
m2_smoothed_mediumOffset_scaledToClosingPrice = ta.ema(scaled_historical_value, i_outputSmoothing)
// Rise over run
m2_smoothedTiny_N_bars_out         = m2_smoothed_tinyOffset[i_m2LeadingIndicator_tinyOffset - i_m2LeadingIndicator_barsToRightOfShortLength]  // TODO may later want own i_m2li_bars_to_right_of_tiny_length variable
m2_smoothedShort_N_bars_out        = m2_smoothed_shortOffset[i_m2LeadingIndicator_shortOffset - i_m2LeadingIndicator_barsToRightOfShortLength]
m2_smoothedMedium_12_bars_out      = m2_smoothed_mediumOffset[i_m2LeadingIndicator_shortOffset]


m2_tinyOffsetDiffToNbarsOut        = m2_smoothedTiny_N_bars_out - m2_smoothed_tinyOffset[i_m2LeadingIndicator_tinyOffset]
m2_shortOffsetDiffToNbarsOut       = m2_smoothedShort_N_bars_out - m2_smoothed_shortOffset[i_m2LeadingIndicator_shortOffset]
m2_mediumOffsetDiffTo12barsOut     = m2_smoothedShort_N_bars_out - m2_smoothed_shortOffset[i_m2LeadingIndicator_mediumOffset]


m2_shortOffsetSlopeToNbarsOut      = m2_shortOffsetDiffToNbarsOut / nz(i_m2LeadingIndicator_barsToRightOfShortLength)
m2_mediumOffsetSlopeTo12barsOut    = m2_shortOffsetDiffToNbarsOut / nz(i_m2LeadingIndicator_barsToRightOfShortLength)

m2_smoothedTinyOffsetSlope_diff    = m2_smoothedTinyOffsetSlope - m2_smoothedTinyOffsetSlope[1]
m2_smoothedShortOffsetSlope_diff   = m2_smoothedShortOffsetSlope - m2_smoothedShortOffsetSlope[1]

//} ========================

//{ M2 MACD Calculations

group_m2_macd       = "M2 MACD Settings"
i_m2Macd_showSignals = input.bool(true, "Show M2 MACD signals", group=group_m2_macd)
i_m2Macd_fastLength     = input.int(50, title="Fast Length", minval=1,  group=group_m2_macd, tooltip="Fast Moving Average length for MACD calculation on *Original* Total M2.", display=display.none)
i_m2Macd_slowLength     = input.int(200, title="Slow Length", minval=1, group=group_m2_macd, tooltip="Slow Moving Average length for MACD calculation on *Original* Total M2.", display=display.none)
i_m2Macd_signalLength   = input.int(9, title="Signal Length", minval=1, group=group_m2_macd, tooltip="Signal Line smoothing length for MACD.", display=display.none)

if i_enable_timeframe_adjustment
    i_m2Macd_fastLength   := int(i_m2Macd_fastLength / timeframe_divisor) > 5000 ? 5000 : int(i_m2Macd_fastLength / timeframe_divisor)
    i_m2Macd_slowLength   := int(i_m2Macd_slowLength / timeframe_divisor) > 5000 ? 5000 : int(i_m2Macd_slowLength / timeframe_divisor)
    i_m2Macd_signalLength := int(i_m2Macd_signalLength / timeframe_divisor) > 5000 ? 5000 : int(i_m2Macd_signalLength / timeframe_divisor)

// Calculate MACD on *Original* Total M2
m2Macd_fastMA       = ta.ema(m2_US_EU_CN, i_m2Macd_fastLength)
m2Macd_slowMA       = ta.ema(m2_US_EU_CN, i_m2Macd_slowLength)
m2Macd_line     = m2Macd_fastMA - m2Macd_slowMA
m2Macd_signalLine   = ta.ema(m2Macd_line, i_m2Macd_signalLength)
m2Macd_hist         = m2Macd_line - m2Macd_signalLine

// MACD Histogram Cross Signals

//short
isM2MacdShortCrossBullish = ta.crossover(m2Macd_line[i_m2LeadingIndicator_shortOffset], m2Macd_signalLine[i_m2LeadingIndicator_shortOffset])
isM2MacdShortCrossBearish = ta.crossunder(m2Macd_line[i_m2LeadingIndicator_shortOffset], m2Macd_signalLine[i_m2LeadingIndicator_shortOffset])
//plot(m2Macd_line, "m2Macd_line", color=color.blue, offset=i_m2LeadingIndicator_longOffset)
m2Macd_shortOffsetDifference = m2Macd_line[i_m2LeadingIndicator_shortOffset] - m2Macd_signalLine[i_m2LeadingIndicator_shortOffset]
plotchar(m2Macd_shortOffsetDifference, title="Debug: m2Macd_shortOffsetDifference", char="L", location=location.abovebar, color=m2Macd_shortOffsetDifference > 0 ? color.green : color.red, display = display.data_window)

//Medium
isM2MacdMediumCrossBullish = ta.crossover(m2Macd_line[i_m2LeadingIndicator_mediumOffset], m2Macd_signalLine[i_m2LeadingIndicator_mediumOffset])
isM2MacdMediumCrossBearish = ta.crossunder(m2Macd_line[i_m2LeadingIndicator_mediumOffset], m2Macd_signalLine[i_m2LeadingIndicator_mediumOffset])
//plot(m2Macd_line, "Debug: m2Macd_line", color=color.blue, offset=i_m2LeadingIndicator_longOffset)

// long
isM2MacdLongCrossBullish = ta.crossover(m2Macd_line[i_m2LeadingIndicator_longOffset], m2Macd_signalLine[i_m2LeadingIndicator_longOffset])
isM2MacdLongCrossBearish = ta.crossunder(m2Macd_line[i_m2LeadingIndicator_longOffset], m2Macd_signalLine[i_m2LeadingIndicator_longOffset])
//} ========================

//{ Stop Loss }
i_longStopLossEnabled   = input.bool(true, title="(T)Enable Stop Loss", group=group_general_settings, tooltip="Enable to have stop losses applied to long entries", display=display.none, inline="StopLoss")
i_longStopLossSrc       = input.source(close,  title="Source", group=group_general_settings, tooltip="Price Source", display=display.none, inline="StopLoss")
i_longStopLossPercent   = input.float(25.0, title="%(25)", group=group_general_settings, tooltip="Enter at which percentage that you want stop loss applied.", display=display.none, inline="StopLoss") / 100 
i_useAtrStop            = input.bool(false, title="(F)Use ATR Stop", group=group_general_settings, tooltip="If true, the stop loss is based on a multiple of the ATR instead of a percentage.", display=display.none, inline="AtrStop")
i_atrLength             = input.int(7, "Length", group=group_general_settings, display=display.none, inline="AtrStop")
i_atrMultiplier         = input.float(4, "Multiplier", group=group_general_settings, display=display.none, inline="AtrStop")
if i_enable_timeframe_adjustment
    i_atrLength := int(i_atrLength / timeframe_divisor) > 5000 ? 5000 : int(i_atrLength / timeframe_divisor)

i_use_trailing_stoploss = input.bool(true, group=group_general_settings, title=" (T)Use Trailing Stop", tooltip="If enabled the stop loss price adjusts along the way based on current price", display=display.none)

var longStopPrice = 0.0

// 1. Calculate the ATR value.
atrValue = ta.atr(i_atrLength)

// 2. Determine the stop loss offset based on the user's selected method (ATR or Percentage).
stopLossOffset = i_useAtrStop ? (atrValue * i_atrMultiplier) : (i_longStopLossSrc * i_longStopLossPercent)

// 3. Calculate the potential new stop price.
potentialLongStopPrice = i_longStopLossSrc - stopLossOffset

// 4. Update the stop price if trailing is enabled and price moves in a favorable direction.
if i_use_trailing_stoploss and (potentialLongStopPrice > longStopPrice)
    longStopPrice := potentialLongStopPrice

//shortStopPrice = strategy.position_avg_price * (1 + shortStopLossPercent)
//} ========================

//{ RSI Divergence }
rsid_label = "RSI Divergence"
i_enable_timeframe_adjustment_rsi = input.bool(true, title="Apply Time Frame adjustment, ", group=rsid_label, display=display.none, inline="rsid_adj")
i_timeframe_adjustment_weight = input.float(1.0, title="w/ weight", minval=0.1, step=0.1, group=rsid_label, display=display.none, inline="rsid_adj")
i_rsid_src            = input(close, title="RSID Source", group=rsid_label, display=display.none)
i_rsid_lookback_1D    = input.int(14, title="Look-back (1D)",  minval=1, step=1,group=rsid_label, display=display.none)
i_rsid_lookback_12H   = input.int(9, title="Look-back (12H)",  minval=1, step=1,group=rsid_label, display=display.none)
i_rsid_lookback       = utils.f_getParamForTimeframe_int(i_rsid_lookback_1D, i_rsid_lookback_12H, i_rsid_lookback_1D)
i_rsid_overbought_1D  = input.int(70, title="Overbought (1D)", minval=1, step=1, group=rsid_label, display=display.none)
i_rsid_overbought_12H = input.int(75, title="Overbought (12H)", minval=1, step=1, group=rsid_label, display=display.none)
i_rsid_overbought     = utils.f_getParamForTimeframe_int(i_rsid_overbought_1D, i_rsid_overbought_12H, i_rsid_overbought_1D)
i_rsid_oversold_1D    = input.int(30, title="Oversold (1D)", minval=1, step=1, group=rsid_label, display=display.none)
i_rsid_oversold_12H   = input.int(20, title="Oversold (12H)", minval=1, step=1, group=rsid_label, display=display.none)
i_rsid_oversold       = utils.f_getParamForTimeframe_int(i_rsid_oversold_1D, i_rsid_oversold_12H, i_rsid_oversold_1D)
i_rsid_minBars        = input.int(5, "Min Bars Between Peaks", minval=1, step=1, group=rsid_label, display=display.none)
i_rsid_maxBars        = input.int(50, "Max Bars Between Peaks", minval=1, step=1, group=rsid_label, display=display.none)

i_plot_rsid           = input(true, title="Show plot", group=rsid_label, display=display.none)
i_rsid_res            = input.timeframe("", title="Oscillator resolution", group=rsid_label, display=display.none)  // TODO look into this, maybe we're double accounting for chart interval changes?
i_realTime_lookbackPeriod = input.int(20, "Lookback Period for Real-Time Div", minval=1, step=1, group=rsid_label, display=display.none)
i_rsid_len            = input.int(14, minval=1, title="Length", group=rsid_label, display=display.none)

i_rsid_bbLength       = input.int(20, "Bollinger Length", minval=1, step=1, group=rsid_label, display=display.none)
i_rsid_bbMultiplier   = input.float(2.0, "Bollinger Multiplier", minval=0.1, step=0.1, group=rsid_label, display=display.none)
i_rsid_gbLength       = input.int(20, "Gaussian Length", minval=1, step=1, group=rsid_label, display=display.none)
i_rsid_gbMultiplier   = input.float(2.0, "Gaussian Multiplier", minval=0.1, step=0.1, group=rsid_label, display=display.none)

if i_enable_timeframe_adjustment and i_enable_timeframe_adjustment_rsi
    // i_rsid_lookback is now handled by f_getParamForTimeframe_int
    i_realTime_lookbackPeriod := int(i_realTime_lookbackPeriod  * i_timeframe_adjustment_weight / timeframe_divisor) > 5000 ? 5000 : int(i_realTime_lookbackPeriod  * i_timeframe_adjustment_weight / timeframe_divisor)
    i_rsid_len  := int(i_rsid_len  * i_timeframe_adjustment_weight / timeframe_divisor) > 5000 ? 5000 : int(i_rsid_len  * i_timeframe_adjustment_weight / timeframe_divisor)
    i_rsid_bbLength := int(i_rsid_bbLength * i_timeframe_adjustment_weight / timeframe_divisor) > 5000 ? 5000 : int(i_rsid_bbLength * i_timeframe_adjustment_weight / timeframe_divisor)
    i_rsid_gbLength := int(i_rsid_gbLength * i_timeframe_adjustment_weight / timeframe_divisor) > 5000 ? 5000 : int(i_rsid_gbLength * i_timeframe_adjustment_weight / timeframe_divisor)

// RSI calculation
rsid_lenUp            = ta.ema(math.max(ta.change(i_rsid_src), 0), i_rsid_len)
rsid_lenDn            = ta.ema(-math.min(ta.change(i_rsid_src), 0), i_rsid_len)
rsi = rsid_lenDn == 0 ? 100 : rsid_lenUp == 0 ? 0 : 100 - (100 / (1 + rsid_lenUp / rsid_lenDn))

// Calculate RSI with resolution
rsid_osc = request.security(syminfo.tickerid, i_rsid_res, rsi)

// Calculate Bollinger Bands
rsid_bb_basis = ta.sma(rsid_osc, i_rsid_bbLength)
rsid_bb_dev   = i_rsid_bbMultiplier * ta.stdev(rsid_osc, i_rsid_bbLength)
rsid_bb_upper = rsid_bb_basis + rsid_bb_dev
rsid_bb_lower = rsid_bb_basis - rsid_bb_dev

// Calculate Gaussian Bands
rsid_gb_basis = ta.sma(rsid_osc, i_rsid_gbLength)
rsid_gb_dev   = i_rsid_gbMultiplier * ta.dev(rsid_osc, i_rsid_gbLength)
rsid_gb_upper = rsid_gb_basis + rsid_gb_dev
rsid_gb_lower = rsid_gb_basis - rsid_gb_dev

// Original RSI Divergence calculations
// Bearish Divergences
// Bearish Regular Divergence
rsid_phFound = rsiDiv.phFound(rsid_osc, i_rsid_lookback, i_rsid_lookback)
rsid_plFound = rsiDiv.plFound(rsid_osc, i_rsid_lookback, i_rsid_lookback)

rsid_overbought = rsid_osc > i_rsid_overbought
rsid_oversold   = rsid_osc < i_rsid_oversold

// RSID bull conditions
_rsiRegularBullishVal = rsiDiv.regularBullish(rsid_osc, low, 0, 5, 100, rsid_plFound)
rsiRegularBullishCondition   = i_enable_longCondition_rsiRegularBullishDivergence and _rsiRegularBullishVal

_rsiSlowingBullishVal = rsiDiv.slowingBullish(rsid_osc, i_rsid_oversold)
rsiSlowingBullishCondition   = rsid_oversold[1] and i_enable_longCondition_rsiSlowingBullishDivergence and _rsiSlowingBullishVal

_rsiDelayedBullishVal = rsiDiv.delayedDipRSI(rsid_osc, i_rsid_oversold, 0)
rsiDelayedBullishCondition   = rsid_oversold[1] and i_enable_longCondition_rsiDelayedDipDivergence and _rsiDelayedBullishVal

_rsiHiddenBullishVal = rsiDiv.hiddenBullish(rsid_osc, close, 0, 5, 100, rsid_plFound)
rsiHiddenBullishCondition    = i_enable_longCondition_rsiHiddenBullishDivergence and _rsiHiddenBullishVal

_rsiRealTimeBullishVal = rsiDiv.realTimeBullishDiv(rsid_osc, low, i_rsid_maxBars, i_rsid_oversold, i_rsid_bbLength, i_rsid_bbMultiplier)
rsiRealTimeBullishCondition  = i_enable_longCondition_rsiRealTimeBullishDivergence and _rsiRealTimeBullishVal

_rsiConfirmedBullishVal = rsiDiv.confirmedBullishDiv(rsid_osc, low, i_rsid_minBars, i_rsid_maxBars, i_rsid_bbLength, i_rsid_bbMultiplier)
rsiConfirmedBullishCondition = i_enable_longCondition_rsiConfirmedBullishDivergence and _rsiConfirmedBullishVal

// RSID bear conditions
_rsiRegularBearVal = rsiDiv.regularBearish(rsid_osc, high, 0, 5, 100, rsid_phFound)
rsiRegularBearCondition      = i_enable_longExitCondition_rsiRegularBearishDivergence and _rsiRegularBearVal

_rsiSlowingBearishVal = rsiDiv.slowingBearish(rsid_osc, i_rsid_overbought)
rsiSlowingBearishCondition   = rsid_overbought[1] and i_enable_longExitCondition_rsiSlowingBearishDivergence and _rsiSlowingBearishVal

_rsiDelayedBearishVal = rsiDiv.delayedPeakRSI(rsid_osc, i_rsid_overbought, 0)
rsiDelayedBearishCondition   = rsid_overbought[1] and i_enable_longExitCondition_rsiDelayedPeakDivergence and _rsiDelayedBearishVal

_rsiHiddenBearishVal = rsiDiv.hiddenBearish(rsid_osc, high, 0, 5, 100, rsid_phFound)
rsiHiddenBearishCondition    = i_enable_longExitCondition_rsiHiddenBearishDivergence and _rsiHiddenBearishVal

//rsiRealTimeBearishCondition  = i_enable_longExitCondition_rsiRealTimeBearishDivergence  ? rsiDiv.realTimeBearishDiv(rsid_osc, high, i_realTime_lookbackPeriod, i_rsid_overbought) : false
rsiRealTimeBearishCondition  = rsiDiv.realTimeBearishDiv(rsid_osc, high, i_realTime_lookbackPeriod, i_rsid_overbought) // Changing to check all the time, not just when enabled. If good, changes lines above and below

_rsiConfirmedBearishVal = rsiDiv.confirmedBearishDiv(rsid_osc, high, i_rsid_minBars, i_rsid_maxBars, i_rsid_bbLength, i_rsid_overbought)
rsiConfirmedBearishCondition = i_enable_longExitCondition_rsiConfirmedBearishDivergence and _rsiConfirmedBearishVal

//} ========================

//{ Stoch and RSI range filter on Long entry}
groupStochAndRSI               = "Stoch and RSI range filter Long Entry"
stochRSI_len                   = input.int(14, "Stoch and RSI length(14)", minval=1, group=groupStochAndRSI, display=display.none)  // recreated to let stoch work
rsi_lowpass_filter             = input.int(30, "RSI Threshold for Low(30)", minval=1, group=groupStochAndRSI, display=display.none)
rsi_highpass_filter            = input.int(60, "RSI Threshold for High(60)", minval=1, group=groupStochAndRSI, display=display.none)
stochvalue_lowpass_filter      = input.int(37, "Stoch Value Threshold for Low(?)", minval=1, group=groupStochAndRSI, display=display.none)
stochvalue_highpass_filter     = input.int(70, "Stoch Value Threshold for High(?)", minval=1, group=groupStochAndRSI, display=display.none)

if i_enable_timeframe_adjustment
    stochRSI_len  := int(stochRSI_len  / timeframe_divisor) > 5000 ? 5000 : int(stochRSI_len  / timeframe_divisor)

rsi_low_range_cond          = false
rsi_medium_range_cond       = false
rsi_high_range_cond         = false

osc = ta.rsi(osc_src, stochRSI_len) // recreated to let stoch work

if rsid_osc > rsi_highpass_filter
    rsi_high_range_cond     := true
if rsid_osc < rsi_lowpass_filter
    rsi_low_range_cond      := true
if rsid_osc > rsi_lowpass_filter and osc < rsi_highpass_filter
    rsi_medium_range_cond   := true

stoch_low_range_cond        = false
stoch_medium_range_cond     = false
stoch_high_range_cond       = false


if stoch_value > stochvalue_highpass_filter
    stoch_high_range_cond   := true
if stoch_value < stochvalue_lowpass_filter
    stoch_low_range_cond    := true
if stoch_value > stochvalue_lowpass_filter and osc < stochvalue_highpass_filter
    stoch_medium_range_cond := true

//} ========================

//{ Realized Price & Divergence}
groupRealizedPrice = "Realized Price"
realizedPriceSettings = libRealizedPrice.RealizedPriceSettings.new()
realizedPriceSettings.realizedPriceComparisonSource := input(title="Source for price to compare to(close)",defval=close, display=display.none, group=groupRealizedPrice)
realizedPriceSettings.smoothingLength := input.int(2, title="Smoothing Length(10)", minval=1, display=display.none, group=groupRealizedPrice)
realizedPriceSettings.smoothingMA := input.string("Simple Moving Average", "Smoothing MA Type", options=["Simple Moving Average", "Exponential Moving Average", "Weighted Moving Average", "Hull Moving Average", "Volume Weighted Moving Average", "Volume Weighted Average Price", "None"], group=groupRealizedPrice, display=display.none)
realizedPriceSettings.realizedPriceLength := input.int(5, title="Realized Price Length(80)", minval=1, display=display.none, group=groupRealizedPrice)
realizedPriceSettings.pivotLeft := input.int(5, title="Divergence Pivot Left(15)", minval=1, display=display.none, group=groupRealizedPrice)
realizedPriceSettings.pivotRight := input.int(1, title="Divergence Pivot Right(5)", minval=1, display=display.none, group=groupRealizedPrice)
realizedPriceSettings.gaussianLen := input.int(15, title="Gaussian Bands Length(50)", group=groupRealizedPrice, display=display.none)
realizedPriceSettings.gaussianMult := input.float(0.65, title="Gaussian Bands StdDev Mult(2)", group=groupRealizedPrice, display=display.none)
realizedPriceSettings.bullNuplThreshold := input.float(0, title="Filter for Bull NUPL Threshold(0)", display=display.none, group=groupRealizedPrice)
realizedPriceSettings.bearNuplThreshold := input.float(2.0, title="Filter for Bear NUPL Threshold(2.0)", display=display.none, group=groupRealizedPrice)

if i_enable_timeframe_adjustment
    realizedPriceSettings.smoothingLength := int(realizedPriceSettings.smoothingLength  / timeframe_divisor) > 5000 ? 5000 : int(realizedPriceSettings.smoothingLength  / timeframe_divisor)
    realizedPriceSettings.pivotLeft       := int(realizedPriceSettings.pivotLeft / timeframe_divisor) > 5000 ? 5000 : int(realizedPriceSettings.pivotLeft / timeframe_divisor)
    realizedPriceSettings.gaussianLen     := int(realizedPriceSettings.gaussianLen / timeframe_divisor) > 5000 ? 5000 : int(realizedPriceSettings.gaussianLen / timeframe_divisor)

[realized_price_bull_div, realized_price_bear_div, realized_price_bull_cond, realized_price_bear_cond, filtered_realized_price_bull_cond, filtered_realized_price_bear_cond, realized_price_smoothed_nupl, realized_price_gaussian_upper, realized_price_nupl] = libRealizedPrice.f_calc(realizedPriceSettings)
//} --------------------------------
//}

atr1_dividedby_close = ta.atr(1) / close

// Create and populate LongEntryInputs
var bool longCondition = false
var string longEntryConditionName = ""
var bool longCondition_disabled_fired = false
var string longEntryDetailedStats = ""
var string longEntryReasonsDetailed = ""

if (bar_index > hma_length)
    longEntryEnablementInputs = libLongEntry.LongEntryEnablementInputs.new()
    longEntryEnablementInputs.i_enablelongCondition_original := i_enablelongCondition_original
    longEntryEnablementInputs.i_enablelongCondition_new := i_enablelongCondition_new
    longEntryEnablementInputs.i_enablelongCondition_base := i_enablelongCondition_base
    longEntryEnablementInputs.i_enablelongCondition_rocLongEntry := i_enablelongCondition_rocLongEntry
    longEntryEnablementInputs.i_enableLongGaussianGreenAndHMA := i_enableLongGaussianGreenAndHMA
    longEntryEnablementInputs.i_enable_longCondition_macd_crossOver := i_enable_longCondition_macd_crossOver
    longEntryEnablementInputs.i_enable_longCondition_rsiSlowingBullishDivergence := i_enable_longCondition_rsiSlowingBullishDivergence
    longEntryEnablementInputs.i_enable_longCondition_rsiDelayedDipDivergence := i_enable_longCondition_rsiDelayedDipDivergence
    longEntryEnablementInputs.i_enable_longCondition_rsiRegularBullishDivergence := i_enable_longCondition_rsiRegularBullishDivergence
    longEntryEnablementInputs.i_enable_longCondition_rsiHiddenBullishDivergence := i_enable_longCondition_rsiHiddenBullishDivergence
    longEntryEnablementInputs.i_enable_longCondition_rsiConfirmedBullishDivergence := i_enable_longCondition_rsiConfirmedBullishDivergence
    longEntryEnablementInputs.i_enable_longCondition_rsiRealTimeBullishDivergence := i_enable_longCondition_rsiRealTimeBullishDivergence
    longEntryEnablementInputs.i_enable_longCondition_realTime_slowing_confirmed := i_enable_longCondition_realTime_slowing_confirmed
    longEntryEnablementInputs.i_enable_longCondition_stochastic_divergence := i_enable_longCondition_stochastic_divergence
    longEntryEnablementInputs.i_enable_longCondition_stochbullish_rocM3bullish_not_macd_flipped_bearish := i_enable_longCondition_stochbullish_rocM3bullish_not_macd_flipped_bearish
    longEntryEnablementInputs.i_enable_longCondition_stochbullish_macd_flipped_bullish_rocM3_flipped_bullish := i_enable_longCondition_stochbullish_macd_flipped_bullish_rocM3_flipped_bullish
    longEntryEnablementInputs.i_enable_longCondition_base_not_macd_is_decreasing := i_enable_longCondition_base_not_macd_is_decreasing
    longEntryEnablementInputs.i_enable_longCondition_base_isMacdHistRising := i_enable_longCondition_base_isMacdHistRising
    longEntryEnablementInputs.i_enable_longCondition_base_isM2SmoothedShortOffsetRising := i_enable_longCondition_base_isM2SmoothedShortOffsetRising
    longEntryEnablementInputs.i_enable_longCondition_base_macd_slope_above_threshold := i_enable_longCondition_base_macd_slope_above_threshold
    longEntryEnablementInputs.i_enable_longCondition_base_not_isM2SmoothedLongOffsetFalling := i_enable_longCondition_base_not_isM2SmoothedLongOffsetFalling
    longEntryEnablementInputs.i_enable_longCondition_base_not_rsi_high_range_cond := i_enable_longCondition_base_not_rsi_high_range_cond
    longEntryEnablementInputs.i_enable_longCondition_base_rsid_osc_above_50 := i_enable_longCondition_base_rsid_osc_above_50
    longEntryEnablementInputs.i_enable_longCondition_base_stoch_high_range_cond := i_enable_longCondition_base_stoch_high_range_cond
    longEntryEnablementInputs.i_enable_longCondition_base_stoch_low_range_cond := i_enable_longCondition_base_stoch_low_range_cond
    longEntryEnablementInputs.i_enable_longCondition_isM2MacdLongCrossBullish := i_enable_longCondition_isM2MacdLongCrossBullish
    longEntryEnablementInputs.i_enable_longCondition_isM2MacdShortCrossBullish := i_enable_longCondition_isM2MacdShortCrossBullish
    longEntryEnablementInputs.i_enable_longCondition_low_rsid := i_enable_longCondition_low_rsid
    longEntryEnablementInputs.i_enable_longCondition_macd_crossUnderPrediction := i_enable_longCondition_macd_crossUnderPrediction
    longEntryEnablementInputs.i_enable_longCondition_vwap_bullish_diff_short := i_enable_longCondition_vwap_bullish_diff_short
    longEntryEnablementInputs.i_enable_longCondition_realized_price_bull_div := i_enable_longCondition_realized_price_bull_div
    longEntryEnablementInputs.i_enable_longCondition_realized_price_bull_cond := i_enable_longCondition_realized_price_bull_cond
    longEntryEnablementInputs.i_enable_longCondition_filtered_realized_price_bull_cond := i_enable_longCondition_filtered_realized_price_bull_cond
    longEntryEnablementInputs.i_enable_longCondition_realized_price_crossOverUpper := i_enable_longCondition_realized_price_crossOverUpper
    longEntryEnablementInputs.i_enable_longCondition_vwap_bullish_all_rising := i_enable_longCondition_vwap_bullish_all_rising
    longEntryEnablementInputs.i_enable_longCondition_rsiHiddenBearishCondition := i_enable_longCondition_rsiHiddenBearishCondition
    longEntryEnablementInputs.i_enable_longCondition_realized_price_bull_div_not_isRisingTinyShort := i_enable_longCondition_realized_price_bull_div_not_isRisingTinyShort
    longEntryEnablementInputs.i_enable_longCondition_isRising_smoothedM3_no_offset := i_enable_longCondition_isRising_smoothedM3_no_offset
    longEntryEnablementInputs.i_enable_longCondition_test := i_enable_longCondition_test
    longEntryEnablementInputs.i_enable_longCondition_base_not_isM3GlobalSmoothedFalling := i_enable_longCondition_base_not_isM3GlobalSmoothedFalling
    longEntryEnablementInputs.i_enable_longCondition_stochbullish_rocM3bullish_not_macd_flipped_bearish_n_bars_out := i_enable_longCondition_stochbullish_rocM3bullish_not_macd_flipped_bearish_n_bars_out
    longEntryEnablementInputs.i_longCondition_base_rsid_rsid_osc_threshold := i_longCondition_base_rsid_rsid_osc_threshold
    longEntryEnablementInputs.i_longCondition_base_rsid_m2_threshold := i_longCondition_base_rsid_m2_threshold
    longEntryEnablementInputs.i_longCondition_low_rsid_threshold := i_longCondition_low_rsid_threshold
    longEntryEnablementInputs.i_longCondition_low_rsid_delta := i_longCondition_low_rsid_delta
    longEntryEnablementInputs.i_stochbullish_rocM3bullish_not_macd_flipped_bearish_macd_value := i_stochbullish_rocM3bullish_not_macd_flipped_bearish_macd_value

    longEntryGeneralInputs = libLongEntry.LongEntryGeneralInputs.new()
    longEntryGeneralInputs.timeCondition := timeCondition
    longEntryGeneralInputs.i_log_variables_to_list_of_trades := i_log_variables_to_list_of_trades
    longEntryGeneralInputs.gaussianGreen := gaussianGreen
    longEntryGeneralInputs.macdLongEntryCondition := macdLongEntryCondition
    longEntryGeneralInputs.longEntryAggressiveness := longEntryAggressiveness
    longEntryGeneralInputs.close := close
    longEntryGeneralInputs.hband := hband
    longEntryGeneralInputs.lband := lband
    longEntryGeneralInputs.osc := osc
    longEntryGeneralInputs.hmaTrend := hmaTrend
    longEntryGeneralInputs.atr1_dividedby_close := atr1_dividedby_close
    longEntryGeneralInputs.osc_high_limit := osc_high_limit

    longEntryRocM3Inputs = libLongEntry.LongEntryRocM3Inputs.new()
    longEntryRocM3Inputs.m3_growthRateRocPercentage_flipped_bullish := m3_growthRateRocPercentage_flipped_bullish
    longEntryRocM3Inputs.m3_growthRateRocPercentage_flipped_bearish := m3_growthRateRocPercentage_flipped_bearish
    longEntryRocM3Inputs.m3ROCEnabledEntry := m3ROCEnabledEntry
    longEntryRocM3Inputs.rocHMALongEntry_smoothed := rocHMALongEntry_raw
    longEntryRocM3Inputs.rocHMALongEntryThreshold := rocHMALongEntryThreshold
    longEntryRocM3Inputs.entryROcM3 := entryROcM3
    longEntryRocM3Inputs.m3_growth_rate_smoothed_rocLongEntryThreshold := m3_growth_rate_smoothed_rocLongEntryThreshold

    longEntryMacdInputs = libLongEntry.LongEntryMacdInputs.new()
    longEntryMacdInputs.macd_flipped_bullish := macd_flipped_bullish
    longEntryMacdInputs.macd_flipped_bearish := macd_flipped_bearish
    longEntryMacdInputs.macd_is_decreasing := macd_is_decreasing
    longEntryMacdInputs.isMacdHistRising := isMacdHistRising
    longEntryMacdInputs.macd_slope_above_threshold := macd_slope_above_threshold
    longEntryMacdInputs.macd_prediction := macd_prediction
    longEntryMacdInputs.macd_slope_current := macd_slope_current
    longEntryMacdInputs.macd := macd
    longEntryMacdInputs.signal := signal

    longEntryRsiDivInputs = libLongEntry.LongEntryRsiDivInputs.new()
    longEntryRsiDivInputs.rsiSlowingBullishCondition := _rsiSlowingBullishVal
    longEntryRsiDivInputs.rsiDelayedBullishCondition := _rsiDelayedBullishVal
    longEntryRsiDivInputs.rsiRegularBullishCondition := _rsiRegularBullishVal
    longEntryRsiDivInputs.rsiHiddenBullishCondition := _rsiHiddenBullishVal
    longEntryRsiDivInputs.rsiHiddenBearishCondition := _rsiHiddenBearishVal
    longEntryRsiDivInputs.rsiRealTimeBullishCondition := _rsiRealTimeBullishVal
    longEntryRsiDivInputs.rsiConfirmedBullishCondition := _rsiConfirmedBullishVal
    longEntryRsiDivInputs.rsi_high_range_cond := rsi_high_range_cond
    longEntryRsiDivInputs.rsi_medium_range_cond := rsi_medium_range_cond
    longEntryRsiDivInputs.rsid_osc := rsid_osc

    longEntryStochInputs = libLongEntry.LongEntryStochInputs.new()
    longEntryStochInputs.stochCondition := stochCondition
    longEntryStochInputs.stoch_high_range_cond := stoch_high_range_cond
    longEntryStochInputs.stoch_low_range_cond := stoch_low_range_cond
    longEntryStochInputs.stoch_bullishDivergence := stoch_bullishDivergence
    longEntryStochInputs.stoch_bearishDivergence := stoch_bearishDivergence
    longEntryStochInputs.stoch_value := stoch_value

    longEntryVwapDivInputs = libLongEntry.LongEntryVwapDivInputs.new(vwap_bullishDivergence, vwap_bearishDivergence)

    longEntryRealizedPriceInputs = libLongEntry.LongEntryRealizedPriceInputs.new()
    longEntryRealizedPriceInputs.realized_price_bull_cond := realized_price_bull_cond
    longEntryRealizedPriceInputs.filtered_realized_price_bull_cond := filtered_realized_price_bull_cond
    longEntryRealizedPriceInputs.realized_price_bull_div := realized_price_bull_div
    longEntryRealizedPriceInputs.realized_price_smoothed_nupl := realized_price_smoothed_nupl
    longEntryRealizedPriceInputs.realized_price_gaussian_upper := realized_price_gaussian_upper

    longEntryM2LiInputs = libLongEntry.LongEntryM2LiInputs.new()
    longEntryM2LiInputs.isM2SmoothedShortOffsetFalling := isM2SmoothedShortOffsetFalling
    longEntryM2LiInputs.isM2SmoothedMediumOffsetFalling := isM2SmoothedMediumOffsetFalling
    longEntryM2LiInputs.isM2SmoothedShortOffsetRising := isM2SmoothedShortOffsetRising
    longEntryM2LiInputs.isM2SmoothedMediumOffsetRising := isM2SmoothedMediumOffsetRising
    longEntryM2LiInputs.isM2SmoothedLongOffsetFalling := isM2SmoothedLongOffsetFalling
    longEntryM2LiInputs.isM2SmoothedLongOffsetRising := isM2SmoothedLongOffsetRising
    longEntryM2LiInputs.isFalling_smoothedM3_short_offset := isFalling_smoothedM3_short_offset
    longEntryM2LiInputs.isM2MacdLongCrossBullish := isM2MacdLongCrossBullish
    longEntryM2LiInputs.isM2MacdShortCrossBullish := isM2MacdShortCrossBullish
    longEntryM2LiInputs.isRising_smoothedM3_short_offset := isRising_smoothedM3_short_offset
    longEntryM2LiInputs.isM2SmoothedTinyOffsetFalling := isM2SmoothedTinyOffsetFalling
    longEntryM2LiInputs.isM2SmoothedTinyOffsetRising := isM2SmoothedTinyOffsetRising
    longEntryM2LiInputs.isM2SmoothedMiniOffsetRising := isM2SmoothedMiniOffsetRising
    longEntryM2LiInputs.isM2SmoothedMicroOffsetFalling := isM2SmoothedMicroOffsetFalling
    longEntryM2LiInputs.isM2SmoothedShortOffsetFlat := isM2SmoothedShortOffsetFlat
    longEntryM2LiInputs.isM2SmoothedMediumOffsetFlat := isM2SmoothedMediumOffsetFlat
    longEntryM2LiInputs.isM2SmoothedLongOffsetFlat := isM2SmoothedLongOffsetFlat
    longEntryM2LiInputs.isFalling_smoothedM3_no_offset := isFalling_smoothedM3_no_offset
    longEntryM2LiInputs.isRising_smoothedM3_no_offset := isRising_smoothedM3_no_offset
    longEntryM2LiInputs.i_m2LeadingIndicator_shortOffset := i_m2LeadingIndicator_shortOffset
    longEntryM2LiInputs.i_m2LeadingIndicator_mediumOffset := i_m2LeadingIndicator_mediumOffset
    longEntryM2LiInputs.i_m2LeadingIndicator_longOffset := i_m2LeadingIndicator_longOffset
    longEntryM2LiInputs.m2_mediumOffsetDiffTo12barsOut := m2_mediumOffsetDiffTo12barsOut
    longEntryM2LiInputs.m2_smoothedLongOffsetSlope := m2_smoothedLongOffsetSlope
    longEntryM2LiInputs.m2_smoothedMediumOffsetSlope := m2_smoothedMediumOffsetSlope
    longEntryM2LiInputs.m2_tinyOffsetDiffToNbarsOut := m2_tinyOffsetDiffToNbarsOut
    longEntryM2LiInputs.m2Macd_shortOffsetDifference := m2Macd_shortOffsetDifference
    longEntryM2LiInputs.m2_shortOffsetDiffToNbarsOut := m2_shortOffsetDiffToNbarsOut
    longEntryM2LiInputs.m2_smoothedShortOffsetSlope := m2_smoothedShortOffsetSlope
    longEntryM2LiInputs.m2_smoothedTinyOffsetSlope := m2_smoothedTinyOffsetSlope
    longEntryM2LiInputs.m2_smoothedShort_N_bars_out := m2_smoothedShort_N_bars_out
    longEntryM2LiInputs.m2_shortOffsetSlopeToNbarsOut := m2_shortOffsetSlopeToNbarsOut
    longEntryM2LiInputs.m2_smoothed_shortOffset := m2_smoothed_shortOffset
    longEntryM2LiInputs.m2_smoothed_mediumOffset := m2_smoothed_mediumOffset
    longEntryM2LiInputs.m2_smoothed_longOffset := m2_smoothed_longOffset
    
    longEntryResults = libLongEntry.f_calculateLongEntry(longEntryEnablementInputs, longEntryGeneralInputs, longEntryRocM3Inputs, longEntryMacdInputs, longEntryRsiDivInputs, longEntryStochInputs, longEntryVwapDivInputs, longEntryRealizedPriceInputs, longEntryM2LiInputs)
    
    longCondition := longEntryResults.longCondition
    longEntryConditionName := longEntryResults.longEntryConditionName
    longCondition_disabled_fired := longEntryResults.longCondition_disabled_fired
    longEntryDetailedStats := longEntryResults.longEntryDetailedStats
    longEntryReasonsDetailed := longEntryResults.longEntryReasonsDetailed

//} ========================

//{ Short Entry}
gaussianRed = ma < ma[1]
var bool m3ShortEntryCondition = true
if m3ShortEntryMode == "Disabled"
    m3ShortEntryCondition := false
if m3ShortEntryMode == "Boost/Dampen Based on Trend"
    if m3_growthRateTrend < 0
        m3ShortEntryCondition := (m3ClampedScale > 0.10)
    else
        m3ShortEntryCondition := (m3ClampedScale > 0.50)

shortCondition = timeCondition
                 and (stochCondition or macd_flipped_bearish)
                 and (m3_growth_rate_smoothed > m3ShortEntryThreshold or macd_flipped_bearish)
                 and (m3_growthRateTrend < m3_growthRateTrendShortEntryThreshold)
                 and (m3_growthRateTrend2 < m3_growthRateTrend2ShortEntryThreshold)
                 and (macd_prediction < 0)
                 and (m3_growthRateTrend + m3_growthRateTrend2 < m3_growthRateTrendsShortEntrySummedThreshold)
//} ========================

//{ Volatility Directional Exit Parameters}
groupVolatility = "Volatility"
longVolatilityExitThreshold     = input.float(30, "Long Exit Volatility Threshold", tooltip="Negative volatility threshold to force exit of long positions", group=groupVolatility, display=display.none)
shortVolatilityEntryThreshold   = input.float(3150, "Short Entry Volatility Threshold", tooltip="Positive volatility threshold to exit longs and potentially enter shorts", group=groupVolatility, display=display.none)
volatilityDirectionLength       = input.int(14, title="Length for std dev of directed volatility", group=groupVolatility, display=display.none)

if i_enable_timeframe_adjustment
    volatilityDirectionLength := int(volatilityDirectionLength / timeframe_divisor) > 5000 ? 5000 : int(volatilityDirectionLength / timeframe_divisor)

// Volatility Calculation (Directional)
volatilityDirection = ta.change(close)
directedVolatility  = ta.stdev(volatilityDirection, volatilityDirectionLength)

// Directional Exit Conditions
longExitVolatilityCondition     = directedVolatility < longVolatilityExitThreshold
shortEntryVolatilityCondition   = directedVolatility > shortVolatilityEntryThreshold

shortCondition := shortCondition or (shortEntryVolatilityCondition and timeCondition)                 
//} ========================

//{ Misc color and plotting, should be moved}
rsid_osc_color = color.blue
if rsid_osc < 30
    rsid_osc_color :=  color.green
else if rsid_osc > 70 
    rsid_osc_color := color.red
//plotchar(rsid_osc,                           title="Debug: Co: rsid_osc", char="L", location=location.abovebar, color=rsid_osc_color, display = display.data_window)

stoch_value_color = color.blue
if stoch_value < 20
    stoch_value_color :=  color.green
else if stoch_value > 80 
    stoch_value_color := color.red
//plotchar(stoch_value,                           title="Debug: Co: stoch_value", char="L", location=location.abovebar, color=stoch_value_color, display = display.data_window)

vwap_bear_level = 0.0
vwap_bear_level := vwap_bearishDivergence ? close * 1.1 : na
//plotshape(vwap_bear_level, title="Debug: VWAP Bearish", text="VWAP_S", style=shape.arrowdown, location=location.absolute, color=color.new(color.red, 0), textcolor=color.white, size=size.small, display=display.data_window)

vwap_bull_level = 0.0
vwap_bull_level := vwap_bullishDivergence ? close * 0.9 : na

showBB = true
//} ========================

[finalExitCondition, longExitCondition_disabled_fired, longExitConditionName, longExitConditions] = libLongExit.f_calculateLongExit(close, timeCondition, i_longStopLossSrc, longStopPrice, hband, isM2SmoothedShortOffsetRising, m2_shortOffsetDiffToNbarsOut, m2_tinyOffsetDiffToNbarsOut, rocHMALongExit, rocHMALongExitThreshold, rocLongExitCondition, longExitVolatilityCondition, rsiRegularBearCondition, isM2SmoothedMediumOffsetFalling, m2_mediumOffsetDiffTo12barsOut, rsiHiddenBearishCondition, stoch_bearishDivergence, rsiSlowingBearishCondition, isM2SmoothedTinyOffsetRising, m2_smoothedTinyOffsetSlope, rsiRealTimeBearishCondition, rsi_high_range_cond, stoch_high_range_cond, m2_smoothedShortOffsetSlope_diff, realized_price_smoothed_nupl, rsiDelayedBearishCondition, macd_flipped_bearish, macd_prediction, macd, signal, shortCondition, macdLongExitCondition, isM2MacdShortCrossBearish, isM2MacdLongCrossBearish, isM2SmoothedShortOffsetFalling, macd_is_decreasing, isM2SmoothedLongOffsetFalling, stoch_value, rsid_osc, i_longExitCondition_stoch_over_N_threshold, i_longExitCondition_rsi_over_N_threshold, i_enable_stochastic_divergence_isFalling_rsid_threshold, isM2SmoothedMediumOffsetFlat, m2_smoothedShortOffsetSlope, m2Macd_shortOffsetDifference, atr1_dividedby_close, realized_price_bear_cond, realized_price_bear_div, realized_price_nupl, filtered_realized_price_bear_cond, isFalling_smoothedM3_no_offset, isM2SmoothedMiniOffsetRising, m2_smoothedTinyOffsetSlope_diff, i_enable_longExitCondition_crossUnderCloseHband, i_enable_longExitCondition_rocHMALongExitUnderThreshold, i_enable_longExitCondition_rocLongExitCondition, i_enable_longExitCondition_volatilityCondition, i_enable_longExitCondition_rsiRegularBearishDivergence, i_enable_longExitCondition_rsiHiddenBearishDivergence, i_enable_longExitCondition_rsiSlowingBearishDivergence, i_enable_longExitCondition_rsiRealTimeBearishDivergence, i_enable_longExitCondition_rsiRealTimeBearishVWAPDivergenceA, i_enable_longExitCondition_rsiRealTimeBearishVWAPDivergenceB, i_enable_longExitCondition_stochbearish_negative_diffs, i_longStopLossEnabled, i_enable_longExitCondition_macd_crossUnderPrediction, i_enable_longExitCondition_shortEntryCondition, i_enable_longExitCondition_macd_crossUnder, i_enable_longExitCondition_stochastic_divergence, i_enable_longExitCondition_stochbearish_vwap_bearish_macd_hist_rising, i_enable_longExitCondition_stochbearish_vwap_bearish_macd_flipped_bearish, i_enable_longExitCondition_isM2MacdLongCrossBearish, i_enable_longExitCondition_isM2MacdShortCrossBearish, i_enable_longExitCondition_m2_diff_less_than, i_enable_longExitCondition_stochbearish_stoch_over_N, i_enable_longExitCondition_stochastic_divergence_isFalling, i_enable_longExitCondition_isFalling_short_high_rsi_high_stoch, i_enable_longExitCondition_m2Macd_shortOffsetDifference_under_0, i_enable_longExitCondition_up_spike_when_isM2SmoothedTinyOffsetFlat, i_enable_longExitCondition_realized_price_bear_cond, i_enable_longExitCondition_realized_price_bear_div, i_enable_longExitCondition_realized_price_bear_div_tiny, i_enable_longExitCondition_filtered_realized_price_bear_cond, i_enable_longExitCondition_realized_price_crossUnderUpper, i_enable_longExitCondition_isFalling_smoothedM3_no_offset, i_enable_longExitCondition_rsiDelayedPeakDivergence, vwap_bearishDivergence, isMacdMinusMacdOneRising, realized_price_gaussian_upper, isM2SmoothedTinyOffsetFalling, isM2SmoothedLongOffsetRising, isM2SmoothedShortOffsetFlat, isM2SmoothedMediumOffsetRising)


//{ Short exit logic and data window
groupShort = "Shorting Group"
m3_growthRateRocPercentageShortEntryThreshold = input.float(0.5, "m3_growthRateRocPercentageShort Entry Threshold", step=0.1, group=groupShort, display=display.none)
m3_growthRateRocPercentageshortExitThreshold  = input.float(-1.0, "m3_growthRateRocPercentageShort Exit Threshold", step=0.02, group=groupShort, display=display.none)

bool rocShortExitCondition = (m3ROCEnabledExit == "Enabled") and (exitROcM3 >= m3_growthRateRocPercentageshortExitThreshold)
finalShortExitCondition = timeCondition and ((m3_growthRateTrend > 0) or (m3_growthRateTrend2 > 0))
//}

//{ Equity Scaling Plot}
//scaledEquity = recentAssetHigh > 0 ? strategy.equity / recentAssetHigh : na
assetHighLookback = input.int(20, "Asset Price High Lookback", minval=1, display=display.none)

if i_enable_timeframe_adjustment
    assetHighLookback := int(assetHighLookback / timeframe_divisor) > 5000 ? 5000 : int(assetHighLookback / timeframe_divisor)

float recentAssetHigh = ta.highest(high, assetHighLookback)

equityScalar = recentAssetHigh > 0 ? strategy.equity / recentAssetHigh : na
equityScalarRounded = math.round(equityScalar)
scaledEquity = strategy.equity / nz(equityScalarRounded)
//}

//{ Strategy Execution (Long & Short) }
var enteredWithSpecificCondition = false
var entry_conditions = array.new_bool()
var exit_conditions = array.new_bool()
var entry_condition_names = array.new_string()

bool longCondition_realized_price_bull_cond = timeCondition and realized_price_bull_cond
// --- Define Specific Condition Pairs ---
// Pair 1: Realized Price
array.push(entry_conditions, longCondition_realized_price_bull_cond and i_enable_longCondition_realized_price_bull_cond)
array.push(exit_conditions, longExitConditions.realized_price_bear_cond and i_enable_longExitCondition_realized_price_bear_cond)
array.push(entry_condition_names, "realized_price_bull_cond")

// You can add more pairs here in the future, for example:
// array.push(entry_conditions, some_other_entry_condition)
// array.push(exit_conditions, some_other_exit_condition)
// array.push(entry_condition_names, "some_other_entry_condition_name")
// ---

var int specific_entry_index = -1

// === ENTRY LOGIC ===
if strategy.position_size == 0
    // Check for specific entry conditions first
    for i = 0 to array.size(entry_conditions) - 1
        if array.get(entry_conditions, i)
            longEntryConditionName := array.get(entry_condition_names, i)
            strategy.entry(id="long", direction=strategy.long, comment = i_log_variables_to_list_of_trades ? (longEntryConditionName + longEntryReasonsDetailed) : longEntryConditionName)
            longStopPrice := strategy.position_avg_price * (1 - i_longStopLossPercent)
            enteredWithSpecificCondition := true
            specific_entry_index := i // Remember which condition was met
            break // Exit the loop once an entry is found

    // If no specific entry was met, check for general long conditions
    if strategy.position_size == 0 and longCondition and timeCondition
        strategy.entry(id="long", direction=strategy.long, comment = i_log_variables_to_list_of_trades ? (longEntryConditionName + longEntryReasonsDetailed) : longEntryConditionName)
        longStopPrice := strategy.position_avg_price * (1 - i_longStopLossPercent)
        enteredWithSpecificCondition := false
        specific_entry_index := -1

// === EXIT LOGIC ===
if strategy.position_size > 0
    bool final_exit = false
    if enteredWithSpecificCondition and specific_entry_index != -1
        final_exit := array.get(exit_conditions, specific_entry_index)
    else
        final_exit := finalExitCondition and not longCondition

    if final_exit
        strategy.close("long", comment=longExitConditionName)
        longStopPrice := na


//{ Gaussian channel fill color, for Ramon}
i_candle_tranparency = input.int(0, title="Candle Transparency(0)", group=group_general_settings, display=display.none)  // to improve readability when enabling drawing over candles, eg with VWMA 
// fcolor  = filt > filt[1] ? color.new(#0aff68, i_candle_tranparency) : filt < filt[1] ? color.new(#ff0a5a, i_candle_tranparency) : color.gray
// barcolor(src > src[1] and src > filt and src < hband  ? color.new(#0aff68,i_candle_tranparency) :
//          src > src[1] and src >= hband                ? color.new(color.rgb(21, 226, 245), i_candle_tranparency) :
//          src <= src[1] and src > filt                 ? color.new(#00752d,i_candle_tranparency) :
//          src < src[1] and src < filt and src > lband  ? color.new(#ff0a5a,i_candle_tranparency) :
//          src < src[1] and src <= lband                ? color.new(#f73c7a, i_candle_tranparency) :
//          src >= src[1] and src < filt                 ? color.new(#990032,i_candle_tranparency) : color.new(color.rgb(186, 182, 184),i_candle_tranparency))

// filtplot  = plot(filt, title="Bands: Filter", color=fcolor, linewidth=3, display = display.pane)
// hbandplot = plot(hband, title="Bands": Filtered True Range High Band", color=fcolor, display = display.pane)
// lbandplot = plot(lband, title="Bands: Filtered True Range Low Band", color=fcolor, display = display.pane)
// fill(hbandplot, lbandplot, title="Bands:Channel Fill", color=color.new(fcolor, 80)) //, display = display.pane)
//}



plotEnabledEntryCondition = timeCondition and i_enable_plot_all_enabled_conditions and longCondition[1]
plotEnabledExitCondition = timeCondition and i_enable_plot_all_enabled_conditions and finalExitCondition[1]
plotDisabledEntryCondition = timeCondition and i_enable_plot_disabled_entry_conditions and longCondition_disabled_fired
plotDisabledExitCondition = timeCondition and i_enable_plot_disabled_exit_conditions and longExitCondition_disabled_fired
//}

//{ Labels: For various Plots }

// An array holding the multipliers you want to cycle through.
var float[] y_entry_offsets = array.from(0.9750, 0.9800 , 0.9825 )
// A persistent counter that tracks how many signals have occurred.
varip int entry_signal_counter = 0

// Use 'var' to declare a label variable. This allows its ID to persist
// between bars so we can modify it.
var label longEntryLabel = na

// If the entry condition is true...
if plotEnabledEntryCondition
        // `entry_signal_counter % array.size(y_entry_offsets)` ensures the index always loops back to 0
    // and never goes out of bounds.
    float current_multiplier = array.get(y_entry_offsets, entry_signal_counter % array.size(y_entry_offsets))
    
    // Calculate the y-position using the selected multiplier
    y = m2_US_EU_CN * current_multiplier

    // 1. CREATE the label. Note that we assign it to our variable using ':= '
    //    The text argument is empty for now.
    longEntryLabel := label.new(
         x = bar_index,                               // Place label on the current bar
         y = y,                                     // Place label at the low of the bar
         yloc = yloc.belowbar,                       // Ensure it's drawn below the bar price
         tooltip = longEntryConditionName[1] + "\n" + longEntryDetailedStats[1],
                                           // Start with empty text
         style = label.style_triangleup,                    // Equivalent to shape.triangleup
         color = color.new(#174e85, 0),
         textcolor = color.white,
         size = size.auto,
         force_overlay  = true
         )
    entry_signal_counter += 1

// An array holding the multipliers you want to cycle through.
var float[] y_exit_offsets = array.from(0.9875, 0.9925 , 0.9975 )
// A persistent counter that tracks how many signals have occurred.
varip int exit_signal_counter = 0

// Use 'var' to declare a label variable. This allows its ID to persist
// between bars so we can modify it.
var label longExitLabel = na
if plotEnabledExitCondition
        // `exit_signal_counter % array.size(y_entry_offsets)` ensures the index always loops back to 0
    // and never goes out of bounds.
    float current_multiplier = array.get(y_exit_offsets, exit_signal_counter % array.size(y_exit_offsets))
    
    // Calculate the y-position using the selected multiplier
    y = m2_US_EU_CN * current_multiplier

    // 1. CREATE the label. Note that we assign it to our variable using ':= '
    //    The text argument is empty for now.
    longExitLabel := label.new(
         x = bar_index,                               // Place label on the current bar
         y = y,                                     // Place label at the low of the bar
         yloc = yloc.abovebar,                       // Ensure it's drawn below the bar price
         tooltip = longExitConditionName[1],
                                           // Start with empty text
         style = label.style_triangledown,                    // Equivalent to shape.triangleup
         color = color.new(#750b95, 3),
         textcolor = color.white,
         size = size.auto,
         force_overlay = true
         )
    exit_signal_counter += 1
//}

//{ Shape: Enabled Plots}

// Converted to label.new()
var label disabledEntryLabel = na
if plotDisabledEntryCondition
    
    disabledEntryLabel := label.new(
         x = bar_index, 
         y = close > open ? open : close, 
         yloc = yloc.belowbar, 
         style = label.style_arrowup, 
         color = color.rgb(15, 58, 117, 0), 
         size = size.huge,
         force_overlay = true,
         //text = "the text for the label",
         tooltip = longEntryConditionName  + "; " + longEntryDetailedStats  
         )

//plotshape(plotDisabledExitCondition, title="ShapeE: Disabled LX", style=shape.triangledown, location = location.abovebar, color=color.rgb(107, 27, 125), display=display.pane, size=size.tiny, force_overlay = true)
var label disabledExitLabel = na
if plotDisabledExitCondition
    
    disabledExitLabel := label.new(
         x = bar_index, 
         y = close > open ? close : open, 
         yloc = yloc.abovebar, 
         style = label.style_arrowup, 
         color = color.rgb(92, 15, 117, 0), 
         size = size.huge,
         force_overlay = true,
         //text = "the text for the label",
         tooltip = longExitConditionName
         )

plotshape(timeCondition and longCondition ? 1.0 : na, title="ShapeD 1+ Enabled  ENTRY conditions are TRUE ====== N >>>>", style=shape.arrowup, size=size.large, location=location.belowbar, color=color.new(#40ceeb, 100), display = display.data_window)
plotshape(finalExitCondition and i_enableLongExit and timeCondition ? 1.0 : na, title="LX: 1+ Enabled  EXIT conditions are true ========= XXX>", style=shape.arrowdown, size=size.large, location=location.abovebar, color=color.new(#ff52f1, 7), display = display.data_window)

// DEBUG PLOTS
plotchar(longCondition, "L - longCondition", "L", location.top, color.green, display=display.data_window)
plotchar(longCondition_disabled_fired, "D - longCondition_disabled_fired", "D", location.bottom, color.yellow, display=display.data_window)
//}
