Rearview Join the waitlist

Examples

Each example is a complete script written from scratch for Rearview. The strategies and scans run on the synthetic sample data that comes with the app, where SYN500 is the index label and SYNSPY the market ETF, and every sample project holds them. To run one on your own data, point members(...) and close(...) at your data’s labels and tickers. The coins, futures, exchanges and intraday examples need data that holds those markets. They are educational templates, not recommendations.

Strategies

Rules that trade the sample data’s stocks and its market ETF: trends, pullbacks, breakouts, rotations, scaling in and out, and one tuned too far on purpose.

Breakout with trend strength

Breakouts work better when a trend is already under way: buy a new 20-day high only when ADX says the trend is strong and the directional lines agree. Positions risk 1% of equity each, with an ATR stop and an ATR trailing stop.

adx_breakout.rvw

language 1
strategy "Breakout with trend strength" {
  universe   members("SYN500")
  enter long when close > donchian_high(20)[1] and adx(14) > strength and plus_di(14) > minus_di(14)
  rank by    adx(14)
  stop       2 x atr(14)
  trail      3 x atr(14)
  size       risk 1% with stop, max 10 positions
  max position 20%
  exit when  close < donchian_low(10)[1]
  param      strength = 25 in 15..35 step 5
}

Bollinger band reversion

Reversion to the mean: buy a stock in a long-term uptrend after it closes below its lower Bollinger band, and sell when it gets back to its 20-day average. The 200-day filter keeps out stocks in free fall; losses still bunch up in sharp market sell-offs.

bollinger_reversion.rvw

language 1
strategy "Bollinger band reversion" {
  universe   members("SYN500")
  enter long when close > sma(close, 200) and close < bollinger_lower(close, 20, width)
  rank by    -zscore(close, 20)
  size       10% of equity, max 10 positions
  exit when  close > sma(close, 20)
  max bars   15
  param      width = 2 in 1.5..3 step 0.5
}

55-day breakout with ATR stop

Donchian breakout with an ATR stop and ATR-based position size.

breakout_atr.rvw

language 1
strategy "55-day breakout with ATR stop" {
  universe   members("SYN500")
  filter     close > sma(close, 100) and adv(20) > $100000
  enter long when close > donchian_high(breakout)[1]
  rank by    roc(close, 60)
  stop       3 x atr(20)
  size       risk 1% with stop, max 8 positions
  max position 25%
  exit when  close < donchian_low(20)[1]
  fill       next_open
  param      breakout = 30 in 20..60 step 10
}

Down days, tuned too far

three_down_days tuned too far, on purpose: its holding period is searched as well as the length of the run, 5 × 10 = 50 settings on one history. Optimize it and read the verdict. On the sample data it is "Probably luck": the setting that looked best on one half of the history mostly ranked below the median on the other half. Every knob tuned on the same history makes a lucky winner more likely.

down_days_overtuned.rvw

language 1
strategy "Down days, tuned too far" {
  universe   members("SYN500")
  enter long when close > sma(close, 200) and count(close < close[1], run) == run
  rank by    -roc(close, run)
  size       10% of equity, max 10 positions
  exit when  close > close[1]
  max bars   hold
  param      run = 3 in 2..6 step 1
  param      hold = 10 in 2..20 step 2
}

Hull average turns

A Hull moving average turns sooner than a simple one. Buy when it turns up while the slower Hull average above it is rising, and sell when the quick one turns down. The Chande momentum oscillator picks the strongest turns.

hull_trend.rvw

language 1
strategy "Hull average turns" {
  universe   members("SYN500")
  fast       hma(close, quick)
  slow       hma(close, 55)
  enter long when fast > fast[1] and fast[1] <= fast[2] and slow > slow[1]
  rank by    cmo(close, 14)
  size       5% of equity, max 15 positions
  exit when  fast < fast[1]
  param      quick = 20 in 10..30 step 5
}

Weak close in an uptrend

A close near the bottom of the day's range, in an uptrend, tends to bounce the next few days. Internal bar strength (ibs) measures where the close sits in the range, 0 to 1. Short holds make costs matter: try it with commission and slippage before trusting it.

ibs_reversion.rvw

language 1
strategy "Weak close in an uptrend" {
  universe   members("SYN500")
  filter     adv(20) > $1000000
  enter long when close > sma(close, 100) and ibs() < weak
  rank by    -ibs()
  size       10% of equity, max 10 positions
  exit when  ibs() > 0.7 or close > highest(high, 3)[1]
  max bars   5
  param      weak = 0.15 in 0.05..0.3 step 0.05
}

Keltner channel breakout

A close above the Keltner channel on rising volume marks unusual strength. Ride it with an ATR trailing stop and get out when the price falls back under its 20-day average.

keltner_breakout.rvw

language 1
strategy "Keltner channel breakout" {
  universe   members("SYN500")
  filter     adv(20) > $500000
  enter long when close > keltner_upper(20, width) and volume > sma(volume, 20)
  rank by    (close - keltner_upper(20, width)) / atr(20)
  size       5% of equity, max 15 positions
  trail      3 x atr(20)
  exit when  close < ema(close, 20)
  param      width = 2 in 1..3 step 0.5
}

Breakout, out in thirds

A breakout that takes profits in thirds: sell a third of the position 8% above the entry, another third at 16%, and let the last third run to the 25% target or until the trend breaks. Each third is of the position held at the first step, so the steps don't shrink.

ladder_scale_out.rvw

language 1
strategy "Breakout, out in thirds" {
  universe   members("SYN500")
  filter     close > sma(close, 100)
  enter long when close > donchian_high(breakout)[1]
  rank by    roc(close, 60)
  scale out  33% at 8%, 33% at 16%
  target     25%
  stop       3 x atr(20)
  size       risk 1% with stop, max 8 positions
  exit when  close < donchian_low(20)[1]
  param      breakout = 30 in 20..60 step 10
}

Long top decile, short bottom decile

Cross-sectional long/short: long the top decile of 60-day momentum scaled by volatility, short the bottom decile. One rank serves both sides, so it measures how extreme a name is.

long_short_decile.rvw

language 1
strategy "Long top decile, short bottom decile" {
  universe   members("SYN500")
  score      roc(close, 60) / volatility(60)
  decile     bucket(score, 10)
  enter long  when decile == 10
  enter short when decile == 1
  rank by    abs(cs_zscore(score))
  size       equal weight, max 6 positions
  exit long when decile <= 7
  exit short when decile >= 4
  max bars   40
  fill       next_open
}

Low beta rotation

Rank by how little each stock moves with the market: its beta to the index over a window of daily changes. Hold the least sensitive tenth while it trends up, and let a stock go when it leaves the calmer half or its trend ends.

low_beta_rotation.rvw

language 1
strategy "Low beta rotation" {
  universe   members("SYN500")
  calm       -beta(close, close("SYNSPY"), window)
  trend      close > sma(close, 200)
  enter long when bucket(calm, 10) == 10 and trend
  exit when  bucket(calm, 10) <= 5 or not trend
  rank by    calm
  size       equal weight, max 20 positions
  param      window = 120 in 60..240 step 60
}

Least volatile tenth

The low-volatility effect: calmer stocks have often earned more per unit of risk than their jumpy peers. Hold the least volatile tenth of the index while it trends up, and let a stock go when it is no longer among the calmer half.

low_volatility_rank.rvw

language 1
strategy "Least volatile tenth" {
  universe   members("SYN500")
  calm       -volatility(window)
  enter long when bucket(calm, 10) == 10 and close > sma(close, 200)
  exit when  bucket(calm, 10) <= 5
  rank by    calm
  size       equal weight, max 20 positions
  param      window = 60 in 20..120 step 20
}

MACD with a market filter

MACD crossovers below zero, taken only while the market itself is in an uptrend: the stock turns up after a dip in a rising market. Exit on the opposite cross or when the market filter switches off.

macd_regime.rvw

language 1
strategy "MACD with a market filter" {
  universe   members("SYN500")
  regime     close("SYNSPY") > sma(close("SYNSPY"), 200)
  line       macd_line(close, 12, 26, 9)
  sig        macd_signal(close, 12, 26, 9)
  enter long when regime and crosses_above(line, sig) and line < 0
  exit when  crosses_below(line, sig) or not regime
  rank by    -line / close
  size       5% of equity, max 15 positions
}

Monthly momentum rotation

Monthly momentum rotation: hold the strongest names by six-month momentum measured on month-end bars, and rotate out when a name loses its rank or turns negative.

momentum_rotation.rvw

language 1
strategy "Monthly momentum rotation" {
  universe   members("SYN500")
  mom        monthly(roc(close, top_months))
  strong     mom > 0 and rank_pct(mom) >= 70
  enter long when strong
  rank by    mom
  size       equal weight, max 8 positions
  exit when  mom < 0 or rank_pct(mom) < 40
  fill       next_open
  param      top_months = 6 in 3..9 step 3
}

Monthly momentum, rebalanced

Monthly momentum, rebalanced: on the first trading day of each month, hold the ten stocks with the strongest six-month momentum that trade above their 200-day average, each resized to an equal share of equity. A stock that drops out of the ten is sold. The 20% band skips resizes too small to matter, so the strategy isn't trading a few shares every month.

monthly_rebalanced_momentum.rvw

language 1
strategy "Monthly momentum, rebalanced" {
  universe   members("SYN500")
  mom        roc(close, lookback)
  enter long when mom > 0 and close > sma(close, 200)
  rank by    mom
  size       equal weight, max 10 positions
  rebalance  monthly, band 20%
  param      lookback = 126 in 63..252 step 63
}

Near the 52-week high

Stocks trading close to their 52-week high tend to keep rising: buy within a few percent of it, ranked by six-month momentum, and hold until the trend breaks or a trailing stop is hit.

near_52w_high.rvw

language 1
strategy "Near the 52-week high" {
  universe   members("SYN500")
  proximity  close / highest(high, 252)
  enter long when proximity > 1 - gap * 1% and close > sma(close, 50)
  rank by    roc(close, 126)
  size       5% of equity, max 20 positions
  exit when  close < sma(close, 50)
  trail      15%
  param      gap = 5 in 2..10 step 1
}

Pullback, half out on the bounce

A pullback with a scale-out: buy a short, sharp dip in an uptrend, sell half once the bounce has lifted RSI(2) above 60, and the rest when it is above 85 or after ten days. The early half banks part of a typical bounce; the rest stays for the bigger ones.

pullback_scale_out.rvw

language 1
strategy "Pullback, half out on the bounce" {
  universe   members("SYN500")
  rsi2       rsi(close, 2)
  enter long when close > sma(close, 200) and rsi2 < dip
  rank by    -rsi2
  scale out  50% when rsi2 > 60
  exit when  rsi2 > 85 or bars_held >= 10
  size       10% of equity, max 10 positions
  stop       8%
  param      dip = 10 in 5..20 step 5
}

Breakout with pyramiding

Breakout with pyramiding: buy a new 50-day high in an uptrend, add to it on each new 20-day high (twice at most), and follow the trend with a trailing stop three ATRs below its high. Half the position is sold at a 15% gain, so a winner pays something even if the trend later fails. After an add, the stop and the partial target are measured from the average cost.

pyramid_breakout.rvw

language 1
strategy "Breakout with pyramiding" {
  universe   members("SYN500")
  enter long when close > highest(close, 50)[1] and close > sma(close, 200)
  add when   close > highest(close, 20)[1]
  max adds   2
  rank by    roc(close, 50)
  size       4% of equity, max 8 positions
  max position 12%
  scale out  50% at 15%
  trail      3 x atr(20)
}

Monthly momentum with a buffer

Monthly momentum with a buffer: on the first trading day of each month, hold the eight strongest stocks by six-month momentum, each resized to an equal share of equity. A holding keeps its place while it still ranks in the top 15, so a name hovering around eighth isn't sold one month and bought back the next. Only one that slips below 15th makes room.

rotation_with_buffer.rvw

language 1
strategy "Monthly momentum with a buffer" {
  universe   members("SYN500")
  mom        roc(close, lookback)
  enter long when mom > 0 and close > sma(close, 200)
  rank by    mom
  size       equal weight, max 8 positions
  rebalance  monthly, band 20%, keep top 15
  param      lookback = 126 in 63..252 step 63
}

RSI(2) pullback with market filter

The classic short-term pullback: buy a stock in a long-term uptrend when RSI(2) shows a sharp dip, but only while the market itself is above its 200-day average, and sell on the bounce or after ten days. It is the language reference’s own example.

rsi2_pullback.rvw

language 1
strategy "RSI(2) pullback with market filter" {
  universe   members("SYN500")                         // index label from the user's data
  regime     close("SYNSPY") > sma(close("SYNSPY"), 200) // cross-symbol filter
  rsi2       rsi(close, 2)
  enter long when regime and close > sma(close, 200) and rsi2 < rsi_entry
  rank by    -rsi2
  size       10% of equity, max 10 positions
  exit when  rsi2 > 70 or bars_held >= 10
  fill       next_open
  param      rsi_entry = 10 in 5..20 step 5
}

Momentum within a sector

Momentum within one sector: rank the sector's stocks by six-month return and hold the leaders while they trend. Sector labels are each stock's current one, not its history, which the run's assumptions point out.

sector_momentum.rvw

language 1
strategy "Momentum within a sector" {
  universe   sector("Technology") and members("SYN500")
  mom        roc(close, 126)
  enter long when rank_pct(mom) > 80 and close > sma(close, 100)
  exit when  rank_pct(mom) < 50
  rank by    mom
  size       equal weight, max 8 positions
}

Short overbought bounces

Short-term mean reversion on the short side: fade stretched up-moves in an index member.

short_meanrev.rvw

language 1
strategy "Short overbought bounces" {
  universe   members("SYN500")
  rsi3       rsi(close, 3)
  stretched  close > sma(close, 10) * 1.02
  enter short when rsi3 > rsi_entry and stretched
  rank by    rsi3
  stop       8%
  size       5% of equity, max 10 positions
  exit short when rsi3 < 45 or close < sma(close, 10)
  max bars   10
  fill       next_open
  param      rsi_entry = 80 in 70..90 step 5
}

Moving-average cross

Trend following with two moving averages: own a stock while its fast average is above its slow one, and step aside when it crosses back below. New crosses compete on six-month momentum. Expect few trades and long holds, and whipsaws when a market goes sideways.

sma_cross_trend.rvw

language 1
strategy "Moving-average cross" {
  universe   members("SYN500")
  fast_ma    sma(close, fast)
  slow_ma    sma(close, slow)
  enter long when crosses_above(fast_ma, slow_ma)
  exit when  crosses_below(fast_ma, slow_ma)
  rank by    roc(close, 126)
  size       5% of equity, max 20 positions
  param      fast = 50 in 20..80 step 10
  param      slow = 200 in 150..250 step 50
}

Stochastic pullback

Buy an oversold stochastic reading while both the stock and the market are in uptrends, and sell when it becomes overbought. A fixed stop caps the damage from the pullbacks that keep going.

stochastic_pullback.rvw

language 1
strategy "Stochastic pullback" {
  universe   members("SYN500")
  regime     close("SYNSPY") > sma(close("SYNSPY"), 200)
  enter long when regime and close > sma(close, 100) and stoch_k(14) < oversold
  rank by    -stoch_k(14)
  size       10% of equity, max 10 positions
  exit when  stoch_k(14) > 80
  stop       8%
  max bars   10
  param      oversold = 20 in 10..30 step 5
}

Supertrend trend following

Ride a trend with a trailing line that only tightens while the trend lasts: buy when the close crosses above the Supertrend line, sell when it crosses back below. The line sits width average true ranges from each bar's midpoint.

supertrend_trend.rvw

language 1
strategy "Supertrend trend following" {
  universe   members("SYN500")
  filter     adv(20) > $500000
  line       supertrend(10, width)
  enter long when crosses_above(close, line) and close > sma(close, 100)
  rank by    (close - line) / atr(10)
  size       5% of equity, max 15 positions
  exit when  crosses_below(close, line)
  param      width = 3 in 2..4 step 1
}

Down days in an uptrend

A run of lower closes inside an uptrend is a short pullback that often reverses. Enter after the run, exit on the first up close. Watch how the result changes with the length of the run: a strong spike at one length and nothing at its neighbours is probably luck.

three_down_days.rvw

language 1
strategy "Down days in an uptrend" {
  universe   members("SYN500")
  enter long when close > sma(close, 200) and count(close < close[1], run) == run
  rank by    -roc(close, run)
  size       10% of equity, max 10 positions
  exit when  close > close[1]
  max bars   10
  param      run = 3 in 2..5 step 1
}

Six-month trend timing

Trend timing with one fund: own the market ETF while its price is above its six-month average, and hold cash otherwise. It is checked once a week, on the week's first trading day, so a dip below the average during the week doesn't trigger a trade; the 10% band keeps the position from being trimmed and topped up by a few shares each week.

trend_timing_etf.rvw

language 1
strategy "Six-month trend timing" {
  universe   symbols("SYNSPY")
  trend      monthly(close) > monthly(sma(close, months))
  enter long when trend
  size       95% of equity
  max positions 1
  rebalance  weekly, band 10%
  param      months = 6 in 4..12 step 2
}

Pullback while uncorrelated

Buy a short-term dip only in a stock that has been moving on its own: its daily changes over the last 60 days correlate weakly with the market's, so a market-wide sell-off is unlikely to be the reason for the dip. Sell when the dip has mended, or after ten days.

uncorrelated_pullback.rvw

language 1
strategy "Pullback while uncorrelated" {
  universe   members("SYN500")
  filter     adv(20) > $500000
  indep      correl(close, close("SYNSPY"), 60) < ceiling
  enter long when indep and close > sma(close, 200) and rsi(close, 3) < 15
  rank by    -rsi(close, 3)
  size       5% of equity, max 15 positions
  exit when  rsi(close, 3) > 60
  max bars   10
  param      ceiling = 0.5 in 0.3..0.7 step 0.2
}

Trend with volatility-scaled sizes

Size by risk instead of by dollars: each position's share of equity is inversely proportional to its volatility, so calm and jumpy stocks add similar risk. The trend rules are deliberately plain; the sizing is the point. Compare it with a fixed 5% size.

volatility_sized_trend.rvw

language 1
strategy "Trend with volatility-scaled sizes" {
  universe   members("SYN500")
  enter long when close > sma(close, 100) and roc(close, 60) > 0
  rank by    roc(close, 60) / volatility(60)
  size       weight risk_pct * 1% / volatility(60), max 15 positions
  max position 15%
  exit when  close < sma(close, 100)
  param      risk_pct = 2 in 1..4 step 1
}

Volatility-targeted weights

Volatility-targeted weights: hold up to 20 uptrending stocks, each weighted so that it adds about the same risk. With the default risk unit, a stock with 20% annual volatility gets a 5% weight, a jumpier one less and a calmer one more, up to 10%. The weights are reset on the first trading day of each month; a 25% band skips resizes too small to pay their commission.

volatility_targeted_weights.rvw

language 1
strategy "Volatility-targeted weights" {
  universe   members("SYN500")
  vol        volatility(60)
  enter long when close > sma(close, 100)
  rank by    roc(close, 63)
  size       weight risk_unit / vol, max 20 positions
  max position 10%
  rebalance  monthly, band 25%
  param      risk_unit = 0.01 in 0.005..0.02 step 0.005
}

Weekly RSI in a monthly uptrend

Weekly momentum inside a monthly trend: buy when the weekly RSI turns up from a low reading while the monthly close is above its 10-month average. Weekly and monthly bars include the week or month in progress, built from the days so far.

weekly_rsi_trend.rvw

language 1
strategy "Weekly RSI in a monthly uptrend" {
  universe   members("SYN500")
  trend      monthly(close) > monthly(sma(close, 10))
  wrsi       weekly(rsi(close, 5))
  enter long when trend and wrsi < low_level and wrsi > wrsi[1]
  rank by    -wrsi
  size       5% of equity, max 20 positions
  exit when  wrsi > 70 or not trend
  param      low_level = 35 in 20..50 step 5
}

Scans

Each lists the sample data’s stocks that meet its conditions on a day, best ranked first, with every value it worked out. See Scans.

New highs on rising volume

New 52-week closing highs on heavy volume: breakouts with buyers behind them. The heaviest volume against its 50-day average first.

scans/new_highs_on_volume.rvw

language 1
scan "New highs on rising volume" {
  universe   members("SYN500")
  high_52w   highest(close, 252)
  surge      volume / sma(volume, 50)
  filter     close >= high_52w and surge > surge_min
  rank by    surge
  param      surge_min = 1.5 in 1..3 step 0.5
}

Oversold above the 200-day

Stocks in a long-term uptrend that have just had a sharp two-day drop: the setup a short-term pullback strategy buys. Most oversold first.

scans/oversold_above_trend.rvw

language 1
scan "Oversold above the 200-day" {
  universe   members("SYN500")
  rsi2       rsi(close, 2)
  trend      close > sma(close, 200)
  filter     trend and rsi2 < rsi_max
  rank by    -rsi2
  param      rsi_max = 10 in 5..20 step 5
}

Pullbacks in leaders

The strongest tenth of the universe by six-month return, dipping below their 10-day average: leaders on sale. The deepest dip first.

scans/pullbacks_in_leaders.rvw

language 1
scan "Pullbacks in leaders" {
  universe   members("SYN500")
  strength   rank_pct(roc(close, 126))
  dip        close / sma(close, 10) - 1
  filter     strength >= 90 and dip < 0
  rank by    -dip
}

Quiet leaders

Six-month winners whose daily swings are among the calmest of the universe: steady trends rather than lottery tickets. Strongest first.

scans/quiet_leaders.rvw

language 1
scan "Quiet leaders" {
  universe   members("SYN500")
  momentum   roc(close, 126)
  calm       rank_pct(-volatility(60))
  filter     momentum > 0 and calm >= 75
  rank by    momentum
}

Coins

These need data with coins in it beside the market ETF, such as Yahoo Finance’s daily files converted with rvw convert ohlcv --crypto. stocks_and_coins.rvwp, beside the script, holds the market ETF strategy and the coin trend in sleeves of 80% and 20%, rebalanced each month. See Coins and the exchange’s days.

Coin trend with a market filter

Coin trend with a market filter: hold the coins that trend up, but only while the stock market does too. A coin is bought when it closes above its 50-day average and the broad market ETF is above its 200-day average; on a weekend the ETF's values are Friday's. Coins trade every day, so a coin's average counts every day and the run's figures use a 365-day year. Coins are never shorted, and a Reg T account buys them with cash.

coins/coin_trend.rvw

language 1
strategy "Coin trend with a market filter" {
  universe   crypto
  regime     close("SYNSPY") > sma(close("SYNSPY"), 200)
  enter long when regime and close > sma(close, days)
  exit when  close < sma(close, days) or not regime
  rank by    roc(close, days)
  size       30% of equity, max 3 positions
  param      days = 50 in 20..100 step 10
}

Futures

These need futures chains with their rolls, such as one file per contract converted with rvw convert futures. stocks_and_futures.rvwp holds the market ETF strategy and the futures trend in sleeves of 70% and 30%, rebalanced each month. See Futures and their rolls.

Futures trend, long or flat

Trend following on futures, long or flat: hold a chain while it is above its 100-day average and has risen over the last 50 days, and step aside when it closes below its 50-day average. Each position risks 1% of equity to an ATR stop, counted in contracts at the chain's point value, so a quiet market and a jumpy one add similar risk. Indicators read each chain adjusted across its rolls; fills are at the prices of the contract held, and a held chain rolls on its own. A cash account backs every contract with cash for its full value, so it never borrows; a contract of a stock index future is worth $100,000 or more, so give the run a few million dollars.

futures/futures_trend.rvw

language 1
strategy "Futures trend, long or flat" {
  universe   futures
  enter long when close > sma(close, 100) and roc(close, 50) > 0
  rank by    roc(close, 50)
  stop       3 x atr(20)
  size       risk 1% with stop, max 3 positions
  max position 40%
  exit when  close < sma(close, exit_days)
  param      exit_days = 50 in 20..100 step 20
}

Exchanges and currencies

These need data from more than one exchange or currency: stocks of other exchanges, a forex pair for each currency, and each currency’s interest rates for carry. stocks_and_forex.rvwp holds the market ETF strategy and the forex trend in sleeves of 70% and 30%, rebalanced each month. See Several exchanges’ days and Currencies and forex pairs.

Forex trend, long or flat

Trend following on currency pairs, long or flat: hold a pair while it is above its 100-day average and has risen over the last 50 days, and step aside when it closes below its 50-day average. Each position risks 1% of equity to an ATR stop, counted in units of the pair's base currency. A pair settles in cash at every close, as a future does, and each day it is held it earns or pays carry: its base currency's interest rate less its quote's, from the data's rates.csv. A cash account backs each pair with cash for its full value, so it never borrows.

world/forex_trend.rvw

language 1
strategy "Forex trend, long or flat" {
  universe   forex
  enter long when close > sma(close, 100) and roc(close, 50) > 0
  rank by    roc(close, 50)
  stop       3 x atr(20)
  size       risk 1% with stop, max 3 positions
  max position 40%
  exit when  close < sma(close, exit_days)
  param      exit_days = 50 in 20..100 step 10
}

Momentum on one exchange

Momentum on one exchange's stocks, in any account currency: on the first trading day of each month, hold the eight US stocks and ETFs with the strongest six-month momentum that trade above their 200-day average, each an equal share of equity. Choose Run Settings ▸ Currency to hold them in an account in Australian dollars, euros or another currency the data has a forex pair for: cash, costs and results are then in that currency, each stock's prices stay in dollars, and its P&L includes the dollar's moves. Change "US" to another exchange's code, such as "ASX", to rotate its stocks instead.

world/one_exchange_momentum.rvw

language 1
strategy "Momentum on one exchange" {
  universe   exchange("US")
  mom        roc(close, lookback)
  enter long when mom > 0 and close > sma(close, 200)
  rank by    mom
  size       equal weight, max 8 positions
  rebalance  monthly, band 20%
  param      lookback = 126 in 63..252 step 63
}

Momentum across exchanges

Momentum across exchanges: every exchange's stocks in one ranking, such as US and ASX stocks together. The run trades on the days any of their exchanges does, and each stock on its own exchange's days: an order waits for its stock's next session, over the other exchange's holidays too. It rebalances on the first day of each month that every exchange trades. A stock priced in another currency than the account's converts at the data's forex rates, so the data needs a pair for each currency.

world/rotation_across_exchanges.rvw

language 1
strategy "Momentum across exchanges" {
  universe   stocks
  mom        roc(close, lookback)
  enter long when mom > 0 and close > sma(close, 200)
  rank by    mom
  size       equal weight, max 10 positions
  rebalance  monthly, band 20%
  param      lookback = 126 in 63..252 step 63
}

Intraday bars

These need stocks’ intraday bars, such as 5-minute files converted with rvw convert ohlcv. See Intraday bars.

Daily trend, intraday pullback

A daily trend with intraday entries, held overnight: while a stock's daily close is above its 50-day average, buy a pullback on 5-minute bars, and hold it under a stop until the daily trend breaks. Lookbacks count bars, so the days come from daily.

intraday/daily_trend_overnight.rvw

language 1
strategy "Daily trend, intraday pullback" {
  universe   stocks
  trend      daily(close) > daily(sma(close, 50))
  enter long when trend and time >= 10:00 and rsi(close, 6) < 25
  exit when  daily(close) < daily(sma(close, 50))
  rank by    daily(roc(close, 20))
  size       10% of equity, max 5 positions
  stop       4%
}

Opening-range breakout

An opening-range breakout on intraday bars, flat at close: after the first half hour, buy a close above yesterday's high that's also above the session's average price, and hold nothing overnight. A stop limits a failed break, and flat at close sells whatever is left at the session's last close, half days included.

intraday/opening_range_breakout.rvw

language 1
strategy "Opening-range breakout" {
  universe   stocks
  filter     daily(close[1]) > $5
  enter long when time >= 10:00 and time < 15:00 and close > daily(high[1]) and close > vwap
  rank by    roc(close, 6)
  size       10% of equity, max 5 positions
  stop       1%
  flat at close
}

VWAP pullback

A pullback to the session's average price on intraday bars, flat at close: in a stock trading above its average today, buy a dip to within half a percent of it after 10:00, and take the bounce. Nothing is held overnight.

intraday/vwap_pullback.rvw

language 1
strategy "VWAP pullback" {
  universe   stocks
  filter     daily(close) > daily(sma(close, 20))
  gap        close / vwap - 1
  enter long when time >= 10:00 and time < 15:30 and gap > 0 and gap < 0.5% and close < close[1]
  rank by    -gap
  size       10% of equity, max 5 positions
  stop       1%
  target     1%
  flat at close
}