Strategy · Pine Script v4 · On the chart

Order Fractals strategy V3

by DaniilOkrug· code credited to icewalk

This strategy identifies reversal points using large and additional fractals on the price chart.

View on GitHub

GitHub stars2on the repository
Pine versionv4older, still runs
Lines of code324
Settings14inputs
LicenceMIT
Last update4 years ago15 Dec 2021

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 strategy, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart. The trades and results appear in the Strategy Tester tab; adjust the settings with the gear icon.

Source Code

324 lines of Pine Script v4 from [Order] Fractals strategy V3.txt, published under MIT. Keep the author's credit and licence lines when you reuse it.

[Order] Fractals strategy V3.txt
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © icewalk

//@version=4
strategy("[Order] Fractals strategy V3", overlay=true, pyramiding=2)

// ---INPUTS--- //

n = input(title="Период крупных фракталов", defval=2, minval=2, type=input.integer, group="Настройки фракталов")
n_additional = input(title="Период меньших фракталов", defval=2, minval=2, type=input.integer, group="Настройки фракталов")

upFractalType = input(title="Тип верхнего фрактала", defval="high", options=["high", "close"], group="Фракталы после пробития")
downFractalType = input(title="Тип нижнего фрактала", defval="low", options=["low", "close"], group="Фракталы после пробития")

numberFs = input(title="Количество отслеживаемых фракталов назад", defval=1, minval=1, type=input.integer, group="Основные уровни")
levelRetestPercent = input(title="Процент дистанции ретеста(%)", defval=2, type=input.float, step=0.1, group="Основные уровни")/100

afterBeaking_bottomRangePercent = input(title="Верхний уровень после пробития(%)", defval=15, type=input.float, group="После пробития основного уровня") / 100
afterBeaking_topRangePercent = input(title="Нижний уровень после пробития(%)", defval=15, type=input.float, group="После пробития основного уровня") / 100

showMainFractals = input(title="Показать крупные фракталы", defval=true, type=input.bool, group="Визуальная часть")
showAdditionalFractals = input(title="Показать меньшие фракталы", defval=false, type=input.bool, group="Визуальная часть")
// showMainLevelsBreaking = input(title="Показать пробитие", defval=true, type=input.bool, group="Визуальная часть")
showRangeAfterBreaking = input(title="Показать линии дипозона фракталов после пробития", defval=true, type=input.bool, group="Визуальная часть")
showRetestLine = input(title="Показать уровень для ретеста", defval=true, type=input.bool, group="Визуальная часть")
showRetestSignal = input(title="Показать сигнал ретеста", defval=true, type=input.bool, group="Визуальная часть")
showRetestAlert = input(title="Ретест", defval=true, type=input.bool, group="Alerts")

// ---INPUTS END--- //

// Фракталы крупного таймфрейма
// UpFractal
bool upflagDownFrontier = true
bool upflagUpFrontier0 = true
bool upflagUpFrontier1 = true
bool upflagUpFrontier2 = true
bool upflagUpFrontier3 = true
bool upflagUpFrontier4 = true

for i = 1 to n
    upflagDownFrontier := upflagDownFrontier and (high[n-i] < high[n])
    upflagUpFrontier0 := upflagUpFrontier0 and (high[n+i] < high[n])
    upflagUpFrontier1 := upflagUpFrontier1 and (high[n+1] <= high[n] and high[n+i + 1] < high[n])
    upflagUpFrontier2 := upflagUpFrontier2 and (high[n+1] <= high[n] and high[n+2] <= high[n] and high[n+i + 2] < high[n])
    upflagUpFrontier3 := upflagUpFrontier3 and (high[n+1] <= high[n] and high[n+2] <= high[n] and high[n+3] <= high[n] and high[n+i + 3] < high[n])
    upflagUpFrontier4 := upflagUpFrontier4 and (high[n+1] <= high[n] and high[n+2] <= high[n] and high[n+3] <= high[n] and high[n+4] <= high[n] and high[n+i + 4] < high[n])
flagUpFrontier = upflagUpFrontier0 or upflagUpFrontier1 or upflagUpFrontier2 or upflagUpFrontier3 or upflagUpFrontier4

upFractal = (upflagDownFrontier and flagUpFrontier)


// downFractal
bool downflagDownFrontier = true
bool downflagUpFrontier0 = true
bool downflagUpFrontier1 = true
bool downflagUpFrontier2 = true
bool downflagUpFrontier3 = true
bool downflagUpFrontier4 = true

for i = 1 to n
    downflagDownFrontier := downflagDownFrontier and (low[n-i] > low[n])
    downflagUpFrontier0 := downflagUpFrontier0 and (low[n+i] > low[n])
    downflagUpFrontier1 := downflagUpFrontier1 and (low[n+1] >= low[n] and low[n+i + 1] > low[n])
    downflagUpFrontier2 := downflagUpFrontier2 and (low[n+1] >= low[n] and low[n+2] >= low[n] and low[n+i + 2] > low[n])
    downflagUpFrontier3 := downflagUpFrontier3 and (low[n+1] >= low[n] and low[n+2] >= low[n] and low[n+3] >= low[n] and low[n+i + 3] > low[n])
    downflagUpFrontier4 := downflagUpFrontier4 and (low[n+1] >= low[n] and low[n+2] >= low[n] and low[n+3] >= low[n] and low[n+4] >= low[n] and low[n+i + 4] > low[n])
flagDownFrontier = downflagUpFrontier0 or downflagUpFrontier1 or downflagUpFrontier2 or downflagUpFrontier3 or downflagUpFrontier4

downFractal = (downflagDownFrontier and flagDownFrontier)


plotshape(upFractal and showMainFractals, style=shape.triangleup,   location=location.abovebar, offset=-n, color=color.green, size = size.small)
plotshape(downFractal and showMainFractals, style=shape.triangledown,   location=location.belowbar, offset=-n, color=color.red, size = size.small)

//Fractals end

// Фрактала меньшег таймрейма

// UpFractal
bool upflagDownFrontier_additional = true
bool upflagUpFrontier0_additional = true
bool upflagUpFrontier1_additional = true
bool upflagUpFrontier2_additional = true
bool upflagUpFrontier3_additional = true
bool upflagUpFrontier4_additional = true

for i = 1 to n_additional
    upflagDownFrontier_additional := upflagDownFrontier_additional and (high[n_additional-i] < high[n_additional])
    upflagUpFrontier0_additional := upflagUpFrontier0_additional and (high[n_additional+i] < high[n_additional])
    upflagUpFrontier1_additional := upflagUpFrontier1_additional and (high[n_additional+1] <= high[n_additional] and high[n_additional+i + 1] < high[n_additional])
    upflagUpFrontier2_additional := upflagUpFrontier2_additional and (high[n_additional+1] <= high[n_additional] and high[n_additional+2] <= high[n_additional] and high[n_additional+i+2] < high[n_additional])
    upflagUpFrontier3_additional := upflagUpFrontier3_additional and (high[n_additional+1] <= high[n_additional] and high[n_additional+2] <= high[n_additional] and high[n_additional+3] <= high[n_additional] and high[n_additional+i + 3] < high[n_additional])
    upflagUpFrontier4_additional := upflagUpFrontier4_additional and (high[n_additional+1] <= high[n_additional] and high[n_additional+2] <= high[n_additional] and high[n_additional+3] <= high[n_additional] and high[n_additional+4] <= high[n_additional] and high[n_additional+i + 4] < high[n_additional])
flagUpFrontier_additional = upflagUpFrontier0_additional or upflagUpFrontier1_additional or upflagUpFrontier2_additional or upflagUpFrontier3_additional or upflagUpFrontier4_additional

upFractal_additional = (upflagDownFrontier_additional and flagUpFrontier_additional)


// downFractal
bool downflagDownFrontier_additional = true
bool downflagUpFrontier0_additional = true
bool downflagUpFrontier1_additional = true
bool downflagUpFrontier2_additional = true
bool downflagUpFrontier3_additional = true
bool downflagUpFrontier4_additional = true

for i = 1 to n_additional
    downflagDownFrontier_additional := downflagDownFrontier_additional and (low[n_additional-i] > low[n_additional])
    downflagUpFrontier0_additional := downflagUpFrontier0_additional and (low[n_additional+i] > low[n_additional])
    downflagUpFrontier1_additional := downflagUpFrontier1_additional and (low[n_additional+1] >= low[n_additional] and low[n_additional+i + 1] > low[n_additional])
    downflagUpFrontier2_additional := downflagUpFrontier2_additional and (low[n_additional+1] >= low[n_additional] and low[n_additional+2] >= low[n_additional] and low[n_additional+i + 2] > low[n_additional])
    downflagUpFrontier3_additional := downflagUpFrontier3_additional and (low[n_additional+1] >= low[n_additional] and low[n_additional+2] >= low[n_additional] and low[n_additional+3] >= low[n_additional] and low[n_additional+i + 3] > low[n_additional])
    downflagUpFrontier4_additional := downflagUpFrontier4_additional and (low[n_additional+1] >= low[n_additional] and low[n_additional+2] >= low[n_additional] and low[n_additional+3] >= low[n_additional] and low[n_additional+4] >= low[n_additional] and low[n_additional+i + 4] > low[n_additional])
flagDownFrontier_additional = downflagUpFrontier0_additional or downflagUpFrontier1_additional or downflagUpFrontier2_additional or downflagUpFrontier3_additional or downflagUpFrontier4_additional

downFractal_additional = (downflagDownFrontier_additional and flagDownFrontier_additional)


plotshape(upFractal_additional and showAdditionalFractals, style=shape.xcross,   location=location.abovebar, offset=-n_additional, color=color.green, size = size.small)
plotshape(downFractal_additional and showAdditionalFractals, style=shape.xcross,   location=location.belowbar, offset=-n_additional, color=color.red, size = size.small)

// ---MAIN--- //

var minFs = array.new_float(0)          // Minimum fractals
var maxFs = array.new_float(0)          // Maximum fractals
var minFs_indexes = array.new_int(0)    // Minimum fractals indexes
var maxFs_indexes = array.new_int(0)    // Maximum fractals indexes

var float levelUp = na                  // Highest breaked fractal
var float levelDown = na                // Lowest breaked fractal

var float rangeAfterBreaking_top = na   
var float rangeAfterBreaking_bottom = na

var float retestLevel_top = na
var float retestLevel_bottom = na

var float breakedFractal_top = na
var float breakedFractal_bottom = na

var bool waitBreakingUp = na
var bool waitBreakingDown = na

var bool waitDownFractal = na
var bool waitUpFractal = na

var bool retestDetected_top = na
var bool retestDetected_bottom = na

var bool waitRetestBottom = na
var bool waitRetestTop = na

var bool waitRetestMainLevelTop = na
var bool waitRetestMainLevelBottom = na

var int openTime = na

// Показываем момент ретеста
plotshape((not na(retestLevel_bottom) and close > retestLevel_bottom and showRetestSignal) or (retestDetected_bottom and showRetestSignal), title="Ретест нижнего уровня", style=shape.labelup, text="Retest bottom", textcolor=color.white, location=location.belowbar, color=color.red, size = size.small)
plotshape((not na(retestLevel_top) and close < retestLevel_top and showRetestSignal) or (retestDetected_top and showRetestSignal), title="Ретест верхнего уровня", style=shape.labeldown, text="Retest top", textcolor=color.white, location=location.abovebar, color=color.green, size = size.small)

retestDetected_top := false
retestDetected_bottom := false

if waitRetestMainLevelTop and not na(breakedFractal_top) and close < breakedFractal_top
    waitRetestMainLevelTop := true
    breakedFractal_top := na
    alert("Ретсет на основном верхнем уровне")
    
if waitRetestMainLevelBottom and not na(breakedFractal_bottom) and close < breakedFractal_bottom
    waitRetestMainLevelBottom := false
    breakedFractal_bottom := na
    alert("Ретсет на основном нижнем уровне")
    
// Ретест снизу вверх на %% уровне
if not na(retestLevel_bottom) and close > retestLevel_bottom
    retestLevel_bottom := na
    breakedFractal_bottom := na
    waitRetestBottom := false
    waitRetestMainLevelBottom := true
        
    if showRetestAlert
        alert("Ретсет на %% уровне")

// Ретест сверху вниз на %% уровне
if not na(retestLevel_top) and close < retestLevel_top
    retestLevel_top := na
    breakedFractal_top := na
    waitRetestTop := false
    waitRetestMainLevelTop := true
    
    if showRetestAlert
        alert("Ретест на %% уровне")

// Сформировался верхний фрактал после пробития вверх
if upFractal_additional and waitUpFractal
    waitUpFractal := false
    waitRetestTop := true
        
    distance = high[n_additional] - array.get(minFs, 0)
    rangeAfterBreaking_top := high[n_additional] - (distance / 2) + distance * afterBeaking_topRangePercent
    rangeAfterBreaking_bottom := high[n_additional] - (distance / 2) - distance * afterBeaking_bottomRangePercent
    
    retestLevel_top := na
    for i = 0 to array.size(maxFs) - 1
        fractalForRange = array.get(maxFs, i)
        
        if rangeAfterBreaking_top > fractalForRange and fractalForRange > rangeAfterBreaking_bottom
            if na(retestLevel_top)
                retestLevel_top := fractalForRange
            
            if fractalForRange > retestLevel_top
                retestLevel_top := fractalForRange
    
    breakedFractal_top := retestLevel_top
    retestLevel_top := retestLevel_top + retestLevel_top  * levelRetestPercent
    
    // for i = 1 to n_additional
    //     if low[i] < retestLevel_top
    //         retestDetected_top := true
    //         waitRetestTop := false
    //         retestLevel_top := na
    //         break

// Сформировался нижний фрактал после пробития вниз
if downFractal_additional and waitDownFractal
    waitDownFractal := false
    waitRetestBottom := true
    
    distance = array.get(maxFs, 0) - low[n_additional]
    rangeAfterBreaking_top := low[n_additional] + (distance / 2) + distance * afterBeaking_topRangePercent
    rangeAfterBreaking_bottom := low[n_additional] + (distance / 2) - distance * afterBeaking_bottomRangePercent
    
    retestLevel_bottom := na
    for i = 0 to array.size(minFs) - 1
        fractalForRange = array.get(minFs, i)
        
        if rangeAfterBreaking_top > fractalForRange and fractalForRange > rangeAfterBreaking_bottom
            if na(retestLevel_bottom)
                retestLevel_bottom := fractalForRange
            
            if fractalForRange < retestLevel_bottom
                retestLevel_bottom := fractalForRange

    breakedFractal_bottom := retestLevel_bottom
    retestLevel_bottom := retestLevel_bottom - retestLevel_bottom * levelRetestPercent
    
    // for i = 1 to n_additional
    //     if high[i] > retestLevel_bottom
    //         retestDetected_bottom := true
    //         waitRetestBottom := false
    //         retestLevel_bottom := na
    //         break

// Показать фрактал сделавший пробитие
// plotshape(upFractal_additional and waitRetestTop and not waitRetestTop[1] and showMainLevelsBreaking, title="Верхний фрактал после пробития", style=shape.labeldown, text="Breaking top", textcolor=color.white, location=location.abovebar, offset=-n_additional, color=color.green, size = size.small)
// plotshape(downFractal_additional and waitRetestBottom and not waitRetestBottom[1] and showMainLevelsBreaking, title="Нижний фрактал посе пробития", style=shape.labelup, text="Breaking down", textcolor=color.white, location=location.belowbar, offset=-n_additional, color=color.red, size = size.small)

// Если появился нижний фрактал, то задаем ожидание пробития верхнего фрактала
if downFractal
    waitBreakingUp := true
    waitBreakingDown := false
        
// Если появился верхний фрактал, то задаем ожидания пробития нижнего фрактала
if upFractal
    waitBreakingDown := true
    waitBreakingUp := false

// Пробитие верхнего фрактала
if array.size(maxFs) > 0 and waitBreakingUp
    if close > array.get(maxFs, 0)
        waitBreakingUp := false
        waitUpFractal := true

// Пробитие нижнего фрактала
if array.size(minFs) > 0 and waitBreakingDown
    if close < array.get(minFs, 0)
        waitBreakingDown := false
        waitDownFractal := true

// Определение верхних фракталов для уровня
if upFractal
    array.unshift(maxFs, high[n])
        
    array.unshift(maxFs_indexes, bar_index[n])
    
    if array.size(maxFs) > numberFs
        array.pop(maxFs)
            
    if array.size(maxFs_indexes) > numberFs
        array.pop(maxFs_indexes)

// Определение нижних фракталов для уровня
if downFractal
    array.unshift(minFs, low[n])
        
    array.unshift(minFs_indexes, bar_index[n])
    
    if array.size(minFs) > numberFs
        array.pop(minFs)
        
    if array.size(minFs_indexes) > numberFs
        array.pop(minFs_indexes)
        
// Визуализация
var line afterBreaking_topLine = na
var line afterBreaking_bottomLine = na

var line retest_topLine = na
var line retest_bottomLine = na

if showRangeAfterBreaking
    line.delete(afterBreaking_topLine)
    line.delete(afterBreaking_bottomLine)
    
    afterBreaking_topLine := line.new(x1=bar_index[1], y1=rangeAfterBreaking_top, x2=bar_index, y2=rangeAfterBreaking_top, extend=extend.both, style=line.style_dashed, color=color.red)
    afterBreaking_bottomLine := line.new(x1=bar_index[1], y1=rangeAfterBreaking_bottom, x2=bar_index, y2=rangeAfterBreaking_bottom, extend=extend.both, style=line.style_dashed, color=color.green)
    
if showRetestLine
    line.delete(retest_topLine)
    line.delete(retest_bottomLine)
    
    retest_topLine := line.new(x1=bar_index[1], y1=retestLevel_top, x2=bar_index, y2=retestLevel_top, extend=extend.both, style=line.style_dashed, color=color.purple)
    retest_bottomLine := line.new(x1=bar_index[1], y1=breakedFractal_bottom, x2=bar_index, y2=breakedFractal_bottom, extend=extend.both, style=line.style_dashed, color=color.blue)

Overview

Order Fractals strategy V3 detects breaks of fractal levels and plots post-break ranges along with retest lines and signals. Entries occur on retest signals, with pyramiding allowing multiple simultaneous positions. Settings adjust fractal periods, retest distances, post-break zones, and visual options for fractals and ranges. The script draws all elements directly on the price chart. It supports custom fractal types such as high or close and tracks a specified number of prior fractals for context.

Details

Published by

DaniilOkrug on GitHub

Code credit

icewalk, as written in the script's header

Type

Strategy, Pine Script v4

Draws

On the price chart

Category

Support & resistance, Breakout, Trend

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

  • The strategy can add several entries in the same direction

Settings

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

SettingTypeDefaultVariable
Период крупных фракталовint2n
Период меньших фракталовint2n_additional
Тип верхнего фракталаstringhighupFractalType
Тип нижнего фракталаstringlowdownFractalType
Количество отслеживаемых фракталов назадint1numberFs
Процент дистанции ретеста(%)float2levelRetestPercent
Верхний уровень после пробития(%)float15afterBeaking_bottomRangePercent
Нижний уровень после пробития(%)float15afterBeaking_topRangePercent
Показать крупные фракталыbooltrueshowMainFractals
Показать меньшие фракталыboolfalseshowAdditionalFractals
Показать линии дипозона фракталов после пробитияbooltrueshowRangeAfterBreaking
Показать уровень для ретестаbooltrueshowRetestLine
Show all 14 settings
SettingTypeDefaultVariable
Показать сигнал ретестаbooltrueshowRetestSignal
РетестbooltrueshowRetestAlert
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

This trend-following strategy executes a classic Donchian channel breakout system designed to cross-validate backtest results against external framework benchmarks. It triggers a long entry when the closing price breaks above the highest high of the prior entr

Strategy v6 BreakoutTrend
Updated today · AGPL-3.0 GitHub repository of Forven S01509 - Simple Donchian 20/10 Breakout
257 stars

This strategy plots running pivot highs as red R circles and pivot lows as blue S circles directly on the price chart. It computes an EMA 3 and a Cto trend line from close prices, then generates long signals on upward EMA-Cto crossovers combined with price pos

Strategy v6 TrendMoving averages Repaints
Updated 6 weeks ago · None stated GitHub repository of Best Chart 1m Strategy Candle Bar
106 stars

Calculates multi-period logarithmic regression trend channels and deviation bands across up to twenty selectable lookback lengths directly on the price chart. It evaluates channel slopes and Pearson's correlation coefficient to detect market trends and generat

Strategy v5 TrendSupport & resistance Repaints
Updated 2 years ago · GPL-3.0 GitHub repository of Advanced Trend Detection Strategy

This trend breakout strategy plots Donchian Channels consisting of upper, lower, and middle bands directly on the main price chart. Long positions enter when price touches the upper channel and pulls back to or below the middle band, placing a stop loss at the

Strategy v6 TrendBreakout
Updated 2 months ago · MPL-2.0 GitHub repository of Donchian Strategy - Dynamic TP, Fixed SL, 1% Risk, Daily Target
43 stars

This strategy executes trades on short-term cryptocurrency charts using a combination of pivot support and resistance levels and a multi-pole smoothed trend filter. Entries trigger when price crosses the smoothed trend line and confirms above or below a short-

Strategy v5 TrendBreakout Repaints
Updated 2 years ago · None stated GitHub repository of SOL 1m - Strategy Candle Bar

More strategys

Trade Your Charts With a Regulated Broker

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

Compare brokers