Ichimoku Oscillator
"Ichimoku Oscillator" by LonesomeTheBlue, MPL-2.0. Ported to FloScript by FloSignals; modifications under MPL-2.0. Original: Ichimoku Oscillator (v1.0), read 2026-10-12T16:06:40.737Z; source language v5.
Licence: Mozilla Public License 2.0 (MPL-2.0) — full text. The source is published with it, modifications included, under the same licence.
Ichimoku Oscillator by LonesomeTheBlue, ported from Pine v5. Pane indicator with 5 plots, 6 marker series, bar/background colouring, alerts and 40 inputs.
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © LonesomeTheBlue
// ------------------------------------------------------------------------------------------------
// Original author: LonesomeTheBlue
// Original title: Ichimoku Oscillator
// Licence: MPL-2.0 (the header above is the original notice, kept verbatim)
// Pine version: 5
// Fetched: 2026-10-12
// Ported to FloScript by FloSignals; modifications under MPL-2.0.
// Converter: @flosignals/floscript 0.1.0, strict mode, score 100/100
// ------------------------------------------------------------------------------------------------
//@floscript=1
//@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) : 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)
This file is under the Mozilla Public License 2.0; it is a port of the original by LonesomeTheBlue, with the original licence header kept and the changes made for FloScript noted in the file.
- v2
Library refresh 2026-10-14
- v1
Library refresh 2026-10-12
Disclaimer. Scripts are written and published by members, or ported by FloSignals from open-source originals, and are their authors' own work and opinion. FloSignals does not review them for correctness and nothing in a script is financial advice or a recommendation to buy or sell anything — read the Risk Disclaimer. Posting here is under the Community Rules; a script that is not the poster's to post can be reported as the Copyright & Takedowns page says.

Comments (0)
No comments yet. Members can leave one.