0bps

Strategy vault / Mean reversion

Price Volatility Mean Reversion Strategy

This strategy detects price reversal opportunities by calculating the standard deviation of price volatility. When there is an anomalously large price fluctuation, it is considered as an opportunity for price…

Author
ChaoZhang
Complexity
Intermediate · 78 lines
Parameters
18
Backtest bar
2d · swing
Tested on
BTC/USDT · futures

Overview

This strategy detects price reversal opportunities by calculating the standard deviation of price volatility. When there is an anomalously large price fluctuation, it is considered as an opportunity for price reversal, and reverse trading positions are taken.

Principle

The strategy uses two main indicators:

  1. VixFix indicator: Calculates the standard deviation of price over a certain period to determine if there is anomalous price volatility. The specific calculation is:
wvf = ((highest(close, pd)-low)/(highest(close, pd)))*100
sDev = mult * stdev(wvf, bbl) 
midLine = sma(wvf, bbl)
lowerBand = midLine - sDev 
upperBand = midLine + sDev

Where wvf is price volatility, sDev is standard deviation, midLine is the average line, lowerBand and upperBand are the lower and upper limit lines. When price exceeds the upper limit line, it is considered anomalous volatility.

  1. RSI indicator: Calculates the Relative Strength Index of price to determine timing of price reversal. The calculation is:
fastup = rma(max(change(close), 0), 7)
fastdown = rma(-min(change(close), 0), 7) 
fastrsi = fastdown == 0 ? 100 : fastup == 0 ? 0 : 100 - (100 / (1 + fastup / fastdown))

When RSI is below a threshold, it indicates oversold status and potential bounce back. When RSI exceeds a threshold, it indicates overbought status and potential pullback.

Entry and Exit

The entry and exit logic is:

Long entry: When price exceeds upper limit or volatility exceeds threshold, and RSI is below a value, go long.

Short entry: When price exceeds upper limit or volatility exceeds threshold, and RSI exceeds a value, go short.

Exit: When candlestick body direction is opposite of position direction, close position.

Advantages

  • Uses statistical properties of anomalous price volatility to determine price reversal with wide coverage.
  • Combining with RSI to judge overbought/oversold improves entry precision.
  • Breaking lower deviation band as entry signal reduces missing opportunities.
  • Candlestick body reversal as stop loss realizes quick stop loss and reduces losses.

Risks

  • Lower deviation band may need adjustment for parameter optimization.
  • Breaking lower band does not guarantee reversal, risks being trapped.
  • RSI parameters need optimization, improper values lead to inaccurate signals.
  • Candlestick body stop loss may be too aggressive, needs adjustment.

Optimization Directions

  • Optimize calculation period of standard deviation to better capture anomalous volatility.
  • Optimize RSI parameters to find better overbought/oversold criteria.
  • Try combining other indicators like KDJ, MACD to determine reversal timing.
  • Optimize stop loss mechanism, set price retracement as stop loss benchmark.

Conclusion

The strategy detects anomalous price volatility through calculating standard deviation of price volatility, to capture reversal opportunities. RSI is combined to judge overbought/oversold status for improving entry precision. Simple candlestick body direction stop loss is used. Overall, the strategy is effective in using statistical data to detect anomalous volatility, but needs further parameter optimization to improve stability. If the stop loss mechanism can be reasonably optimized to reduce losses, the strategy would perform even better.

Parameters

NameDefaultWhat it controls
v_input_1trueLong
v_input_2trueShort
v_input_3trueleverage
v_input_440RSI Limit
v_input_522LookBack Period Standard Deviation High
v_input_620Bolinger Band Length
v_input_72Bollinger Band Standard Devaition Up
v_input_850Look Back Period Percentile High
v_input_90.85Highest Percentile - 0.90=90%, 0.95=95%, 0.99=99%
v_input_101.01Lowest Percentile - 1.10=90%, 1.05=95%, 1.01=99%
v_input_11falseShow High Range - Based on Percentile and LookBack Period?
v_input_12falseShow Standard Deviation Line?
v_input_131900From Year
v_input_142100To Year
v_input_15trueFrom Month
v_input_1612To Month
v_input_17trueFrom day
v_input_1831To day

Source Pine Script

/*backtest
start: 2022-10-04 00:00:00
end: 2023-10-10 00:00:00
period: 2d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//Noro
//2018

//@version=2
strategy(title = "Noro's VixFix + RSI Strategy v1.0", shorttitle = "VixFix + RSI str 1.0", overlay = true, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, pyramiding = 5)

//Settings
needlong = input(true, defval = true, title = "Long")
needshort = input(true, defval = true, title = "Short")
leverage = input(1, defval = 1, minval = 1, maxval = 100, title = "leverage")
limit = input(40, defval = 40, minval = 2, maxval = 50, title = "RSI Limit")

pd = input(22, title="LookBack Period Standard Deviation High")
bbl = input(20, title="Bolinger Band Length")
mult = input(2.0, minval = 1, maxval = 5, title = "Bollinger Band Standard Devaition Up")
lb = input(50, title="Look Back Period Percentile High")
ph = input(.85, title="Highest Percentile - 0.90=90%, 0.95=95%, 0.99=99%")
pl = input(1.01, title="Lowest Percentile - 1.10=90%, 1.05=95%, 1.01=99%")
hp = input(false, title="Show High Range - Based on Percentile and LookBack Period?")
sd = input(false, title="Show Standard Deviation Line?")

fromyear = input(1900, defval = 1900, minval = 1900, maxval = 2100, title = "From Year")
toyear = input(2100, defval = 2100, minval = 1900, maxval = 2100, title = "To Year")
frommonth = input(01, defval = 01, minval = 01, maxval = 12, title = "From Month")
tomonth = input(12, defval = 12, minval = 01, maxval = 12, title = "To Month")
fromday = input(01, defval = 01, minval = 01, maxval = 31, title = "From day")
today = input(31, defval = 31, minval = 01, maxval = 31, title = "To day")

//Vix Fix
wvf = ((highest(close, pd)-low)/(highest(close, pd)))*100
sDev = mult * stdev(wvf, bbl)
midLine = sma(wvf, bbl)
lowerBand = midLine - sDev
upperBand = midLine + sDev
rangeHigh = (highest(wvf, lb)) * ph
rangeLow = (lowest(wvf, lb)) * pl

col = wvf >= upperBand or wvf >= rangeHigh ? lime : gray

//RSI
fastup = rma(max(change(close), 0), 7)
fastdown = rma(-min(change(close), 0), 7)
fastrsi = fastdown == 0 ? 100 : fastup == 0 ? 0 : 100 - (100 / (1 + fastup / fastdown))

//Body
body = abs(close - open)
abody = sma(body, 10)

//Signals
up = (wvf >= upperBand or wvf >= rangeHigh) and fastrsi < limit and close < open
dn = (wvf >= upperBand or wvf >= rangeHigh) and fastrsi > (100 - limit) and close > open
exit = ((strategy.position_size > 0 and close > open) or (strategy.position_size < 0 and close < open)) and body > abody / 3

//Trading
lot = strategy.position_size == 0 ? strategy.equity / close * leverage : lot[1]

if up
    if strategy.position_size < 0
        strategy.close_all()
        
    strategy.entry("Bottom", strategy.long, needlong == false ? 0 : lot, when=(time > timestamp(fromyear, frommonth, fromday, 00, 00) and time < timestamp(toyear, tomonth, today, 23, 59)))

if dn
    if strategy.position_size > 0
        strategy.close_all()
        
    strategy.entry("Top", strategy.short, needshort == false ? 0 : lot, when=(time > timestamp(fromyear, frommonth, fromday, 00, 00) and time < timestamp(toyear, tomonth, today, 23, 59)))
    
if time > timestamp(toyear, tomonth, today, 23, 59) or exit
    strategy.close_all()

Published by ChaoZhang on the FMZ strategy square · last modified 2023-10-11. Collected in the Quant Trading Vault. Unvalidated research: re-test with your own data and costs before trusting it.

Build this with AgenKit

A spec is not a trading system. Paste this into your coding agent and AgenKit runs a specialist team — architecture, test-first build, risk gates, review — with paper trading on by default.

in Claude Code, Cursor, Codex & 4 more
/agenkit build a production-grade trading bot with a backtest engine, risk controls and paper trading by default from strategies/Price-Volatility-Mean-Reversion-Strategy.md
  1. npx agenkit install engineering-kit in your project
  2. Paste the command into your agent and approve each phase
  3. Get tests, backtest, risk controls and a paper-trading switch

Understand it first

Before you run this, read the lesson behind the idea and how to backtest it honestly. Specs like this one are the survivors of an unknown number of trials; deflate their results accordingly.

Related specs

esc

Try , , or .

↑↓ move↵ open