
この戦略は,Wave Trend振動器とVWMA指標を組み合わせて,トレンドを追跡する量化取引戦略を実現する.この戦略は,市場のトレンドを認識し,Wave Trend振動器の信号に基づいて買いまたは売却を行う.また,取引サイズは,VWMA指標の信号に基づいて決定される.
この戦略は主に以下の2つの指標に基づいています.
Wave Trend振動器:LazyBearがTradingViewに移植した指標で,価格の波動の波を識別し,買入/売却のシグナルを生成する.具体的計算方法は,価格の平均値apを計算し,次にapのEMAを計算し,次にapとesaの差値の絶対値EMAを計算し,最後に一致性指数ci=(ap-esa) / 0.015を計算する.*d) ciのEMAはWave Trend ((wt1)) と,wt1の4周期SMAはwt2である.wt1の上を通るときはwt2が買信で,下を通るときは売り信である.
VWMA指数:取引量を考慮した加重移動平均である.価格に応じてVWMABands (VWMAの上下軌道) の内または外で,+1 (多頭),0 (中性),または-1 (空頭) の信号を生成する.
Wave Trendのシグナルに基づいて買入と売却のタイミングを決定する.VWMA指標の多空シグナルに基づいて,取引の具体的な数を決定する.
この戦略は,トレンド判断と量能指標を統合し,より高度なトレンド追跡戦略を実現している.この戦略には一定の優位性があるが,注意すべきいくつかのリスクもある.パラメータと規則の最適化により,戦略の安定性と収益率をさらに向上させる見通しがある.
/*backtest
start: 2023-12-26 00:00:00
end: 2024-01-25 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"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/
//
// Created by jadamcraig
//
// This strategy benefits from extracts taken from the following
// studies/authors. Thank you for developing and sharing your ideas in an open
// way!
// * Wave Trend Strategy by thomas.gigure
// * cRSI + Waves Strategy with VWMA overlay by Dr_Roboto
//
//@version=4
//==============================================================================
//==============================================================================
overlay = true // plots VWMA (need to close and re-add)
//overlay = false // plots Wave Trend (need to close and re-add)
strategy("Wave Trend w/ VWMA overlay", overlay=overlay)
baseQty = input(defval=1, title="Base Quantity", type=input.float, minval=1)
useSessions = input(defval=true, title="Limit Signals to Trading Sessions?")
sess1_startHour = input(defval=8, title="Session 1: Start Hour",
type=input.integer, minval=0, maxval=23)
sess1_startMinute = input(defval=25, title="Session 1: Start Minute",
type=input.integer, minval=0, maxval=59)
sess1_stopHour = input(defval=10, title="Session 1: Stop Hour",
type=input.integer, minval=0, maxval=23)
sess1_stopMinute = input(defval=25, title="Session 1: Stop Minute",
type=input.integer, minval=0, maxval=59)
sess2_startHour = input(defval=12, title="Session 2: Start Hour",
type=input.integer, minval=0, maxval=23)
sess2_startMinute = input(defval=55, title="Session 2: Start Minute",
type=input.integer, minval=0, maxval=59)
sess2_stopHour = input(defval=14, title="Session 2: Stop Hour",
type=input.integer, minval=0, maxval=23)
sess2_stopMinute = input(defval=55, title="Session 2: Stop Minute",
type=input.integer, minval=0, maxval=59)
sess1_closeAll = input(defval=false, title="Close All at End of Session 1")
sess2_closeAll = input(defval=true, title="Close All at End of Session 2")
//==============================================================================
//==============================================================================
// Volume Weighted Moving Average (VWMA)
//==============================================================================
//==============================================================================
plotVWMA = overlay
// check if volume is available for this equity
useVolume = input(
title="VWMA: Use Volume (uncheck if equity does not have volume)",
defval=true)
vwmaLen = input(defval=21, title="VWMA: Length", type=input.integer, minval=1,
maxval=200)
vwma = vwma(close, vwmaLen)
vwma_high = vwma(high, vwmaLen)
vwma_low = vwma(low, vwmaLen)
if not(useVolume)
vwma := wma(close, vwmaLen)
vwma_high := wma(high, vwmaLen)
vwma_low := wma(low, vwmaLen)
// +1 when above, -1 when below, 0 when inside
vwmaSignal(priceOpen, priceClose, vwmaHigh, vwmaLow) =>
sig = 0
color = color.gray
if priceClose > vwmaHigh
sig := 1
color := color.green
else if priceClose < vwmaLow
sig := -1
color := color.red
else
sig := 0
color := color.gray
[sig,color]
[vwma_sig, vwma_color] = vwmaSignal(open, close, vwma_high, vwma_low)
priceAboveVWMA = vwma_sig == 1 ? true : false
priceBelowVWMA = vwma_sig == -1 ? true : false
// plot(priceAboveVWMA?2.0:0,color=color.blue)
// plot(priceBelowVWMA?2.0:0,color=color.maroon)
//bandTrans = input(defval=70, title="VWMA Band Transparancy (100 invisible)",
// type=input.integer, minval=0, maxval=100)
//fillTrans = input(defval=70, title="VWMA Fill Transparancy (100 invisible)",
// type=input.integer, minval=0, maxval=100)
bandTrans = 60
fillTrans = 60
// ***** Plot VWMA *****
highband = plot(plotVWMA?fixnan(vwma_high):na, title='VWMA High band',
color = vwma_color, linewidth=1, transp=bandTrans)
lowband = plot(plotVWMA?fixnan(vwma_low):na, title='VWMA Low band',
color = vwma_color, linewidth=1, transp=bandTrans)
fill(lowband, highband, title='VWMA Band fill', color=vwma_color,
transp=fillTrans)
plot(plotVWMA?vwma:na, title='VWMA', color = vwma_color, linewidth=3,
transp=bandTrans)
//==============================================================================
//==============================================================================
// Wave Trend
//==============================================================================
//==============================================================================
plotWaveTrend = not(overlay)
n1 = input(10, "Wave Trend: Channel Length")
n2 = input(21, "Wave Trend: Average Length")
obLevel1 = input(60, "Wave Trend: Over Bought Level 1")
obLevel2 = input(53, "Wave Trend: Over Bought Level 2")
osLevel1 = input(-60, "Wave Trend: Over Sold Level 1")
osLevel2 = input(-53, "Wave Trend: Over Sold Level 2")
ap = hlc3
esa = ema(ap, n1)
d = ema(abs(ap - esa), n1)
ci = (ap - esa) / (0.015 * d)
tci = ema(ci, n2)
wt1 = tci
wt2 = sma(wt1,4)
plot(plotWaveTrend?0:na, color=color.gray)
plot(plotWaveTrend?obLevel1:na, color=color.red)
plot(plotWaveTrend?osLevel1:na, color=color.green)
plot(plotWaveTrend?obLevel2:na, color=color.red, style=3)
plot(plotWaveTrend?osLevel2:na, color=color.green, style=3)
plot(plotWaveTrend?wt1:na, color=color.green)
plot(plotWaveTrend?wt2:na, color=color.red, style=3)
plot(plotWaveTrend?wt1-wt2:na, color=color.blue, transp=80)
//==============================================================================
//==============================================================================
// Order Management
//==============================================================================
//==============================================================================
// Define Long and Short Conditions
longCondition = crossover(wt1, wt2)
shortCondition = crossunder(wt1, wt2)
// Define Quantities
orderQty = baseQty * 2
if (longCondition)
if (vwma_sig == 1)
if ( strategy.position_size >= (baseQty * 4 * -1) and
strategy.position_size < 0 )
orderQty := baseQty * 4 + abs(strategy.position_size)
else
orderQty := baseQty * 4
else if (vwma_sig == 0)
if ( strategy.position_size >= (baseQty * 2 * -1) and
strategy.position_size < 0 )
orderQty := baseQty * 2 + abs(strategy.position_size)
else
orderQty := baseQty * 2
else if (vwma_sig == -1)
if ( strategy.position_size >= (baseQty * 1 * -1) and
strategy.position_size < 0 )
orderQty := baseQty * 1 + abs(strategy.position_size)
else
orderQty := baseQty * 1
else if (shortCondition)
if (vwma_sig == -1)
if ( strategy.position_size <= (baseQty * 4) and
strategy.position_size > 0 )
orderQty := baseQty * 4 + strategy.position_size
else
orderQty := baseQty * 4
else if (vwma_sig == 0)
if ( strategy.position_size <= (baseQty * 2) and
strategy.position_size > 2 )
orderQty := baseQty * 2 + strategy.position_size
else
orderQty := baseQty * 2
else if (vwma_sig == 1)
if ( strategy.position_size <= (baseQty * 1) and
strategy.position_size > 0 )
orderQty := baseQty * 1 + strategy.position_size
else
orderQty := baseQty * 1
// Determine if new trades are permitted
newTrades = false
if (useSessions)
if ( hour == sess1_startHour and minute >= sess1_startMinute )
newTrades := true
else if ( hour > sess1_startHour and hour < sess1_stopHour )
newTrades := true
else if ( hour == sess1_stopHour and minute < sess1_stopMinute )
newTrades := true
else if ( hour == sess2_startHour and minute >= sess2_startMinute )
newTrades := true
else if ( hour > sess2_startHour and hour < sess2_stopHour )
newTrades := true
else if ( hour == sess2_stopHour and minute < sess2_stopMinute )
newTrades := true
else
newTrades := false
else
newTrades := true
// Long Signals
if ( longCondition )
strategy.order("Buy", strategy.long, orderQty)
// Short Signals
if ( shortCondition )
strategy.order("Sell", strategy.short, orderQty)
// Close open position at end of Session 1, if enabled
if (sess1_closeAll )
strategy.close_all()
// Close open position at end of Session 2, if enabled
if (sess2_closeAll )
strategy.close_all()