Indicator · Pine Script v5 · Own pane

Ichimoku Oscillator

by regalouisei· code credited to LonesomeTheBlue

The Ichimoku Oscillator indicator calculates conversion line, base line, leading span, and lagging span using specified periods.

View on GitHub

GitHub stars2on the repository
Pine versionv5runs as is
Lines of code186
Settings40inputs
LicenceNone statedfile: MPL-2.0
Last update8 months ago25 Feb 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

186 lines of Pine Script v5 from pinescript/editors_picks/ichimoku-oscillator.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

ichimoku-oscillator.pine
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © LonesomeTheBlue
 
//@version=5
indicator(title="Ichimoku Oscillator", shorttitle="IO", explicit_plot_zorder = true)
conversionPeriods = input.int(8, minval=1, title="Conversion Line Length", group = "Setup")
basePeriods = input.int(13, minval=1, title="Base Line Length", group = "Setup")
laggingSpan2Periods = input.int(26, minval=1, title="Leading Span B Length", group = "Setup")
displacement = input.int(13, minval=1, title="Lagging Span", group = "Setup")
useatr = input.bool(defval = true, title ="Use ATR", tooltip = "Protection from Whipsaw", group = "Setup")
atrlen = input.int(defval = 9, title = " Length", minval = 1, group = "Setup")
atrmul = input.float(defval = 2.0, title = " Mult", minval = 0.1, step = 0.1, group = "Setup")
bounceoff = input.bool(defval = false, title = "Bounce Off Support/Resistance", tooltip = "Enables the Additional Entries when price bounce off Support/Resistance Zone", group = "Setup")
useema = input.bool(defval = true, title ="Show EMA", group = "Setup")
emalen = input.int(defval = 9, title = " Length", minval = 1, group = "Setup")
emacol = input.color(defval = #d1c4e9, title = " Color", group = "Setup")
emawd = input.int(defval = 1, title = " Width", minval = 1, maxval = 5, group = "Setup")
ematkpartprft = input.bool(defval = true, title = "Take Partial Profit by EMA")
entexlongcol = input.color(defval = color.white, title = "Entry/Exit Colors", inline = "entcol", group = "Colors")
entexshortcol = input.color(defval = color.yellow, title = "", inline = "entcol", group = "Colors")
coloredbg = input.bool(defval = true, title = "Colored Background", group = "Colors")
bgcolupI = input.string(defval = "Green", title = " Uptrend", options = ["Green", "Red", "Blue"], group = "Colors")
bgcoldnI = input.string(defval = "Blue", title = " Downtrend", options = ["Green", "Red", "Blue"], group = "Colors")
bgtransp = input.int(defval = 60, title = " Transparency", step = 10, minval = 0, maxval = 100, group = "Colors")
upcol1 = input.color(defval = color.rgb(0 , 250, 0, 0), title = "Uptrend Colors", inline = "upcols", group = "Colors")
upcol2 = input.color(defval = color.rgb(0 , 190, 0, 0), title = "", inline = "upcols", group = "Colors")
upcol3 = input.color(defval = color.rgb(0 , 130, 0, 0), title = "", inline = "upcols", group = "Colors")
upcol4 = input.color(defval = color.rgb(0 , 70, 0, 0), title = "", inline = "upcols", group = "Colors")
dbcol1 = input.color(defval = color.rgb(250, 0, 0, 0), title = "Downtrend Colors", inline = "dbcols", group = "Colors")
dbcol2 = input.color(defval = color.rgb(190, 0, 0, 0), title = "", inline = "dbcols", group = "Colors")
dbcol3 = input.color(defval = color.rgb(130, 0, 0, 0), title = "", inline = "dbcols", group = "Colors")
dbcol4 = input.color(defval = color.rgb(70, 0, 0, 0), title = "", inline = "dbcols", group = "Colors")
inSRcolor = input.color(defval = #d1d4dc, title = "In Support/Resistance Zone", group = "Colors")
// Alerts
mainalert = input.bool(defval = true, title = "Main Buy/Sell Alert", group = "Alerts")
addalert = input.bool(defval = true, title = "Additional Buy/Sell Alert", group = "Alerts")
alertlongmsg  = input.string(defval = "Buy / Main, Close = close", title = " Long message", group = "Alerts")
alertshortmsg = input.string(defval = "Sell / Main, Close = close", title = " Short message", group = "Alerts")
alertaddlongmsg  = input.string(defval = "Buy / Additonal, Close = close", title = " Long message", group = "Alerts")
alertaddshortmsg = input.string(defval = "Sell / Additonal, Close = close", title = " Short message", group = "Alerts")
mainfrequency = input.string(defval = alert.freq_once_per_bar_close, title = " Frequency", options = [alert.freq_once_per_bar_close, alert.freq_once_per_bar], group = "Alerts")
closealert = input.bool(defval = true, title = "Close Position Alert", group = "Alerts")
closepartalert = input.bool(defval = true, title = "Take Partial Profit Alert", group = "Alerts")
closemainmsg  = input.string(defval = "Close Position, Close = close", title = " Close Position Message", group = "Alerts")
closepartmsg = input.string(defval = "Take Partial Profit, Close = close", title = " Take Partial Profit Message", group = "Alerts")
closefrequency = input.string(defval = alert.freq_once_per_bar, title = " Frequency", options = [alert.freq_once_per_bar_close, alert.freq_once_per_bar], group = "Alerts")

// ichimoku calculation
donchian(len) => math.avg(ta.lowest(len), ta.highest(len))
conversionLine = donchian(conversionPeriods)
baseLine = donchian(basePeriods)
leadLine1 = math.avg(conversionLine, baseLine)
leadLine2 = donchian(laggingSpan2Periods)

// Oscillator calculation
var int mtrend = 0
var int trend = 0
cloudup = leadLine1 >= leadLine2
clouddn = leadLine1 <= leadLine2
CloudMin = math.min(leadLine1[displacement - 1], leadLine2[displacement - 1])
CloudMax = math.max(leadLine1[displacement - 1], leadLine2[displacement - 1])
inthecloud = close >= CloudMin and close <= CloudMax
mtrend := close > CloudMax ? 1 : close < CloudMin ? -1 : mtrend 

// first layer
Oscline = mtrend == 1 ? (close - CloudMin) : (close - CloudMax)
Osccolor = inthecloud ? inSRcolor: close > CloudMax ? upcol1 : dbcol1

//second layer
Lagging = Oscline + (mtrend == 1 ? math.max(close - CloudMax[displacement - 1], 0) : // , close - close[displacement - 1]
                                   math.min(close - CloudMin[displacement - 1], 0)) // , close - close[displacement - 1]
//third layer
ConvBase = Lagging + (mtrend == 1 ? math.max((conversionLine - baseLine), 0) : math.min((conversionLine -baseLine), 0))
ConvBaseColor = conversionLine >= baseLine ? upcol3 : dbcol3

// fourth layer
cloud = ConvBase + (mtrend == 1 ? math.max(leadLine1 - leadLine2, 0) : math.min(leadLine1 - leadLine2, 0))

anyofthemrising = ta.change(conversionLine) > 0 or ta.change(baseLine) > 0
anyofthemfalling = ta.change(conversionLine) < 0 or ta.change(baseLine) < 0
convoverbase = conversionLine >= baseLine
baseoverconv = conversionLine <= baseLine
// little Protection from whipsaw
tole = useatr ? ta.atr(atrlen) * atrmul : 0

// calculation of the trend and getting entry level if trend appears
var float entrylevel = na
if mtrend == 1
    trend := mtrend[1] == -1 ? 0 : trend
    if trend < 4 and close > CloudMax
        trend := (Lagging > Oscline ? 1 : 0) + 
                 (convoverbase and anyofthemrising? 1 : 0) +
                 (cloudup ? 1 : 0) +
                 1
        if trend == 4
            entrylevel := close
    else
        trend := (conversionLine < baseLine - tole ? 0 : trend)
else if mtrend == -1
    trend := mtrend[1] == 1 ? 0 : trend
    if trend > - 4 and close < CloudMin
        trend := (Lagging < Oscline ? -1 : 0) - 
                 (baseoverconv and anyofthemfalling ? 1 : 0) -
                 (clouddn ? 1 : 0) -
                 1
        if trend == -4
            entrylevel := close
    else
        trend := (conversionLine > baseLine + tole? 0 : trend)

// Background coloring if Enabled
uptmult = 159 + math.pow(trend, 3)
dntmult = 159 - math.pow(trend, 3)
bgcolup = color.rgb(bgcolupI == "Red" ? uptmult : 0, bgcolupI == "Green" ? uptmult : 0, bgcolupI == "Blue" ? uptmult : 0, bgtransp)
bgcoldn = color.rgb(bgcoldnI == "Red" ? dntmult : 0, bgcoldnI == "Green" ? dntmult : 0, bgcoldnI == "Blue" ? dntmult : 0, bgtransp)
bgcolor(color = coloredbg ? trend > 0 ? bgcolup : trend < 0 ? bgcoldn : inSRcolor : na)

// ploting layers
plot(cloud, color = mtrend == 1 ? upcol4 : dbcol4, style = plot.style_area)
plot(ConvBase, color = ConvBaseColor, style = plot.style_area)
plot(Lagging, color = close > CloudMax ? upcol2 : close < CloudMin ? dbcol2 : color.new(color.white, 100), style = plot.style_area)
plot(Oscline, color = Osccolor, style = plot.style_area)

// convert the message
getClose(message) => str.replace(message, "close", str.tostring(close))

// closing main position
closetrade = ta.change(trend) != 0 and math.abs(trend[1]) == 4
plotshape(cloud, color = closetrade ? (trend[1] > 0 ? entexlongcol : entexshortcol): color.new(color.white, 100), style = shape.xcross, size = size.small, location = location.absolute)
if closetrade and closealert
    alert(getClose(closemainmsg), closefrequency)

// take long position
uptrend = trend == 4 and ta.change(trend) != 0
plotshape(0, color = uptrend ? entexlongcol : color.new(color.white, 100), style = shape.triangleup, size = size.small, location = location.absolute)
bouncbackup = bounceoff and trend == 4 and close > CloudMax and inthecloud[1]
plotshape(0, color = bouncbackup ? entexlongcol : color.new(color.white, 100), style = shape.triangleup, size = size.tiny, location = location.absolute)

// long position alerts
if trend == 4
    if uptrend and mainalert
        alert(getClose(alertlongmsg), mainfrequency)
    if bouncbackup and addalert
        alert(getClose(alertaddlongmsg), mainfrequency)

// take short position
downtrend = trend == -4 and ta.change(trend) != 0
plotshape(0, color = downtrend ? entexshortcol : color.new(color.white, 100), style = shape.triangledown, size = size.small, location = location.absolute)
bouncbackdn = bounceoff and trend == -4 and close < CloudMin  and inthecloud[1]
plotshape(0, color = bouncbackdn ? entexshortcol : color.new(color.white, 100), style = shape.triangledown, size = size.tiny, location = location.absolute)

// short position alerts
if trend == -4
    if downtrend and mainalert
        alert(getClose(alertshortmsg), mainfrequency)
    if bouncbackdn and addalert
        alert(getClose(alertaddshortmsg), mainfrequency)

// plot ema line if enabled
emaline = ta.ema(cloud, emalen) 
plot(emaline, linewidth = emawd, color = useema ? emacol : color.new(color.white, 100))

// possible/partially take profit if profitable
convcrossbase = ta.crossover(conversionLine, baseLine)
basecrosscons = ta.crossover(baseLine, conversionLine)
emacrosscloud = ta.crossover(emaline, cloud)
cloudcrossema = ta.crossover(cloud, emaline)

profitable = trend == 4 and close > entrylevel or trend == -4 and close < entrylevel

posexitcol = profitable ? trend == 4 and basecrosscons ? entexlongcol : 
                         trend == 4 and emacrosscloud and ematkpartprft ? emacol : 
                         trend == -4 and convcrossbase ? entexshortcol :
                         trend == -4 and cloudcrossema and ematkpartprft ? emacol :
                         color.new(color.white, 100) :
                         color.new(color.white, 100)

plotshape(cloud, color = posexitcol, location = location.absolute, style = shape.xcross, size = size.tiny)
partclose =  trend == 4 and basecrosscons or 
             trend == 4 and emacrosscloud and ematkpartprft or
             trend == -4 and convcrossbase or 
             trend == -4 and cloudcrossema and ematkpartprft 

// partially take profit alert
if partclose and closepartalert
    alert(getClose(closepartmsg), closefrequency)

Overview

Ichimoku Oscillator plots these values in a separate pane along with an optional EMA overlay. Main settings allow customization of line lengths, ATR parameters for whipsaw protection, and EMA options. Signals are generated for entries and exits with optional partial profit taking by the EMA. Colored background highlights uptrend and downtrend periods. Support and resistance bounce can trigger additional entries when enabled.

Details

Published by

regalouisei on GitHub

Code credit

LonesomeTheBlue, as written in the script's header

Type

Indicator, Pine Script v5

Draws

Separate pane below the chart

Category

Trend, Oscillators & momentum, Moving averages

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Conversion Line Lengthint8conversionPeriods
Base Line Lengthint13basePeriods
Leading Span B Lengthint26laggingSpan2Periods
Lagging Spanint13displacement
Use ATRbooltrueuseatr
 Lengthint9atrlen
 Multfloat2.0atrmul
Bounce Off Support/Resistanceboolfalsebounceoff
Show EMAbooltrueuseema
 Lengthint9emalen
 Colorcolor#d1c4e9emacol
 Widthint1emawd
Show all 40 settings
SettingTypeDefaultVariable
Take Partial Profit by EMAbooltrueematkpartprft
Entry/Exit Colorscolorcolor.whiteentexlongcol
entexshortcolcolorcolor.yellowentexshortcol
Colored Backgroundbooltruecoloredbg
 UptrendstringGreenbgcolupI
 DowntrendstringBluebgcoldnI
 Transparencyint60bgtransp
Uptrend Colorscolorcolor.rgb(0 , 250, 0, 0)upcol1
upcol2colorcolor.rgb(0 , 190, 0, 0)upcol2
upcol3colorcolor.rgb(0 , 130, 0, 0)upcol3
upcol4colorcolor.rgb(0 , 70, 0, 0)upcol4
Downtrend Colorscolorcolor.rgb(250, 0, 0, 0)dbcol1
dbcol2colorcolor.rgb(190, 0, 0, 0)dbcol2
dbcol3colorcolor.rgb(130, 0, 0, 0)dbcol3
dbcol4colorcolor.rgb(70, 0, 0, 0)dbcol4
In Support/Resistance Zonecolor#d1d4dcinSRcolor
Main Buy/Sell Alertbooltruemainalert
Additional Buy/Sell Alertbooltrueaddalert
 Long messagestringBuy / Main, Close = closealertlongmsg
 Short messagestringSell / Main, Close = closealertshortmsg
 Long messagestringBuy / Additonal, Close = closealertaddlongmsg
 Short messagestringSell / Additonal, Close = closealertaddshortmsg
 Frequencystringalert.freq_once_per_bar_closemainfrequency
Close Position Alertbooltrueclosealert
Take Partial Profit Alertbooltrueclosepartalert
 Close Position MessagestringClose Position, Close = closeclosemainmsg
 Take Partial Profit MessagestringTake Partial Profit, Close = closeclosepartmsg
 Frequencystringalert.freq_once_per_barclosefrequency
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

Beep Boop

by magic8bot
409 stars

This indicator calculates a modified MACD oscillator and signal line alongside a trend EMA filter, plotting the output as a stylized column histogram in a separate pane. Instead of plotting true MACD distance, it quantifies positive and negative histogram mome

Indicator v4 Oscillators & momentumTrend
Updated 3 years ago · MIT GitHub repository of Beep Boop
218 stars

Multi-Timeframe Analysis Suite calculates trend direction and momentum conditions across five user-selected timeframes using moving averages, RSI, and Stochastic oscillators. It evaluates moving average slope and oscillator levels to compute trend alignment, m

Indicator v6 Screeners & dashboardsTrend
Updated 3 months ago · None stated GitHub repository of Multi-Timeframe Analysis Suite

KamaFama

by Mastaaa1987
141 stars

KamaFama is an indicator that translates a Freqtrade trading strategy into Pine Script for visualization. It combines Kaufman Adaptive Moving Average (KAMA), MAMA/FAMA calculations derived via Hilbert Transform, Williams %R, and correlation trend filters to ev

Indicator v6 Moving averagesOscillators & momentum
Updated 6 weeks ago · MIT GitHub repository of KamaFama

MultiIndicator

by capissimo
114 stars

MultiIndicator combines multiple technical indicators into a single separate pane to save chart space. It calculates and displays market regime detection based on ordinary least squares regression, a Holt exponential smoothing crossover, normalized RSI, ADX, a

Indicator v4 Oscillators & momentumTrend
Updated 1 year ago · None stated GitHub repository of MultiIndicator

Elder Impulse System

by mihakralj
99 stars

Elder Impulse System plots a column series in a separate pane. It compares a 13-period exponential moving average with its previous value and a MACD histogram with its previous value. A rising EMA and rising histogram print 1, a falling EMA and falling histogr

Indicator v5 TrendOscillators & momentum
Updated 4 weeks ago · Apache-2.0 GitHub repository of Elder Impulse System
47 stars

This indicator calculates the Williams Gator Oscillator derived from Bill Williams Alligator lines and plots dual histograms in a separate pane. The upper histogram displays the absolute difference between the Jaw and Teeth moving averages, while the lower his

Indicator v6 Oscillators & momentumMoving averages
Updated 8 months ago · MIT GitHub repository of Williams Gator Oscillator

More indicators

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers