← К каталогу
Исходный код · ID 3883

Advanced SMC

indicator advanced smc for tradingview(1).pine

Похожие материалы по тегам

ares_indicator.pineTradingView · 1 общих теговgold_trend_revers.mq5MQL5 / MetaTrader 5 · 1 общих тегов!!!-mt4 x-xardg-rsi.mq5MQL5 / MetaTrader 5 · 1 общих тегов! cycle-identifier.mq5MQL5 / MetaTrader 5 · 1 общих тегов!!! rsi ma simple+arrows 1.2 (mtf).mq5MQL5 / MetaTrader 5 · 1 общих теговprecisionflowea.mq5MQL5 / MetaTrader 5 · 1 общих тегов
Вы автор или правообладатель?

Сообщите нам, если считаете, что материал размещён без разрешения.

Краткий обзор

О программе

Advanced SMC — индикатор для TradingView с отображением на графике, написанный на Pine Script v5. Он объединяет несколько модулей технического анализа: расчёт показателей, отрисовку линий и графических отметок, а также задание условий для оповещений.

Модуль рыночной структуры определяет фракталы, Break of Structure и Change of Character, рисует линии поддержки и сопротивления с отслеживанием их пробоя. Модуль Fair Value Gaps выявляет зоны дисбаланса, отслеживает их митигацию и задаёт условия оповещений.

Включены ATR-трастоп с сигналами покупки/продажи, детекция ликвидности с зонами, распознавание свечных паттернов Marubozu и Engulfing с алертами, свинг-лайны с пробоями ликвидности. Дополнительно: мультитаймфреймовая поддержка/сопротивление, дивергенции с сравнением символов, EMA, энвелоп Надарая-Уотсона, детекция импульсов RSI и дашборд.

Настройки программы

НастройкаОписание
length Длина фрактала — Длина для обнаружения фракталов.
showBull Bullish Structures — Отображение бычьих структур.
bullCss Цвет Bullish Structures — Цвет бычьих структур.
showBear Bearish Structures — Отображение медвежьих структур.
bearCss Цвет Bearish Structures — Цвет медвежьих структур.
showSupport Support — Отображение линий поддержки.
supCss Цвет Support — Цвет линий поддержки.
showResistance Resistance — Отображение линий сопротивления.
resCss Цвет Resistance — Цвет линий сопротивления.
showDash Показать дашборд — Показать дашборд.
dashLoc Расположение дашборда — Расположение дашборда.
textSize Размер текста — Размер текста дашборда.
numDays Дней отката — Количество дней для отката.
showUP UP FVG — Показывать UP FVG.
colUp Цвет UP FVG — Цвет UP FVG.
showDN DOWN FVG — Показывать DOWN FVG.
colDn Цвет DOWN FVG — Цвет DOWN FVG.
showCE Показать CE — Показывать CE-линию.
ceCol Цвет CE-линии — Цвет CE-линии (Common Equity).
ceStyle Стиль CE-линии — Стиль CE-линии.
deleteFilledBoxes Удалить заполненные ящики и линии — Удаление заполненных ящиков и линий.
CEcond Использовать CE — Переключатель: использовать CE (Common Equity) вместо полного заполнения FVG.
a Чувствительность — Ключевое значение, изменяющее чувствительность ATR-трастопа.
c Период ATR — Период ATR для трастопа.
h111 Сигналы Heikin Ashi — Сигналы на основе Heikin Ashi свечей.
bullCss1 Цвет уровня Bullish FVG — Цвет уровня Bullish FVG.
bullAreaCss Цвет зоны Bullish FVG — Цвет зоны Bullish FVG.
bullMitigatedCss Цвет митигированных Bullish FVG — Цвет митигированных Bullish FVG.
bearCss1 Цвет уровня Bearish FVG — Цвет уровня Bearish FVG.
bearAreaCss Цвет зоны Bearish FVG — Цвет зоны Bearish FVG.
bearMitigatedCss Цвет митигированных Bearish FVG — Цвет митигированных Bearish FVG.
cooldownPeriod Период охлаждения — Период охлаждения между сигналами свинга.
showSwing Показать свинги — Показать свинги.
swingClr Цвет свингов — Цвет свинг-линий.
bullWidth Толщина бычьих линий — Толщина линий бычьего свинга.
bullStyle Стиль бычьих линий — Стиль линий бычьего свинга.
bullColor Цвет бычьих линий — Цвет линий бычьего свинга/ликвидности.
bearWidth Толщина медвежьих линий — Толщина линий медвежьего свинга.
bearStyle Стиль медвежьих линий — Стиль линий медвежьего свинга.
bearColor Цвет медвежьих линий — Цвет линий медвежьего свинга/ликвидности.
length1 Длина Zig Zag — Длина для Zig Zag.
extend Продлить до последней свечи — Продлить до последней свечи.
show_ext Показать экстремальности — Показать экстремальности.
show_labels Показать метки — Показать метки Zig Zag.
upcol Цвет верхней экстремальности — Цвет верхней экстремальности Zig Zag.
midcol Цвет Zig Zag — Цвет средней линии Zig Zag.
dncol Цвет нижней экстремальности — Цвет нижней экстремальности Zig Zag.
liqLen Длина обнаружения — Длина обнаружения ликвидности.
liqBuy Buyside Liquidity Zones — Отображение зон buyside ликвидности.
marBuy Маржин Buyside — Маржин для buyside ликвидности.
cLIQ_B Цвет Buyside Liquidity — Цвет зон buyside ликвидности.
liqSel Sellside Liquidity Zones — Отображение зон sellside ликвидности.
marSel Маржин Sellside — Маржин для sellside ликвидности.
cLIQ_S Цвет Sellside Liquidity — Цвет зон sellside ликвидности.
lqVoid Liquidity Void Bullish — Отображение бычьих зон Liquidity Void.
cLQV_B Цвет Liquidity Void Bullish — Цвет зон Liquidity Void (бычьих).
cLQV_S Цвет Liquidity Void Bearish — Цвет зон Liquidity Void (медвежьих).
lqText Показать метки — Отображение меток для Liquidity Void.
mode Режим — Режим отображения ликвидности.
visLiq Количество уровней — Количество видимых уровней ликвидности.
label_color_bearish Цвет меток Bearish — Цвет меток медвежьих паттернов.
label_color_bullish Цвет меток Bullish — Цвет меток бычьих паттернов.
trendRule Определение тренда — Основа определения тренда.
length2 Размер окна — Размер окна для энвелопа.
h1 Полоса пропускания — Полоса пропускания энвелопа.
mult Множитель — Множитель для энвелопа.
srcUpperBand Источник Upper Band — Источник верхней полосы.
src1 Источник Lower Band — Источник нижней полосы.
up_col Цвет верхней линии — Цвет верхней линии энвелопа.
dn_col Цвет нижней линии — Цвет нижней линии энвелопа.
show_bands Показать полосы — Показывать полосы энвелопа.
show_sma_7_low_1 SMA 7 LOW +1 — Показать SMA 7 LOW +1.
show_sma_7_low_7 SMA 7 LOW -7 — Показать SMA 7 LOW -7.
show_sma_30_high SMA 30 High — Показать SMA 30 High.
length3 Глубина пивотов — Глубина поиска пивотов для дивергенций.
useSym1 Использовать символ 1 — Использовать символ 1 для сравнения.
sym1 Символ 1 — Сравниваемый символ 1.
useSym2 Использовать символ 2 — Использовать символ 2 для сравнения.
sym2 Символ 2 — Сравниваемый символ 2.
bullDivCss Цвет Swing High — Цвет меток Swing High для дивергенций.
bearDivCss Цвет Swing Low — Цвет меток Swing Low для дивергенций.
showema Показать EMA — Показать все EMA.
Overridetargetsize Изменить размер цели — Переключатель для изменения стандартного размера цели.
Targetssize Размер цели (пипсы) — Размер цели в пипсах.
showgreydiamond Показать алмаз — Показать алмаз для бэктеста.
Imbcol Цвет импульсов — Цвет зон импульсов (Imbalance).
Dimcol Цвет импульсов Bearish — Цвет маркеров импульсов (Bearish).
offset Смещение — Смещение EMA.
resistanceSupportCount Количество S&R — Количество уровней поддержки и сопротивления.
pivotRange Диапазон пивотов — Диапазон пивотов для поддержки/сопротивления.
strength Сила — Сила (количество касаний) для S&R.
expandLines Расширить линии и зоны — Расширение линий и зон.
enableZones Включить зоны — Включение зон поддержки/сопротивления.
zoneWidthType Тип ширины зоны — Тип ширины зоны.
zoneWidth Ширина зоны — Фиксированная ширина зоны.
timeframe1Enabled Включить ТФ 1 — Включить таймфрейм 1.
timeframe1 Таймфрейм 1 — Таймфрейм 1.
timeframe2Enabled Включить ТФ 2 — Включить таймфрейм 2.
timeframe2 Таймфрейм 2 — Таймфрейм 2.
timeframe3Enabled Включить ТФ 3 — Включить таймфрейм 3.
Получить полный код

Поиск по коду файла

indicator("Advanced SMC", overlay = true, max_lines_count = 500, max_labels_count = 500, max_boxes_count = 500, max_bars_back = 1000)

length = input.int(5, minval = 3)

showBull = input(true, 'Bullish Structures', inline = 'bull', group = 'Style')
bullCss = input.color(#089981, '', inline = 'bull', group = 'Style')

showBear = input(true, 'Bearish Structures', inline = 'bear', group = 'Style')
bearCss = input.color(#f23645, '', inline = 'bear', group = 'Style')

showSupport = input(false, 'Support', inline = 's', group = 'Style')
supCss = input.color(#089981, '', inline = 's', group = 'Style')

showResistance = input(false, 'Resistance', inline = 'r', group = 'Style')
resCss = input.color(#f23645, '', inline = 'r', group = 'Style')

showDash  = input(false, 'Show Dashboard'                                                               , group = 'Dashboard')
dashLoc  = input.string('Top Right', 'Location', options = ['Top Right', 'Bottom Right', 'Bottom Left'], group = 'Dashboard')
textSize = input.string('Small', 'Size'        , options = ['Tiny', 'Small', 'Normal']                 , group = 'Dashboard')

type fractal
    float value
    int loc
    bool iscrossed

var p = int(length/2)
n = bar_index

dh = math.sum(math.sign(high - high[1]), p)
dl = math.sum(math.sign(low - low[1]), p)

bullf = dh == -p and dh[p] == p and high[p] == ta.highest(length)
bearf = dl == p and dl[p] == -p and low[p] == ta.lowest(length)

bullf_count = ta.cum(bullf ? 1 : 0)
bearf_count = ta.cum(bearf ? 1 : 0)

var upper = fractal.new()
var line lower_lvl = na
var label ms_lbl = na
var bull_ms_count = 0
var broken_sup = false
var os = 0

if bullf
    upper.value := high[p]
    upper.loc := n-p
    upper.iscrossed := false

if ta.crossover(close, upper.value) and not upper.iscrossed
    line.new(upper.loc, upper.value, n, upper.value, color = showBull ? bullCss : na)

    ms_lbl := label.new(int(math.avg(n, upper.loc)), upper.value, os == -1 ? 'ChoCH' : 'BOS'
      , color = color(na)
      , textcolor = showBull ? bullCss : na
      , style = label.style_label_down
      , size = size.tiny)

    k = 2
    min = low[1]
    for i = 2 to (n - upper.loc)-1
        min := math.min(low[i], min)
        k := low[i] == min ? i : k

    if showSupport
        lower_lvl := line.new(n-k, min, n, min, color = bullCss, style = line.style_dashed)
        broken_sup := false

    upper.iscrossed := true
    bull_ms_count += 1
    os := 1

else if showSupport and not broken_sup
    lower_lvl.set_x2(n)

    if close < lower_lvl.get_y2()
        broken_sup := true

var lower = fractal.new()
var line upper_lvl = na
var broken_res = false
var bear_ms_count = 0

if bearf
    lower.value := low[p]
    lower.loc := n-p
    lower.iscrossed := false

if ta.crossunder(close, lower.value) and not lower.iscrossed
    line.new(lower.loc, lower.value, n, lower.value, color = showBear ? bearCss : na)

    label.new(int(math.avg(n, lower.loc)), lower.value, os == 1 ? 'ChoCH' : 'BOS'
      , color = color(na)
      , textcolor = showBear ? bearCss : na
      , style = label.style_label_up
      , size = size.tiny)

    k = 2
    max = high[1]
    for i = 2 to (n - lower.loc)-1
        max := math.max(high[i], max)
        k := high[i] == max ? i : k

    if showResistance
        upper_lvl := line.new(n-k, max, n, max, color = bearCss, style = line.style_dashed)
        broken_res := false

    lower.iscrossed := true
    bear_ms_count += 1
    os := -1

else if showResistance and not broken_res
    upper_lvl.set_x2(n)

    if close > upper_lvl.get_y2()
        broken_res := true

var table_position = dashLoc == 'Bottom Left' ? position.bottom_left 
  : dashLoc == 'Top Right' ? position.top_right 
  : position.bottom_right

var table_size = textSize == 'Tiny' ? size.tiny 
  : textSize == 'Small' ? size.small 
  : size.normal

var tb = table.new(table_position, 2, 3
  , bgcolor = #1e222d
  , border_color = #373a46
  , border_width = 1
  , frame_color = #373a46
  , frame_width = 1)

if showDash
    if barstate.isfirst
        tb.cell(0, 0, 'Structure To Fractal %', text_color = color.white, text_size = table_size)
        tb.merge_cells(0,0,1,0)

        tb.cell(0, 1, 'Bullish', text_color = #089981, text_size = table_size)
        tb.cell(1, 1, 'Bearish', text_color = #f23645, text_size = table_size)

    if barstate.islast
        tb.cell(0, 2, str.tostring(bull_ms_count / bullf_count * 100, format.percent), text_color = #089981, text_size = table_size)
        tb.cell(1, 2, str.tostring(bear_ms_count / bearf_count * 100, format.percent), text_color = #f23645, text_size = table_size)

plot(broken_res and not broken_res[1] ? low : na, 'Resistance Breakout', #089981, 2, plot.style_circles)
plot(broken_sup and not broken_sup[1] ? high : na, 'Support Breakout', #f23645, 2, plot.style_circles)

numDays = input.int(7, "number of days lookback")
showUP = input.bool(true, "'UP' FVGs:", inline ='1')
colUp = input.color(color.new(#2195f3, 95), "", inline ='1')
showDN = input.bool(true, "'DOWN' FVGs:", inline ='2')
colDn = input.color(color.new(#ff9900, 95), "", inline ='2')
showCE = input.bool(true, "show CE", inline ='3')
ceCol = input.color(color.new(#363a45, 95), "| color:", inline ='3')
ceStyle = input.string(line.style_dotted, "| style:", options=[line.style_dotted,line.style_solid,  line.style_dashed], inline ='3')
deleteFilledBoxes = input.bool(true, "delete filled boxes & lines")
CEcond = input.bool (true, "Use CE (as opposed to Full Fill)", group = 'conditions/alerts', tooltip = "If toggled OFF, FVGs and CEs will paint until FVG has been completely filled.\n\nThis threshold is used for Above/Below threshold Alert conditions too (but does not effect the IOFED alerts):\ni.e. this will determine if your 'ABOVE threshold' alert fires when price hits latest active FVG CE ABOVE or latest active FVG Full Fill ABOVE\n\nAlerts are set by clicking the three dots on the indicator display line.")
colorNone = color.new(color.white, 100)
_day = 24*3600*1000
var box bxUp = na, var box bxDn = na, var line lnUp = na, var line lnDn = na
var array<box> bxUpArr = array.new<box>(0), var array<line> lnUpArr = array.new<line>(0)
var array<box> bxDnArr = array.new<box>(0), var array<line> lnDnArr = array.new<line>(0)
dnCE = high[1] + (low[3]-high[1])/2
upCE = low[1] - (low[1]-high[3])/2
if low[3] > high[1] and time> timenow- numDays*_day and showDN
    bxDnArr.push(box.new(bar_index-3, low[3], bar_index, high[1], bgcolor = colDn, border_color = colorNone))
    lnDnArr.push(line.new(bar_index-3, dnCE, bar_index, dnCE, color = showCE?ceCol:colorNone, style =ceStyle))
if high[3] < low[1] and time> timenow- numDays*_day and showUP
    bxUpArr.push(box.new(bar_index-3, low[1], bar_index, high[3], bgcolor = colUp, border_color = colorNone))
    lnUpArr.push(line.new(bar_index-3, upCE, bar_index, upCE, color = showCE?ceCol:colorNone, style =ceStyle))

var array<int> _countArr =array.new<int>(0)
var array<int> _countArrIOFED =array.new<int>(0)

extendAndRemoveBx(array<box> boxArray, array<line> lineArray, array<int> countArr1, array<int> countArr2, simple bool isBull, int maxSize) => 
    if boxArray.size() > 0
        for i = boxArray.size() -1 to 0
            line ln = lineArray.get(i)
            box bx = boxArray.get(i)
            bx.set_right(bar_index)
            ln.set_x2(bar_index)
            float price = CEcond?ln.get_price(bar_index):(isBull?bx.get_top():bx.get_bottom())    
            float price_IOFED = isBull?bx.get_bottom():bx.get_top()          
            int m = isBull ? 1 : -1
            float hiLo = isBull ? high : low  
            if hiLo * m > price * m 
                boxArray.remove(i)
                lineArray.remove(i)
                countArr1.push(isBull?1:-1) //for 'above/below threshold alerts; counter sum will decrement 1 on lower threshold hit, increment 1 on upper threshold hit
                if deleteFilledBoxes
                    bx.set_bgcolor(colorNone)
                    ln.set_color(colorNone)
            if hiLo*m>price_IOFED*m
                countArr2.push(isBull?1:-1)

    if boxArray.size() > maxSize
        box.delete(boxArray.shift())
        line.delete(lineArray.shift())

extendAndRemoveBx(bxDnArr,lnDnArr,_countArr,_countArrIOFED, true, 12) //12 should be good for around 2200 bars of history
extendAndRemoveBx(bxUpArr, lnUpArr,_countArr,_countArrIOFED, false, 12)

upThresholdLst = array.sum(_countArr)>array.sum(_countArr)[1]
dnThresholdLst = array.sum(_countArr)<array.sum(_countArr)[1]

upIOFEDlast= array.sum(_countArrIOFED)>array.sum(_countArrIOFED)[1]
dnIOFEDlast= array.sum(_countArrIOFED)<array.sum(_countArrIOFED)[1]

a = input(2, title='Key Vaule. \'This changes the sensitivity\'')
c = input(1, title='ATR Period')
h111 = input(false, title='Signals from Heikin Ashi Candles')

xATR = ta.atr(c)
nLoss = a * xATR

src = h111 ? request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, close, lookahead=barmerge.lookahead_off) : close

xATRTrailingStop = 0.0
iff_1 = src > nz(xATRTrailingStop[1], 0) ? src - nLoss : src + nLoss
iff_2 = src < nz(xATRTrailingStop[1], 0) and src[1] < nz(xATRTrailingStop[1], 0) ? math.min(nz(xATRTrailingStop[1]), src + nLoss) : iff_1
xATRTrailingStop := src > nz(xATRTrailingStop[1], 0) and src[1] > nz(xATRTrailingStop[1], 0) ? math.max(nz(xATRTrailingStop[1]), src - nLoss) : iff_2

pos = 0
iff_3 = src[1] > nz(xATRTrailingStop[1], 0) and src < nz(xATRTrailingStop[1], 0) ? -1 : nz(pos[1], 0)
pos := src[1] < nz(xATRTrailingStop[1], 0) and src > nz(xATRTrailingStop[1], 0) ? 1 : iff_3

xcolor = pos == -1 ? color.red : pos == 1 ? color.green : color.blue

ema = ta.ema(src, 1)
above = ta.crossover(ema, xATRTrailingStop)
below = ta.crossover(xATRTrailingStop, ema)

buy = src > xATRTrailingStop and above
sell = src < xATRTrailingStop and below

barbuy = src > xATRTrailingStop
barsell = src < xATRTrailingStop

plotshape(buy, title='Buy', text='Buy', style=shape.labelup, location=location.belowbar, color=color.new(color.green, 0), textcolor=color.new(color.white, 0), size=size.tiny)
plotshape(sell, title='Sell', text='Sell', style=shape.labeldown, location=location.abovebar, color=color.new(color.red, 0), textcolor=color.new(color.white, 0), size=size.tiny)

barcolor(barbuy ? color.green : na)
barcolor(barsell ? color.red : na)

alertcondition(buy, 'UT Long', 'UT Long')
alertcondition(sell, 'UT Short', 'UT Short')

bullCss1          = input.color(color.teal, 'FVG Level'               , inline = 'bull')
bullAreaCss      = input.color(color.new(color.teal, 50), 'Area'     , inline = 'bull')
bullMitigatedCss = input.color(color.new(color.teal, 80), 'Mitigated', inline = 'bull')

bearCss1          = input.color(color.red, 'FVG Level'                , inline = 'bear')
bearAreaCss      = input.color(color.new(color.red, 50), 'Area'      , inline = 'bear')
bearMitigatedCss = input.color(color.new(color.red, 80), 'Mitigated' , inline = 'bear')

type fvg
    float top
    float btm
    bool  mitigated
    bool  isnew
    bool  isbull
    line  lvl
    box   area

type session_range
    line max
    line min

nl = bar_index

method set_fvg(fvg id, offset, bg_css, l_css)=>
    avg = math.avg(id.top, id.btm)

    area  = box.new(nl - offset, id.top, nl, id.btm, na, bgcolor = bg_css)
    avg_l = line.new(nl - offset, avg, nl, avg, color = l_css, style = line.style_dashed)

    id.lvl := avg_l
    id.area := area

method set_range(session_range id)=>
    max = math.max(high, id.max.get_y2())
    min = math.min(low, id.min.get_y2())

    id.max.set_xy2(nl, max)
    id.max.set_y1(max)

    id.min.set_xy2(nl, min)
    id.min.set_y1(min)

var chartCss = color.new(chart.fg_color, 50)

var fvg sfvg = fvg.new(na, na, na, true, na)
var session_range sesr = na

var box area = na
var line avg = na

bull_fvg = low > high[2] and close[1] > high[2]
bear_fvg = high < low[2] and close[1] < low[2]

bull_isnew      = false
bear_isnew      = false
bull_mitigated  = false
bear_mitigated  = false
within_bull_fvg = false
within_bear_fvg = false

dtf = timeframe.change('D')

if dtf

    line.new(nl, high + syminfo.mintick
      , nl, low - syminfo.mintick
      , color = chartCss
      , style = line.style_dashed
      , extend = extend.both)

    sesr := session_range.new(
      line.new(nl, high, nl, high, color = chartCss)
      , line.new(nl, low, nl, low, color = chartCss))

    sfvg.isnew := true

    if not na(sfvg.lvl)
        sfvg.lvl.set_x2(nl-2)
        sfvg.area.set_right(nl-2)

else if not na(sesr)
    sesr.set_range()

    sesr.max.set_color(sfvg.isbull ? bullCss1 : bearCss1)
    sesr.min.set_color(sfvg.isbull ? bullCss1 : bearCss1)

if bull_fvg and sfvg.isnew
    sfvg := fvg.new(low, high[2], false, false, true)
    sfvg.set_fvg(2, bullAreaCss, bullCss1)

    bull_isnew := true

else if bear_fvg and sfvg.isnew
    sfvg := fvg.new(low[2], high, false, false, false)
    sfvg.set_fvg(2, bearAreaCss, bearCss1)

    bear_isnew := true

if not sfvg.mitigated

    if sfvg.isbull and close < sfvg.btm
        sfvg.set_fvg(1, bullMitigatedCss, bullCss1)

        sfvg.mitigated := true
        bull_mitigated := true

    else if not sfvg.isbull and close > sfvg.top
        sfvg.set_fvg(1, bearMitigatedCss, bearCss1)

        sfvg.mitigated := true
        bear_mitigated := true

if not sfvg.isnew
    sfvg.lvl.set_x2(nl)
    sfvg.area.set_right(nl)

alertcondition(bull_isnew, 'Bullish FVG', 'New session bullish fvg')
alertcondition(bear_isnew, 'Bearish FVG', 'New session bearish fvg')

alertcondition(bull_mitigated, 'Mitigated Bullish FVG', 'Session bullish fvg has been mitigated')
alertcondition(bear_mitigated, 'Mitigated Bearish FVG', 'Session bearish fvg has been mitigated')

alertcondition(close >= sfvg.btm and close <= sfvg.top and sfvg.isbull and not sfvg.isnew
  , 'Price Within Bullish FVG'
  , 'Price is within bullish fvg')

alertcondition(close >= sfvg.btm and close <= sfvg.top and not sfvg.isbull and not sfvg.isnew
  , 'Price Within Bearish FVG'
  , 'Price is within bearish fvg')

alertcondition(ta.cross(close, math.avg(sfvg.top, sfvg.btm)) and sfvg.isbull and not sfvg.isnew
  , 'Bullish FVG AVG Cross'
  , 'Price crossed bullish fvg average')

alertcondition(ta.cross(close, math.avg(sfvg.top, sfvg.btm)) and not sfvg.isbull and not sfvg.isnew
  , 'Bearish FVG AVG Cross'
  , 'Price crossed bearish fvg average')

cooldownPeriod = input.int(10,title="Cooldown Period", minval=0, group = "Settings") 

lbLeft = 20
lbRight = 20

showSwing = input.bool(true,title="Show Swings?", inline="s_1", group = 'Swing Detaction')
swingClr = input.color(color.new(color.orange, 0), title='', inline="s_1", group = 'Swing Detaction')

bullWidth = input.int(1, title='Line Width:', group='Bullish Sweep')
bullStyle = input.string('Dashed', title='Line Style:', options=['Solid', 'Dotted', 'Dashed'], group='Bullish Sweep')
bullColor = input.color(color.new(color.teal, 0), title='Bullish Color:', group='Bullish Sweep')

bearWidth = input.int(1, title='Line Width:', group='Bearish Sweep')
bearStyle = input.string('Dashed', title='Line Style:', options=['Solid', 'Dotted', 'Dashed'], group='Bearish Sweep')
bearColor = input.color(color.new(color.maroon, 0), title='Bearish Color:', group='Bearish Sweep')

lineStyle(s) =>
    if s == 'Solid'
        line.style_solid
    else if s == 'Dotted'
        line.style_dotted
    else
        line.style_dashed

var int bullSignalIndex = 0
var int bearSignalIndex = 0

var line bullLine = na
var line bearLine = na

var line highLine = na
var line lowLine = na

var label swingHighLbl = na
var label swingLowLbl = na
var label swingHighLblTxt = na
var label swingLowLblTxt = na

var float swingLowVal = na
var float swingHighVal = na

pLow = ta.pivotlow(low, lbLeft, lbRight)
pHigh = ta.pivothigh(high, lbLeft, lbRight)

pLowVal = ta.valuewhen(not na(pLow), low[lbRight], 0) 
pHighVal = ta.valuewhen(not na(pHigh), high[lbRight], 0)

prevLowIndex = ta.valuewhen(not na(pLow), bar_index[lbRight], 0)
prevHighIndex = ta.valuewhen(not na(pHigh), bar_index[lbRight], 0)

lp = ta.lowest(low, lbLeft)
hp = ta.highest(high, lbLeft)

highestClose = ta.highest(close, lbLeft)
lowestClose = ta.lowest(close, lbLeft)

bullishSFP = low < pLowVal and close > pLowVal and open > pLowVal and low == lp and lowestClose >= pLowVal
bearishSFP = high > pHighVal and close < pHighVal and open < pHighVal and high == hp and highestClose <= pHighVal

bullCond = bullishSFP[3] and (close > pLowVal) and  (close[1] > pLowVal[1]) and (close[2] > pLowVal[2]) and bar_index >= bullSignalIndex + cooldownPeriod
bearCond = bearishSFP[3] and (close < pHighVal) and  (close[1] < pHighVal[1]) and (close[2] < pHighVal[2]) and bar_index >= bearSignalIndex + cooldownPeriod

var int swingLowCounter = 0
var int swingHighCounter = 0
var bool isSwingLowCheck = false
var bool isSwingHighCheck = false
var bool stopPrintingLow = false
var bool stopPrintingHigh = false

if high < swingLowVal and isSwingLowCheck
    swingLowCounter := swingLowCounter+1

if low > swingHighVal and isSwingHighCheck
    swingHighCounter := swingHighCounter+1

if ta.crossunder(close, swingLowVal) and isSwingLowCheck == false
    isSwingLowCheck := true
    swingLowCounter := 1

if ta.crossover(close, swingHighVal) and isSwingHighCheck == false
    isSwingHighCheck := true
    swingHighCounter := 1

if swingLowCounter == 5 and isSwingLowCheck
    stopPrintingLow := true
    isSwingLowCheck := false
    line.set_x2(lowLine,bar_index[4])

if swingHighCounter == 5 and isSwingHighCheck
    stopPrintingHigh := true
    isSwingHighCheck := false
    line.set_x2(highLine,bar_index[4])

if bullCond
    bullSignalIndex := bar_index
    bullLine := line.new(prevLowIndex, pLowVal, bar_index-3, pLowVal, color=bullColor, width=bullWidth, style=lineStyle(bullStyle))

if bearCond
    bearSignalIndex := bar_index
    bearLine := line.new(prevHighIndex, pHighVal, bar_index-3, pHighVal, color=bearColor, width=bearWidth, style=lineStyle(bearStyle))

var swingHighArr = array.new_label(0)
var swingHighTextArr = array.new_label(0)

var swingLowArr = array.new_label(0)
var swingLowTextArr = array.new_label(0)

if array.size(swingHighArr) >= 3
    label.delete(array.shift(swingHighArr))
    label.delete(array.shift(swingHighTextArr))

if array.size(swingLowArr) >= 3
    label.delete(array.shift(swingLowArr))
    label.delete(array.shift(swingLowTextArr))

if showSwing
    if stopPrintingHigh == false 
        line.set_x2(highLine,bar_index+5)
    if stopPrintingLow == false
        line.set_x2(lowLine,bar_index+5)

if showSwing and not na(pHigh) and bearishSFP[lbRight] == false
    stopPrintingHigh := false
    swingHighVal := high[lbRight]
    line.delete(highLine)
    highLine := line.new(bar_index[lbRight], high[lbRight], bar_index+10, high[lbRight], color = swingClr, width = 2)

    swingHighLbl := label.new(bar_index[lbRight], high[lbRight], text="", yloc=yloc.abovebar, color = swingClr, textcolor = swingClr, style = label.style_triangledown, size = size.auto)
    swingHighLblTxt := label.new(bar_index[lbRight], high[lbRight], text="Swing\nH", yloc=yloc.abovebar, color = swingClr, textcolor = swingClr, style = label.style_none, size = size.small)
    array.push(swingHighArr, swingHighLbl)
    array.push(swingHighTextArr, swingHighLblTxt)

if showSwing and not na(pLow) and bullishSFP[lbRight] == false
    stopPrintingLow := false
    swingLowVal := low[lbRight]
    line.delete(lowLine)
    lowLine := line.new(bar_index[lbRight], low[lbRight], bar_index+10, low[lbRight], color = swingClr, width = 2)

    swingLowLbl := label.new(bar_index[lbRight], low[lbRight], text="", yloc=yloc.belowbar, color = swingClr, textcolor = swingClr, style = label.style_triangleup, size = size.auto)
    swingLowLblTxt := label.new(bar_index[lbRight], low[lbRight], text="Swing\nL", yloc=yloc.belowbar, color = swingClr, textcolor = swingClr, style = label.style_none, size = size.small)
    array.push(swingLowArr, swingLowLbl)
    array.push(swingLowTextArr, swingLowLblTxt) 

plotshape(bullCond, text='Sweep', color=bullColor, textcolor=bullColor, location=location.belowbar, offset = -3)
plotshape(bearCond, text='Sweep', color=bearColor, textcolor=bearColor, location=location.abovebar, offset = -3) 

alertcondition(bullishSFP, title='Bullish Sweep', message='{{ticker}} Bullish Sweep, Price:{{close}}')
alertcondition(bearishSFP, title='Bearish Sweep', message='{{ticker}} Bearish Sweep, Price:{{close}}')

length1      = input(100)
extend      = input(true,'Extend To Last Bar')
show_ext    = input(true,'Show Extremities') 
show_labels = input(true,'Show Labels') 

upcol = input(#ff1100,'Upper Extremity Color',group='Style')
midcol = input(#ff5d00,'Zig Zag Color',group='Style')
dncol = input(#2157f3,'Lower Extremity Color',group='Style')

liqGrp = 'Liquidity Detection'
liqLen = input.int   (7, title = 'Detection Length', minval = 3, maxval = 13, inline = 'LIQ', group = liqGrp)
liqMar = 10 / input.float (6.9, 'Margin', minval = 4, maxval = 9, step = 0.1, inline = 'LIQ', group = liqGrp)

liqBuy = input.bool (true, 'Buyside Liquidity Zones, Margin', inline = 'Buyside', group = liqGrp)
marBuy    = input.float(2.3, '', minval = 1.5, maxval = 10, step = .1, inline = 'Buyside', group = liqGrp)
cLIQ_B = input.color (color.new(#4caf50,  0), '', inline = 'Buyside', group = liqGrp)

liqSel = input.bool (true, 'Sellside Liquidity Zones, Margin', inline = 'Sellside', group = liqGrp)
marSel = input.float(2.3, '', minval = 1.5, maxval = 10, step = .1, inline = 'Sellside', group = liqGrp)
cLIQ_S = input.color (color.new(#f23645,  0), '', inline = 'Sellside', group = liqGrp)

lqVoid = input.bool (false, 'Liquidity Voids, Bullish', inline = 'void', group = liqGrp)
cLQV_B = input.color (color.new(#4caf50,  0), '', inline = 'void', group = liqGrp)
cLQV_S = input.color (color.new(#f23645,  0), 'Bearish', inline = 'void', group = liqGrp)
lqText = input.bool (false, 'Label', inline = 'void', group = liqGrp)

mode   = input.string('Present', title = 'Mode', options =['Present', 'Historical'], inline = 'MOD', group = liqGrp)
visLiq = input.int   (3, '    # Visible Levels', minval = 1, maxval = 50, inline = 'MOD', group = liqGrp)

maxSize = 50
atr     = ta.atr(10)
atr200  = ta.atr(200)
per     = mode == 'Present' ? last_bar_index - bar_index <=  500 : true

type ZZ 
    int   [] d
    int   [] x 
    float [] y 

type bar
    float o = open
    float h = high
    float l = low
    float c = close
    int   i = bar_index

type liq
    box   bx
    box   bxz
    box   bxt
    bool  brZ
    bool  brL
    line  ln
    line  lne

var ZZ aZZ = ZZ.new(
 array.new <int>  (maxSize,  0), 
 array.new <int>  (maxSize,  0), 
 array.new <float>(maxSize, na)
 )

bar b = bar.new()

var liq[] b_liq_B = array.new<liq> (1, liq.new(box(na), box(na), box(na), false, false, line(na), line(na)))
var liq[] b_liq_S = array.new<liq> (1, liq.new(box(na), box(na), box(na), false, false, line(na), line(na)))

var b_liq_V = array.new_box()

var int dir = na, var int x1 = na, var float y1 = na, var int x2 = na, var float y2 = na

method in_out(ZZ aZZ, int _d, int _x, float _y) =>
    aZZ.d.unshift(_d), aZZ.x.unshift(_x), aZZ.y.unshift(_y), aZZ.d.pop(), aZZ.x.pop(), aZZ.y.pop()

max_bars_back(time, 1000)

x2 := b.i - 1
ph  = ta.pivothigh(liqLen, 1)
pl  = ta.pivotlow (liqLen, 1)

if ph   
    dir := aZZ.d.get(0) 
    x1  := aZZ.x.get(0) 
    y1  := aZZ.y.get(0) 
    y2  := nz(b.h[1])

    if dir < 1
        aZZ.in_out(1, x2, y2)
    else
        if dir == 1 and ph > y1 
            aZZ.x.set(0, x2), aZZ.y.set(0, y2)

    if per
        count = 0
        st_P  = 0.
        st_B  = 0
        minP  = 0.
        maxP  = 10e6

        for i = 0 to maxSize - 1
            if aZZ.d.get(i) ==  1 
                if aZZ.y.get(i) > ph + (atr / liqMar)
                    break
                else
                    if aZZ.y.get(i) > ph - (atr / liqMar) and aZZ.y.get(i) < ph + (atr / liqMar)
                        count += 1
                        st_B := aZZ.x.get(i)
                        st_P := aZZ.y.get(i)
                        if aZZ.y.get(i) > minP
                            minP := aZZ.y.get(i)
                        if aZZ.y.get(i) < maxP 
                            maxP := aZZ.y.get(i)

        if count > 2
            getB = b_liq_B.get(0)

            if st_B == getB.bx.get_left()
                getB.bx.set_top(math.avg(minP, maxP) + (atr / liqMar))
                getB.bx.set_rightbottom(b.i + 10, math.avg(minP, maxP) - (atr / liqMar))
            else
                b_liq_B.unshift(
                 liq.new(
                   box.new(st_B, math.avg(minP, maxP) + (atr / liqMar), b.i + 10, math.avg(minP, maxP) - (atr / liqMar), bgcolor=color(na), border_color=color(na)), 
                   box.new(na, na, na, na, bgcolor = color(na), border_color = color(na)),
                   box.new(st_B, st_P, b.i + 10, st_P, text = 'Buyside liquidity', text_size = size.tiny, text_halign = text.align_left, text_valign = text.align_bottom, text_color = color.new(cLIQ_B, 25), bgcolor = color(na), border_color = color(na)),
                   false, 
                   false,
                   line.new(st_B   , st_P, b.i - 1, st_P, color = color.new(cLIQ_B, 0)),
                   line.new(b.i - 1, st_P, na     , st_P, color = color.new(cLIQ_B, 0), style = line.style_dotted))
                 )

                alert('buyside liquidity level detected/updated for ' + syminfo.ticker)

            if b_liq_B.size() > visLiq
                getLast = b_liq_B.pop()
                getLast.bx.delete()
                getLast.bxz.delete()
                getLast.bxt.delete()
                getLast.ln.delete()
                getLast.lne.delete()               

if pl
    dir := aZZ.d.get (0) 
    x1  := aZZ.x.get (0) 
    y1  := aZZ.y.get (0) 
    y2  := nz(b.l[1])

    if dir > -1
        aZZ.in_out(-1, x2, y2)
    else
        if dir == -1 and pl < y1 
            aZZ.x.set(0, x2), aZZ.y.set(0, y2)

    if per
        count = 0
        st_P  = 0.
        st_B  = 0
        minP  = 0.
        maxP  = 10e6

        for i = 0 to maxSize - 1
            if aZZ.d.get(i) == -1 
                if aZZ.y.get(i) < pl - (atr / liqMar)
                    break
                else
                    if aZZ.y.get(i) > pl - (atr / liqMar) and aZZ.y.get(i) < pl + (atr / liqMar)
                        count += 1
                        st_B := aZZ.x.get(i)
                        st_P := aZZ.y.get(i)
                        if aZZ.y.get(i) > minP
                            minP := aZZ.y.get(i)
                        if aZZ.y.get(i) < maxP 
                            maxP := aZZ.y.get(i)

        if count > 2
            getB = b_liq_S.get(0)

            if st_B == getB.bx.get_left()
                getB.bx.set_top(math.avg(minP, maxP) + (atr / liqMar))
                getB.bx.set_rightbottom(b.i + 10, math.avg(minP, maxP) - (atr / liqMar))
            else
                b_liq_S.unshift(
                 liq.new(
                   box.new(st_B, math.avg(minP, maxP) + (atr / liqMar), b.i + 10, math.avg(minP, maxP) - (atr / liqMar), bgcolor=color(na), border_color=color(na)),
                   box.new(na, na, na, na, bgcolor=color(na), border_color=color(na)),
                   box.new(st_B, st_P, b.i + 10, st_P, text = 'Sellside liquidity', text_size = size.tiny, text_halign = text.align_left, text_valign = text.align_top, text_color = color.new(cLIQ_S, 25), bgcolor=color(na), border_color=color(na)),
                   false,
                   false,
                   line.new(st_B   , st_P, b.i - 1, st_P, color = color.new(cLIQ_S, 0)),
                   line.new(b.i - 1, st_P, na     , st_P, color = color.new(cLIQ_S, 0), style = line.style_dotted))
                 )  

                alert('sellside liquidity level detected/updated for ' + syminfo.ticker)

            if b_liq_S.size() > visLiq
                getLast = b_liq_S.pop()
                getLast.bx.delete()
                getLast.bxz.delete()
                getLast.bxt.delete()
                getLast.ln.delete()            
                getLast.lne.delete()               

for i = 0 to b_liq_B.size() - 1
    x = b_liq_B.get(i)

    if not x.brL
        x.lne.set_x2(b.i)

        if b.h > x.bx.get_top()
            x.brL := true
            x.brZ := true
            alert('buyside liquidity level breached for ' + syminfo.ticker)

            x.bxz.set_lefttop(b.i - 1, math.min(x.ln.get_y1() + marBuy * (atr), b.h))
            x.bxz.set_rightbottom(b.i + 1, x.ln.get_y1())
            x.bxz.set_bgcolor(color.new(cLIQ_B, liqBuy ? 73 : 100))

    else if x.brZ
        if b.l > x.ln.get_y1() - marBuy * (atr) and b.h < x.ln.get_y1() + marBuy * (atr)
            x.bxz.set_right(b.i + 1)
            x.bxz.set_top(math.max(b.h, x.bxz.get_top()))
            if liqBuy
                x.lne.set_x2(b.i + 1)
        else
            x.brZ := false

for i = 0 to b_liq_S.size() - 1
    x = b_liq_S.get(i)

    if not x.brL
        x.lne.set_x2(b.i)

        if b.l < x.bx.get_bottom()
            x.brL := true
            x.brZ := true
            alert('sellside liquidity level breached for ' + syminfo.ticker)

            x.bxz.set_lefttop(b.i - 1, x.ln.get_y1())
            x.bxz.set_rightbottom(b.i + 1, math.max(x.ln.get_y1() - marSel * (atr), b.l))
            x.bxz.set_bgcolor(color.new(cLIQ_S, liqSel ? 73 : 100))

    else if x.brZ
        if b.l > x.ln.get_y1() - marSel * (atr) and b.h < x.ln.get_y1() + marSel * (atr)
            x.bxz.set_rightbottom(b.i + 1, math.min(b.l, x.bxz.get_bottom()))
            if liqSel
                x.lne.set_x2(b.i + 1)
        else
            x.brZ := false

if lqVoid and per
    bull = b.l - b.h[2] > atr200 and b.l > b.h[2] and b.c[1] > b.h[2]
    bear = b.l[2] - b.h > atr200 and b.h < b.l[2] and b.c[1] < b.l[2]

    if bull 
        l  = 13
        if bull[1] 
            st = math.abs(b.l - b.l[1]) / l
            for i = 0 to l - 1
                array.push(b_liq_V, box.new(b.i - 2, b.l[1] + i * st, b.i, b.l[1] + (i + 1) * st, border_color = na, bgcolor = color.new(cLQV_B, 90) ))
        else   
            st = math.abs(b.l - b.h[2]) / l
            for i = 0 to l - 1
                if lqText and i == 0
                    array.push(b_liq_V, box.new(b.i - 2, b.h[2] + i * st, b.i, b.h[2] + (i + 1) * st, text = 'Liquidity Void   ', text_size = size.tiny, text_halign = text.align_right, text_valign = text.align_bottom, text_color = na, border_color = na, bgcolor = color.new(cLQV_B, 90) ))
                else
                    array.push(b_liq_V, box.new(b.i - 2, b.h[2] + i * st, b.i, b.h[2] + (i + 1) * st, border_color = na, bgcolor = color.new(cLQV_B, 90) ))

    if bear
        l  = 13
        if bear[1]
            st = math.abs(b.h[1] - b.h) / l
            for i = 0 to l - 1
                array.push(b_liq_V, box.new(b.i - 2, b.h + i * st, b.i, b.h + (i + 1) * st, border_color = na, bgcolor = color.new(cLQV_S, 90) ))
        else
            st = math.abs(b.l[2] - b.h) / l
            for i = 0 to l - 1
                if lqText and i == l - 1
                    array.push(b_liq_V, box.new(b.i - 2, b.h + i * st, b.i, b.h + (i + 1) * st, text = 'Liquidity Void   ', text_size = size.tiny, text_halign = text.align_right, text_valign = text.align_top, text_color = na, border_color = na, bgcolor = color.new(cLQV_S, 90) ))
                else
                    array.push(b_liq_V, box.new(b.i - 2, b.h + i * st, b.i, b.h + (i + 1) * st, border_color = na, bgcolor = color.new(cLQV_S, 90) ))

if b_liq_V.size() > 0
    qt = b_liq_V.size()
    for bn = qt - 1 to 0
        if bn < b_liq_V.size()
            cb = b_liq_V.get(bn)
            ba = math.avg(cb.get_bottom(), cb.get_top())

            if math.sign(b.c[1] - ba) != math.sign(b.c - ba) or math.sign(b.c[1] - ba) != math.sign(b.l - ba) or math.sign(b.c[1] - ba) != math.sign(b.h - ba)
                b_liq_V.remove(bn)
            else
                cb.set_right(b.i + 1)

                if b.i - cb.get_left() > 21
                    cb.set_text_color(color.new(color.gray, 25))

C_Len = 14 // ta.ema depth for bodyAvg
C_ShadowPercent = 5.0 // size of shadows
C_ShadowEqualsPercent = 100.0
C_DojiBodyPercent = 5.0
C_Factor = 2.0 // shows the number of times the shadow dominates the candlestick body

C_BodyHi = math.max(close, open)
C_BodyLo = math.min(close, open)
C_Body = C_BodyHi - C_BodyLo
C_BodyAvg = ta.ema(C_Body, C_Len)
C_SmallBody = C_Body < C_BodyAvg
C_LongBody = C_Body > C_BodyAvg
C_UpShadow = high - C_BodyHi
C_DnShadow = C_BodyLo - low
C_HasUpShadow = C_UpShadow > C_ShadowPercent / 100 * C_Body
C_HasDnShadow = C_DnShadow > C_ShadowPercent / 100 * C_Body
C_WhiteBody = open < close
C_BlackBody = open > close
C_Range = high-low
C_IsInsideBar = C_BodyHi[1] > C_BodyHi and C_BodyLo[1] < C_BodyLo
C_BodyMiddle = C_Body / 2 + C_BodyLo
C_ShadowEquals = C_UpShadow == C_DnShadow or (math.abs(C_UpShadow - C_DnShadow) / C_DnShadow * 100) < C_ShadowEqualsPercent and (math.abs(C_DnShadow - C_UpShadow) / C_UpShadow * 100) < C_ShadowEqualsPercent
C_IsDojiBody = C_Range > 0 and C_Body <= C_Range * C_DojiBodyPercent / 100
C_Doji = C_IsDojiBody and C_ShadowEquals

patternLabelPosLow = low - (ta.atr(30) * 0.6)
patternLabelPosHigh = high + (ta.atr(30) * 0.6)

label_color_bearish = input(color.rgb(255, 82, 82, 90), "Label Color Bearish")
label_color_bullish = input(color.rgb(33, 149, 243, 90), "Label Color Bullish")

C_MarubozuBlackBearishNumberOfCandles = 1
C_MarubozuWhiteBullishNumberOfCandles = 1
C_MarubozuShadowPercentBearish = 5.0
C_MarubozuShadowPercentWhite = 5.0

C_MarubozuBlackBearish = C_BlackBody and C_LongBody and C_UpShadow <= C_MarubozuShadowPercentBearish/100*C_Body and C_DnShadow <= C_MarubozuShadowPercentBearish/100*C_Body and C_BlackBody
C_MarubozuWhiteBullish = C_WhiteBody and C_LongBody and C_UpShadow <= C_MarubozuShadowPercentWhite/100*C_Body and C_DnShadow <= C_MarubozuShadowPercentWhite/100*C_Body and C_WhiteBody

combined_alert_condition = C_MarubozuBlackBearish or C_MarubozuWhiteBullish

alertcondition(combined_alert_condition, title = "Marubozu Pattern Detected", message = "A Marubozu pattern has been detected!")

if C_MarubozuBlackBearish
    var ttBearishMarubozuBlack = "Marubozu Black\nThis is a candlestick that has no shadow, which extends from the red-bodied candle at the open, the close, or even at both. In Japanese, the name means “close-cropped” or “close-cut.” The candlestick can also be referred to as Bald or Shaven Head."
    label.new(bar_index, patternLabelPosHigh, text="MB", style=label.style_label_down, color = label_color_bearish, textcolor=color.white, tooltip = ttBearishMarubozuBlack)

if C_MarubozuWhiteBullish
    var ttBullishMarubozuWhite = "Marubozu White\nA Marubozu White Candle is a candlestick that does not have a shadow that extends from its candle body at either the open or the close. Marubozu is Japanese for “close-cropped” or “close-cut.” Other sources may call it a Bald or Shaven Head Candle."
    label.new(bar_index, patternLabelPosLow, text="MW", style=label.style_label_up, color = label_color_bullish, textcolor=color.white, tooltip = ttBullishMarubozuWhite)

C_DownTrend = true
C_UpTrend = true
var trendRule1 = "SMA50"
var trendRule2 = "SMA50, SMA200"
var trendRule = input.string(trendRule1, "Detect Trend Based On", options=[trendRule1, trendRule2, "No detection"])

if trendRule == trendRule1
	priceAvg = ta.sma(close, 50)
	C_DownTrend := close < priceAvg
	C_UpTrend := close > priceAvg

if trendRule == trendRule2
	sma200 = ta.sma(close, 200)
	sma50 = ta.sma(close, 50)
	C_DownTrend := close < sma50 and sma50 < sma200
	C_UpTrend := close > sma50 and sma50 > sma200

C_EngulfingBullishNumberOfCandles = 2
C_EngulfingBullish = C_DownTrend and C_WhiteBody and C_LongBody and C_BlackBody[1] and C_SmallBody[1] and close >= open[1] and open <= close[1] and ( close > open[1] or open < close[1] )
alertcondition(C_EngulfingBullish, title = "New pattern detected", message = "New Engulfing – Bullish pattern detected")
if C_EngulfingBullish
    var ttBullishEngulfing = "Engulfing\nAt the end of a given downward trend, there will most likely be a reversal pattern. To distinguish the first day, this candlestick pattern uses a small body, followed by a day where the candle body fully overtakes the body from the day before, and closes in the trend’s opposite direction. Although similar to the outside reversal chart pattern, it is not essential for this pattern to completely overtake the range (high to low), rather only the open and the close."
    label.new(bar_index, patternLabelPosLow, text="BE", style=label.style_label_up, color = label_color_bullish, textcolor=color.white, tooltip = ttBullishEngulfing)

C_EngulfingBearishNumberOfCandles = 2
C_EngulfingBearish = C_UpTrend and C_BlackBody and C_LongBody and C_WhiteBody[1] and C_SmallBody[1] and close <= open[1] and open >= close[1] and ( close < open[1] or open > close[1] )
alertcondition(C_EngulfingBearish, title = "New pattern detected", message = "New Engulfing – Bearish pattern detected")
if C_EngulfingBearish
    var ttBearishEngulfing = "Engulfing\nAt the end of a given uptrend, a reversal pattern will most likely appear. During the first day, this candlestick pattern uses a small body. It is then followed by a day where the candle body fully overtakes the body from the day before it and closes in the trend’s opposite direction. Although similar to the outside reversal chart pattern, it is not essential for this pattern to fully overtake the range (high to low), rather only the open and the close."
    label.new(bar_index, patternLabelPosHigh, text="BE", style=label.style_label_down, color = label_color_bearish, textcolor=color.white, tooltip = ttBearishEngulfing)

shortest = ta.ema(close, 20)
short = ta.ema(close, 50)
long = ta.ema(close, 200)
color c0 = color.new(color.orange, 50)
color c1 = color.new(color.red, 80)
color c2 = color.new(color.blue, 80)
color c3 = color.new(#2195f3, 30)
plot(shortest, color = c0)
plot(short, color = c1)
plot(long, color = c2)
plot(ta.cross(short, long) ? short : na, style = plot.style_cross, linewidth = 4,color = c3)

length2 = input.float(500,'Window Size',maxval=500,minval=0)
h1      = input.float(10.,'Bandwidth')
mult   = input.float(3.) 
srcUpperBand = input.source(low,'Source Upper Band')
src1    = input.source(high,'Source Lower Band')

up_col = input.color(#ff1100,'Colors',inline='col')
dn_col = input.color(#39ff14,'',inline='col')
show_bands = input(false, 'Show Bands')
show_sma_7_low_1 = input(false, 'Show SMA 7 LOW +1')
show_sma_7_low_7 = input(false, 'Show SMA 7 LOW -7')
show_sma_30_high = input(false, 'Show SMA 30 HIGH')

var k = 2
var upper1 = array.new_line(0) 
var lower1 = array.new_line(0) 

sma7_low = ta.sma(low, 7)
sma30_high = ta.sma(high, 30)

strDownArrows = "↓▼↓"
strUpArrows = "↑▲↑"

RoundUp(number, decimals) =>
    factor = math.pow(10, decimals)
    math.ceil(number * factor) / factor

plot(show_sma_7_low_1?sma7_low:na, color=color.rgb(255, 235, 59, 81), title="SMA 7 LOW +1", offset=+1, linewidth=1)
plot(show_sma_7_low_7?sma7_low:na, color=color.rgb(255, 235, 59, 81), title="7 sma", offset=-7, linewidth=1)
plot(show_sma_30_high ? sma30_high:na, color=color.purple, title="SMA 30 High", linewidth=1)
lset(l,x1,y1,x2,y2,col)=>
    line.set_xy1(l,x1,y1)
    line.set_xy2(l,x2,y2)
    line.set_color(l,col)
    line.set_width(l,2)

if barstate.isfirst
    for i = 0 to length2/k-1
        array.push(upper1,line.new(na,na,na,na))
        array.push(lower1,line.new(na,na,na,na))

line up = na
line dn = na

cross_up = 0.
cross_dn = 0.
if barstate.islast
    y = array.new_float(0)
    yUpper = array.new_float(0)

    sum_upper_e = 0.
    sum_e = 0.
    for i = 0 to length2-1
        sum_upper = 0.
        sumw_upper = 0.
        sum = 0.
        sumw = 0.

        for j = 0 to length2-1
            w = math.exp(-(math.pow(i-j,2)/(h1*h1*2)))
            sum_upper += srcUpperBand[j]*w
            sum += src1[j]*w
            sumw += w

        y_upper_2 = sum_upper/sumw
        sum_upper_e += math.abs(srcUpperBand[i] - y_upper_2)
        array.push(yUpper,y_upper_2)

        y2 = sum/sumw
        sum_e += math.abs(src1[i] - y2)
        array.push(y,y2)

    mae_upper = sum_upper_e/length2*mult
    mae = sum_e/length2*mult

    for i = 1 to length2-1
        upper_y2 = array.get(yUpper,i)
        upper_y1 = array.get(yUpper,i-1)

        y2 = array.get(y,i)
        y1 = array.get(y,i-1)

        up := array.get(upper1,i/k) 
        dn := array.get(lower1,i/k)

        if show_bands
            lset(up,n-i+1,upper_y1 + mae_upper,n-i,upper_y2 + mae_upper,up_col)
            lset(dn,n-i+1,y1 - mae,n-i,y2 - mae,dn_col)

        if sma30_high[i] > upper_y1 + mae_upper and sma30_high[i+1] < upper_y2 + mae_upper
            label.new(n-i,srcUpperBand[i]+mae_upper,strDownArrows,color=#00000000,style=label.style_label_down,textcolor=#ec0505,textalign=text.align_center)

        if sma7_low[i] > upper_y1 + mae_upper and sma7_low[i+1] < upper_y2 + mae_upper
            label.new(n-i,src1[i],strDownArrows,color=#00000000,style=label.style_label_down,textcolor=color.orange,textalign=text.align_center)
        if sma7_low[i] < y1 - mae and sma7_low[i+1] > y2 - mae
            label.new(n-i,src1[i]-mae,strUpArrows,color=#00000000,style=label.style_label_up,textcolor=color.rgb(16, 177, 4),textalign=text.align_center)

    cross_up := array.get(yUpper,0) + mae_upper
    cross_dn := array.get(y,0) - mae	

sma7_crossover = ta.crossover(sma7_low,cross_up)
sma7_crossunder = ta.crossunder(sma7_low,cross_dn)

sma30_crossover = ta.crossover(sma30_high,cross_up)
sma30_crossunder = ta.crossunder(sma30_high,cross_dn)

alertcondition(sma30_crossunder or sma7_crossunder,title="LONG", message='LONG: {{ticker}}/{{interval}} at price {{close}} on {{exchange}}' )
alertcondition(sma7_crossover or sma30_crossover,title="SHORT", message='SHORT: {{ticker}}/{{interval}} at price {{close}} on {{exchange}}' )

length3 = input.int(3, 'Pivot Lookback', minval = 2)

useSym1 = input(true, 'Comparison Symbol', inline = 'symA')
sym1    = input.symbol('CME_MINI_DL:ES1!', '', inline = 'symA')

useSym2 = input(true, 'Comparison Symbol', inline = 'symB')
sym2   = input.symbol('CBOT_MINI_DL:YM1!', '', inline = 'symB')

bullDivCss = input.color(#ff110082, 'Swing High', group = 'Style')
bearDivCss = input.color(#2156f380, 'Swing Low', group = 'Style')

get_hl() => [high, low, close]

get_divergence(ph1, y2, sym_y2, css)=>
    var float y1 = na
    var float sym_y1 = na
    var int x1 = na
    var smt = 0

    if y2 != y2[1] and sym_y2 != sym_y2[1] 

        if (y2 - y1) * (sym_y2 - sym_y1) < 0
            line.new(n[length3], y2, x1, y1, color = css)

            smt += 1

        sym_y1 := sym_y2
        y1 := y2
        x1 := n[length3]
    else if (ph1 and y2 > y2[1]) or (not ph1 and y2 < y2[1]) 
        sym_y1 := na
        y1 := y2
        x1 := n[length3]

    smt

var phN = 0, var plN = 0
var ph_smt1 = 0.
var pl_smt1 = 0.
var ph_smt2 = 0.
var pl_smt2 = 0.

ticker1 = syminfo.ticker(sym1)
ticker2 = syminfo.ticker(sym2)

ph1 = fixnan(ta.pivothigh(length3, length3))
pl1 = fixnan(ta.pivotlow(length3, length3))
phN += ph1 != ph1[1] ? 1 : 0
plN += pl1 != pl1[1] ? 1 : 0

[h11, l1, c11] = request.security(sym1, timeframe.period, get_hl())
[h21, l2, c21] = request.security(sym2, timeframe.period, get_hl())

if useSym1
    sym_ph1 = fixnan(ta.pivothigh(h11, length3, length3))
    sym_pl1 = fixnan(ta.pivotlow(l1, length3, length3))

    ph_smt1 := get_divergence(true, ph1, sym_ph1, bullDivCss)
    pl_smt1 := get_divergence(false, pl1, sym_pl1, bearDivCss)

if useSym2
    sym_ph2 = fixnan(ta.pivothigh(h21, length3, length3))
    sym_pl2 = fixnan(ta.pivotlow(l2, length3, length3))

    ph_smt2 := get_divergence(true, ph1, sym_ph2, bullDivCss)
    pl_smt2 := get_divergence(false, pl1, sym_pl2, bearDivCss)

txt = ''
if ph1 != ph1[1]
    if ph_smt1 > ph_smt1[1]
        txt += ticker1
    if ph_smt2 > ph_smt2[1]
        txt += txt != '' ? ' | ' : ''
        txt += ticker2

    if txt != ''
        label.new(n[length3], ph1, txt
          , color = bullDivCss
          , style = label.style_label_down
          , textcolor = color.white
          , size = size.tiny)
else
    if pl_smt1 > pl_smt1[1]
        txt += ticker1
    if pl_smt2 > pl_smt2[1]
        txt += txt != '' ? ' | ' : ''
        txt += ticker2

    if txt != ''
        label.new(n[length3], pl1, txt
          , color = bearDivCss
          , style = label.style_label_up
          , textcolor = color.white
          , size = size.tiny)

if barstate.isfirst and showDash
    tb.cell(1, 0, 'Swing High', text_color = color.white)
    tb.cell(2, 0, 'Swing Low', text_color = color.white)

    tb.cell(0, 1, ticker1, text_color = color.white)
    tb.cell(0, 2, ticker2, text_color = color.white)

if barstate.islast and showDash

    tb.cell(1, 1, str.format('{0} ({1, number, percent})', ph_smt1, ph_smt1 / phN)
      , text_color = bullDivCss)
    tb.cell(2, 1, str.format('{0} ({1, number, percent})', pl_smt1, pl_smt1 / plN)
      , text_color = bearDivCss)

    tb.cell(1, 2, str.format('{0} ({1, number, percent})', ph_smt2, ph_smt2 / phN)
      , text_color = bullDivCss)
    tb.cell(2, 2, str.format('{0} ({1, number, percent})', pl_smt2, pl_smt2 / plN)
      , text_color = bearDivCss)

showema = input(defval=false, title='Show all EMAs', group='Plot EMA ')
Overridetargetsize = input(defval=false, title='Change Standard Target Size', group='Targets')
Targetssize = input.float(title='Pips for Target', defval=0.0001, minval=0.0001, group = 'Targets')

color black100 = color.new(color.black,100)
color green75 = color.new(color.green,75)
color green0 = color.new(#4caf4f, 10)
color aqua0 = color.new(color.aqua, 0)
color black0 = color.new(color.black, 0)
color blue0 = color.new(#0F52BA, 0)
color gray0 = color.new(#787b86, 100)
color orange0 = color.new(#ff8c00, 10)
color red0 = color.new(#ff5252, 10)
color red75 = color.new(color.red,75)
color white0 = color.new(color.white, 0)
color yellow0 = color.new(#fff700, 100)
bool showgreydiamond = input(defval=false, title='Show Diamond For Back Testing' ,group='=== Information ===')

LabelDigitDisplay =
 syminfo.ticker == 'AUDCAD' == true ? '#.#####' : syminfo.ticker == 'AUDCHF' == true ? '#.#####' : syminfo.ticker == 'AUDJPY' == true ? '#.###'   : syminfo.ticker == 'AUDNZD' == true ? '#.#####'  :
 syminfo.ticker == 'AUDUSD' == true ? '#.#####' : syminfo.ticker == 'CADCHF' == true ? '#.#####' : syminfo.ticker == 'CADJPY' == true ? '#.###'   : syminfo.ticker == 'CHFJPY' == true ? '#.###'    : 
 syminfo.ticker == 'EURAUD' == true ? '#.#####' : syminfo.ticker == 'EURCAD' == true ? '#.#####' : syminfo.ticker == 'EURCHF' == true ? '#.#####' : syminfo.ticker == 'EURGBP' == true ? '#.#####' :
 syminfo.ticker == 'EURJPY' == true ?  '#.###'  : syminfo.ticker == 'EURNZD' == true ? '#.#####' : syminfo.ticker == 'EURUSD' == true ? '#.#####' : syminfo.ticker == 'GBPAUD' == true ? '#.#####' :
 syminfo.ticker == 'GBPCAD' == true ? '#.#####' : syminfo.ticker == 'GBPCHF' == true ? '#.#####' : syminfo.ticker == 'GBPJPY' == true ? '#.###'   : syminfo.ticker == 'GBPNZD' == true ? '#.#####' : 
 syminfo.ticker == 'GBPUSD' == true ? '#.#####' : syminfo.ticker == 'NZDCAD' == true ? '#.#####' : syminfo.ticker == 'NZDCHF' == true ? '#.#####' : syminfo.ticker == 'NZDJPY' == true ? '#.###': 
 syminfo.ticker == 'NZDUSD' == true ? '#.#####' : syminfo.ticker == 'USDCAD' == true ? '#.#####' : syminfo.ticker == 'USDCHF' == true ? '#.#####' : syminfo.ticker == 'USDJPY' == true ? '#.###': 
 syminfo.ticker == 'GOLD'   == true ? '#.##'    : syminfo.ticker == 'US100'  == true ? '#.##'    : syminfo.ticker == 'US30'   == true ? '#.##'    : syminfo.ticker == 'US500'  == true ? '#.##'    : syminfo.ticker == 'DE40' == true ? '#.##' : '#.#####'

PipsMultiplier = 
 syminfo.ticker == 'AUDCAD' == true ? 0.00050 : syminfo.ticker == 'AUDCHF' == true ? 0.00050 : syminfo.ticker == 'AUDJPY' == true ? 00.050   : syminfo.ticker == 'AUDNZD' == true ? 0.00050 :
 syminfo.ticker == 'AUDUSD' == true ? 0.00050 : syminfo.ticker == 'CADCHF' == true ? 0.00050 : syminfo.ticker == 'CADJPY' == true ? 00.050   : syminfo.ticker == 'CHFJPY' == true ? 00.050: 
 syminfo.ticker == 'EURAUD' == true ? 0.00050 : syminfo.ticker == 'EURCAD' == true ? 0.00050 : syminfo.ticker == 'EURCHF' == true ? 0.00050 : syminfo.ticker == 'EURGBP' == true ? 0.00050 :
 syminfo.ticker == 'EURJPY' == true ? 00.050   : syminfo.ticker == 'EURNZD' == true ? 0.00050 : syminfo.ticker == 'EURUSD' == true ? 0.00050 : syminfo.ticker == 'GBPAUD' == true ? 0.00050 :
 syminfo.ticker == 'GBPCAD' == true ? 0.00050 : syminfo.ticker == 'GBPCHF' == true ? 0.00050 : syminfo.ticker == 'GBPJPY' == true ? 00.050   : syminfo.ticker == 'GBPNZD' == true ? 0.00050 : 
 syminfo.ticker == 'GBPUSD' == true ? 0.00050 : syminfo.ticker == 'NZDCAD' == true ? 0.00050 : syminfo.ticker == 'NZDCHF' == true ? 0.00050 : syminfo.ticker == 'NZDJPY' == true ? 00.050: 
 syminfo.ticker == 'NZDUSD' == true ? 0.00050 : syminfo.ticker == 'USDCAD' == true ? 0.00050 : syminfo.ticker == 'USDCHF' == true ? 0.00050 : syminfo.ticker == 'USDJPY' == true ? 00.050:
 syminfo.ticker == 'GOLD' == true ? 1.5 : syminfo.ticker == 'US100' == true ? 10 : syminfo.ticker == 'US30' == true ? 25   : syminfo.ticker == 'US500' == true ? 10 : syminfo.ticker == 'DE40' == true ? 10 : 1

Targettouse = Overridetargetsize ? Targetssize : PipsMultiplier

Imbcol = input.color(yellow0, 'Imbalance Colour', inline="1" ,group='=== Information ===')
Dimcol = input.color(gray0, 'Imbalance Colour', inline="1" ,group='=== Information ===')
TopImbalance = low[2] <= open[1] and high[0] >= close[1]
TopImbalancesize = low[2] - high[0]
if TopImbalance and TopImbalancesize > 0
    BOX1 = box.new(left=bar_index[1], top=low[2], right=bar_index[0], bottom=high[0])
    box.set_bgcolor(BOX1, Imbcol )
    box.set_border_color(BOX1, Imbcol )

BottomInbalance = high[2] >= open[1] and low[0] <= close[1]
BottomInbalancesize = low[0] - high[2]
if BottomInbalance and BottomInbalancesize > 0
    BOX2 = box.new(left=bar_index[1], top=low[0], right=bar_index[0], bottom=high[2])
    box.set_bgcolor(BOX2, Imbcol )
    box.set_border_color(BOX2, Imbcol )

DownImbalance = TopImbalance and TopImbalancesize > 0
plotshape(DownImbalance[0] and showgreydiamond, style=shape.diamond, location=location.abovebar, color=Dimcol, size=size.tiny)

UpImbalance = BottomInbalance and BottomInbalancesize > 0
plotshape(UpImbalance[0] and showgreydiamond, style=shape.diamond, location=location.belowbar, color=Dimcol, size=size.tiny)

DownSell = close[1]>open[1] and close<open
UpBuy    = close[1]<open[1] and close>open

boxcolourtop        = UpBuy    ? green0 : black100
boxcolourbottom     = DownSell ? red0   : black100
boxcolourtopfill    = UpBuy    ? green75 : black100
boxcolourbottomfill = DownSell ? red75   : black100

BottomLabel = label.new(x=bar_index, y=high+(Targettouse/3), xloc=xloc.bar_index)
label.set_text(BottomLabel, text
 = "\n \n Entry = " + str.tostring(close,LabelDigitDisplay) 
 + "\n Stop Loss = " + str.tostring(high,LabelDigitDisplay) 
 + "\n Take Profit = " + str.tostring(close-PipsMultiplier,LabelDigitDisplay)
 + "\n Target Size = " + str.tostring(PipsMultiplier,LabelDigitDisplay))
label.set_textalign(BottomLabel, text.align_left)    
label.set_style(BottomLabel, label.style_label_left)
label.set_color(BottomLabel,  black100)
label.set_textcolor(BottomLabel, boxcolourbottom) 
label.delete(BottomLabel[1])
Bottom = box.new(left=bar_index[0], top=low, right=bar_index[0], bottom=low-Targettouse, xloc=xloc.bar_index)
box.set_right(Bottom,right=box.get_right(id=Bottom)+10)
box.set_bgcolor(Bottom , color=boxcolourbottomfill )
box.set_border_color(Bottom , color=boxcolourbottom)
box.delete(Bottom [1]) 

TopLabel = label.new(x=bar_index, y=low-(Targettouse/3), xloc=xloc.bar_index)
label.set_text(TopLabel, text
 = "\n \n Entry = " + str.tostring(close,LabelDigitDisplay) 
 + "\n Stop Loss = " + str.tostring(low,LabelDigitDisplay) 
 + "\n Take Profit = " + str.tostring(close+Targettouse,LabelDigitDisplay)
 + "\n Target Size = " + str.tostring(PipsMultiplier,LabelDigitDisplay))
label.set_textalign(TopLabel, text.align_left)    
label.set_style(TopLabel, label.style_label_left)
label.set_color(TopLabel,  black100)
label.set_textcolor(TopLabel, boxcolourtop ) 
label.delete(TopLabel[1])   
Top =  box.new(left=bar_index[0], top=high+Targettouse, right=bar_index[0], bottom=high, xloc=xloc.bar_index)
box.set_right(Top,right=box.get_right(id=Top)+10)
box.set_bgcolor(Top , color=boxcolourtopfill  )
box.set_border_color(Top, color=boxcolourtop )
box.delete(Top[1]) 

ema13colour = showema ? red0    : black100
ema35colour = showema ? orange0 : black100
ema50colour = showema ? aqua0   : black100

offset = input.int(title='Offset', defval=0, minval=-500, maxval=500)

emalen1513 =26 //input.int(13, minval=1, title='Length 13 EMA 15 Min', group='=== EMA Information ===')
emasrc1513 = close
EMA13 = request.security(syminfo.tickerid, '1', ta.ema(emasrc1513, emalen1513))
plot(EMA13, title='EMA 13 15 Min', color=ema13colour, linewidth=1, offset=offset)

emalen1535 = 63 //input.int(35, minval=1, title='Length 35 EMA 15 Min', group='=== EMA Information ===')
emasrc1535 = close
EMA35 = request.security(syminfo.tickerid, '1', ta.ema(emasrc1535, emalen1535))
plot(EMA35, title='EMA 35 15 Min', color=ema35colour, linewidth=1, offset=offset)

emalen1550 = 100 //input.int(50, minval=1, title='Length 50 EMA 15 Min', group='=== EMA Information ===')
emasrc1550 = close
EMA50 = request.security(syminfo.tickerid, '1', ta.ema(emasrc1550, emalen1550))
plot(EMA50, title='EMA 50 15 Min', color=ema50colour, linewidth=2, offset=offset)

Up   = EMA13 > EMA35 and EMA35 > EMA50
Down = EMA13 < EMA35 and EMA35 < EMA50

plotshape(Up , title='Up',   style=shape.square,   location=location.bottom, color=green0, size=size.tiny) 
plotshape(Down , title='Down',   style=shape.square,   location=location.bottom, color=red0, size=size.tiny) 
plotshape(not Down and not Up , title='Warning',   style=shape.square,   location=location.bottom, color=orange0, size=size.tiny) 

alertcondition(Up and not Up[1] ,  title='Buy  Switch On', message='Buy  Switch On')
alertcondition(Down and not Down[1],  title='Sell Switch On', message='Sell Switch On')
alertcondition(Up[1] and not Up ,  title='Warning Stop any More Buys', message='Warning Stop any More Buys')
alertcondition(Down[1] and not Down,  title='Warning Stop any More Sells', message='Warning Stop any More Sells')

alertcondition(open > close or close <= open ,  title='Every Bar Alert', message='Every Bar Alert')

const bool DEBUG = false
const int timeframeCount = 3
const float touchATR = 1.0 / 30.0
const float retestATR = 1.0 / 30.0
const float labelOffsetY = 1.5
const int labelOffsetsXIndex = 30
const int maxPivotsBackSR = 15
const int retestLabelEveryXBars = 3
const int maxTraverse = 250  // Affects bar history limit. Default value 250.
const int maxRetestLabels = 100
const int maxSupports = 3
const int maxResistances = 3
const int debug_maxPivotLabels = 25

resistanceSupportCount = input.int(3, "Support & Resistance Count", options = [1, 2, 3], group = "General Configuration", display = display.none)
pivotRange = input.int(15, "Pivot Range", options = [5, 15, 30], tooltip = "Increase for more gener

Показано первые 50% кода (символов: 86927)

Открыть по тарифу

Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.

Разовая покупка файла

На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.

Чтобы оформить заказ, введите email и перейдите к оплате.

Стоимость полного кода
8 692,70₽ ≈ $106.24