Strategy 24_SPY -- Using VIX to help time a simple trend following strategy for SPY
This strategy is free for all readers! It has a CAGR of 5.1%, MaxDD of -4.89%, a profit factor of 6.91, and a Sharpe ratio of 1.02.
Disclaimer: the following post is an organized representation of my research and project notes. It doesn’t represent any type of advice, financial or otherwise. Its purpose is to be informative and educational. Backtest results are based on historical data, not real-time data. There is no guarantee that these hypothetical results will continue in the future. Day trading is extremely risky, and I do not suggest running any of these strategies live.
This strategy is a simple experiment in testing out two different ideas that I came across on the internet. Actually, I think both of these strategies came to me via the HGT Signal chat room, but that doesn't really matter.
Below, you will see a tweet (uh, what are they called now?) by a relatively popular algo-trader about the VIX and SPY.
That's a bold claim, I think. Not that I have a better indicator/idea. I just find it hard to believe that there would be a "best". From what I can tell, the markets change and it's not uncommon for signals to lose their edge over time. Despite that, I decided I wanted to to test the claim. Unfortunately, the author doesn't explain exactly how they use the VIX/VIX3M and VIX6M, so I had to wing it.
I decided to test the filter on a simple public strategy (linked below). This strategy uses what is called a "zero-lag moving average". Again, bold claim. I am not a mathematician, but I think it would be difficult to create a true "zero-lag" moving average when using historical data. I think that is the nature of using historical data. There are some statistical methods you can use to "extend" a moving average (or whatever) past the most recent historical bar, to create a true zero-lag indicator, but it would still be estimating those future values (predicting). I plan on exploring this when I take on a complex trend indicator in the near future.
Zero-lag MA Trend Strategy -- TradingView
With both those ideas in hand, I decided to create this strategy. Since both the ideas for this strategy come from open sources, I have decided to make this strategy open as well. In it's current state, it trades rarely, but boasts a high win rate, profit factor, and Sharpe ratio. Hope you enjoy it.
Strategy 24_SPY Results
Stats Overview:
The full report can be seen at the link below:
Logic
Strategy 24 uses volatility indicators and moving averages to determine long and short trading opportunities.
Parameters
rr_ratio
: 1.1 (range: 1 to 3, step: 0.1)rr_ratio_stop
: 0.8 (range: 0.01 to 1, step: 0.05)lookback
: 34 (range: 3 to 100, step: 1)
Strategy 24 Long
Long Entry Conditions:
vix_diff < 0
zlma
crosses aboveema34
Long Exit Conditions:
Take Profit:
tp_long = FillPrice + (FillPrice - (zlma - atr252)) * 1.1
Stop Loss:
sl_long = zlma - atr252 * 0.8
Exit Rules:
If
vix_diff >= 0
→ "Filter Exit"If
zlma < ema34
→ "ZLMA crossed below EMA"
Strategy 24 Short
Short Entry Conditions:
vix_diff > 1
ema34
crosses abovezlma
Short Exit Conditions:
Take Profit:
tp_short = FillPrice - ((zlma - atr252) - FillPrice) * 2.5
Stop Loss:
sl_short = zlma + atr252 * 0.4
Exit Time: Next closing price (we wait to flatten the trade until the close, instead of the open)
Exit Rules:
If
vix_diff <= 0
→ "Filter Exit"If
Close > zlma
→ "Price crossed ZLMA"
Notes
ZLMA Calculation:
zlma = EMA(correction, lookback)
Explanation: The Zero-lag Long Moving Average (ZLMA) is derived by first adjusting the closing price with a correction factor (
correction = Close + (Close - ema34)
), then applying an Exponential Moving Average over thelookback
period. This enhances trend detection by emphasizing price movements relative to the EMA34.
VIX Diff calculation:
((vix / vix3m) * vix6m) - vix6m
Code
Notes:
Import: // requires Norgate Platinum subscription
DataSource: Norgate
IncludeList: $VIX, $VIX3M, $VIX6M
IncludeList: SPY
StartDate: 1/1/2005
EndDate: Latest
SaveAs: 24_SPY.rtd
Settings:
DataFile: 24_SPY.rtd
StartDate: 01/01/2007
EndDate: Latest // 12/12/2024
BarSize: Daily
AccountSize: 1e5
HolidayList: us_auto
Parameters:
rr_ratio: from 1 to 3 step 0.1 def 1.1
rr_ratio_stop: from 0.01 to 1 step 0.05 def 0.8
lookback: from 3 to 100 step 1 def 34
Data:
// ATR, non-Wilder's style. I just dropped the exponential smoothing.
var: Max(High - Low, High - Close[1], Close[1] - Low)
atr252: Sum(var, 252) / 252
ema34: EMA(Close, lookback)
correction: Close + (Close - ema34)
zlma: EMA(correction, lookback)
//Lodson VIX
vix: Extern($$VIX, Close)
vix3m: Extern($$VIX3M, Close)
vix6m: Extern($$VIX6M, Close)
vix_factor: (vix / vix3m) * vix6m
vix_diff: vix_factor - vix6m
// Strategy logic
long: InList(2) and vix_diff < 0 and cross(zlma, ema34)
short: InList(2) and vix_diff > 1 and cross(ema34, zlma)
Library:
sl_long: zlma - atr252 * 0.8
tp_long: FillPrice + (FillPrice - (zlma - atr252)) * 1.1
sl_short: zlma + atr252 * 0.4
tp_short: FillPrice - ((zlma - atr252) - FillPrice) * 2.5
Charts:
vix_diff: {|} vix_diff
sl_long: {} If(BarDate >= T.DateIn and BarDate <= T.DateOut, sl_long[barsheld], nan)
tp_long: {} If(BarDate >= T.DateIn and BarDate <= T.DateOut, tp_long[barsheld], nan)
ema34: {} ema34
zlma: {} zlma
Strategy: strategy_24_long
Allocation: S.Equity
QtyType: Percent
Commission: Max(1, 0.005 * Shares)
LimitExtra: 0.001 * C
Side: Long
Quantity: 100
EntrySetup: long
ExitLimit: tp_long[BarsHeld]
ExitStop: sl_long[BarsHeld]
ExitRule: Select(vix_diff >= 0, "Filter Exit", zlma < ema34, "ZLMA crossed below EMA")
Strategy: strategy_24_short
Allocation: S.Equity
QtyType: Percent
Commission: Max(1, 0.005 * Shares)
LimitExtra: 0.001 * C
Side: Short
Quantity: 100
EntrySetup: short
ExitLimit: tp_short[BarsHeld]
ExitStop: sl_short[BarsHeld]
ExitTime: NextClose
ExitRule: Select(vix_diff <= 0, "Filter Exit", Close > zlma, "Price crossed ZLMA")
Conclusion
If you liked this post and are interested in checking out the other strategies in the publication, subscribe/upgrade and check them out. Tomorrow's post is going to be the last strategy of 2024, then we are going to go to 2 strategy publications a month and fill in the gaps with other projects to help improve our algo trading game. we are going to start building strategy portfolios and get them running in simulation for some forward testing data. We are going to start building more complex indicators and importing their values into the RealTest backtesting engine to test them. We are also going to create some prediction models and test out their accuracy. You don't want to miss any of it.
Happy hunting.
Feel free to comment below or e-mail me if you need help with anything, wish to criticize, or have thoughts on improvements. You can also DM me or start a chat thread. Red Team members can access this code and more at the private HGT GitHub repo. As always, this newsletter represents refined versions of my research notes. That means these notes are plastic. There could be mistakes or better ways to accomplish what I am trying to do. Nothing is perfect, and I always look for ways to improve my techniques.