Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
- // © Goldburger
- // Note: we don't take fees into account. They should be insignificant for leveraged products vs the gainz, but still impact the bottom line.
- // 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.
- //We keep strategy open/close points for 2 reasons:
- // 1. Indication purposes. You can just follow this chart and when you see a position change, follow it.
- // 2. To get buy and hold performance in the backtest page for comparison.
- // 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.
- //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.
- // 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.
- //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
- //over 80%. However, Startegy Tester will report a paltry ~44%, a far cry from the real situation.
- //@version=4
- strategy("LeveragedStrat", overlay=true, default_qty_value=100, default_qty_type=strategy.percent_of_equity, calc_on_order_fills=true, currency="USD", precision=3)
- // Init
- ma_type = input("Volume Weighted", "MA Type", options = ["Simple", "Exponential", "Volume Weighted", "Weighted"])
- ma_len = input(200, "MA Length")
- underlying_symb = input("NASDAQ:QQQ", "Underlying", type=input.symbol)
- hedge_symb = input("AMEX:TMF", "Hedge", type=input.symbol)
- vola_symb = input("CBOE:VXN", "Underlying Vola Proxy", type=input.symbol)
- do_hedge = input(true, "Rotate Into Hedge")
- src = input(close, "Source")
- vola = security(vola_symb, "D", close)
- fromMonth = input(defval = 1, title = "From Month", type = input.integer, minval = 1, maxval = 12)
- fromDay = input(defval = 1, title = "From Day", type = input.integer, minval = 1, maxval = 31)
- fromYear = input(defval = 2000, title = "From Year", type = input.integer, minval = 1970)
- toMonth = input(defval = 0, title = "To Month", type = input.integer, minval = 0, maxval = 12)
- toDay = input(defval = 0, title = "To Day", type = input.integer, minval = 0, maxval = 31)
- toYear = input(defval = 0, title = "To Year", type = input.integer, minval = 0)
- toMonth := toMonth > 0? toMonth : month(timenow)
- toDay := toDay > 0? toDay : dayofmonth(timenow)
- toYear := toYear > 0? toYear : year(timenow)
- start = timestamp(fromYear, fromMonth, fromDay, 00, 00) // backtest start window
- finish = timestamp(toYear, toMonth, toDay, 23, 59) // backtest finish window
- window() => time >= start and time <= finish
- sell_atr_mult = input(16.0, "ATR Sell Signal Mult")
- buy_atr_mult = input(5.0, "ATR Buy Signal Mult")
- vola_thr = input(20.0, "Volatility Minimum For Trades")
- 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)
- var init_cash = strategy.initial_capital
- var init_price = -1.0
- if (init_price < 0.0) and window()
- init_price := close
- var curr_cash = strategy.initial_capital
- var curr_mode = 0 // 0 = not invested; 1 = downtrend (money in hedge); 2 = uptrend (money in leveraged security)
- var curr_pos = 0 // Entry position size for current strategy leg
- var leftovers = 0.0 // Uninvested cash
- hedge = security(hedge_symb, "D", close)
- underlying_c = security(underlying_symb, "D", close)
- underlying_l = security(underlying_symb, "D", low)
- underlying_h = security(underlying_symb, "D", high)
- atr = security(underlying_symb, "D", atr(ma_len))
- underlying_ma = security(underlying_symb, "D", ma_fn(src, ma_len))
- // Current cash value computation
- if ((curr_mode == 1) and do_hedge)
- curr_cash := (curr_pos * hedge) + leftovers
- else if(curr_mode == 2)
- curr_cash := (curr_pos * close) + leftovers
- // Drawdown computation
- max_val = 0.0
- max_val := bar_index > 0? max(max_val[1], curr_cash) : curr_cash // Latest peak for drawdown
- curr_drawdown = 0.0
- curr_drawdown := bar_index > 0? max(curr_drawdown[1], (max_val - curr_cash) / max_val) : 0.0
- max_drawdown = 0.0
- max_drawdown := bar_index > 0? max(max_drawdown[1], curr_drawdown) : 0.0
- ready = true // Prevent simultaneous selling and buying
- // Strategy update
- longCondition = (vola > vola_thr) and (underlying_c < underlying_ma - buy_atr_mult * atr) and ready[1] and window()
- if (longCondition)
- strategy.entry("Buy", strategy.long, when = window())
- curr_mode := 2
- ready := false
- curr_pos := floor(curr_cash / close)
- leftovers := curr_cash - (curr_pos * close)
- shortCondition = (vola > vola_thr) and (underlying_c > underlying_ma + sell_atr_mult * atr) and ready[1] and (curr_mode == 2) and window()
- if (shortCondition)
- strategy.close("Buy", when = window())
- curr_mode := 1
- ready := false
- curr_pos := floor(curr_cash / hedge)
- leftovers := curr_cash - (curr_pos * hedge)
- // Plots
- plot(underlying_ma * (close/underlying_c), title="Underlying MA (Scaled)")
- init_pos = floor(init_cash / init_price)
- 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)
- plot(100.0 * (curr_cash / init_cash), title="Total Returns %", color=color.green)
- plot(100.0 * max_drawdown, title="Max Drawdown %", color=color.red)
- plot(vola, title="Volatility", color=color.purple)
Add Comment
Please, Sign In to add comment