Guest User

Untitled

a guest
Aug 23rd, 2020
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.12 KB | None | 0 0
  1. // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
  2. // © Goldburger
  3. // Note: we don't take fees into account. They should be insignificant for leveraged products vs the gainz, but still impact the bottom line.
  4. // The backtesting results are to be ignored since it's not possible as far as I know to create a multi-symbol strategy. Instead we manually update total cash value.
  5. //We keep strategy open/close points for 2 reasons:
  6. // 1. Indication purposes. You can just follow this chart and when you see a position change, follow it.
  7. // 2. To get buy and hold performance in the backtest page for comparison.
  8. // The lines can individually be turned on/off, so if the profit tally is getting in the way of the underlying/MA, it can be ticked off in the settings.
  9. //Unfortunately, as far as I'm aware, there's no way to pop it off as non-overlayed or to scale it to something more reasonable while keeping the value display.
  10. // Note on max drawdown: TradingView now reports it based on net profit, i.e. excluding open profit. Here we calculate the TRUE max drawdown, that is incluidng open profit.
  11. //Thus, you cannot rely on the calculation in the strategy tester tab for comparison. Taking 2000-01-01 to today, SOXL-TMF strat, the max drawdown is approx. 76%. For buy and hold, it is
  12. //over 80%. However, Startegy Tester will report a paltry ~44%, a far cry from the real situation.
  13.  
  14. //@version=4
  15. strategy("LeveragedStrat", overlay=true, default_qty_value=100, default_qty_type=strategy.percent_of_equity, calc_on_order_fills=true, currency="USD", precision=3)
  16.  
  17. // Init
  18. ma_type = input("Volume Weighted", "MA Type", options = ["Simple", "Exponential", "Volume Weighted", "Weighted"])
  19. ma_len = input(200, "MA Length")
  20. underlying_symb = input("NASDAQ:QQQ", "Underlying", type=input.symbol)
  21. hedge_symb = input("BATS:VXX", "Hedge", type=input.symbol)
  22. vola_symb = input("CBOE:VXN", "Underlying Vola Proxy", type=input.symbol)
  23. do_hedge = input(true, "Rotate Into Hedge")
  24. src = input(close, "Source")
  25.  
  26. vola = security(vola_symb, "D", close)
  27.  
  28. fromMonth = input(defval = 1, title = "From Month", type = input.integer, minval = 1, maxval = 12)
  29. fromDay = input(defval = 1, title = "From Day", type = input.integer, minval = 1, maxval = 31)
  30. fromYear = input(defval = 2000, title = "From Year", type = input.integer, minval = 1970)
  31. toMonth = input(defval = 0, title = "To Month", type = input.integer, minval = 0, maxval = 12)
  32. toDay = input(defval = 0, title = "To Day", type = input.integer, minval = 0, maxval = 31)
  33. toYear = input(defval = 0, title = "To Year", type = input.integer, minval = 0)
  34. toMonth := toMonth > 0? toMonth : month(timenow)
  35. toDay := toDay > 0? toDay : dayofmonth(timenow)
  36. toYear := toYear > 0? toYear : year(timenow)
  37. start = timestamp(fromYear, fromMonth, fromDay, 00, 00) // backtest start window
  38. finish = timestamp(toYear, toMonth, toDay, 23, 59) // backtest finish window
  39. window() => time >= start and time <= finish
  40.  
  41. sell_atr_mult = input(16.0, "ATR Sell Signal Mult")
  42. buy_atr_mult = input(4.0, "ATR Buy Signal Mult")
  43.  
  44. vola_thr_buy = input(35.0, "Volatility Minimum For Buy")
  45. vola_thr_sell = input(15.0, "Volatility Minimum For Sell")
  46.  
  47. ma_fn(s, lgt) => ma_type == "Simple"? sma(s, lgt) : ma_type == "Exponential"? ema(s, lgt) : ma_type == "Volume Weighted"? vwma(s, lgt) : wma(s, lgt)
  48.  
  49. var init_cash = strategy.initial_capital
  50. var init_price = -1.0
  51. if (init_price < 0.0) and window()
  52. init_price := close
  53. var curr_cash = strategy.initial_capital
  54. var curr_mode = 0 // 0 = not invested; 1 = downtrend (money in hedge); 2 = uptrend (money in leveraged security)
  55. var curr_pos = 0 // Entry position size for current strategy leg
  56. var leftovers = 0.0 // Uninvested cash
  57.  
  58. hedge = security(hedge_symb, "D", close)
  59. underlying_c = security(underlying_symb, "D", close)
  60. underlying_l = security(underlying_symb, "D", low)
  61. underlying_h = security(underlying_symb, "D", high)
  62. atr = security(underlying_symb, "D", atr(ma_len))
  63. underlying_ma = security(underlying_symb, "D", ma_fn(src, ma_len))
  64.  
  65. // Current cash value computation
  66. if ((curr_mode == 1) and do_hedge)
  67. curr_cash := (curr_pos * hedge) + leftovers
  68. else if(curr_mode == 2)
  69. curr_cash := (curr_pos * close) + leftovers
  70.  
  71. // Drawdown computation
  72. max_val = 0.0
  73. max_val := bar_index > 0? max(max_val[1], curr_cash) : curr_cash // Latest peak for drawdown
  74. curr_drawdown = 0.0
  75. curr_drawdown := bar_index > 0? max(curr_drawdown[1], (max_val - curr_cash) / max_val) : 0.0
  76. max_drawdown = 0.0
  77. max_drawdown := bar_index > 0? max(max_drawdown[1], curr_drawdown) : 0.0
  78. ready = true // Prevent simultaneous selling and buying
  79.  
  80. // Strategy update
  81. longCondition = ((vola > vola_thr_buy) and (underlying_c < underlying_ma - buy_atr_mult * atr)) and ready[1] and window()
  82. if (longCondition)
  83. strategy.entry("Buy", strategy.long, when = window())
  84. curr_mode := 2
  85. ready := false
  86. curr_pos := floor(curr_cash / close)
  87. leftovers := curr_cash - (curr_pos * close)
  88.  
  89. shortCondition = (vola > vola_thr_sell) and (underlying_c > underlying_ma + sell_atr_mult * atr) and ready[1] and (curr_mode == 2) and window()
  90. if (shortCondition)
  91. strategy.close("Buy", when = window())
  92. curr_mode := 1
  93. ready := false
  94. curr_pos := floor(curr_cash / hedge)
  95. leftovers := curr_cash - (curr_pos * hedge)
  96.  
  97. // Plots
  98. scaled_ma = underlying_ma * (close/underlying_c)
  99. plot(scaled_ma, title="Underlying MA (Scaled)")
  100. init_pos = floor(init_cash / init_price)
  101. plot(init_price > 0.0 ? 100.0 * ((init_pos * close + (init_cash - init_pos * init_price)) / init_cash) : na, title="Buy & Hold %", color=color.olive)
  102. plot(window()? 100.0 * (curr_cash / init_cash) : na, title="Total Returns %", color=color.green)
  103. plot(window()? 100.0 * max_drawdown : na, title="Max Drawdown %", color=color.red)
  104. plot(vola, title="Volatility", color=color.teal)
  105. plot(window()? scaled_ma + (sell_atr_mult * atr) * (close/underlying_c) : na, title="Sell Range", color=color.purple)
  106. plot(window()? scaled_ma - (buy_atr_mult * atr) * (close/underlying_c) : na, title="Buy Range", color=color.purple)
Add Comment
Please, Sign In to add comment