0bps

Strategy vault / Other

Bad guy strategy

Pine Script strategy by Zer3192.

Author
Zer3192
Complexity
Advanced · 296 lines
Parameters
18
Backtest bar
4h · intraday
Tested on
BTC/USDT · spot

The original spec has no written description. Read the source below.

Parameters

NameDefaultWhat it controls
v_input_1_open0src: open | high | low | close | hl2 | hlc3 | hlcc4 | ohlc4
v_input_20Longs / Shorts: Both | Longs | Shorts
v_input_55SL [%]
v_input_6falseActivate leverage?
v_input_73Max lev.
v_input_850Volume lenght lev.
v_input_30.7(?Backtesting)TP_L [%]
v_input_40.9TP_S [%]
v_input_9true(?BACKTEST)Backtest
v_input_10trueLongs
v_input_11trueShorts
v_input_12100risk
v_input_132000start year
v_input_14truestart month
v_input_15truestart day
v_input_163333stop year
v_input_1712stop month
v_input_1831stop day

Source Pine Script

/*backtest
start: 2021-05-08 00:00:00
end: 2022-05-07 23:59:00
period: 4h
basePeriod: 15m
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
//@version=4
strategy("Badb's strategy", overlay = true, pyramiding=1,initial_capital = 10000, default_qty_type= strategy.percent_of_equity, default_qty_value = 100, calc_on_order_fills=false, slippage=0,commission_type=strategy.commission.percent,commission_value=0.04)

//SOURCE =============================================================================================================================================================================================================================================================================================================

src                 =                   input(open)

// POSITION ==========================================================================================================================================================================================================================================================================================================

Position            =                   input("Both",                           title= "Longs / Shorts",                                    options = ["Both","Longs","Shorts"])

is_Long             =                   Position                                                    == "SHORT" ? na : true
is_Short            =                   Position                                                    == "LONG" ? na : true


ADX_options         =                   "MASANAKAMURA"
ADX_len             =                   22
th                  =                   19



c1                =                   19
c2                =                   2.5


x1         =                   12
x2         =                   16                                                            
x3         =                   9                                                        


u          =                   3.3
o          =                   20

n1                 =                   ""
n2                 =                   high


v1                 =                   0.5     
v2                 =                   0.2
v3                 =                   0.4

y          =                   2.7
i          =                   33                                                               


//ADX-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

calcADX(_len) =>
    up              =                                                                                                                       change(high)
	down            =                                                                                                                      -change(low)
	plusDM          =                                                                                                                       na(up)   ? na : (up > down and up > 0   ? up   : 0)
    minusDM         =                                                                                                                       na(down) ? na : (down > up and down > 0 ? down : 0)
	truerange       =                                                                                                                       rma(tr, _len)
	_plus           =                                                                                                                       fixnan(100 * rma(plusDM, _len)  / truerange)
	_minus          =                                                                                                                       fixnan(100 * rma(minusDM, _len) / truerange)
	sum             =                                                                                                                       _plus + _minus
	_adx            =                                                                                                                       100 * rma(abs(_plus - _minus) / (sum == 0 ? 1 : sum), _len)
    [_plus,_minus,_adx]
calcADX_Masanakamura(_len) =>
    SmoothedTrueRange                   =                                                                                                   0.0
    SmoothedDirectionalMovementPlus     =                                                                                                   0.0
    SmoothedDirectionalMovementMinus    =                                                                                                   0.0
    TrueRange                           =                                                                                                   max(max(high - low, abs(high - nz(close[1]))), abs(low - nz(close[1])))
    DirectionalMovementPlus             =                                                                                                   high - nz(high[1]) > nz(low[1]) - low ? max(high - nz(high[1]), 0) : 0
    DirectionalMovementMinus            =                                                                                                   nz(low[1]) - low > high - nz(high[1]) ? max(nz(low[1]) - low, 0)   : 0
    SmoothedTrueRange                   :=                                                                                                  nz(SmoothedTrueRange[1]) - (nz(SmoothedTrueRange[1]) /_len) + TrueRange
    SmoothedDirectionalMovementPlus     :=                                                                                                  nz(SmoothedDirectionalMovementPlus[1])  - (nz(SmoothedDirectionalMovementPlus[1])  / _len) + DirectionalMovementPlus
    SmoothedDirectionalMovementMinus    :=                                                                                                  nz(SmoothedDirectionalMovementMinus[1]) - (nz(SmoothedDirectionalMovementMinus[1]) / _len) + DirectionalMovementMinus
    DIP                                 =                                                                                                   SmoothedDirectionalMovementPlus  / SmoothedTrueRange * 100
    DIM                                 =                                                                                                   SmoothedDirectionalMovementMinus / SmoothedTrueRange * 100
    DX                                  =                                                                                                   abs(DIP-DIM) / (DIP+DIM)*100
    adx                                 =                                                                                                   sma(DX, _len)
    [DIP,DIM,adx]
[DIPlusC,DIMinusC,ADXC] =                                                                                                                   calcADX(ADX_len) 
[DIPlusM,DIMinusM,ADXM] =                                                                                                                   calcADX_Masanakamura(ADX_len)

DIPlus                  =                                                                                                                   ADX_options == "CLASSIC" ? DIPlusC    : DIPlusM
DIMinus                 =                                                                                                                   ADX_options == "CLASSIC" ? DIMinusC   : DIMinusM
ADX                     =                                                                                                                   ADX_options == "CLASSIC" ? ADXC       : ADXM
L_adx                   =                                                       DIPlus > DIMinus and ADX > th
S_adx                   =                                                       DIPlus < DIMinus and ADX > th

a1                 =                                                                                                                               ema(src, x1)
a2                 =                                                                                                                               ema(src, x2)
a3                    =                                                                                                                               a1 - a2
a4                 =                                                                                                                               sma(a3, x3)
L_a3                  =                                                       a3 > a4 
S_a3                  =                                                       a3 < a4 


var bool L_d = na,  var bool S_d = na

q(_src, _c1, _c2)=>
    var float d1   =                                                                                                                   0.0
    var float d2 =                                                                                                                   0.0
    d3                =                                                                                                                   (_c1*2) - 1
    d4               =                                                                                                                   ema(abs(_src - _src[1]), _c1)
    d5          =                                                                                                                   ema(d4, d3)*_c2
    d6               =                                                                                                                   _src
    d6               :=                                                                                                                  _src > nz(d6[1]) ? ((_src-d5) < nz(d6[1]) ? nz(d6[1]) : (_src-d5)) : ((_src+d5) > nz(d6[1]) ? nz(d6[1]) : (_src+d5))
    d1             :=                                                                                                                  d6 > d6[1] ? nz(d1[1]) + 1 : d6 < d6[1] ? 0 : nz(d1[1])
    d2           :=                                                                                                                  d6 < d6[1] ? nz(d2[1]) + 1 : d6 > d6[1] ? 0 : nz(d2[1])
    [d5,d6,d1,d2]
[d7, d8, d9, d10] = q(src, c1, c2)
d11                   =                                                                                                                   d8 + d7
d12                   =                                                                                                                   d8 - d7
L_d                    :=                                                      high > d11 and d9 > 0
S_d                    :=                                                      low < d12 and d10 > 0


f                     =                                                                                                                   sar(v1, v2, v3)
L_f                   =                                                       (f < close)
S_f                   =                                                       (f > close)


g1            =                                                       volume > sma(volume,o)*u
g2  =                                                       volume > sma(volume,i  )*y


h1                                        =                                                                                                                                                           20
j                                        =                                                                                                                                                           3.0
k                                         =                                                                                                                                                           security(syminfo.tickerid, n1, sma(n2 , h1))

k1                                         =                                                                                                                                                           k + security(syminfo.tickerid, n1, stdev(n2 , h1)) * j
l1                                         =                                                                                                                                                           k - security(syminfo.tickerid, n1, stdev(n2 , h1)) * j

L_BB_2 = close > k1
S_BB_2 = close > l1



//L/S variables----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

var bool longCond                    = na, var bool shortCond                   = na, longCond := nz(longCond[1]), shortCond := nz(shortCond[1])
var int CondIni_long                 = 0, var int CondIni_short                 = 0, CondIni_long := nz(CondIni_long[1]), CondIni_short := nz(CondIni_short[1])
var bool Final_longCondition         = na, var bool Final_shortCondition        = na, Final_longCondition := nz(Final_longCondition[1]), Final_shortCondition := nz(Final_shortCondition[1])
var bool BT_Final_longCondition      = na, var bool BT_Final_shortCondition     = na, BT_Final_longCondition := nz(BT_Final_longCondition[1]), BT_Final_shortCondition := nz(BT_Final_shortCondition[1])
var float last_open_longCondition    = na, var float last_open_shortCondition   = na
var int last_longCondition           = na, var int last_shortCondition          = na
var int nLongs = na, var int nShorts = na, nLongs := nz(nLongs[1]), nShorts     := nz(nShorts[1])

//STRATEGY ==========================================================================================================================================================================================================================================================================================================



L_1 =                                                              L_adx and g2 and L_d and L_f and L_a3
S_1 =                                                              S_adx and g2 and S_d and S_f and S_a3
//Add restrictions
L_2   =                                                               L_adx and L_f and L_a3 and L_d  and  g1 and g2
S_2   =                                                               S_adx and S_f and S_a3 and S_d  and  g1 and g2


L_3 =                                                             L_adx and L_BB_2 and g1 and g2 and L_d and L_a3
S_3 =                                                             S_adx and S_BB_2 and g1 and g2 and S_d and S_a3

Final_Long_Condt =                                                              L_2 or L_1 or L_3
Final_Short_Condt =                                                             S_2 or S_1 or S_3

longCond        :=                                                              Final_Long_Condt
shortCond       :=                                                              Final_Short_Condt

CondIni_long    :=                                                              longCond[1] ? 1 : shortCond[1] ? -1 : nz(CondIni_long[1])
CondIni_short   :=                                                              longCond[1] ? 1 : shortCond[1] ? -1 : nz(CondIni_short[1])
longCondition   =                                                               (longCond[1] and nz(CondIni_long[1]) == -1)
shortCondition  =                                                               (shortCond[1] and nz(CondIni_short[1]) == 1)

// Price position----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

var int last_long_sl = na, var int last_short_sl = na
last_open_longCondition             :=                                          longCondition ? close[1] :                                                      nz(last_open_longCondition[1])
last_open_shortCondition            :=                                          shortCondition ? close[1] :                                                     nz(last_open_shortCondition[1])
last_longCondition                  :=                                          longCondition ? time :                                                          nz(last_longCondition[1])
last_shortCondition                 :=                                          shortCondition ? time :                                                         nz(last_shortCondition[1])
in_longCondition                    =                                           last_longCondition > last_shortCondition
in_shortCondition                   =                                           last_shortCondition > last_longCondition

if longCondition
    nLongs                          :=                                          nLongs + 1
    nShorts                         :=                                          na
    
if shortCondition
    nLongs                          :=                                          na
    nShorts                         :=                                          nShorts + 1

Final_longCondition                 := is_Long          and longCondition
Final_shortCondition                := is_Short         and shortCondition

//TP_1 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

tp_l                     = input(0.7, "TP_L [%]",                     type    = input.float, step = 0.1, group="Backtesting") 
tp_s                     = input(0.9, "TP_S [%]",                     type    = input.float, step = 0.1, group="Backtesting") 

var bool long_tp        = na, var bool short_tp                                     = na
var int last_long_tp    = na, var int last_short_tp                                 = na
var bool Final_Long_tp  = na, var bool Final_Short_tp                               = na, Final_Long_tp := nz(Final_Long_tp[1]), Final_Short_tp := nz(Final_Short_tp[1])
long_tp                 := (is_Long and high > (last_open_longCondition*(1+(tp_l/100))) and  in_longCondition)
short_tp                := (is_Short and low < (last_open_shortCondition*(1-(tp_s/100))) and  in_shortCondition)
last_long_tp            := long_tp ? time : nz(last_long_tp[1])
last_short_tp           := short_tp ? time : nz(last_short_tp[1])
Final_Long_tp           := (long_tp and last_longCondition > nz(last_long_tp[1]) and last_longCondition > nz(last_long_sl[1]))
Final_Short_tp          := (short_tp and last_shortCondition > nz(last_short_tp[1]) and last_shortCondition > nz(last_short_sl[1]))
l_h = iff(Final_Long_tp, last_open_longCondition*(1+(tp_l/100)), na),
s_h = iff(Final_Short_tp, last_open_shortCondition*(1-(tp_s/100)), na)


// SL ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

sl                      = input(5, "SL [%]",                      type    = input.float, step = 0.1)
var int CondIni_long_sl = 0, var int CondIni_short_sl                               = 0
var bool Final_Long_sl0 = na, var bool Final_Short_sl0                              = na, Final_Long_sl0 := nz(Final_Long_sl0[1]), Final_Short_sl0 := nz(Final_Short_sl0[1])
var bool Final_Long_sl  = na, var bool Final_Short_sl                               = na, Final_Long_sl := nz(Final_Long_sl[1]), Final_Short_sl := nz(Final_Short_sl[1])
long_sl                 =  is_Long and low <= ((1-(sl/100))*last_open_longCondition) and not (open < ((1-(sl/100))*last_open_longCondition)) 
short_sl                =  is_Short and high >= ((1+(sl/100))*last_open_shortCondition) and not (open > ((1+(sl/100))*last_open_shortCondition))
Final_Long_sl0          := Position == "BOTH" ? long_sl and nz(CondIni_long_sl[1]) == -1 and not Final_Long_tp and not shortCondition  : long_sl and nz(CondIni_long_sl[1]) == -1 and not Final_Long_tp
Final_Short_sl0         := Position == "BOTH" ? short_sl and nz(CondIni_short_sl[1]) == -1 and not Final_Short_tp and not longCondition  : short_sl and nz(CondIni_short_sl[1]) == -1 and not Final_Short_tp
last_long_sl            := Final_Long_sl ? time : nz(last_long_sl[1])
last_short_sl           := Final_Short_sl ? time : nz(last_short_sl[1])
Final_Long_sl           := Final_Long_sl0 and last_longCondition > nz(last_long_tp[1]) and last_longCondition > nz(last_long_sl[1])
Final_Short_sl          := Final_Short_sl0 and last_shortCondition > nz(last_short_tp[1]) and last_shortCondition > nz(last_short_sl[1])
CondIni_long_sl         := Final_Long_tp or Final_Long_sl or  Final_shortCondition  ? 1 : Final_longCondition ? -1 : nz(CondIni_long_sl[1])
CondIni_short_sl        := Final_Short_tp or Final_Short_sl  or Final_longCondition  ? 1 : Final_shortCondition ? -1 : nz(CondIni_short_sl[1])

// Leverage ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

var float   last_leverage_L  = na,   var float   last_leverage_S = na

Act_Lev                 =           input(false,                                title="Activate leverage?"                                                                                                                  )
Max_Lev                 =           input(3,                                    title="Max lev.",                                                               type    = input.integer,   minval = 1,     maxval = 5       )
o_lev          =           input(50,                                   title="Volume lenght lev.",                                                     minval  = 1                                                 )

long = ((longCond and not in_longCondition) or (longCond and Final_Long_tp) or (longCond and Final_Long_sl)) or (longCond and not longCondition and (last_long_tp> nz(last_longCondition))) or (longCond and not longCondition and (last_long_sl > nz(last_longCondition))) 
Long      = (longCond and not in_longCondition) or (longCond and Final_Long_tp) or (longCond and Final_Long_sl) or (longCond and not longCondition and (last_long_tp >= nz(last_longCondition))) or (longCond and not longCondition and (last_long_sl >= nz(last_longCondition)))
short = ((shortCond and not in_shortCondition) or (shortCond and Final_Short_tp) or (shortCond and Final_Short_sl)) or (shortCond and not shortCondition and (last_short_tp > nz(last_shortCondition))) or (shortCond and not shortCondition and (last_short_sl > nz(last_shortCondition))) 
Short     = (shortCond and not in_shortCondition) or (shortCond and Final_Short_tp) or (shortCond and Final_Short_sl) or (shortCond and not shortCondition and (last_short_tp >= nz(last_shortCondition))) or (shortCond and not shortCondition and (last_short_sl >= nz(last_shortCondition)))




//RE-ENTRY ON TP-HIT-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

var float sum_long              =                                                           0.0,                                                                    var float sum_short = 0.0
var float Position_Price        =                                                           0.0

if Final_Long_tp or Final_Long_sl  
    CondIni_long                :=                                                          -1
    sum_long                    :=                                                          0.0
    nLongs                      :=                                                          na
if Final_Short_tp or Final_Short_sl
    CondIni_short               :=                                                          1
    sum_short                   :=                                                          0.0
    nShorts                     :=                                                          na
   

// PLOTSPAHES ======================================================================================================================================================================================================================================================================================================

plotshape(Final_Long_tp ,                 title="Long TP HIT",            style=shape.flag,                       location=location.abovebar,                         color=color.red,            size=size.small ,          textcolor=color.red,             transp = 0                          ) 
plotshape(Final_Short_tp ,                title="Short TP HIT",           style=shape.flag,                       location=location.belowbar,                         color=color.green,          size=size.small ,          textcolor=color.green,           transp = 0                          ) 

//BACKTESTING inputs --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

ACT_BT              =                   input(true,                             title="Backtest",                                           type = input.bool,                                                              group= "BACKTEST")
long_               =                   input(true,                             title="Longs",                                                                                                                              group= "BACKTEST")
short_              =                   input(true,                             title="Shorts",                                                                                                                             group= "BACKTEST")
risk                =                   input(100,                                                                                                                                                                          group= "BACKTEST")
testStartYear       =                   input(2000,                             title="start year",                                         minval = 1997, maxval = 3000,                                                   group= "BACKTEST") 
testStartMonth      =                   input(01,                               title="start month",                                        minval = 1, maxval = 12,                                                        group= "BACKTEST")
testStartDay        =                   input(01,                               title="start day",                                          minval = 1, maxval = 31,                                                        group= "BACKTEST")
testPeriodStart     =                   timestamp(testStartYear,testStartMonth,testStartDay,0,0)
testStopYear        =                   input(3333,                             title="stop year",                                          minval=1980, maxval = 2222,                                                     group= "BACKTEST")
testStopMonth       =                   input(12,                               title="stop month",                                         minval=1, maxval=12,                                                            group= "BACKTEST")
testStopDay         =                   input(31,                               title="stop day",                                           minval=1, maxval=31,                                                            group= "BACKTEST")
testPeriodStop      =                   timestamp(testStopYear, testStopMonth, testStopDay, 0, 0)
testPeriod          =                   time >= testPeriodStart and time <= testPeriodStop ? true : false

//BACKTESTING--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

if long and ACT_BT
    strategy.entry("L", strategy.long,when = testPeriod)


if short and ACT_BT
    strategy.entry("S", strategy.short,when = testPeriod)


strategy.exit("TP_L", "L", profit = (abs((last_open_longCondition   *       (1+(tp_l/100)))-last_open_longCondition)/syminfo.mintick),    loss = (abs((last_open_longCondition    *   (1-(sl/100)))-last_open_longCondition)/syminfo.mintick  ))

strategy.exit("TP_S", "S", profit = (abs((last_open_shortCondition  *       (1-(tp_s/100)))-last_open_shortCondition)/syminfo.mintick),   loss = (abs((last_open_shortCondition   *   (1+(sl/100)))-last_open_shortCondition)/syminfo.mintick ))

Published by Zer3192 on the FMZ strategy square · last modified 2022-08-29. Collected in the Quant Trading Vault. Unvalidated research: re-test with your own data and costs before trusting it.

Build this with AgenKit

A spec is not a trading system. Paste this into your coding agent and AgenKit runs a specialist team — architecture, test-first build, risk gates, review — with paper trading on by default.

in Claude Code, Cursor, Codex & 4 more
/agenkit build a production-grade trading bot with a backtest engine, risk controls and paper trading by default from strategies/Bad-guy-strategy.md
  1. npx agenkit install engineering-kit in your project
  2. Paste the command into your agent and approve each phase
  3. Get tests, backtest, risk controls and a paper-trading switch

Understand it first

Before you run this, read the lesson behind the idea and how to backtest it honestly. Specs like this one are the survivors of an unknown number of trials; deflate their results accordingly.

Related specs

esc

Try , , or .

↑↓ move↵ open