Hull Suite by InSilico: Three Formulas and a Two-Bar Reference
Hull Suite groups three moving-average constructions behind a mode selector. This reference selects one construction at a time and plots its current value beside its value two bars ago. The colored band describes that difference; it does not measure a strategy’s win rate or establish that a price reversal will follow.
Inspect the Pine ScriptOriginal suite and this reference have different controls
InSilico’s published Hull Suite provides HMA, EHMA and THMA choices and documents additional display, timeframe and alert features. Its original publication is dated October 2019. Alan Hull describes the underlying HMA on his own website.
The smaller source on this page is not the full published suite. It fixes close, mode 1, length 55 and multiplier 1 in its function call. It draws two lines and a fill, with no Settings inputs, candle coloring, alerts, orders or higher-timeframe request. Change the call or add explicit input controls to adapt it. A multiplier changes the number of chart bars used; it does not fetch higher-timeframe candles.
Follow the selected formula and integer windows
Let L be max(1, int(length × multiplier)), h be max(1, int(L/2)) and r be max(1, round(√L)). For positive values, int truncates the fractional part. Mode 1 calculates WMA(2 × WMA(source, h) − WMA(source, L), r). Mode 3 uses the same structure with EMA instead of WMA. Both apply square-root-length smoothing at the final stage.
Mode 2 first sets K = max(1, int(L/2)). It then calculates WMA(3 × WMA(source, max(1, int(K/3))) − WMA(source, max(1, int(K/2))) − WMA(source, K), K). This THMA branch uses three inner weighted averages and a final weighted average. It has no square-root stage and is not the conventional triangular moving average.
For length 55 and multiplier 1, L is 55. HMA and EHMA use inner lengths 27 and 55, followed by length 7. THMA uses K = 27, inner lengths 9, 13 and 27, then final length 27. With multiplier 0.5, L truncates to 27, and THMA’s K truncates again to 13. Those two truncation steps matter; “half as slow” is not a mathematical consequence.
The reference makes integer conversions and minimum windows explicit and rejects invalid modes or nonpositive parameters. Its rounding policy is part of this implementation, not a claim of bit-for-bit equivalence with every published Hull script or the built-in ta.hma(). EMA and WMA also differ in initialization and historical weighting. Compare their numerical series under the same source and history before interpreting differences.
The band compares now with two bars ago
MHULL is the current selected Hull value. SHULL is that same series indexed two bars into the past, plotted at the current chart position. It is not a second, longer moving average and the plot has no negative offset.
The code colors both lines green when MHULL > SHULL. Every other comparison result follows the red branch, including equality. At the start of the series, unavailable values can prevent a complete band. Red therefore does not always mean a strict decrease, and green does not prove that each of the last two one-bar changes was positive.
For a synthetic sequence of Hull values 100, 103 and 102, the latest band is green because 102 > 100, although the latest one-bar change is −1. For 100, 102 and 100, the latest comparison is equal and the code chooses red. These are arithmetic examples, not chart observations or backtest results.
The band’s absolute width is |Hull[t] − Hull[t−2]| in price units. A wider band means a larger two-bar displacement of this filtered series. It does not independently identify buying pressure, participation, acceleration or a probability of continuation. Compare normalized widths deliberately if prices or instruments differ.
Confirmation, timeframe and performance boundaries
The current close changes while a bar is developing, so the current Hull value and color may also change. This snippet does not require barstate.isconfirmed. If a rule needs a confirmed color change, specify a transition evaluated at close and how to treat ties and unavailable history. “Green for five bars” requires five separate observations; a comparison against Hull[2] does not enforce it.
A length of 55 means chart bars. Its elapsed time depends on the interval, session and gaps. No fixed best market or interval is established here. All branches can overshoot price and react differently to steps, reversals and oscillating data; there is no universal ranking in bars of lag or percentage of false signals.
Calling the function twice on a daily chart still calculates two daily-chart series. A weekly filter needs a real higher-timeframe request and a defined confirmed-week policy, as described in TradingView’s timeframe documentation. Multiplying a daily length is not generally equivalent to calculating the indicator on weekly closes.
To evaluate a color rule, first fix the variant, integer rounding, source, entry timing, exits, transaction costs and position sizing. Reserve data for evaluation after choosing parameters. The example supplies no trade record, return estimate or measured improvement from an EMA, volume or pullback filter.
A short verification sequence before adapting the code
Start with mode 1 and the fixed default call. Compare the current line with its own Data Window value two bars earlier. Test a tie and a one-bar decline within a positive two-bar difference. Then inspect mode 2’s halved length separately from mode 3’s EMA weighting.
Use a fixed synthetic input or a documented chart interval to compare outputs. Record rounding and warm-up policy rather than assuming identically named scripts match. A zero or negative multiplier should produce an explicit error. No comparison on this page establishes which variant is profitable.
The separate HMA reference examines step response and rounding. The EMA guide explains recursive weights and initialization.
Pine Script v6: implementation and limits
This self-contained reference uses explicit positive integer windows and fixed parameters. Only the selected branch is plotted. It has no alerts, trade orders or higher-timeframe request. Compare values after sufficient history and distinguish the open bar from confirmed observations.
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Pineify
//@version=6
indicator(title="Hull Suite by InSilico", overlay=true, max_labels_count=500)
p_custom_sources() =>
[open, high, low, close, volume]
// Explicit integer windows and fixed parameters for all three branches.
p_ta_hull_suite_hma(series float src, simple int length) =>
halfLength = math.max(1, int(length / 2))
rootLength = math.max(1, int(math.round(math.sqrt(length))))
ta.wma(2 * ta.wma(src, halfLength) - ta.wma(src, length), rootLength)
p_ta_hull_suite_ehma(series float src, simple int length) =>
halfLength = math.max(1, int(length / 2))
rootLength = math.max(1, int(math.round(math.sqrt(length))))
ta.ema(2 * ta.ema(src, halfLength) - ta.ema(src, length), rootLength)
p_ta_hull_suite_thma(series float src, simple int length) =>
thirdLength = math.max(1, int(length / 3))
halfLength = math.max(1, int(length / 2))
ta.wma(3 * ta.wma(src, thirdLength) - ta.wma(src, halfLength) - ta.wma(src, length), length)
p_ta_hull_suite(series float source, simple int modeSwitch, simple int length, simple float lengthMult) =>
if length < 1 or lengthMult <= 0
runtime.error("Length and multiplier must be positive.")
if modeSwitch < 1 or modeSwitch > 3
runtime.error("Mode must be 1 (HMA), 2 (THMA) or 3 (EHMA).")
adjustedLength = math.max(1, int(length * lengthMult))
thmaLength = math.max(1, int(adjustedLength / 2))
hull = modeSwitch == 1 ? p_ta_hull_suite_hma(source, adjustedLength) : modeSwitch == 3 ? p_ta_hull_suite_ehma(source, adjustedLength) : p_ta_hull_suite_thma(source, thmaLength)
[hull, hull[2]]
[p_ind_1_mhull, p_ind_1_shull] = p_ta_hull_suite(close, 1, 55, 1)
p_ind_1_hull_color = p_ind_1_mhull > p_ind_1_shull ? color.rgb(38, 166, 154, 0) : color.rgb(239, 83, 80, 0)
p_ind_1_mhull_plot = plot(p_ind_1_mhull, title="Hull Suite - MHULL", color=p_ind_1_hull_color, linewidth=1)
p_ind_1_shull_plot = plot(p_ind_1_shull, title="Hull Suite - SHULL", color=p_ind_1_hull_color, linewidth=1)
fill(p_ind_1_mhull_plot, p_ind_1_shull_plot, title="Hull Suite - Band", color=color.new(p_ind_1_hull_color, 40))
Specify a checkable adaptation in Pineify
Specify the intended branch, rounding policy, source and minimum length. Ask for explicit input controls if needed, and define ties, unavailable history and confirmed color-change events. For a higher-timeframe version, require the actual request and confirmation policy. Review the generated source, run syntax validation and compare known numerical values before testing a trading rule.
Open Pine Script AI Coding AgentEducational indicator analysis. No measured trading performance is established here. Syntax validation does not prove formula equivalence, execution assumptions or profitability.