Created
December 26, 2025 18:15
-
-
Save ViralTaco/f8d077d73b0f87439eac86323e7f0927 to your computer and use it in GitHub Desktop.
A custom indicator for tradingview. Adapted from the Elder's Force Indicator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //Copyright © 2025 unsigned_lemon | |
| //Read the license agreement (at the bottom of the page), before using this indicator. | |
| //@version=6 | |
| //@description RSI Style Elder Force Index with bar coloring | |
| indicator(title = "Viral Force Index Enhanced", shorttitle = "vfi v3", format = format.volume, | |
| precision = 4) | |
| // ===== CONSTANTS ===== | |
| var int kMaxFreeBarsBack = 5000 - 1 | |
| // Group Constants | |
| string G_VFI = "VFI Settings" | |
| string G_LINREG = "Linear Regression" | |
| string G_EXTREME = "Extreme Levels" | |
| string G_STYLE = "Styling" | |
| // ===== TYPES ===== | |
| type DebugPanel | |
| table id | |
| bool show | |
| // Initialize the table | |
| method init(DebugPanel this, simple int columns = 2, simple int rows = 7) => | |
| if this.show and barstate.islast | |
| this.id := table.new(position = position.top_right, | |
| columns = columns, | |
| rows = rows, | |
| bgcolor = color.new(color.gray, 95), | |
| border_width = 1, | |
| border_color = color.gray) | |
| table.cell(this.id, 0, 0, "PARAMETER", text_color = color.white) | |
| table.cell(this.id, 1, 0, "VALUE", text_color = color.white) | |
| // Update a row in the table | |
| method update_row(DebugPanel this, int row, string label, string val, color val_color) => | |
| if this.show and barstate.islast | |
| table.cell(this.id, 0, row, label, text_color = color.gray) | |
| table.cell(this.id, 1, row, val, text_color = val_color) | |
| // ===== INPUTS ===== | |
| // Group 1: VFI Settings | |
| float source = input.source(close, "Source", group = G_VFI, tooltip = "The source price to use for calculations.") | |
| int length = input.int(13, "EMA Length", minval = 1, group = G_VFI, tooltip = "The length of the EMA smoothing.") | |
| int max_lookback_bars = input.int(500, "Lookback Length", minval = 2, | |
| maxval = kMaxFreeBarsBack, group = G_VFI, tooltip = "Number of bars to look back for scaling and percentile rank.") | |
| // Group 2: Linear Regression | |
| int linreg_length = input.int(13, "Linear Regression Length", minval = 1, | |
| group = G_LINREG, tooltip = "Length for the Linear Regression calculation.") | |
| int linreg_offset = input.int(3, "Linear Regression Offset", group = G_LINREG, tooltip = "Offset for the Linear Regression.") | |
| // Group 3: Extreme Levels | |
| float upper_threshold = input.float(95.0, "Upper Threshold", minval = 50, maxval = 100, | |
| step = 0.5, group = G_EXTREME, tooltip = "Percentile rank threshold for overbought conditions.") | |
| float lower_threshold = input.float(5.0, "Lower Threshold", minval = 0, maxval = 50, | |
| step = 0.5, group = G_EXTREME, tooltip = "Percentile rank threshold for oversold conditions.") | |
| // Group 4: Styling | |
| var color up_color = input.color(#7bed36, "Up Color", group = G_STYLE, inline = "colors", tooltip = "Color for positive values.") | |
| var color down_color = input.color(#f79400, "Down Color", group = G_STYLE, inline = "colors", tooltip = "Color for negative values.") | |
| var color extreme_color = input.color(color.blue, "Extreme Color", group = G_STYLE, | |
| inline = "colors", tooltip = "Color for extreme levels.") | |
| bool use_linreg_color = input.bool(true, "Use Linear Regression for Bar Color", group = G_STYLE, | |
| tooltip = "If true, uses the Linear Regression slope for bar coloring.") | |
| bool linreg_gradient_on = input.bool(true, "Use gradient color for linear regression line", | |
| group = G_STYLE, inline = "colors2") | |
| var color linreg_solid = input.color(color.white, "Linear regression line color", | |
| group = G_STYLE, inline = "colors2", active = not linreg_gradient_on) | |
| bool show_debug = input.bool(true, "Show Debug Panel", group = G_STYLE, tooltip = "Toggle the visibility of the debug panel.") | |
| // ===== CALCULATIONS ===== | |
| varip series float volume_symbol = input.source(volume, "use volume ticker") | |
| float price_change = ta.change(source / syminfo.mintick) | |
| if price_change == 0 | |
| price_change := price_change[1] | |
| float raw_change = price_change * volume_symbol | |
| // Simplified scaling factor | |
| float kFactor = math.max(ta.highest(math.abs(raw_change), max_lookback_bars) / 1000, 1.0) | |
| // Calculate VFI with improved EMA smoothing | |
| float raw_vfi = raw_change / kFactor | |
| float vfi = ta.ema(raw_vfi, length) | |
| // Use fixed lookback for percent rank to ensure consistency | |
| float normed_rank = ta.percentrank(vfi, max_lookback_bars) | |
| // Improved extreme detection using statistical thresholds | |
| bool is_extreme_level = normed_rank >= upper_threshold or normed_rank <= lower_threshold | |
| // Linear regression for trend detection | |
| float linreg = ta.linreg(vfi, linreg_length, linreg_offset) | |
| // Color calculations | |
| color current_color = color.from_gradient(vfi, -50, 50, down_color, up_color) | |
| color extreme_color_final = is_extreme_level ? extreme_color : current_color | |
| color smooth_color = color.from_gradient(linreg, -25, 25, down_color, up_color) | |
| color bar_fill_color = use_linreg_color ? smooth_color : extreme_color_final | |
| color colin = linreg_gradient_on ? smooth_color : linreg_solid | |
| // ===== PLOTS & VISUALS ===== | |
| // Main VFI plot with improved styling | |
| plot(vfi, "VFI", | |
| color = extreme_color_final, | |
| style = plot.style_histogram, | |
| linewidth = 1, | |
| histbase = 0) | |
| // Linear regression trend line | |
| plot(linreg, "Linear Regression", | |
| color = colin, | |
| style = plot.style_line, | |
| linewidth = 1) | |
| // Reference levels | |
| hline(100, "Upper Bound", color = color.new(color.white, 70), linestyle = hline.style_dotted) | |
| h75 = hline(75, "Upper Quartile", color = color.new(color.white, 80), linestyle = hline.style_dotted) | |
| h50 = hline(50, "Mid Upper", color = color.new(color.white, 90), linestyle = hline.style_dotted) | |
| h25 = hline(25, "Low Upper", color = color.new(color.white, 90), linestyle = hline.style_dotted) | |
| h0 = hline(0, "Zero Line", color = color.new(color.gray, 50), linestyle = hline.style_dotted) | |
| hm25 = hline(-25, "High Lower", color = color.new(color.white, 90), linestyle = hline.style_dotted) | |
| hm50 = hline(-50, "Mid Lower", color = color.new(color.white, 90), linestyle = hline.style_dotted) | |
| hm75 = hline(-75, "Lower Quartile", color = color.new(color.white, 80), linestyle = hline.style_dotted) | |
| hline(-100, "Lower Bound", color = color.new(color.white, 70), linestyle = hline.style_dotted) | |
| // Fills | |
| fill(h0, h25, color.new(up_color, 95), title = "0-25 Fill") | |
| fill(h25, h50, color.new(up_color, 90), title = "25-50 Fill") | |
| fill(h50, h75, color.new(up_color, 85), title = "50-75 Fill") | |
| fill(h0, hm25, color.new(down_color, 95), title = "0-(-25) Fill") | |
| fill(hm25, hm50, color.new(down_color, 90), title = "(-25)-(-50) Fill") | |
| fill(hm50, hm75, color.new(down_color, 85), title = "(-50)-(-75) Fill") | |
| // Bar coloring | |
| barcolor(bar_fill_color) | |
| // Background color for extreme levels | |
| bgcolor(is_extreme_level ? color.new(extreme_color, 90) : na, title = "Extreme Level Background") | |
| // Debug Panel | |
| var DebugPanel panel = DebugPanel.new(table(na), show_debug) | |
| panel.init() | |
| panel.update_row(1, "Raw VFI", str.tostring(raw_vfi, "#.####"), color.orange) | |
| panel.update_row(2, "Smoothed VFI", str.tostring(vfi, "#.####"), current_color) | |
| panel.update_row(3, "Percent Rank", str.tostring(normed_rank, "#.##") + "%", | |
| is_extreme_level ? extreme_color : color.gray) | |
| //panel.update_row(4, "Scaling Factor", str.tostring(kFactor, "#.####"), color.silver) | |
| panel.update_row(4, "LinReg Slope", str.tostring(linreg, "#.####"), smooth_color) | |
| panel.update_row(5, "Extreme Level", is_extreme_level ? "YES" : "NO", | |
| is_extreme_level ? extreme_color : color.green) | |
| // ===== ALERTS ===== | |
| alertcondition(is_extreme_level, "VFI Extreme Level", | |
| "VFI has entered extreme territory at {{close}}") | |
| // | |
| // The Viral License - 1.1.0~use-only | |
| // | |
| // Permission is hereby granted, free of charge, | |
| // to anyone obtaining a copy of this software (the 'Recipient', 'You', 'Your'), | |
| // associated documentation files (the 'Software', the 'Indicator'), | |
| // and the source code of the Software, including any inline documentation (the 'Source'), | |
| // to use the Software, and Source, subject to the following conditions: | |
| // | |
| // • The above copyright notice as well as this permission notice (including the next paragraphs) | |
| // shall be included in all copies, or substantial portions of the Software as well as the Source. | |
| // | |
| // • For the purpose of this license, the term 'use' is dvfined as: | |
| // 0) Applying the Indicator to a chart on TradingView | |
| // 1) Reading the Source | |
| // 2) Editing the Source, applying the result to a chart on TradingView for Your use ONLY. | |
| // 3) The use is Yours CANNOT be transfered. | |
| // | |
| // • The Software, the Source, or portions of the Source | |
| // SHALL NOT be distributed without EXPRESS AUTHORIZATION from the Author. | |
| // | |
| // • Commercial use of the Software without PRIOR SIGNED APPROVAL from the Author | |
| // is PROHIBITED, and WILL result in litigation. | |
| // | |
| // • You ACCEPT to STOP using the Software if ANY condition is illegal, or null. | |
| // | |
| // • You UNDERSTAND AND You ACCEPT every condition and its —potential— implications, | |
| // including all limitations layed herein, including the following: | |
| // | |
| // THE SOFTWARE AND THE SOURCE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. | |
| // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, | |
| // OR IN AN CONNECTION WITH, THE SOFTWARE, OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
| // | |
| // Mediation and Arbitration: THE BELGIAN CENTRE FOR ARBITRATION AND MEDIATION |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment