Strategy · Pine Script v5 · On the chart

Bjorgum Double Tap

by hasnocool· code credited to Bjorgum

Bjorgum Double Tap is a price-chart strategy that detects double-bottom and double-top patterns from pivots.

View on GitHub

GitHub stars106on the repository
Pine versionv5runs as is
Lines of code461
Settings37inputs
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

461 lines of Pine Script v5 from Bjorgum Double Tap.pine, published under GPL-3.0. Keep the author's credit and licence lines when you reuse it.

Bjorgum Double Tap.pine
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Bjorgum
//   ________________________________________________________________ 
//  |\______________________________________________________________/| 
//  ||   ________________                                           || 
//  ||   ___  __ )_____(_)___________________ ____  ________ ___    || 
//  ||   __  __  |____  /_  __ \_  ___/_  __ `/  / / /_  __ `__ \   || 
//  ||   _  /_/ /____  / / /_/ /  /   _  /_/ // /_/ /_  / / / / /   ||
//  ||   /_____/ ___  /  \____//_/    _\__, / \__,_/ /_/ /_/ /_/    ||
//  ||           /___/                /____/                        ||
//  ||______________________________________________________________||
//  |/______________________________________________________________\|
//@version=5
// @strategy_alert_message {{strategy.order.alert_message}}
strategy(
 title                  =   "Bjorgum Double Tap",
 shorttitle             =   "Bj Double Tap",
 overlay                =   true, 
 max_lines_count        =   500, 
 max_labels_count       =   500, 
 precision              =   3, 
 default_qty_type       =   strategy.cash, 
 commission_value       =   0.04, 
 commission_type        =   strategy.commission.percent, 
 slippage               =   1, 
 currency               =   currency.USD, 
 default_qty_value      =   1000, 
 initial_capital        =   1000)
// ══════════════════════════════════ //
// —————> Immutable Constants <—————— //
// ══════════════════════════════════ //
string      useStratTip =   "Enables or disables the strategy tester allowing a change between either an indicator or a strategy."
string      dLongTip    =   "Detect long setups."
string      dShortTip   =   "Detect short setups."
string      FLIPTip     =   "Allow entry in the opposite bias while already in a position."
string      startTip    =   "Start date & time to begin backtest period. Useful for beginning new bot. eg. Set time to now to make broker emulator in a flat position with the proper starting captial before setting alerts"
string      endTip      =   "End date & time to stop searching for setups for back testing."
string      tolTip      =   "The difference in height allowable for the signifcant points of the pattern expressed as a percent of the pattern height. Example: The points can vary in height by 15% of the pattern height from one another."
string      lenTip      =   "The length used to calcuate significant points to form pivots for pattern detection. Example: The highest or lowest point in 50 bars."
string      fibTip      =   "The fib target extension projected from the neckline of the pattern in the direction of the pattern bias expressed as a percent. Example: 100% is a 1:1 measurment of the height from the pattern neckline."
string      stopPerTip  =   "The fib extension of the pattern height measured from the point of invalidation. Example: 0% would be the high point of a double top. 50% would be halfway between the top and the neckline."
string      offsetTip   =   "The number of bars lines are extended into the future during an ongoing pattern."
string      atrStopTip  =   "Enables an ATR trailing stop once the target extension is breached. NOTE: This disables a take profit order in the strategy format."
string      atrLenTip   =   "The number of bars used in the ATR calculation."
string      atrMultTip  =   "The multiplier of the ATR value to subtract from the swing low or swing high point. Example: 1 is 100% of the ATR, 2 is 2x the ATR value."
string      lookbackTip =   "The number of bars to look back to find a swing high or swing low to be used in the trailing stop calculation. Example: 1 ATR subtracted from the lowest point in 5 bars. 1 would use the lowest point within the last bar."
string      tableTip    =   "Show the data table for trade limit levels during an active trade. (table will only show when a pattern is present on the chart, or in bar replay)."
string      labelTip    =   "Updates the double top/bottom label with 'Success' or 'Failure' and updates color based on the outcome of the pattern."
string      thirdTip    =   "Where would you like to send your alerts?"
string      pPhraseTip  =   "A custom passphrase to authenticate your json message with a touch more security."
string      aTronKeyTip =   "The name of your Alertatron API keys. (Add the ticker in brackets). Example: MyKeys(XBTUSD)."
string      tickerTip   =   "The ticker to be traded when using Trading Connector"
string      LongTip     =   "3Commas start long deal bot keys."
string      LongEndTip  =   "3Commas end long deal bot keys."
string      ShortTip    =   "3Commas start short deal bot keys."
string      ShortEndTip =   "3Commas end short deal bot keys."
string      dt          =   "Double Top"   
string      db          =   "Double Bottom"
string      suc         =   " - Success"  
string      fail        =   " - Failure"
string      winStr      =   "Target reached! 💰" 
string      loseStr     =   "Stopped out... 🤷‍♂"
string      tabPerc     =   "{0, number, #.##}\n({1, number, #.##}%)"     
string      tcStop      =   "slmod slprice={0} tradeid={1}"
string      dExit       =   "'{'\"content\": \"```Bjorgum {0}\\n\\n\\t'{{ticker}}' '{{interval}}'\\n\\n\\t{1}```\"'}'" 
string      S1          =   "tiny"   ,  string P1 = "top" 
string      S2          =   "small"  ,  string P2 = "middle" 
string      S3          =   "normal" ,  string P3 = "bottom" 
string      S4          =   "large"  ,  string P4 = "left" 
string      S5          =   "huge"   ,  string P5 = "center"
string      S6          =   "auto"   ,  string P6 = "right"
var string  tnB         =   ""       ,  string A1 = "Custom Json"
string      altStr      =   ""       ,  string A2 = "Trading Connector"
string      tUp         =   ""       ,  string A3 = "Alertatron"
string      dCordWin    =   ""       ,  string A4 = "3Commas"
string      dCordLose   =   ""       ,  string A5 = "Discord"
 
float       pos         =   strategy.position_size
int         sync        =   bar_index
bool        confirm     =   barstate.isconfirmed
var int     dir         =   na
var float   lmt         =   na 
var float   stp         =   na 
string      altExit     =   na
bool        FLAT        =   pos == 0
bool        LONG        =   pos >  0
bool        SHORT       =   pos <  0
var int     tradeId     =   0
color       col1        =   color.new(#b2b5be, 15)
color       col2        =   color.new(#b2b5be, 87)
color       col3        =   color.new(#ffffff,  0)
color       col4        =   color.new(#17ff00, 15)
color       col5        =   color.new(#ff0000, 15)
color       col6        =   color.new(#ff5252,  0)
var matrix<float> logs  =   matrix.new<float>  (5, 3)
var line [] zLines      =   array.new_line     (5)
var line [] tLines      =   array.new_line     (5)
var line [] bLines      =   array.new_line     (5)
var label[] bullLb      =   array.new_label     ()
var label[] bearLb      =   array.new_label     ()
int timeStart           =   timestamp("01 Jan 2000")
int timeEnd             =   timestamp("01 Jan 2099")
// ══════════════════════════════════ //
// —————————> User Input <——————————— //
// ══════════════════════════════════ //
string      GRP1        =   "════  Detection and Trade Parameters  ════"
bool        useStrat    =   input.bool  (true     , "Use Strategy"    , group= GRP1, tooltip= useStratTip)
bool        dLong       =   input.bool  (true     , "Detect Bottoms"  , group= GRP1, tooltip= dLongTip   )
bool        dShort      =   input.bool  (true     , "Detect Tops"     , group= GRP1, tooltip= dShortTip  )
bool        FLIP        =   input.bool  (true     , "Flip Trades"     , group= GRP1, tooltip= FLIPTip    )       
float       tol         =   input.float (15       , "Pivot Tolerance" , group= GRP1, tooltip= tolTip     , minval= 1)
int         len         =   input.int   (50       , "Pivot Length"    , group= GRP1, tooltip= lenTip     , minval= 1)
float       fib         =   input.float (100      , "Target Fib"      , group= GRP1, tooltip= fibTip     , minval= 0)
int         stopPer     =   input.int   (0        , "Stop Loss Fib"   , group= GRP1, tooltip= stopPerTip )
int         offset      =   input.int   (30       , "Line Offset"     , group= GRP1, tooltip= offsetTip  , minval= 0)
string      GRP2        =   "═══════════ Time Filter ═══════════"
int         startTime   =   input.time(timeStart  , "Start Filter"    , group= GRP2, tooltip= startTip)      
int         endTime     =   input.time(timeEnd    , "End Filter"      , group= GRP2, tooltip= endTip  )        
string      GRP3        =   "══════════ Trailing Stop ══════════"
bool        atrStop     =   input.bool  (false    , "Use Trail Stop"  , group= GRP3, tooltip= atrStopTip )
int         atrLength   =   input.int   (14       , "ATR Length"      , group= GRP3, tooltip= atrLenTip  , minval= 1)
float       atrMult     =   input.float (1        , "ATR Multiplier"  , group= GRP3, tooltip= atrMultTip , minval= 0)
int         lookback    =   input.int   (5        , "Swing Lookback"  , group= GRP3, tooltip= lookbackTip, minval= 1)
string      GRP5        =   "════════════ Colors ════════════"
color       col         =   input.color (col1     , "Lines        "   , group= GRP5, inline= "41")
color       zCol        =   input.color (col3     , "Patterns       " , group= GRP5, inline= "42")
int         hWidth      =   input.int   (1        , ""                , group= GRP5, inline= "41", minval= 1)
int         zWidth      =   input.int   (1        , ""                , group= GRP5, inline= "42", minval= 1)
color       colf        =   input.color (col2     , "Stop Fill"       , group= GRP5)
color       tCol        =   input.color (col4     , "Target Color"    , group= GRP5)
color       sCol        =   input.color (col5     , "Stop Color"      , group= GRP5)
color       trailCol    =   input.color (col6     , "Trail Color"     , group= GRP5)
string      GRP6        =   "═════════  Table and Label  ═════════"
bool        showTable   =   input.bool  (true     , "Show Table"      , group= GRP6, tooltip= tableTip) 
bool        setLab      =   input.bool  (true     , "Update Label"    , group= GRP6, tooltip= labelTip)
string      labSize     =   input.string("small"  , "Label Text Size" , group= GRP6, options= [S1, S2, S3, S4, S5, S6])
string      textSize    =   input.string("normal" , "Table Text Size" , group= GRP6, options= [S1, S2, S3, S4, S5, S6])
string      tableYpos   =   input.string("bottom" , "Table Position"  , group= GRP6, options= [P1, P2, P3])
string      tableXpos   =   input.string("right"  , ""                , group= GRP6, options= [P4, P5, P6])
string      GRP7        =   "══════════ Alert Strings ══════════"
string      thirdParty  =   input.string(A1       , "3rd Party"       , group= GRP7, tooltip= thirdTip, options= [A1, A2, A3, A4, A5])
string      pPhrase     =   input.string("1234"   , "Json Passphrase" , group= GRP7, tooltip= pPhraseTip ) 
string      aTronKey    =   input.string("myKeys" , "Alertatron Key"  , group= GRP7, tooltip= aTronKeyTip)
string      tcTicker    =   input.string(""       , "TC Ticker"       , group= GRP7, tooltip= tickerTip  )
string      c3Long      =   input.string(""       , "3Comma Long"     , group= GRP7, tooltip= LongTip    )
string      c3LongEnd   =   input.string(""       , "3Comma Long End" , group= GRP7, tooltip= LongEndTip )
string      c3Short     =   input.string(""       , "3Comma Short"    , group= GRP7, tooltip= ShortTip   )
string      c3ShortEnd  =   input.string(""       , "3Comma Short End", group= GRP7, tooltip= ShortEndTip)
// ══════════════════════════════════ //
// ————> Variable Calculations <————— //
// ══════════════════════════════════ //
    
bool        dif         =   stopPer != 0 
int         set         =   sync + offset
float       atr         =   ta.atr          (14)
float       sLow        =   ta.lowest       (lookback) - (atr * atrMult)
float       sHigh       =   ta.highest      (lookback) + (atr * atrMult)
float       pivHigh     =   ta.highest      (len)
float       pivLows     =   ta.lowest       (len)
float       hbar        =   ta.highestbars  (len)
float       lbar        =   ta.lowestbars   (len)
// ══════════════════════════════════ //
// ———> Functional Declarations <———— //
// ══════════════════════════════════ //
High(m)  => 
    float result = (m == 1 ? high : low)
    
Low(m)   => 
    float result = (m == 1 ? low  : high)
    
perD(_p) => 
    float result = (_p - close) / close * 100
_coords(_x, _i)                      =>
    x = matrix.get                   (_x, _i, 0)
    y = matrix.get                   (_x, _i, 1)
    [int(x), y]
_arrayLoad(_x, _max, _val)           =>  
    array.unshift                    (_x,   _val)   
    if  array.size                   (_x) > _max
        array.pop                    (_x)
_matrixPush(_mx, _max, _row)         =>
    matrix.add_row(_mx, matrix.rows  (_mx),  _row)
    if matrix.rows                   (_mx) > _max
        matrix.remove_row            (_mx, 0)
_mxLog(_cond, _x, _y)                =>
    float[] _row = array.from        (sync, _y, 0)
    if _cond 
        _matrixPush                  (_x, 5, _row)
_mxUpdate(_cond, _dir, _x, y)        =>
    int m    = _dir ? 1 : -1
    int _end = matrix.rows           (_x) -1
    if  _cond and y * m > matrix.get (_x, _end, 1) * m 
        matrix.set                   (_x, _end, 0, sync)
        matrix.set                   (_x, _end, 1, y)
_extend(_x, _len) =>
    for l in _x
        line.set_x2(l, _len)
_hLine(_l, x2, y2, y3, y4, y5, _t)   =>
    line l1 =             line.new   (x2    , y2, set, y2, color= col,  width= hWidth)
    line l2 =             line.new   (x2    , y4, set, y4, color= col,  width= hWidth)
    array.set (_l    , 3, l1)
    array.set (_l    , 2, l2)
    array.set (_l    , 1, line.new   (x2    , y3, set, y3, color= col,  width= hWidth))
    array.set (_l    , 0, line.new   (sync-1, _t, set, _t, color= col,  width= hWidth))
    linefill.new                     (l1    , l2, colf)
    if stopPer != 0
        array.set (_l, 4, line.new   (sync-1, y5, set, y5, color= col,  width= hWidth))
_zLine(x1, y1, x2, y2, x3, y3, x4, y4) =>
    array.set (zLines, 3, line.new   (x1, y1, x2  , y2   , color= zCol, width= zWidth))
    array.set (zLines, 2, line.new   (x2, y2, x3  , y3   , color= zCol, width= zWidth))
    array.set (zLines, 1, line.new   (x3, y3, x4  , y4   , color= zCol, width= zWidth))
    array.set (zLines, 0, line.new   (x4, y4, sync, close, color= zCol, width= zWidth))
_label(x, y, m) =>
    m > 0 ?  
   _arrayLoad (bearLb, 1, label.new  (x, y, dt, color= color(na), style= label.style_label_down, textcolor= col, size= labSize)) : 
   _arrayLoad (bullLb, 1, label.new  (x, y, db, color= color(na), style= label.style_label_up,   textcolor= col, size= labSize))
_labelUpdate(_x, _y, m)              =>
    if (_x or _y) and setLab
        label  lab  = array.get      (m > 0 ? bearLb : bullLb, 0)
        string oStr =                (m > 0 ? dt     : db)
        string nStr = oStr +         (_x    ? suc    : fail)
        label.set_text               (lab, nStr)
        label.set_textcolor          (lab, _x ? tCol : sCol)
_atrTrail(_cond, _lt, _s, m)         =>
    var float _stop  = na
    var bool  _flag  = na
    var bool  _trail = na
    _flag           := _cond
    _stop           := _s
    _trail          := _flag ? false : _trail
    if atrStop and useStrat
        if  _lt
            _flag   := false 
            _trail  := true  
        _stop       := m == -1 ? _lt ? sLow  : math.max(_stop, sLow)  : _stop 
        _stop       := m ==  1 ? _lt ? sHigh : math.min(_stop, sHigh) : _stop 
    if High(m) * m > _stop * m 
        _flag       := true
        _trail      := false
    [_flag, _stop, _trail]
_inTrade(_cond, _x, _e, m)           =>
    var bool  _flag  =               na
    var float _stop  =               na 
    var float _limit =               na
    line      l1     = array.get     (_x, 0)
    float     lp     = line.get_price(l1, sync)
    line      l2     = array.get     (_x, dif ? 4 : 2)
    float     ls     = line.get_price(l2, sync)
    bool      win    = Low (m) *     m <= lp * m and not _e
    bool      lose   = High(m) *     m >= ls * m and not _e
    _flag           := _cond
    _stop           := _e ? ls :     _stop
    _limit          := _e ? lp :     _limit
    if win or lose  
        _flag       :=               true
        _extend                      (_x    , sync)
        _labelUpdate                 (win   , lose, m)
        line.set_color               (win   ? l1 : l2, win ? tCol : sCol)
        array.fill                   (_x    , na)
        array.fill                   (zLines, na)
    [_f, _s, _t]     = _atrTrail     (_flag , win  , _stop, m)
    _flag           :=               atrStop  ? _f : _flag
    _stop           :=               _t and _s * m < _stop * m and confirm ? _s : _stop
    [_flag, _stop, _t, _limit]
_double(_cond, _l, _x, m)            =>
    var bool _flag   = na
    int _rows        = matrix.rows   (_x)
    _flag           := _cond
    if _flag
        [x1, y1]     = _coords       (_x , _rows - 5)
        [x2, y2]     = _coords       (_x , _rows - 4)
        [x3, y3]     = _coords       (_x , _rows - 3)
        [x4, y4]     = _coords       (_x , _rows - 2)
        bool  traded = matrix.get    (_x , _rows - 2, 2)
        float height = math.avg      (y2 , y4)   - y3
        float _high  = y2 + height * (tol/ 100)
        float _low   = y2 - height * (tol/ 100)
        float _t     = y3 - height * (fib/ 100)
        float y5     = y2 * m < y4 * m ? y2 : y4
        float y6     = y2 * m > y4 * m ? y2 : y4
        float y7     = y6 - height *(stopPer/100)    
        bool result  = y1*m < y3*m and y4*m <= _high*m and y4*m >= _low*m and close*m < y3*m and not (close[1]*m < y3*m) and not traded
        if result and _flag and (m > 0 ? dShort : dLong)
            _hLine       (_l, x2, y5, y3, y6, y7, _t)
            _zLine       (x1, y1, x2, y2, x3, y3, x4, y4)
            _label       (x4, y6, m)
            matrix.set   (_x, _rows - 2, 2, 1)
            _flag :=     false
    _flag 
_scan(_l, _x, m)     =>
    var bool _cond   = true
    _cond           := _double       (_cond, _l, _x, m)
    bool enter       = _cond[1]      and not _cond
    [f,s,t,l]        = _inTrade      (_cond, _l, enter, m)
    _cond           := f
    _extend(_l, set)
    [f,s,t,l]
_populate(_n, _x, _i, _col) => 
    for [i, _a] in _x 
        if not na(_a)
            table.cell(table_id  = _n,  column     = _i  , 
                       row       =  i,  bgcolor    = na  , 
                       text      = _a,  text_color = _col, 
                       text_size =      textSize)
    
// ══════════════════════════════════ //
// ————————> Logical Order <————————— //
// ══════════════════════════════════ //
dir            :=  not hbar ? 1 : not lbar ? 0 : dir
bool dirUp      =  dir != dir[1] and     dir 
bool dirDn      =  dir != dir[1] and not dir 
bool setUp      =  not hbar and     dir 
bool setDn      =  not lbar and not dir 
_mxLog             (dirUp or dirDn,      logs, dirUp ? pivHigh : pivLows)
_mxUpdate          (setUp or setDn, dir, logs, setUp ? pivHigh : pivLows)
[bear,ss,ts,sl] =  _scan(tLines, logs,  1)
[bull,ls,tl,ll] =  _scan(bLines, logs, -1)
bool st         =  SHORT ? ts : false
bool lt         =  LONG  ? tl : false
bool sell       =  bear[1] and not bear 
bool buy        =  bull[1] and not bull
color ssCol     =  st or st[1] ? trailCol : na
color lsCol     =  lt or lt[1] ? trailCol : na
bool longEntry  =  buy  and (FLAT or (SHORT and FLIP)) 
bool shortEntry =  sell and (FLAT or (LONG  and FLIP)) 
bool dateFilter =  time >= startTime and time <= endTime
tradeId        +=  longEntry or shortEntry ? 1 : 0
lmt            :=  atrStop    ? na :
                   shortEntry ? sl : longEntry ? ll : lmt 
stp            :=  shortEntry or SHORT and atrStop ? ss : 
                   longEntry  or LONG  and atrStop ? ls : stp
                   
plot               (atrStop ? ss : na, "Short Stop", ssCol, style= plot.style_linebr)
plot               (atrStop ? ls : na, "Long Stop",  lsCol, style= plot.style_linebr)
bgcolor            (not dateFilter ? color.new(color.red,80) : na, title= "Filter Color")
// ══════════════════════════════════ //
// —————————> Data Display <————————— //
// ══════════════════════════════════ //
if showTable
    
    string   tls    = bull ? na : str.format(tabPerc, ls, perD(ls))
    string   tss    = bear ? na : str.format(tabPerc, ss, perD(ss))
    string   tll    = bull ? na : str.format(tabPerc, ll, perD(ll))
    string   tsl    = bear ? na : str.format(tabPerc, sl, perD(sl))
    
    string[] titles = array.from(na, bull ? na : "Bullish", bear ? na : "Bearish")
    
    string[] stops  = array.from("Stop"  , tls, tss)
    string[] limtis = array.from("Target", tll, tsl)
    
    table    bjTab  = table.new(tableYpos + "_" + tableXpos, 3, 3, border_color= color.new(color.gray, 60), border_width= 1)
    
    if not bear or not bull 
        _populate(bjTab, titles, 0, color.white)
        _populate(bjTab, stops,  1, color.red)
        if not (na(ll) or lt) or not (na(sl) or st)
            _populate(bjTab, limtis, 2, color.green)
// ══════════════════════════════════ //
// ——————> String Variables <———————— //
// ══════════════════════════════════ //
bool cSon  = thirdParty == A1
bool tCon  = thirdParty == A2
bool aTron = thirdParty == A3
bool c3    = thirdParty == A4
bool dCord = thirdParty == A5
if cSon and useStrat
    
    string json = 
    
     "'{'
     \n    \"passphrase\": \"{0}\",
     \n    \"time\": '\"{{timenow}}\"',
     \n    \"ticker\": '\"{{ticker}}\"',
     \n    \"plot\": '{'
     \n        \"stop_price\": {1, number, #.########},
     \n        \"limit_price\": {2, number, #.########}
     \n    '}',
     \n    \"strategy\": '{'
     \n        \"position_size\": '{{strategy.position_size}}',
     \n        \"order_action\": '\"{{strategy.order.action}}\"',
     \n        \"market_position\": '\"{{strategy.market_position}}\"',
     \n        \"market_position_size\": '{{strategy.market_position_size}}',
     \n        \"prev_market_position\": '\"{{strategy.prev_market_position}}\"',
     \n        \"prev_market_position_size\": '{{strategy.prev_market_position_size}}'
     \n    '}'
     \n'}'"
    
    altStr := str.format(json, pPhrase, stp, lmt)
if tCon and useStrat
    string tcTrade = 
     "'{{strategy.order.action}}' tradesymbol={0} tradeid={1}" 
     + (atrStop ? "" : ' tpprice={2, number, #.########}') 
     + ' slprice={3, number, #.########}' 
    
    altStr  := str.format(tcTrade, tcTicker, tradeId, lmt, stp)
    tUp     := str.format(tcStop, stp, tradeId)
if aTron and useStrat
    string altEnt  = aTronKey + " '{'\ncancel(which=all);\nmarket(position='{{strategy.position_size}}');\n"
    string altEnd  = "'}'\n#bot"
    string altBrkt = 
       (atrStop ? "stopOrder(" : "stopOrTakeProfit(")
     + (atrStop ? "" : "tp=@{0, number, #.########}, ")
     + (atrStop ? "offset=@" : "sl=@") + "{1, number, #.########}, position=0, reduceOnly=true"
     + (atrStop ? ", tag=trail" : "")
     + ");\n"
    
    string enter = altEnt + altBrkt + altEnd 
    string exit  = altEnt + altEnd
    
    altStr  := str.format(enter, lmt, stp)
    altExit := na(altExit) ? exit : altExit
    string stopUpdate = aTronKey + " '{'\ncancel(which=tagged, tag=trail);\n" + altBrkt + altEnd
    
    tUp := atrStop ? str.format(stopUpdate, lmt, stp) : tUp
if dCord and useStrat
    tnB := longEntry ? db : shortEntry ? dt : tnB
    string postTrade = 
    
     "'{'\"content\": \"```🚨 Bjorgum {0} detected 🚨\\n\\n\\t'{{ticker}}' '{{interval}}'\\n\\n\\t"
     + (atrStop ? "" : "🎯 Target: {1, number, #.########}\\n\\t") 
     + "🛑 Stop:   {2, number, #.########}```\"'}'"
    altStr    := str.format(postTrade, tnB, lmt, stp)
    dCordWin  := str.format(dExit, tnB, winStr)
    dCordLose := str.format(dExit, tnB, loseStr)
if c3 and useStrat
    c3Long  := SHORT and buy  ? str.format("[{0}, {1}]", c3ShortEnd, c3Long)  : c3Long 
    c3Short := LONG  and sell ? str.format("[{0}, {1}]", c3LongEnd,  c3Short) : c3Short
// ══════════════════════════════════ //
// ——————> Strategy Execution <—————— //
// ══════════════════════════════════ //
strategy.entry("Long" , strategy.long , comment= "Long",  when= useStrat and longEntry  and dateFilter, alert_message= c3 ? c3Long  : altStr)
strategy.entry("Short", strategy.short, comment= "Short", when= useStrat and shortEntry and dateFilter, alert_message= c3 ? c3Short : altStr)
strategy.exit("Long Exit", 
              "Long",  
              stop          = stp, 
              limit         = lmt, 
              comment       = "L Exit", 
              alert_message = c3    ? c3LongEnd : aTron ? altExit : tCon ? "closelong"  : dCord ? na : altStr, 
              alert_profit  = dCord ? dCordWin  : na, 
              alert_loss    = dCord ? dCordLose : na)
strategy.exit("Short Exit", 
              "Short", 
              stop          = stp, 
              limit         = lmt, 
              comment       = "S Exit", 
              alert_message = c3    ? c3ShortEnd : aTron ? altExit : tCon ? "closeshort" : dCord ? na : altStr, 
              alert_profit  = dCord ? dCordWin   : na, 
              alert_loss    = dCord ? dCordLose  : na)
    
// ══════════════════════════════════ //
// —————> Alert Functionality <—————— //
// ══════════════════════════════════ //
if (lt and ls != ls[1] or st and ss != ss[1]) and (tCon or aTron)
    alert(tUp, alert.freq_once_per_bar_close)
if not useStrat and (buy or sell)
    alert((buy ? db : dt) + ' Detected', alert.freq_once_per_bar)
//  ____  __ _  ____ 
// (  __)(  ( \(    \
//  ) _) /    / ) D (
// (____)\_)__)(____/
Expand (544 lines)

Overview

Bjorgum Double Tap enters long or short when those patterns form, and it can flip into the opposite direction while a position is open. Targets and stops are Fibonacci extensions of pattern height from the neckline and invalidation point. An optional ATR trail replaces the take-profit once the target is breached. Settings change pivot length and tolerance, fib distances, line offset, and the backtest window. It draws pattern lines, stops, targets, and an optional stats table.

Details

Published by

hasnocool on GitHub

Code credit

Bjorgum, as written in the script's header

Type

Strategy, Pine Script v5

Draws

On the price chart

Category

Support & resistance, Breakout

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Topics

analysisbtcusdtcryptocurrencydatapandaspythonsimulationtradingtradingview

Settings

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

SettingTypeDefaultVariable
Use StrategybooltrueuseStrat
Detect BottomsbooltruedLong
Detect TopsbooltruedShort
Flip TradesbooltrueFLIP
Pivot Tolerancefloat15tol
Pivot Lengthint50len
Target Fibfloat100fib
Stop Loss Fibint0stopPer
Line Offsetint30offset
Start FiltertimetimeStartstartTime
End FiltertimetimeEndendTime
Use Trail StopboolfalseatrStop
Show all 37 settings
SettingTypeDefaultVariable
ATR Lengthint14atrLength
ATR Multiplierfloat1atrMult
Swing Lookbackint5lookback
Lines        colorcol1col
Patterns       colorcol3zCol
hWidthint1hWidth
zWidthint1zWidth
Stop Fillcolorcol2colf
Target Colorcolorcol4tCol
Stop Colorcolorcol5sCol
Trail Colorcolorcol6trailCol
Show TablebooltrueshowTable
Update LabelbooltruesetLab
Label Text SizestringsmalllabSize
Table Text SizestringnormaltextSize
Table PositionstringbottomtableYpos
tableXposstringrighttableXpos
3rd PartystringA1thirdParty
Json Passphrasestring1234pPhrase
Alertatron KeystringmyKeysaTronKey
TC TickerstringtcTicker
3Comma Longstringc3Long
3Comma Long Endstringc3LongEnd
3Comma Shortstringc3Short
3Comma Short Endstringc3ShortEnd
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

STRG-HOLP

by harryguiacorn
219 stars

STRG-HOLP is a trading strategy that identifies High of Low Period (HOLP) and Low of High Period (LOHP) breakout setups. It tracks the lowest low or highest high over a user-defined lookback window. A long trade opens when the close breaks above the high of th

Strategy v5 BreakoutSupport & resistance
Updated 1 year ago · None stated GitHub repository of STRG-HOLP

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 trades SOL perpetual candles on the price chart. It tracks confirmed pivot highs and lows as support and resistance circles, then compares close with a smoothed filter and a three-period EMA to mark long and short conditions after the bar closes.

Strategy v5 Moving averagesSupport & resistance 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