Volume Weighted Average Price (VWAP) as Precise Trend-Following Indicator for Day-Traders
Log in to collectAcademic paper
Volume Weighted Average Price (VWAP) The Holy Grail for Day Trading Systems
Carlo Zarattini; Andrew Aziz
- Pentum Group (United States)
- ?Concretum Group
- ?Concretum Research
- ?Bear Bull Traders
- ?Peak Capital Trading
Strategy in a nutshell
Trade QQQ (or TQQQ) intraday using a VWAP-based trend system. Enter long if the first 1-min candle closes above VWAP, short if below. Stop-loss triggered by candle crossing VWAP. Positions closed at day’s end.
Economic rationale
VWAP captures intraday market trends and liquidity. The strategy exploits statistically validated short-term price patterns, enhancing intraday execution, risk-adjusted returns, and algorithmic trading efficiency.
Backtest performance
Annualised return43%
Volatility18%
Beta-0.001
Sharpe ratio2.39
Sortino ratio0.511
Maximum drawdown-9.4%
Win rate17%
Full Python code
from AlgorithmImports import *
import numpy as np
# endregion
class VolumeWeightedAveragePriceVWAPAsPreciseTrendFollowingIndicatorForDayTraders(QCAlgorithm):
def Initialize(self) -> None:
self.SetStartDate(2018, 1, 1)
self.SetCash(100000)
self.symbol: Symbol = self.AddEquity("QQQ", Resolution.Minute).Symbol
self.Securities[self.symbol].SetFeeModel(ConstantFeeModel(0))
# self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin)
self.VWAP: IntradayVwap = IntradayVwap(self.symbol)
self.traded_weight: float = 1.
self.trade_flag: bool = False
self.Settings.MinimumOrderMarginPortfolioPercentage = 0.
self.Schedule.On(self.DateRules.EveryDay(self.symbol), self.TimeRules.AfterMarketOpen(self.symbol), self.OnMarketOpen)
self.Schedule.On(self.DateRules.EveryDay(self.symbol), self.TimeRules.BeforeMarketClose(self.symbol, 1), self.BeforeMarketClose)
def OnData(self, data: Slice) -> None:
# trading allowed only after open market
if not self.trade_flag:
return
# update VWAP indicator
bar: TradeBar = data.Bars.get(self.symbol)
self.VWAP.Update(bar)
# trade execution
if self.VWAP.IsReady:
if data[self.symbol].Close > self.VWAP.Current.Value:
if not self.Portfolio[self.symbol].IsLong:
self.SetHoldings(self.symbol, self.traded_weight)
else:
if not self.Portfolio[self.symbol].IsShort:
self.SetHoldings(self.symbol, -self.traded_weight)
def OnMarketOpen(self) -> None:
self.trade_flag = True
def BeforeMarketClose(self) -> None:
self.Liquidate()
self.VWAP.Reset()
self.trade_flag = False