igorkrnic

Untitled

Jun 21st, 2022
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.07 KB | None | 0 0
  1. //@version=5
  2.  
  3. //---------------------------------//YT: 1min Scalping Strategy\\---------------------------------\\
  4.  
  5. strategy('Minute Master Pro', process_orders_on_close=true, overlay = true)
  6.  
  7. //---------------------------------//Options\\---------------------------------\\
  8. // Session Filter
  9. showsession = input.bool(defval=false, title='', inline='Session')
  10. session2 = input.session(defval='0000-0000', title='Session Timings(to avoid trades)', inline='Session')
  11.  
  12. rr = input.float(defval=1.5, minval=0.1, step = 0.1, title = "Risk : Reward = 1 : ", group = "Strategy Options") // input rr for tp
  13. sloption = input.string(defval='ATR', title='SL ', group = "Strategy Options") // sl options
  14. sltext = input.float(defval=0.85,minval=0.1,step=0.1,title="ATR Multiplier", group = "Strategy Options") // atr multilier input
  15. atrlength = input.int(defval=14, title='ATR Length', group='Strategy Options')
  16. emaFilter = input.int(title='EMA Filter', defval=200, group='Strategy Options', tooltip='EMA length to filter trades - set to zero to disable')
  17. lookback = input.int(defval=5, minval=0, step=1, title='ADX Lookback', group='Strategy Options')
  18. 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')
  19. useexitcond = input(defval=false, title='Use Exit Condition', tooltip=' Set RR to 10! Strategy Dashboard Results inaccurate')
  20.  
  21. // Backtester Settings
  22. var g_tester = 'Backtester Settings'
  23. startBalance = input.float(title='Starting Balance', defval=10000.0, group=g_tester, tooltip='Your starting balance for the custom inbuilt tester system')
  24. riskPerTrade = input.float(title='Risk Per Trade', defval=1.0, group=g_tester, tooltip='Your desired % risk per trade (as a whole number)')
  25. drawTester = input.bool(title='Draw Backtester', defval=true, group=g_tester, tooltip='Turn on/off inbuilt backtester display')
  26.  
  27. //------------------------//Backtester Options\\------------------------\\
  28.  
  29. var g_filter = 'Filter Settings'
  30. 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')
  31. 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')
  32.  
  33.  
  34. //-----------------------------//EMA Filter\\---------------------------------\\
  35.  
  36. ema = ta.ema(close, emaFilter == 0 ? 1 : emaFilter)
  37.  
  38. //-----------------------------// Filter\\---------------------------------\\
  39.  
  40. width = 5
  41. upcolor = color.green
  42. downcolor = color.red
  43.  
  44. TF_1_time = input("1", "Timeframe 1")
  45. TF_2_time = input("10", "Timeframe 2")
  46. TF_3_time = input("15", "Timeframe 3")
  47. TF_4_time = input("30", "Timeframe 4")
  48.  
  49. lengthKC=input(20, title="KC Length")
  50. multKC = input(1.5, title="KC MultFactor")
  51. lengthBB=input(20, title="BB Length")
  52.  
  53. kc() =>
  54. ma = ta.sma(close, lengthKC)
  55. rang = ta.tr
  56. rangema = ta.sma(rang, lengthKC)
  57. upperKC = ma + rangema * multKC
  58. lowerKC = ma - rangema * multKC
  59. [lowerKC, upperKC]
  60.  
  61. bb() =>
  62. source = close
  63. basis = ta.sma(source, lengthBB)
  64. dev = multKC * ta.stdev(source, lengthBB)
  65. upperBB = basis + dev
  66. lowerBB = basis - dev
  67. [upperBB, lowerBB]
  68.  
  69. TF_1 = request.security(syminfo.tickerid, TF_1_time, open) < request.security(syminfo.tickerid, TF_1_time, close) ? true:false
  70. TF_1_color = TF_1 ? upcolor:downcolor
  71.  
  72. TF_2 = request.security(syminfo.tickerid, TF_2_time, open) < request.security(syminfo.tickerid, TF_2_time, close) ? true:false
  73. TF_2_color = TF_2 ? upcolor:downcolor
  74.  
  75. TF_3 = request.security(syminfo.tickerid, TF_3_time, open) < request.security(syminfo.tickerid, TF_3_time, close) ? true:false
  76. TF_3_color = TF_3 ? upcolor:downcolor
  77.  
  78. TF_4 = request.security(syminfo.tickerid, TF_4_time, open) < request.security(syminfo.tickerid, TF_4_time, close) ? true:false
  79. TF_4_color = TF_4 ? upcolor:downcolor
  80.  
  81. TF_global = TF_1 and TF_2 and TF_3 and TF_4
  82. TF_global_bear = TF_1 == false and TF_2 == false and TF_3 == false and TF_4 == false
  83. TF_global_color = TF_global ? color.green : TF_global_bear ? color.red : color.white
  84. TF_trigger_width = TF_global ? 6 : width
  85.  
  86. exitCondition_Long = TF_global_bear
  87. exitCondition_Short = TF_global
  88.  
  89. longCondition = TF_global
  90. shortCondition = TF_global_bear
  91.  
  92. barcolor(longCondition?color.lime:shortCondition?color.red:na)
  93. [kc_lower,kc_upper] = kc()
  94.  
  95. nobull=close < kc_upper
  96. nobear=close > kc_lower
  97. barcolor(nobull?color.yellow:nobear?color.yellow:na)
  98.  
  99. n=input(title="Trend Lenght Period",defval=88)
  100.  
  101. n2ma=2*ta.wma(close,math.round(n/2))
  102. nma=ta.wma(close,n)
  103. diff=n2ma-nma
  104. sqn=math.round(math.sqrt(n))
  105.  
  106. n2ma1=2*ta.wma(close[1],math.round(n/2))
  107. nma1=ta.wma(close[1],n)
  108. diff1=n2ma1-nma1
  109. sqn1=math.round(math.sqrt(n))
  110.  
  111. n1=ta.wma(diff,sqn)
  112. n2=ta.wma(diff1,sqn)
  113. c=n1>n2?color.lime:color.red
  114. plot(n1,color=c, linewidth = 1)
  115. //plot(n2,color=c, linewidth = 1)
  116. BullX=ta.crossover(n1,n2)
  117. BearX=ta.crossunder(n1,n2)
  118.  
  119. //---------------------------------//ADX Code\\---------------------------------\\
  120.  
  121. len = input(14, title='ADX Length', group='ADX Settings')
  122. th = input(20, title='ADX threshold', group='ADX Settings')
  123.  
  124. TrueRange = math.max(math.max(high - low, math.abs(high - nz(close[1]))), math.abs(low - nz(close[1])))
  125. DirectionalMovementPlus = high - nz(high[1]) > nz(low[1]) - low ? math.max(high - nz(high[1]), 0) : 0
  126. DirectionalMovementMinus = nz(low[1]) - low > high - nz(high[1]) ? math.max(nz(low[1]) - low, 0) : 0
  127.  
  128. SmoothedTrueRange = 0.0
  129. SmoothedTrueRange := nz(SmoothedTrueRange[1]) - nz(SmoothedTrueRange[1]) / len + TrueRange
  130.  
  131. SmoothedDirectionalMovementPlus = 0.0
  132. SmoothedDirectionalMovementPlus := nz(SmoothedDirectionalMovementPlus[1]) - nz(SmoothedDirectionalMovementPlus[1]) / len + DirectionalMovementPlus
  133.  
  134. SmoothedDirectionalMovementMinus = 0.0
  135. SmoothedDirectionalMovementMinus := nz(SmoothedDirectionalMovementMinus[1]) - nz(SmoothedDirectionalMovementMinus[1]) / len + DirectionalMovementMinus
  136.  
  137. DIPlus = SmoothedDirectionalMovementPlus / SmoothedTrueRange * 100
  138. DIMinus = SmoothedDirectionalMovementMinus / SmoothedTrueRange * 100
  139. DX = math.abs(DIPlus - DIMinus) / (DIPlus + DIMinus) * 100
  140. ADX = ta.sma(DX, len)
  141.  
  142. //plot(DIPlus, color=color.new(color.green, 0), title='DI+')
  143. //plot(DIMinus, color=color.new(color.red, 0), title='DI-')
  144. //plot(ADX, color=color.new(color.navy, 0), title='ADX')
  145. //hline(th, color=color.black)
  146.  
  147.  
  148. //---------------------------------//ATR Code\\---------------------------------\\
  149.  
  150. //length = input.int(title='Length', defval=14, minval=1)
  151. smoothing = input.string(title='ATR Smoothing', defval='RMA', options=['RMA', 'SMA', 'EMA', 'WMA'], group='ATR Settings')
  152. //m = input(0.85, 'Multiplier')
  153. src1 = input(high)
  154. src2 = input(low)
  155. pline = input(true, 'Show Price Lines', group='ATR Settings')
  156. col1 = input(color.blue, 'ATR Text Color', group='ATR Settings')
  157. col2 = input.color(color.teal, 'Low Text Color', group='ATR Settings', inline='1')
  158. col3 = input.color(color.red, 'High Text Color', group='ATR Settings', inline='2')
  159.  
  160. collong = input.color(color.gray, 'Low Line Color', inline='1', group='ATR Settings')
  161. colshort = input.color(color.gray, 'High Line Color', inline='2', group='ATR Settings')
  162.  
  163. ma_function(source, atrlength) =>
  164. if smoothing == 'RMA'
  165. ta.rma(source, atrlength)
  166. else
  167. if smoothing == 'SMA'
  168. ta.sma(source, atrlength)
  169. else
  170. if smoothing == 'EMA'
  171. ta.ema(source, atrlength)
  172. else
  173. ta.wma(source, atrlength)
  174.  
  175. a = ma_function(ta.tr(true), atrlength) * sltext
  176. ssl = ma_function(ta.tr(true), atrlength) * sltext + src1
  177. lsl = src2 - ma_function(ta.tr(true), atrlength) * sltext
  178.  
  179. p1 = plot(ssl, title='ATR Short Stop Loss', color=colshort, trackprice=pline ? true : false, transp=20)
  180. p2 = plot(lsl, title='ATR Long Stop Loss', color=collong, trackprice=pline ? true : false, transp=20)
  181.  
  182. //---------------------------------//ATR Code\\---------------------------------\\
  183.  
  184. //lengthatr = input.int(title="Length", defval=14, minval=1, group = "ATR Settings")
  185. smoothing1 = input.string(title="Smoothing", defval="RMA", options=["RMA", "SMA", "EMA", "WMA"], group = "ATR Settings")
  186. ma_function1(source, lengthatr) =>
  187. switch smoothing1
  188. "RMA" => ta.rma(source, atrlength)
  189. "SMA" => ta.sma(source, atrlength)
  190. "EMA" => ta.ema(source, atrlength)
  191. => ta.wma(source, atrlength)
  192.  
  193. atr1=(ma_function1(ta.tr(true), atrlength))*sltext
  194.  
  195. //---------------------------------//Candle Size\\---------------------------------\\
  196.  
  197. open_pos = open * 1
  198. close_pos = close * 1
  199.  
  200. // Body size as a percentage of the total candle
  201. diffcandle = math.abs(close_pos - open_pos)
  202.  
  203. //---------------------------------//Logic\\---------------------------------\\
  204.  
  205. // See if bar's time happened within the time filter
  206. session = time('1', session2 + string(':1234567'), str.tostring(syminfo.timezone))
  207. sessioncond = showsession ? not session : true
  208.  
  209.  
  210. // See if this bar's time happened within date filter
  211. dateFilter = time >= i_startTime and time <= i_endTime
  212.  
  213. // Check Candle Size
  214. candlesizefilter= diffcandle <= candlesize
  215.  
  216. // Check EMA Filter
  217. emaFilterLong = emaFilter == 0 or close > ema
  218. emaFilterShort = emaFilter == 0 or close < ema
  219.  
  220. // Check ADX
  221. adxlongcond = ta.crossover(DIPlus, DIMinus) or ta.barssince(ta.crossover(DIPlus, DIMinus)) < lookback
  222. adxshortcond = ta.crossunder(DIPlus, DIMinus) or ta.barssince(ta.crossunder(DIPlus, DIMinus)) < lookback
  223.  
  224. // Check Trend Filter
  225. trendfilterlong= close>n1 and open>n1 and n1>n2
  226. trendfiltershort= close<n1 and open<n1 and n1<n2
  227.  
  228. // Check Candle Color
  229. longfilter=longCondition
  230. shortfilter=shortCondition
  231.  
  232. // Determine if we have a valid setup
  233. validBullSignal = longfilter and adxlongcond and emaFilterLong and trendfilterlong and sessioncond and dateFilter and candlesizefilter and close != open and close > open
  234. validBearSignal = shortfilter and adxshortcond and emaFilterShort and trendfiltershort and sessioncond and dateFilter and candlesizefilter and close != open and close < open
  235.  
  236. // Check if we have confirmation for our setup
  237. validLong = validBullSignal and strategy.position_size == 0 and barstate.isconfirmed
  238. validShort = validBearSignal and strategy.position_size == 0 and barstate.isconfirmed
  239.  
  240. // Calculate our stop distance & size for the current bar
  241. stopSize = atr1
  242. longStopPrice = low < low[1] ? low - stopSize : low[1] - stopSize
  243. longStopDistance = close - longStopPrice
  244. longTargetPrice = close + longStopDistance * rr
  245. shortStopPrice = high > high[1] ? high + stopSize : high[1] + stopSize
  246. shortStopDistance = shortStopPrice - close
  247. shortTargetPrice = close - shortStopDistance * rr
  248.  
  249. // Save trade stop & target & position size if a valid setup is detected
  250. var t_entry = 0.0
  251. var t_stop = 0.0
  252. var t_target = 0.0
  253. var t_direction = 0
  254.  
  255. // Detect valid long setups & trigger alert
  256. if validLong
  257. t_entry := close
  258. t_stop := longStopPrice
  259. t_target := longTargetPrice
  260. t_direction := 1
  261. strategy.entry(id='Long', direction=strategy.long, when=validLong)
  262. alert(message= "Long Entry", freq=alert.freq_once_per_bar_close)
  263.  
  264. // Detect valid short setups & trigger alert
  265. if validShort
  266. t_entry := close
  267. t_stop := shortStopPrice
  268. t_target := shortTargetPrice
  269. t_direction := -1
  270. strategy.entry(id='Short', direction=strategy.short, when=validShort)
  271. alert(message= "Short Entry", freq=alert.freq_once_per_bar_close)
  272.  
  273. longexitcond = useexitcond ? adxshortcond and strategy.openprofit >= 0 : false
  274. shortexitcond = useexitcond ? adxlongcond and strategy.openprofit >= 0 : false
  275.  
  276. if (strategy.position_size>0 and longexitcond)
  277. strategy.close_all(comment = "Exit Long", alert_message = "Exit Long")
  278.  
  279. if (strategy.position_size < 0 and shortexitcond)
  280. strategy.close_all(comment = "Exit Short", alert_message = "Exit Short")
  281.  
  282. // Exit trades whenever our stop or target is hit
  283. strategy.exit(id='Long Exit', from_entry='Long', limit=t_target, stop=t_stop, when=strategy.position_size > 0)
  284. strategy.exit(id='Short Exit', from_entry='Short', limit=t_target, stop=t_stop, when=strategy.position_size < 0)
  285.  
  286. // Draw trade data
  287. 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)
  288. 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)
  289. 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)
  290. fill(sl, entry, color=color.new(color.red, 80))
  291. fill(tp, entry, color=color.new(color.green, 80))
  292.  
  293. // Draw EMA if it's enabled
  294. plot(emaFilter == 0 ? na : ema, color=emaFilterLong ? color.green : color.red, linewidth=2, title='EMA')
  295.  
  296. //---------------------------------//Dashbaord\\---------------------------------\\
  297.  
  298. // Custom function to truncate (cut) excess decimal places
  299. truncate(_number, _decimalPlaces) =>
  300. _factor = math.pow(10, _decimalPlaces)
  301. int(_number * _factor) / _factor
  302.  
  303. // --- BEGIN TESTER CODE --- //
  304. // Declare performance tracking variables
  305. var balance = startBalance
  306. var drawdown = 0.0
  307. var maxDrawdown = 0.0
  308. var maxBalance = 0.0
  309. var totalPips = 0.0
  310. var totalWins = 0
  311. var totalLoss = 0
  312.  
  313. // Detect winning trades
  314. if strategy.wintrades != strategy.wintrades[1]
  315. balance += riskPerTrade / 100 * balance * rr
  316. //totalPips += math.abs(t_entry - t_target)
  317. totalWins += 1
  318. if balance > maxBalance
  319. maxBalance := balance
  320. maxBalance
  321.  
  322. // Detect losing trades
  323. if strategy.losstrades != strategy.losstrades[1]
  324. balance -= riskPerTrade / 100 * balance
  325. //totalPips -= math.abs(t_entry - t_stop)
  326. totalLoss += 1
  327. // Update drawdown
  328. drawdown := balance / maxBalance - 1
  329. if drawdown < maxDrawdown
  330. maxDrawdown := drawdown
  331. maxDrawdown
  332.  
  333. // ProfitFactor returns the strategy's current profit factor,
  334. ProfitFactor = strategy.grossprofit / strategy.grossloss
  335.  
  336. maxloss = math.round(maxDrawdown*(-100))/riskPerTrade
  337.  
  338. winrate = (strategy.wintrades / strategy.closedtrades) * 100
  339.  
  340. initbalance = startBalance
  341.  
  342.  
  343. // Prepare stats table
  344. var table testTable = table.new(position.top_right, 5, 3, border_width=1)
  345. f_fillCell(_table, _column, _row, _title, _value, _bgcolor, _txtcolor) =>
  346. _cellText = _title + '\n' + _value
  347. table.cell(_table, _column, _row, _cellText, bgcolor=_bgcolor, text_color=_txtcolor)
  348.  
  349. // Draw stats table
  350. var bgcolor = color.new(color.black, 0)
  351. if drawTester
  352. if barstate.islastconfirmedhistory
  353. // Update table
  354. dollarReturn = balance - startBalance
  355. f_fillCell(testTable, 0, 0, 'Backtest', str.tostring(syminfo.tickerid) , color.blue, color.white)
  356. f_fillCell(testTable, 0, 1, 'Minute Master', str.tostring(timeframe.period) + 'M' , color.blue, color.white)
  357. f_fillCell(testTable, 1, 0, 'Total Trades:', str.tostring(strategy.closedtrades), bgcolor, color.white)
  358. f_fillCell(testTable, 1, 1, 'Win Rate:', str.tostring(truncate(winrate, 2)) + '%', winrate > 40 ? color.green : color.red, color.white)// bgcolor, color.white)
  359. f_fillCell(testTable, 2, 0, 'Starting:', '$' + str.tostring(startBalance), bgcolor, color.white)
  360. f_fillCell(testTable, 2, 1, 'Ending:', '$' + str.tostring(truncate(balance, 2)), balance > initbalance ? color.green : color.red, color.white)
  361. f_fillCell(testTable, 3, 0, 'Profit Factor:', str.tostring(truncate(ProfitFactor, 2)), ProfitFactor > 0 ? color.green : color.red, color.white)
  362. 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)
  363. f_fillCell(testTable, 4, 0, 'Return:', (dollarReturn > 0 ? '+' : '') + str.tostring(truncate(dollarReturn / startBalance * 100, 2)) + '%', dollarReturn > 0 ? color.green : color.red, color.white)
  364. f_fillCell(testTable, 4, 1, 'Max DD:', str.tostring(truncate(maxDrawdown * 100, 2)) + '%', color.red, color.white)
  365.  
  366.  
  367.  
Advertisement
Add Comment
Please, Sign In to add comment