0bps

Strategy vault / Trend following

Moving Vegas Channel Crossover Strategy

The core idea of this strategy is to determine the short, mid and long term trend direction of stocks based on EMAs with different cycles such as 36, 143, 169, combined with MACD indicator to issue buying and selling…

Author
ChaoZhang
Complexity
Intermediate · 126 lines
Parameters
14
Backtest bar
1d · swing
Tested on
BTC/USDT · futures

IMG

The core idea of this strategy is to determine the short, mid and long term trend direction of stocks based on EMAs with different cycles such as 36, 143, 169, combined with MACD indicator to issue buying and selling signals. Specifically, in short term, 5 and 10 day EMAs are used to judge, in mid term, 20 and 60 day EMAs are used to judge, in long term, 120 and 250 day EMAs are used to judge, when short term EMA crosses middle term EMA upwards, it's bullish, otherwise it's bearish; MACD indicator of bullish and bearish signals is used to determine buying and selling time.

The specific mechanism of the Vegas Tunnel strategy:

  1. Use EMA 36 and EMA 43 to form short term trend judgment, they make up the red channel;
  2. Use EMA 144 and EMA 169 to form medium-term trend judgment, they make up the green channel;
  3. Use EMA576 and EMA676 to form long term trend judgment, they make up the gray channel;
  4. When the price stands on the above EMA lines, go long, combined with MACD indicator breaking through 0 axis upwards as buying signal;
  5. When the price breaks below the above EMA lines, go short, combined with MACD indicator breaking through 0 axis downwards as selling signal;
  6. According to the EMA line breakthrough, three strategies are defined, short, medium and long term respectively, corresponding to different holding period.

Advantages of this strategy:

  1. Combining short, medium and long three channels to judge trend direction, relatively stable;
  2. Vegas tunnel is intuitive to determine trend;
  3. MACD helps capture better buying and selling timing;
  4. Divided into short, medium and long three strategies for more flexible operations.

Major risks:

  1. When prices fluctuate wildly, EMA lines lag, likely to make wrong judgments;
  2. When three channels show inconsistent signals, risks of wrong operations exist;
  3. Minute chart operations need stronger psychological endurance.

Coping methods:

  1. Adjust EMA cycle to better match current market characteristics;
  2. Adjust position size beforehand to limit single loss.

Optimization space:

  1. Vegas tunnels' trend judgement capability needs improving, Bollinger bands may be added;
  2. MACD works poorly for sideways markets, indicators like KD and RSI may be better options;
  3. Add stop loss policies, like stop loss when closing price breaks key EMA lines;
  4. Short ETF to hedge given A share limit-ups and downs having greater impacts.

Parameters

NameDefaultWhat it controls
v_input_1trueUse Current Chart Resolution?
v_input_2DUse Different Timeframe? Uncheck Box Above
v_input_31212 EMA
v_input_4240240 SMA
v_input_520BB Length
v_input_6_close0BB Source: close | high | low | open | hl2 | hlc3 | hlcc4 | ohlc4
v_input_72BB StdDev
v_input_8falseBB Offset
v_input_9trueStart Date
v_input_10trueStart Month
v_input_112018Start Year
v_input_12trueEnd Date
v_input_1311End Month
v_input_142030End Year

Source Pine Script

/*backtest
start: 2022-12-26 00:00:00
end: 2024-01-01 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4

strategy("Vegas Tunnel strategy", overlay=true)
//-------------------------------------------
//-------------------------------------------
// Inputs
useCurrentRes = input(true, title="Use Current Chart Resolution?")
resCustom = input(title="Use Different Timeframe? Uncheck Box Above", type=input.resolution, defval="D")
//tfSet = input(title = "Time Frame", options=["Current","120", "240", "D", "W"], defval="D")
tfSet = useCurrentRes ? timeframe.period : resCustom
maPeriods2 = input(12, "12 EMA")
maPeriods6 = input(240, "240 SMA")
BBlength = input(20, title="BB Length", minval=1)
BBsrc = input(close, title="BB Source")
mult = input(2.0, minval=0.001, maxval=50, title="BB StdDev")
sm2 = security(syminfo.tickerid, tfSet, ema(close, maPeriods2))
sm6 = security(syminfo.tickerid, tfSet, sma(close, maPeriods6))
p2 = plot(sm2, color=color.green, transp=30,  linewidth=2, title="SMA2")
p6 = plot(sm6, color=color.white, transp=30,  linewidth=2, title="SMA6")
//BB
basis = sma(BBsrc, BBlength)
dev = mult * stdev(BBsrc, BBlength)
upper = basis + dev
lower = basis - dev
offset = input(0, "BB Offset", type = input.integer, minval = -500, maxval = 500)
//plot(basis, "Basis", color=color.blue,linewidth, offset = offset)
pBB1 = plot(upper, "Upper", color=color.blue, offset = offset)
pBB2= plot(lower, "Lower", color=color.blue, offset = offset)

//MACD
fast_ma = ema(close, 48)
slow_ma = ema(close, 56)
macd = fast_ma - slow_ma

//vagasTunnel
f1=ema(close, 36)
f2=ema(close, 43)
f3=ema(close, 144)
f4=ema(close, 169)
f5=ema(close, 576)
f6=ema(close, 676)
f7=ema(close,2304)
z1=plot(f1,color=color.red, title="ema36",transp=100)
z2=plot(f2,color=color.red, title="ema43",transp=100)
z3=plot(f3,color=color.green, title="ema144",transp=100)
z4=plot(f4,color=color.green, title="ema169",transp=100)
z5=plot(f5,color=color.white, title="ema576",transp=100)
z6=plot(f6,color=color.white, title="ema676",transp=100)
fill(z1, z2, color=color.red,transp=60)
fill(z3, z4, color=color.green,transp=60)
fill(z5, z6, color=color.gray,transp=60)

// Make input options that configure backtest date range
startDate = input(title="Start Date", type=input.integer,
     defval=1, minval=1, maxval=31)
startMonth = input(title="Start Month", type=input.integer,
     defval=1, minval=1, maxval=12)
startYear = input(title="Start Year", type=input.integer,
     defval=2018, minval=1800, maxval=2100)
endDate = input(title="End Date", type=input.integer,
     defval=1, minval=1, maxval=31)
endMonth = input(title="End Month", type=input.integer,
     defval=11, minval=1, maxval=12)
endYear = input(title="End Year", type=input.integer,
     defval=2030, minval=1800, maxval=2100)
// Look if the close time of the current bar
// falls inside the date range
inDateRange =  true

//Swing long
if (inDateRange and crossunder(f3,f1))// 
    strategy.entry("buy", strategy.long,1, when=macd>0, comment = "buyLong-term")
buyclose=crossunder(f3,f5) 
strategy.close("buy", when = buyclose, comment = "CloseLong-term")
//Multiple strategies1
if (inDateRange and crossover(low , f3) and macd>0 and f3>f6)
    strategy.entry("buy1", strategy.long,100, comment = "buyMid-term")
buyclose1=crossunder(close,upper*0.999) 
if (macd<0 or f3<f6)
    strategy.close("buy1", comment = "CloseMid-term")
//strategy.close("buy1",when=cross(basis,close), comment = "CloseM",qty_percent=50)
strategy.close("buy1", when = buyclose1, comment = "CloseMid-term",qty_percent=100)
//Multiple strategies3
if (inDateRange and  (macd>0) and crossunder(low,f1) and f1>f4) // 
    strategy.entry("buy3", strategy.long,1, comment = "buyShort-term")
buyclose3=crossunder(close,upper*0.999)
if (macd<0 or f1<f4)
    strategy.close("buy3", comment = "CloseShort-term")
strategy.close("buy3", when = buyclose3, comment = "CloseShort-term")
//Multiple strategies4
if (inDateRange and  (macd>0) and crossunder(low,f5) and f4>f5) // 
    strategy.entry("buy4", strategy.long,1, comment = "buyLong-term")
buyclose4=crossunder(close,upper*0.999)
if (macd<0 or f4<f6)
    strategy.close("buy4", comment = "CloseLong-term")
strategy.close("buy4", when = buyclose4, comment = "CloseLong-term")
    
//Short strategy1
if (inDateRange and  (macd<0) and crossunder(high,f1) and f1<f3 and f3<f6) // 
    strategy.entry("sell1", strategy.short,1, comment = "EmptyShort-term")
sellclose1=crossunder(lower*0.999,close)
if (macd>0 or f1>f4)
    strategy.close("sell1", comment = "Guan KongShort-term")
strategy.close("sell1", when = sellclose1, comment = "Guan KongShort-term")
//Short strategy2
if (inDateRange and  (macd<0) and crossunder(high,f4) and f4<f6) // 
    strategy.entry("sell2", strategy.short,1, comment = "EmptyMid-term")
sellclose2=crossunder(lower,close)
if (macd>0 or f4>f6)
    strategy.close("sell2", comment = "Guan KongMid-term")
strategy.close("sell2", when = sellclose2, comment = "CloseMid-term")
//Short strategy3
if (inDateRange and (macd<0) and crossunder(high,f6)) // 
    strategy.entry("sell3", strategy.short,1, comment = "EmptyLong-term")
sellclose3=crossunder(lower,close)
if (macd>0 or f6>f7)
    strategy.close("sell3", comment = "Guan KongLong-term")
strategy.close("sell3", when = sellclose3, comment = "Guan KongLong-term")

Published by ChaoZhang on the FMZ strategy square · last modified 2024-01-02. 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/Moving-Vegas-Channel-Crossover-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