RSI-VWAP Price-Volume Strategy - FMZ (2024)

  1. Square
  2. RSI-VWAP Price-Volume Strategy

Author: ChaoZhang, Date: 2023-10-08 13:52:09
Tags:

Overview

The RSI-VWAP price-volume strategy is a trend following strategy. It combines the Relative Strength Index (RSI) and Volume Weighted Average Price (VWAP) to implement pyramiding and stop loss in trends. This strategy is suitable for medium-to-long term trend trading.

Principle

When the RSI line falls from the overbought zone into the oversold zone, it is considered a trend reversal signal to go long. When the RSI line rises from the oversold zone into the overbought zone, it is considered a trend reversal signal to go short.

The stop loss for long positions is set at (1-stop loss percentage) of the latest entry price. The take profit is set at (1+take profit percentage) of the average holding price. The settings for short positions are similar.

After each new entry, the strategy allows up to 5 additional pyramiding entries if the signal triggers again. The position size increases with each new entry to follow the trend.

Advantages

  1. Combining the RSI indicator and VWAP indicator helps better identify trend reversal points.

  2. Pyramiding entries allow taking full advantage of trending moves. As the number of entries increases, the position size gradually expands to follow the trend.

  3. The stop loss effectively controls risks. Exits are triggered when a loss occurs to avoid further losses.

  4. The trailing take profit locks in profits and avoids giving back gains.

Risks

  1. The RSI indicator has repainting. Actual signal timing may deviate.

  2. VWAP may also repaint. The actual optimal entry can only be determined in hindsight.

  3. Improper stop loss placement may cause unnecessary losses.

  4. Improper take profit placement may prevent gains from being realized.

  5. Wrong trend judgment can increase losses from persistently holding long or short positions.

Enhancements

  1. Optimize RSI parameters to find the optimal lookback period.

  2. Optimize the overbought/oversold zones for better trend reversal signals.

  3. Test different pyramiding strategies to find the optimal approach.

  4. Optimize the stops and takes to find the best parameters.

  5. Try combining other indicators to increase probability of accurately detecting trend reversals.

Conclusion

The RSI-VWAP strategy identifies trend reversal points using RSI and VWAP, pyramids to follow the trend, takes profit when predefined targets are met, and stops out with a loss. It balances risk management and profit protection. Further optimizations can improve strategy performance. This strategy suits experienced traders for medium-to-long term trend trading.

/*backteststart: 2023-09-07 00:00:00end: 2023-10-07 00:00:00period: 2hbasePeriod: 15mexchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]*/// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/// © Xaviz//#####©ÉÉÉɶN###############################################//####*..´´´´´´,,,»ëN########################################//###ë..´´´´´´,,,,,,''%©#####################################//###'´´´´´´,,,,,,,'''''?¶###################################//##o´´´´´´,,,,,,,''''''''*©#################################//##'´´´´´,,,,,,,'''''''^^^~±################################//#±´´´´´,,,,,,,''''''''^í/;~*©####æ%;í»~~~~;==I±N###########//#»´´´´,,,,,,'''''''''^;////;»¶X/í~~/~~~;=~~~~~~~~*¶########//#'´´´,,,,,,''''''''^^;////;%I^~/~~/~~~=~~~;=?;~~~~;?ë######//©´´,,,,,,,''''''''^^~/////X~/~~/~~/~~»í~~=~~~~~~~~~~^;É####//¶´,,,,,,,''''''''^^^;///;%;~/~~;í~~»~í?~?~~~?I/~~~~?*=íÑ###//N,,,,,,,'''''''^^^^^///;;o/~~;;~~;£=»í»;IX/=~~~~~~^^^^'*æ##//#í,,,,,''''''''^^^^^;;;;;o~»~~~~íX//~/»~;í?IíI»~~^/*?'''=N#//#%,,,'''''''''^^^^^^í;;;;£;~~~//»I»/£X/X/»í*&~~~^^^^'^*~'É#//#©,,''''''''^^^^^^^^~;;;;&/~/////*X;í;o*í»~=*?*===^'''''*£#//##&''''''''^^^^^^^^^^~;;;;X=í~~~»;;;/~;í»~»±;^^^^^';=''''É#//##N^''''''^^^^^^^^^^~~~;;;;/£;~~/»~~»~~///o~~^^^^''''?^',æ#//###Ñ''''^^^^^^^^^^^~~~~~;;;;;í*X*í»;~~IX?~~^^^^/?'''''=,=##//####X'''^^^^^^^^^^~~~~~~~~;;íííííí~~í*=~~~~Ií^'''=''''^»©##//#####£^^^^^^^^^^^~~~~~~~~~~~íííííí~~~~~*~^^^;/''''='',,N###//######æ~^^^^^^^^~~~~~~~~~~~~~~íííí~~~~~^*^^^'=''''?',,§####//########&^^^^^^~~~~~~~~~~~~~~~~~~~~~~~^^=^^''=''''?,íN#####//#########N?^^~~~~~~~~~~~~~~~~~~~~~~~~^^^=^''^?''';í@#######//###########N*~~~~~~~~~~~~~~~~~~~~~~~^^^*'''^='''/É#########//##############@;~~~~~~~~~~~~~~~~~~~^^~='''~?'';É###########//#################É=~~~~~~~~~~~~~~^^^*~'''*~?§##############//#####################N§£I/~~~~~~»*?~»o§æN##################//@version=4// strategy("RSI-VWAP", overlay=true, initial_capital = 1000, currency = "USD", pyramiding = 5, default_qty_type = strategy.cash, default_qty_value = 1000, commission_value = 0.04)//Uncomment for alerts//study("RSI-VWAP INDICATOR", overlay=true)// ================================================================================================================================================================================// VARIABLES// ================================================================================================================================================================================var bool longCondition = na, var bool shortCondition = na, var bool Xlong = na,var int CondIni_Xlong = 0, var bool XlongCondition = navar float last_open_longCondition = na, var float last_open_shortCondition = navar int last_longCondition = 0, var int last_shortCondition = 0var int last_long_sl = na, var int last_short_sl = navar bool CondIni_long_sl = 0, var bool CondIni_short_sl = 0var int nLongs = na, var int nShorts = na, var int pyr = navar float sum_long = 0.0, var float sum_short = 0.0var float Position_Price = 0.0, Position_Price := nz(Position_Price[1])var bool Final_Long_sl = na, var bool Final_Short_sl = na, var bool Act_sl = na, var float sl = navar int last_long_tp = na, var int last_short_tp = navar bool CondIni_long_tp = 0, var bool CondIni_short_tp = 0var float Quantity = na, var float Increase = navar float sum_qty_l = na, var float sum_qty_s = na// ================================================================================================================================================================================// RSI VWAP INDICATOR// ================================================================================================================================================================================// Initial inputsPositions = input("LONG ONLY", "LONG / SHORT", options = ["LONG & SHORT","LONG ONLY"])Long_only = Positions == "LONG ONLY" ? true : naAct_RSI_VWAP = input(true, "RSI VOLUME WEIGHTED AVERAGE PRICE")RSI_VWAP_length = input(17, "RSI-VWAP LENGTH")RSI_VWAP_overSold = input(19, "RSI-VWAP OVERSOLD", type=input.float)RSI_VWAP_overBought = input(80, "RSI-VWAP OVERBOUGHT", type=input.float)// RSI with VWAP as sourceRSI_VWAP = rsi(vwap(close), RSI_VWAP_length)// Plotting, overlay=false//r=plot(RSI_VWAP, color = RSI_VWAP > RSI_VWAP_overBought ? color.red : RSI_VWAP < RSI_VWAP_overSold ? color.lime : color.teal, title="rsi", linewidth=2, style=plot.style_line)//h1=plot(RSI_VWAP_overBought, color = color.gray, style=plot.style_stepline)//h2=plot(RSI_VWAP_overSold, color = color.gray, style=plot.style_stepline)//fill(r,h1, color = RSI_VWAP > RSI_VWAP_overBought ? color.red : na, transp = 75)//fill(r,h2, color = RSI_VWAP < RSI_VWAP_overSold ? color.lime : na, transp = 75)// ================================================================================================================================================================================// STRATEGY// ================================================================================================================================================================================// Long/Short/Xlong ConditionslongCondition := (crossover(RSI_VWAP, RSI_VWAP_overSold)) and (nz(nLongs[1]) < pyr)shortCondition := (crossunder(RSI_VWAP, RSI_VWAP_overBought)) and (nz(nShorts[1]) < pyr) and not Long_onlyXlong := (crossunder(RSI_VWAP, RSI_VWAP_overBought)) and Long_onlyCondIni_Xlong := longCondition ? 1 : Xlong ? -1 : nz(CondIni_Xlong[1])XlongCondition := Xlong and nz(CondIni_Xlong[1]) == 1// Get the price of the last opened long or shortlast_open_longCondition := longCondition ? close : nz(last_open_longCondition[1])last_open_shortCondition := shortCondition ? close : nz(last_open_shortCondition[1])// Get the bar time of the last opened long or shortlast_longCondition := longCondition ? time : nz(last_longCondition[1])last_shortCondition := shortCondition ? time : nz(last_shortCondition[1])// In long/short conditionsin_longCondition = last_longCondition > last_shortConditionin_shortCondition = last_shortCondition > last_longCondition// ================================================================================================================================================================================// PRICE AVERAGE / PYRAMIDING// ================================================================================================================================================================================// Pyramidingpyr := input(5, "PYRAMIDING 🎢")// Counting long & short iterationsnLongs := nz(nLongs[1])nShorts := nz(nShorts[1])// Longs Counterif longCondition or (Final_Long_sl and not Act_sl) nLongs := nLongs + 1 nShorts := na // Shorts Counterif shortCondition or (Final_Short_sl and not Act_sl) nLongs := na nShorts := nShorts + 1// Quantity FactorQF_l = Quantity+(Increase*(nLongs-1))QF_s = Quantity+(Increase*(nShorts-1))// Price average of your position according to the quantitiesif longCondition sum_long := nz(last_open_longCondition)*QF_l + nz(sum_long[1]) sum_short := 0.0 sum_qty_l := QF_l + nz(sum_qty_l[1]) sum_qty_s := na if Final_Long_sl and not Act_sl sum_long := ((1-(sl/100))*last_open_longCondition)*QF_l + nz(sum_long[1]) sum_short := 0.0 sum_qty_l := QF_l + nz(sum_qty_l[1]) sum_qty_s := na if shortCondition sum_short := nz(last_open_shortCondition)*QF_s + nz(sum_short[1]) sum_long := 0.0 sum_qty_s := QF_s + nz(sum_qty_s[1]) sum_qty_l := na if Final_Short_sl and not Act_sl sum_long := 0.0 sum_short := ((1+(sl/100))*last_open_shortCondition)*QF_s + nz(sum_short[1]) sum_qty_s := QF_s + nz(sum_qty_s[1]) sum_qty_l := na // Calculating and Plotting the price averagePosition_Price := nz(Position_Price[1])Position_Price := longCondition or (Final_Long_sl and not Act_sl) ? sum_long/(sum_qty_l) : shortCondition or (Final_Short_sl and not Act_sl) ? sum_short/(sum_qty_s) : naplot(Position_Price[1], title = "Average Price", color = in_longCondition ? color.blue : color.red, linewidth = 2, style = plot.style_cross, transp = 0)// ================================================================================================================================================================================// STOP LOSS / RE-ENTRY// ================================================================================================================================================================================// SL initial inputsAct_sl := input(true, "ACTIVATE SL / DEACTIVATE RE-ENTRY")sl := input(7.5, "STOP LOSS / RE-ENTRY %", type = input.float, minval = 0, step = 0.5)// Initial SL conditionslong_sl = crossunder(low, (1-(sl/100))*last_open_longCondition) and in_longCondition and not longConditionshort_sl = crossover(high, (1+(sl/100))*last_open_shortCondition) and in_shortCondition and not shortCondition// Get the time of the last sllast_long_sl := long_sl ? time : nz(last_long_sl[1])last_short_sl := short_sl ? time : nz(last_short_sl[1])// Sl counterCondIni_long_sl := long_sl ? 1 : longCondition ? -1 : nz(CondIni_long_sl[1])CondIni_short_sl := short_sl ? 1 : shortCondition ? -1 : nz(CondIni_short_sl[1])// Final SL conditionsFinal_Long_sl := long_sl and nz(CondIni_long_sl[1]) == -1 and in_longCondition and not longConditionFinal_Short_sl := short_sl and nz(CondIni_short_sl[1]) == -1 and in_shortCondition and not shortCondition// ================================================================================================================================================================================// TAKE PROFIT// ================================================================================================================================================================================// Take Profit inputAct_tp = input(false, "ACTIVATE TAKE PROFIT")tp = input(10.0, "TAKE PROFIT %", type = input.float, minval = 0, step = 0.5)// Initial TP conditionslong_tp = crossover(high, (1+(tp/100))*fixnan(Position_Price)) and in_longCondition and not longCondition and not Final_Long_sl and Act_tpshort_tp = crossunder(low, (1-(tp/100))*fixnan(Position_Price)) and in_shortCondition and not shortCondition and not Final_Short_sl and Act_tp// Get the time of the last tplast_long_tp := long_tp ? time : nz(last_long_tp[1])last_short_tp := short_tp ? time : nz(last_short_tp[1])// Tp signal orderingCondIni_long_tp := (Final_Long_sl and Act_sl) or XlongCondition ? 1 : longCondition ? -1 : nz(CondIni_long_tp[1])CondIni_short_tp := Final_Short_sl and Act_sl ? 1 : shortCondition ? -1 : nz(CondIni_short_tp[1])// Final tp conditionFinal_Long_tp = long_tp and last_longCondition > nz(last_long_tp[1]) and nz(CondIni_long_tp[1]) == -1Final_Short_tp = short_tp and last_shortCondition > nz(last_short_tp[1]) and nz(CondIni_short_tp[1]) == -1if Final_Long_tp or (Final_Long_sl and Act_sl) or XlongCondition sum_long := 0.0 nLongs := na CondIni_long_sl := 1 sum_qty_l := na if Final_Short_tp or (Final_Short_sl and Act_sl) sum_short := 0.0 nShorts := na CondIni_short_sl := 1 sum_qty_s := na // ================================================================================================================================================================================// SIGNALS// ================================================================================================================================================================================// Longs// label.new(// x = longCondition[1] ? time : na, // y = na, // text = 'LONG '+tostring(nLongs), // color = color.blue, // textcolor = color.black, // style = label.style_labelup, // xloc = xloc.bar_time, // yloc = yloc.belowbar,// size = size.tiny// )// // Shorts// label.new(// x = shortCondition[1] ? time : na, // y = na, // text = 'SHORT '+tostring(nShorts), // color = color.red, // textcolor = color.black, // style = label.style_labeldown, // xloc = xloc.bar_time, // yloc = yloc.abovebar,// size = size.tiny// )// // XLongs// label.new(// x = XlongCondition[1] ? time : na, // y = na, // text = 'XLONG', // color = color.yellow, // textcolor = color.black, // style = label.style_labeldown, // xloc = xloc.bar_time, // yloc = yloc.abovebar,// size = size.tiny// ) // // Tp on longs// label.new(// x = Final_Long_tp ? time : na, // y = na, // text = 'TP '+tostring(tp)+'%', // color = color.orange, // textcolor = color.black, // style = label.style_labeldown, // xloc = xloc.bar_time, // yloc = yloc.abovebar,// size = size.tiny// ) ltp = iff(Final_Long_tp, (fixnan(Position_Price)*(1+(tp/100))), na), plot(ltp, style=plot.style_cross, linewidth=3, color = color.white, editable = false)// Tp on shorts// label.new(// x = Final_Short_tp ? time : na, // y = na, // text = 'TP '+tostring(tp)+'%', // color = color.orange, // textcolor = color.black, // style = label.style_labelup, // xloc = xloc.bar_time, // yloc = yloc.belowbar,// size = size.tiny// ) stp = iff(Final_Short_tp, (fixnan(Position_Price)*(1-(tp/100))), na), plot(stp, style=plot.style_cross, linewidth=3, color = color.white, editable = false)// Sl on Longs// label.new(// x = Final_Long_sl ? time : na, // y = na, // text = Act_sl ? ('SL '+tostring(sl)+'%') : ('RE '+tostring(sl)+'%'), // color = color.green, // textcolor = color.black, // style = label.style_labelup, // xloc = xloc.bar_time, // yloc = yloc.belowbar,// size = size.tiny// ) // Sl on Longs dot lsl = iff(Final_Long_sl, (last_open_longCondition*(1-(sl/100))), na), plot(lsl, style=plot.style_cross, linewidth=3, color = color.white, editable = false)// Sl on Shorts// label.new(// x = Final_Short_sl ? time : na, // y = na, // text = Act_sl ? ('SL '+tostring(sl)+'%') : ('RE '+tostring(sl)+'%'), // color = color.maroon, // textcolor = color.black, // style = label.style_labeldown, // xloc = xloc.bar_time, // yloc = yloc.abovebar,// size = size.tiny// ) // Sl on Shorts dotssl = iff(Final_Short_sl, (last_open_shortCondition*(1+(sl/100))), na), plot(ssl, style=plot.style_cross, linewidth=3, color = color.white, editable = false)// ================================================================================================================================================================================// BACKTEST// ================================================================================================================================================================================// Backtest inputsAct_BT = input(true, "BACKTEST 💹")Quantity := input(1000, "$ QUANTITY 1ST ENTRY")/closeIncrease := input(500, "$ INCREASE NEXT ENTRY")/close// Backtest Period inputstestStartYear = input(2019, "BACKTEST START YEAR ⏲️", minval = 1980, maxval = 2222) testStartMonth = input(01, "BACKTEST START MONTH", minval = 1, maxval = 12)testStartDay = input(01, "BACKTEST START DAY", minval = 1, maxval = 31)testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,0,0)testStopYear = input(2222, "BACKTEST STOP YEAR", minval=1980, maxval = 2222)testStopMonth = input(12, "BACKTEST STOP MONTH", minval=1, maxval=12)testStopDay = input(31, "BACKTEST STOP DAY", minval=1, maxval=31)testPeriodStop = timestamp(testStopYear, testStopMonth, testStopDay, 0, 0)// Backtest ConditiontestPeriod = true// Backtest entriesif (Act_BT and not na(RSI_VWAP) and testPeriod) strategy.entry("Long", strategy.long, qty = QF_l, when = longCondition or (Final_Long_sl and not Act_sl)) strategy.close("Long", when = XlongCondition) strategy.entry("Short", strategy.short, qty = QF_s, when = (shortCondition or (Final_Short_sl and not Act_sl))) strategy.exit("XL", "Long", limit = Act_tp ? (fixnan(Position_Price)*(1+(tp/100))) : na, stop = (Act_sl ? (1-(sl/100))*last_open_longCondition : na)) strategy.exit("XS", "Short", limit = Act_tp ? (fixnan(Position_Price)*(1-(tp/100))) : na, stop = (Act_sl ? (1+(sl/100))*last_open_shortCondition : na))// ================================================================================================================================================================================// ALERTS// ================================================================================================================================================================================alertcondition((longCondition[1] or (Final_Long_sl and not Act_sl)) and nLongs == 1, title="Long 1 Alert", message = "LONG1")alertcondition((longCondition[1] or (Final_Long_sl and not Act_sl)) and nLongs == 2, title="Long 2 Alert", message = "LONG2")alertcondition((longCondition[1] or (Final_Long_sl and not Act_sl)) and nLongs == 3, title="Long 3 Alert", message = "LONG3")alertcondition((longCondition[1] or (Final_Long_sl and not Act_sl)) and nLongs == 4, title="Long 4 Alert", message = "LONG4")alertcondition((longCondition[1] or (Final_Long_sl and not Act_sl)) and nLongs == 5, title="Long 5 Alert", message = "LONG5")alertcondition(Final_Long_tp or (Final_Long_sl and Act_sl), title="TPL/SLL Alert", message = "TPL/SLL")alertcondition((shortCondition[1] or (Final_Short_sl and not Act_sl)) and nShorts == 1, title="Short 1 Alert", message = "SHORT1")alertcondition((shortCondition[1] or (Final_Short_sl and not Act_sl)) and nShorts == 2, title="Short 2 Alert", message = "SHORT2")alertcondition((shortCondition[1] or (Final_Short_sl and not Act_sl)) and nShorts == 3, title="Short 3 Alert", message = "SHORT3")alertcondition((shortCondition[1] or (Final_Short_sl and not Act_sl)) and nShorts == 4, title="Short 4 Alert", message = "SHORT4")alertcondition((shortCondition[1] or (Final_Short_sl and not Act_sl)) and nShorts == 5, title="Short 5 Alert", message = "SHORT5")alertcondition(Final_Short_tp or (Final_Short_sl and Act_sl), title="TPS/SLS Alert", message = "TPS/SLS")// by Xaviz

template: strategy.tpl:40:21: executing "strategy.tpl" at <.api.GetStrategyListByName>: wrong number of args for GetStrategyListByName: want 7 got 6

RSI-VWAP Price-Volume Strategy - FMZ (2024)
Top Articles
Start Investing Online Today with J.P. Morgan
Financial Accounting Standard 157 (FAS 157): Definition
Katie Nickolaou Leaving
Pixel Speedrun Unblocked 76
Roblox Roguelike
Tyrunt
Fototour verlassener Fliegerhorst Schönwald [Lost Place Brandenburg]
Locate Td Bank Near Me
Where's The Nearest Wendy's
今月のSpotify Japanese Hip Hopベスト作品 -2024/08-|K.EG
Med First James City
Summoners War Update Notes
How Much Is Tj Maxx Starting Pay
What is Rumba and How to Dance the Rumba Basic — Duet Dance Studio Chicago | Ballroom Dance in Chicago
NHS England » Winter and H2 priorities
Prosser Dam Fish Count
Unity - Manual: Scene view navigation
Ahrefs Koopje
Accident On The 210 Freeway Today
Robeson County Mugshots 2022
Sussyclassroom
Jail View Sumter
Brbl Barber Shop
O'reilly's In Monroe Georgia
897 W Valley Blvd
Maths Open Ref
Does Royal Honey Work For Erectile Dysfunction - SCOBES-AR
N.J. Hogenkamp Sons Funeral Home | Saint Henry, Ohio
APUSH Unit 6 Practice DBQ Prompt Answers & Feedback | AP US History Class Notes | Fiveable
Solve 100000div3= | Microsoft Math Solver
Old Peterbilt For Sale Craigslist
Lake Dunson Robertson Funeral Home Lagrange Georgia Obituary
Despacito Justin Bieber Lyrics
Clark County Ky Busted Newspaper
Nsav Investorshub
Doordash Promo Code Generator
Puretalkusa.com/Amac
Panorama Charter Portal
Achieving and Maintaining 10% Body Fat
Traumasoft Butler
Winta Zesu Net Worth
What to Do at The 2024 Charlotte International Arts Festival | Queen City Nerve
Crystal Glassware Ebay
Greg Steube Height
Myapps Tesla Ultipro Sign In
6463896344
Game Like Tales Of Androgyny
Secondary Math 2 Module 3 Answers
ats: MODIFIED PETERBILT 389 [1.31.X] v update auf 1.48 Trucks Mod für American Truck Simulator
La Fitness Oxford Valley Class Schedule
Latest Posts
Article information

Author: Patricia Veum II

Last Updated:

Views: 6640

Rating: 4.3 / 5 (44 voted)

Reviews: 83% of readers found this page helpful

Author information

Name: Patricia Veum II

Birthday: 1994-12-16

Address: 2064 Little Summit, Goldieton, MS 97651-0862

Phone: +6873952696715

Job: Principal Officer

Hobby: Rafting, Cabaret, Candle making, Jigsaw puzzles, Inline skating, Magic, Graffiti

Introduction: My name is Patricia Veum II, I am a vast, combative, smiling, famous, inexpensive, zealous, sparkling person who loves writing and wants to share my knowledge and understanding with you.