Ichimoku Kinko Hyo [+Conditions]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// ©thermal_winds
// @version=5

indicator(title="Ichimoku Cloud Twist", shorttitle="ICT", overlay=true)
// strategy(title="Ichimoku Cloud Twist", shorttitle="ICT", overlay=true, max_bars_back=4900, calc_on_every_tick=false, calc_on_order_fills=false, initial_capital=100.0, default_qty_type=strategy.percent_of_equity, default_qty_value=100.0, commission_type=strategy.commission.percent, commission_value=0.1)

// --- (Start) Ichimoku kinko Hyo ------------------------------------------- // Credits : LonesomeTheBlue

middleDonchian(Length) =>
    lower = ta.lowest(Length), upper = ta.highest(Length)
    math.avg(upper, lower)

conversionPeriods = input.int(defval=9, minval=1)
basePeriods = input.int(defval=26, minval=1)
laggingSpan2Periods = input.int(defval=52, minval=1)
displacement = input.int(defval=26, minval=1)

Tenkan = middleDonchian(conversionPeriods)
Kijun =  middleDonchian(basePeriods)
xChikou = close
SenkouA = middleDonchian(laggingSpan2Periods)
SenkouB = (Tenkan[basePeriods-displacement] + Kijun[basePeriods-displacement]) / 2

plot(Tenkan, color=color.red, title="Tenkan", linewidth=2, display=display.all)
plot(Kijun, color=color.blue, title="Kijun", linewidth=2, display=display.all)
plot(xChikou, color= color.lime , title="Chikou", offset = -displacement, display=display.all)
A = plot(SenkouA, color=color.new(color.red,70), title="SenkouA", offset=displacement, display=display.none)
B = plot(SenkouB, color=color.new(color.green,70), title="SenkouB", offset=displacement, display=display.none)
fill(A, B, color= (SenkouA > SenkouB) ? color.new(color.red,90) : color.new(color.green,90), title='Kumo Cloud')

// --- (End) Ichimoku kinko Hyo --------------------------------------------- //

// --- (Start) Ichimoku conditions ------------------------------------------ //

red_kumo_cloud = SenkouA[displacement] > SenkouB[displacement] // Verified
green_kumo_cloud = SenkouA[displacement] < SenkouB[displacement] // Verified
red_kumo_cloud_future = SenkouA > SenkouB // Verified
green_kumo_cloud_future = SenkouA < SenkouB // Verified
close_crosses_kijun = close > Kijun and close[1] < Kijun[1] // Verified
tenkan_over_kijun = Tenkan > Kijun // Verified
tenkan_below_kijun_tenkan_up_kijun_flat = (Tenkan < Kijun) and (ta.change(Tenkan, 1) > 0) and (Kijun[0] == Kijun[1]) // Verified
[close_middle_bb, close_upper_bb, close_lower_bb] = ta.bb(series=close, length=20, mult=1)
chikou_open_space = (xChikou < close_lower_bb[displacement] and xChikou < SenkouA[2*displacement] and xChikou < SenkouB[2*displacement] and xChikou < 2*low[displacement]) or (xChikou > close_upper_bb[displacement] and xChikou > SenkouA[2*displacement] and xChikou > SenkouB[2*displacement] and xChikou > 2*high[displacement]) // Verified
future_senkouB_up_flat =  green_kumo_cloud_future and (ta.change(SenkouB, 1) > 0 or SenkouB[0] == SenkouB[1]) // Verified
tenkan_in_cloud = (Tenkan < SenkouA[displacement] and Tenkan > SenkouB[displacement]) or (Tenkan > SenkouA[displacement] and Tenkan < SenkouB[displacement]) // Verified
kijun_in_cloud = (Kijun < SenkouA[displacement] and Kijun > SenkouB[displacement]) or (Kijun > SenkouA[displacement] and Kijun < SenkouB[displacement]) // Verified
price_in_green_cloud = green_kumo_cloud and ((open < SenkouB[displacement] and open > SenkouA[displacement]) or (high < SenkouB[displacement] and high > SenkouA[displacement]) or (low < SenkouB[displacement] and low > SenkouA[displacement]) or (close < SenkouB[displacement] and close > SenkouA[displacement])) // Verified
price_in_red_cloud = red_kumo_cloud and ((open < SenkouA[displacement] and open > SenkouB[displacement]) or (high < SenkouA[displacement] and high > SenkouB[displacement]) or (low < SenkouA[displacement] and low > SenkouB[displacement]) or (close < SenkouA[displacement] and close > SenkouB[displacement])) // Verified
price_in_cloud = price_in_green_cloud or price_in_red_cloud // Verified
chikou_in_cloud = (green_kumo_cloud[displacement] and (xChikou < SenkouB[2*displacement] and xChikou > SenkouA[2*displacement])) or (red_kumo_cloud[displacement] and (xChikou < SenkouA[2*displacement] and xChikou > SenkouB[2*displacement])) // Verified
price_tenkan_kijun_chikou_not_in_cloud = (not tenkan_in_cloud) and (not kijun_in_cloud) and (not price_in_cloud) and (not chikou_in_cloud) // Verified
cloud_thickness = math.abs(SenkouA[displacement] - SenkouB[displacement])
percent_thick_cloud = green_kumo_cloud ? (cloud_thickness * 100) / SenkouA[displacement] : (cloud_thickness * 100) / SenkouB[displacement]
thickness_threshold = 14, thickest_cloud = ta.highest(percent_thick_cloud, 10000)
thick_cloud = percent_thick_cloud >= (thickest_cloud * (thickness_threshold/100)) // Verified
price_tenkan_kijun_chikou_in_thick_cloud = (not price_tenkan_kijun_chikou_not_in_cloud) and thick_cloud // Verified
proximity_mult = 0.001 // 0.1 %
tenkan_middle_bb = Tenkan + (Tenkan*0), tenkan_upper_bb = Tenkan + (Tenkan*proximity_mult), tenkan_lower_bb = Tenkan + (Tenkan*-proximity_mult)
kijun_middle_bb = Kijun + (Kijun*0), kijun_upper_bb = Kijun + (Kijun*proximity_mult), kijun_lower_bb = Kijun + (Kijun*-proximity_mult)
price_near_tenkan = (open < tenkan_upper_bb and open > tenkan_lower_bb) or (high < tenkan_upper_bb and high > tenkan_lower_bb) or (low < tenkan_upper_bb and low > tenkan_lower_bb) or (close < tenkan_upper_bb and close > tenkan_lower_bb)
price_near_kijun = (open < kijun_upper_bb and open > kijun_lower_bb) or (high < kijun_upper_bb and high > kijun_lower_bb) or (low < kijun_upper_bb and low > kijun_lower_bb) or (close < kijun_upper_bb and close > kijun_lower_bb)
price_near_tenkan_kijun = price_near_tenkan or price_near_kijun
cloud_thickness_future = math.abs(SenkouA[0] - SenkouB[0])
percent_thick_cloud_future = green_kumo_cloud_future ? (cloud_thickness_future * 100) / SenkouA[0] : (red_kumo_cloud_future ? (cloud_thickness_future * 100) / SenkouB[0] : na)
thickness_threshold_future = 0.20
thin_cloud = percent_thick_cloud_future <= thickness_threshold_future
red_2_green_cloud = (SenkouA[displacement+1] > SenkouB[displacement+1]) and (SenkouA[displacement+0] < SenkouB[displacement+0])
green_2_red_cloud = (SenkouA[displacement+1] < SenkouB[displacement+1]) and (SenkouA[displacement+0] > SenkouB[displacement+0])
close_above_cloud = close > SenkouA[displacement] and close > SenkouB[displacement]
close_below_kijun = close < Kijun
tenkan_crossover_kijun = ta.crossover(Tenkan, Kijun)
tenkan_over_cloud = Tenkan > SenkouA[displacement] and Tenkan > SenkouB[displacement]
tenkan_over_red_cloud = red_kumo_cloud and tenkan_over_cloud
kijun_crosses_red_cloud = red_kumo_cloud and ta.crossover(Kijun, SenkouA[displacement])

// --- (End) Ichimoku conditions -------------------------------------------- //

// --- Trade Conditions ----------------------------------------------------- //

var is_long_open=false, var is_short_open=false

long_e = red_2_green_cloud // and close_above_cloud
long_x = green_2_red_cloud

long_e_color = input.color(defval=color.new(color.green,0), title='Long Entry', group='Signals Style - Setting', inline='il1')
long_x_color = input.color(defval=color.new(color.red,0), title='Long Exit', group='Signals Style - Setting', inline='il1')

is_trade_bar = (long_e and not is_long_open) or (long_x and is_long_open)

barcolor(color=is_trade_bar ? na : (close>open ? color.new(color.green,90) : color.new(color.red,90)))

barcolor(color=long_e and not is_long_open ? long_e_color : na, title="Long - Entry Bar", editable=false)
barcolor(color=long_x and is_long_open ? long_x_color : na, title="Long - Exit Bar", editable=false)

plotshape(long_e and not is_long_open, text="B", textcolor=color.white, style=shape.labelup, color=long_e_color, size=size.tiny, location=location.belowbar, title="Long - Entry Labels", editable=false)
plotshape(long_x and is_long_open, text="S", textcolor=color.white, style=shape.labeldown, color=long_x_color, size=size.tiny, location=location.abovebar, title="Long - Exit Labels", editable=false)

if long_e and not is_long_open
    is_long_open:=true
if long_x and is_long_open
    is_long_open:=false

// --- Trade Executions ----------------------------------------------------- //

start_date  = input.time(title='Testing Start Date', defval=timestamp("1975-01-01T00:00:00"), group='Trading Settings')
finish_date = input.time(title='Testing End Date', defval=timestamp("2025-01-01T00:00:00"), group='Trading Settings')
_testperiod = time >= start_date and time <= finish_date // and timeframe.period == 'D'

// strategy.entry("Long", strategy.long, comment=" ", when=long_e and _testperiod)
// strategy.close("Long", comment=" ", when=long_x and _testperiod)
