Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //@version=5
- //---------------------------------//YT: 1min Scalping Strategy\\---------------------------------\\
- strategy('Minute Master Pro', process_orders_on_close=true, overlay = true)
- //---------------------------------//Options\\---------------------------------\\
- // Session Filter
- showsession = input.bool(defval=false, title='', inline='Session')
- session2 = input.session(defval='0000-0000', title='Session Timings(to avoid trades)', inline='Session')
- rr = input.float(defval=1.5, minval=0.1, step = 0.1, title = "Risk : Reward = 1 : ", group = "Strategy Options") // input rr for tp
- sloption = input.string(defval='ATR', title='SL ', group = "Strategy Options") // sl options
- sltext = input.float(defval=0.85,minval=0.1,step=0.1,title="ATR Multiplier", group = "Strategy Options") // atr multilier input
- atrlength = input.int(defval=14, title='ATR Length', group='Strategy Options')
- emaFilter = input.int(title='EMA Filter', defval=200, group='Strategy Options', tooltip='EMA length to filter trades - set to zero to disable')
- lookback = input.int(defval=5, minval=0, step=1, title='ADX Lookback', group='Strategy Options')
- candlesize = input.float(defval=0.001, minval=0, step=0.001, title='Big Ass Candle Filter', group='Strategy Options', tooltip='Please refer to Candle Size AP Indicator for reference')
- useexitcond = input(defval=false, title='Use Exit Condition', tooltip=' Set RR to 10! Strategy Dashboard Results inaccurate')
- // Backtester Settings
- var g_tester = 'Backtester Settings'
- startBalance = input.float(title='Starting Balance', defval=10000.0, group=g_tester, tooltip='Your starting balance for the custom inbuilt tester system')
- riskPerTrade = input.float(title='Risk Per Trade', defval=1.0, group=g_tester, tooltip='Your desired % risk per trade (as a whole number)')
- drawTester = input.bool(title='Draw Backtester', defval=true, group=g_tester, tooltip='Turn on/off inbuilt backtester display')
- //------------------------//Backtester Options\\------------------------\\
- var g_filter = 'Filter Settings'
- i_startTime = input.time(title='Start Date Filter', defval=timestamp('01 Jan 2000 13:30 +0000'), group=g_filter, tooltip='Date & time to begin trading from')
- i_endTime = input.time(title='End Date Filter', defval=timestamp('1 Jan 2099 19:30 +0000'), group=g_filter, tooltip='Date & time to stop trading')
- //-----------------------------//EMA Filter\\---------------------------------\\
- ema = ta.ema(close, emaFilter == 0 ? 1 : emaFilter)
- //-----------------------------// Filter\\---------------------------------\\
- width = 5
- upcolor = color.green
- downcolor = color.red
- TF_1_time = input("1", "Timeframe 1")
- TF_2_time = input("10", "Timeframe 2")
- TF_3_time = input("15", "Timeframe 3")
- TF_4_time = input("30", "Timeframe 4")
- lengthKC=input(20, title="KC Length")
- multKC = input(1.5, title="KC MultFactor")
- lengthBB=input(20, title="BB Length")
- kc() =>
- ma = ta.sma(close, lengthKC)
- rang = ta.tr
- rangema = ta.sma(rang, lengthKC)
- upperKC = ma + rangema * multKC
- lowerKC = ma - rangema * multKC
- [lowerKC, upperKC]
- bb() =>
- source = close
- basis = ta.sma(source, lengthBB)
- dev = multKC * ta.stdev(source, lengthBB)
- upperBB = basis + dev
- lowerBB = basis - dev
- [upperBB, lowerBB]
- TF_1 = request.security(syminfo.tickerid, TF_1_time, open) < request.security(syminfo.tickerid, TF_1_time, close) ? true:false
- TF_1_color = TF_1 ? upcolor:downcolor
- TF_2 = request.security(syminfo.tickerid, TF_2_time, open) < request.security(syminfo.tickerid, TF_2_time, close) ? true:false
- TF_2_color = TF_2 ? upcolor:downcolor
- TF_3 = request.security(syminfo.tickerid, TF_3_time, open) < request.security(syminfo.tickerid, TF_3_time, close) ? true:false
- TF_3_color = TF_3 ? upcolor:downcolor
- TF_4 = request.security(syminfo.tickerid, TF_4_time, open) < request.security(syminfo.tickerid, TF_4_time, close) ? true:false
- TF_4_color = TF_4 ? upcolor:downcolor
- TF_global = TF_1 and TF_2 and TF_3 and TF_4
- TF_global_bear = TF_1 == false and TF_2 == false and TF_3 == false and TF_4 == false
- TF_global_color = TF_global ? color.green : TF_global_bear ? color.red : color.white
- TF_trigger_width = TF_global ? 6 : width
- exitCondition_Long = TF_global_bear
- exitCondition_Short = TF_global
- longCondition = TF_global
- shortCondition = TF_global_bear
- barcolor(longCondition?color.lime:shortCondition?color.red:na)
- [kc_lower,kc_upper] = kc()
- nobull=close < kc_upper
- nobear=close > kc_lower
- barcolor(nobull?color.yellow:nobear?color.yellow:na)
- n=input(title="Trend Lenght Period",defval=88)
- n2ma=2*ta.wma(close,math.round(n/2))
- nma=ta.wma(close,n)
- diff=n2ma-nma
- sqn=math.round(math.sqrt(n))
- n2ma1=2*ta.wma(close[1],math.round(n/2))
- nma1=ta.wma(close[1],n)
- diff1=n2ma1-nma1
- sqn1=math.round(math.sqrt(n))
- n1=ta.wma(diff,sqn)
- n2=ta.wma(diff1,sqn)
- c=n1>n2?color.lime:color.red
- plot(n1,color=c, linewidth = 1)
- //plot(n2,color=c, linewidth = 1)
- BullX=ta.crossover(n1,n2)
- BearX=ta.crossunder(n1,n2)
- //---------------------------------//ADX Code\\---------------------------------\\
- len = input(14, title='ADX Length', group='ADX Settings')
- th = input(20, title='ADX threshold', group='ADX Settings')
- TrueRange = math.max(math.max(high - low, math.abs(high - nz(close[1]))), math.abs(low - nz(close[1])))
- DirectionalMovementPlus = high - nz(high[1]) > nz(low[1]) - low ? math.max(high - nz(high[1]), 0) : 0
- DirectionalMovementMinus = nz(low[1]) - low > high - nz(high[1]) ? math.max(nz(low[1]) - low, 0) : 0
- SmoothedTrueRange = 0.0
- SmoothedTrueRange := nz(SmoothedTrueRange[1]) - nz(SmoothedTrueRange[1]) / len + TrueRange
- SmoothedDirectionalMovementPlus = 0.0
- SmoothedDirectionalMovementPlus := nz(SmoothedDirectionalMovementPlus[1]) - nz(SmoothedDirectionalMovementPlus[1]) / len + DirectionalMovementPlus
- SmoothedDirectionalMovementMinus = 0.0
- SmoothedDirectionalMovementMinus := nz(SmoothedDirectionalMovementMinus[1]) - nz(SmoothedDirectionalMovementMinus[1]) / len + DirectionalMovementMinus
- DIPlus = SmoothedDirectionalMovementPlus / SmoothedTrueRange * 100
- DIMinus = SmoothedDirectionalMovementMinus / SmoothedTrueRange * 100
- DX = math.abs(DIPlus - DIMinus) / (DIPlus + DIMinus) * 100
- ADX = ta.sma(DX, len)
- //plot(DIPlus, color=color.new(color.green, 0), title='DI+')
- //plot(DIMinus, color=color.new(color.red, 0), title='DI-')
- //plot(ADX, color=color.new(color.navy, 0), title='ADX')
- //hline(th, color=color.black)
- //---------------------------------//ATR Code\\---------------------------------\\
- //length = input.int(title='Length', defval=14, minval=1)
- smoothing = input.string(title='ATR Smoothing', defval='RMA', options=['RMA', 'SMA', 'EMA', 'WMA'], group='ATR Settings')
- //m = input(0.85, 'Multiplier')
- src1 = input(high)
- src2 = input(low)
- pline = input(true, 'Show Price Lines', group='ATR Settings')
- col1 = input(color.blue, 'ATR Text Color', group='ATR Settings')
- col2 = input.color(color.teal, 'Low Text Color', group='ATR Settings', inline='1')
- col3 = input.color(color.red, 'High Text Color', group='ATR Settings', inline='2')
- collong = input.color(color.gray, 'Low Line Color', inline='1', group='ATR Settings')
- colshort = input.color(color.gray, 'High Line Color', inline='2', group='ATR Settings')
- ma_function(source, atrlength) =>
- if smoothing == 'RMA'
- ta.rma(source, atrlength)
- else
- if smoothing == 'SMA'
- ta.sma(source, atrlength)
- else
- if smoothing == 'EMA'
- ta.ema(source, atrlength)
- else
- ta.wma(source, atrlength)
- a = ma_function(ta.tr(true), atrlength) * sltext
- ssl = ma_function(ta.tr(true), atrlength) * sltext + src1
- lsl = src2 - ma_function(ta.tr(true), atrlength) * sltext
- p1 = plot(ssl, title='ATR Short Stop Loss', color=colshort, trackprice=pline ? true : false, transp=20)
- p2 = plot(lsl, title='ATR Long Stop Loss', color=collong, trackprice=pline ? true : false, transp=20)
- //---------------------------------//ATR Code\\---------------------------------\\
- //lengthatr = input.int(title="Length", defval=14, minval=1, group = "ATR Settings")
- smoothing1 = input.string(title="Smoothing", defval="RMA", options=["RMA", "SMA", "EMA", "WMA"], group = "ATR Settings")
- ma_function1(source, lengthatr) =>
- switch smoothing1
- "RMA" => ta.rma(source, atrlength)
- "SMA" => ta.sma(source, atrlength)
- "EMA" => ta.ema(source, atrlength)
- => ta.wma(source, atrlength)
- atr1=(ma_function1(ta.tr(true), atrlength))*sltext
- //---------------------------------//Candle Size\\---------------------------------\\
- open_pos = open * 1
- close_pos = close * 1
- // Body size as a percentage of the total candle
- diffcandle = math.abs(close_pos - open_pos)
- //---------------------------------//Logic\\---------------------------------\\
- // See if bar's time happened within the time filter
- session = time('1', session2 + string(':1234567'), str.tostring(syminfo.timezone))
- sessioncond = showsession ? not session : true
- // See if this bar's time happened within date filter
- dateFilter = time >= i_startTime and time <= i_endTime
- // Check Candle Size
- candlesizefilter= diffcandle <= candlesize
- // Check EMA Filter
- emaFilterLong = emaFilter == 0 or close > ema
- emaFilterShort = emaFilter == 0 or close < ema
- // Check ADX
- adxlongcond = ta.crossover(DIPlus, DIMinus) or ta.barssince(ta.crossover(DIPlus, DIMinus)) < lookback
- adxshortcond = ta.crossunder(DIPlus, DIMinus) or ta.barssince(ta.crossunder(DIPlus, DIMinus)) < lookback
- // Check Trend Filter
- trendfilterlong= close>n1 and open>n1 and n1>n2
- trendfiltershort= close<n1 and open<n1 and n1<n2
- // Check Candle Color
- longfilter=longCondition
- shortfilter=shortCondition
- // Determine if we have a valid setup
- validBullSignal = longfilter and adxlongcond and emaFilterLong and trendfilterlong and sessioncond and dateFilter and candlesizefilter and close != open and close > open
- validBearSignal = shortfilter and adxshortcond and emaFilterShort and trendfiltershort and sessioncond and dateFilter and candlesizefilter and close != open and close < open
- // Check if we have confirmation for our setup
- validLong = validBullSignal and strategy.position_size == 0 and barstate.isconfirmed
- validShort = validBearSignal and strategy.position_size == 0 and barstate.isconfirmed
- // Calculate our stop distance & size for the current bar
- stopSize = atr1
- longStopPrice = low < low[1] ? low - stopSize : low[1] - stopSize
- longStopDistance = close - longStopPrice
- longTargetPrice = close + longStopDistance * rr
- shortStopPrice = high > high[1] ? high + stopSize : high[1] + stopSize
- shortStopDistance = shortStopPrice - close
- shortTargetPrice = close - shortStopDistance * rr
- // Save trade stop & target & position size if a valid setup is detected
- var t_entry = 0.0
- var t_stop = 0.0
- var t_target = 0.0
- var t_direction = 0
- // Detect valid long setups & trigger alert
- if validLong
- t_entry := close
- t_stop := longStopPrice
- t_target := longTargetPrice
- t_direction := 1
- strategy.entry(id='Long', direction=strategy.long, when=validLong)
- alert(message= "Long Entry", freq=alert.freq_once_per_bar_close)
- // Detect valid short setups & trigger alert
- if validShort
- t_entry := close
- t_stop := shortStopPrice
- t_target := shortTargetPrice
- t_direction := -1
- strategy.entry(id='Short', direction=strategy.short, when=validShort)
- alert(message= "Short Entry", freq=alert.freq_once_per_bar_close)
- longexitcond = useexitcond ? adxshortcond and strategy.openprofit >= 0 : false
- shortexitcond = useexitcond ? adxlongcond and strategy.openprofit >= 0 : false
- if (strategy.position_size>0 and longexitcond)
- strategy.close_all(comment = "Exit Long", alert_message = "Exit Long")
- if (strategy.position_size < 0 and shortexitcond)
- strategy.close_all(comment = "Exit Short", alert_message = "Exit Short")
- // Exit trades whenever our stop or target is hit
- strategy.exit(id='Long Exit', from_entry='Long', limit=t_target, stop=t_stop, when=strategy.position_size > 0)
- strategy.exit(id='Short Exit', from_entry='Short', limit=t_target, stop=t_stop, when=strategy.position_size < 0)
- // Draw trade data
- sl=plot(strategy.position_size != 0 or validLong or validShort ? t_stop : na, title='Trade Stop Price', color=color.new(color.red, 0), style=plot.style_linebr)
- entry=plot(strategy.position_size != 0 or validLong or validShort ? t_entry : na, title='Trade Stop Price', color=color.new(color.white, 50), style=plot.style_linebr)
- tp=plot(strategy.position_size != 0 or validLong or validShort ? t_target : na, title='Trade Target Price', color=color.new(color.green, 0), style=plot.style_linebr)
- fill(sl, entry, color=color.new(color.red, 80))
- fill(tp, entry, color=color.new(color.green, 80))
- // Draw EMA if it's enabled
- plot(emaFilter == 0 ? na : ema, color=emaFilterLong ? color.green : color.red, linewidth=2, title='EMA')
- //---------------------------------//Dashbaord\\---------------------------------\\
- // Custom function to truncate (cut) excess decimal places
- truncate(_number, _decimalPlaces) =>
- _factor = math.pow(10, _decimalPlaces)
- int(_number * _factor) / _factor
- // --- BEGIN TESTER CODE --- //
- // Declare performance tracking variables
- var balance = startBalance
- var drawdown = 0.0
- var maxDrawdown = 0.0
- var maxBalance = 0.0
- var totalPips = 0.0
- var totalWins = 0
- var totalLoss = 0
- // Detect winning trades
- if strategy.wintrades != strategy.wintrades[1]
- balance += riskPerTrade / 100 * balance * rr
- //totalPips += math.abs(t_entry - t_target)
- totalWins += 1
- if balance > maxBalance
- maxBalance := balance
- maxBalance
- // Detect losing trades
- if strategy.losstrades != strategy.losstrades[1]
- balance -= riskPerTrade / 100 * balance
- //totalPips -= math.abs(t_entry - t_stop)
- totalLoss += 1
- // Update drawdown
- drawdown := balance / maxBalance - 1
- if drawdown < maxDrawdown
- maxDrawdown := drawdown
- maxDrawdown
- // ProfitFactor returns the strategy's current profit factor,
- ProfitFactor = strategy.grossprofit / strategy.grossloss
- maxloss = math.round(maxDrawdown*(-100))/riskPerTrade
- winrate = (strategy.wintrades / strategy.closedtrades) * 100
- initbalance = startBalance
- // Prepare stats table
- var table testTable = table.new(position.top_right, 5, 3, border_width=1)
- f_fillCell(_table, _column, _row, _title, _value, _bgcolor, _txtcolor) =>
- _cellText = _title + '\n' + _value
- table.cell(_table, _column, _row, _cellText, bgcolor=_bgcolor, text_color=_txtcolor)
- // Draw stats table
- var bgcolor = color.new(color.black, 0)
- if drawTester
- if barstate.islastconfirmedhistory
- // Update table
- dollarReturn = balance - startBalance
- f_fillCell(testTable, 0, 0, 'Backtest', str.tostring(syminfo.tickerid) , color.blue, color.white)
- f_fillCell(testTable, 0, 1, 'Minute Master', str.tostring(timeframe.period) + 'M' , color.blue, color.white)
- f_fillCell(testTable, 1, 0, 'Total Trades:', str.tostring(strategy.closedtrades), bgcolor, color.white)
- f_fillCell(testTable, 1, 1, 'Win Rate:', str.tostring(truncate(winrate, 2)) + '%', winrate > 40 ? color.green : color.red, color.white)// bgcolor, color.white)
- f_fillCell(testTable, 2, 0, 'Starting:', '$' + str.tostring(startBalance), bgcolor, color.white)
- f_fillCell(testTable, 2, 1, 'Ending:', '$' + str.tostring(truncate(balance, 2)), balance > initbalance ? color.green : color.red, color.white)
- f_fillCell(testTable, 3, 0, 'Profit Factor:', str.tostring(truncate(ProfitFactor, 2)), ProfitFactor > 0 ? color.green : color.red, color.white)
- f_fillCell(testTable, 3, 1, 'Consec. Loss:', str.tostring(maxloss), maxloss <= 5 ? color.green : color.red, color.white)//color.new(color.red,50), bgcolor, color.white)
- f_fillCell(testTable, 4, 0, 'Return:', (dollarReturn > 0 ? '+' : '') + str.tostring(truncate(dollarReturn / startBalance * 100, 2)) + '%', dollarReturn > 0 ? color.green : color.red, color.white)
- f_fillCell(testTable, 4, 1, 'Max DD:', str.tostring(truncate(maxDrawdown * 100, 2)) + '%', color.red, color.white)
Advertisement
Add Comment
Please, Sign In to add comment