Strategy · Pine Script v4 · On the chart

2Tier Ichimoku Pyramiding [Takazudo]

by hasnocool

This overlay strategy plots a two-timeframe Ichimoku setup on the price chart, with Tenkan, Kijun, Chikou, and Kumo from a base higher timeframe and an optional highest-timeframe cloud.

View on GitHub

GitHub stars106on the repository
Pine versionv4older, still runs
Lines of code918
Settings33inputs
LicenceGPL-3.0
Last update2 years ago18 Sep 2024

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

918 lines of Pine Script v4 from 2Tier Ichimoku Pyramiding [Takazudo].pine, published under GPL-3.0. Keep the author's credit and licence lines when you reuse it.

2Tier Ichimoku Pyramiding [Takazudo].pine
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// https://www.tradingview.com/script/UhhFWEus-MTF-Ichimoku-Takazudo/
//@version=4
//@author=Takazudo
strategy("2Tier Ichimoku Pyramiding [Takazudo]",
  pyramiding=2,
  overlay=true,
  default_qty_type=strategy.fixed,
  initial_capital=0,
  currency=currency.USD)
//============================================================================
// consts, inputs
//============================================================================
// colors
var COLOR_KIJUN = color.new(#fcb103, 20)
var COLOR_TENKAN = color.new(#f57f17, 20)
var COLOR_CHIKOU = color.new(#ffffff, 50)
var COLOR_KUMO_BASEHTF_BULL = color.new(#315F2E, 60)
var COLOR_KUMO_BASEHTF_BEAR = color.new(#802A1C, 60)
var COLOR_KUMO_HIGHESTTF_BULL = color.new(#1D4F8A, 60)
var COLOR_KUMO_HIGHESTTF_BEAR = color.new(#6B2B55, 60)
var COLOR_SENKOUA_BASEHTF = color.new(#315F2E, 30)
var COLOR_SENKOUB_BASEHTF = color.new(#802A1C, 30)
var COLOR_SENKOUA_HIGHESTTF = color.new(#1D4F8A, 30)
var COLOR_SENKOUB_HIGHESTTF = color.new(#6B2B55, 30)
var COLOR_CROSS_POINT_BULL = color.new(#315F2E, 20)
var COLOR_CROSS_POINT_BEAR = color.new(#802A1C, 20)
var COLOR_CHIKOU_CROSS_POINT_BULL = color.new(#315F2E, 20)
var COLOR_CHIKOU_CROSS_POINT_BEAR = color.new(#802A1C, 20)
var COLOR_CHIKOU_KUMO_BREAKOUT_BULL = color.new(#315F2E, 0)
var COLOR_CHIKOU_KUMO_BREAKOUT_BEAR = color.new(#802A1C, 0)
var COLOR_CHIKOU_HINT_BULL = color.new(#315F2E, 0)
var COLOR_CHIKOU_HINT_BEAR = color.new(#802A1C, 0)
var COLOR_SENKOU_CROSS_HINT_BULL = color.new(#315F2E, 0)
var COLOR_SENKOU_CROSS_HINT_BEAR = color.new(#802A1C, 0)
var COLOR_TENKAN_CROSS_BG = color.new(#f2931d, 90)
var COLOR_CHIKOU_BREAKOUT_BG = color.new(#656565, 90)
var COLOR_SENKOU_CROSS_BG = color.new(#7a73d8, 90)
var COLOR_GAP_KUMO = color.new(#FCC02C, 97)
var COLOR_RANGE_EDGE = color.new(#43A6F5, 30)
var COLOR_RESISTANCE_PRICE_LINE = color.new(#e0f64d, 20)
var COLOR_TRANSPARENT = color.new(#000000, 100)
// HTF
var _1 = input(true, "═════════ HTF ══════════")
var config_baseHtf = input("D", "Base Higher Timeframe", type = input.resolution)
var config_useHighestTf = input(true, "use Highest Timeframe (Kumo only)")
var config_highestTf= input("W", "Highest Timeframe", type = input.resolution)
var _2 = input(true, "═════════ Ichimoku ══════════")
var config_tenkanSen = input(9, minval=1, title="Tenkan-Sen Bars")
var config_kijunSen = input(26, minval=1, title="Kijun-Sen Bars")
var config_senkouSpanB = input(52, minval=1, title="Senkou-Span B Bars")
var config_chikouSpan = input(26, minval=1, title="Chikou-Span Offset")
var config_senkouSpan = input(26, minval=1, title="Senkou-Span Offset")
var _3 = input(true, "═════════ Smooth Line ══════════")
var config_useSmooth = input(true, "enable smooth line")
var config_smoothFactor = input(2, minval=2, title="smooth factor")
var _4 = input(true, "═════════ MTF stuff ══════════")
var config_autoSwitchToHtf = input(true, "avoid to refer lower resolution indicator")
var config_avoidTooHighResolution = input(true, "avoid to refer too high resolution indicator")
var config_useGapKumo = input(true, "use Gap Kumo")
var _5 = input(true, "═════════ etc ══════════")
var config_bullDetectBars = input(defval = 3, title = "bull detection min bar count",  minval = 1)
var config_rangeDetectBars = input(defval = 200, title = "range detection bar count",  minval = 1)
var config_recentBars = input(defval = 50, title = "recent bar count for SL",  minval = 1)
var config_atrLength = input(4, title = "Trailing stop ATR Length")
var config_atrSlMult = input(1, title = "Trailing stop ATR Multiple factor", type=input.float)
var config_atrEntryPaddingMult = input(0.5, title = "Entry padding ATR Multiple factor", type=input.float)
var config_atrEntryPaddingLength = input(10, title = "Entry padding ATR Length")
var config_extraEntryStopDetectBars = input(defval = 10, title = "Pyramiding entry recent detect bar count",  minval = 1)
var _6 = input(true, "═════════ Backtesting range ══════════")
// From Date Inputs
fromYear  = input(defval = 2019, title = "From Year",  minval = 1970)
fromMonth = input(defval = 1,    title = "From Month", minval = 1, maxval = 12)
fromDay   = input(defval = 1,    title = "From Day",   minval = 1, maxval = 31)
// To Date Inputs
toYear  = input(defval = 2021, title = "To Year",  minval = 1970)
toMonth = input(defval = 3,    title = "To Month", minval = 1, maxval = 12)
toDay   = input(defval = 10,    title = "To Day",   minval = 1, maxval = 31)
//============================================================================
// MTF Selection Framework
// http://www.pinecoders.com/faq_and_code/#other-intervals-mtf
//============================================================================
// ————— Converts current "timeframe.multiplier" plus the TF into minutes of type float.
f_resInMinutes() =>
    _resInMinutes = timeframe.multiplier * (
      timeframe.isseconds ? 1. / 60. :
      timeframe.isminutes ? 1.       :
      timeframe.isdaily   ? 1440.    :
      timeframe.isweekly  ? 10080.   :
      timeframe.ismonthly ? 43800.   : na)
// ————— Returns resolution of _resolution period in minutes.
f_tfResInMinutes(_res) =>
    // _res: resolution of any TF (in "timeframe.period" string format).
    security(syminfo.tickerid, _res, f_resInMinutes())
// ————— Given current resolution, returns next step of HTF.
f_resNextStep(_res) =>
    // _res: current TF in fractional minutes.
    _res    <= 1        ? "15"  :
      _res  <= 5        ? "60"  :
      _res  <= 30       ? "240" :
      _res  <= 60       ? "1D"  :
      _res  <= 360      ? "3D"  :
      _res  <= 1440     ? "1W"  :
      _res  <= 10080    ? "1M"  : "12M"
// ————— Returns a multiple of current resolution as a string in "timeframe.period" format usable with "security()".
f_multipleOfRes(_res, _mult) =>
    // _res:  current resolution in minutes, in the fractional format supplied by f_resInMinutes() companion function.
    // _mult: Multiple of current TF to be calculated.
    // Convert current float TF in minutes to target string TF in "timeframe.period" format.
    _targetResInMin = _res * max(_mult, 1)
    // Find best string to express the resolution.
    _targetResInMin   <= 0.083 ? "5S"  :
      _targetResInMin <= 0.251 ? "15S" :
      _targetResInMin <= 0.501 ? "30S" :
      _targetResInMin <= 1440  ? tostring(round(_targetResInMin)) :
      _targetResInMin <= 43800 ? tostring(round(min(_targetResInMin / 1440, 365))) + "D" :
      tostring(round(min(_targetResInMin / 43800, 12))) + "M"
// ————— Converts a resolution expressed in float minutes into a string usable by "security()".
// See our FAQ & Code for an example of using this function: http://www.pinecoders.com/faq_and_code/#how-can-i-convert-a-resolution-in-float-minutes-into-a-string-usable-with-security
f_resFromMinutes(_minutes) =>
    _minutes     <= 0.0167       ? "1S"  :
      _minutes   <= 0.0834       ? "5S"  :
      _minutes   <= 0.2500       ? "15S" :
      _minutes   <= 0.5000       ? "30S" :
      _minutes   <= 1440         ? tostring(round(_minutes)) :
      _minutes   <= 43800        ? tostring(round(min(_minutes / 1440, 365))) + "D" :
      tostring(round(min(_minutes / 43800, 12))) + "M"
// Returns the theoretical numbers of current chart bars in the given target HTF resolution (note that this number maybe very different from actual number on certain symbols).
f_theoreticalDilationOf(_res) =>
    // _res: resolution of any TF (in "timeframe.period" string format).
    f_tfResInMinutes(_res) / f_resInMinutes()
// Returns the average number of current chart bars in the given target HTF resolution (this reflects the dataset's history).
f_avgDilationOf(_res) =>
    // _res: resolution of any TF (in "timeframe.period" string format).
    b = barssince(change(time(_res)))
    cumTotal = cum(b == 0 ? b[1] + 1 : 0)
    cumCount = cum(b == 0 ? 1 : 0)
    cumTotal / cumCount
// ————— Print a label at end of chart.
f_htfLabel(_txt, _y, _color, _offsetLabels) =>
    _t = int(time + (f_resInMinutes() * _offsetLabels * 60000))
    // Create the label on the dataset's first bar.
    var _lbl = label.new(_t, _y, _txt, xloc.bar_time, yloc.price, #00000000, label.style_none, color.gray, size.large)
    if barstate.islast
        // Rather than delete and recreate the label on every realtime bar update,
        // simply update the label's information; it's more efficient.
        label.set_xy(_lbl, _t, _y)
        label.set_text(_lbl, _txt)
        label.set_textcolor(_lbl, _color)
// }
//============================================================================
// utils, setup
//============================================================================
// initialize
var tenkanLine_baseHtf = 0.0
var kijunLine_baseHtf = 0.0
var senkouALine_baseHtf = 0.0
var senkouBLine_baseHtf = 0.0
var tenkanLine_highestTf = 0.0
var kijunLine_highestTf = 0.0
var senkouALine_highestTf = 0.0
var senkouBLine_highestTf = 0.0
var gapKumo_high = 0.0
var gapKumo_low = 0.0
f_isUsingHtf() =>
    _current = f_resInMinutes()
    _target = f_tfResInMinutes(config_baseHtf)
    _current < _target
f_isOverHtf() =>
    _current = f_resInMinutes()
    _target = f_tfResInMinutes(config_baseHtf)
    _current > _target
f_isOverHighestTf() =>
    _current = f_resInMinutes()
    _target = f_tfResInMinutes(config_highestTf)
    _current >= _target
f_shouldAvoidHighestTf(barsMultipiller) =>
    // it the resolution was too high, requested candle sticks
    // hit the limit of trading view.
    // this function detects the limit
    config_avoidTooHighResolution and barsMultipiller > 150
var useSmooth = f_isUsingHtf() and config_useSmooth
f_smooth(_series) =>
    _f = config_smoothFactor
    // Tricky part. the lines that refers higher Timeframe got zig-zag
    // because the granularity of the value per bar is the same
    // inside the higher timeframe's one bar length.
    // This smooth factor blends the value with previous values using ema.
    _smoothed = ema(ema(ema(_series, _f), _f), _f)
    useSmooth ? _smoothed : _series
lostPositionsInPrevBar = strategy.position_size == 0 and (strategy.position_size[0] != strategy.position_size[1])
// remember entry price
var previousEntryPrice = hl2
//============================================================================
// entry quantity caliculation
// wider SL = less quantities
//============================================================================
f_calcQtyForInitialEntry(_percentage) =>
    if _percentage < 1
        10000
    else if _percentage < 2
        8000
    else if _percentage < 3
        6000
    else
        4000
f_calcQtyForExtraEntry(_percentage) =>
    if _percentage < 1
        5000
    else if _percentage < 2
        4000
    else if _percentage < 3
        3000
    else
        2000
//============================================================================
// candle actions
//============================================================================
f_isUpDoji() =>
    fullPriceHeight = high-low
    bodyPriceHeight = abs(close-open)
    (bodyPriceHeight < fullPriceHeight * 1/7) and (max(open, close) > (low + (high-low) * 2/3))
f_isDownDoji() =>
    fullPriceHeight = high-low
    bodyPriceHeight = abs(close-open)
    (bodyPriceHeight < fullPriceHeight * 1/7) and (min(open, close) < (high - (high-low) * 2/3))
f_isLastCandleUp() =>
    result = false
    (close > open) or f_isUpDoji()
f_isLastCandleDown() =>
    result = false
    (close < open) or f_isDownDoji()
//============================================================================
// Ichimoku calcs
//============================================================================
f_donchian(len) =>
    avg(lowest(len), highest(len))
f_tenkan() =>
    f_donchian(config_tenkanSen)
f_kijun() =>
    f_donchian(config_kijunSen)
f_senkouA(_tenkan, _kijun) =>
    avg(_tenkan, _kijun)
f_senkouB() =>
    f_donchian(config_senkouSpanB)
barsMultipiller_baseHtf = f_isOverHtf() ? 1 : f_theoreticalDilationOf(config_baseHtf)
barsMultipiller_highestTf = f_isOverHighestTf() ? 1 : f_theoreticalDilationOf(config_highestTf)
shouldAvoidHighestTf = f_shouldAvoidHighestTf(barsMultipiller_highestTf)
f_calcUseHighestTf() =>
    _result = true
    if shouldAvoidHighestTf
        _result := false
    else
        if config_useHighestTf
            if f_isOverHighestTf()
                _result := false
            else
                _result := true
    _result
var useHighestTf = f_calcUseHighestTf()
senkouOffset = config_senkouSpan - 1
chikouOffset = -config_chikouSpan + 1
senkouOffset_baseHtf = round((config_senkouSpan - 1) * barsMultipiller_baseHtf)
chikouOffset_baseHtf = round((config_chikouSpan - 1) * barsMultipiller_baseHtf)
senkouOffsetForPlot_baseHtf = round(senkouOffset * barsMultipiller_baseHtf)
chikouOffsetForPlot_baseHtf = round(-chikouOffset_baseHtf)
senkouOffset_highestTf = useHighestTf ? round((config_senkouSpan - 1) * barsMultipiller_highestTf) : 0
chikouOffset_highestTf = useHighestTf ? round((config_chikouSpan - 1) * barsMultipiller_highestTf) : 0
senkouOffsetForPlot_highestTf = useHighestTf ? round(senkouOffset * barsMultipiller_highestTf) : 0
chikouOffsetForPlot_highestTf = useHighestTf ? round(-chikouOffset_highestTf) : 0
senkouSpanIndexDiff = senkouOffsetForPlot_highestTf - senkouOffsetForPlot_baseHtf
// not sure why but it says negative index was detected
if senkouSpanIndexDiff < 0
    senkouSpanIndexDiff := 0
if not useHighestTf or not config_useGapKumo
    senkouSpanIndexDiff := 0
f_calcIchimoku_baseHtf() =>
    _useCurrentRes = config_autoSwitchToHtf and f_isOverHtf()
    _tenkan = f_tenkan()
    _kijun = f_kijun()
    _senkouA = f_senkouA(_tenkan[0], _kijun[0])
    _senkouB = f_senkouB()
    _htfTenkan = _useCurrentRes ? _tenkan : security(syminfo.tickerid, config_baseHtf, _tenkan)
    _htfKijun = _useCurrentRes ? _kijun : security(syminfo.tickerid, config_baseHtf, _kijun)
    _htfSenkouA = _useCurrentRes ? _senkouA : security(syminfo.tickerid, config_baseHtf, _senkouA)
    _htfSenkouB = _useCurrentRes ? _senkouB : security(syminfo.tickerid, config_baseHtf, _senkouB)
    [_htfTenkan, _htfKijun, _htfSenkouA, _htfSenkouB]
f_calcIchimoku_highestTf() =>
    _tenkan = f_tenkan()
    _kijun = f_kijun()
    _senkouA = f_senkouA(_tenkan[0], _kijun[0])
    _senkouB = f_senkouB()
    _highestTfTenkan = useHighestTf ? security(syminfo.tickerid, config_highestTf, _tenkan) : _tenkan
    _highestTfKijun = useHighestTf ? security(syminfo.tickerid, config_highestTf, _kijun) : _kijun
    _highestTfSenkouA = useHighestTf ? security(syminfo.tickerid, config_highestTf, _senkouA) : _senkouA
    _highestTfSenkouB = useHighestTf ? security(syminfo.tickerid, config_highestTf, _senkouB) : _senkouB
    [_highestTfTenkan, _highestTfKijun, _highestTfSenkouA, _highestTfSenkouB]
//--------------------------------------
// HTF Ichimoku values
[_htfTenkan, _htfKijun, _htfSenkouA, _htfSenkouB] = f_calcIchimoku_baseHtf()
tenkanLine_baseHtf := _htfTenkan
kijunLine_baseHtf := _htfKijun
senkouALine_baseHtf := _htfSenkouA
senkouBLine_baseHtf := _htfSenkouB
//--------------------------------------
// Highest TF Ichimoku values
[_highestTfTenkan, _highestTfKijun, _highestTfSenkouA, _highestTfSenkouB] = f_calcIchimoku_highestTf()
tenkanLine_highestTf := _highestTfTenkan
kijunLine_highestTf := _highestTfKijun
senkouALine_highestTf := _highestTfSenkouA
senkouBLine_highestTf := _highestTfSenkouB
f_calcIchimokuSignals_baseHtf() =>
    var _chikouAboveCandle = false
    var _chikouBelowCandle = false
    var _chikouAboveKumo = false
    var _chikouBelowKumo = false
    _kumoColor_bull = senkouALine_baseHtf > senkouBLine_baseHtf
    _senkouCross_bull = crossover(senkouALine_baseHtf, senkouBLine_baseHtf)
    _senkouCross_bear = crossover(senkouBLine_baseHtf, senkouALine_baseHtf)
    _senkouSpanHigh = max(senkouALine_baseHtf[senkouOffset_baseHtf], senkouBLine_baseHtf[senkouOffset_baseHtf])
    _senkouSpanLow = min(senkouALine_baseHtf[senkouOffset_baseHtf], senkouBLine_baseHtf[senkouOffset_baseHtf])
    _chikouKumoHigh = max(senkouALine_baseHtf[senkouOffset_baseHtf+chikouOffset_baseHtf], senkouBLine_baseHtf[senkouOffset_baseHtf+chikouOffset_baseHtf])
    _chikouKumoLow = min(senkouALine_baseHtf[senkouOffset_baseHtf+chikouOffset_baseHtf], senkouBLine_baseHtf[senkouOffset_baseHtf+chikouOffset_baseHtf])
    _tenkanCross_bull = crossover(tenkanLine_baseHtf, kijunLine_baseHtf)
    _tenkanCross_bear = crossover(kijunLine_baseHtf, tenkanLine_baseHtf)
    _tenkanAboveKijun = tenkanLine_baseHtf > kijunLine_baseHtf
    _tenkanBelowKijun = tenkanLine_baseHtf < kijunLine_baseHtf
    _chikouAboveCandle := close > close[chikouOffset_baseHtf]
    _chikouBelowCandle := close < close[chikouOffset_baseHtf]
    _chikouCross_bull = _chikouAboveCandle and not _chikouAboveCandle[1]
    _chikouCross_bear = _chikouBelowCandle and not _chikouBelowCandle[1]
    _chikouAboveKumo := close > _chikouKumoHigh
    _chikouBelowKumo := close < _chikouKumoLow
    _currentInKumo = (_senkouSpanLow <= close) and (close <= _senkouSpanHigh)
    _currentTouchingKumo = not _currentInKumo and
      (((low <= _senkouSpanHigh) and (low >= _senkouSpanLow)) or
      ((high >= _senkouSpanLow) and (high <= _senkouSpanHigh)))
    _currentAboveKumo = close > _senkouSpanHigh
    _currentBelowKumo = close < _senkouSpanLow
    _chikouInKumo = (_chikouKumoLow <= close) and (close <= _chikouKumoHigh)
    _chikouTouchingKumo = not _chikouInKumo and
      (((low <= _chikouKumoHigh) and (low >= _chikouKumoLow)) or
      ((high >= _chikouKumoLow) and (high <= _chikouKumoHigh)))
    _chikouKumoBreakout_bull = _chikouAboveKumo and not _chikouAboveKumo[1]
    _chikouKumoBreakout_bear = _chikouBelowKumo and not _chikouBelowKumo[1]
    [_currentInKumo, _currentTouchingKumo, _kumoColor_bull, _senkouCross_bull, _senkouCross_bear,
      _senkouSpanHigh, _senkouSpanLow,
      _chikouKumoHigh, _chikouKumoLow,
      _chikouAboveCandle, _chikouBelowCandle,
      _tenkanCross_bull, _tenkanCross_bear,
      _tenkanAboveKijun, _tenkanBelowKijun,
      _chikouCross_bull, _chikouCross_bear,
      _chikouAboveKumo, _chikouBelowKumo,
      _chikouKumoBreakout_bull, _chikouKumoBreakout_bear,
      _currentAboveKumo, _currentBelowKumo,
      _chikouInKumo, _chikouTouchingKumo]
f_calcIchimokuSignals_highestTf() =>
    var _chikouAboveCandle = false
    var _chikouBelowCandle = false
    var _chikouAboveKumo = false
    var _chikouBelowKumo = false
    _kumoColor_bull = senkouALine_highestTf > senkouBLine_highestTf
    _senkouCross_bull = crossover(senkouALine_highestTf, senkouBLine_highestTf)
    _senkouCross_bear = crossover(senkouBLine_highestTf, senkouALine_highestTf)
    _senkouSpanCurrentHigh = max(senkouALine_highestTf[senkouOffset_highestTf], senkouBLine_highestTf[senkouOffset_highestTf])
    _senkouSpanCurrentLow = min(senkouALine_highestTf[senkouOffset_highestTf], senkouBLine_highestTf[senkouOffset_highestTf])
    _chikouKumoHigh = max(senkouALine_highestTf[senkouOffset_highestTf+chikouOffset_highestTf], senkouBLine_highestTf[senkouOffset_highestTf+chikouOffset_highestTf])
    _chikouKumoLow = min(senkouALine_highestTf[senkouOffset_highestTf+chikouOffset_highestTf], senkouBLine_highestTf[senkouOffset_highestTf+chikouOffset_highestTf])
    _tenkanCross_bull = crossover(tenkanLine_highestTf, kijunLine_highestTf)
    _tenkanCross_bear = crossover(kijunLine_highestTf, tenkanLine_highestTf)
    _chikouAboveCandle := close > close[chikouOffset_highestTf]
    _chikouBelowCandle := close < close[chikouOffset_highestTf]
    _chikouCross_bull = _chikouAboveCandle and not _chikouAboveCandle[1]
    _chikouCross_bear = _chikouBelowCandle and not _chikouBelowCandle[1]
    _chikouAboveKumo := close > _chikouKumoHigh
    _chikouBelowKumo := close < _chikouKumoLow
    _chikouKumoBreakout_bull = _chikouAboveKumo and not _chikouAboveKumo[1]
    _chikouKumoBreakout_bear = _chikouBelowKumo and not _chikouBelowKumo[1]
    _currentAboveKumo = close > _senkouSpanCurrentHigh
    _currentBelowKumo = close < _senkouSpanCurrentLow
    [_kumoColor_bull, _senkouCross_bull, _senkouCross_bear,
      _senkouSpanCurrentHigh, _senkouSpanCurrentLow,
      _chikouKumoHigh, _chikouKumoLow,
      _chikouAboveCandle, _chikouBelowCandle,
      _tenkanCross_bull, _tenkanCross_bear,
      _chikouCross_bull, _chikouCross_bear,
      _chikouAboveKumo, _chikouBelowKumo,
      _chikouKumoBreakout_bull, _chikouKumoBreakout_bear,
      _currentAboveKumo, _currentBelowKumo]
f_calcGapKumo(_tf1_senkouA, _tf1_senkouB, _tf2_senkouA, _tf2_senkouB) =>
    _max = max(_tf1_senkouA, _tf1_senkouB, _tf2_senkouA, _tf2_senkouB)
    _tf1IsHigher = (_tf1_senkouA == _max) or (_tf1_senkouB == _max)
    _kumoA_max = _tf1IsHigher ? max(_tf1_senkouA, _tf1_senkouB) : max(_tf2_senkouA, _tf2_senkouB)
    _kumoA_min = _tf1IsHigher ? min(_tf1_senkouA, _tf1_senkouB) : min(_tf2_senkouA, _tf2_senkouB)
    _kumoB_max = _tf1IsHigher ? max(_tf2_senkouA, _tf2_senkouB) : max(_tf1_senkouA, _tf1_senkouB)
    _kumoB_min = _tf1IsHigher ? min(_tf2_senkouA, _tf2_senkouB) : min(_tf1_senkouA, _tf1_senkouB)
    _kumoCrossed = false
    _gapKumo_high = max(_kumoA_max, _kumoB_max)
    _gapKumo_low = _gapKumo_high
    if _kumoA_max > _kumoB_max
        if _kumoA_min < _kumoB_max
            _kumoCrossed := true
        else
            _gapKumo_high := _kumoA_min
            _gapKumo_low := _kumoB_max
    else
        if _kumoB_min < _kumoA_max
            _kumoCrossed := true
        else
            _gapKumo_high := _kumoB_min
            _gapKumo_low := _kumoA_max
    [_kumoCrossed, _gapKumo_high, _gapKumo_low]
//============================================================================
// calc Ichimoku values for plot
//============================================================================
//--------------------------------------
// HTF Ichimoku signals
[currentInKumo_baseHtf, _, kumoColor_bull_baseHtf, _, _,
  senkouSpanHigh_baseHtf, senkouSpanLow_baseHtf,
  _, _,
  chikouAboveCandle_baseHtf, chikouBelowCandle_baseHtf,
  _, _,
  tenkanAboveKijun_baseHtf, tenkanBelowKijun_baseHtf,
  _, _,
  chikouAboveKumo_baseHtf, chikouBelowKumo_baseHtf,
  _, _,
  currentAboveKumo_baseHtf, currentBelowKumo_baseHtf,
  _, _] = f_calcIchimokuSignals_baseHtf()
//--------------------------------------
// Highest TF Ichimoku signals
[kumoColor_bull_highestTf, senkouCross_bull_highestTf, senkouCross_bear_highestTf,
  senkouSpanHigh_highestTf, senkouSpanLow_highestTf,
  _, _,
  _, _,
  tenkanCross_bull_highestTf, tenkanCross_bear_highestTf,
  chikouCross_bull_highestTf, chikouCross_bear_highestTf,
  _, _,
  chikouKumoBreakout_bull_highestTf, chikouKumoBreakout_bear_highestTf,
  currentAboveKumo_highestTf, currentBelowKumo_highestTf] = f_calcIchimokuSignals_highestTf()
//--------------------------------------
// smooth lines
smooth_tenkanLine_baseHtf = f_smooth(tenkanLine_baseHtf)
smooth_kijunLine_baseHtf = f_smooth(kijunLine_baseHtf)
smooth_senkouALine_baseHtf = f_smooth(senkouALine_baseHtf)
smooth_senkouBLine_baseHtf = f_smooth(senkouBLine_baseHtf)
//smooth_tenkanLine_highestTf = f_smooth(tenkanLine_highestTf)
//smooth_kijunLine_highestTf = f_smooth(kijunLine_highestTf)
smooth_senkouALine_highestTf = f_smooth(senkouALine_highestTf)
smooth_senkouBLine_highestTf = f_smooth(senkouBLine_highestTf)
//--------------------------------------
// gap kumo
//max_bars_back(senkouALine_highestTf, 600)
//max_bars_back(senkouBLine_highestTf, 600)
[_, _gapKumo_high, _gapKumo_low] = f_calcGapKumo(
  senkouALine_baseHtf,
  senkouBLine_baseHtf,
  senkouALine_highestTf[senkouSpanIndexDiff],
  senkouBLine_highestTf[senkouSpanIndexDiff])
gapKumo_high := _gapKumo_high
gapKumo_low := _gapKumo_low
smooth_gapKumo_high = f_smooth(gapKumo_high)
smooth_gapKumo_low = f_smooth(gapKumo_low)
//============================================================================
// plot stuffs
//============================================================================
// gap kumo
val_gapKumo_high = useHighestTf and config_useGapKumo ? smooth_gapKumo_high : na
val_gapKumo_low = useHighestTf and config_useGapKumo ? smooth_gapKumo_low : na
plot_gapKumo_high = plot(val_gapKumo_high,
  offset=senkouOffsetForPlot_baseHtf,
  color=COLOR_TRANSPARENT,
  transp=0,
  linewidth=1,
  title="Gap Kumo High")
plot_gapKumo_low = plot(val_gapKumo_low,
  offset=senkouOffsetForPlot_baseHtf,
  color=COLOR_TRANSPARENT,
  transp=0,
  linewidth=1,
  title="Gap Kumo LOW")
fill(plot_gapKumo_high, plot_gapKumo_low,
  color=COLOR_GAP_KUMO,
  transp=0,
  title="Gap Kumo")
// kumo HighestTF
plotVal_senkouA_highestTf = useHighestTf ? smooth_senkouALine_highestTf : na
plotVal_senkouB_highestTf = useHighestTf ? smooth_senkouBLine_highestTf : na
color_kumo_highestTf = kumoColor_bull_highestTf ? COLOR_KUMO_HIGHESTTF_BULL : COLOR_KUMO_HIGHESTTF_BEAR
plot_senkouA_highestTf = plot(plotVal_senkouA_highestTf,
  offset=senkouOffsetForPlot_highestTf,
  color=COLOR_SENKOUA_HIGHESTTF,
  transp=0,
  linewidth=1,
  title="Highest TFSenkou-Span A")
plot_senkouB_highestTf = plot(plotVal_senkouB_highestTf,
  offset=senkouOffsetForPlot_highestTf,
  color=COLOR_SENKOUB_HIGHESTTF,
  transp=0,
  linewidth=1,
  title="Highest TFSenkou-Span B")
fill(plot_senkouA_highestTf, plot_senkouB_highestTf,
  color=color_kumo_highestTf,
  transp=0,
  title="Highest TF Kumo")
// kumo HTF
color_kumo_baseHtf = kumoColor_bull_baseHtf ? COLOR_KUMO_BASEHTF_BULL : COLOR_KUMO_BASEHTF_BEAR
plot_senkouA_baseHtf = plot(smooth_senkouALine_baseHtf,
  offset=senkouOffsetForPlot_baseHtf,
  color=COLOR_SENKOUA_BASEHTF,
  transp=0,
  linewidth=1,
  title="Base HTF: Senkou-Span A")
plot_senkouB_baseHtf = plot(smooth_senkouBLine_baseHtf,
  offset=senkouOffsetForPlot_baseHtf,
  color=COLOR_SENKOUB_BASEHTF,
  transp=0,
  linewidth=1,
  title="Base HTF: Senkou-Span B")
fill(plot_senkouA_baseHtf, plot_senkouB_baseHtf,
  color=color_kumo_baseHtf,
  transp=0,
  title="Base HTF Kumo")
// chikou
plot(close,
  offset=chikouOffsetForPlot_baseHtf,
  color=COLOR_CHIKOU,
  linewidth=1,
  transp=0,
  title="Chikou-Span")
// tenkan & kijun
plot(smooth_tenkanLine_baseHtf,
  color=COLOR_TENKAN,
  linewidth=1,
  transp=0,
  title="Tenkan-Sen")
plot(smooth_kijunLine_baseHtf,
  color=COLOR_KIJUN,
  linewidth=3,
  transp=0,
  title="Kijun-Sen")
//============================================================================
// backtest duration
//============================================================================
// Calculate start/end date and time condition
startDate  = timestamp(fromYear, fromMonth, fromDay, 00, 00)
finishDate = timestamp(toYear,   toMonth,   toDay,   00, 00)
//============================================================================
// bullish / bearish detection
//============================================================================
var bullish = false
var bearish = false
// detect bullish or bearish by many incidents
bullish := kumoColor_bull_baseHtf and chikouAboveCandle_baseHtf and
  tenkanAboveKijun_baseHtf and chikouAboveKumo_baseHtf and
  currentAboveKumo_baseHtf and currentAboveKumo_highestTf
bearish := not kumoColor_bull_baseHtf and chikouBelowCandle_baseHtf and
  tenkanBelowKijun_baseHtf and chikouBelowKumo_baseHtf and
  currentBelowKumo_baseHtf and currentBelowKumo_highestTf
// calc continuous bullish or bearish
f_isContinuousBull() =>
    inTrend = 0
    for i = 0 to (config_bullDetectBars-1)
        if bullish[i]
            inTrend := inTrend + 1
    inTrend == config_bullDetectBars
f_isContinuousBear() =>
    inTrend = 0
    for i = 0 to (config_bullDetectBars-1)
        if bearish[i]
            inTrend := inTrend + 1
    inTrend == config_bullDetectBars
continuousBull = f_isContinuousBull()
continuousBear = f_isContinuousBear()
//============================================================================
// MACD
//============================================================================
f_isMacdUpTrend() =>
    [_macdLine, _signalLine, _] = macd(close, 12, 26, 9)
    _upTrend = _macdLine > _signalLine
// calc macd for entry
macdUpTrend = f_isMacdUpTrend()
macdDownTrend = not macdUpTrend
//============================================================================
// recent high / low
//============================================================================
f_calcRecentHigh() =>
    startIndex = 1
    highest = max(open[startIndex], close[startIndex])
    for i = startIndex to (config_recentBars - 1)
        current = max(open[i], close[i])
        if highest < current
            highest := current
    highest
f_calcRecentLow() =>
    startIndex = 1
    lowest = min(open[startIndex], close[startIndex])
    for i = startIndex to (config_recentBars - 1)
        current = min(open[i], close[i])
        if lowest > current
            lowest := current
    lowest
recentHigh = f_calcRecentHigh()
recentLow = f_calcRecentLow()
//============================================================================
// ATR based stuff
//============================================================================
entryPadding = config_atrEntryPaddingMult * atr(config_atrEntryPaddingLength)
sl_val = config_atrSlMult * atr(config_atrLength)
atrSl_long = low - sl_val
atrSl_short = high + sl_val
//============================================================================
// Kumo based SL
//============================================================================
kumoBasedSlLong = (senkouSpanHigh_baseHtf + atrSl_long) / 2
kumoBasedSlShort = (senkouSpanLow_baseHtf + atrSl_short) / 2
//============================================================================
// Mixed SL
//============================================================================
var initialEntryTpPrice_long = hl2
var initialEntryTpPrice_short = hl2
var mixedTrailingSl_long = hl2
var mixedTrailingSl_short = hl2
mixedSlLong = min(atrSl_long, kumoBasedSlLong, recentLow)
mixedSlShort = max(atrSl_short, kumoBasedSlShort, recentHigh)
//plot(mixedSlLong, color=color.green, linewidth=2)
//plot(mixedSlShort, color=color.red, linewidth=2)
//============================================================================
// Range Edge caliculation
//============================================================================
// calc range edge
f_calcRangeEdge_high() =>
    //highest = high[3]
    highest = max(open[3], close[3])
    for i = 4 to (config_rangeDetectBars - 1)
        //current = high[i]
        current = max(open[i], close[i])
        if highest < current
            highest := current
    highest
f_calcRangeEdge_low() =>
    //lowest = low[3]
    lowest = min(open[3], close[3])
    for i = 4 to (config_rangeDetectBars - 1)
        //current = low[i]
        current = min(open[i], close[i])
        if lowest > current
            lowest := current
    lowest
entryLimitHigh = f_calcRangeEdge_high()
entryLimitLow = f_calcRangeEdge_low()
plot(entryLimitHigh, color=COLOR_RANGE_EDGE, linewidth=1)
plot(entryLimitLow, color=COLOR_RANGE_EDGE, linewidth=1)
//============================================================================
// entry timing judge
//============================================================================
f_trendStatsChanged() =>
    var trendStats = 0
    var kumoBull = false
    var kumoBear = false
    var kumoRanged = false
    kumoBull := currentAboveKumo_baseHtf and currentAboveKumo_highestTf
    kumoBear := currentBelowKumo_baseHtf and currentBelowKumo_highestTf
    kumoRanged := not kumoBull and not kumoBear
    if kumoRanged
        trendStats := 0
        // respect recent bullish or bearish
        if kumoBull[1] or kumoBull[2] or kumoBull[3] or kumoBear[1] or kumoBear[2] or kumoBear[3]
            trendStats := trendStats[1]
    if kumoBull
        trendStats := 1
    if kumoBear
        trendStats := -1
    trendStats[1] != trendStats[0]
trendStatsChanged = f_trendStatsChanged()
var isFirstEntry = true
var resistancePrice = hl2
var rangeBreakSignalDetected = false
var rangeBreakMacdReversalDetected = false
var rangeBreakConfirmed = false
//--------------------------------------
// reset flags
// if trend stats changed, reset flags
if trendStatsChanged
    isFirstEntry := true
    rangeBreakSignalDetected := false
    rangeBreakMacdReversalDetected := false
    rangeBreakConfirmed := false
else
    // if has no positions
    if strategy.position_size == 0
        isFirstEntry := isFirstEntry[1]
        // if lost positions in prev bar
        if lostPositionsInPrevBar
            rangeBreakSignalDetected := false
            rangeBreakConfirmed := false
        else
            rangeBreakSignalDetected := rangeBreakSignalDetected[1]
            rangeBreakConfirmed := rangeBreakConfirmed[1]
    // if has any position
    else
        isFirstEntry := false // no more first entry
        resistancePrice := hl2 // no resistance price
//--------------------------------------
// 1st entry confirmation
var firstReverseAfterTrendChange = false
var trendConfirmed = false
// this operation is for the 1st entry
if isFirstEntry
    if bullish
        // wait for the short reversal for confirmation
        if not firstReverseAfterTrendChange and not rangeBreakMacdReversalDetected
            if macdDownTrend
                rangeBreakMacdReversalDetected := true
        if rangeBreakMacdReversalDetected
            if macdUpTrend
                trendConfirmed := true
    if bearish
        if not firstReverseAfterTrendChange and not rangeBreakMacdReversalDetected
            if macdUpTrend
                rangeBreakMacdReversalDetected := true
        if rangeBreakMacdReversalDetected
            if macdDownTrend
                trendConfirmed := true
else
    trendConfirmed := false
    firstReverseAfterTrendChange := false
if (bullish[0] != bullish[1]) or (bearish[0] != bearish[1])
    trendConfirmed := false
// plot trend confirmation
if (trendConfirmed[0] == true) and (trendConfirmed[1] == false)
    if bullish
        label.new(bar_index, low, 'Trend Confirmed', style=label.style_triangleup, size=size.tiny, color=#ffffff, textcolor=#ffffff)
    else
        label.new(bar_index, high, 'Trend Confirmed', style=label.style_triangledown, size=size.tiny, color=#ffffff, textcolor=#ffffff)
//--------------------------------------
// later entry confirmation
if strategy.position_size == 0
    // this operation is for later entry
    if isFirstEntry
        resistancePrice := hl2
    else
        // if range break was detected, set flag
        if not rangeBreakSignalDetected and continuousBull and entryLimitHigh < close
            rangeBreakSignalDetected := true
        if not rangeBreakSignalDetected and continuousBear and close < entryLimitLow
            rangeBreakSignalDetected := true
        // after range break, wait for short MACD reversal.
        // after this confirmation, make stop entry
        if rangeBreakSignalDetected
            if senkouSpanHigh_baseHtf < close
                resistancePrice := entryLimitHigh
                if macdDownTrend
                    rangeBreakConfirmed := true
            if senkouSpanLow_baseHtf > close
                resistancePrice := entryLimitLow
                if macdUpTrend
                    rangeBreakConfirmed := true
// plot rangebreak detection
if (rangeBreakSignalDetected[0] == true) and (rangeBreakSignalDetected[1] == false)
    if bullish
        label.new(bar_index, low, 'Rangebreak detected', style=label.style_triangleup, size=size.tiny, color=#ffffff, textcolor=#ffffff)
    else
        label.new(bar_index, high, 'Rangebreak detected', style=label.style_triangledown, size=size.tiny, color=#ffffff, textcolor=#ffffff)
// plot resistance price line
resitancePriceColor = rangeBreakConfirmed and strategy.position_size == 0 ? COLOR_RESISTANCE_PRICE_LINE : COLOR_TRANSPARENT
plot(resistancePrice, linewidth=4, color=resitancePriceColor)
//============================================================================
// Pyramiding entry judge
//============================================================================
f_calcExtraEntryStopForShort() =>
    startIndex = 2
    highest = max(open[startIndex], close[startIndex])
    for i = startIndex to (config_extraEntryStopDetectBars - 1)
        current = max(open[i], close[i])
        if highest < current
            highest := current
    highest
f_calcExtraEntryStopForLong() =>
    startIndex = 2
    lowest = min(open[startIndex], close[startIndex])
    for i = startIndex to (config_extraEntryStopDetectBars - 1)
        current = min(open[i], close[i])
        if lowest > current
            lowest := current
    lowest
extraEntryStopLong = f_calcExtraEntryStopForLong() + entryPadding
extraEntryStopShort = f_calcExtraEntryStopForShort() - entryPadding
extraEntryStop = bullish ? extraEntryStopLong :
  bearish ? extraEntryStopShort :
  hl2
extraEntryStopColor = (bullish or bearish) ? color.green : COLOR_TRANSPARENT
// plot as line
plot(extraEntryStop, color=extraEntryStopColor, linewidth=2)
//============================================================================
// entry, TP, SL
//============================================================================
shouldMakeEntryLong = continuousBull and ((isFirstEntry and trendConfirmed) or (rangeBreakConfirmed and close > resistancePrice))
shouldMakeEntryShort = continuousBear and ((isFirstEntry and trendConfirmed) or (rangeBreakConfirmed and close < resistancePrice))
// TP caliculation
if strategy.position_size == 0
    initialEntryTpPrice_long := entryLimitHigh + (hl2 - extraEntryStopLong)
    initialEntryTpPrice_short := entryLimitLow - (extraEntryStopShort - hl2)
// SL caliculation
mixedTrailingSl_long := if ((strategy.position_size == 0) and shouldMakeEntryLong) or ((strategy.position_size > 0) and (mixedTrailingSl_long < mixedSlLong))
    mixedSlLong
else if (strategy.position_size == 0) or (strategy.position_size < 0)
    hl2
else
    mixedTrailingSl_long[1]
mixedTrailingSl_short := if ((strategy.position_size == 0) and shouldMakeEntryShort) or ((strategy.position_size < 0) and (mixedTrailingSl_short > mixedSlShort))
    mixedSlShort
else if (strategy.position_size == 0) or (strategy.position_size > 0)
    hl2
else
    mixedTrailingSl_short[1]
// final entry price
initialEntryStopPrice_long = entryLimitHigh + entryPadding
initialEntryStopPrice_short = entryLimitLow - entryPadding
extraEntryLimitPrice_long = extraEntryStopLong
extraEntryLimitPrice_short = extraEntryStopShort
extraEntryTpPrice_long = entryLimitHigh + entryPadding
extraEntryTpPrice_short = entryLimitLow - entryPadding
//============================================================================
// Quantitiy caliculation
//============================================================================
var initialQty = 0
slPercentage = bullish ? abs(mixedTrailingSl_long-hl2)/hl2*100 : abs(mixedTrailingSl_short-hl2)/hl2*100
qtyForInitialEntry = f_calcQtyForInitialEntry(slPercentage)
qtyForExtraEntry = f_calcQtyForExtraEntry(slPercentage)
//============================================================================
// Pyramiding judge
//============================================================================
var anyTpTriggered = false
var hasAnyPositions = false
if strategy.position_size != 0 and strategy.position_size[1] == 0
    hasAnyPositions := true
if strategy.position_size == 0 and strategy.position_size[1] != 0
    hasAnyPositions := false
    anyTpTriggered := false
if hasAnyPositions and not anyTpTriggered and (abs(strategy.position_size) < initialQty)
    anyTpTriggered := true
pyramidingReady =
  (anyTpTriggered and bullish and (extraEntryStopLong > previousEntryPrice) and f_isLastCandleUp()) or
  (anyTpTriggered and bearish and (extraEntryStopShort < previousEntryPrice) and f_isLastCandleDown())
//============================================================================
// make entries
//============================================================================
if (time >= startDate and time <= finishDate)
    if strategy.position_size == 0
        if shouldMakeEntryLong
            initialQty := qtyForInitialEntry
            strategy.entry(id="Long", long=true, stop=initialEntryStopPrice_long, qty=initialQty)
            previousEntryPrice := entryLimitHigh
        if shouldMakeEntryShort
            initialQty := qtyForInitialEntry
            strategy.entry(id="Short", long=false, stop=initialEntryStopPrice_short, qty=initialQty)
            previousEntryPrice := entryLimitLow
    // Long pyramiding
    if (strategy.position_size > 0) and pyramidingReady
        previousEntryPrice := extraEntryStopLong
        strategy.entry(id="LongExtra", long=true, limit=extraEntryLimitPrice_long, qty=qtyForExtraEntry)
    else
        strategy.cancel(id="LongExtra")
    // Short pyramiding
    if (strategy.position_size < 0) and pyramidingReady
        previousEntryPrice := extraEntryStopShort
        strategy.entry(id="ShortExtra", long=false, limit=extraEntryLimitPrice_short, qty=qtyForExtraEntry)
    else
        strategy.cancel(id="ShortExtra")
    // cancel stop entries
    if not continuousBull
        strategy.cancel(id="Long")
        strategy.cancel(id="LongExtra")
    if not continuousBear
        strategy.cancel(id="Short")
        strategy.cancel(id="ShortExtra")
    // TP, SL
    strategy.exit('Long-TP', 'Long', stop=mixedTrailingSl_long, limit=initialEntryTpPrice_long, qty=(initialQty/2))
    strategy.exit('Long-SL', 'Long', stop=mixedTrailingSl_long)
    strategy.exit('LongExtra-SL/TP', 'LongExtra', stop=mixedTrailingSl_long, limit=extraEntryTpPrice_long)
    strategy.exit('Short-TP', 'Short', stop=mixedTrailingSl_short, limit=initialEntryTpPrice_short, qty=(initialQty/2))
    strategy.exit('Short-SL', 'Short', stop=mixedTrailingSl_short)
    strategy.exit('ShortExtra-SL/TP', 'ShortExtra', stop=mixedTrailingSl_short, limit=extraEntryTpPrice_short)
//============================================================================
// plot SL, TP
//============================================================================
sl = if strategy.position_size > 0
    mixedTrailingSl_long
else if strategy.position_size < 0
    mixedTrailingSl_short
else
    na
tp = if hasAnyPositions and not anyTpTriggered
    strategy.position_size > 0 ? initialEntryTpPrice_long : initialEntryTpPrice_short
else
    na
plot(sl, color=color.red, style=plot.style_cross, linewidth=2, title="SL")
plot(tp, color=color.blue, style=plot.style_cross, linewidth=2, title="T")
//============================================================================
// debug
//============================================================================
// continuous bull / bear check
value_bgcolor = continuousBull ? color.green : continuousBear ? color.red: color.new(#000000, 100)
// MACD up or down check
//value_bgcolor = macdUpTrend ? color.green : color.red
// both kumo bull
//value_bgcolor = (kumoColor_bull_baseHtf and kumoColor_bull_highestTf) ? color.green:
//  (not kumoColor_bull_baseHtf and not kumoColor_bull_highestTf) ? color.red: color.new(#000000, 100)
// doji
//dojiUp = bullish and f_isUpDoji()
//dojiDown = bearish and f_isDownDoji()
//value_bgcolor = dojiUp ? color.green :
//  dojiDown ? color.red :
//  COLOR_TRANSPARENT
//value_bgcolor = f_isLastCandleUp() ? color.green : COLOR_TRANSPARENT
//value_bgcolor = pyramidingReady ? color.green : COLOR_TRANSPARENT
bgcolor(value_bgcolor, transp=95)
Expand (1085 lines)

Overview

2Tier Ichimoku Pyramiding [Takazudo] allows two entries in the same direction and uses ATR-based trailing stops plus ATR entry padding. Settings change Ichimoku lengths, line smoothing, gap-cloud use, bull and range detection, and the backtest start date. Exit logic beyond the trailing stop is not shown in the provided code.

Details

Published by

hasnocool on GitHub

Type

Strategy, Pine Script v4

Draws

On the price chart

Category

Trend, Volatility & bands, Support & resistance

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

  • The strategy can add several entries in the same direction

Topics

analysisbtcusdtcryptocurrencydatapandaspythonsimulationtradingtradingview

Settings

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

SettingTypeDefaultVariable
═════════ HTF ══════════booltrue_1
Base Higher TimeframetimeframeDconfig_baseHtf
use Highest Timeframe (Kumo only)booltrueconfig_useHighestTf
Highest TimeframetimeframeWconfig_highestTf
═════════ Ichimoku ══════════booltrue_2
Tenkan-Sen Barsint9config_tenkanSen
Kijun-Sen Barsint26config_kijunSen
Senkou-Span B Barsint52config_senkouSpanB
Chikou-Span Offsetint26config_chikouSpan
Senkou-Span Offsetint26config_senkouSpan
═════════ Smooth Line ══════════booltrue_3
enable smooth linebooltrueconfig_useSmooth
Show all 33 settings
SettingTypeDefaultVariable
smooth factorint2config_smoothFactor
═════════ MTF stuff ══════════booltrue_4
avoid to refer lower resolution indicatorbooltrueconfig_autoSwitchToHtf
avoid to refer too high resolution indicatorbooltrueconfig_avoidTooHighResolution
use Gap Kumobooltrueconfig_useGapKumo
═════════ etc ══════════booltrue_5
bull detection min bar countint3config_bullDetectBars
range detection bar countint200config_rangeDetectBars
recent bar count for SLint50config_recentBars
Trailing stop ATR Lengthint4config_atrLength
Trailing stop ATR Multiple factorfloat1config_atrSlMult
Entry padding ATR Multiple factorfloat0.5config_atrEntryPaddingMult
Entry padding ATR Lengthint10config_atrEntryPaddingLength
Pyramiding entry recent detect bar countint10config_extraEntryStopDetectBars
═════════ Backtesting range ══════════booltrue_6
From Yearint2019fromYear
From Monthint1fromMonth
From Dayint1fromDay
To Yearint2021toYear
To Monthint3toMonth
To Dayint10toDay
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

257 stars

This strategy plots VWMA-based Bollinger bands on the 1-minute ES futures price chart for volatility analysis and potential breakout identification. It calculates dynamic long and short stop loss and take profit levels using percentage inputs relative to entry

Strategy v6 Volatility & bandsSupport & resistance
Updated 6 weeks ago · None stated GitHub repository of V1.6 ES - Futures 1M No Repaint

Nasdaq Prop Firm Strategy

by TradersPost
218 stars

This strategy uses multiple VWAP anchors and a custom Lull indicator to generate buy and sell signals on the Nasdaq price chart. It plots the VWAP trend line and three VWAP anchors with customizable colors and mitigation methods. The Lull indicator produces si

Strategy v6 TrendSupport & resistance Repaints
Updated 3 months ago · None stated GitHub repository of Nasdaq Prop Firm Strategy

This strategy implements a multi-stage trend following system inspired by John W. Seykota. It generates long and short entries when price breaks above or below Donchian channels of specified length. Each entry adds a unit sized to risk a fixed percentage of cu

Strategy v6 TrendVolatility & bands
Updated 11 months ago · None stated GitHub repository of Seykota Alt 29: Multi-Stage Scaling
11 stars

Calculates upper and lower Donchian Channel bands over a customizable lookback length and plots them on the main price chart. At a specified exchange hour, the strategy places a long buy stop order at the upper Donchian Channel level. Unfilled pending orders a

Strategy v6 BreakoutSupport & resistance
Updated 5 months ago · Apache-2.0 GitHub repository of Estrategia Donchian Breakout
8 stars

This strategy combines moving averages, ATR volatility bands and ADX trend strength on the price chart. It calculates ADX from price data and adjusts the ATR multiplier dynamically based on whether ADX is rising or falling. Long and short entries are controlle

Strategy v4 TrendMoving averages
Updated 4 years ago · None stated GitHub repository of MA+ATR+ADX+PP Strategy

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

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