ADX スマートトレンドフォロー戦略


作成日: 2023-11-28 14:04:00 最終変更日: 2023-11-28 14:04:00
コピー: 0 クリック数: 884
1
フォロー
1617
フォロワー

ADX スマートトレンドフォロー戦略

概要

ADXインテリジェントトレンド追跡戦略は,平均トレンド指数 ((ADX) を利用してトレンドの強さを判断し,トレンドが弱い時にトレンドキャプチャを行い,強いトレンドで追跡利益を得る.この戦略は,トレンドの強さを判断しながら価格突破を組み合わせて取引信号を生成する.これはトレンド追跡戦略の一種である.

戦略原則

この戦略は,主に平均トレンド指数 ((ADX) をベースに現在のトレンドの力を判断する.ADXは,価格変動のDIRECTIONAL INDICATORの平均値を計算して一定の周期でトレンドの力を表現する.ADX値が設定値を下回ったとき,我々は,状況が整理されていると考えている.このとき,四方枠の範囲を判定する.価格が四方枠を突破すれば,トレード信号を生成する.

具体的には,戦略は,まず14周期のADX値を計算し,18周期を下回るとトレンドが弱いと考えます. そして,過去20K線の最高価格と最低価格が形成された枠の範囲を計算します. 価格が枠を突破すると,買入と売却のシグナルが生じます. ストップ距離は枠のサイズで50%,ストップ距離は枠のサイズで100%です.

この戦略は,トレンドの強さを判断し,突破信号を組み合わせ,トレンドが弱く,整理に入るときにキャッチすることができ,乱雑な状況で頻繁に取引を避ける. 強いトレンドが発生すると,止まる範囲は大きいので,より多くの利益を得ることができます.

戦略的優位性

  1. 取引の流れを判断することで,乱雑な状況で頻繁に取引を避けることができます.
  2. フレーム突破は,震動の際に引っ込まれるのを防ぐためのフィルターを追加しました.
  3. 市場が動いているとき,より大きな停止スペースを得ることができます.
  4. ADXパラメータ,方格パラメータ,止損止係数など,異なる品種に適応できる.

戦略リスク

  1. ADXパラメータの設定が不適切である場合,トレンドを逃すか判断を誤る可能性があります.
  2. 大きすぎても小さすぎても効果が落ちます.
  3. 止損止係数が正しくない場合,止損が小さすぎたり,早すぎたりする可能性があります.

ADXパラメータ,スクエアパラメータ,ストップ・ストップ係数などの調整によって最適化することができ,異なる品種と市場環境に適したものにすることができる.同時に,厳格な資金管理も重要であり,単一ストップの割合を制御し,単一の大損失を避ける.

戦略最適化の方向性

  1. ADXパラメータは,異なる周期効果をテストできます.
  2. 平方枠パラメータは,異なる長さをテストして,最適な範囲の大きさを判断できます.
  3. ストップダストストップ係数は,リスク・リターン比率を最適化するために微調整できます.
  4. 単一取引の効果をテストできます.
  5. 増量能指数など,他の指数と組み合わせることができる.

要約する

ADXのスマートトレンド追跡戦略は,全体的に比較して安定したトレンド戦略である.それは,トレンドの強さの判断と価格の突破信号を同時に組み合わせ,一般的なトレンド追跡戦略の高殺低を追跡する問題をある程度回避する.パラメータの最適化と厳格な資金管理により,この戦略を安定的に収益化することができる.

ストラテジーソースコード
/*backtest
start: 2023-11-20 00:00:00
end: 2023-11-27 00:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//Developer: Andrew Palladino. 
//Creator: Rob Booker.
//Date: 9/29/2017
//@version=5
//Date: 08/10/2022
//Updated to V5 from V1, default cash settings added and indicators made more easily visible by:
// @ Powerscooter

strategy("Rob Booker - ADX Breakout", shorttitle="ADX Breakout V5", overlay=true, default_qty_type = strategy.cash, default_qty_value = 100000, initial_capital = 100000)

adxSmoothPeriod = input(14, title="ADX Smoothing Period", group = "ADX Settings")
adxPeriod = input(14, title="ADX Period", group = "ADX Settings")
adxLowerLevel = input(18, title="ADX Lower Level", group = "ADX Settings")
boxLookBack = input(20, title="BreakoutBox Lookback Period", group = "BreakoutBox")
profitTargetMultiple = input(1.0, title="Profit Target Box Width Multiple", group = "Take Profit and Stop Loss")
stopLossMultiple = input(0.5, title="Stop Loss Box Width Multiple", group = "Take Profit and Stop Loss")
enableDirection = input(0, title="Both(0), Long(1), Short(-1)", group = "Trade Direction")


// When the ADX drops below threshold limit, then we consider the pair in consolidation. 
// Set Box around highs and lows of the last 20 candles. with upper and lower boundaries. 
// When price breaks outside of box, a trade is taken. (on close or on touch?)
// Stop is placed, default 50%, of the size of the box. So if box is 200 pips, stop is at 100 pips. 
// Profit target is 100% of the size of the box. Default. User can set a profit target of 0.5, 1 full size, 2 or 3. 


dirmov(len) =>
	up = ta.change(high)
	down = -ta.change(low)
	truerange = ta.rma(ta.tr, len)
	plus = fixnan(100 * ta.rma(up > down and up > 0 ? up : 0, len) / truerange)
	minus = fixnan(100 * ta.rma(down > up and down > 0 ? down : 0, len) / truerange)
	[plus, minus]

adx(dilen, adxlen) => 
	[plus, minus] = dirmov(dilen)
	sum = plus + minus
	adx = 100 * ta.rma(math.abs(plus - minus) / (sum == 0 ? 1 : sum), adxlen)

adxHigh(dilen, adxlen) => 
	[plus, minus] = dirmov(dilen)
	plus
	
adxLow(dilen, adxlen) => 
	[plus, minus] = dirmov(dilen)
	minus
	
sig = adx(adxSmoothPeriod, adxPeriod)
//sigHigh = adxHigh(dilen, adxlen)
//sigLow = adxLow(dilen, adxlen)

isADXLow = sig < adxLowerLevel

//boxUpperLevel = ta.highest(high, boxLookBack)[1]
//boxLowerLevel = ta.lowest(low, boxLookBack)[1]

var float boxUpperLevelCarry = 0
var float boxLowerLevelCarry = 0

boxUpperLevel = strategy.position_size == 0 ? ta.highest(high, boxLookBack)[1] : boxUpperLevelCarry
boxUpperLevelCarry := boxUpperLevel
boxLowerLevel = strategy.position_size == 0 ? ta.lowest(low, boxLookBack)[1] : boxLowerLevelCarry
boxLowerLevelCarry := boxLowerLevel

boxWidth = boxUpperLevel - boxLowerLevel

profitTarget = strategy.position_size > 0  ? strategy.position_avg_price + profitTargetMultiple*boxWidth : strategy.position_size < 0 ?  strategy.position_avg_price - profitTargetMultiple*boxWidth : na
stopLoss = strategy.position_size > 0 ? strategy.position_avg_price - stopLossMultiple*boxWidth : strategy.position_size < 0 ? strategy.position_avg_price + stopLossMultiple*boxWidth : na

plot(strategy.position_size == 0 ? boxUpperLevel : na, color=color.white, style = plot.style_linebr)
plot(strategy.position_size == 0 ? boxLowerLevel : na, color=color.white, style = plot.style_linebr)


bgcolor(isADXLow ? color.purple : na, transp=72, title = "ADX limit")
plot(stopLoss, color=color.red, linewidth=2, style = plot.style_linebr, title="StopLossLine")
plot(profitTarget, color=color.blue, linewidth=2, style = plot.style_linebr, title="ProfitTargetLine")

isBuyValid = strategy.position_size == 0 and ta.cross(close, boxUpperLevel) and isADXLow

//Long Entry Condition
strategy.exit("close_long", from_entry="open_long", limit = profitTarget, stop = stopLoss)
if isBuyValid and strategy.opentrades == 0 and (enableDirection == -1 or enableDirection == 0)
    strategy.entry("open_long", strategy.long)

isSellValid = strategy.position_size == 0 and ta.cross(close, boxLowerLevel) and isADXLow

//Short Entry condition
strategy.exit(id="close_short", from_entry="open_short", limit = profitTarget, stop = stopLoss)
if isSellValid and strategy.opentrades == 0 and (enableDirection == 1 or enableDirection == 0)
    strategy.entry("open_short", strategy.short)