W.D. Gann Toolkit [UAlgo]W.D. Gann Toolkit is a multi tool market structure overlay built to project several classic Gann concepts directly from confirmed pivot points. Instead of focusing on only one angle or one timing idea, the script combines Gann Fan, Gann Box, Square of 9 levels, Master Time Factor markers, Gann retracements, and a live swing charting layer inside a single framework.
The indicator begins with confirmed pivot highs and pivot lows. Once a new pivot is detected, it becomes a structural anchor from which the selected Gann tools are drawn. This makes the toolkit adaptive to changing market structure rather than forcing the user to manually place every anchor point. The user can also decide how many historical pivots should remain active, which helps balance chart detail and readability.
One of the most important parts of any Gann based study is scale. A 1x1 angle only has meaning if the price per bar relationship is defined in a sensible way. For that reason, this script includes several scale methods. It can estimate scale from the broader chart range, from the most recent swing, from ATR, or from a fully manual input. This makes the toolkit flexible enough for different markets and chart styles while still keeping the geometry grounded in visible price behavior.
The Gann Fan module projects the classic angle family such as 1x8, 1x4, 1x3, 1x2, 1x1, 2x1, 3x1, 4x1, and 8x1. The Gann Box creates a ninety bar by scaled price box from the pivot. The Square of 9 module projects rotational price levels from the pivot using square root based calculations. The Master Time Factor module adds important future bar intervals from the pivot. The retracement module draws classic Gann proportional levels between two pivots. A simple Gann style swing chart is also included to visualize directional swing progression on the live chart.
In practical use, W.D. Gann Toolkit is useful for traders who want one structured environment for price, angle, time, and proportion analysis without manually recreating each Gann tool from scratch.
🔹 Features
🔸 Automatic Pivot Anchoring
All tools are drawn from confirmed pivot highs and pivot lows. This lets the toolkit respond to live market structure and keeps the drawings tied to meaningful turning points.
🔸 Multiple Scaling Methods
The script supports Auto Chart Range, Auto Swing, Auto ATR, and Manual scale modes. This is especially important for Gann work because angle interpretation depends on a stable price per bar relationship.
🔸 Gann Fan Projection
The indicator draws the classic Gann angle family from each selected pivot, including the key 1x1 line and the faster and slower angle groups around it.
🔸 Gann Box
A ninety bar box is projected from the pivot using the active scale. This gives the chart a combined time and price measurement zone.
🔸 Square of 9 Price Levels
The script projects Square of 9 levels such as 180°, 360°, 540°, and 720° from the pivot price using the square root transformation method.
🔸 Master Time Factor Markers
Vertical time markers are projected from each pivot at important intervals such as 30, 45, 90, and 180 bars.
🔸 Gann Retracements
When two pivots are available, the script draws classic Gann retracement levels such as 12.5%, 25%, 33.3%, 50%, 66.7%, 75%, and 87.5%.
🔸 Gann Swing Charting
A live swing line tracks directional shifts based on higher highs with higher lows or lower highs with lower lows, creating a simple structural swing map.
🔸 Historical Pivot Control
The user can choose how many recent pivots remain active for tool projection. This keeps the chart cleaner when needed.
🔸 Modern Color Theming
Different tool families use their own color groups, which makes it much easier to separate angles, price levels, time levels, retracements, and swing structure visually.
🔹 Calculations
1) Detecting Confirmed Pivot Highs and Lows
float ph = ta.pivothigh(high, i_piv_len, i_piv_len)
float pl = ta.pivotlow(low, i_piv_len, i_piv_len)
bool is_new_pivot = false
Pivot new_pivot = na
if not na(ph)
new_pivot := Pivot.new(time , bar_index , ph, true)
is_new_pivot := true
else if not na(pl)
new_pivot := Pivot.new(time , bar_index , pl, false)
is_new_pivot := true
This is the structural entry point of the whole toolkit.
The script waits for a confirmed pivot high or pivot low using the chosen pivot length on both sides. Once a pivot is confirmed, it stores the pivot time, bar index, price, and whether it is a high or low.
That pivot then becomes the anchor for all Gann tools. So the entire toolkit is driven by real confirmed turning points rather than by arbitrary chart positions.
2) Storing Recent Active Pivots
if is_new_pivot
active_pivots.unshift(new_pivot)
if active_pivots.size() > i_history + 1
active_pivots.pop()
Whenever a new pivot appears, it is pushed to the front of the active pivot list.
The script keeps only the most recent pivots needed for the selected historical depth. This prevents excessive clutter and ensures that the drawings stay focused on the most relevant recent anchors.
So the toolkit is always working from a controlled pivot memory rather than an unlimited list of old pivots.
3) ATR Based Scaling
float tr_atr = ta.atr(i_atr_len)
float scale_atr = nz(tr_atr, ta.tr) * i_atr_mult
This block creates the ATR based price per bar scale.
The script first calculates ATR over the selected length. That ATR value is then multiplied by the chosen multiplier to produce the scale.
This approach adapts the Gann geometry to current volatility. When ATR expands, the scale expands as well. When ATR contracts, the scale becomes tighter.
So ATR scaling is useful for traders who want the toolkit to stay responsive to the current volatility regime.
4) Chart Range Based Scaling
float price_range = ta.highest(high, i_range_len) - ta.lowest(low, i_range_len)
float scale_chart = price_range / i_range_len
This is the chart range scaling method.
The script measures the total price range across the selected number of bars, then divides that range by the same bar count. The result is an average price per bar scale.
This is often the safest automatic scaling choice because it ties the Gann geometry to the visible chart environment and helps avoid extreme or unrealistic slopes.
So chart range scaling is a balanced default when the user wants a stable visual relationship between price and time.
5) Swing Based Scaling
float scale_swing = na
if active_pivots.size() >= 2
Pivot p_curr = active_pivots.get(0)
Pivot p_prev = active_pivots.get(1)
int bars_diff = math.abs(p_curr.bar_index - p_prev.bar_index)
if bars_diff > 0
scale_swing := math.abs(p_curr.price - p_prev.price) / bars_diff
This method derives scale from the most recent completed pivot to pivot move.
The script measures the price distance between the two latest pivots and divides that by the bar distance between them. The result is a recent swing price per bar ratio.
This makes the Gann angles more sensitive to the latest market structure than the broader chart range method.
So swing scaling is useful when the user wants the geometry to follow the most recent active move more closely.
6) Choosing the Final Active Scale
float current_scale = switch i_scale_method
"Auto (Chart Range)" => scale_chart
"Auto (Swing)" => nz(scale_swing, scale_chart)
"Auto (ATR)" => scale_atr
"Manual" => i_manual_scale
=> i_manual_scale
This is the scale selection engine.
Depending on the user setting, the script picks:
chart range scale,
swing scale,
ATR scale,
or manual scale.
If swing scale is selected but there are not yet enough pivots to calculate it, the script falls back to chart range scale.
This is one of the most important parts of the indicator because all fan angles, box projections, and price projections depend on this final scale value.
7) Gann Fan Slope Logic
array names = array.from("1x8", "1x4", "1x3", "1x2", "1x1", "2x1", "3x1", "4x1", "8x1")
array dy_arr = array.from(1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 3.0, 4.0, 8.0)
array dx_arr = array.from(8.0, 4.0, 3.0, 2.0, 1.0, 1.0, 1.0, 1.0, 1.0)
float slope = dir * scale * (dy_arr.get(i) / dx_arr.get(i))
This is the mathematical foundation of the Gann Fan.
Each fan line is defined by a price over time ratio. For example:
1x1 means one unit of price per one unit of time,
2x1 means two units of price per one unit of time,
1x2 means one unit of price per two units of time.
The script multiplies the selected scale by the angle ratio to produce the actual slope of each line. Direction is positive for low based pivots and negative for high based pivots.
So the fan is not drawn with arbitrary visual angles. It is drawn from a real price per bar relationship.
8) Limiting Fan Projection Distance Safely
float max_y_dist = recent_range <= 0 ? p.price * 0.05 : recent_range * 1.0
float target_y_delta = slope * 100
int safe_bars = 100
if math.abs(target_y_delta) > max_y_dist
safe_bars := int(math.max(1, math.round(max_y_dist / math.abs(slope))))
This safety logic prevents the fan lines from projecting to unrealistic extremes.
The script estimates a maximum reasonable vertical travel based on the recent chart range. If a projected line would travel too far over a standard forward distance, the script shortens the number of bars used for the initial anchor segment.
This helps keep fast angles readable and prevents extreme slopes from distorting the chart.
So the fan remains visually controlled even when scale is large or price is volatile.
9) Drawing the Fan Lines
float future_price = p.price + (slope * safe_bars)
int future_bar = p.bar_index + safe_bars
line ln = line.new(p.bar_index, p.price, future_bar, future_price, color=line_col, style=line.style_solid, extend=extend.right)
Once the slope is known, the script calculates the projected price after a safe number of bars and draws the line from the pivot to that future point. The line is then extended to the right.
This means every fan ray begins from the pivot and continues forward as an active angular support or resistance guide.
10) Gann Box Calculation
float dir = p.is_high ? -1.0 : 1.0
int span = 90
float target_price = p.price + (dir * scale * span)
int target_bar = p.bar_index + span
box bx = box.new(p.bar_index, p.price, target_bar, target_price, border_color=c_box, bgcolor=color.new(c_box, 90), border_style=line.style_dashed)
The Gann Box uses a fixed time width of ninety bars.
The price height of the box is determined by:
scale × ninety
If the anchor is a high pivot, the box projects downward.
If the anchor is a low pivot, the box projects upward.
So the box combines price and time into a balanced projection area using the active scale.
11) Square of 9 Price Projection
float sqrt_p = math.sqrt(p.price)
array offsets = array.from(0.5, 1.0, 1.5, 2.0)
array names = array.from("Sq9 180°", "Sq9 360°", "Sq9 540°", "Sq9 720°")
float new_price = math.pow(sqrt_p + (dir * offsets.get(i)), 2)
This is the core Square of 9 calculation.
The script takes the square root of the pivot price, adds or subtracts a rotational offset, then squares the result again to get the projected price level.
The offsets correspond to:
180°,
360°,
540°,
and 720° style steps.
If the pivot is a high, the offsets project downward.
If the pivot is a low, they project upward.
So the Square of 9 module transforms the pivot price through the classic square root rotation concept associated with Gann price geometry.
12) Drawing Master Time Factor Levels
array intervals = array.from(30, 45, 90, 180)
for i = 0 to intervals.size() - 1
int b_idx = p.bar_index + intervals.get(i)
if b_idx <= bar_index + 100
line ln = line.new(b_idx, p.price, b_idx, p.price * (p.is_high ? 0.95 : 1.05), color=c_mtf, style=line.style_solid, extend=extend.both)
The Master Time Factor module projects important future time counts from the pivot.
The selected intervals are:
30 bars,
45 bars,
90 bars,
and 180 bars.
Each one is drawn as a vertical time marker. These are not price targets by themselves. They are timing references that may align with future reversals, reactions, or acceleration points.
So this module adds the time side of Gann analysis to the toolkit.
13) Gann Retracement Levels
float high_p = math.max(p1.price, p2.price)
float low_p = math.min(p1.price, p2.price)
float rng = high_p - low_p
array percents = array.from(0.125, 0.25, 0.333, 0.50, 0.667, 0.75, 0.875)
array p_names = array.from("12.5%", "25%", "33.3%", "50% (Key)", "66.7%", "75%", "87.5%")
float lvl_price = low_p + (rng * percents.get(i))
This is the retracement engine.
Given two pivots, the script measures the price range between them and then calculates key Gann proportional retracement levels inside that range.
The plotted levels are:
12.5%,
25%,
33.3%,
50%,
66.7%,
75%,
and 87.5%.
The 50% level is emphasized more strongly because it is one of the most widely watched Gann reference levels.
So this module gives the toolkit a proportional price structure layer between two pivot anchors.
14) Gann Swing Chart Logic
bool up_swing = high > high and low > low
bool dn_swing = high < high and low < low
This is the directional trigger for the swing chart.
A bullish swing condition requires both the high and the low of the current bar to be above the previous bar.
A bearish swing condition requires both the high and the low of the current bar to be below the previous bar.
So the swing chart changes direction only when the bar structure shows a clear full shift in both extremes.
15) Starting a New Swing Segment
if up_swing and swing_dir != 1
swing_dir := 1
int start_x = na(last_swing_line) ? bar_index : line.get_x2(last_swing_line)
float start_y = na(last_swing_line) ? low : line.get_y2(last_swing_line)
last_swing_line := line.new(start_x, start_y, bar_index, high, color=c_swg, width=2)
else if dn_swing and swing_dir != -1
swing_dir := -1
int start_x = na(last_swing_line) ? bar_index : line.get_x2(last_swing_line)
float start_y = na(last_swing_line) ? high : line.get_y2(last_swing_line)
last_swing_line := line.new(start_x, start_y, bar_index, low, color=c_swg, width=2)
When the swing direction changes, the script starts a new swing segment.
If the direction turns bullish, it starts a line toward the current high.
If the direction turns bearish, it starts a line toward the current low.
The starting point is either the previous bar’s extreme or the end of the last swing line if one already exists.
So the swing chart forms a connected directional structure rather than isolated markers.
16) Extending the Active Swing Segment
else
if swing_dir == 1 and not na(last_swing_line) and high > line.get_y2(last_swing_line)
line.set_xy2(last_swing_line, bar_index, high)
else if swing_dir == -1 and not na(last_swing_line) and low < line.get_y2(last_swing_line)
line.set_xy2(last_swing_line, bar_index, low)
If the current swing direction stays the same, the script extends the active swing line when a new extreme is made.
For bullish swings, it updates the end of the line to a new higher high.
For bearish swings, it updates the end of the line to a new lower low.
So the swing chart behaves like a live directional staircase that keeps extending until a new opposite swing begins.
17) Using Historical Pivots to Draw Multiple Tool Sets
for i = 0 to math.min(active_pivots.size() - 1, i_history - 1)
Pivot p = active_pivots.get(i)
GannElement f_el = fan_elements.get(i)
GannElement b_el = box_elements.get(i)
GannElement s_el = sq9_elements.get(i)
GannElement m_el = mtf_elements.get(i)
f_el.drawFan(p, current_scale, global_recent_range)
b_el.drawBox(p, current_scale)
s_el.drawSq9(p, current_scale)
m_el.drawMTF(p)
This loop is what makes the toolkit multi layer.
For each recent pivot within the selected history depth, the script redraws the fan, box, Square of 9 levels, and Master Time Factor markers.
So the chart can display tools from several recent pivots at once instead of only the latest anchor.
18) Drawing Retracements From Consecutive Pivots
if active_pivots.size() > i + 1
GannElement r_el = ret_elements.get(i)
Pivot p2 = active_pivots.get(i + 1)
r_el.drawRetracements(p, p2)
Retracements need two pivots, not one.
This block takes each pivot and the next older pivot, then draws the Gann retracement levels between them. That means retracement structure is always built from a real completed price range between two confirmed turning points.
So the retracement module is linked directly to pivot progression rather than floating independently on the chart.
Indicatore Pine Script®


